From 13e0f35e0052d76e6f5b6f7746d299100e110b61 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 25 Dec 2021 13:48:28 -0800 Subject: [PATCH] Add munchlax slot checking for DPPt/BDSP honey trees Closes #3352 --- PKHeX.Core/Legality/Areas/EncounterArea4.cs | 49 ++++++++++++++++++- PKHeX.Core/Legality/Areas/EncounterArea8b.cs | 44 +++++++++++++++++ PKHeX.Core/Saves/SAV4Sinnoh.cs | 13 +++-- .../Save Editors/Gen4/SAV_HoneyTree.cs | 2 +- 4 files changed, 101 insertions(+), 7 deletions(-) diff --git a/PKHeX.Core/Legality/Areas/EncounterArea4.cs b/PKHeX.Core/Legality/Areas/EncounterArea4.cs index 6e29de5bc..58b22694a 100644 --- a/PKHeX.Core/Legality/Areas/EncounterArea4.cs +++ b/PKHeX.Core/Legality/Areas/EncounterArea4.cs @@ -65,10 +65,10 @@ namespace PKHeX.Core return GetSlotsFuzzy(chain); if (pkm.Met_Location != Location) return Array.Empty(); - return GetSlotsMatching(chain, pkm.Met_Level); + return GetSlotsMatching(chain, pkm.Met_Level, pkm); } - private IEnumerable GetSlotsMatching(IReadOnlyList chain, int lvl) + private IEnumerable GetSlotsMatching(IReadOnlyList chain, int lvl, PKM pk) { foreach (var slot in Slots) { @@ -86,12 +86,57 @@ namespace PKHeX.Core if (!slot.IsLevelWithinRange(lvl)) break; + if (Type is SlotType.HoneyTree && IsInaccessibleHoneySlotLocation(slot, pk)) + break; + yield return slot; break; } } } + private static bool IsInaccessibleHoneySlotLocation(EncounterSlot4 slot, PKM pk) + { + // A/B/C tables, only Munchlax is a 'C' encounter, and A/B are accessible from any tree. + // C table encounters are only available from 4 trees, which are determined by TID/SID of the save file. + if (slot.Species is not (int)Species.Munchlax) + return false; + + // We didn't encode the honey tree index to the encounter slot resource. + // Check if any of the slot's location doesn't match any of the groupC trees' area location ID. + var location = pk.Met_Location; + var trees = SAV4Sinnoh.CalculateMunchlaxTrees(pk.TID, pk.SID); + return LocationID_HoneyTree[trees.Tree1] != location + && LocationID_HoneyTree[trees.Tree2] != location + && LocationID_HoneyTree[trees.Tree3] != location + && LocationID_HoneyTree[trees.Tree4] != location; + } + + private static readonly byte[] LocationID_HoneyTree = + { + 20, // 00 Route 205 Floaroma + 20, // 01 Route 205 Eterna + 21, // 02 Route 206 + 22, // 03 Route 207 + 23, // 04 Route 208 + 24, // 05 Route 209 + 25, // 06 Route 210 Solaceon + 25, // 07 Route 210 Celestic + 26, // 08 Route 211 + 27, // 09 Route 212 Hearthome + 27, // 10 Route 212 Pastoria + 28, // 11 Route 213 + 29, // 12 Route 214 + 30, // 13 Route 215 + 33, // 14 Route 218 + 36, // 15 Route 221 + 37, // 16 Route 222 + 47, // 17 Valley Windworks + 48, // 18 Eterna Forest + 49, // 19 Fuego Ironworks + 58, // 20 Floaroma Meadow + }; + // original met level cannot be inferred private IEnumerable GetSlotsFuzzy(IReadOnlyList chain) { diff --git a/PKHeX.Core/Legality/Areas/EncounterArea8b.cs b/PKHeX.Core/Legality/Areas/EncounterArea8b.cs index 0dc0c7c48..56c2e228b 100644 --- a/PKHeX.Core/Legality/Areas/EncounterArea8b.cs +++ b/PKHeX.Core/Legality/Areas/EncounterArea8b.cs @@ -89,10 +89,54 @@ namespace PKHeX.Core if (slot.Form != evo.Form && slot.Species is not (int)Species.Burmy) break; + if (Type is SlotType.HoneyTree && IsInaccessibleHoneySlotLocation(slot, pkm)) + break; + yield return slot; break; } } } + private static bool IsInaccessibleHoneySlotLocation(EncounterSlot8b slot, PKM pk) + { + // A/B/C tables, only Munchlax is a 'C' encounter, and A/B are accessible from any tree. + // C table encounters are only available from 4 trees, which are determined by TID/SID of the save file. + if (slot.Species is not (int)Species.Munchlax) + return false; + + // We didn't encode the honey tree index to the encounter slot resource. + // Check if any of the slot's location doesn't match any of the groupC trees' area location ID. + var location = pk.Met_Location; + var trees = SAV4Sinnoh.CalculateMunchlaxTrees(pk.TID, pk.SID); + return LocationID_HoneyTree[trees.Tree1] != location + && LocationID_HoneyTree[trees.Tree2] != location + && LocationID_HoneyTree[trees.Tree3] != location + && LocationID_HoneyTree[trees.Tree4] != location; + } + + private static readonly ushort[] LocationID_HoneyTree = + { + 359, // 00 Route 205 Floaroma + 361, // 01 Route 205 Eterna + 362, // 02 Route 206 + 364, // 03 Route 207 + 365, // 04 Route 208 + 367, // 05 Route 209 + 373, // 06 Route 210 Solaceon + 375, // 07 Route 210 Celestic + 378, // 08 Route 211 + 379, // 09 Route 212 Hearthome + 383, // 10 Route 212 Pastoria + 385, // 11 Route 213 + 392, // 12 Route 214 + 394, // 13 Route 215 + 400, // 14 Route 218 + 404, // 15 Route 221 + 407, // 16 Route 222 + 197, // 17 Valley Windworks + 199, // 18 Eterna Forest + 201, // 19 Fuego Ironworks + 253, // 20 Floaroma Meadow + }; } } diff --git a/PKHeX.Core/Saves/SAV4Sinnoh.cs b/PKHeX.Core/Saves/SAV4Sinnoh.cs index 3a538ecbe..82568b306 100644 --- a/PKHeX.Core/Saves/SAV4Sinnoh.cs +++ b/PKHeX.Core/Saves/SAV4Sinnoh.cs @@ -129,9 +129,9 @@ namespace PKHeX.Core SetData(General, tree.Data, OFS_HONEY + (HONEY_SIZE * index)); } - public int[] GetMunchlaxTrees() => CalculateMunchlaxTrees(TID, SID); + public MunchlaxTreeSet4 GetMunchlaxTrees() => CalculateMunchlaxTrees(TID, SID); - private static int[] CalculateMunchlaxTrees(int tid, int sid) + public static MunchlaxTreeSet4 CalculateMunchlaxTrees(int tid, int sid) { int A = (tid >> 8) % 21; int B = (tid & 0x00FF) % 21; @@ -145,7 +145,7 @@ namespace PKHeX.Core if (B == D) D = (D + 1) % 21; if (C == D) D = (D + 1) % 21; - return new[] {A, B, C, D}; + return new(A, B, C, D); } #endregion @@ -228,4 +228,9 @@ namespace PKHeX.Core Stopwatch, Alarm_Clock, } -} \ No newline at end of file + + public readonly record struct MunchlaxTreeSet4(int Tree1, int Tree2, int Tree3, int Tree4) + { + public int[] ToArray() => new[] { Tree1, Tree2, Tree3, Tree4 }; + } +} diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_HoneyTree.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_HoneyTree.cs index e3f473d3b..77aa092a7 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_HoneyTree.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_HoneyTree.cs @@ -24,7 +24,7 @@ namespace PKHeX.WinForms }; // Get Munchlax tree for this savegame in screen - MunchlaxTrees = SAV.GetMunchlaxTrees(); + MunchlaxTrees = SAV.GetMunchlaxTrees().ToArray(); const string sep = "- "; L_Tree0.Text = string.Join(Environment.NewLine, MunchlaxTrees.Select(z => sep + CB_TreeList.Items[z]));