mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-24 11:27:08 +00:00
Offload gen1/2 event templates to pickles
Thanks @ShadowMario3 for doing the raw data entry for these templates -- see PKHeX.EncounterSlotDumper for the csv -> pkl conversion logic. Reduces object size by classifying groups of events with specific features, and reduces the explicitness of defining each single encounter. Hard-code the span of Gen1 VC mew to not need to grab the resource, and add an overload to iterate a single template (skips an array creation). Co-Authored-By: ShadowMario3 <36941677+ShadowMario3@users.noreply.github.com>
This commit is contained in:
parent
8206427d21
commit
b435f8c258
15 changed files with 355 additions and 486 deletions
PKHeX.Core
Legality
Encounters
Data
Generator
Possible
Search
Templates
Verifiers
PKM/Strings/Trash
Resources/legality/mgdb
|
@ -1,38 +1,21 @@
|
|||
using System;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
internal static class Encounters1GBEra
|
||||
{
|
||||
private static readonly IndividualValueSet Yoshira = new(5, 10, 1, 12, 5, 5);
|
||||
private static readonly string[] YoshiOT = ["YOSHIRA", "YOSHIRB", "YOSHIBA", "YOSHIBB"];
|
||||
private static readonly string[] TourOT = ["LINKE", "LINKW", "LUIGE", "LUIGW", "LUIGIC", "YOSHIC"];
|
||||
private static readonly string[] StadiumOT_Int = ["STADIUM", "STADE", "STADIO", "ESTADIO"];
|
||||
private const string StadiumOT_JPN = "スタジアム";
|
||||
public static readonly EncounterGift1[] Gifts = GetGifts(Util.GetBinaryResource("event1.pkl"));
|
||||
|
||||
internal static readonly EncounterGift1[] Gifts =
|
||||
[
|
||||
// Stadium 1 (International)
|
||||
new(001, 05, GameVersion.Stadium) {Moves = new(033, 045), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Bulbasaur
|
||||
new(004, 05, GameVersion.Stadium) {Moves = new(010, 043), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Charmander
|
||||
new(007, 05, GameVersion.Stadium) {Moves = new(033, 045), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Squirtle
|
||||
new(106, 20, GameVersion.Stadium) {Moves = new(024, 096), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Hitmonlee
|
||||
new(107, 20, GameVersion.Stadium) {Moves = new(004, 097), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Hitmonchan
|
||||
new(133, 25, GameVersion.Stadium) {Moves = new(033, 039), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Eevee
|
||||
new(138, 20, GameVersion.Stadium) {Moves = new(055, 110), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Omanyte
|
||||
new(140, 20, GameVersion.Stadium) {Moves = new(010, 106), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Kabuto
|
||||
new(054, 15, GameVersion.Stadium) {Moves = new(133, 010), TID16 = 2000, TrainerNames = StadiumOT_Int, Language = EncounterGBLanguage.International}, // Psyduck (Amnesia)
|
||||
|
||||
// Stadium 2 (Japan)
|
||||
new(001, 05, GameVersion.Stadium) {Moves = new(033, 045), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Bulbasaur
|
||||
new(004, 05, GameVersion.Stadium) {Moves = new(010, 043), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Charmander
|
||||
new(007, 05, GameVersion.Stadium) {Moves = new(033, 045), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Squirtle
|
||||
new(106, 20, GameVersion.Stadium) {Moves = new(024, 096), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Hitmonlee
|
||||
new(107, 20, GameVersion.Stadium) {Moves = new(004, 097), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Hitmonchan
|
||||
new(133, 25, GameVersion.Stadium) {Moves = new(033, 039), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Eevee
|
||||
new(138, 20, GameVersion.Stadium) {Moves = new(055, 110), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Omanyte
|
||||
new(140, 20, GameVersion.Stadium) {Moves = new(010, 106), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Kabuto
|
||||
new(054, 15, GameVersion.Stadium) {Moves = new(133, 010), TID16 = 1999, OriginalTrainerName = StadiumOT_JPN}, // Psyduck (Amnesia)
|
||||
|
||||
new(151, 5, GameVersion.RB) {IVs = Yoshira, TrainerNames = YoshiOT, Language = EncounterGBLanguage.International }, // Yoshira Mew Events
|
||||
new(151, 5, GameVersion.RB) {IVs = Yoshira, TrainerNames = TourOT, Language = EncounterGBLanguage.International }, // Pokémon 2000 Stadium Tour Mew
|
||||
];
|
||||
private static EncounterGift1[] GetGifts(ReadOnlySpan<byte> bin)
|
||||
{
|
||||
const int Size = EncounterGift1.SerializedSize;
|
||||
var result = new EncounterGift1[bin.Length / Size];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
var data = bin[..Size];
|
||||
result[i] = new EncounterGift1(data);
|
||||
bin = bin[Size..];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,5 @@ namespace PKHeX.Core;
|
|||
|
||||
internal static class Encounters1VC
|
||||
{
|
||||
private static readonly IndividualValueSet Flawless15 = new(15, 15, 15, 15, 15, 15);
|
||||
|
||||
internal static readonly EncounterGift1[] Gifts =
|
||||
[
|
||||
// Event Mew
|
||||
new(151, 5, GameVersion.RBY) { IVs = Flawless15, TID16 = 22796, OriginalTrainerName = "GF", Language = EncounterGBLanguage.International },
|
||||
new(151, 5, GameVersion.RBY) { IVs = Flawless15, TID16 = 22796, OriginalTrainerName = "ゲーフリ" },
|
||||
];
|
||||
internal static readonly EncounterGift1 Gift = new([151,5, 1,0,0,0, 0,1]); // GF Mew
|
||||
}
|
||||
|
|
|
@ -1,254 +1,21 @@
|
|||
using static PKHeX.Core.GameVersion;
|
||||
using static PKHeX.Core.EncounterGBLanguage;
|
||||
using System;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
internal static class Encounters2GBEra
|
||||
{
|
||||
private static readonly string[] PCNYx = ["PCNYa", "PCNYb", "PCNYc", "PCNYd"];
|
||||
private static readonly string[] Stadium2 = ["Stade", "Stadion", "Stadio", "Estadio"];
|
||||
public static readonly EncounterGift2[] Gifts = GetGifts(Util.GetBinaryResource("event2.pkl"));
|
||||
|
||||
internal static readonly EncounterGift2[] StaticEventsGB =
|
||||
[
|
||||
// Stadium 2 Baton Pass Farfetch'd
|
||||
new(083, 05, C) {Moves = new(226, 14, 97, 163), Location = 127, TID16 = 2000, OriginalTrainerName = "スタジアム"},
|
||||
new(083, 05, C) {Moves = new(226, 14, 97, 163), Location = 127, TID16 = 2000, OriginalTrainerName = "Stadium", Language = International},
|
||||
new(083, 05, C) {Moves = new(226, 14, 97, 163), Location = 127, TID16 = 2001, TrainerNames = Stadium2, Language = International},
|
||||
|
||||
// Stadium 2 Earthquake Gligar
|
||||
new(207, 05, C) {Moves = new(89, 68, 17), Location = 127, TID16 = 2000, OriginalTrainerName = "スタジアム"},
|
||||
new(207, 05, C) {Moves = new(89, 68, 17), Location = 127, TID16 = 2000, OriginalTrainerName = "Stadium", Language = International},
|
||||
new(207, 05, C) {Moves = new(89, 68, 17), Location = 127, TID16 = 2001, TrainerNames = Stadium2, Language = International},
|
||||
|
||||
//New York Pokémon Center Events
|
||||
|
||||
// Legendary Beasts (November 22 to 29, 2001)
|
||||
new(243, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Raikou
|
||||
new(244, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Entei
|
||||
new(245, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Suicune
|
||||
|
||||
// Legendary Birds (November 30 to December 6, 2001)
|
||||
new(144, 05, C) {TrainerNames = PCNYx, CurrentLevel = 50, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Articuno
|
||||
new(145, 05, C) {TrainerNames = PCNYx, CurrentLevel = 50, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Zapdos
|
||||
new(146, 05, C) {TrainerNames = PCNYx, CurrentLevel = 50, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Moltres
|
||||
|
||||
// Christmas Week (December 21 to 27, 2001)
|
||||
new(225, 05, GS) {TrainerNames = PCNYx, Moves = new(006), EggCycles = 10, Language = International}, // Pay Day Delibird
|
||||
new(251, 05, C) {TrainerNames = PCNYx, Location = 127, Language = International}, // Celebi
|
||||
|
||||
// The Initial Three Set (December 28, 2001, to January 31, 2002)
|
||||
new(001, 05, GS) {TrainerNames = PCNYx, Moves = new(246), EggCycles = 10, Language = International}, // Bulbasaur Ancientpower
|
||||
new(004, 05, GS) {TrainerNames = PCNYx, Moves = new(242), EggCycles = 10, Language = International}, // Charmander Crunch
|
||||
new(007, 05, GS) {TrainerNames = PCNYx, Moves = new(192), EggCycles = 10, Language = International}, // Squirtle Zap Cannon
|
||||
new(152, 05, GS) {TrainerNames = PCNYx, Moves = new(080), EggCycles = 10, Language = International}, // Chikorita Petal Dance
|
||||
new(155, 05, GS) {TrainerNames = PCNYx, Moves = new(038), EggCycles = 10, Language = International}, // Cyndaquil Double-Edge
|
||||
new(158, 05, GS) {TrainerNames = PCNYx, Moves = new(066), EggCycles = 10, Language = International}, // Totodile Submission
|
||||
|
||||
// Valentine Week (February 1 to 14, 2002)
|
||||
new(029, 05, GS) {TrainerNames = PCNYx, Moves = new(142), EggCycles = 10, Language = International}, // Nidoran (F) Lovely Kiss
|
||||
new(029, 05, GS) {TrainerNames = PCNYx, Moves = new(186), EggCycles = 10, Language = International}, // Nidoran (F) Sweet Kiss
|
||||
new(032, 05, GS) {TrainerNames = PCNYx, Moves = new(142), EggCycles = 10, Language = International}, // Nidoran (M) Lovely Kiss
|
||||
new(032, 05, GS) {TrainerNames = PCNYx, Moves = new(186), EggCycles = 10, Language = International}, // Nidoran (M) Sweet Kiss
|
||||
new(069, 05, GS) {TrainerNames = PCNYx, Moves = new(142), EggCycles = 10, Language = International}, // Bellsprout Lovely Kiss
|
||||
new(069, 05, GS) {TrainerNames = PCNYx, Moves = new(186), EggCycles = 10, Language = International}, // Bellsprout Sweet Kiss
|
||||
|
||||
// Swarm Week (February 22 to March 14, 2002)
|
||||
new(183, 05, GS) {TrainerNames = PCNYx, Moves = new(056), EggCycles = 10, Language = International}, // Marill Hydro Pump
|
||||
new(193, 05, GS) {TrainerNames = PCNYx, Moves = new(211), EggCycles = 10, Language = International}, // Yanma Steel Wing
|
||||
new(206, 05, GS) {TrainerNames = PCNYx, Moves = new(032), EggCycles = 10, Language = International}, // Dunsparce Horn Drill
|
||||
new(209, 05, GS) {TrainerNames = PCNYx, Moves = new(142), EggCycles = 10, Language = International}, // Snubbull Lovely Kiss
|
||||
new(211, 05, GS) {TrainerNames = PCNYx, Moves = new(038), EggCycles = 10, Language = International}, // Qwilfish Double-Edge
|
||||
new(223, 05, GS) {TrainerNames = PCNYx, Moves = new(133), EggCycles = 10, Language = International}, // Remoraid Amnesia
|
||||
|
||||
// Shiny RBY Starters (March 15 to 21, 2002)
|
||||
new(003, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Venusaur
|
||||
new(006, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Charizard
|
||||
new(009, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Blastoise
|
||||
|
||||
// Babies Week (March 22 to April 11, 2002)
|
||||
new(172, 05, GS) {TrainerNames = PCNYx, Moves = new(047), EggCycles = 10, Language = International}, // Pichu Sing
|
||||
new(173, 05, GS) {TrainerNames = PCNYx, Moves = new(129), EggCycles = 10, Language = International}, // Cleffa Swift
|
||||
new(174, 05, GS) {TrainerNames = PCNYx, Moves = new(102), EggCycles = 10, Language = International}, // Igglybuff Mimic
|
||||
new(238, 05, GS) {TrainerNames = PCNYx, Moves = new(118), EggCycles = 10, Language = International}, // Smoochum Metronome
|
||||
new(239, 05, GS) {TrainerNames = PCNYx, Moves = new(228), EggCycles = 10, Language = International}, // Elekid Pursuit
|
||||
new(240, 05, GS) {TrainerNames = PCNYx, Moves = new(185), EggCycles = 10, Language = International}, // Magby Faint Attack
|
||||
|
||||
// Spring Into Spring (April 12 to May 4, 2002)
|
||||
new(054, 05, GS) {TrainerNames = PCNYx, Moves = new(080), EggCycles = 10, Language = International}, // Psyduck Petal Dance
|
||||
new(152, 05, GS) {TrainerNames = PCNYx, Moves = new(080), EggCycles = 10, Language = International}, // Chikorita Petal Dance
|
||||
new(172, 05, GS) {TrainerNames = PCNYx, Moves = new(080), EggCycles = 10, Language = International}, // Pichu Petal Dance
|
||||
new(173, 05, GS) {TrainerNames = PCNYx, Moves = new(080), EggCycles = 10, Language = International}, // Cleffa Petal Dance
|
||||
new(174, 05, GS) {TrainerNames = PCNYx, Moves = new(080), EggCycles = 10, Language = International}, // Igglybuff Petal Dance
|
||||
new(238, 05, GS) {TrainerNames = PCNYx, Moves = new(080), EggCycles = 10, Language = International}, // Smoochum Petal Dance
|
||||
|
||||
// Baby Weeks (May 5 to June 7, 2002)
|
||||
new(194, 05, GS) {Moves = new(187), EggCycles = 10, Language = International}, // Wooper Belly Drum
|
||||
|
||||
// Tropical Promotion to Summer Festival 1 (June 8 to 21, 2002)
|
||||
new(060, 05, GS) {TrainerNames = PCNYx, Moves = new(074), EggCycles = 10, Language = International}, // Poliwag Growth
|
||||
new(116, 05, GS) {TrainerNames = PCNYx, Moves = new(114), EggCycles = 10, Language = International}, // Horsea Haze
|
||||
new(118, 05, GS) {TrainerNames = PCNYx, Moves = new(014), EggCycles = 10, Language = International}, // Goldeen Swords Dance
|
||||
new(129, 05, GS) {TrainerNames = PCNYx, Moves = new(179), EggCycles = 10, Language = International}, // Magikarp Reversal
|
||||
new(183, 05, GS) {TrainerNames = PCNYx, Moves = new(146), EggCycles = 10, Language = International}, // Marill Dizzy Punch
|
||||
|
||||
// Tropical Promotion to Summer Festival 2 (July 12 to August 8, 2002)
|
||||
new(054, 05, GS) {TrainerNames = PCNYx, Moves = new(161), EggCycles = 10, Language = International}, // Psyduck Tri Attack
|
||||
new(072, 05, GS) {TrainerNames = PCNYx, Moves = new(109), EggCycles = 10, Language = International}, // Tentacool Confuse Ray
|
||||
new(131, 05, GS) {TrainerNames = PCNYx, Moves = new(044), EggCycles = 10, Language = International}, // Lapras Bite
|
||||
new(170, 05, GS) {TrainerNames = PCNYx, Moves = new(113), EggCycles = 10, Language = International}, // Chinchou Light Screen
|
||||
new(223, 05, GS) {TrainerNames = PCNYx, Moves = new(054), EggCycles = 10, Language = International}, // Remoraid Mist
|
||||
new(226, 05, GS) {TrainerNames = PCNYx, Moves = new(016), EggCycles = 10, Language = International}, // Mantine Gust
|
||||
|
||||
// Safari Week (August 9 to 29, 2002)
|
||||
new(029, 05, GS) {TrainerNames = PCNYx, Moves = new(236), EggCycles = 10, Language = International}, // Nidoran (F) Moonlight
|
||||
new(032, 05, GS) {TrainerNames = PCNYx, Moves = new(234), EggCycles = 10, Language = International}, // Nidoran (M) Morning Sun
|
||||
new(113, 05, GS) {TrainerNames = PCNYx, Moves = new(230), EggCycles = 10, Language = International}, // Chansey Sweet Scent
|
||||
new(115, 05, GS) {TrainerNames = PCNYx, Moves = new(185), EggCycles = 10, Language = International}, // Kangaskhan Faint Attack
|
||||
new(128, 05, GS) {TrainerNames = PCNYx, Moves = new(098), EggCycles = 10, Language = International}, // Tauros Quick Attack
|
||||
new(147, 05, GS) {TrainerNames = PCNYx, Moves = new(056), EggCycles = 10, Language = International}, // Dratini Hydro Pump
|
||||
|
||||
// Sky Week (August 30 to September 26, 2002)
|
||||
new(021, 05, GS) {TrainerNames = PCNYx, Moves = new(049), EggCycles = 10, Language = International}, // Spearow SonicBoom
|
||||
new(083, 05, GS) {TrainerNames = PCNYx, Moves = new(210), EggCycles = 10, Language = International}, // Farfetch'd Fury Cutter
|
||||
new(084, 05, GS) {TrainerNames = PCNYx, Moves = new(067), EggCycles = 10, Language = International}, // Doduo Low Kick
|
||||
new(177, 05, GS) {TrainerNames = PCNYx, Moves = new(219), EggCycles = 10, Language = International}, // Natu Safeguard
|
||||
new(198, 05, GS) {TrainerNames = PCNYx, Moves = new(251), EggCycles = 10, Language = International}, // Murkrow Beat Up
|
||||
new(227, 05, GS) {TrainerNames = PCNYx, Moves = new(210), EggCycles = 10, Language = International}, // Skarmory Fury Cutter
|
||||
|
||||
// The Kanto Initial Three Pokémon (September 27 to October 3, 2002)
|
||||
new(150, 05, C) {TrainerNames = PCNYx, CurrentLevel = 70, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Mewtwo
|
||||
|
||||
// Power Plant Pokémon (October 4 to October 10, 2002)
|
||||
new(172, 05, GS) {TrainerNames = PCNYx, Moves = new(146), EggCycles = 10, Language = International}, // Pichu Dizzy Punch
|
||||
new(081, 05, GS) {TrainerNames = PCNYx, Moves = new(097), EggCycles = 10, Language = International}, // Magnemite Agility
|
||||
new(239, 05, GS) {TrainerNames = PCNYx, Moves = new(146), EggCycles = 10, Language = International}, // Elekid Dizzy Punch
|
||||
new(100, 05, GS) {TrainerNames = PCNYx, Moves = new(097), EggCycles = 10, Language = International}, // Voltorb Agility
|
||||
|
||||
// Scary Face Pokémon (October 25 to October 31, 2002)
|
||||
new(173, 05, GS) {TrainerNames = PCNYx, Moves = new(184), EggCycles = 10, Language = International}, // Cleffa Scary Face
|
||||
new(174, 05, GS) {TrainerNames = PCNYx, Moves = new(184), EggCycles = 10, Language = International}, // Igglybuff Scary Face
|
||||
new(183, 05, GS) {TrainerNames = PCNYx, Moves = new(184), EggCycles = 10, Language = International}, // Marill Scary Face
|
||||
new(172, 05, GS) {TrainerNames = PCNYx, Moves = new(184), EggCycles = 10, Language = International}, // Pichu Scary Face
|
||||
new(194, 05, GS) {TrainerNames = PCNYx, Moves = new(184), EggCycles = 10, Language = International}, // Wooper Scary Face
|
||||
|
||||
// Silver Cave (November 1 to November 7, 2002)
|
||||
new(114, 05, GS) {TrainerNames = PCNYx, Moves = new(235), EggCycles = 10, Language = International}, // Tangela Synthesis
|
||||
new(077, 05, GS) {TrainerNames = PCNYx, Moves = new(067), EggCycles = 10, Language = International}, // Ponyta Low Kick
|
||||
new(200, 05, GS) {TrainerNames = PCNYx, Moves = new(095), EggCycles = 10, Language = International}, // Misdreavus Hypnosis
|
||||
new(246, 05, GS) {TrainerNames = PCNYx, Moves = new(099), EggCycles = 10, Language = International}, // Larvitar Rage
|
||||
|
||||
// Union Cave Pokémon (November 8 to 14, 2002)
|
||||
new(120, 05, GS) {TrainerNames = PCNYx, Moves = new(239), EggCycles = 10, Language = International}, // Staryu Twister
|
||||
new(098, 05, GS) {TrainerNames = PCNYx, Moves = new(232), EggCycles = 10, Language = International}, // Krabby Metal Claw
|
||||
new(095, 05, GS) {TrainerNames = PCNYx, Moves = new(159), EggCycles = 10, Language = International}, // Onix Sharpen
|
||||
new(131, 05, GS) {TrainerNames = PCNYx, Moves = new(248), EggCycles = 10, Language = International}, // Lapras Future Sight
|
||||
|
||||
// Johto Legendary (November 15 to 21, 2002)
|
||||
new(250, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Ho-Oh
|
||||
new(249, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Lugia
|
||||
|
||||
// Celebi Present SP (November 22 to 28, 2002)
|
||||
new(151, 05, C) {TrainerNames = PCNYx, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Mew
|
||||
|
||||
// Psychic Type Pokémon (November 29 to December 5, 2002)
|
||||
new(063, 05, GS) {TrainerNames = PCNYx, Moves = new(193), EggCycles = 10, Language = International}, // Abra Foresight
|
||||
new(096, 05, GS) {TrainerNames = PCNYx, Moves = new(133), EggCycles = 10, Language = International}, // Drowzee Amnesia
|
||||
new(102, 05, GS) {TrainerNames = PCNYx, Moves = new(230), EggCycles = 10, Language = International}, // Exeggcute Sweet Scent
|
||||
new(122, 05, GS) {TrainerNames = PCNYx, Moves = new(170), EggCycles = 10, Language = International}, // Mr. Mime Mind Reader
|
||||
|
||||
// The Johto Initial Three Pokémon (December 6 to 12, 2002)
|
||||
new(154, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Meganium
|
||||
new(157, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Typhlosion
|
||||
new(160, 05, C) {TrainerNames = PCNYx, CurrentLevel = 40, Shiny = Shiny.Always, Location = 127, Language = International}, // Shiny Feraligatr
|
||||
|
||||
// Rock Tunnel Pokémon (December 13 to December 19, 2002)
|
||||
new(074, 05, GS) {TrainerNames = PCNYx, Moves = new(229), EggCycles = 10, Language = International}, // Geodude Rapid Spin
|
||||
new(041, 05, GS) {TrainerNames = PCNYx, Moves = new(175), EggCycles = 10, Language = International}, // Zubat Flail
|
||||
new(066, 05, GS) {TrainerNames = PCNYx, Moves = new(037), EggCycles = 10, Language = International}, // Machop Thrash
|
||||
new(104, 05, GS) {TrainerNames = PCNYx, Moves = new(031), EggCycles = 10, Language = International}, // Cubone Fury Attack
|
||||
|
||||
// Ice Type Pokémon (December 20 to 26, 2002)
|
||||
new(225, 05, GS) {TrainerNames = PCNYx, Moves = new(191), EggCycles = 10, Language = International}, // Delibird Spikes
|
||||
new(086, 05, GS) {TrainerNames = PCNYx, Moves = new(175), EggCycles = 10, Language = International}, // Seel Flail
|
||||
new(220, 05, GS) {TrainerNames = PCNYx, Moves = new(018), EggCycles = 10, Language = International}, // Swinub Whirlwind
|
||||
|
||||
// Pokémon that Appear at Night only (December 27, 2002, to January 2, 2003)
|
||||
new(163, 05, GS) {TrainerNames = PCNYx, Moves = new(101), EggCycles = 10, Language = International}, // Hoothoot Night Shade
|
||||
new(215, 05, GS) {TrainerNames = PCNYx, Moves = new(236), EggCycles = 10, Language = International}, // Sneasel Moonlight
|
||||
|
||||
// Grass Type ( January 3 to 9, 2003)
|
||||
new(191, 05, GS) {TrainerNames = PCNYx, Moves = new(150), EggCycles = 10, Language = International}, // Sunkern Splash
|
||||
new(046, 05, GS) {TrainerNames = PCNYx, Moves = new(235), EggCycles = 10, Language = International}, // Paras Synthesis
|
||||
new(187, 05, GS) {TrainerNames = PCNYx, Moves = new(097), EggCycles = 10, Language = International}, // Hoppip Agility
|
||||
new(043, 05, GS) {TrainerNames = PCNYx, Moves = new(073), EggCycles = 10, Language = International}, // Oddish Leech Seed
|
||||
|
||||
// Normal Pokémon (January 10 to 16, 2003)
|
||||
new(161, 05, GS) {TrainerNames = PCNYx, Moves = new(146), EggCycles = 10, Language = International}, // Sentret Dizzy Punch
|
||||
new(234, 05, GS) {TrainerNames = PCNYx, Moves = new(219), EggCycles = 10, Language = International}, // Stantler Safeguard
|
||||
new(241, 05, GS) {TrainerNames = PCNYx, Moves = new(025), EggCycles = 10, Language = International}, // Miltank Mega Kick
|
||||
new(190, 05, GS) {TrainerNames = PCNYx, Moves = new(102), EggCycles = 10, Language = International}, // Aipom Mimic
|
||||
new(108, 05, GS) {TrainerNames = PCNYx, Moves = new(003), EggCycles = 10, Language = International}, // Lickitung DoubleSlap
|
||||
new(143, 05, GS) {TrainerNames = PCNYx, Moves = new(150), EggCycles = 10, Language = International}, // Snorlax Splash
|
||||
|
||||
// Mt. Mortar (January 24 to 30, 2003)
|
||||
new(066, 05, GS) {TrainerNames = PCNYx, Moves = new(206), EggCycles = 10, Language = International}, // Machop False Swipe
|
||||
new(129, 05, GS) {TrainerNames = PCNYx, Moves = new(145), EggCycles = 10, Language = International}, // Magikarp Bubble
|
||||
new(236, 05, GS) {TrainerNames = PCNYx, Moves = new(099), EggCycles = 10, Language = International}, // Tyrogue Rage
|
||||
|
||||
// Dark Cave Pokémon (January 31 to February 6, 2003)
|
||||
new(206, 05, GS) {TrainerNames = PCNYx, Moves = new(031), EggCycles = 10, Language = International}, // Dunsparce Fury Attack
|
||||
new(202, 05, GS) {TrainerNames = PCNYx, Moves = new(102), EggCycles = 10, Language = International}, // Wobbuffet Mimic
|
||||
new(231, 05, GS) {TrainerNames = PCNYx, Moves = new(071), EggCycles = 10, Language = International}, // Phanpy Absorb
|
||||
new(216, 05, GS) {TrainerNames = PCNYx, Moves = new(230), EggCycles = 10, Language = International}, // Teddiursa Sweet Scent
|
||||
|
||||
// Valentine's Day Special (February 7 to 13, 2003)
|
||||
new(060, 05, GS) {TrainerNames = PCNYx, Moves = new(186), EggCycles = 10, Language = International}, // Poliwag Sweet Kiss
|
||||
new(060, 05, GS) {TrainerNames = PCNYx, Moves = new(142), EggCycles = 10, Language = International}, // Poliwag Lovely Kiss
|
||||
new(143, 05, GS) {TrainerNames = PCNYx, Moves = new(186), EggCycles = 10, Language = International}, // Snorlax Sweet Kiss
|
||||
new(143, 05, GS) {TrainerNames = PCNYx, Moves = new(142), EggCycles = 10, Language = International}, // Snorlax Lovely Kiss
|
||||
|
||||
// Rare Pokémon (February 21 to 27, 2003)
|
||||
new(140, 05, GS) {TrainerNames = PCNYx, Moves = new(088), EggCycles = 10, Language = International}, // Kabuto Rock Throw
|
||||
new(138, 05, GS) {TrainerNames = PCNYx, Moves = new(088), EggCycles = 10, Language = International}, // Omanyte Rock Throw
|
||||
new(142, 05, GS) {TrainerNames = PCNYx, Moves = new(088), EggCycles = 10, Language = International}, // Aerodactyl Rock Throw
|
||||
new(137, 05, GS) {TrainerNames = PCNYx, Moves = new(112), EggCycles = 10, Language = International}, // Porygon Barrier
|
||||
new(133, 05, GS) {TrainerNames = PCNYx, Moves = new(074), EggCycles = 10, Language = International}, // Eevee Growth
|
||||
new(185, 05, GS) {TrainerNames = PCNYx, Moves = new(164), EggCycles = 10, Language = International}, // Sudowoodo Substitute
|
||||
|
||||
// Bug Type Pokémon (February 28 to March 6, 2003)
|
||||
new(123, 05, GS) {TrainerNames = PCNYx, Moves = new(049), EggCycles = 10, Language = International}, // Scyther SonicBoom
|
||||
new(214, 05, GS) {TrainerNames = PCNYx, Moves = new(069), EggCycles = 10, Language = International}, // Heracross Seismic Toss
|
||||
new(127, 05, GS) {TrainerNames = PCNYx, Moves = new(088), EggCycles = 10, Language = International}, // Pinsir Rock Throw
|
||||
new(165, 05, GS) {TrainerNames = PCNYx, Moves = new(112), EggCycles = 10, Language = International}, // Ledyba Barrier
|
||||
new(167, 05, GS) {TrainerNames = PCNYx, Moves = new(074), EggCycles = 10, Language = International}, // Spinarak Growth
|
||||
new(193, 05, GS) {TrainerNames = PCNYx, Moves = new(186), EggCycles = 10, Language = International}, // Yanma Sweet Kiss
|
||||
new(204, 05, GS) {TrainerNames = PCNYx, Moves = new(164), EggCycles = 10, Language = International}, // Pineco Substitute
|
||||
|
||||
// Japanese Only (all below)
|
||||
new(251, 30, GSC) {Location = 014}, // Celebi @ Ilex Forest (GBC)
|
||||
|
||||
// Gen2 Events
|
||||
// Egg Cycles Subject to Change. OTs for Eggs are unknown.
|
||||
// Pokémon Center Mystery Egg #1 (December 15, 2001, to January 14, 2002)
|
||||
new(152, 05, GSC) {Moves = new(080), EggCycles = 10}, // Chikorita Petal Dance
|
||||
new(172, 05, GSC) {Moves = new(047), EggCycles = 10}, // Pichu Sing
|
||||
new(173, 05, GSC) {Moves = new(129), EggCycles = 10}, // Cleffa Swift
|
||||
new(194, 05, GSC) {Moves = new(187), EggCycles = 10}, // Wooper Belly Drum
|
||||
new(231, 05, GSC) {Moves = new(227), EggCycles = 10}, // Phanpy Encore
|
||||
new(238, 05, GSC) {Moves = new(118), EggCycles = 10}, // Smoochum Metronome
|
||||
|
||||
// Pokémon Center Mystery Egg #2 (March 16 to April 7, 2002)
|
||||
new(054, 05, GSC) {Moves = new(080), EggCycles = 10}, // Psyduck Petal Dance
|
||||
new(152, 05, GSC) {Moves = new(080), EggCycles = 10}, // Chikorita Petal Dance
|
||||
new(172, 05, GSC) {Moves = new(080), EggCycles = 10}, // Pichu Petal Dance
|
||||
new(173, 05, GSC) {Moves = new(080), EggCycles = 10}, // Cleffa Petal Dance
|
||||
new(174, 05, GSC) {Moves = new(080), EggCycles = 10}, // Igglybuff Petal Dance
|
||||
new(238, 05, GSC) {Moves = new(080), EggCycles = 10}, // Smoochum Petal Dance
|
||||
|
||||
// Pokémon Center Mystery Egg #3 (April 27 to May 12, 2002)
|
||||
new(001, 05, GSC) {Moves = new(246), EggCycles = 10}, // Bulbasaur Ancientpower
|
||||
new(004, 05, GSC) {Moves = new(242), EggCycles = 10}, // Charmander Crunch
|
||||
new(158, 05, GSC) {Moves = new(066), EggCycles = 10}, // Totodile Submission
|
||||
new(163, 05, GSC) {Moves = new(101), EggCycles = 10}, // Hoot-Hoot Night Shade
|
||||
];
|
||||
private static EncounterGift2[] GetGifts(ReadOnlySpan<byte> bin)
|
||||
{
|
||||
const int Size = EncounterGift2.SerializedSize;
|
||||
var result = new EncounterGift2[bin.Length / Size];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
var data = bin[..Size];
|
||||
result[i] = new EncounterGift2(data);
|
||||
bin = bin[Size..];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ public record struct EncounterPossible1(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
{ State = YieldState.EventVC; goto case YieldState.EventVC; }
|
||||
State = YieldState.EventGB; goto case YieldState.EventGB;
|
||||
case YieldState.EventVC:
|
||||
if (TryGetNext(Encounters1VC.Gifts))
|
||||
if (TryGetNext(Encounters1VC.Gift))
|
||||
return true;
|
||||
break;
|
||||
case YieldState.EventGB:
|
||||
|
@ -196,6 +196,19 @@ public record struct EncounterPossible1(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetNext<T>(T enc) where T : class, IEncounterable, IEncounterMatch
|
||||
{
|
||||
if (Index++ != 0)
|
||||
return false;
|
||||
foreach (var evo in Chain)
|
||||
{
|
||||
if (evo.Species != enc.Species)
|
||||
continue;
|
||||
return SetCurrent(enc);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetNext<T>(T[] db) where T : class, IEncounterable, IEncounterMatch
|
||||
{
|
||||
for (; Index < db.Length;)
|
||||
|
|
|
@ -169,7 +169,7 @@ public record struct EncounterPossible2(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
return SetCurrent(Encounters2.CelebiVC);
|
||||
break;
|
||||
case YieldState.EventGB:
|
||||
if (TryGetNext(Encounters2GBEra.StaticEventsGB))
|
||||
if (TryGetNext(Encounters2GBEra.Gifts))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ public record struct EncounterEnumerator1(PKM Entity, EvoCriteria[] Chain) : IEn
|
|||
{ State = YieldState.EventVC; goto case YieldState.EventVC; }
|
||||
State = YieldState.EventGB; goto case YieldState.EventGB;
|
||||
case YieldState.EventVC:
|
||||
if (TryGetNext(Encounters1VC.Gifts))
|
||||
if (TryGetNext(Encounters1VC.Gift))
|
||||
return true;
|
||||
goto case YieldState.Fallback;
|
||||
case YieldState.EventGB:
|
||||
|
@ -209,6 +209,29 @@ public record struct EncounterEnumerator1(PKM Entity, EvoCriteria[] Chain) : IEn
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetNext<T>(T enc) where T : class, IEncounterable, IEncounterMatch
|
||||
{
|
||||
if (Index++ != 0)
|
||||
return false;
|
||||
foreach (var evo in Chain)
|
||||
{
|
||||
if (evo.Species != enc.Species)
|
||||
continue;
|
||||
if (!enc.IsMatchExact(Entity, evo))
|
||||
break;
|
||||
var rating = enc.GetMatchRating(Entity);
|
||||
if (rating == EncounterMatchRating.Match)
|
||||
return SetCurrent(enc);
|
||||
if (rating < Rating)
|
||||
{
|
||||
Deferred = enc;
|
||||
Rating = rating;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool SetCurrent<T>(T enc, EncounterMatchRating rating = EncounterMatchRating.Match) where T : IEncounterable
|
||||
{
|
||||
Current = new MatchedEncounter<IEncounterable>(enc, rating);
|
||||
|
|
|
@ -171,7 +171,7 @@ public record struct EncounterEnumerator2 : IEnumerator<MatchedEncounter<IEncoun
|
|||
return SetCurrent(Encounters2.CelebiVC);
|
||||
goto case YieldState.Fallback;
|
||||
case YieldState.EventGB:
|
||||
if (TryGetNext(Encounters2GBEra.StaticEventsGB))
|
||||
if (TryGetNext(Encounters2GBEra.Gifts))
|
||||
return true;
|
||||
State = YieldState.Fallback; goto case YieldState.Fallback;
|
||||
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Generations 1 & 2 cannot communicate between Japanese & International versions.
|
||||
/// </summary>
|
||||
public enum EncounterGBLanguage
|
||||
{
|
||||
/// <summary> Can only be obtained in Japanese games. </summary>
|
||||
Japanese,
|
||||
|
||||
/// <summary> Can only be obtained in International (not Japanese) games. </summary>
|
||||
International,
|
||||
|
||||
/// <summary> Can be obtained in any localization. </summary>
|
||||
Any,
|
||||
}
|
|
@ -1,13 +1,17 @@
|
|||
using System;
|
||||
using static PKHeX.Core.EncounterGift1.TrainerType;
|
||||
using static PKHeX.Core.LanguageID;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Event data for Generation 1
|
||||
/// </summary>
|
||||
public sealed record EncounterGift1(ushort Species, byte Level, GameVersion Version = GameVersion.RB)
|
||||
: IEncounterable, IEncounterMatch, IEncounterConvertible<PK1>, IFixedGBLanguage, IMoveset, IFixedIVSet
|
||||
public sealed record EncounterGift1 : IEncounterable, IEncounterMatch, IEncounterConvertible<PK1>,
|
||||
IMoveset, IFixedIVSet
|
||||
{
|
||||
public const int SerializedSize = 8;
|
||||
|
||||
public byte Generation => 1;
|
||||
public EntityContext Context => EntityContext.Gen1;
|
||||
public bool EggEncounter => false;
|
||||
|
@ -16,113 +20,153 @@ public sealed record EncounterGift1(ushort Species, byte Level, GameVersion Vers
|
|||
public AbilityPermission Ability => AbilityPermission.OnlyHidden;
|
||||
public bool IsShiny => false;
|
||||
public ushort Location => 0;
|
||||
|
||||
public const ushort UnspecifiedID = 0;
|
||||
|
||||
public Shiny Shiny { get; init; } = Shiny.Random;
|
||||
public byte Form => 0;
|
||||
public Shiny Shiny => Shiny.Random;
|
||||
|
||||
public EncounterGBLanguage Language { get; init; } = EncounterGBLanguage.Japanese;
|
||||
|
||||
/// <summary> Trainer name for the event. </summary>
|
||||
public string OriginalTrainerName { get; init; } = string.Empty;
|
||||
|
||||
public ReadOnlyMemory<string> TrainerNames { get; init; }
|
||||
|
||||
/// <summary> Trainer ID for the event. </summary>
|
||||
public ushort TID16 { get; init; } = UnspecifiedID;
|
||||
|
||||
public IndividualValueSet IVs { get; init; }
|
||||
public Moveset Moves { get; init; }
|
||||
public Moveset Moves { get; }
|
||||
public IndividualValueSet IVs { get; }
|
||||
public ushort Species { get; }
|
||||
public byte Level { get; }
|
||||
public GameVersion Version { get; }
|
||||
public LanguageRestriction Language { get; }
|
||||
public TrainerType Trainer { get; }
|
||||
|
||||
public string Name => "Event Gift";
|
||||
public string LongName => Name;
|
||||
public byte LevelMin => Level;
|
||||
public byte LevelMax => Level;
|
||||
|
||||
public enum LanguageRestriction : byte
|
||||
{
|
||||
Any = 0,
|
||||
Japanese = 1,
|
||||
International = 2,
|
||||
}
|
||||
|
||||
public enum TrainerType : byte
|
||||
{
|
||||
Recipient,
|
||||
VirtualConsoleMew = 1,
|
||||
Stadium = 2,
|
||||
EuropeTour = 3,
|
||||
}
|
||||
|
||||
private const ushort TrainerIDStadiumJPN = 1999;
|
||||
private const ushort TrainerIDStadiumINT = 2000;
|
||||
private const ushort TrainerIDVirtualConsoleMew = 2_27_96; // Red/Green (Japan) release date!
|
||||
private const string StadiumENG = "STADIUM";
|
||||
private const string StadiumJPN = "スタジアム";
|
||||
private const string StadiumFRE = "STADE";
|
||||
private const string StadiumITA = "STADIO";
|
||||
private const string StadiumSPA = "ESTADIO";
|
||||
private const string VirtualConsoleMewINT = "GF";
|
||||
private const string VirtualConsoleMewJPN = "ゲーフリ";
|
||||
private const string FirstTourOT = "YOSHIRA";
|
||||
|
||||
private static bool IsTourOT(ReadOnlySpan<char> str) => str switch
|
||||
{
|
||||
"YOSHIRA" => true,
|
||||
"YOSHIRB" => true,
|
||||
"YOSHIBA" => true,
|
||||
"YOSHIBB" => true,
|
||||
"LINKE" => true,
|
||||
"LINKW" => true,
|
||||
"LUIGE" => true,
|
||||
"LUIGW" => true,
|
||||
"LUIGIC" => true,
|
||||
"YOSHIC" => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public EncounterGift1(ReadOnlySpan<byte> data)
|
||||
{
|
||||
Species = data[0];
|
||||
Level = data[1];
|
||||
Moves = new Moveset(data[2], data[3], data[4], data[5]);
|
||||
Language = (LanguageRestriction)data[6];
|
||||
Trainer = (TrainerType)data[7];
|
||||
|
||||
if (Trainer is EuropeTour)
|
||||
IVs = new(5, 10, 1, 12, 5, 5);
|
||||
else if (Trainer is VirtualConsoleMew)
|
||||
IVs = new(15, 15, 15, 15, 15, 15);
|
||||
|
||||
Version = Trainer == Stadium ? GameVersion.Stadium : GameVersion.RB;
|
||||
}
|
||||
|
||||
#region Generating
|
||||
PKM IEncounterConvertible.ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria) => ConvertToPKM(tr, criteria);
|
||||
PKM IEncounterConvertible.ConvertToPKM(ITrainerInfo tr) => ConvertToPKM(tr);
|
||||
|
||||
public PK1 ConvertToPKM(ITrainerInfo tr) => ConvertToPKM(tr, EncounterCriteria.Unrestricted);
|
||||
|
||||
public PK1 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
{
|
||||
var lang = GetTemplateLanguage(tr);
|
||||
var isJapanese = lang == (int)LanguageID.Japanese;
|
||||
var pi = EncounterUtil.GetPersonal1(Version, Species);
|
||||
var lang = GetLanguage((LanguageID)tr.Language);
|
||||
var isJapanese = lang == Japanese;
|
||||
var pi = PersonalTable.RB[Species];
|
||||
var rand = Util.Rand;
|
||||
var pk = new PK1(isJapanese)
|
||||
{
|
||||
Species = Species,
|
||||
CurrentLevel = LevelMin,
|
||||
CatchRate = GetInitialCatchRate(pi),
|
||||
DV16 = IVs.IsSpecified ? EncounterUtil.GetDV16(IVs) : EncounterUtil.GetRandomDVs(Util.Rand),
|
||||
|
||||
OriginalTrainerName = EncounterUtil.GetTrainerName(tr, lang),
|
||||
TID16 = tr.TID16,
|
||||
Nickname = SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
Nickname = SpeciesName.GetSpeciesNameGeneration(Species, (int)lang, Generation),
|
||||
Type1 = pi.Type1,
|
||||
Type2 = pi.Type2,
|
||||
DV16 = IVs.IsSpecified ? EncounterUtil.GetDV16(IVs) : EncounterUtil.GetRandomDVs(rand),
|
||||
|
||||
CatchRate = Trainer switch
|
||||
{
|
||||
Stadium => 168, // be nice and give a Gorgeous Box
|
||||
_ => pi.CatchRate,
|
||||
},
|
||||
TID16 = Trainer switch
|
||||
{
|
||||
Recipient => tr.TID16,
|
||||
Stadium => lang == Japanese ? TrainerIDStadiumJPN : TrainerIDStadiumINT,
|
||||
VirtualConsoleMew => TrainerIDVirtualConsoleMew,
|
||||
_ => (ushort)rand.Next(10, 200),
|
||||
},
|
||||
|
||||
OriginalTrainerName = Trainer switch
|
||||
{
|
||||
Recipient => EncounterUtil.GetTrainerName(tr, (int)lang),
|
||||
Stadium => lang switch
|
||||
{
|
||||
Japanese => StadiumJPN,
|
||||
English => StadiumENG,
|
||||
French => StadiumFRE,
|
||||
Italian => StadiumITA,
|
||||
German => StadiumENG, // Same as English
|
||||
Spanish => StadiumSPA,
|
||||
_ => StadiumENG, // shouldn't hit here
|
||||
},
|
||||
EuropeTour => FirstTourOT, // YOSHIRA
|
||||
_ => string.Empty,
|
||||
},
|
||||
};
|
||||
|
||||
if (TID16 != UnspecifiedID)
|
||||
pk.TID16 = TID16;
|
||||
if (OriginalTrainerName.Length != 0)
|
||||
pk.OriginalTrainerName = OriginalTrainerName;
|
||||
else if (TrainerNames.Length != 0)
|
||||
pk.OriginalTrainerName = TrainerNames.Span[Util.Rand.Next(TrainerNames.Length)];
|
||||
|
||||
if (Version == GameVersion.Stadium)
|
||||
{
|
||||
// Amnesia Psyduck has different catch rates depending on language
|
||||
if (Species == (int)Core.Species.Psyduck)
|
||||
pk.CatchRate = pk.Japanese ? (byte)167 : (byte)168;
|
||||
else
|
||||
pk.CatchRate = Util.Rand.Next(2) == 0 ? (byte)167 : (byte)168;
|
||||
}
|
||||
|
||||
if (Moves.HasMoves)
|
||||
pk.SetMoves(Moves);
|
||||
else
|
||||
EncounterUtil.SetEncounterMoves(pk, Version, LevelMin);
|
||||
|
||||
pk.SetMoves(Moves);
|
||||
pk.ResetPartyStats();
|
||||
return pk;
|
||||
}
|
||||
|
||||
private int GetTemplateLanguage(ITrainerInfo tr)
|
||||
private LanguageID GetLanguage(LanguageID request)
|
||||
{
|
||||
// Japanese events must be Japanese
|
||||
if (Language == EncounterGBLanguage.Japanese)
|
||||
return 1;
|
||||
if (Language == LanguageRestriction.Japanese)
|
||||
return Japanese;
|
||||
|
||||
// International events must be non-Japanese
|
||||
var lang = (int)Core.Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, Version);
|
||||
if (lang == 1 && Language == EncounterGBLanguage.International)
|
||||
return 2;
|
||||
return lang;
|
||||
if (request is not (English or French or Italian or German or Spanish))
|
||||
return English;
|
||||
return request;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private byte GetInitialCatchRate(PersonalInfo1 pi)
|
||||
{
|
||||
if (Version == GameVersion.Stadium)
|
||||
{
|
||||
// Amnesia Psyduck has different catch rates depending on language
|
||||
if (Species == (int)Core.Species.Psyduck)
|
||||
return Language == EncounterGBLanguage.Japanese ? (byte)167 : (byte)168;
|
||||
}
|
||||
|
||||
// Encounters can have different Catch Rates (RBG vs Y)
|
||||
return pi.CatchRate;
|
||||
}
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
||||
{
|
||||
if (Language != EncounterGBLanguage.Any && pk.Japanese != (Language == EncounterGBLanguage.Japanese))
|
||||
if (Language != LanguageRestriction.Any && pk.Japanese != (Language == LanguageRestriction.Japanese))
|
||||
return false;
|
||||
if (!IsMatchEggLocation(pk))
|
||||
return false;
|
||||
|
@ -130,9 +174,6 @@ public sealed record EncounterGift1(ushort Species, byte Level, GameVersion Vers
|
|||
return false;
|
||||
if (Level > evo.LevelMax)
|
||||
return false;
|
||||
// Encounters with this version have to originate from the Japanese Blue game.
|
||||
if (Version == GameVersion.BU && !pk.Japanese)
|
||||
return false;
|
||||
if (Form != evo.Form && !FormInfo.IsFormChangeable(Species, Form, pk.Form, Context, pk.Context))
|
||||
return false;
|
||||
if (IVs.IsSpecified)
|
||||
|
@ -151,24 +192,41 @@ public sealed record EncounterGift1(ushort Species, byte Level, GameVersion Vers
|
|||
// EC/PID check doesn't exist for these, so check Shiny state here.
|
||||
if (!IsShinyValid(pk))
|
||||
return false;
|
||||
|
||||
if (TID16 != UnspecifiedID && pk.TID16 != TID16)
|
||||
if (!IsTrainerIDValid(pk))
|
||||
return false;
|
||||
if (!IsTrainerNameValid(pk))
|
||||
return false;
|
||||
|
||||
if (OriginalTrainerName.Length != 0)
|
||||
{
|
||||
if (pk.OriginalTrainerName != OriginalTrainerName)
|
||||
return false;
|
||||
}
|
||||
else if (TrainerNames.Length != 0)
|
||||
{
|
||||
if (!TrainerNames.Span.Contains(pk.OriginalTrainerName))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsTrainerNameValid(PKM pk) => Trainer switch
|
||||
{
|
||||
Recipient => true,
|
||||
VirtualConsoleMew => pk.OriginalTrainerName == (pk.Language == 1 ? VirtualConsoleMewJPN : VirtualConsoleMewINT),
|
||||
Stadium => pk.Language switch
|
||||
{
|
||||
(int)Japanese => pk.OriginalTrainerName == StadiumJPN,
|
||||
_ => pk.OriginalTrainerName switch
|
||||
{
|
||||
StadiumENG => true,
|
||||
StadiumFRE => true,
|
||||
StadiumITA => true,
|
||||
StadiumSPA => true,
|
||||
_ => false,
|
||||
},
|
||||
},
|
||||
EuropeTour => IsTourOT(pk.OriginalTrainerName),
|
||||
_ => true,
|
||||
};
|
||||
|
||||
private bool IsTrainerIDValid(ITrainerID16 pk) => Trainer switch
|
||||
{
|
||||
Recipient => true,
|
||||
VirtualConsoleMew => pk.TID16 == TrainerIDVirtualConsoleMew,
|
||||
Stadium => pk.TID16 == (Language == LanguageRestriction.Japanese ? TrainerIDStadiumJPN : TrainerIDStadiumINT),
|
||||
_ => true,
|
||||
};
|
||||
|
||||
private bool IsShinyValid(PKM pk) => Shiny switch
|
||||
{
|
||||
Shiny.Never => !pk.IsShiny,
|
||||
|
@ -213,15 +271,10 @@ public sealed record EncounterGift1(ushort Species, byte Level, GameVersion Vers
|
|||
return true;
|
||||
|
||||
if (Version == GameVersion.Stadium)
|
||||
{
|
||||
// Amnesia Psyduck has different catch rates depending on language
|
||||
if (Species == (int)Core.Species.Psyduck)
|
||||
return rate == (Language == EncounterGBLanguage.Japanese ? 167 : 168);
|
||||
return rate is 167 or 168;
|
||||
}
|
||||
|
||||
// Encounters can have different Catch Rates (RBG vs Y)
|
||||
return GBRestrictions.RateMatchesEncounter(Species, Version, rate);
|
||||
var pi = PersonalTable.RB[Species];
|
||||
return pi.CatchRate == rate;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Exposes info on language restriction for Gen1/2.
|
||||
/// </summary>
|
||||
public interface IFixedGBLanguage
|
||||
{
|
||||
/// <summary>
|
||||
/// Language restriction for the encounter template.
|
||||
/// </summary>
|
||||
EncounterGBLanguage Language { get; }
|
||||
}
|
|
@ -1,50 +1,88 @@
|
|||
using System;
|
||||
using static PKHeX.Core.LanguageID;
|
||||
using static PKHeX.Core.EncounterGift2.TrainerType;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Event data for Generation 2
|
||||
/// </summary>
|
||||
public sealed record EncounterGift2(ushort Species, byte Level, GameVersion Version = GameVersion.GS)
|
||||
: IEncounterable, IEncounterMatch, IEncounterConvertible<PK2>, IFixedGBLanguage, IHatchCycle, IMoveset, IFixedIVSet
|
||||
public sealed record EncounterGift2
|
||||
: IEncounterable, IEncounterMatch, IEncounterConvertible<PK2>, IHatchCycle, IMoveset, IFixedIVSet
|
||||
{
|
||||
public const int SerializedSize = 12;
|
||||
|
||||
public byte Generation => 2;
|
||||
public EntityContext Context => EntityContext.Gen2;
|
||||
public byte Form => 0;
|
||||
|
||||
public Ball FixedBall => Ball.Poke;
|
||||
ushort ILocation.Location => Location;
|
||||
public ushort EggLocation => 0;
|
||||
public bool IsShiny => Shiny == Shiny.Always;
|
||||
public AbilityPermission Ability => AbilityPermission.OnlyHidden;
|
||||
|
||||
public Shiny Shiny { get; init; } = Shiny.Random;
|
||||
public byte Location { get; init; }
|
||||
public IndividualValueSet IVs { get; init; }
|
||||
public Moveset Moves { get; init; }
|
||||
public bool EggEncounter => EggCycles != 0;
|
||||
|
||||
public Moveset Moves { get; }
|
||||
public IndividualValueSet IVs => default; // future?
|
||||
public ushort Species { get; }
|
||||
public byte Level { get; }
|
||||
public GameVersion Version { get; }
|
||||
public TrainerType Trainer { get; }
|
||||
public byte CurrentLevel { get; }
|
||||
public byte EggCycles { get; }
|
||||
public byte Location { get; }
|
||||
public Shiny Shiny { get; }
|
||||
public LanguageRestriction Language { get; }
|
||||
|
||||
public string Name => "GB Era Event Gift";
|
||||
public string LongName => Name;
|
||||
public byte LevelMin => Level;
|
||||
public byte LevelMax => Level;
|
||||
public EncounterGBLanguage Language { get; init; } = EncounterGBLanguage.Japanese;
|
||||
|
||||
/// <summary> Trainer name for the event. </summary>
|
||||
public string OriginalTrainerName { get; init; } = string.Empty;
|
||||
public enum LanguageRestriction : byte
|
||||
{
|
||||
International = 0,
|
||||
Japanese = 1,
|
||||
English = 2,
|
||||
InternationalNotEnglish = 3,
|
||||
}
|
||||
|
||||
public ReadOnlyMemory<string> TrainerNames { get; init; }
|
||||
public enum TrainerType : byte
|
||||
{
|
||||
Recipient,
|
||||
GiftStadiumJPN = 1,
|
||||
GiftStadiumENG = 2,
|
||||
GiftStadiumINT = 3,
|
||||
PokemonCenterNewYork = 4,
|
||||
}
|
||||
|
||||
private const ushort UnspecifiedID = 0;
|
||||
private const ushort TrainerIDStadiumJPN = 2000;
|
||||
private const ushort TrainerIDStadiumENG = 2000;
|
||||
private const ushort TrainerIDStadiumINT = 2001;
|
||||
private const string StadiumJPN = "スタジアム";
|
||||
private const string StadiumENG = "Stadium";
|
||||
private const string StadiumFRE = "Stade";
|
||||
private const string StadiumGER = "Stadion";
|
||||
private const string StadiumITA = "Stadio";
|
||||
private const string StadiumSPA = "Estadio";
|
||||
private const string FirstPCNY = "PCNYa";
|
||||
|
||||
/// <summary> Trainer ID for the event. </summary>
|
||||
public ushort TID16 { get; init; } = UnspecifiedID;
|
||||
public static bool IsTrainerPCNY(ReadOnlySpan<char> str) => str is "PCNYa" or "PCNYb" or "PCNYc" or "PCNYd";
|
||||
|
||||
public bool IsGift => TID16 != UnspecifiedID;
|
||||
public EncounterGift2(ReadOnlySpan<byte> data)
|
||||
{
|
||||
Species = data[0];
|
||||
Level = data[1];
|
||||
Moves = new(data[2], data[3], data[4], data[5]);
|
||||
Location = data[6];
|
||||
CurrentLevel = data[7];
|
||||
Shiny = data[8] == 0 ? Shiny.Random : Shiny.Always;
|
||||
EggCycles = data[9] == 1 ? (byte)10 : (byte)0;
|
||||
Language = (LanguageRestriction)data[10];
|
||||
Trainer = (TrainerType)data[11];
|
||||
|
||||
public byte CurrentLevel { get; init; }
|
||||
|
||||
public byte EggCycles { get; init; }
|
||||
Version = Location != 0 ? GameVersion.C : GameVersion.GS;
|
||||
}
|
||||
|
||||
#region Generating
|
||||
|
||||
|
@ -54,29 +92,47 @@ public sealed record EncounterGift2(ushort Species, byte Level, GameVersion Vers
|
|||
|
||||
public PK2 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
{
|
||||
var version = this.GetCompatibleVersion(tr.Version);
|
||||
int lang = GetTemplateLanguage(tr);
|
||||
var lang = GetLanguage((LanguageID)tr.Language);
|
||||
var pi = PersonalTable.C[Species];
|
||||
var pk = new PK2
|
||||
{
|
||||
Species = Species,
|
||||
CurrentLevel = CurrentLevel == 0 ? LevelMin : CurrentLevel,
|
||||
|
||||
TID16 = TID16 != UnspecifiedID ? TID16 : tr.TID16,
|
||||
OriginalTrainerName = GetInitialOT(tr),
|
||||
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
Nickname = SpeciesName.GetSpeciesNameGeneration(Species, (int)lang, Generation),
|
||||
|
||||
Nickname = SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
TID16 = Trainer switch
|
||||
{
|
||||
Recipient => tr.TID16,
|
||||
GiftStadiumJPN => TrainerIDStadiumJPN,
|
||||
GiftStadiumENG => TrainerIDStadiumENG,
|
||||
GiftStadiumINT => TrainerIDStadiumINT,
|
||||
_ => (ushort)Util.Rand.Next(10, 200),
|
||||
},
|
||||
OriginalTrainerName = Trainer switch
|
||||
{
|
||||
Recipient => EncounterUtil.GetTrainerName(tr, (int)lang),
|
||||
GiftStadiumJPN => StadiumJPN,
|
||||
GiftStadiumENG => StadiumENG,
|
||||
GiftStadiumINT => lang switch
|
||||
{
|
||||
French => StadiumFRE,
|
||||
Italian => StadiumITA,
|
||||
German => StadiumGER,
|
||||
Spanish => StadiumSPA,
|
||||
_ => StadiumENG, // shouldn't hit here
|
||||
},
|
||||
PokemonCenterNewYork => FirstPCNY,
|
||||
_ => EncounterUtil.GetTrainerName(tr, 1),
|
||||
},
|
||||
};
|
||||
|
||||
if (EggEncounter)
|
||||
{
|
||||
// Fake as hatched on G/S.
|
||||
}
|
||||
else if (Version == GameVersion.C || (Version == GameVersion.GSC && tr.Version == GameVersion.C))
|
||||
else
|
||||
{
|
||||
if (!IsGift)
|
||||
pk.OriginalTrainerGender = tr.Gender;
|
||||
pk.MetLevel = LevelMin;
|
||||
pk.MetLocation = Location;
|
||||
pk.MetTimeOfDay = EncounterTime.Any.RandomValidTime();
|
||||
|
@ -84,42 +140,28 @@ public sealed record EncounterGift2(ushort Species, byte Level, GameVersion Vers
|
|||
|
||||
if (Shiny == Shiny.Always)
|
||||
pk.SetShiny();
|
||||
|
||||
if (Moves.HasMoves)
|
||||
pk.SetMoves(Moves);
|
||||
else
|
||||
EncounterUtil.SetEncounterMoves(pk, version, LevelMin);
|
||||
|
||||
pk.SetMoves(Moves);
|
||||
if (IVs.IsSpecified)
|
||||
criteria.SetRandomIVs(pk, IVs);
|
||||
else
|
||||
criteria.SetRandomIVs(pk);
|
||||
|
||||
pk.ResetPartyStats();
|
||||
|
||||
return pk;
|
||||
}
|
||||
|
||||
private int GetTemplateLanguage(ITrainerInfo tr)
|
||||
private LanguageID GetLanguage(LanguageID request)
|
||||
{
|
||||
// Japanese events must be Japanese
|
||||
if (Language == EncounterGBLanguage.Japanese)
|
||||
return 1;
|
||||
if (Language == LanguageRestriction.Japanese)
|
||||
return Japanese;
|
||||
if (Language == LanguageRestriction.English)
|
||||
return English;
|
||||
|
||||
// International events must be non-Japanese
|
||||
var lang = (int)Core.Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, Version);
|
||||
if (lang == 1 && Language == EncounterGBLanguage.International)
|
||||
return 2;
|
||||
return lang;
|
||||
}
|
||||
|
||||
private string GetInitialOT(ITrainerInfo tr)
|
||||
{
|
||||
if (OriginalTrainerName.Length != 0)
|
||||
return OriginalTrainerName;
|
||||
if (TrainerNames.Length != 0)
|
||||
return TrainerNames.Span[Util.Rand.Next(TrainerNames.Length)];
|
||||
return tr.OT;
|
||||
if (request is not (English or French or Italian or German or Spanish))
|
||||
request = English;
|
||||
if (request == English && Language == LanguageRestriction.InternationalNotEnglish)
|
||||
return French;
|
||||
return request;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -152,7 +194,7 @@ public sealed record EncounterGift2(ushort Species, byte Level, GameVersion Vers
|
|||
if (Form != evo.Form && !FormInfo.IsFormChangeable(Species, Form, pk.Form, Context, pk.Context))
|
||||
return false;
|
||||
|
||||
if (Language != EncounterGBLanguage.Any && pk.Japanese != (Language == EncounterGBLanguage.Japanese))
|
||||
if (!IsLanguageValid(pk.Language))
|
||||
return false;
|
||||
|
||||
if (CurrentLevel != 0 && CurrentLevel > pk.CurrentLevel)
|
||||
|
@ -166,23 +208,46 @@ public sealed record EncounterGift2(ushort Species, byte Level, GameVersion Vers
|
|||
return true;
|
||||
|
||||
// Check OT Details
|
||||
if (TID16 != UnspecifiedID && pk.TID16 != TID16)
|
||||
if (!IsTrainerIDValid(pk))
|
||||
return false;
|
||||
if (!IsTrainerNameValid(pk))
|
||||
return false;
|
||||
|
||||
if (OriginalTrainerName.Length != 0)
|
||||
{
|
||||
if (pk.OriginalTrainerName != OriginalTrainerName)
|
||||
return false;
|
||||
}
|
||||
else if (TrainerNames.Length != 0)
|
||||
{
|
||||
if (!TrainerNames.Span.Contains(pk.OriginalTrainerName))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsLanguageValid(int pkLanguage)
|
||||
{
|
||||
if (pkLanguage == (int)Japanese)
|
||||
return Language is LanguageRestriction.Japanese;
|
||||
return Language is not LanguageRestriction.Japanese;
|
||||
}
|
||||
|
||||
private bool IsTrainerNameValid(PKM pk) => Trainer switch
|
||||
{
|
||||
Recipient => true,
|
||||
GiftStadiumJPN => pk.OriginalTrainerName == StadiumJPN,
|
||||
GiftStadiumENG => pk.OriginalTrainerName == StadiumENG,
|
||||
GiftStadiumINT => pk.OriginalTrainerName switch
|
||||
{
|
||||
StadiumGER => true,
|
||||
StadiumFRE => true,
|
||||
StadiumITA => true,
|
||||
StadiumSPA => true,
|
||||
_ => false,
|
||||
},
|
||||
PokemonCenterNewYork => IsTrainerPCNY(pk.OriginalTrainerName),
|
||||
_ => true,
|
||||
};
|
||||
|
||||
private bool IsTrainerIDValid(ITrainerID16 pk) => Trainer switch
|
||||
{
|
||||
Recipient => true,
|
||||
GiftStadiumJPN => pk.TID16 == TrainerIDStadiumJPN,
|
||||
GiftStadiumENG => pk.TID16 == TrainerIDStadiumENG,
|
||||
GiftStadiumINT => pk.TID16 == TrainerIDStadiumINT,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
private bool IsMatchEggLocation(PKM pk)
|
||||
{
|
||||
if (pk is not ICaughtData2 c2)
|
||||
|
|
|
@ -94,7 +94,7 @@ public sealed class TrainerNameVerifier : Verifier
|
|||
{
|
||||
// Transferring from RBY->Gen7 won't have OT Gender in PK1, nor will PK1 originated encounters.
|
||||
// GSC Trades already checked for OT Gender matching.
|
||||
if (pk is { Format: > 2, VC1: true } || enc is { Generation: 1 } or EncounterGift2 { IsGift: true })
|
||||
if (pk is { Format: > 2, VC1: true } || enc is { Generation: 1 } or EncounterGift2 { EggEncounter: false })
|
||||
data.AddLine(GetInvalid(LG1OTGender));
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ public static class TrashBytes
|
|||
/// </summary>
|
||||
/// <param name="buffer">Buffer to check the length of.</param>
|
||||
/// <param name="terminator">String terminator to search for.</param>
|
||||
/// <returns>Index of the terminator, or max length if not found.</returns>
|
||||
/// <returns>Decoded index (char) of the terminator, or max length if not found.</returns>
|
||||
public static int GetStringLength(ReadOnlySpan<byte> buffer, ushort terminator = 0)
|
||||
{
|
||||
int index = FindTerminatorIndex(buffer, terminator);
|
||||
|
@ -25,7 +25,7 @@ public static class TrashBytes
|
|||
/// </summary>
|
||||
/// <param name="buffer">Backing buffer of the string.</param>
|
||||
/// <param name="terminator">Terminator character to search for.</param>
|
||||
/// <returns>Index of the terminator, or -1 if not found.</returns>
|
||||
/// <returns>Decoded index (char) of the terminator, or -1 if not found.</returns>
|
||||
/// <remarks>When used on a raw string, returns the computed length of the string, assuming a terminator is present.</remarks>
|
||||
public static int FindTerminatorIndex(ReadOnlySpan<byte> buffer, ushort terminator = 0)
|
||||
{
|
||||
|
|
BIN
PKHeX.Core/Resources/legality/mgdb/event1.pkl
Normal file
BIN
PKHeX.Core/Resources/legality/mgdb/event1.pkl
Normal file
Binary file not shown.
BIN
PKHeX.Core/Resources/legality/mgdb/event2.pkl
Normal file
BIN
PKHeX.Core/Resources/legality/mgdb/event2.pkl
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue