private CheckResult VerifyCommonMemory(PKM pkm, int handler, int gen) { var memory = MemoryVariableSet.Read(pkm, handler); // Actionable HM moves int matchingMoveMemory = Array.IndexOf(Memories.MoveSpecificMemories[0], memory.MemoryID); if (matchingMoveMemory != -1) { // Gen8 has no HMs, so this memory can never exist. if (gen != 6 || (pkm.Species != (int)Species.Smeargle && !Legal.GetCanLearnMachineMove(pkm, Memories.MoveSpecificMemories[1][matchingMoveMemory], 6))) { return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); } } switch (memory.MemoryID) { // {0} saw {2} carrying {1} on its back. {4} that {3}. case 21 when gen != 6 || !Legal.GetCanLearnMachineMove(new PK6 { Species = memory.Variable, EXP = Experience.GetEXP(100, PersonalTable.XY.GetFormeIndex(memory.Variable, 0)) }, 19, 6): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); case 16 when memory.Variable == 0 && !GetIsMoveKnowable(pkm, gen, memory.Variable): case 48 when memory.Variable == 0 && !GetIsMoveKnowable(pkm, gen, memory.Variable): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); // {0} was able to remember {2} at {1}'s instruction. {4} that {3}. case 49 when memory.Variable == 0 && !GetIsMoveLearnable(pkm, gen, memory.Variable): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); } if (gen == 6 && !Memories.CanHaveIntensity(memory.MemoryID, memory.Intensity)) { if (pkm.Gen6 || (pkm.Gen7 && memory.MemoryID != 0)) // todo: memory intensity checks for gen8 { return(GetInvalid(string.Format(LMemoryIndexIntensityMin, memory.Handler, Memories.GetMinimumIntensity(memory.MemoryID)))); } } if (gen == 6 && memory.MemoryID != 4 && !Memories.CanHaveFeeling(memory.MemoryID, memory.Feeling)) { if (pkm.Gen6 || (pkm.Gen7 && memory.MemoryID != 0)) // todo: memory feeling checks for gen8 { return(GetInvalid(string.Format(LMemoryFeelInvalid, memory.Handler))); } } return(GetValid(string.Format(LMemoryF_0_Valid, memory.Handler))); }
/// <summary> /// Gets the minimum Experience points for the specified level. /// </summary> /// <param name="level">Current level</param> /// <param name="species">National Dex number of the Pokémon.</param> /// <param name="forme">AltForm ID (starters in Let's Go)</param> /// <returns>Experience points needed to have specified level.</returns> public static uint GetEXP(int level, int species, int forme) { return(Experience.GetEXP(level, species, forme)); }
public override void Verify(LegalityAnalysis data) { var pkm = data.pkm; if (pkm is IAwakened a) { VerifyAwakenedValues(data, a); return; } var enc = data.EncounterMatch; int sum = pkm.EVTotal; if (sum > 0 && pkm.IsEgg) { data.AddLine(GetInvalid(LEffortEgg)); } // In Generations I and II, when a Pokémon is taken out of the Day Care, its experience will lower to the minimum value for its current level. int format = pkm.Format; if (format < 3) // can abuse daycare for EV training without EXP gain { return; } if (sum > 510) // format >= 3 { data.AddLine(GetInvalid(LEffortAbove510)); } var evs = pkm.EVs; if (format >= 6 && evs.Any(ev => ev > 252)) { data.AddLine(GetInvalid(LEffortAbove252)); } const int vitaMax = 100; // Vitamin Max if (format < 5) // 3/4 { if (enc.LevelMin == 100) // only true for Gen4 and Format=4 { // Cannot EV train at level 100 -- Certain events are distributed at level 100. if (evs.Any(ev => ev > vitaMax)) // EVs can only be increased by vitamins to a max of 100. { data.AddLine(GetInvalid(LEffortCap100)); } } else // check for gained EVs without gaining EXP -- don't check gen5+ which have wings to boost above 100. { var growth = PersonalTable.HGSS[enc.Species].EXPGrowth; var baseEXP = Experience.GetEXP(enc.LevelMin, growth); if (baseEXP == pkm.EXP && evs.Any(ev => ev > vitaMax)) { data.AddLine(GetInvalid(string.Format(LEffortUntrainedCap, vitaMax))); } } } // Only one of the following can be true: 0, 508, and x%6!=0 if (sum == 0 && !enc.IsWithinRange(pkm)) { data.AddLine(Get(LEffortEXPIncreased, Severity.Fishy)); } else if (sum == 508) { data.AddLine(Get(LEffort2Remaining, Severity.Fishy)); } else if (evs[0] != 0 && evs.All(ev => evs[0] == ev)) { data.AddLine(Get(LEffortAllEqual, Severity.Fishy)); } }
private CheckResult VerifyCommonMemory(PKM pkm, int handler, int gen, LegalInfo info) { var memory = MemoryVariableSet.Read((ITrainerMemories)pkm, handler); // Actionable HM moves int matchingMoveMemory = Array.IndexOf(Memories.MoveSpecificMemories[0], memory.MemoryID); if (matchingMoveMemory != -1) { // Gen8 has no HMs, so this memory can never exist. if (gen != 6 || (pkm.Species != (int)Species.Smeargle && !Legal.GetCanLearnMachineMove(pkm, Memories.MoveSpecificMemories[1][matchingMoveMemory], 6))) { return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); } } switch (memory.MemoryID) { // {0} saw {2} carrying {1} on its back. {4} that {3}. case 21 when gen != 6 || !Legal.GetCanLearnMachineMove(new PK6 { Species = memory.Variable, EXP = Experience.GetEXP(100, PersonalTable.XY.GetFormIndex(memory.Variable, 0)) }, 19, 6): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); case 16 or 48 when !CanKnowMove(pkm, memory, gen, info, memory.MemoryID == 16): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); case 49 when memory.Variable == 0 || !Legal.GetCanRelearnMove(pkm, memory.Variable, gen, info.EvoChainsAllGens[gen]): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); // Dynamaxing // {0} battled at {1}’s side against {2} that Dynamaxed. {4} that {3}. case 71 when !GetCanBeCaptured(memory.Variable, 8, handler == 0 ? (GameVersion)pkm.Version : GameVersion.Any): // {0} battled {2} and Dynamaxed upon {1}’s instruction. {4} that {3}. case 72 when !((PersonalInfoSWSH)PersonalTable.SWSH[memory.Variable]).IsPresentInGame: return(GetInvalid(string.Format(LMemoryArgBadSpecies, handler == 0 ? L_XOT : L_XHT))); // Move // {0} studied about how to use {2} in a Box, thinking about {1}. {4} that {3}. // {0} practiced its cool pose for the move {2} in a Box, wishing to be praised by {1}. {4} that {3}. case 80 or 81 when !CanKnowMove(pkm, memory, gen, info): return(Get(string.Format(LMemoryArgBadMove, memory.Handler), gen == 8 ? Severity.Fishy : Severity.Invalid)); // Species // {0} had a great chat about {1} with the {2} that it was in a Box with. {4} that {3}. // {0} became good friends with the {2} in a Box, practiced moves with it, and talked about the day that {0} would be praised by {1}. {4} that {3}. // {0} got in a fight with the {2} that it was in a Box with about {1}. {4} that {3}. case 82 or 83 or 87 when !((PersonalInfoSWSH)PersonalTable.SWSH[memory.Variable]).IsPresentInGame: 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: return(GetInvalid(string.Format(LMemoryArgBadItem, memory.Handler))); } if (gen == 6 && !Memories.CanHaveIntensity(memory.MemoryID, memory.Intensity)) { if (pkm.Gen6 || (pkm.Gen7 && memory.MemoryID != 0)) // todo: memory intensity checks for gen8 { return(GetInvalid(string.Format(LMemoryIndexIntensityMin, memory.Handler, Memories.GetMinimumIntensity(memory.MemoryID)))); } } if (gen == 6 && memory.MemoryID != 4 && !Memories.CanHaveFeeling(memory.MemoryID, memory.Feeling)) { if (pkm.Gen6 || (pkm.Gen7 && memory.MemoryID != 0)) // todo: memory feeling checks for gen8 { return(GetInvalid(string.Format(LMemoryFeelInvalid, memory.Handler))); } } return(GetValid(string.Format(LMemoryF_0_Valid, memory.Handler))); }
public override void Verify(LegalityAnalysis data) { var pkm = data.pkm; var EncounterMatch = data.EncounterOriginal; if (EncounterMatch is MysteryGift gift) { if (gift.Level != pkm.Met_Level && pkm.HasOriginalMetLocation) { switch (gift) { case WC3 wc3 when wc3.Met_Level == pkm.Met_Level || wc3.IsEgg: break; case WC7 wc7 when wc7.MetLevel == pkm.Met_Level: break; default: data.AddLine(GetInvalid(LLevelMetGift)); return; } } if (gift.Level > pkm.CurrentLevel) { data.AddLine(GetInvalid(LLevelMetGiftFail)); return; } } if (pkm.IsEgg) { int elvl = Legal.GetEggHatchLevel(pkm); if (elvl != pkm.CurrentLevel) { data.AddLine(GetInvalid(string.Format(LEggFMetLevel_0, elvl))); return; } var reqEXP = EncounterMatch is EncounterStatic s && s.Version == GameVersion.C ? 125 // Gen2 Dizzy Punch gifts always have 125 EXP, even if it's more than the Lv5 exp required. : Experience.GetEXP(elvl, pkm.Species, pkm.AltForm); if (reqEXP != pkm.EXP) { data.AddLine(GetInvalid(LEggEXP)); } return; } int lvl = pkm.CurrentLevel; if (lvl < pkm.Met_Level) { data.AddLine(GetInvalid(LLevelMetBelow)); } else if (!EncounterMatch.IsWithinRange(pkm) && lvl != 100 && pkm.EXP == Experience.GetEXP(lvl, pkm.Species, pkm.AltForm)) { data.AddLine(Get(LLevelEXPThreshold, Severity.Fishy)); } else { data.AddLine(GetValid(LLevelMetSane)); } }
public override void Verify(LegalityAnalysis data) { var pkm = data.pkm; var enc = data.EncounterOriginal; if (enc is MysteryGift gift) { if (gift.Level != pkm.Met_Level && pkm.HasOriginalMetLocation) { switch (gift) { case WC3 wc3 when wc3.Met_Level == pkm.Met_Level || wc3.IsEgg: break; case WC7 wc7 when wc7.MetLevel == pkm.Met_Level: break; case PGT { IsManaphyEgg: true } when pkm.Met_Level == 0 : break; default: data.AddLine(GetInvalid(LLevelMetGift)); return; } } if (gift.Level > pkm.CurrentLevel) { data.AddLine(GetInvalid(LLevelMetGiftFail)); return; } } if (pkm.IsEgg) { int elvl = enc.LevelMin; if (elvl != pkm.CurrentLevel) { data.AddLine(GetInvalid(string.Format(LEggFMetLevel_0, elvl))); return; } var reqEXP = enc is EncounterStatic2Odd ? 125 // Gen2 Dizzy Punch gifts always have 125 EXP, even if it's more than the Lv5 exp required. : Experience.GetEXP(elvl, pkm.PersonalInfo.EXPGrowth); if (reqEXP != pkm.EXP) { data.AddLine(GetInvalid(LEggEXP)); } return; } int lvl = pkm.CurrentLevel; if (lvl >= 100) { var expect = Experience.GetEXP(100, pkm.PersonalInfo.EXPGrowth); if (pkm.EXP != expect) { data.AddLine(GetInvalid(LLevelEXPTooHigh)); } } if (lvl < pkm.Met_Level) { data.AddLine(GetInvalid(LLevelMetBelow)); } else if (!enc.IsWithinEncounterRange(pkm) && lvl != 100 && pkm.EXP == Experience.GetEXP(lvl, pkm.PersonalInfo.EXPGrowth)) { data.AddLine(Get(LLevelEXPThreshold, Severity.Fishy)); } else { data.AddLine(GetValid(LLevelMetSane)); } }
private CheckResult VerifyCommonMemory(PKM pkm, int handler, int gen, LegalInfo info, MemoryContext context) { var memory = MemoryVariableSet.Read((ITrainerMemories)pkm, handler); // Actionable HM moves int matchingMoveMemory = Array.IndexOf(MemoryContext6.MoveSpecificMemories[0], memory.MemoryID); if (matchingMoveMemory != -1) { if (gen != 6) // Gen8 has no HMs, so this memory can never exist. { return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); } if (pkm.Species != (int)Species.Smeargle) { if (!GetCanLearnMachineMove(pkm, info.EvoChainsAllGens[gen], MemoryContext6.MoveSpecificMemories[1][matchingMoveMemory], 6)) { return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); } } } if (context.IsInvalidGeneralLocationMemoryValue(memory.MemoryID, memory.Variable, info.EncounterMatch, pkm)) { return(GetInvalid(string.Format(LMemoryArgBadLocation, memory.Handler))); } switch (memory.MemoryID) { case 19 when pkm.Species is (int)Species.Urshifu && memory.Variable is not 34: // tall building is the only location for evolving Urshifu case 19 when pkm.Species is (int)Species.Runerigus && memory.Variable is not 72: // vast field is the only location for evolving Runerigus return(GetInvalid(string.Format(LMemoryArgBadLocation, memory.Handler))); // {0} saw {2} carrying {1} on its back. {4} that {3}. case 21 when gen != 6 || !GetCanLearnMachineMove(new PK6 { Species = memory.Variable, EXP = Experience.GetEXP(100, PersonalTable.XY.GetFormIndex(memory.Variable, 0)) }, (int)Move.Fly, 6): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); // {0} used {2} at {1}’s instruction, but it had no effect. {4} that {3}. // The Move Deleter that {0} met through {1} made it forget {2}. {4} that {3}. case 16 or 48 when !CanKnowMove(pkm, memory, gen, info, memory.MemoryID == 16): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); case 49 when memory.Variable == 0 || !GetCanRelearnMove(pkm, memory.Variable, gen, info.EvoChainsAllGens[gen]): return(GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler))); // Dynamaxing // {0} battled at {1}’s side against {2} that Dynamaxed. {4} that {3}. case 71 when !GetCanDynamaxTrainer(memory.Variable, 8, handler == 0 ? (GameVersion)pkm.Version : GameVersion.Any): // {0} battled {2} and Dynamaxed upon {1}’s instruction. {4} that {3}. case 72 when !((PersonalInfoSWSH)PersonalTable.SWSH[memory.Variable]).IsPresentInGame: return(GetInvalid(string.Format(LMemoryArgBadSpecies, memory.Handler))); // Move // {0} studied about how to use {2} in a Box, thinking about {1}. {4} that {3}. // {0} practiced its cool pose for the move {2} in a Box, wishing to be praised by {1}. {4} that {3}. case 80 or 81 when !CanKnowMove(pkm, memory, gen, info): return(Get(string.Format(LMemoryArgBadMove, memory.Handler), Severity.Invalid)); // Species // {0} had a great chat about {1} with the {2} that it was in a Box with. {4} that {3}. // {0} became good friends with the {2} in a Box, practiced moves with it, and talked about the day that {0} would be praised by {1}. {4} that {3}. // {0} got in a fight with the {2} that it was in a Box with about {1}. {4} that {3}. case 82 or 83 or 87 when !((PersonalInfoSWSH)PersonalTable.SWSH[memory.Variable]).IsPresentInGame: return(GetInvalid(string.Format(LMemoryArgBadSpecies, memory.Handler))); // Item // {0} went to a Pokémon Center with {1} to buy {2}. {4} that {3}. case 5 when !CanBuyItem(gen, memory.Variable, handler == 0 ? (GameVersion)pkm.Version : GameVersion.Any): // {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: return(GetInvalid(string.Format(LMemoryArgBadItem, memory.Handler))); } return(VerifyCommonMemoryEtc(memory, context)); }
public override void Verify(LegalityAnalysis data) { var pkm = data.pkm; if (pkm is IAwakened a) { VerifyAwakenedValues(data, a); return; } var EncounterMatch = data.EncounterMatch; var evs = pkm.EVs; int sum = pkm.EVTotal; if (sum > 0 && pkm.IsEgg) { data.AddLine(GetInvalid(LEffortEgg)); } if (pkm.Format >= 3 && sum > 510) { data.AddLine(GetInvalid(LEffortAbove510)); } if (pkm.Format >= 6 && evs.Any(ev => ev > 252)) { data.AddLine(GetInvalid(LEffortAbove252)); } if (pkm.Format == 4 && pkm.Gen4 && EncounterMatch.LevelMin == 100) { // Cannot EV train at level 100 -- Certain events are distributed at level 100. if (evs.Any(ev => ev > 100)) // EVs can only be increased by vitamins to a max of 100. { data.AddLine(GetInvalid(LEffortCap100)); } } else if (pkm.Format < 5) { // In Generations I and II, when a Pokémon is taken out of the Day Care, its experience will lower to the minimum value for its current level. if (pkm.Format < 3) // can abuse daycare for EV training without EXP gain { return; } const int maxEV = 100; // Vitamin Max if (Experience.GetEXP(EncounterMatch.LevelMin, pkm.Species, pkm.AltForm) == pkm.EXP && evs.Any(ev => ev > maxEV)) { data.AddLine(GetInvalid(string.Format(LEffortUntrainedCap, maxEV))); } } // Only one of the following can be true: 0, 508, and x%6!=0 if (sum == 0 && !EncounterMatch.IsWithinRange(pkm)) { data.AddLine(Get(LEffortEXPIncreased, Severity.Fishy)); } else if (sum == 508) { data.AddLine(Get(LEffort2Remaining, Severity.Fishy)); } else if (evs[0] != 0 && evs.All(ev => evs[0] == ev)) { data.AddLine(Get(LEffortAllEqual, Severity.Fishy)); } }