diff --git a/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs b/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs index d671a278c..df6b5708f 100644 --- a/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs +++ b/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Linq; using static PKHeX.Core.EncounterUtil; using static PKHeX.Core.GameVersion; @@ -128,43 +127,6 @@ internal static class Encounters2 private const string tradeGSC = "tradegsc"; private static readonly string[][] TradeGift_GSC_OTs = Util.GetLanguageStrings8(tradeGSC); - internal static bool IsTreeAvailable(EncounterSlot encounter, int trainerID) - { - if (!Trees.TryGetValue(encounter.Location, out var permissions)) - return false; - - var pivot = trainerID % 10; - var type = encounter.Area.Type; - return type switch - { - SlotType.Headbutt => (permissions & (1 << pivot)) != 0, - /*special*/_ => (permissions & (1 << (pivot + 12))) != 0, - }; - } - - private static readonly Dictionary Trees = new() - { - {02, 0x3FF_3FF}, // Route 29 - {04, 0x39D_3FF}, // Route 30 - {05, 0x13D_3FF}, // Route 31 - {08, 0x2FF_3FF}, // Route 32 - {11, 0x009_3FF}, // Route 33 - {12, 0x3DF_3FF}, // Azalea Town - {14, 0x3FF_3FF}, // Ilex Forest - {15, 0x100_2FF}, // Route 34 - {18, 0x099_3FF}, // Route 35 - {20, 0x3FF_3FF}, // Route 36 - {21, 0x2F6_3FF}, // Route 37 - {25, 0x3FF_3FF}, // Route 38 - {26, 0x188_3FF}, // Route 39 - {34, 0x3FE_3FF}, // Route 42 - {37, 0x3B7_3FF}, // Route 43 - {38, 0x3FF_3FF}, // Lake of Rage - {39, 0x2FF_3FF}, // Route 44 - {91, 0x300_3FF}, // Route 26 - {92, 0x1FE_3FF}, // Route 27 - }; - internal static readonly EncounterStatic2[] StaticGSC = Encounter_GSC; internal static readonly EncounterStatic2[] StaticGS = Encounter_GS; internal static readonly EncounterStatic2[] StaticC = Encounter_C; diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot/EncounterSlot2.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot/EncounterSlot2.cs index ae1523078..ac0ed9ff8 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterSlot/EncounterSlot2.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterSlot/EncounterSlot2.cs @@ -1,4 +1,6 @@ -namespace PKHeX.Core +using System.Collections.Generic; + +namespace PKHeX.Core { /// /// Encounter Slot found in . @@ -22,8 +24,52 @@ protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteri base.ApplyDetails(sav, criteria, pk); var pk2 = (PK2)pk; + + if ((Area.Type & SlotType.Headbutt) != 0) + { + while (!IsTreeAvailable(pk2.TID)) + pk2.TID = Util.Rand.Next(ushort.MaxValue); + } + if (Version == GameVersion.C) pk2.Met_TimeOfDay = ((EncounterArea2)Area).Time.RandomValidTime(); } + + private static readonly Dictionary Trees = new() + { + { 02, 0x3FF_3FF }, // Route 29 + { 04, 0x39D_3FF }, // Route 30 + { 05, 0x13D_3FF }, // Route 31 + { 08, 0x2FF_3FF }, // Route 32 + { 11, 0x009_3FF }, // Route 33 + { 12, 0x3DF_3FF }, // Azalea Town + { 14, 0x3FF_3FF }, // Ilex Forest + { 15, 0x100_2FF }, // Route 34 + { 18, 0x099_3FF }, // Route 35 + { 20, 0x3FF_3FF }, // Route 36 + { 21, 0x2F6_3FF }, // Route 37 + { 25, 0x3FF_3FF }, // Route 38 + { 26, 0x188_3FF }, // Route 39 + { 34, 0x3FE_3FF }, // Route 42 + { 37, 0x3B7_3FF }, // Route 43 + { 38, 0x3FF_3FF }, // Lake of Rage + { 39, 0x2FF_3FF }, // Route 44 + { 91, 0x300_3FF }, // Route 26 + { 92, 0x1FE_3FF }, // Route 27 + }; + + internal bool IsTreeAvailable(int trainerID) + { + if (!Trees.TryGetValue(Location, out var permissions)) + return false; + + var pivot = trainerID % 10; + var type = Area.Type; + return type switch + { + SlotType.Headbutt => (permissions & (1 << pivot)) != 0, + /*special*/ _ => (permissions & (1 << (pivot + 12))) != 0, + }; + } } } diff --git a/PKHeX.Core/Legality/Encounters/Generator/Moveset/EncounterMovesetGenerator.cs b/PKHeX.Core/Legality/Encounters/Generator/Moveset/EncounterMovesetGenerator.cs index 86ab9f80d..1e8f6be0f 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/Moveset/EncounterMovesetGenerator.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/Moveset/EncounterMovesetGenerator.cs @@ -356,7 +356,7 @@ private static IEnumerable GetSlots(PKM pk, IReadOnlyList ne var slots = EncounterSlotGenerator.GetPossible(pk, chain); foreach (var slot in slots) { - if (slot.IsUnobtainable(pk)) + if (slot.IsUnobtainable()) continue; if (needs.Count == 0) @@ -374,14 +374,10 @@ private static IEnumerable GetSlots(PKM pk, IReadOnlyList ne } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool IsUnobtainable(this EncounterSlot slot, ITrainerID pk) + private static bool IsUnobtainable(this EncounterSlot slot) { switch (slot.Generation) { - case 2: - if ((slot.Area.Type & SlotType.Headbutt) != 0) // Unreachable Headbutt Trees. - return !Encounters2.IsTreeAvailable(slot, pk.TID); - break; case 4: if (slot.Location == 193 && slot.Area.Type == SlotType.Surf) // Johto Route 45 surfing encounter. Unreachable Water tiles. return true; diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/EncounterVerifier.cs b/PKHeX.Core/Legality/Encounters/Verifiers/EncounterVerifier.cs index 30f9659c5..80d133713 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/EncounterVerifier.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/EncounterVerifier.cs @@ -46,14 +46,6 @@ private static CheckResult VerifyEncounterG12(PKM pkm, LegalInfo info) // Gen2 Wild Encounters private static CheckResult VerifyWildEncounterGen2(PKM pkm, EncounterSlot2 encounter) - { - if (encounter.Version == GameVersion.C) - return VerifyWildEncounterCrystal(pkm, encounter); - - return new CheckResult(Severity.Valid, LEncCondition, CheckIdentifier.Encounter); - } - - private static CheckResult VerifyWildEncounterCrystal(PKM pkm, EncounterSlot encounter) { switch (encounter.Area.Type) { @@ -74,9 +66,9 @@ private static CheckResult VerifyWildEncounterCrystal(PKM pkm, EncounterSlot enc return new CheckResult(Severity.Valid, LEncCondition, CheckIdentifier.Encounter); } - private static CheckResult VerifyWildEncounterCrystalHeadbutt(ITrainerID tr, EncounterSlot encounter) + private static CheckResult VerifyWildEncounterCrystalHeadbutt(ITrainerID tr, EncounterSlot2 s2) { - return Encounters2.IsTreeAvailable(encounter, tr.TID) + return s2.IsTreeAvailable(tr.TID) ? new CheckResult(Severity.Valid, LG2TreeID, CheckIdentifier.Encounter) : new CheckResult(Severity.Invalid, LG2InvalidTileTreeNotFound, CheckIdentifier.Encounter); }