diff --git a/PKHeX.Core/Legality/Encounters/Generator/EncounterCriteria.cs b/PKHeX.Core/Legality/Encounters/Generator/EncounterCriteria.cs index 07548675c..9dca473b3 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/EncounterCriteria.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/EncounterCriteria.cs @@ -188,19 +188,26 @@ public sealed record EncounterCriteria pk.IV_SPE = IV_SPE != RandomIV ? IV_SPE : Util.Rand.Next(32); } + /// + /// Applies random IVs with a minimum and maximum (bitshifted >> 1) + /// + /// Entity to mutate. + /// Minimum IV from GO + /// Maximum IV from GO public void SetRandomIVsGO(PKM pk, int minIV = 0, int maxIV = 15) { + var bareMin = (minIV << 1) | 1; var rnd = Util.Rand; pk.IV_HP = - IV_HP != RandomIV ? IV_HP | 1 + IV_HP != RandomIV && IV_HP >= bareMin ? IV_HP | 1 : (rnd.Next(minIV, maxIV + 1) << 1) | 1; // hp pk.IV_ATK = pk.IV_SPA = - IV_ATK != RandomIV ? IV_ATK | 1 - : IV_SPA != RandomIV ? IV_SPA | 1 + IV_ATK != RandomIV && IV_ATK >= bareMin ? IV_ATK | 1 + : IV_SPA != RandomIV && IV_SPA >= bareMin ? IV_SPA | 1 : (rnd.Next(minIV, maxIV + 1) << 1) | 1; // attack pk.IV_DEF = pk.IV_SPD = - IV_DEF != RandomIV ? IV_DEF | 1 - : IV_SPD != RandomIV ? IV_SPD | 1 + IV_DEF != RandomIV && IV_DEF >= bareMin ? IV_DEF | 1 + : IV_SPD != RandomIV && IV_SPD >= bareMin ? IV_SPD | 1 : (rnd.Next(minIV, maxIV + 1) << 1) | 1; // defense pk.IV_SPE = IV_SPE != RandomIV ? IV_SPE diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen2/EncounterStatic2.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen2/EncounterStatic2.cs index f2c3f173f..ca1c5493c 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen2/EncounterStatic2.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen2/EncounterStatic2.cs @@ -56,7 +56,7 @@ public sealed record EncounterStatic2(ushort Species, byte Level, GameVersion Ve if (EggEncounter) { - if (DizzyPunchEgg) + if (DizzyPunchEgg) // Fixed EXP value instead of exactly Level 5 pk.EXP = 125; } else if (Version == GameVersion.C || (Version == GameVersion.GSC && tr.Game == (int)GameVersion.C)) @@ -94,7 +94,7 @@ public sealed record EncounterStatic2(ushort Species, byte Level, GameVersion Ve if (EggEncounter && Moves.HasMoves) // Odd Egg { if (pk.Format > 2) - return false; + return false; // Can't be transferred to Gen7+ if (!pk.HasMove((int)Move.DizzyPunch)) return false; diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen6/EncounterTrade6.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen6/EncounterTrade6.cs index 9be2f0a12..9f938674e 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen6/EncounterTrade6.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen6/EncounterTrade6.cs @@ -65,6 +65,7 @@ public sealed record EncounterTrade6 : IEncounterable, IEncounterMatch, IFixedTr { var version = this.GetCompatibleVersion((GameVersion)tr.Game); int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, version); + var pi = PersonalTable.AO[Species, 0]; var pk = new PK6 { PID = Util.Rand32(), @@ -88,7 +89,7 @@ public sealed record EncounterTrade6 : IEncounterable, IEncounterMatch, IFixedTr OT_Intensity = OT_Intensity, OT_Feeling = OT_Feeling, OT_TextVar = OT_TextVar, - OT_Friendship = PersonalTable.AO[Species, 0].BaseFriendship, + OT_Friendship = pi.BaseFriendship, IsNicknamed = IsFixedNickname, Nickname = IsFixedNickname ? Nicknames[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation), @@ -96,7 +97,7 @@ public sealed record EncounterTrade6 : IEncounterable, IEncounterMatch, IFixedTr HT_Name = tr.OT, HT_Gender = tr.Gender, CurrentHandler = 1, - HT_Friendship = PersonalTable.AO[Species, 0].BaseFriendship, + HT_Friendship = pi.BaseFriendship, }; if (tr is IRegionOrigin r) r.CopyRegionOrigin(pk); diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen7/EncounterTrade7.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen7/EncounterTrade7.cs index b9ee909b4..37e6820d6 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen7/EncounterTrade7.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen7/EncounterTrade7.cs @@ -63,6 +63,7 @@ public sealed record EncounterTrade7 : IEncounterable, IEncounterMatch, IFixedTr { var version = this.GetCompatibleVersion((GameVersion)tr.Game); int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, version); + var pi = PersonalTable.USUM[Species, Form]; var pk = new PK7 { PID = Util.Rand32(), @@ -87,7 +88,7 @@ public sealed record EncounterTrade7 : IEncounterable, IEncounterMatch, IFixedTr OT_Intensity = OT_Intensity, OT_Feeling = OT_Feeling, OT_TextVar = OT_TextVar, - OT_Friendship = PersonalTable.USUM[Species, Form].BaseFriendship, + OT_Friendship = pi.BaseFriendship, IsNicknamed = true, Nickname = Nicknames[lang], @@ -95,7 +96,7 @@ public sealed record EncounterTrade7 : IEncounterable, IEncounterMatch, IFixedTr HT_Name = tr.OT, HT_Gender = tr.Gender, CurrentHandler = 1, - HT_Friendship = PersonalTable.USUM[Species, Form].BaseFriendship, + HT_Friendship = pi.BaseFriendship, }; if (tr is IRegionOrigin r) r.CopyRegionOrigin(pk); diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen7b/EncounterTrade7b.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen7b/EncounterTrade7b.cs index aa4b4d7e6..49956b595 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen7b/EncounterTrade7b.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen7b/EncounterTrade7b.cs @@ -45,6 +45,7 @@ public sealed record EncounterTrade7b(GameVersion Version) : IEncounterable, IEn { var version = this.GetCompatibleVersion((GameVersion)tr.Game); int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, version); + var pi = PersonalTable.GG[Species, Form]; var pk = new PB7 { Species = Species, @@ -61,7 +62,7 @@ public sealed record EncounterTrade7b(GameVersion Version) : IEncounterable, IEn OT_Gender = OTGender, OT_Name = TrainerNames[lang], - OT_Friendship = PersonalTable.GG[Species, Form].BaseFriendship, + OT_Friendship = pi.BaseFriendship, HeightScalar = PokeSizeUtil.GetRandomScalar(), WeightScalar = PokeSizeUtil.GetRandomScalar(), @@ -71,7 +72,7 @@ public sealed record EncounterTrade7b(GameVersion Version) : IEncounterable, IEn HT_Name = tr.OT, HT_Gender = tr.Gender, CurrentHandler = 1, - HT_Friendship = PersonalTable.GG[Species, Form].BaseFriendship, + HT_Friendship = pi.BaseFriendship, }; EncounterUtil1.SetEncounterMoves(pk, version, Level); diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterTrade8.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterTrade8.cs index 5669b8bf6..de456fe7e 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterTrade8.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterTrade8.cs @@ -95,6 +95,7 @@ public sealed record EncounterTrade8 : IEncounterable, IEncounterMatch, IFixedTr { var version = this.GetCompatibleVersion((GameVersion)tr.Game); int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, version); + var pi = PersonalTable.SWSH[Species, Form]; var pk = new PK8 { PID = Util.Rand32(), @@ -117,7 +118,7 @@ public sealed record EncounterTrade8 : IEncounterable, IEncounterMatch, IFixedTr OT_Intensity = OT_Intensity, OT_Feeling = OT_Feeling, OT_TextVar = OT_TextVar, - OT_Friendship = PersonalTable.SWSH[Species, Form].BaseFriendship, + OT_Friendship = pi.BaseFriendship, IsNicknamed = IsFixedNickname, Nickname = IsFixedNickname ? Nicknames[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation), @@ -126,7 +127,7 @@ public sealed record EncounterTrade8 : IEncounterable, IEncounterMatch, IFixedTr HT_Gender = tr.Gender, HT_Language = (byte)tr.Language, CurrentHandler = 1, - HT_Friendship = PersonalTable.SWSH[Species, Form].BaseFriendship, + HT_Friendship = pi.BaseFriendship, }; if (Shiny == Shiny.Never && pk.IsShiny) pk.PID ^= 0x1000_0000u; diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen8a/IMasteryInitialMoveShop8.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen8a/IMasteryInitialMoveShop8.cs index 3e1a943b0..b23aa24da 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen8a/IMasteryInitialMoveShop8.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen8a/IMasteryInitialMoveShop8.cs @@ -13,12 +13,15 @@ public interface IMasteryInitialMoveShop8 void SetInitialMastery(PKM pk) { if (pk is PA8 pa8) - { - Span moves = stackalloc ushort[4]; - var level = pa8.Met_Level; - var (learn, mastery) = LearnSource8LA.GetLearnsetAndMastery(pk.Species, pk.Form); - LoadInitialMoveset(pa8, moves, learn, level); - pa8.SetEncounterMasteryFlags(moves, mastery, level); - } + SetInitialMastery(pa8); + } + + void SetInitialMastery(PA8 pk) + { + Span moves = stackalloc ushort[4]; + var level = pk.Met_Level; + var (learn, mastery) = LearnSource8LA.GetLearnsetAndMastery(pk.Species, pk.Form); + LoadInitialMoveset(pk, moves, learn, level); + pk.SetEncounterMasteryFlags(moves, mastery, level); } } diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen8b/EncounterTrade8b.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen8b/EncounterTrade8b.cs index 6923db924..941107700 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen8b/EncounterTrade8b.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen8b/EncounterTrade8b.cs @@ -72,6 +72,7 @@ public sealed record EncounterTrade8b : IEncounterable, IEncounterMatch, IFixedT { var version = this.GetCompatibleVersion((GameVersion)tr.Game); int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, version); + var pi = PersonalTable.BDSP[Species, Form]; var pk = new PB8 { PID = PID, @@ -100,7 +101,7 @@ public sealed record EncounterTrade8b : IEncounterable, IEncounterMatch, IFixedT WeightScalar = WeightScalar, HT_Name = tr.OT, HT_Language = (byte)tr.Language, - HT_Friendship = PersonalTable.BDSP[Species, Form].BaseFriendship, + HT_Friendship = pi.BaseFriendship, }; // Has German Language ID for all except German origin, which is Japanese diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen9/EncounterTrade9.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen9/EncounterTrade9.cs index 0ba321c3c..8c74d5e23 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen9/EncounterTrade9.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen9/EncounterTrade9.cs @@ -63,6 +63,7 @@ public sealed record EncounterTrade9 { var version = this.GetCompatibleVersion((GameVersion)tr.Game); int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, version); + var pi = PersonalTable.SV[Species, Form]; var pk = new PK9 { Species = Species, @@ -82,7 +83,7 @@ public sealed record EncounterTrade9 OT_Gender = OTGender, OT_Name = TrainerNames[lang], - OT_Friendship = PersonalTable.SV[Species, Form].BaseFriendship, + OT_Friendship = pi.BaseFriendship, IsNicknamed = true, Nickname = Nicknames[lang], @@ -95,24 +96,24 @@ public sealed record EncounterTrade9 HT_Name = tr.OT, HT_Language = (byte)tr.Language, CurrentHandler = 1, - HT_Friendship = PersonalTable.SV[Species, Form].BaseFriendship, + HT_Friendship = pi.BaseFriendship, Obedience_Level = Level, }; EncounterUtil1.SetEncounterMoves(pk, version, Level); - SetPINGA(pk, criteria); + SetPINGA(pk, criteria, pi); pk.ResetPartyStats(); return pk; } - private void SetPINGA(PK9 pk, EncounterCriteria criteria) + private void SetPINGA(PK9 pk, EncounterCriteria criteria, PersonalInfo9SV pi) { pk.PID = Util.Rand32(); pk.EncryptionConstant = Util.Rand32(); pk.Nature = pk.StatNature = (int)criteria.GetNature(Nature.Random); - pk.Gender = criteria.GetGender(-1, PersonalTable.SV.GetFormEntry(Species, Form)); + pk.Gender = criteria.GetGender(-1, pi); pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability)); criteria.SetRandomIVs(pk, IVs); } diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs b/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs index c166329a7..72f443f57 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs @@ -55,11 +55,12 @@ public static class EvolutionChain EvolutionUtil.ConditionBaseChainForward(chain, encSpecies); if (context == EntityContext.Gen2) { + // Handle the evolution case for Gen2->Gen1 EvolutionGroup2.Instance.Evolve(chain, pk, enc, history); EvolutionGroup1.Instance.Evolve(chain, pk, enc, history); - if (pk.Format > 2) + if (pk.Format > 2) // Skip forward to Gen7 context = EntityContext.Gen7; - else + else // no more possible contexts; done. return history; } diff --git a/PKHeX.Core/Saves/SAV9SV.cs b/PKHeX.Core/Saves/SAV9SV.cs index 00c5bc473..222811a71 100644 --- a/PKHeX.Core/Saves/SAV9SV.cs +++ b/PKHeX.Core/Saves/SAV9SV.cs @@ -184,7 +184,7 @@ public sealed class SAV9SV : SaveFile, ISaveBlock9Main, ISCBlockArray, ISaveFile return pk.Species switch { (int)Species.Furfrou => 5u, // Furfrou - (int)Species.Hoopa => 3u, // Hoopa + // Hoopa no longer sets Form Argument for Unbound form. Let it set 0. _ => 0u, }; }