diff --git a/PKHeX.Core/Game/GameVersion.cs b/PKHeX.Core/Game/GameVersion.cs index 69589a3c8..df10d6901 100644 --- a/PKHeX.Core/Game/GameVersion.cs +++ b/PKHeX.Core/Game/GameVersion.cs @@ -25,6 +25,7 @@ /* VC2*/ GD = 39, SV = 40, C, // Game Groupings (SaveFile type) + RB = 97, RBY = 98, GSC = 99, RS = 100, @@ -58,8 +59,10 @@ switch (g1) { + case GameVersion.RB: + return g2 == GameVersion.RD || g2 == GameVersion.BU || g2 == GameVersion.GN; case GameVersion.RBY: - return g2 == GameVersion.RD || g2 == GameVersion.BU || g2 == GameVersion.YW || g2 == GameVersion.GN; + return GameVersion.RB.Contains(g2) || g2 == GameVersion.YW; case GameVersion.Gen1: return GameVersion.RBY.Contains(g2) || g2 == GameVersion.Stadium || g2 == GameVersion.EventsGBGen1 || g2 == GameVersion.VCEvents; case GameVersion.Stadium: diff --git a/PKHeX.Core/Legality/Core.cs b/PKHeX.Core/Legality/Core.cs index bbbfc50c4..2c8e64618 100644 --- a/PKHeX.Core/Legality/Core.cs +++ b/PKHeX.Core/Legality/Core.cs @@ -61,6 +61,7 @@ namespace PKHeX.Core private static readonly EvolutionTree Evolves2; private static readonly EncounterArea[] SlotsGSC, SlotsGS, SlotsC; private static readonly EncounterStatic[] StaticGSC, StaticGS, StaticC; + private static readonly TreesArea[] HeadbuttTreesC = TreesArea.GetArray(Data.UnpackMini(Util.GetBinaryResource("trees_h_c.pkl"), "ch")); // Gen 3 private static readonly Learnset[] LevelUpE = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_e.pkl"), "em")); @@ -323,6 +324,12 @@ namespace PKHeX.Core foreach (EncounterStatic Encounter in Encounters) Encounter.Generation = Generation; } + private static void MarkEncountersVersion(ref EncounterArea[] Areas, GameVersion Version) + { + foreach (EncounterArea Area in Areas) + foreach (EncounterSlot1 Slot in Area.Slots) + Slot.Version = Version; + } private static void MarkEncountersGeneration(ref EncounterArea[] Areas, int Generation) { foreach (EncounterArea Area in Areas) @@ -338,6 +345,16 @@ namespace PKHeX.Core Slots = a.SelectMany(m => m.Slots).ToArray() }).ToArray(); } + private static void MarkSlotLocation(ref EncounterArea[] Areas) + { + foreach(EncounterArea Area in Areas) + { + foreach (EncounterSlot Slot in Area.Slots) + { + Slot.Location = Area.Location; + } + } + } private static void MarkG2Slots(ref EncounterArea[] Areas) { ReduceAreasSize(ref Areas); @@ -717,6 +734,12 @@ namespace PKHeX.Core var rb_fish = EncounterArea.GetArray1_F(Util.GetBinaryResource("encounter_rb_f.pkl")); var ylw_fish = EncounterArea.GetArray1_FY(Util.GetBinaryResource("encounter_yellow_f.pkl")); + MarkEncountersVersion(ref red_gw, GameVersion.RD); + MarkEncountersVersion(ref blu_gw, GameVersion.BW); + MarkEncountersVersion(ref ylw_gw, GameVersion.YW); + MarkEncountersVersion(ref rb_fish, GameVersion.RB); + MarkEncountersVersion(ref ylw_fish, GameVersion.YW); + var table = AddExtraTableSlots(red_gw, blu_gw, ylw_gw, rb_fish, ylw_fish); Array.Resize(ref table, table.Length + 1); table[table.Length - 1] = FishOldGood_RBY; @@ -728,6 +751,7 @@ namespace PKHeX.Core EncounterArea[] Slots = null; // Fishing var f = EncounterArea.GetArray2_F(Util.GetBinaryResource("encounter_gsc_f.pkl")); + if (Version == GameVersion.GS || Version == GameVersion.GSC) { // Grass/Water @@ -736,8 +760,18 @@ namespace PKHeX.Core // Headbutt/Rock Smash var h_g = EncounterArea.GetArray2_H(Util.GetBinaryResource("encounter_gold_h.pkl")); var h_s = EncounterArea.GetArray2_H(Util.GetBinaryResource("encounter_silver_h.pkl")); + var safari_gs = EncounterSafari_GSC; + var bcc_gs = EncounterBCC_GSC; - Slots = AddExtraTableSlots(g, s, h_g, h_s, f, EncounterBCC_GSC); + MarkEncountersVersion(ref bcc_gs, GameVersion.GS); + MarkEncountersVersion(ref f, GameVersion.GS); + MarkEncountersVersion(ref g, GameVersion.GD); + MarkEncountersVersion(ref s, GameVersion.SV); + MarkEncountersVersion(ref h_g, GameVersion.GD); + MarkEncountersVersion(ref h_s, GameVersion.SV); + MarkEncountersVersion(ref safari_gs, GameVersion.GS); + + Slots = AddExtraTableSlots(g, s, h_g, h_s, f, bcc_gs, safari_gs); } if (Version == GameVersion.C || Version == GameVersion.GSC) { @@ -745,8 +779,16 @@ namespace PKHeX.Core var c = EncounterArea.GetArray2_GW(Util.GetBinaryResource("encounter_crystal.pkl")); // Headbutt/Rock Smash var h_c = EncounterArea.GetArray2_H(Util.GetBinaryResource("encounter_crystal_h.pkl")); + var safari_c= EncounterSafari_GSC; + var bcc_c = EncounterBCC_GSC; - var extra = AddExtraTableSlots(c, h_c, f, EncounterBCC_GSC); + MarkEncountersVersion(ref bcc_c, GameVersion.C); + MarkEncountersVersion(ref safari_c, GameVersion.C); + MarkEncountersVersion(ref f, GameVersion.C); + MarkEncountersVersion(ref c, GameVersion.C); + MarkEncountersVersion(ref h_c, GameVersion.C); + + var extra = AddExtraTableSlots(c, h_c, f, bcc_c, safari_c); return Version == GameVersion.C ? extra : AddExtraTableSlots(Slots, extra); } @@ -776,6 +818,7 @@ namespace PKHeX.Core MarkG2Slots(ref SlotsGS); MarkG2Slots(ref SlotsC); MarkG2Slots(ref SlotsGSC); + MarkSlotLocation(ref SlotsC); MarkEncountersGeneration(ref SlotsGS, 2); MarkEncountersGeneration(ref SlotsC, 2); MarkEncountersGeneration(ref SlotsGSC, 2); @@ -821,6 +864,12 @@ namespace PKHeX.Core SlotsFR = AddExtraTableSlots(FR_Slots, SlotsFRLGAlt); SlotsLG = AddExtraTableSlots(LG_Slots, SlotsFRLGAlt); + MarkSlotLocation(ref SlotsR); + MarkSlotLocation(ref SlotsS); + MarkSlotLocation(ref SlotsE); + MarkSlotLocation(ref SlotsFR); + MarkSlotLocation(ref SlotsLG); + Evolves3 = new EvolutionTree(new[] { Util.GetBinaryResource("evos_g3.pkl") }, GameVersion.RS, PersonalTable.RS, MaxSpeciesID_3); // Update Personal Entries with TM/Tutor Data @@ -917,7 +966,13 @@ namespace PKHeX.Core MarkDPPtEncounterTypeSlots(ref SlotsPt); MarkHGSSEncounterTypeSlots(ref SlotsHG); MarkHGSSEncounterTypeSlots(ref SlotsSS); - + + MarkSlotLocation(ref SlotsD); + MarkSlotLocation(ref SlotsP); + MarkSlotLocation(ref SlotsPt); + MarkSlotLocation(ref SlotsHG); + MarkSlotLocation(ref SlotsSS); + Evolves4 = new EvolutionTree(new[] { Util.GetBinaryResource("evos_g4.pkl") }, GameVersion.DP, PersonalTable.DP, MaxSpeciesID_4); // Update Personal Entries with Tutor Data @@ -1412,24 +1467,22 @@ namespace PKHeX.Core } // Encounter - internal static GameVersion[] GetGen2GameEncounter(PKM pkm) + internal static GameVersion[] GetGen2GameEncounter(PKM pkm, LegalInfo Info) { - return AllowGen2VCCrystal ? new[] { GameVersion.GS, GameVersion.C } : new[] { GameVersion.GS}; + if (AllowGen2Crystal && Info.Game == GameVersion.C) + return new[] { GameVersion.C }; + // Any encounter marked with version GSC is for pokemon with the same moves in g/s and crystal, it is enought to check only g/s moves + return new[] { GameVersion.GS }; } - internal static GameVersion[] GetGen1GameEncounter(PKM pkm) + internal static GameVersion[] GetGen1GameEncounter(PKM pkm, LegalInfo Info) { - if (!(pkm is PK1 pk) || !pkm.Gen1_NotTradeback) - return new[] { GameVersion.RD, GameVersion.YW }; - if (25 <= pk.Species && pk.Species <= 26) - // Yellow Pikachu detected by its special catch rate - return new[] { pk.Catch_Rate == 163 ? GameVersion.YW : GameVersion.RD }; - if (64 <= pk.Species && pk.Species <= 65) - // Yellow Kadabra detected by its special catch rate - return new[] { pk.Catch_Rate == 96 ? GameVersion.YW : GameVersion.RD }; - if (148 <= pk.Species && pk.Species <= 149 && pk.Catch_Rate == 27) - // Yellow Dragonair detected by its special catch rate, is have another catch rate could be red/blue dratini or yellow dratini + if (Info.EncounterMatch.Species == 133 && Info.Game == GameVersion.Stadium) + // Staidum eevee, check for red/blue and yellow initial moves + return new[] { GameVersion.RB, GameVersion.YW }; + if (Info.Game == GameVersion.YW) return new[] { GameVersion.YW }; - return new[] { GameVersion.RD, GameVersion.YW }; + // Any encounter marked with version RBY is for pokemon with the same moves and catch rate in red/blue and yellow, it is enought to check only red/blue moves + return new[] { GameVersion.RB }; } internal static IEnumerable GetInitialMovesGBEncounter(int species, int lvl, GameVersion ver) { @@ -1442,6 +1495,7 @@ namespace PKHeX.Core case GameVersion.RD: case GameVersion.BU: case GameVersion.GN: + case GameVersion.RB: { var LevelTable = ver == GameVersion.YW ? LevelUpY : LevelUpRB; int index = PersonalTable.RB.GetFormeIndex(species, 0); @@ -1455,6 +1509,8 @@ namespace PKHeX.Core break; } case GameVersion.C: + case GameVersion.GD: + case GameVersion.SV: case GameVersion.GS: { if (species == 235) @@ -2929,5 +2985,10 @@ namespace PKHeX.Core Outsider |= Savegame_Gender != pkm.OT_Gender || Savegame_Version != (GameVersion) pkm.Version; return Outsider; } + + internal static TreesArea GetCrystalTreeArea(PKM pkm,EncounterSlot Slot) + { + return HeadbuttTreesC.FirstOrDefault(a => a.Location == Slot.Location); + } } } diff --git a/PKHeX.Core/Legality/Encounters/EncounterFinder.cs b/PKHeX.Core/Legality/Encounters/EncounterFinder.cs index 787291e08..e24764fc5 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterFinder.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterFinder.cs @@ -21,7 +21,7 @@ namespace PKHeX.Core { bool PIDMatch = info.PIDIVMatches; var EncounterMatch = info.EncounterMatch = encounter.Current; - var e = EncounterValidator(pkm, EncounterMatch); + var e = EncounterValidator(pkm, info, EncounterMatch); if (!e.Valid && encounter.PeekIsNext()) continue; info.Parse.Add(e); @@ -81,7 +81,7 @@ namespace PKHeX.Core info.Moves = VerifyCurrentMoves.VerifyMoves(pkm, info); return info; } - private static Func GetEncounterVerifierMethod(PKM pkm) + private static Func GetEncounterVerifierMethod(PKM pkm) { switch (pkm.GenNumber) { diff --git a/PKHeX.Core/Legality/Encounters/EncounterGenerator.cs b/PKHeX.Core/Legality/Encounters/EncounterGenerator.cs index 655be9e10..80f60345c 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterGenerator.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterGenerator.cs @@ -416,7 +416,10 @@ namespace PKHeX.Core if (e.Species == 054 && !japanese && catch_rate != 168) continue; } - else if (catch_rate != PersonalTable.RB[e.Species].CatchRate && catch_rate != PersonalTable.Y[e.Species].CatchRate) + // Encounter with the different catch rate in yellow and redblue are duplicated with different gameverion + else if (e.Version == GameVersion.YW && catch_rate != PersonalTable.Y[e.Species].CatchRate) + continue; + else if (e.Version != GameVersion.YW && catch_rate != PersonalTable.RB[e.Species].CatchRate) continue; } @@ -540,7 +543,8 @@ namespace PKHeX.Core // Get Valid levels IEnumerable vs = GetValidPreEvolutions(pkm, maxspeciesorigin: maxspeciesorigin, lvl: ignoreLevel ? 100 : -1, skipChecks: ignoreLevel); - bool IsRGBKadabra = false; + bool RBDragonair = false; + GameVersion Gen1Version = GameVersion.RBY; if (pkm is PK1 pk1 && pkm.Gen1_NotTradeback) { // Pure gen 1, slots can be filter by catch rate @@ -548,14 +552,31 @@ namespace PKHeX.Core // Yellow Pikachu, is not a wild encounter yield break; if ((pkm.Species == 64 || pkm.Species == 65) && pk1.Catch_Rate == 96) + { // Yellow Kadabra, ignore Abra encounters vs = vs.Where(s => s.Species == 64); - if ((pkm.Species == 148 || pkm.Species == 149) && pk1.Catch_Rate == 27) - // Yellow Dragonair, ignore Dratini encounters - vs = vs.Where(s => s.Species == 148); + Gen1Version = GameVersion.YW; + } + if (pkm.Species == 148 || pkm.Species == 149) + { + if (pk1.Catch_Rate == 27) + { + // Yellow Dragonair, ignore Dratini encounters + vs = vs.Where(s => s.Species == 148); + Gen1Version = GameVersion.YW; + } + else + // Red blue dragonair have the same catch rate as dratini, it could also be a dratini from any game + RBDragonair = true; + } else { - IsRGBKadabra = (pkm.Species == 64 || pkm.Species == 65) && pk1.Catch_Rate == 100; + if((pkm.Species == 64 || pkm.Species == 65) && pk1.Catch_Rate == 100) + { + // Red Blue Kadabra + vs = vs.Where(s => s.Species == 64); + Gen1Version = GameVersion.RB; + } vs = vs.Where(s => pk1.Catch_Rate == PersonalTable.RB[s.Species].CatchRate); } } @@ -573,8 +594,21 @@ namespace PKHeX.Core if (gen <= 2) { - if (IsRGBKadabra) //Red Kadabra slots : Level 49 and 51 in RGB, but level 20 and 27 in Yellow - encounterSlots = encounterSlots.Where(slot => slot.LevelMin >= 49).ToList(); + if (gen == 1 && Gen1Version != GameVersion.RBY) + { + encounterSlots = encounterSlots.Where(slot => Gen1Version.Contains(((EncounterSlot1)slot).Version)).ToList(); + } + + if (gen == 1 && RBDragonair) + { + // Red Blue dragonair or dratini from any gen 1 games + encounterSlots = encounterSlots.Where(slot => GameVersion.RB.Contains(((EncounterSlot1)slot).Version) || slot.Species == 147).ToList(); + } + + if (gen == 2 && pkm is PK2 pk2 && pk2.Met_Day != 0) + { + encounterSlots = encounterSlots.Where(slot => ((EncounterSlot1)slot).Time.Contains(pk2.Met_Day)).ToList(); + } foreach (var s in encounterSlots.OrderBy(slot => slot.LevelMin)) yield return s; @@ -746,10 +780,18 @@ namespace PKHeX.Core // Even if the in game trade uses the tables with source pokemon allowing generation 2 games, the traded pokemon could be a non-tradeback pokemon var rate = (pkm as PK1)?.Catch_Rate; - if (z is EncounterTradeCatchRate r && rate != r.Catch_Rate) - continue; - if (rate != PersonalTable.RB[z.Species].CatchRate && rate != PersonalTable.Y[z.Species].CatchRate) - continue; + if (z is EncounterTradeCatchRate r ) + { + if (rate != r.Catch_Rate) + continue; + } + else + { + if (z.Version == GameVersion.YW && rate != PersonalTable.Y[z.Species].CatchRate) + continue; + if (z.Version != GameVersion.YW && rate != PersonalTable.RB[z.Species].CatchRate) + continue; + } yield return z; } diff --git a/PKHeX.Core/Legality/Encounters/EncounterVerifier.cs b/PKHeX.Core/Legality/Encounters/EncounterVerifier.cs index af0490c14..637094fd8 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterVerifier.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterVerifier.cs @@ -5,7 +5,7 @@ namespace PKHeX.Core { public static class EncounterVerifier { - public static CheckResult VerifyEncounter(PKM pkm, IEncounterable encounter) + public static CheckResult VerifyEncounter(PKM pkm, LegalInfo info, IEncounterable encounter) { if (encounter is EncounterEgg e) { @@ -17,7 +17,7 @@ namespace PKHeX.Core if (encounter is EncounterTrade t) return VerifyEncounterTrade(pkm, t); if (encounter is EncounterSlot w) - return VerifyEncounterWild(pkm, w); + return VerifyEncounterWild(pkm, info, w); if (encounter is EncounterStatic s) return VerifyEncounterStatic(pkm, s, null); if (encounter is MysteryGift g) @@ -25,7 +25,7 @@ namespace PKHeX.Core return new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter); } - public static CheckResult VerifyEncounterG12(PKM pkm, IEncounterable encounter) + public static CheckResult VerifyEncounterG12(PKM pkm, LegalInfo info, IEncounterable encounter) { var EncounterMatch = encounter is GBEncounterData g ? g.Encounter : encounter; if (encounter.EggEncounter) @@ -33,8 +33,12 @@ namespace PKHeX.Core pkm.WasEgg = true; return VerifyEncounterEgg(pkm, EncounterMatch); } - if (EncounterMatch is EncounterSlot) + if (EncounterMatch is EncounterSlot1 l) + { + if (info.Generation == 2) + return VerifyWildEncounterGen2(pkm, l); return new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter); + } if (EncounterMatch is EncounterStatic s) return VerifyEncounterStatic(pkm, s, null); if (EncounterMatch is EncounterTrade t) @@ -43,6 +47,55 @@ namespace PKHeX.Core return new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter); } + private static CheckResult VerifyWildEncounterGen2(PKM pkm, EncounterSlot1 encounter) + { + if (encounter.Type == SlotType.Old_Rod_Safari || encounter.Type == SlotType.Good_Rod_Safari || encounter.Type == SlotType.Super_Rod_Safari) + // Fishing in the beta gen 2 safari zone + return new CheckResult(Severity.Invalid, V609, CheckIdentifier.Encounter); + + if (encounter.Version == GameVersion.C) + return VerifyWildEncounterCrystal(pkm, encounter); + + return new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter); + } + + private static CheckResult VerifyWildEncounterCrystal(PKM pkm, EncounterSlot1 encounter) + { + if(encounter.Type == SlotType.Headbutt || encounter.Type == SlotType.Headbutt_Special) + { + return VerifyWildEncounterCrystalHeadbutt(pkm, encounter); + } + if (encounter.Type == SlotType.Old_Rod || encounter.Type == SlotType.Good_Rod || encounter.Type == SlotType.Super_Rod) + { + if (encounter.Location == 19) + // Fishing in National Park + return new CheckResult(Severity.Invalid, V607, CheckIdentifier.Encounter); + if (encounter.Location == 76) + // Fishing in Route 14 + return new CheckResult(Severity.Invalid, V608, CheckIdentifier.Encounter); + } + + return new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter); + } + + private static CheckResult VerifyWildEncounterCrystalHeadbutt(PKM pkm, EncounterSlot1 encounter) + { + var Area = Legal.GetCrystalTreeArea(pkm, encounter); + if (Area == null) // Failsafe, every area with headbutt encounters have a tree area + return new CheckResult(Severity.Invalid, V605, CheckIdentifier.Encounter); + var trainerpivot = pkm.TID % 10; + var availabletree = encounter.Type == SlotType.Headbutt ? Area.TrainerModerateEncounterTree[trainerpivot] : Area.TrainerLowEncounterTree[trainerpivot]; + switch (availabletree) + { + case TreeEncounterAvailable.ValidTree: + return new CheckResult(Severity.Valid, V604, CheckIdentifier.Encounter); + case TreeEncounterAvailable.InvalidTree: + return new CheckResult(Severity.Invalid, V604, CheckIdentifier.Encounter); + default: //reeEncounterAvailable.Impossible + return new CheckResult(Severity.Invalid, V605, CheckIdentifier.Encounter); + } + } + // Eggs private static CheckResult VerifyEncounterEgg(PKM pkm, IEncounterable egg) { @@ -163,13 +216,13 @@ namespace PKHeX.Core } // Etc - private static CheckResult VerifyEncounterWild(PKM pkm, EncounterSlot slot) + private static CheckResult VerifyEncounterWild(PKM pkm, LegalInfo info, EncounterSlot slot) { // Check for Unreleased Encounters / Collisions switch (pkm.GenNumber) { case 4: - if (pkm.HasOriginalMetLocation && pkm.Met_Location == 193 && slot.Type == SlotType.Surf) + if (slot.Location == 193 && slot.Type == SlotType.Surf) { // Pokemon surfing in Johto Route 45 return new CheckResult(Severity.Invalid, V384, CheckIdentifier.Encounter); diff --git a/PKHeX.Core/Legality/Encounters/VerifyCurrentMoves.cs b/PKHeX.Core/Legality/Encounters/VerifyCurrentMoves.cs index 74ad64d5b..7b792e3af 100644 --- a/PKHeX.Core/Legality/Encounters/VerifyCurrentMoves.cs +++ b/PKHeX.Core/Legality/Encounters/VerifyCurrentMoves.cs @@ -182,7 +182,7 @@ namespace PKHeX.Core } private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, int[] Moves, LegalInfo info) { - GameVersion[] games = (info.EncounterMatch as IGeneration)?.Generation == 1 ? Legal.GetGen1GameEncounter(pkm) : Legal.GetGen2GameEncounter(pkm); + GameVersion[] games = (info.EncounterMatch as IGeneration)?.Generation == 1 ? Legal.GetGen1GameEncounter(pkm, info) : Legal.GetGen2GameEncounter(pkm, info); CheckMoveResult[] res = new CheckMoveResult[4]; var G1Encounter = info.EncounterMatch; if (G1Encounter == null) diff --git a/PKHeX.Core/Legality/LegalityCheckStrings.cs b/PKHeX.Core/Legality/LegalityCheckStrings.cs index b03938fe6..c1c8cde1f 100644 --- a/PKHeX.Core/Legality/LegalityCheckStrings.cs +++ b/PKHeX.Core/Legality/LegalityCheckStrings.cs @@ -407,6 +407,12 @@ namespace PKHeX.Core public static string V601 { get; set; } = "Missing Ribbons: {0}"; public static string V602 { get; set; } = "All ribbons accounted for."; public static string V603 { get; set; } = "Can't receive Ribbon(s) as an Egg."; + public static string V604 { get; set; } = "Found a tree for crystal heabutt encounter that matches OTID"; + public static string V605 { get; set; } = "Found an unreacheable tree for crystal heabutt encounter that matches OTID."; + public static string V606 { get; set; } = "Could not found a tree for crystal heabutt encounter that matches OTID."; + public static string V607 { get; set; } = "Kanto Route 14 fishing encounter. Unreachable Water tiles."; + public static string V608 { get; set; } = "National Park fishing encounter. Unreachable Water tiles."; + public static string V609 { get; set; } = "Generation 2 safari zone fishing encounter. Unreachable zone."; #endregion } diff --git a/PKHeX.Core/Legality/Structures/EncounterArea.cs b/PKHeX.Core/Legality/Structures/EncounterArea.cs index 226bdc192..536fa1708 100644 --- a/PKHeX.Core/Legality/Structures/EncounterArea.cs +++ b/PKHeX.Core/Legality/Structures/EncounterArea.cs @@ -67,6 +67,10 @@ namespace PKHeX.Core rates[i] = data[ofs++]; var slots = ReadSlots(data, ref ofs, slotSets * slotCount, t, rates[0]); + for (int i = 0; i < slotCount; i++) + { + slots[i].Time = EncounterTime.Morning; + } for (int r = 1; r < slotSets; r++) { for (int i = 0; i < slotCount; i++) @@ -74,6 +78,7 @@ namespace PKHeX.Core int index = i + r*slotCount; slots[index].Rate = rates[r]; slots[index].SlotNumber = i; + slots[i].Time = r == 1 ? EncounterTime.Day : EncounterTime.Night; } } @@ -111,8 +116,11 @@ namespace PKHeX.Core // slot set ends in 0xFF var slots = new List(); int tableCount = t == SlotType.Headbutt ? 2 : 1; + SlotType slottype = t; while (tableCount != 0) { + if (t == SlotType.Headbutt) + slottype = tableCount == 2 ? SlotType.Headbutt_Special : SlotType.Headbutt; int rate = data[ofs++]; if (rate == 0xFF) // end of table { @@ -129,7 +137,7 @@ namespace PKHeX.Core Species = species, LevelMin = level, LevelMax = level, - Type = t + Type = slottype }); } return slots.ToArray(); @@ -140,9 +148,10 @@ namespace PKHeX.Core var areas = new List(); while (data[ofs] != 0xFF) // end { + int _Location = data[ofs++] << 8 | data[ofs++]; areas.Add(new EncounterArea { - Location = data[ofs++] << 8 | data[ofs++], + Location = _Location, Slots = GetSlots2_GW(data, ref ofs, t, slotSets, slotCount), }); } @@ -175,7 +184,6 @@ namespace PKHeX.Core var slot = slots[i]; if (slot.Type != SlotType.Special) continue; - Array.Resize(ref slots, slots.Length + 1); Array.Copy(slots, i, slots, i+1, slots.Length - i - 1); // shift slots down slots[i+1] = slot.Clone(); // differentiate copied slot @@ -183,10 +191,11 @@ namespace PKHeX.Core int index = slot.LevelMin*2; for (int j = 0; j < 2; j++) // load special slot info { - var s = slots[i + j]; + var s = slots[i + j] as EncounterSlot1; s.Species = dl[index + j].Species; s.LevelMin = s.LevelMax = dl[index + j].Level; s.Type = slots[i - 1].Type; // special slots are never first in a set, so copy previous type + s.Time = j == 0 ? EncounterTime.MorningDay : EncounterTime.Night; } } area.Slots = slots; diff --git a/PKHeX.Core/Legality/Structures/EncounterSlot.cs b/PKHeX.Core/Legality/Structures/EncounterSlot.cs index e632518cf..6c93c7bc1 100644 --- a/PKHeX.Core/Legality/Structures/EncounterSlot.cs +++ b/PKHeX.Core/Legality/Structures/EncounterSlot.cs @@ -15,6 +15,7 @@ } public class EncounterSlot : IEncounterable, IGeneration { + public int Location { get; set; } = -1; public int Species { get; set; } public int Form { get; set; } public int LevelMin { get; set; } @@ -54,6 +55,8 @@ public class EncounterSlot1 : EncounterSlot { public int Rate; + public EncounterTime Time = EncounterTime.Any; + public GameVersion Version = GameVersion.Any; public override EncounterSlot Clone() { return new EncounterSlot1 @@ -64,7 +67,9 @@ Type = Type, SlotNumber = SlotNumber, _perm = _perm, - Rate = Rate + Rate = Rate, + Time = Time, + Generation = Generation, }; } } diff --git a/PKHeX.Core/Legality/Structures/EncounterTime.cs b/PKHeX.Core/Legality/Structures/EncounterTime.cs new file mode 100644 index 000000000..f4d544c2b --- /dev/null +++ b/PKHeX.Core/Legality/Structures/EncounterTime.cs @@ -0,0 +1,32 @@ +namespace PKHeX.Core +{ + public enum EncounterTime + { + Any = -1, + MorningDay = -2, + Morning = 1, + Day = 2, + Night = 3 + } + + public static class EncounterTimeExtension + { + public static bool Contains(this EncounterTime t1, int t2) + { + return t1.Contains((EncounterTime)t2); + } + private static bool Contains(this EncounterTime t1, EncounterTime t2) + { + if (t1 == t2 || t1 == EncounterTime.Any || t2 == EncounterTime.Any) + return true; + + if (t1 == EncounterTime.MorningDay) + return (t2 == EncounterTime.Morning || t2 == EncounterTime.Day); + + if (t2 == EncounterTime.MorningDay) + return (t1 == EncounterTime.Morning || t1 == EncounterTime.Day); + + return false; + } + } +} \ No newline at end of file diff --git a/PKHeX.Core/Legality/Structures/TreesArea.cs b/PKHeX.Core/Legality/Structures/TreesArea.cs new file mode 100644 index 000000000..9d95ac070 --- /dev/null +++ b/PKHeX.Core/Legality/Structures/TreesArea.cs @@ -0,0 +1,146 @@ +using System.Linq; + +namespace PKHeX.Core +{ + // Pokemon Crystal Headbutt tree encounters by trainer id, base on mechanics described in + // https://bulbapedia.bulbagarden.net/wiki/Headbutt_tree#Mechanics + + public enum TreeEncounterAvailable + { + ValidTree, // Encounter is possible a reacheable tree + InvalidTree, // Encounter is only possible a tree reacheable only with walk-trought walls cheats + Impossible // Encounter is not possible in any tree + } + + public class TreeCoordinates + { + internal int X { get; set; } + internal int Y { get; set; } + internal int Index => ((X * Y + X + Y) / 5) % 10; + } + + public class TreesArea + { + public int Location { get; private set; } + public TreeEncounterAvailable[] TrainerModerateEncounterTree { get; private set; } + public TreeEncounterAvailable[] TrainerLowEncounterTree { get; private set; } + + private int[] ValidTreeIndex { get; set; } + private int[] InvalidTreeIndex { get; set; } + + private TreeCoordinates[] ValidTrees { get; set; } + private TreeCoordinates[] InvalidTrees { get; set; } + private static int[][] TrainerModerateTreeIndex { get; set; } + + internal static TreesArea[] GetArray(byte[][] entries) + { + if (entries == null) + return null; + TrainerModerateTreeIndex = GenerateTrainersTreeIndex(); + var Areas = new TreesArea[entries.Length]; + for(int i = 0; i < entries.Length; i++) + { + Areas[i] = GetArea(entries[i]); + } + return Areas; + } + + private static int[][] GenerateTrainersTreeIndex() + { + // A tree have a low encounter or moderate encounter base on the TID Pivot Index ( TID % 10) + // Calculate for every Trainer Pivot Index the 5 tree index for low encounters + int[][] TrainersIndex = new int[10][]; + for (int pivotindex = 0; pivotindex < 10; pivotindex++) + { + int[] ModerateEncounterTreeIndex = new int[5]; + for(int index = 0; index <= 4; index++) + ModerateEncounterTreeIndex[index] = (pivotindex + index) % 10; + TrainersIndex[pivotindex] = ModerateEncounterTreeIndex.OrderBy(x => x).ToArray(); + } + return TrainersIndex; + } + + private static TreesArea GetArea(byte[] entrie) + { + var Area = new TreesArea(); + + Area.ReadAreaRawData(entrie); + Area.GenerateAreaTreeIndex(); + Area.GenerateAreaTrainerEncounters(); + return Area; + } + + private void ReadAreaRawData(byte[] entrie) + { + // Coordinates of trees for every are obtained with programa G2Map + // ValidTrees are those accesible from the player + // Invalid tress are trees that the player can not reach without cheating devices, like a tree beyond other trees + Location = entrie[0]; + ValidTrees = new TreeCoordinates[entrie[1]]; + + var ofs = 2; + for (int i = 0; i < ValidTrees.Length; i++) + { + ValidTrees[i] = new TreeCoordinates() + { + X = entrie[ofs], + Y = entrie[ofs + 1] + }; + ofs += 2; + } + InvalidTrees = new TreeCoordinates[entrie[ofs]]; + ofs += 1; + for (int i = 0; i < InvalidTrees.Length; i++) + { + InvalidTrees[i] = new TreeCoordinates() + { + X = entrie[ofs], + Y = entrie[ofs + 1] + }; + ofs += 2; + } + } + + private void GenerateAreaTreeIndex() + { + // For legallity purpose only the tree index is needed, group the trees data by their index, trees with the same index are indistinguible + ValidTreeIndex = ValidTrees.Select(t => t.Index).Distinct().OrderBy(i => i).ToArray(); + InvalidTreeIndex = InvalidTrees.Select(t => t.Index).Distinct().OrderBy(i => i).Except(ValidTreeIndex).ToArray(); + } + + private void GenerateAreaTrainerEncounters() + { + // Check for every trainer pivot index if there is trees with low encounter and moderate encounter available in the area + TrainerModerateEncounterTree = new TreeEncounterAvailable[10]; + TrainerLowEncounterTree = new TreeEncounterAvailable[10]; + for (int pivotindex = 0; pivotindex < 10; pivotindex++) + { + var TrainerModerateTrees = TrainerModerateTreeIndex[pivotindex]; + + var ModerateValid = ValidTreeIndex.Any(t => TrainerModerateTrees.Contains(t)); + var ModerateInvalid = InvalidTreeIndex.Any(t => TrainerModerateTrees.Contains(t)); + if (ModerateValid) + // There is a valid tree with an index for moderate encounters + TrainerModerateEncounterTree[pivotindex] = TreeEncounterAvailable.ValidTree; + else if (ModerateInvalid) + // There is a tree with an index for moderate encounters but is invalid + TrainerModerateEncounterTree[pivotindex] = TreeEncounterAvailable.InvalidTree; + else + // No trees for moderate encounters + TrainerModerateEncounterTree[pivotindex] = TreeEncounterAvailable.Impossible; + + var LowValid = ValidTreeIndex.Except(TrainerModerateTrees).Any(); + var LowInvalid = InvalidTreeIndex.Except(TrainerModerateTrees).Any(); + if (LowValid) + // There is a valid tree with an index for low encounters + TrainerLowEncounterTree[pivotindex] = TreeEncounterAvailable.ValidTree; + else if (LowInvalid) + // There is a tree with an index for low encounters but is invalid + TrainerLowEncounterTree[pivotindex] = TreeEncounterAvailable.InvalidTree; + else + // No trees for low encounters + TrainerLowEncounterTree[pivotindex] = TreeEncounterAvailable.Impossible; + } + } + } +} diff --git a/PKHeX.Core/Legality/Tables1.cs b/PKHeX.Core/Legality/Tables1.cs index 5bd4eddb4..69bc76a6e 100644 --- a/PKHeX.Core/Legality/Tables1.cs +++ b/PKHeX.Core/Legality/Tables1.cs @@ -52,14 +52,16 @@ namespace PKHeX.Core internal static readonly EncounterStatic[] Encounter_RBY = { + // Gameversion is RBY for pokemon with the same catch rate and initial moves in all games + // If there are differents in moves or catch rate they will have different encounters defined new EncounterStatic { Species = 001, Level = 05, Version = GameVersion.RBY }, // Bulbasaur new EncounterStatic { Species = 004, Level = 05, Version = GameVersion.RBY }, // Charmander new EncounterStatic { Species = 007, Level = 05, Version = GameVersion.RBY }, // Squirtle new EncounterStatic { Species = 025, Level = 05, Version = GameVersion.YW }, // Pikachu // Game Corner - new EncounterStatic { Species = 030, Level = 17, Version = GameVersion.RBY }, // Nidorina (Red Game Corner) - new EncounterStatic { Species = 033, Level = 17, Version = GameVersion.RBY }, // Nidorino (Blue[EN] / Green[JP] Game Corner) + new EncounterStatic { Species = 030, Level = 17, Version = GameVersion.RB }, // Nidorina (Red Game Corner) + new EncounterStatic { Species = 033, Level = 17, Version = GameVersion.BU }, // Nidorino (Blue[EN] / Green[JP] Game Corner) new EncounterStatic { Species = 035, Level = 08, Version = GameVersion.RBY }, // Clefairy (Red Game Corner) new EncounterStatic { Species = 036, Level = 24, Version = GameVersion.RBY }, // Clefable (Blue[JP] Game Corner) new EncounterStatic { Species = 037, Level = 18, Version = GameVersion.RBY }, // Vulpix (Yellow Game Corner) @@ -67,19 +69,20 @@ namespace PKHeX.Core new EncounterStatic { Species = 063, Level = 06, Version = GameVersion.RBY }, // Abra (Blue[EN] / Green[JP] Game Corner) new EncounterStatic { Species = 116, Level = 18, Version = GameVersion.RBY }, // Horsea (Blue[JP] Game Corner) new EncounterStatic { Species = 123, Level = 25, Version = GameVersion.RBY }, // Scyther (Red Game Corner) - new EncounterStatic { Species = 127, Level = 20, Version = GameVersion.RBY }, // Pinsir (Blue[EN] / Green[JP] Game Corner) + new EncounterStatic { Species = 127, Level = 20, Version = GameVersion.BU }, // Pinsir (Blue[EN] / Green[JP] Game Corner) + new EncounterStatic { Species = 127, Level = 30, Version = GameVersion.YW }, // Pinsir (Yellow Game Corner) (Different initial moves) new EncounterStatic { Species = 137, Level = 18, Version = GameVersion.RBY }, // Porygon (Blue[EN] / Green[JP] Game Corner) new EncounterStatic { Species = 147, Level = 18, Version = GameVersion.RBY }, // Dratini (Red Game Corner) - new EncounterStatic { Species = 148, Level = 30, Version = GameVersion.RBY }, // Dragonair (Blue[JP] Game Corner) + new EncounterStatic { Species = 148, Level = 30, Version = GameVersion.BU }, // Dragonair (Blue[JP] Game Corner) + new EncounterStatic { Species = 025, Level = 12, Version = GameVersion.BU }, // Pikachu (Blue[JP] Game Corner) (Different catch rate) + // Lower level less ideal matches; best match is from above. - // new EncounterStatic { Species = 025, Level = 12 }, // Pikachu (Blue[JP] Game Corner) // new EncounterStatic { Species = 035, Level = 12 }, // Clefairy (Blue[EN] / Green[JP] Game Corner) // new EncounterStatic { Species = 063, Level = 09 }, // Abra (Red Game Corner) // new EncounterStatic { Species = 063, Level = 08 }, // Abra (Blue[JP] Game Corner) // new EncounterStatic { Species = 063, Level = 15 }, // Abra (Yellow Game Corner) // new EncounterStatic { Species = 123, Level = 30 }, // Scyther (Yellow Game Corner) - // new EncounterStatic { Species = 127, Level = 30 }, // Pinsir (Yellow Game Corner) // new EncounterStatic { Species = 137, Level = 22 }, // Porygon (Blue[JP] Game Corner) // new EncounterStatic { Species = 137, Level = 26 }, // Porygon (Red Game Corner) // new EncounterStatic { Species = 137, Level = 26 }, // Porygon (Yellow Game Corner) @@ -101,10 +104,10 @@ namespace PKHeX.Core new EncounterStatic { Species = 150, Level = 70, Version = GameVersion.RBY }, // Mewtwo - new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.RBY }, // Eevee + new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.RB }, // Eevee + new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.YW }, // Eevee (Different initial moves) // Yellow Only -- duplicate encounters with a higher level - // new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.YW }, // Eevee (Celadon City) // new EncounterStatic { Species = 001, Level = 10, Version = GameVersion.YW }, // Bulbasaur (Cerulean City) // new EncounterStatic { Species = 004, Level = 10, Version = GameVersion.YW }, // Charmander (Route 24) // new EncounterStatic { Species = 007, Level = 10, Version = GameVersion.YW }, // Squirtle (Vermillion City) @@ -124,64 +127,65 @@ namespace PKHeX.Core { // Species & Minimum level (legal) possible to acquire at. //new EncounterTrade { Species = 122, Generation = 1, Level = 06 }, // Mr. Mime - Game Corner Abra - new EncounterTrade { Species = 032, Generation = 1, Level = 02 }, // Nidoran♂ - Wild Nidoran♀ - new EncounterTrade { Species = 029, Generation = 1, Level = 02 }, // Nidoran♀ - Wild Nidoran♂ - new EncounterTrade { Species = 030, Generation = 1, Level = 16 }, // Nidorina - Evolve Nidorino - new EncounterTrade { Species = 108, Generation = 1, Level = 15 }, // Lickitung - Surf Slowbro - new EncounterTrade { Species = 083, Generation = 1, Level = 02 }, // Farfetch’d - Wild Spearow - new EncounterTrade { Species = 101, Generation = 1, Level = 03 }, // Electrode - Wild Raichu + new EncounterTrade { Species = 032, Generation = 1, Level = 02, Version = GameVersion.RD }, // Nidoran♂ - Wild Nidoran♀ + new EncounterTrade { Species = 029, Generation = 1, Level = 02, Version = GameVersion.BU }, // Nidoran♀ - Wild Nidoran♂ + new EncounterTrade { Species = 030, Generation = 1, Level = 16, Version = GameVersion.RB }, // Nidorina - Evolve Nidorino + new EncounterTrade { Species = 030, Generation = 1, Level = 16, Version = GameVersion.YW }, // Nidorina - Evolve Nidorino (Different initial moves) + new EncounterTrade { Species = 108, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Lickitung - Surf Slowbro + new EncounterTrade { Species = 083, Generation = 1, Level = 02, Version = GameVersion.RBY }, // Farfetch’d - Wild Spearow + new EncounterTrade { Species = 101, Generation = 1, Level = 03, Version = GameVersion.RBY }, // Electrode - Wild Raichu - new EncounterTrade { Species = 122, Generation = 1, Level = 03 }, // Mr. Mime - Wild Jigglypuff - new EncounterTrade { Species = 060, Generation = 1, Level = 02 }, // Poliwag - Wild Rattata + new EncounterTrade { Species = 122, Generation = 1, Level = 03, Version = GameVersion.RBY }, // Mr. Mime - Wild Jigglypuff + new EncounterTrade { Species = 060, Generation = 1, Level = 02, Version = GameVersion.RBY }, // Poliwag - Wild Rattata //new EncounterTrade { Species = 083, Generation = 1, Level = 02 }, // Farfetch’d - Wild Pidgey - new EncounterTrade { Species = 079, Generation = 1, Level = 22 }, // Slowpoke - Wild Seel + new EncounterTrade { Species = 079, Generation = 1, Level = 22, Version = GameVersion.RBY }, // Slowpoke - Wild Seel - new EncounterTrade { Species = 051, Generation = 1, Level = 15 }, // Dugtrio - Trade Lickitung - new EncounterTrade { Species = 047, Generation = 1, Level = 13 }, // Parasect - Trade Tangela + new EncounterTrade { Species = 051, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Dugtrio - Trade Lickitung + new EncounterTrade { Species = 047, Generation = 1, Level = 13, Version = GameVersion.RBY }, // Parasect - Trade Tangela }; internal static readonly EncounterTrade[] TradeGift_RBY_NoTradeback = TradeGift_RBY_Common.Concat(new[] { // Species & Minimum level (legal) possible to acquire at. - new EncounterTrade { Species = 124, Generation = 1, Level = 15 }, // Jynx - Fish Poliwhirl (GSC: 10) - new EncounterTrade { Species = 114, Generation = 1, Level = 13 }, // Tangela - Wild Venonat (GSC: 5) - new EncounterTrade { Species = 086, Generation = 1, Level = 28 }, // Seel - Wild Ponyta (GSC: 6) + new EncounterTrade { Species = 124, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Jynx - Fish Poliwhirl (GSC: 10) + new EncounterTrade { Species = 114, Generation = 1, Level = 13, Version = GameVersion.RBY }, // Tangela - Wild Venonat (GSC: 5) No different moves at level 13 + new EncounterTrade { Species = 086, Generation = 1, Level = 28, Version = GameVersion.RBY }, // Seel - Wild Ponyta (GSC: 6) - new EncounterTrade { Species = 115, Generation = 1, Level = 42 }, // Kangaskhan - Evolve Rhydon (GSC: 30) - new EncounterTrade { Species = 128, Generation = 1, Level = 28 }, // Tauros - Evolve Persian (GSC: 18) - new EncounterTradeCatchRate { Species = 093, Generation = 1, Level = 20, Catch_Rate = 45, EvolveOnTrade = true }, // Haunter - Trade Machoke (GSC: 10) - new EncounterTradeCatchRate { Species = 075, Generation = 1, Level = 16, Catch_Rate = 45, EvolveOnTrade = true }, // Graveler - Evolve Kadabra (GSC: 15) - new EncounterTradeCatchRate { Species = 098, Generation = 1, Level = 15, Catch_Rate = 204 }, // Krabby - Wild Growlithe (GSC: 5) + new EncounterTrade { Species = 115, Generation = 1, Level = 42, Version = GameVersion.RBY }, // Kangaskhan - Evolve Rhydon (GSC: 30) + new EncounterTrade { Species = 128, Generation = 1, Level = 28, Version = GameVersion.RBY }, // Tauros - Evolve Persian (GSC: 18) + new EncounterTradeCatchRate { Species = 093, Generation = 1, Level = 20, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Haunter - Trade Machoke (GSC: 10) + new EncounterTradeCatchRate { Species = 075, Generation = 1, Level = 16, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Graveler - Evolve Kadabra (GSC: 15) + new EncounterTradeCatchRate { Species = 098, Generation = 1, Level = 15, Catch_Rate = 204, Version = GameVersion.RBY }, // Krabby - Wild Growlithe (GSC: 5) //new EncounterTrade { Species = 122, Generation = 1, Level = 08 }, // Mr. Mime - Wild Clefairy (GSC: 6) - new EncounterTrade { Species = 067, Generation = 1, Level = 20 }, // Machoke - Wild Cubone (GSC: 10) - new EncounterTrade { Species = 112, Generation = 1, Level = 15 }, // Rhydon - Surf Golduck (GSC: 10) - new EncounterTrade { Species = 087, Generation = 1, Level = 15 }, // Dewgong - Wild Growlithe (GSC: 5) - new EncounterTrade { Species = 089, Generation = 1, Level = 25 }, // Muk - Wild Kangaskhan (GSC: 14) + new EncounterTradeCatchRate { Species = 067, Generation = 1, Level = 20, Catch_Rate = 180, EvolveOnTrade = true, Version = GameVersion.RBY }, // Machoke - Wild Cubone (GSC: 10) + new EncounterTrade { Species = 112, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Rhydon - Surf Golduck (GSC: 10) + new EncounterTrade { Species = 087, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Dewgong - Wild Growlithe (GSC: 5) + new EncounterTrade { Species = 089, Generation = 1, Level = 25, Version = GameVersion.RBY }, // Muk - Wild Kangaskhan (GSC: 14) }).ToArray(); internal static readonly EncounterTrade[] TradeGift_RBY_Tradeback = TradeGift_RBY_Common.Concat(new[] { // Trade gifts that can be obtained at a lower level due to the requested Pokémon being a lower level in GSC - new EncounterTrade { Species = 124, Generation = 1, Level = 10 }, // Jynx - Fish Poliwhirl (RBY: 15) - new EncounterTrade { Species = 114, Generation = 1, Level = 05 }, // Tangela - Wild Venonat (RBY: 13) - new EncounterTrade { Species = 086, Generation = 1, Level = 05 }, // Seel - Egg Ponyta (RBY: 28) + new EncounterTrade { Species = 124, Generation = 1, Level = 10, Version = GameVersion.RBY }, // Jynx - Fish Poliwhirl (RBY: 15) + new EncounterTrade { Species = 114, Generation = 1, Level = 05, Version = GameVersion.RBY }, // Tangela - Wild Venonat (RBY: 13) + new EncounterTrade { Species = 086, Generation = 1, Level = 05, Version = GameVersion.RBY }, // Seel - Egg Ponyta (RBY: 28) - new EncounterTrade { Species = 115, Generation = 1, Level = 30 }, // Kangaskhan - Evolve Rhydon (RBY: 42) - new EncounterTrade { Species = 128, Generation = 1, Level = 18 }, // Tauros - Evolve Persian (RBY: 28) - new EncounterTradeCatchRate { Species = 093, Generation = 1, Level = 10, Catch_Rate = 45, EvolveOnTrade = true }, // Haunter - Trade Machoke (RBY: 20) - new EncounterTradeCatchRate { Species = 075, Generation = 1, Level = 15, Catch_Rate = 45, EvolveOnTrade = true }, // Graveler - Evolve Kadabra (RBY: 16) - new EncounterTradeCatchRate { Species = 098, Generation = 1, Level = 05, Catch_Rate = 204 }, // Krabby - Egg Growlithe (RBY: 15) + new EncounterTrade { Species = 115, Generation = 1, Level = 30, Version = GameVersion.RBY }, // Kangaskhan - Evolve Rhydon (RBY: 42) + new EncounterTrade { Species = 128, Generation = 1, Level = 18, Version = GameVersion.RBY }, // Tauros - Evolve Persian (RBY: 28) + new EncounterTradeCatchRate { Species = 093, Generation = 1, Level = 10, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Haunter - Trade Machoke (RBY: 20) + new EncounterTradeCatchRate { Species = 075, Generation = 1, Level = 15, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Graveler - Evolve Kadabra (RBY: 16) + new EncounterTradeCatchRate { Species = 098, Generation = 1, Level = 05, Catch_Rate = 204, Version = GameVersion.RBY }, // Krabby - Egg Growlithe (RBY: 15) //new EncounterTrade { Species = 122, Generation = 1, Level = 08 }, // Mr. Mime - Wild Clefairy (RBY: 6) - new EncounterTrade { Species = 067, Generation = 1, Level = 05 }, // Machoke - Egg Cubone (RBY: 20) - new EncounterTrade { Species = 112, Generation = 1, Level = 10 }, // Rhydon - Surf Golduck (RBY: 15) - new EncounterTrade { Species = 087, Generation = 1, Level = 05 }, // Dewgong - Egg Growlithe (RBY: 15) - new EncounterTrade { Species = 089, Generation = 1, Level = 05 }, // Muk - Egg Kangaskhan (RBY: 25) + new EncounterTradeCatchRate { Species = 067, Generation = 1, Level = 05, Catch_Rate = 180, EvolveOnTrade = true, Version = GameVersion.RBY }, // Machoke - Egg Cubone (RBY: 20) + new EncounterTrade { Species = 112, Generation = 1, Level = 10, Version = GameVersion.RBY }, // Rhydon - Surf Golduck (RBY: 15) + new EncounterTrade { Species = 087, Generation = 1, Level = 05, Version = GameVersion.RBY }, // Dewgong - Egg Growlithe (RBY: 15) + new EncounterTrade { Species = 089, Generation = 1, Level = 05, Version = GameVersion.RBY }, // Muk - Egg Kangaskhan (RBY: 25) }).ToArray(); internal static readonly EncounterArea FishOldGood_RBY = new EncounterArea { Location = -1, Slots = new EncounterSlot[] { - new EncounterSlot1 {Species = 129, LevelMin = 05, LevelMax = 05, Type = SlotType.Old_Rod, Rate = -1, }, // Magikarp - new EncounterSlot1 {Species = 118, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, }, // Goldeen - new EncounterSlot1 {Species = 060, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, }, // Poliwag + new EncounterSlot1 {Species = 129, LevelMin = 05, LevelMax = 05, Type = SlotType.Old_Rod, Rate = -1, Version = GameVersion.RBY }, // Magikarp + new EncounterSlot1 {Species = 118, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, Version = GameVersion.RBY }, // Goldeen + new EncounterSlot1 {Species = 060, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, Version = GameVersion.RBY }, // Poliwag }}; internal static readonly int[] FutureEvolutionsGen1 = diff --git a/PKHeX.Core/Legality/Tables2.cs b/PKHeX.Core/Legality/Tables2.cs index 8e32a7d48..a1d48248b 100644 --- a/PKHeX.Core/Legality/Tables2.cs +++ b/PKHeX.Core/Legality/Tables2.cs @@ -69,6 +69,24 @@ namespace PKHeX.Core new EncounterSlot1 {Species = 127, LevelMin = 13, LevelMax = 14, Rate = 05, SlotNumber = 9}, // Pinsir } }}; + + internal static readonly EncounterArea[] EncounterSafari_GSC = { new EncounterArea { + Location = 81, + Slots = new EncounterSlot[] + { + new EncounterSlot1 {Species = 129, LevelMin = 10, LevelMax = 10, Type = SlotType.Old_Rod_Safari}, // Magikarp + new EncounterSlot1 {Species = 098, LevelMin = 10, LevelMax = 10, Type = SlotType.Old_Rod_Safari}, // Krabby + new EncounterSlot1 {Species = 098, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod_Safari}, // Krabby + new EncounterSlot1 {Species = 129, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod_Safari}, // Magikarp + new EncounterSlot1 {Species = 222, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod_Safari}, // Corsola + new EncounterSlot1 {Species = 120, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod_Safari}, // Staryu + new EncounterSlot1 {Species = 098, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod_Safari}, // Krabby + new EncounterSlot1 {Species = 222, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod_Safari}, // Corsola + new EncounterSlot1 {Species = 120, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod_Safari}, // Staryu + new EncounterSlot1 {Species = 121, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod_Safari}, // Kingler + } + }}; + internal static readonly EncounterStatic[] Encounter_GSC_Common = { new EncounterStatic { Species = 152, Level = 05, Location = 001, Version = GameVersion.GSC }, // Chikorita @ New Bark Town diff --git a/PKHeX.Core/PKHeX.Core.csproj b/PKHeX.Core/PKHeX.Core.csproj index d96b00677..53768f62d 100644 --- a/PKHeX.Core/PKHeX.Core.csproj +++ b/PKHeX.Core/PKHeX.Core.csproj @@ -96,6 +96,7 @@ + @@ -192,6 +193,7 @@ + diff --git a/PKHeX.Core/Resources/byte/trees_h_c.pkl b/PKHeX.Core/Resources/byte/trees_h_c.pkl new file mode 100644 index 000000000..2897e196b Binary files /dev/null and b/PKHeX.Core/Resources/byte/trees_h_c.pkl differ diff --git a/PKHeX.Core/Resources/text/en/LegalityCheckStrings_en.txt b/PKHeX.Core/Resources/text/en/LegalityCheckStrings_en.txt index d952d4e31..8acf94cdb 100644 --- a/PKHeX.Core/Resources/text/en/LegalityCheckStrings_en.txt +++ b/PKHeX.Core/Resources/text/en/LegalityCheckStrings_en.txt @@ -1,346 +1,352 @@ -V = Valid. -V193 = Legal! -V190 = Internal error. -V189 = Analysis not available for this Pokémon. -V196 = {0}: {1} -V191 = {0} Move {1}: {2} -V192 = {0} Relearn Move {1}: {2} -V195 = Encounter Type: {0} -V500 = Indeterminate -V501 = Invalid -V502 = Fishy -V503 = Valid -V504 = Not Implemented -V205 = OT -V206 = HT -V167 = Empty Move. -V171 = Egg Move. -V172 = Relearnable Move. -V173 = Learned by TM/HM. -V174 = Learned by Move Tutor. -V175 = Special Non-Relearn Move. -V177 = Learned by Level-up. -V330 = Learned by Level-up in Generation {0}. -V331 = Learned by TM/HM in Generation {0}. -V332 = Learned by Move Tutor in Generation {0}. -V333 = Event Egg Move. -V344 = Inherited Egg move. -V345 = Inherited move learned by Level-up. -V346 = Inherited tutor move. -V349 = Inherited TM/HM move. -V355 = Learned by evolving Nincada into Ninjask. -V356 = Learned by evolving Nincada into Ninjask in Generation {0}. -V361 = Default move. -V362 = Default move in Generation {0}. -V372 = {0} Berry -V380 = Encounter Type matches encounter. -V382 = Encounter Type not implemented for Pokémon encounter. -V391 = Porygon with valid Type A and B values. -V392 = Valid Type A, matches species type. -V393 = Valid Type B, matches species type. -V394 = Catch rate matches a valid held item from Generation 2. -V398 = Catch Rate matches any species from Pokémon evolution chain. -V403 = Valid International Stadium OT. -V404 = Valid Japanese Stadium OT. -V203 = Genderless Pokémon should not have a gender. -V201 = Encryption Constant is not set. -V204 = Held item is unreleased. -V187 = Species does not exist in origin game. -V188 = Fateful Encounter with no matching Encounter. Has the Mystery Gift data been contributed? -V194 = Ingame Trade for Sun/Moon not implemented. -V250 = Gender matches PID. -V251 = PID-Gender mismatch. -V252 = Nature matches PID. -V253 = PID-Nature mismatch. -V207 = PID is not set. -V208 = Encryption Constant matches PID. -V209 = Static Encounter shiny mismatch. -V210 = Wurmple evolution Encryption Constant mismatch. -V211 = Encryption Constant matches shinyxored PID. -V212 = Wurmple Evolution: {0} -V215 = PID should be equal to EC [with top bit flipped]! -V216 = PID should be equal to EC! -V220 = N's Pokémon cannot be shiny. -V221 = Hidden Grotto captures cannot be shiny. -V14 = Egg matches language Egg name. -V17 = Nickname does not match another species name. -V18 = Nickname matches species name. -V19 = Nickname matches demo language name. -V11 = Ingame Trade OT and Nickname have not been altered. -V1 = Nickname too long. -V2 = Nickname is empty. -V4 = Language ID > 8. -V5 = Language ID > 10. -V222 = Cannot be given this Nickname. -V3 = Species index invalid for Nickname comparison. -V20 = Nickname does not match species name. -V13 = Egg name does not match language Egg name. -V12 = Egg must be nicknamed. -V224 = Egg must be not nicknamed. -V7 = Ingame Trade invalid version? -V8 = Ingame Trade invalid index? -V10 = Ingame Trade OT has been altered. -V9 = Ingame Trade Nickname has been altered. -V15 = Nickname matches another species name (+language). -V16 = Nickname flagged, matches species name. -V0 = Event gift has been nicknamed. -V21 = Matches: {0} {1} -V25 = EV total cannot be above 510. -V22 = Eggs cannot receive EVs. -V23 = All EVs are zero, but leveled above Met Level. -V24 = 2 EVs remaining. -V26 = EVs cannot go above 252. -V27 = EVs are all equal. -V31 = All IVs are 0. -V32 = All IVs are equal. -V218 = All IVs of N's Pokémon should be 30. -V28 = Should have at least {0} IVs = 31. -V29 = Friend Safari captures should have at least 2 IVs = 31. -V30 = IVs do not match Mystery Gift Data. -V38 = OT Name too long. -V39 = Incorrect RBY event OT Name. -V34 = SID should be 0. -V219 = The Name/TID/SID of N is incorrect. -V33 = TID and SID are 0. -V35 = TID and SID are equal. -V36 = TID is zero. -V37 = SID is zero. -V40 = Can't Hyper Train a Pokémon that isn't level 100. -V41 = Can't Hyper Train a Pokémon with perfect IVs. -V42 = Can't Hyper Train a perfect IV. -V49 = Valid Pokémon Link gift. -V47 = Pokémon Link gift Shiny mismatch. -V48 = Pokémon Link gift should not be Fateful Encounter. -V43 = Can't find matching Pokémon Link gift. -V44 = Can't obtain this Pokémon Link gift in XY. -V45 = Can't obtain this Pokémon Link gift in ORAS. -V46 = Can't obtain this Pokémon Link gift in SM. -V63 = Valid un-hatched Egg. -V53 = Able to hatch an Egg at Met Location. -V56 = Able to hatch a traded Egg at Met Location. -V54 = Can't hatch an Egg at Met Location. -V55 = Can't obtain Egg from Egg Location. -V57 = Can't transfer Eggs between Generations. -V50 = Can't obtain Egg for this species. -V51 = Invalid Met Location for hatched Egg. -V52 = Invalid Met Level, expected {0}. -V58 = Invalid Met Level for transfer. -V59 = Invalid Egg Location, expected none. -V60 = Invalid Met Location, expected Pal Park. -V61 = Invalid Met Location, expected Transporter. -V62 = Invalid Egg Location, shouldn't be 'traded' while an Egg. -V66 = Valid Friend Safari encounter. -V64 = Friend Safari: Not valid color. -V6 = Friend Safari: Not average sized. -V65 = Friend Safari: Not Spring form. -V67 = Valid Wild Encounter at location (Pressure/Hustle/Vital Spirit). -V68 = Valid Wild Encounter at location. -V69 = Valid Wild Encounter at location (White Flute & Pressure/Hustle/Vital Spirit). -V70 = Valid Wild Encounter at location (White Flute). -V71 = Valid Wild Encounter at location (Black Flute & Pressure/Hustle/Vital Spirit). -V72 = Valid Wild Encounter at location (Black Flute). -V73 = Valid Wild Encounter at location (DexNav). -V76 = Valid ingame trade. -V75 = Valid gift/static encounter. -V74 = Static encounter relearn move mismatch. -V77 = Can't obtain Species from Virtual Console games. -V79 = Can't obtain Special encounter in Virtual Console games. -V78 = Unable to match to a Mystery Gift in the database. -V80 = Unable to match an encounter from origin game. -V81 = Invalid Transfer Met Location. -V82 = Mewtwo cannot be transferred while knowing Pay Day. -V88 = Current level is not below met level. -V83 = Met Level does not match Mystery Gift level. -V84 = Current Level below Mystery Gift level. -V85 = Current level is below met level. -V86 = Evolution not valid (or level/trade evolution unsatisfied). -V87 = Current experience matches level threshold. -V89 = Can't Super Train an Egg. -V90 = Super Training missions are not available in games visited. -V91 = Can't have active Super Training unlocked flag for origins. -V92 = Can't have active Super Training complete flag for origins. -V93 = Super Training complete flag mismatch. -V94 = Distribution Super Training missions are not released. -V98 = Unused Super Training Flag is flagged. -V107 = Ability is not valid for species/form. -V108 = Hidden Ability mismatch for encounter type. -V223 = Ability mismatch for encounter. -V109 = Ability modified with Ability Capsule. -V110 = Ability does not match Mystery Gift. -V111 = Hidden Ability on non-SOS wild encounter. -V300 = Hidden Ability on non-horde/friend safari wild encounter. -V112 = Hidden Ability not available. -V217 = Hidden Grotto captures should have Hidden Ability. -V115 = Ability matches ability number. -V113 = Ability does not match PID. -V114 = Ability does not match ability number. -V119 = Correct ball for encounter type. -V118 = Can't have ball for encounter type. -V116 = Can't have Heavy Ball for light, low-catch rate species (Gen VII). -V117 = Can't have Master Ball for regular Egg. -V120 = Can't have Cherish Ball for regular Egg. -V121 = Can't obtain species in Ball. -V122 = Can't obtain Hidden Ability with Ball. -V123 = Ball possible for species. -V125 = No check satisfied, assuming illegal. -V126 = Ball unobtainable in origin Generation. -V145 = History block is valid. -V155 = {0} Memory is valid. -V127 = Skipped History check due to other check being invalid. -V128 = No History Block to check. -V129 = OT Affection should be 0. -V130 = Can't have any OT Memory. -V124 = Current handler cannot be past gen OT for transferred specimen. -V131 = HT Gender invalid: {0} -V132 = Event OT Friendship does not match base friendship. -V133 = Event OT Affection should be zero. -V134 = Current handler should not be Event OT. -V138 = Contest Stats should be 0. -V301 = Invalid Console Region. -V302 = Geolocation: Country is not in 3DS region. -V303 = Geolocation: Country is in 3DS region. -V137 = GeoLocation Memory: Memories should be present. -V135 = GeoLocation Memory: Gap/Blank present. -V136 = GeoLocation Memory: Region without Country. -V146 = GeoLocation Memory: HT Name present but has no previous Country. -V147 = GeoLocation Memory: Previous country of residence present with no Handling Trainer. -V139 = Untraded: Current handler should not be the Handling Trainer. -V140 = Untraded: Handling Trainer Friendship should be 0. -V141 = Untraded: Handling Trainer Affection should be 0. -V142 = Untraded: Requires a trade evolution. -V143 = Untraded: Beauty is not high enough for Level-up Evolution. -V144 = Untraded: Beauty is high enough but still Level 1. -V148 = Memory: Handling Trainer Memory present with no Handling Trainer name. -V150 = Memory: Handling Trainer Memory missing. -V152 = Memory: Original Trainer Memory missing. -V329 = Memory: Not cleared properly. -V149 = Memory: Can't have Handling Trainer Memory as Egg. -V151 = Memory: Can't have Original Trainer Memory as Egg. -V164 = {0} Memory: Species can be captured in game. -V153 = {0} Memory: Species can't learn this move. -V154 = {0} Memory: Location doesn't have a Pokémon Center. -V160 = {0} Memory: {0} did not hatch this. -V202 = {0} Memory: {0} did not catch this. -V161 = {0} Memory: Link Trade is not a valid first memory. -V162 = {0} Memory: Can't obtain Location on {0} Version. -V163 = {0} Memory: Can't obtain Memory on {0} Version. -V165 = {0} Memory: Can't capture species in game. -V197 = {0} Memory: Should be index {1}. -V198 = {0} Memory: Intensity should be index {1}. -V199 = {0} Memory: TextVar should be index {1}. -V200 = {0} Memory: Feeling should be index {1}. -V168 = Duplicate Move. -V176 = Invalid Move. -V166 = Invalid Move (Sketch). -V169 = Keldeo Move/Form mismatch. -V181 = Expected the following Relearn Moves: {0} -V170 = Relearn Moves missing: {0} -V178 = Expected: {0}. -V179 = Base Egg move. -V180 = Base Egg move missing. -V182 = Not an expected Relearnable move. -V183 = Not an expected DexNav move. -V184 = Expected no Relearn Move in slot. -V185 = Egg Moves Source: {0}. -V186 = Egg Move set check unimplemented. -V156 = Should have a Link Trade HT Memory. -V157 = Should have a HT Memory TextVar value (somewhere). -V158 = Should have a HT Memory Intensity value (1st). -V159 = Should have a HT Memory Feeling value 0-9. -V318 = Form is Valid. -V304 = Form Count is out of range. Expected <= {0}, got {1}. -V305 = Cosplay Pikachu cannot have the default form. -V306 = Only Cosplay Pikachu can have this form. -V307 = Event Pikachu cannot have the default form. -V308 = Held item does not match Form. -V309 = Held item matches Form. -V310 = Form cannot exist outside of a battle. -V311 = Event Vivillon pattern on pre-evolution. -V312 = Invalid Vivillon pattern. -V313 = Valid Vivillon pattern. -V314 = Invalid Eternal Flower encounter. -V315 = Valid Eternal Flower encounter. -V316 = Form cannot exist outside of Party. -V317 = Form cannot be obtained for pre-Alola Generation games. -V319 = Cannot apply PP Ups to an Egg. -V320 = Cannot increase Contest Stats of an Egg. -V321 = Mystery Gift Fateful Encounter. -V322 = Mystery Gift Fateful Encounter flag missing. -V323 = Special ingame Fateful Encounter. -V324 = Special ingame Fateful Encounter flag missing. -V325 = Fateful Encounter should not be checked. -V326 = Special ingame N's Sparkle flag missing. -V327 = Special ingame N's Sparkle flag should not be checked. -V328 = Version Specific evolution requires a trade to opposite version. A Handling Trainer is required. -V334 = Non-tradeback Egg move. Incompatible with Generation 1 exclusive moves. -V335 = Generation 1 exclusive move. Incompatible with Non-tradeback moves. -V336 = Egg Move. Incompatible with event Egg moves. -V337 = Event Egg Move. Incompatible with normal Egg moves. -V338 = Defog and whirpool. One of the two moves should have been removed before transfered to Generation 5. -V339 = Generation {0} HM. Should have been removed before transfered to Generation {1}. -V340 = Not an expected Egg move. -V341 = Egg Move.Not expected in an event Egg. -V342 = Event Egg move missing. -V343 = Expected the following Moves: {0} -V347 = Inherited move learned by Level-up.Not expected in an event Egg. -V348 = Inherited tutor move. Not expected in an event Egg. -V350 = Inherited TM/HM move. Not expected in an event Egg. -V351 = Invalid Met Location, expected Transporter or Crown. -V352 = Arceus from Hall of Origin. Unreleased event. -V353 = Non japanese Mew from Faraway Island. Unreleased event. -V354 = Non Platinum Shaymin from Flower Paradise. Unreleased event. -V383 = Non Platinum Darkrai from Newmoon Island. Unreleased event. -V384 = Johto Route 45 surfing encounter. Unreachable Water tiles. -V357 = Only one Ninjask move allowed. -V358 = Inherited move learned by Level-up. Incompatible with event Egg moves. -V359 = Unable to match a gift Egg encounter from origin game. -V360 = Unable to match an event Egg encounter from origin game. -V363 = Incompatible moves. Learned at the same level in Red/Blue and Yellow. -V365 = Incompatible evolution moves. {0} Move learned at a lower level than other {1} moves. -V366 = Incompatible evolution moves. {1} Move learned at a higher level than other {0} moves. -V367 = Individual EV for a level 100 encounter in Generation 4 cannot be greater than 100. -V368 = Eggs can not be infected with Pokérus. -V369 = Invalid E-Reader Berry. -V370 = Japanese E-Reader Berry in international savegame. -V371 = American E-Reader Berry in Japanese savegame. -V373 = Ability does not match Generation 3 species ability. -V374 = Invalid Egg hatch cycles. -V375 = {0} Egg Move. Incompatible with {1} Egg moves. -V376 = {0} Exclusive Move. Incompatible with {1} Egg moves. -V377 = Egg Move. Not expected in a gift Egg. -V378 = Inherited move learned by Level-up. Not expected in a gift Egg. -V379 = {0} Inherited Move. Incompatible with {1} inherited moves. -V381 = Encounter Type does not match encounter. -V385 = Moves combinations is not compatible with {0} evolution. -V386 = Porygon with invalid Type A value. -V387 = Porygon with invalid Type B value. -V388 = Porygon with invalid Type A and B values. Does not a match a valid type combination. -V389 = Invalid Type A, does not match species type. -V390 = Invalid Type B, does not match species type. -V395 = Catch rate does not match a valid held item from Generation 2. -V396 = Catch rate match species without encounters. Expected a preevolution catch rate. -V397 = Catch rate does not match any species from Pokémon evolution chain. -V399 = Catch rate does not match any species from Pokémon evolution chain or any Generation 2 held items. -V400 = Unable to match encounter conditions to a possible RNG frame. -V401 = In-game trade {0} should have evolved into {1}. -V402 = Incorrect Stadium OT. -V405 = Outsider {0} should have evolved into {1}. -V406 = Non Japanese Shadow E-reader Pokémon. Unreleased encounter. -V407 = OT from Colosseum/XD cannot be female. -V408 = Female OT from Generation 1/2 is invalid. -V409 = Mystery Gift shiny mismatch. -V410 = Mystery Gift fixed PID mismatch. -V411 = Encounter Type PID mismatch. -V412 = Non-tradeback pre evolution move. Incompatible with Generation 1 exclusive moves. -V413 = Unreleased event. -V414 = Eggs cannot have Shiny Leaf/Crown. -V415 = Eggs cannot have Pokéathlon stats. -V416 = Mystery Gift cannot be received by this version. -V417 = Suspicious Original Trainer details. -V418 = Individual EV without changing EXP cannot be greater than {0}. -V419 = Eggs cannot hold items. -V420 = Eggs cannot have modified PP counts. -V602 = All ribbons accounted for. -V600 = Missing Ribbons: {0} -V601 = Invalid Ribbons: {0} -V603 = Can't receive Ribbon(s) as an Egg. +V = Valid. +V193 = Legal! +V190 = Internal error. +V189 = Analysis not available for this Pokémon. +V196 = {0}: {1} +V191 = {0} Move {1}: {2} +V192 = {0} Relearn Move {1}: {2} +V195 = Encounter Type: {0} +V500 = Indeterminate +V501 = Invalid +V502 = Fishy +V503 = Valid +V504 = Not Implemented +V205 = OT +V206 = HT +V167 = Empty Move. +V171 = Egg Move. +V172 = Relearnable Move. +V173 = Learned by TM/HM. +V174 = Learned by Move Tutor. +V175 = Special Non-Relearn Move. +V177 = Learned by Level-up. +V330 = Learned by Level-up in Generation {0}. +V331 = Learned by TM/HM in Generation {0}. +V332 = Learned by Move Tutor in Generation {0}. +V333 = Event Egg Move. +V344 = Inherited Egg move. +V345 = Inherited move learned by Level-up. +V346 = Inherited tutor move. +V349 = Inherited TM/HM move. +V355 = Learned by evolving Nincada into Ninjask. +V356 = Learned by evolving Nincada into Ninjask in Generation {0}. +V361 = Default move. +V362 = Default move in Generation {0}. +V372 = {0} Berry +V380 = Encounter Type matches encounter. +V382 = Encounter Type not implemented for Pokémon encounter. +V391 = Porygon with valid Type A and B values. +V392 = Valid Type A, matches species type. +V393 = Valid Type B, matches species type. +V394 = Catch rate matches a valid held item from Generation 2. +V398 = Catch Rate matches any species from Pokémon evolution chain. +V403 = Valid International Stadium OT. +V404 = Valid Japanese Stadium OT. +V203 = Genderless Pokémon should not have a gender. +V201 = Encryption Constant is not set. +V204 = Held item is unreleased. +V187 = Species does not exist in origin game. +V188 = Fateful Encounter with no matching Encounter. Has the Mystery Gift data been contributed? +V194 = Ingame Trade for Sun/Moon not implemented. +V250 = Gender matches PID. +V251 = PID-Gender mismatch. +V252 = Nature matches PID. +V253 = PID-Nature mismatch. +V207 = PID is not set. +V208 = Encryption Constant matches PID. +V209 = Static Encounter shiny mismatch. +V210 = Wurmple evolution Encryption Constant mismatch. +V211 = Encryption Constant matches shinyxored PID. +V212 = Wurmple Evolution: {0} +V215 = PID should be equal to EC [with top bit flipped]! +V216 = PID should be equal to EC! +V220 = N's Pokémon cannot be shiny. +V221 = Hidden Grotto captures cannot be shiny. +V14 = Egg matches language Egg name. +V17 = Nickname does not match another species name. +V18 = Nickname matches species name. +V19 = Nickname matches demo language name. +V11 = Ingame Trade OT and Nickname have not been altered. +V1 = Nickname too long. +V2 = Nickname is empty. +V4 = Language ID > 8. +V5 = Language ID > 10. +V222 = Cannot be given this Nickname. +V3 = Species index invalid for Nickname comparison. +V20 = Nickname does not match species name. +V13 = Egg name does not match language Egg name. +V12 = Egg must be nicknamed. +V224 = Egg must be not nicknamed. +V7 = Ingame Trade invalid version? +V8 = Ingame Trade invalid index? +V10 = Ingame Trade OT has been altered. +V9 = Ingame Trade Nickname has been altered. +V15 = Nickname matches another species name (+language). +V16 = Nickname flagged, matches species name. +V0 = Event gift has been nicknamed. +V21 = Matches: {0} {1} +V25 = EV total cannot be above 510. +V22 = Eggs cannot receive EVs. +V23 = All EVs are zero, but leveled above Met Level. +V24 = 2 EVs remaining. +V26 = EVs cannot go above 252. +V27 = EVs are all equal. +V31 = All IVs are 0. +V32 = All IVs are equal. +V218 = All IVs of N's Pokémon should be 30. +V28 = Should have at least {0} IVs = 31. +V29 = Friend Safari captures should have at least 2 IVs = 31. +V30 = IVs do not match Mystery Gift Data. +V38 = OT Name too long. +V39 = Incorrect RBY event OT Name. +V34 = SID should be 0. +V219 = The Name/TID/SID of N is incorrect. +V33 = TID and SID are 0. +V35 = TID and SID are equal. +V36 = TID is zero. +V37 = SID is zero. +V40 = Can't Hyper Train a Pokémon that isn't level 100. +V41 = Can't Hyper Train a Pokémon with perfect IVs. +V42 = Can't Hyper Train a perfect IV. +V49 = Valid Pokémon Link gift. +V47 = Pokémon Link gift Shiny mismatch. +V48 = Pokémon Link gift should not be Fateful Encounter. +V43 = Can't find matching Pokémon Link gift. +V44 = Can't obtain this Pokémon Link gift in XY. +V45 = Can't obtain this Pokémon Link gift in ORAS. +V46 = Can't obtain this Pokémon Link gift in SM. +V63 = Valid un-hatched Egg. +V53 = Able to hatch an Egg at Met Location. +V56 = Able to hatch a traded Egg at Met Location. +V54 = Can't hatch an Egg at Met Location. +V55 = Can't obtain Egg from Egg Location. +V57 = Can't transfer Eggs between Generations. +V50 = Can't obtain Egg for this species. +V51 = Invalid Met Location for hatched Egg. +V52 = Invalid Met Level, expected {0}. +V58 = Invalid Met Level for transfer. +V59 = Invalid Egg Location, expected none. +V60 = Invalid Met Location, expected Pal Park. +V61 = Invalid Met Location, expected Transporter. +V62 = Invalid Egg Location, shouldn't be 'traded' while an Egg. +V66 = Valid Friend Safari encounter. +V64 = Friend Safari: Not valid color. +V6 = Friend Safari: Not average sized. +V65 = Friend Safari: Not Spring form. +V67 = Valid Wild Encounter at location (Pressure/Hustle/Vital Spirit). +V68 = Valid Wild Encounter at location. +V69 = Valid Wild Encounter at location (White Flute & Pressure/Hustle/Vital Spirit). +V70 = Valid Wild Encounter at location (White Flute). +V71 = Valid Wild Encounter at location (Black Flute & Pressure/Hustle/Vital Spirit). +V72 = Valid Wild Encounter at location (Black Flute). +V73 = Valid Wild Encounter at location (DexNav). +V76 = Valid ingame trade. +V75 = Valid gift/static encounter. +V74 = Static encounter relearn move mismatch. +V77 = Can't obtain Species from Virtual Console games. +V79 = Can't obtain Special encounter in Virtual Console games. +V78 = Unable to match to a Mystery Gift in the database. +V80 = Unable to match an encounter from origin game. +V81 = Invalid Transfer Met Location. +V82 = Mewtwo cannot be transferred while knowing Pay Day. +V88 = Current level is not below met level. +V83 = Met Level does not match Mystery Gift level. +V84 = Current Level below Mystery Gift level. +V85 = Current level is below met level. +V86 = Evolution not valid (or level/trade evolution unsatisfied). +V87 = Current experience matches level threshold. +V89 = Can't Super Train an Egg. +V90 = Super Training missions are not available in games visited. +V91 = Can't have active Super Training unlocked flag for origins. +V92 = Can't have active Super Training complete flag for origins. +V93 = Super Training complete flag mismatch. +V94 = Distribution Super Training missions are not released. +V98 = Unused Super Training Flag is flagged. +V107 = Ability is not valid for species/form. +V108 = Hidden Ability mismatch for encounter type. +V223 = Ability mismatch for encounter. +V109 = Ability modified with Ability Capsule. +V110 = Ability does not match Mystery Gift. +V111 = Hidden Ability on non-SOS wild encounter. +V300 = Hidden Ability on non-horde/friend safari wild encounter. +V112 = Hidden Ability not available. +V217 = Hidden Grotto captures should have Hidden Ability. +V115 = Ability matches ability number. +V113 = Ability does not match PID. +V114 = Ability does not match ability number. +V119 = Correct ball for encounter type. +V118 = Can't have ball for encounter type. +V116 = Can't have Heavy Ball for light, low-catch rate species (Gen VII). +V117 = Can't have Master Ball for regular Egg. +V120 = Can't have Cherish Ball for regular Egg. +V121 = Can't obtain species in Ball. +V122 = Can't obtain Hidden Ability with Ball. +V123 = Ball possible for species. +V125 = No check satisfied, assuming illegal. +V126 = Ball unobtainable in origin Generation. +V145 = History block is valid. +V155 = {0} Memory is valid. +V127 = Skipped History check due to other check being invalid. +V128 = No History Block to check. +V129 = OT Affection should be 0. +V130 = Can't have any OT Memory. +V124 = Current handler cannot be past gen OT for transferred specimen. +V131 = HT Gender invalid: {0} +V132 = Event OT Friendship does not match base friendship. +V133 = Event OT Affection should be zero. +V134 = Current handler should not be Event OT. +V138 = Contest Stats should be 0. +V301 = Invalid Console Region. +V302 = Geolocation: Country is not in 3DS region. +V303 = Geolocation: Country is in 3DS region. +V137 = GeoLocation Memory: Memories should be present. +V135 = GeoLocation Memory: Gap/Blank present. +V136 = GeoLocation Memory: Region without Country. +V146 = GeoLocation Memory: HT Name present but has no previous Country. +V147 = GeoLocation Memory: Previous country of residence present with no Handling Trainer. +V139 = Untraded: Current handler should not be the Handling Trainer. +V140 = Untraded: Handling Trainer Friendship should be 0. +V141 = Untraded: Handling Trainer Affection should be 0. +V142 = Untraded: Requires a trade evolution. +V143 = Untraded: Beauty is not high enough for Level-up Evolution. +V144 = Untraded: Beauty is high enough but still Level 1. +V148 = Memory: Handling Trainer Memory present with no Handling Trainer name. +V150 = Memory: Handling Trainer Memory missing. +V152 = Memory: Original Trainer Memory missing. +V329 = Memory: Not cleared properly. +V149 = Memory: Can't have Handling Trainer Memory as Egg. +V151 = Memory: Can't have Original Trainer Memory as Egg. +V164 = {0} Memory: Species can be captured in game. +V153 = {0} Memory: Species can't learn this move. +V154 = {0} Memory: Location doesn't have a Pokémon Center. +V160 = {0} Memory: {0} did not hatch this. +V202 = {0} Memory: {0} did not catch this. +V161 = {0} Memory: Link Trade is not a valid first memory. +V162 = {0} Memory: Can't obtain Location on {0} Version. +V163 = {0} Memory: Can't obtain Memory on {0} Version. +V165 = {0} Memory: Can't capture species in game. +V197 = {0} Memory: Should be index {1}. +V198 = {0} Memory: Intensity should be index {1}. +V199 = {0} Memory: TextVar should be index {1}. +V200 = {0} Memory: Feeling should be index {1}. +V168 = Duplicate Move. +V176 = Invalid Move. +V166 = Invalid Move (Sketch). +V169 = Keldeo Move/Form mismatch. +V181 = Expected the following Relearn Moves: {0} +V170 = Relearn Moves missing: {0} +V178 = Expected: {0}. +V179 = Base Egg move. +V180 = Base Egg move missing. +V182 = Not an expected Relearnable move. +V183 = Not an expected DexNav move. +V184 = Expected no Relearn Move in slot. +V185 = Egg Moves Source: {0}. +V186 = Egg Move set check unimplemented. +V156 = Should have a Link Trade HT Memory. +V157 = Should have a HT Memory TextVar value (somewhere). +V158 = Should have a HT Memory Intensity value (1st). +V159 = Should have a HT Memory Feeling value 0-9. +V318 = Form is Valid. +V304 = Form Count is out of range. Expected <= {0}, got {1}. +V305 = Cosplay Pikachu cannot have the default form. +V306 = Only Cosplay Pikachu can have this form. +V307 = Event Pikachu cannot have the default form. +V308 = Held item does not match Form. +V309 = Held item matches Form. +V310 = Form cannot exist outside of a battle. +V311 = Event Vivillon pattern on pre-evolution. +V312 = Invalid Vivillon pattern. +V313 = Valid Vivillon pattern. +V314 = Invalid Eternal Flower encounter. +V315 = Valid Eternal Flower encounter. +V316 = Form cannot exist outside of Party. +V317 = Form cannot be obtained for pre-Alola Generation games. +V319 = Cannot apply PP Ups to an Egg. +V320 = Cannot increase Contest Stats of an Egg. +V321 = Mystery Gift Fateful Encounter. +V322 = Mystery Gift Fateful Encounter flag missing. +V323 = Special ingame Fateful Encounter. +V324 = Special ingame Fateful Encounter flag missing. +V325 = Fateful Encounter should not be checked. +V326 = Special ingame N's Sparkle flag missing. +V327 = Special ingame N's Sparkle flag should not be checked. +V328 = Version Specific evolution requires a trade to opposite version. A Handling Trainer is required. +V334 = Non-tradeback Egg move. Incompatible with Generation 1 exclusive moves. +V335 = Generation 1 exclusive move. Incompatible with Non-tradeback moves. +V336 = Egg Move. Incompatible with event Egg moves. +V337 = Event Egg Move. Incompatible with normal Egg moves. +V338 = Defog and whirpool. One of the two moves should have been removed before transfered to Generation 5. +V339 = Generation {0} HM. Should have been removed before transfered to Generation {1}. +V340 = Not an expected Egg move. +V341 = Egg Move.Not expected in an event Egg. +V342 = Event Egg move missing. +V343 = Expected the following Moves: {0} +V347 = Inherited move learned by Level-up.Not expected in an event Egg. +V348 = Inherited tutor move. Not expected in an event Egg. +V350 = Inherited TM/HM move. Not expected in an event Egg. +V351 = Invalid Met Location, expected Transporter or Crown. +V352 = Arceus from Hall of Origin. Unreleased event. +V353 = Non japanese Mew from Faraway Island. Unreleased event. +V354 = Non Platinum Shaymin from Flower Paradise. Unreleased event. +V383 = Non Platinum Darkrai from Newmoon Island. Unreleased event. +V384 = Johto Route 45 surfing encounter. Unreachable Water tiles. +V357 = Only one Ninjask move allowed. +V358 = Inherited move learned by Level-up. Incompatible with event Egg moves. +V359 = Unable to match a gift Egg encounter from origin game. +V360 = Unable to match an event Egg encounter from origin game. +V363 = Incompatible moves. Learned at the same level in Red/Blue and Yellow. +V365 = Incompatible evolution moves. {0} Move learned at a lower level than other {1} moves. +V366 = Incompatible evolution moves. {1} Move learned at a higher level than other {0} moves. +V367 = Individual EV for a level 100 encounter in Generation 4 cannot be greater than 100. +V368 = Eggs can not be infected with Pokérus. +V369 = Invalid E-Reader Berry. +V370 = Japanese E-Reader Berry in international savegame. +V371 = American E-Reader Berry in Japanese savegame. +V373 = Ability does not match Generation 3 species ability. +V374 = Invalid Egg hatch cycles. +V375 = {0} Egg Move. Incompatible with {1} Egg moves. +V376 = {0} Exclusive Move. Incompatible with {1} Egg moves. +V377 = Egg Move. Not expected in a gift Egg. +V378 = Inherited move learned by Level-up. Not expected in a gift Egg. +V379 = {0} Inherited Move. Incompatible with {1} inherited moves. +V381 = Encounter Type does not match encounter. +V385 = Moves combinations is not compatible with {0} evolution. +V386 = Porygon with invalid Type A value. +V387 = Porygon with invalid Type B value. +V388 = Porygon with invalid Type A and B values. Does not a match a valid type combination. +V389 = Invalid Type A, does not match species type. +V390 = Invalid Type B, does not match species type. +V395 = Catch rate does not match a valid held item from Generation 2. +V396 = Catch rate match species without encounters. Expected a preevolution catch rate. +V397 = Catch rate does not match any species from Pokémon evolution chain. +V399 = Catch rate does not match any species from Pokémon evolution chain or any Generation 2 held items. +V400 = Unable to match encounter conditions to a possible RNG frame. +V401 = In-game trade {0} should have evolved into {1}. +V402 = Incorrect Stadium OT. +V405 = Outsider {0} should have evolved into {1}. +V406 = Non Japanese Shadow E-reader Pokémon. Unreleased encounter. +V407 = OT from Colosseum/XD cannot be female. +V408 = Female OT from Generation 1/2 is invalid. +V409 = Mystery Gift shiny mismatch. +V410 = Mystery Gift fixed PID mismatch. +V411 = Encounter Type PID mismatch. +V412 = Non-tradeback pre evolution move. Incompatible with Generation 1 exclusive moves. +V413 = Unreleased event. +V414 = Eggs cannot have Shiny Leaf/Crown. +V415 = Eggs cannot have Pokéathlon stats. +V416 = Mystery Gift cannot be received by this version. +V417 = Suspicious Original Trainer details. +V418 = Individual EV without changing EXP cannot be greater than {0}. +V419 = Eggs cannot hold items. +V420 = Eggs cannot have modified PP counts. +V602 = All ribbons accounted for. +V600 = Missing Ribbons: {0} +V601 = Invalid Ribbons: {0} +V603 = Can't receive Ribbon(s) as an Egg. +V604 = Found a tree for crystal heabutt encounter that matches OTID. +V605 = Found an unreacheable tree for crystal heabutt encounter that matches OTID. +V606 = Could not found a tree for crystal heabutt encounter that matches OTID. +V607 = Kanto Route 14 fishing encounter. Unreachable Water tiles. +V608 = National Park fishing encounter. Unreachable Water tiles. +V609 = Generation 2 safari zone fishing encounter. Unreachable zone. diff --git a/PKHeX.Core/Resources/text/ko/LegalityCheckStrings_ko.txt b/PKHeX.Core/Resources/text/ko/LegalityCheckStrings_ko.txt index b91b2bc4c..8222488ca 100644 --- a/PKHeX.Core/Resources/text/ko/LegalityCheckStrings_ko.txt +++ b/PKHeX.Core/Resources/text/ko/LegalityCheckStrings_ko.txt @@ -344,3 +344,9 @@ V602 = 모든 리본이 채워졌습니다. V600 = 없는 리본: {0} V601 = 사용할 수 없는 리본: {0} V603 = 알은 리본을 얻을 수 없습니다. +V604 = Found a tree for crystal heabutt encounter that matches OTID. +V605 = Found an unreacheable tree for crystal heabutt encounter that matches OTID. +V606 = Could not found a tree for crystal heabutt encounter that matches OTID. +V607 = Kanto Route 14 fishing encounter. Unreachable Water tiles. +V608 = National Park fishing encounter. Unreachable Water tiles. +V609 = Generation 2 safari zone fishing encounter. Unreachable zone. \ No newline at end of file diff --git a/PKHeX.Core/Resources/text/zh/LegalityCheckStrings_zh.txt b/PKHeX.Core/Resources/text/zh/LegalityCheckStrings_zh.txt index 615bbda41..1c9fd4c3b 100644 --- a/PKHeX.Core/Resources/text/zh/LegalityCheckStrings_zh.txt +++ b/PKHeX.Core/Resources/text/zh/LegalityCheckStrings_zh.txt @@ -344,3 +344,9 @@ V602 = 所有奖章合法。 V600 = 缺失奖章: {0} V601 = 不合法奖章: {0} V603 = 蛋不能接受奖章。 +V604 = Found a tree for crystal heabutt encounter that matches OTID. +V605 = Found an unreacheable tree for crystal heabutt encounter that matches OTID. +V606 = Could not found a tree for crystal heabutt encounter that matches OTID. +V607 = Kanto Route 14 fishing encounter. Unreachable Water tiles. +V608 = National Park fishing encounter. Unreachable Water tiles. +V609 = Generation 2 safari zone fishing encounter. Unreachable zone. \ No newline at end of file