diff --git a/PKHeX.WinForms/MainWindow/MainCK3.cs b/PKHeX.WinForms/MainWindow/MainCK3.cs index b04b8459d..236427d92 100644 --- a/PKHeX.WinForms/MainWindow/MainCK3.cs +++ b/PKHeX.WinForms/MainWindow/MainCK3.cs @@ -29,7 +29,8 @@ namespace PKHeX.WinForms Label_OTGender.ForeColor = ck3.OT_Gender == 1 ? Color.Red : Color.Blue; TB_PID.Text = ck3.PID.ToString("X8"); CB_HeldItem.SelectedValue = ck3.HeldItem; - CB_Ability.SelectedIndex = ck3.AbilityNumber > CB_Ability.Items.Count ? 0 : ck3.AbilityNumber; + int abil = ck3.AbilityNumber >> 1; + CB_Ability.SelectedIndex = abil > CB_Ability.Items.Count ? 0 : abil; CB_Nature.SelectedValue = ck3.Nature; TB_TID.Text = ck3.TID.ToString("00000"); TB_SID.Text = ck3.SID.ToString("00000"); @@ -136,7 +137,7 @@ namespace PKHeX.WinForms ck3.SID = Util.ToInt32(TB_SID.Text); ck3.EXP = Util.ToUInt32(TB_EXP.Text); ck3.PID = Util.getHEXval(TB_PID.Text); - ck3.AbilityNumber = CB_Ability.SelectedIndex; + ck3.AbilityNumber = 1 << CB_Ability.SelectedIndex; // to match gen6+ ck3.FatefulEncounter = CHK_Fateful.Checked; ck3.Gender = PKX.getGender(Label_Gender.Text); diff --git a/PKHeX.WinForms/MainWindow/MainPK3.cs b/PKHeX.WinForms/MainWindow/MainPK3.cs index 86bf064d8..75bfb647c 100644 --- a/PKHeX.WinForms/MainWindow/MainPK3.cs +++ b/PKHeX.WinForms/MainWindow/MainPK3.cs @@ -29,7 +29,8 @@ namespace PKHeX.WinForms Label_OTGender.ForeColor = pk3.OT_Gender == 1 ? Color.Red : Color.Blue; TB_PID.Text = pk3.PID.ToString("X8"); CB_HeldItem.SelectedValue = pk3.HeldItem; - CB_Ability.SelectedIndex = pk3.AbilityNumber > CB_Ability.Items.Count ? 0 : pk3.AbilityNumber; + int abil = pk3.AbilityNumber >> 1; + CB_Ability.SelectedIndex = abil > CB_Ability.Items.Count ? 0 : abil; CB_Nature.SelectedValue = pk3.Nature; TB_TID.Text = pk3.TID.ToString("00000"); TB_SID.Text = pk3.SID.ToString("00000"); @@ -114,7 +115,7 @@ namespace PKHeX.WinForms pk3.SID = Util.ToInt32(TB_SID.Text); pk3.EXP = Util.ToUInt32(TB_EXP.Text); pk3.PID = Util.getHEXval(TB_PID.Text); - pk3.AbilityNumber = CB_Ability.SelectedIndex; // 0/1 (stored in IVbits) + pk3.AbilityNumber = 1 << CB_Ability.SelectedIndex; // to match gen6+ pk3.FatefulEncounter = CHK_Fateful.Checked; pk3.Gender = PKX.getGender(Label_Gender.Text); diff --git a/PKHeX.WinForms/MainWindow/MainXK3.cs b/PKHeX.WinForms/MainWindow/MainXK3.cs index 203ceb363..3731171f7 100644 --- a/PKHeX.WinForms/MainWindow/MainXK3.cs +++ b/PKHeX.WinForms/MainWindow/MainXK3.cs @@ -29,7 +29,8 @@ namespace PKHeX.WinForms Label_OTGender.ForeColor = xk3.OT_Gender == 1 ? Color.Red : Color.Blue; TB_PID.Text = xk3.PID.ToString("X8"); CB_HeldItem.SelectedValue = xk3.HeldItem; - CB_Ability.SelectedIndex = xk3.AbilityNumber > CB_Ability.Items.Count ? 0 : xk3.AbilityNumber; + int abil = xk3.AbilityNumber >> 1; + CB_Ability.SelectedIndex = abil > CB_Ability.Items.Count ? 0 : abil; CB_Nature.SelectedValue = xk3.Nature; TB_TID.Text = xk3.TID.ToString("00000"); TB_SID.Text = xk3.SID.ToString("00000"); @@ -136,7 +137,7 @@ namespace PKHeX.WinForms xk3.SID = Util.ToInt32(TB_SID.Text); xk3.EXP = Util.ToUInt32(TB_EXP.Text); xk3.PID = Util.getHEXval(TB_PID.Text); - xk3.AbilityNumber = CB_Ability.SelectedIndex; // 0/1 (stored in IVbits) + xk3.AbilityNumber = 1 << CB_Ability.SelectedIndex; // to match gen6+ xk3.FatefulEncounter = CHK_Fateful.Checked; xk3.Gender = PKX.getGender(Label_Gender.Text); diff --git a/PKHeX/Legality/Analysis.cs b/PKHeX/Legality/Analysis.cs index 1ea18e7fe..809dae109 100644 --- a/PKHeX/Legality/Analysis.cs +++ b/PKHeX/Legality/Analysis.cs @@ -50,7 +50,7 @@ namespace PKHeX.Core if (!Parse.Any()) switch (pk.GenNumber) { - case 3: parsePK3(pk); break; + case 3: if (pk.Version != 15) parsePK3(pk); break; case 4: parsePK4(pk); break; case 5: parsePK5(pk); break; case 6: parsePK6(pk); break; @@ -324,12 +324,19 @@ namespace PKHeX.Core int loc = getSuggestedTransferLocation(pkm); if (pkm.WasEgg) + { + int lvl = 1; // gen5+ + if (!pkm.IsNative) + lvl = pkm.CurrentLevel; // be generous with transfer conditions + else if (pkm.Format < 5) // and native + lvl = 0; return new EncounterStatic { Species = Legal.getBaseSpecies(pkm), Location = loc != -1 ? loc : getSuggestedEggMetLocation(pkm), - Level = 1, + Level = lvl, }; + } var area = Legal.getCaptureLocation(pkm); if (area != null) @@ -353,6 +360,21 @@ namespace PKHeX.Core // Return one of legal hatch locations for game switch ((GameVersion)pkm.Version) { + case GameVersion.R: + case GameVersion.S: + case GameVersion.E: + case GameVersion.FR: + case GameVersion.LG: + switch (pkm.Format) + { + case 3: + return pkm.FRLG ? 146 /* Four Island */ : 32; // Route 117 + case 4: + return 0x37; // Pal Park + default: + return 30001; // Transporter + } + case GameVersion.D: case GameVersion.P: case GameVersion.Pt: diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index 0eaa94337..3db8f1a72 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -1069,13 +1069,25 @@ namespace PKHeX.Core } else { - if (wc.Egg_Location + 3000 != pkm.Met_Location) continue; + if (pkm.Format != 4) // transferred + { + bool valid = false; + if (pkm.Met_Location == 30001) + valid = true; + else if (CrownBeasts[0] == pkm.Species) // 251 = Celebi + valid = pkm.Met_Location == 30010 || pkm.Met_Location == 30011; // unused || used + else if (CrownBeasts.Skip(1).Any(x => x == pkm.Species)) // Raikou, Entei, Suicune + valid = pkm.Met_Location == 30012 || pkm.Met_Location == 30013; // unused || used + if (!valid) + continue; + } + else if (wc.Egg_Location + 3000 != pkm.Met_Location) continue; } if (wc.CurrentLevel != pkm.Met_Level) continue; if (wc.Ball != pkm.Ball) continue; if (wc.OT_Gender < 3 && wc.OT_Gender != pkm.OT_Gender) continue; - if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) continue; + if (wc.PID == 1 && pkm.IsShiny) continue; if (wc.Gender != 3 && wc.Gender != pkm.Gender) continue; if (wc.CNT_Cool > pkm.CNT_Cool) continue; @@ -1108,7 +1120,6 @@ namespace PKHeX.Core if (wc.SID != pkm.SID) continue; if (wc.TID != pkm.TID) continue; if (wc.OT != pkm.OT_Name) continue; - if (wc.OTGender != pkm.OT_Gender) continue; if (wc.PID != 0 && pkm.PID != wc.PID) continue; if (wc.PIDType == 0 && pkm.IsShiny) continue; if (wc.PIDType == 2 && !pkm.IsShiny) continue; diff --git a/PKHeX/PKM/CK3.cs b/PKHeX/PKM/CK3.cs index 863a398fe..f4d95ddaf 100644 --- a/PKHeX/PKM/CK3.cs +++ b/PKHeX/PKM/CK3.cs @@ -36,7 +36,7 @@ namespace PKHeX.Core public override int Gender { get { return PKX.getGender(Species, PID); } set { } } public override int Characteristic => -1; public override int CurrentFriendship { get { return OT_Friendship; } set { OT_Friendship = value; } } - public override int Ability { get { int[] abils = PersonalTable.RS.getAbilities(Species, 0); return abils[abils[1] == 0 ? 0 : AbilityNumber]; } set { } } + public override int Ability { get { int[] abils = PersonalTable.RS.getAbilities(Species, 0); return abils[abils[1] == 0 ? 0 : AbilityNumber >> 1]; } set { } } public override int CurrentHandler { get { return 0; } set { } } public override int Egg_Location { get { return 0; } set { } } @@ -167,7 +167,7 @@ namespace PKHeX.Core public override int PKRS_Strain { get { return Data[0xCA] & 0xF; } set { Data[0xCA] = (byte)(value & 0xF); } } public override bool IsEgg { get { return Data[0xCB] == 1; } set { Data[0xCB] = (byte)(value ? 1 : 0); } } - public override int AbilityNumber { get { return Data[0xCC]; } set { Data[0xCC] = (byte)(value & 1); } } + public override int AbilityNumber { get { return 1 << Data[0xCC]; } set { Data[0xCC] = (byte)((value >> 1) & 1); } } public override bool Valid { get { return Data[0xCD] == 0; } set { if (value) Data[0xCD] = 0; } } // 0xCE unknown public override int MarkValue { get { return Data[0xCF]; } protected set { Data[0xCF] = (byte)value; } } diff --git a/PKHeX/PKM/PK3.cs b/PKHeX/PKM/PK3.cs index 93f2f2cfd..010e1c9a8 100644 --- a/PKHeX/PKM/PK3.cs +++ b/PKHeX/PKM/PK3.cs @@ -33,7 +33,7 @@ namespace PKHeX.Core public override int Gender { get { return PKX.getGender(Species, PID); } set { } } public override int Characteristic => -1; public override int CurrentFriendship { get { return OT_Friendship; } set { OT_Friendship = value; } } - public override int Ability { get { int[] abils = PersonalInfo.Abilities; return abils[abils[1] == 0 ? 0 : AbilityNumber]; } set { } } + public override int Ability { get { int[] abils = PersonalInfo.Abilities; return abils[abils[1] == 0 ? 0 : AbilityNumber >> 1]; } set { } } public override int CurrentHandler { get { return 0; } set { } } public override int Egg_Location { get { return 0; } set { } } @@ -120,7 +120,7 @@ namespace PKHeX.Core public override int IV_SPA { get { return (int)(IV32 >> 20) & 0x1F; } set { IV32 = (uint)((IV32 & ~(0x1F << 20)) | (uint)((value > 31 ? 31 : value) << 20)); } } public override int IV_SPD { get { return (int)(IV32 >> 25) & 0x1F; } set { IV32 = (uint)((IV32 & ~(0x1F << 25)) | (uint)((value > 31 ? 31 : value) << 25)); } } public override bool IsEgg { get { return ((IV32 >> 30) & 1) == 1; } set { IV32 = (uint)((IV32 & ~0x40000000) | (uint)(value ? 0x40000000 : 0)); } } - public override int AbilityNumber { get { return (int)((IV32 >> 31) & 1); } set { IV32 = (IV32 & 0x7FFFFFFF) | (value == 1 ? 0x80000000 : 0); } } + public override int AbilityNumber { get { return 1 << (int)((IV32 >> 31) & 1); } set { IV32 = (IV32 & 0x7FFFFFFF) | (value > 1 ? 0x80000000 : 0); } } private uint RIB0 { get { return BitConverter.ToUInt32(Data, 0x4C); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x4C); } } public int RibbonCountG3Cool { get { return (int)(RIB0 >> 00) & 7; } set { RIB0 = (uint)((RIB0 & ~(7 << 00)) | (uint)(value & 7) << 00); } } diff --git a/PKHeX/PKM/XK3.cs b/PKHeX/PKM/XK3.cs index 67cbb0efd..92a351ab9 100644 --- a/PKHeX/PKM/XK3.cs +++ b/PKHeX/PKM/XK3.cs @@ -34,7 +34,7 @@ namespace PKHeX.Core public override int Gender { get { return PKX.getGender(Species, PID); } set { } } public override int Characteristic => -1; public override int CurrentFriendship { get { return OT_Friendship; } set { OT_Friendship = value; } } - public override int Ability { get { int[] abils = PersonalTable.RS.getAbilities(Species, 0); return abils[abils[1] == 0 ? 0 : AbilityNumber]; } set { } } + public override int Ability { get { int[] abils = PersonalTable.RS.getAbilities(Species, 0); return abils[abils[1] == 0 ? 0 : AbilityNumber >> 1]; } set { } } public override int CurrentHandler { get { return 0; } set { } } public override int Egg_Location { get { return 0; } set { } } @@ -66,7 +66,7 @@ namespace PKHeX.Core public bool UnusedFlag3 { get { return (XDPKMFLAGS & (1 << 3)) == 1 << 3; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 3) | (value ? 1 << 3 : 0); } } public bool BlockTrades { get { return (XDPKMFLAGS & (1 << 4)) == 1 << 4; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 4) | (value ? 1 << 4 : 0); } } public override bool Valid { get { return (XDPKMFLAGS & (1 << 5)) == 0; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 5) | (value ? 0 : 1 << 5); } } // invalid flag - public override int AbilityNumber { get { return (XDPKMFLAGS >> 6) & 1; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 6) | (value << 6); } } + public override int AbilityNumber { get { return 1 << ((XDPKMFLAGS >> 6) & 1); }set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 6) | (((value >> 1) & 1) << 6); } } public override bool IsEgg { get { return (XDPKMFLAGS & (1 << 7)) == 1 << 7; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 7) | (value ? 1 << 7 : 0); } } // 0x1E-0x1F Unknown public override uint EXP { get { return BigEndian.ToUInt32(Data, 0x20); } set { BigEndian.GetBytes(value).CopyTo(Data, 0x20); } }