From 62bf1c275548cd9da939ef9de80386ca133cf84d Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 30 Jan 2021 19:15:39 -0800 Subject: [PATCH] Add stubs for verifying memories regarding items Not implementing these, but at least setting up a clean area for anyone else to implement the logic --- PKHeX.Core/Game/GameStrings/MemoryStrings.cs | 2 +- PKHeX.Core/Legality/Restrictions/Memories.cs | 22 +++ .../Legality/Verifiers/MemoryPermissions.cs | 133 ++++++++++++++++++ .../Legality/Verifiers/MemoryVerifier.cs | 103 ++------------ 4 files changed, 169 insertions(+), 91 deletions(-) create mode 100644 PKHeX.Core/Legality/Verifiers/MemoryPermissions.cs diff --git a/PKHeX.Core/Game/GameStrings/MemoryStrings.cs b/PKHeX.Core/Game/GameStrings/MemoryStrings.cs index 88778a1ee..d4e7d5815 100644 --- a/PKHeX.Core/Game/GameStrings/MemoryStrings.cs +++ b/PKHeX.Core/Game/GameStrings/MemoryStrings.cs @@ -22,7 +22,7 @@ public MemoryStrings(GameStrings strings, int format) private List GetItems(int format) { - var permit = format < 8 ? Legal.HeldItem_AO : Legal.HeldItem_AO.Concat(Legal.HeldItems_SWSH).Distinct(); + var permit = Memories.GetMemoryItemParams(format); var asInt = permit.Select(z => (int) z).ToArray(); return Util.GetCBList(s.itemlist, asInt); } diff --git a/PKHeX.Core/Legality/Restrictions/Memories.cs b/PKHeX.Core/Legality/Restrictions/Memories.cs index c79caf0c0..459d32555 100644 --- a/PKHeX.Core/Legality/Restrictions/Memories.cs +++ b/PKHeX.Core/Legality/Restrictions/Memories.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; namespace PKHeX.Core { @@ -155,6 +156,16 @@ public static bool GetHasPokeCenterLocation(GameVersion game, int loc) private static readonly HashSet MemoryItem = new() { 5, 15, 26, 34, 40, 51, 84, 88 }; private static readonly HashSet MemorySpecies = new() { 7, 9, 13, 14, 17, 21, 18, 25, 29, 44, 45, 50, 60, 70, 71, 72, 75, 82, 83, 87 }; + private static readonly Dictionary KeyItemMemoryArgs = new() + { + {(int) Species.Rotom, new ushort[] {1278}}, // Rotom Catalog + {(int) Species.Kyurem, new ushort[] {628, 629}}, // DNA Splicers + {(int) Species.Necrozma, new ushort[] {943, 944, 945, 946}}, // N-Lunarizer / N-Solarizer + {(int) Species.Calyrex, new ushort[] {1590, 1591}}, // Reigns of Unity + }; + + public static IEnumerable KeyItemArgValues => KeyItemMemoryArgs.Values.SelectMany(z => z); + public static MemoryArgType GetMemoryArgType(int memory, int format) { if (MemoryGeneral.Contains(memory)) return MemoryArgType.GeneralLocation; @@ -198,6 +209,17 @@ public static int GetMinimumIntensity(int memory) return -1; return MemoryMinIntensity[memory]; } + + public static IEnumerable GetMemoryItemParams(int format) + { + return format switch + { + 6 or 7 => Legal.HeldItem_AO.Distinct().Concat(KeyItemArgValues).Where(z => z < Legal.MaxItemID_6_AO), + 8 => Legal.HeldItem_AO.Concat(Legal.HeldItems_SWSH).Distinct().Concat(KeyItemArgValues) + .Where(z => z < Legal.MaxItemID_8_R2), + _ => System.Array.Empty(), + }; + } } public readonly struct MemoryVariableSet diff --git a/PKHeX.Core/Legality/Verifiers/MemoryPermissions.cs b/PKHeX.Core/Legality/Verifiers/MemoryPermissions.cs new file mode 100644 index 000000000..8fa271ee0 --- /dev/null +++ b/PKHeX.Core/Legality/Verifiers/MemoryPermissions.cs @@ -0,0 +1,133 @@ +using System.Collections.Generic; +using System.Linq; + +using static PKHeX.Core.Encounters6; +using static PKHeX.Core.Encounters8; +using static PKHeX.Core.Move; +using static PKHeX.Core.Species; + +namespace PKHeX.Core +{ + /// + /// Validation logic for specific memory conditions + /// + public static class MemoryPermissions + { + public static bool CanWinRotoLoto(int generation, int item) + { + return true; // todo + } + + public static bool CanHoldItem(int generation, int item) + { + return true; // todo + } + + public static bool CanPlantBerry(int generation, int item) + { + return true; // todo + } + + public static bool CanUseItemGeneric(int generation, int item) + { + return true; // todo + } + + public static bool CanUseItem(int generation, int item, int species) + { + return true; // todo + } + + public static bool CanBuyItem(int generation, int item) + { + return true; // todo + } + + public static bool CanKnowMove(PKM pkm, MemoryVariableSet memory, int gen, LegalInfo info, bool battleOnly = false) + { + var move = memory.Variable; + if (move == 0) + return false; + + if (pkm.HasMove(move)) + return true; + + if (pkm.IsEgg) + return false; + + if (Legal.GetCanKnowMove(pkm, memory.Variable, gen, info.EvoChainsAllGens)) + return true; + + var enc = info.EncounterMatch; + if (enc is IMoveset ms && ms.Moves.Contains(move)) + return true; + + if (battleOnly) + { + // Some moves can only be known in battle; outside of battle they aren't obtainable as a memory parameter. + switch (move) + { + case (int)BehemothBlade when pkm.Species == (int)Zacian: + case (int)BehemothBash when pkm.Species == (int)Zamazenta: + return true; + } + } + + return false; + } + + public static bool GetCanBeCaptured(int species, int gen, GameVersion version) + { + switch (gen) + { + // Capture Memory only obtainable via Gen 6. + case 6: + switch (version) + { + case GameVersion.Any: + return Legal.FriendSafari.Contains(species) + || GetCanBeCaptured(species, SlotsX, StaticX) + || GetCanBeCaptured(species, SlotsY, StaticY) + || GetCanBeCaptured(species, SlotsA, StaticA) + || GetCanBeCaptured(species, SlotsO, StaticO); + case GameVersion.X: + return Legal.FriendSafari.Contains(species) + || GetCanBeCaptured(species, SlotsX, StaticX); + case GameVersion.Y: + return Legal.FriendSafari.Contains(species) + || GetCanBeCaptured(species, SlotsY, StaticY); + + case GameVersion.AS: + return GetCanBeCaptured(species, SlotsA, StaticA); + case GameVersion.OR: + return GetCanBeCaptured(species, SlotsO, StaticO); + } + break; + + case 8: + { + switch (version) + { + case GameVersion.Any: + return GetCanBeCaptured(species, SlotsSW.Concat(SlotsSH), StaticSW.Concat(StaticSH)); + case GameVersion.SW: + return GetCanBeCaptured(species, SlotsSW, StaticSW); + case GameVersion.SH: + return GetCanBeCaptured(species, SlotsSH, StaticSH); + } + break; + } + } + return false; + } + + private static bool GetCanBeCaptured(int species, IEnumerable area, IEnumerable statics) + { + if (area.Any(loc => loc.Slots.Any(slot => slot.Species == species))) + return true; + if (statics.Any(enc => enc.Species == species && !enc.Gift)) + return true; + return false; + } + } +} diff --git a/PKHeX.Core/Legality/Verifiers/MemoryVerifier.cs b/PKHeX.Core/Legality/Verifiers/MemoryVerifier.cs index 3780b7719..7a299955d 100644 --- a/PKHeX.Core/Legality/Verifiers/MemoryVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/MemoryVerifier.cs @@ -1,9 +1,7 @@ using System; -using System.Collections.Generic; using System.Linq; using static PKHeX.Core.LegalityCheckStrings; -using static PKHeX.Core.Encounters6; -using static PKHeX.Core.Encounters8; +using static PKHeX.Core.MemoryPermissions; namespace PKHeX.Core { @@ -66,6 +64,18 @@ private CheckResult VerifyCommonMemory(PKM pkm, int handler, int gen, LegalInfo return GetInvalid(string.Format(LMemoryArgBadSpecies, handler == 0 ? L_XOT : L_XHT)); // Item + // {0} went to a Pokémon Center with {1} to buy {2}. {4} that {3}. + case 5 when !CanBuyItem(gen, memory.Variable): + // {1} used {2} when {0} was in trouble. {4} that {3}. + case 15 when !CanUseItem(gen, memory.Variable, pkm.Species): + // {0} saw {1} using {2}. {4} that {3}. + case 26 when !CanUseItemGeneric(gen, memory.Variable): + // {0} planted {2} with {1} and imagined a big harvest. {4} that {3}. + case 34 when !CanPlantBerry(gen, memory.Variable): + // {1} had {0} hold items like {2} to help it along. {4} that {3}. + case 40 when !CanHoldItem(gen, memory.Variable): + // {0} was excited when {1} won prizes like {2} through Loto-ID. {4} that {3}. + case 51 when !CanWinRotoLoto(gen, memory.Variable): // {0} was worried if {1} was looking for the {2} that it was holding in a Box. {4} that {3}. // When {0} was in a Box, it thought about the reason why {1} had it hold the {2}. {4} that {3}. case 84 or 88 when !Legal.HeldItems_SWSH.Contains((ushort)memory.Variable) || pkm.IsEgg: @@ -87,39 +97,6 @@ private CheckResult VerifyCommonMemory(PKM pkm, int handler, int gen, LegalInfo return GetValid(string.Format(LMemoryF_0_Valid, memory.Handler)); } - private static bool CanKnowMove(PKM pkm, MemoryVariableSet memory, int gen, LegalInfo info, bool battleOnly = false) - { - var move = memory.Variable; - if (move == 0) - return false; - - if (pkm.HasMove(move)) - return true; - - if (pkm.IsEgg) - return false; - - if (Legal.GetCanKnowMove(pkm, memory.Variable, gen, info.EvoChainsAllGens)) - return true; - - var enc = info.EncounterMatch; - if (enc is IMoveset ms && ms.Moves.Contains(move)) - return true; - - if (battleOnly) - { - // Some moves can only be known in battle; outside of battle they aren't obtainable as a memory parameter. - switch (move) - { - case 781 when pkm.Species == (int)Species.Zacian: // Behemoth Blade - case 782 when pkm.Species == (int)Species.Zamazenta: // Behemoth Blade - return true; - } - } - - return false; - } - /// /// Used for enforcing a fixed memory detail. /// @@ -365,59 +342,5 @@ private void VerifyHTMemoryTransferTo7(LegalityAnalysis data, PKM pkm, LegalInfo if (mem.HT_Feeling > 10) data.AddLine(Severity.Invalid, LMemoryIndexFeelHT09, CheckIdentifier.Memory); } - - private static bool GetCanBeCaptured(int species, int gen, GameVersion version) - { - switch (gen) - { - // Capture Memory only obtainable via Gen 6. - case 6: - switch (version) - { - case GameVersion.Any: - return Legal.FriendSafari.Contains(species) - || GetCanBeCaptured(species, SlotsX, StaticX) - || GetCanBeCaptured(species, SlotsY, StaticY) - || GetCanBeCaptured(species, SlotsA, StaticA) - || GetCanBeCaptured(species, SlotsO, StaticO); - case GameVersion.X: - return Legal.FriendSafari.Contains(species) - || GetCanBeCaptured(species, SlotsX, StaticX); - case GameVersion.Y: - return Legal.FriendSafari.Contains(species) - || GetCanBeCaptured(species, SlotsY, StaticY); - - case GameVersion.AS: - return GetCanBeCaptured(species, SlotsA, StaticA); - case GameVersion.OR: - return GetCanBeCaptured(species, SlotsO, StaticO); - } - break; - - case 8: - { - switch (version) - { - case GameVersion.Any: - return GetCanBeCaptured(species, SlotsSW.Concat(SlotsSH), StaticSW.Concat(StaticSH)); - case GameVersion.SW: - return GetCanBeCaptured(species, SlotsSW, StaticSW); - case GameVersion.SH: - return GetCanBeCaptured(species, SlotsSH, StaticSH); - } - break; - } - } - return false; - } - - private static bool GetCanBeCaptured(int species, IEnumerable area, IEnumerable statics) - { - if (area.Any(loc => loc.Slots.Any(slot => slot.Species == species))) - return true; - if (statics.Any(enc => enc.Species == species && !enc.Gift)) - return true; - return false; - } } }