diff --git a/src/lib/generators/index.ts b/src/lib/generators/index.ts index d759f63..a7c4a17 100644 --- a/src/lib/generators/index.ts +++ b/src/lib/generators/index.ts @@ -1 +1,2 @@ export * as RTDX from './rtdx'; +export * as RT from './rt'; diff --git a/src/lib/generators/rt/data.ts b/src/lib/generators/rt/data.ts new file mode 100755 index 0000000..6b20afa --- /dev/null +++ b/src/lib/generators/rt/data.ts @@ -0,0 +1,163 @@ +import RomData from './romdata'; + +interface PokemonData { + name: string; + index: number; + valid: boolean; +} + +interface DungeonData { + name: string; + index: number; + floors: number; + items: number[]; + difficulties: number[]; + valid: boolean; +} + +interface ItemData { + name: string; + index: number; + valid: boolean; +} + +/** + * Transforms string into only numbers and lowercase letters + */ +function toID(str?: string): string { + if (!str) return ''; + return str.toLowerCase().replace(/[^a-z0-9]+/g, ''); +} + +const Data = { + pokemon: { + all(): PokemonData[] { + return RomData.pokemon.map((pokemon, i) => ({ ...pokemon, index: i })); + }, + get(indexOrName: number | string) { + let pokemon: PokemonData | undefined; + if (typeof indexOrName === 'number') { + const data = this.all()[indexOrName]; + if (data) { + pokemon = { + name: data.name, + index: indexOrName, + valid: data.valid, + }; + } + } else { + const index = this.all().findIndex((p) => toID(p.name) === toID(indexOrName)); + if (index >= 0) { + const data = this.all()[index]; + pokemon = { + name: data.name, + index, + valid: data.valid, + }; + } + } + if (!pokemon) { + pokemon = { + name: '', + index: -1, + valid: false, + }; + } + return pokemon; + }, + }, + dungeons: { + all(): DungeonData[] { + return RomData.dungeons.map((dungeon, i) => ({ ...dungeon, index: i })); + }, + get(indexOrName: number | string) { + let dungeon: DungeonData | undefined; + if (typeof indexOrName === 'number') { + const data = this.all()[indexOrName]; + if (data) { + dungeon = { + name: data.name, + index: indexOrName, + floors: data.floors, + items: data.items, + difficulties: data.difficulties, + valid: data.valid, + }; + } + } else { + const index = this.all().findIndex((d) => toID(d.name) === toID(indexOrName)); + if (index >= 0) { + const data = this.all()[index]; + dungeon = { + name: data.name, + index, + floors: data.floors, + items: data.items, + difficulties: data.difficulties, + valid: data.valid, + }; + } + } + if (!dungeon) { + dungeon = { + name: '', + index: -1, + floors: 0, + items: [], + difficulties: [], + valid: false, + }; + } + return dungeon; + }, + getDifficulty(dungeon: DungeonData, floor: number, missionType: number) { + if (!dungeon.difficulties.length || floor < 1 || floor > dungeon.floors) return 0; + const baseDifficulty = dungeon.difficulties[floor - 1]; + if (!baseDifficulty) return 0; + let difficulty = baseDifficulty; + if (missionType === 2) difficulty += 2; + difficulty = Math.min(difficulty, 15); + difficulty = Math.floor(difficulty / 2); + difficulty = Math.min(difficulty, 6); + return difficulty; + }, + }, + items: { + all(): ItemData[] { + return RomData.items.map((item, i) => ({ ...item, index: i })); + }, + get(indexOrName: number | string) { + let item: ItemData | undefined; + if (typeof indexOrName === 'number') { + const data = this.all()[indexOrName]; + if (data) { + item = { + name: data.name, + index: indexOrName, + valid: data.valid, + }; + } + } else { + const index = this.all().findIndex((i) => toID(i.name) === toID(indexOrName)); + if (index >= 0) { + const data = this.all()[index]; + item = { + name: data.name, + index, + valid: data.valid, + }; + } + } + if (!item) { + item = { + name: '', + index: -1, + valid: false, + }; + } + return item; + }, + }, + missionTypes: ['Help me', 'Find someone', 'Escort', 'Find item', 'Deliver item'], +}; +export default Data; diff --git a/src/lib/generators/rt/index.ts b/src/lib/generators/rt/index.ts new file mode 100755 index 0000000..b957675 --- /dev/null +++ b/src/lib/generators/rt/index.ts @@ -0,0 +1,2 @@ +export { generateWondermail } from './wm/generate'; +export { default as data } from './data'; diff --git a/src/lib/generators/rt/romdata.ts b/src/lib/generators/rt/romdata.ts new file mode 100644 index 0000000..3edff6e --- /dev/null +++ b/src/lib/generators/rt/romdata.ts @@ -0,0 +1,3558 @@ +const RomData = { + pokemon: [ + { + name: '', + valid: false, + }, + { + name: 'Bulbasaur', + valid: true, + }, + { + name: 'Ivysaur', + valid: true, + }, + { + name: 'Venusaur', + valid: true, + }, + { + name: 'Charmander', + valid: true, + }, + { + name: 'Charmeleon', + valid: true, + }, + { + name: 'Charizard', + valid: true, + }, + { + name: 'Squirtle', + valid: true, + }, + { + name: 'Wartortle', + valid: true, + }, + { + name: 'Blastoise', + valid: true, + }, + { + name: 'Caterpie', + valid: true, + }, + { + name: 'Metapod', + valid: true, + }, + { + name: 'Butterfree', + valid: true, + }, + { + name: 'Weedle', + valid: true, + }, + { + name: 'Kakuna', + valid: false, + }, + { + name: 'Beedrill', + valid: true, + }, + { + name: 'Pidgey', + valid: true, + }, + { + name: 'Pidgeotto', + valid: true, + }, + { + name: 'Pidgeot', + valid: true, + }, + { + name: 'Rattata', + valid: true, + }, + { + name: 'Raticate', + valid: true, + }, + { + name: 'Spearow', + valid: true, + }, + { + name: 'Fearow', + valid: true, + }, + { + name: 'Ekans', + valid: true, + }, + { + name: 'Arbok', + valid: true, + }, + { + name: 'Pikachu', + valid: true, + }, + { + name: 'Raichu', + valid: true, + }, + { + name: 'Sandshrew', + valid: true, + }, + { + name: 'Sandslash', + valid: true, + }, + { + name: 'Nidoran♀', + valid: true, + }, + { + name: 'Nidorina', + valid: true, + }, + { + name: 'Nidoqueen', + valid: true, + }, + { + name: 'Nidoran♂', + valid: true, + }, + { + name: 'Nidorino', + valid: true, + }, + { + name: 'Nidoking', + valid: true, + }, + { + name: 'Clefairy', + valid: true, + }, + { + name: 'Clefable', + valid: true, + }, + { + name: 'Vulpix', + valid: true, + }, + { + name: 'Ninetales', + valid: true, + }, + { + name: 'Jigglypuff', + valid: true, + }, + { + name: 'Wigglytuff', + valid: true, + }, + { + name: 'Zubat', + valid: true, + }, + { + name: 'Golbat', + valid: true, + }, + { + name: 'Oddish', + valid: true, + }, + { + name: 'Gloom', + valid: true, + }, + { + name: 'Vileplume', + valid: true, + }, + { + name: 'Paras', + valid: true, + }, + { + name: 'Parasect', + valid: true, + }, + { + name: 'Venonat', + valid: true, + }, + { + name: 'Venomoth', + valid: true, + }, + { + name: 'Diglett', + valid: true, + }, + { + name: 'Dugtrio', + valid: true, + }, + { + name: 'Meowth', + valid: true, + }, + { + name: 'Persian', + valid: true, + }, + { + name: 'Psyduck', + valid: true, + }, + { + name: 'Golduck', + valid: true, + }, + { + name: 'Mankey', + valid: true, + }, + { + name: 'Primeape', + valid: true, + }, + { + name: 'Growlithe', + valid: true, + }, + { + name: 'Arcanine', + valid: true, + }, + { + name: 'Poliwag', + valid: true, + }, + { + name: 'Poliwhirl', + valid: true, + }, + { + name: 'Poliwrath', + valid: true, + }, + { + name: 'Abra', + valid: true, + }, + { + name: 'Kadabra', + valid: true, + }, + { + name: 'Alakazam', + valid: true, + }, + { + name: 'Machop', + valid: true, + }, + { + name: 'Machoke', + valid: true, + }, + { + name: 'Machamp', + valid: true, + }, + { + name: 'Bellsprout', + valid: true, + }, + { + name: 'Weepinbell', + valid: true, + }, + { + name: 'Victreebel', + valid: true, + }, + { + name: 'Tentacool', + valid: true, + }, + { + name: 'Tentacruel', + valid: true, + }, + { + name: 'Geodude', + valid: true, + }, + { + name: 'Graveler', + valid: true, + }, + { + name: 'Golem', + valid: true, + }, + { + name: 'Ponyta', + valid: true, + }, + { + name: 'Rapidash', + valid: true, + }, + { + name: 'Slowpoke', + valid: true, + }, + { + name: 'Slowbro', + valid: true, + }, + { + name: 'Magnemite', + valid: false, + }, + { + name: 'Magneton', + valid: false, + }, + { + name: "Farfetch'd", + valid: true, + }, + { + name: 'Doduo', + valid: true, + }, + { + name: 'Dodrio', + valid: true, + }, + { + name: 'Seel', + valid: true, + }, + { + name: 'Dewgong', + valid: true, + }, + { + name: 'Grimer', + valid: true, + }, + { + name: 'Muk', + valid: true, + }, + { + name: 'Shellder', + valid: true, + }, + { + name: 'Cloyster', + valid: true, + }, + { + name: 'Gastly', + valid: true, + }, + { + name: 'Haunter', + valid: true, + }, + { + name: 'Gengar', + valid: false, + }, + { + name: 'Onix', + valid: true, + }, + { + name: 'Drowzee', + valid: true, + }, + { + name: 'Hypno', + valid: true, + }, + { + name: 'Krabby', + valid: true, + }, + { + name: 'Kingler', + valid: true, + }, + { + name: 'Voltorb', + valid: true, + }, + { + name: 'Electrode', + valid: true, + }, + { + name: 'Exeggcute', + valid: true, + }, + { + name: 'Exeggutor', + valid: true, + }, + { + name: 'Cubone', + valid: true, + }, + { + name: 'Marowak', + valid: true, + }, + { + name: 'Hitmonlee', + valid: true, + }, + { + name: 'Hitmonchan', + valid: true, + }, + { + name: 'Lickitung', + valid: true, + }, + { + name: 'Koffing', + valid: true, + }, + { + name: 'Weezing', + valid: true, + }, + { + name: 'Rhyhorn', + valid: true, + }, + { + name: 'Rhydon', + valid: true, + }, + { + name: 'Chansey', + valid: true, + }, + { + name: 'Tangela', + valid: true, + }, + { + name: 'Kangaskhan', + valid: true, + }, + { + name: 'Horsea', + valid: true, + }, + { + name: 'Seadra', + valid: true, + }, + { + name: 'Goldeen', + valid: true, + }, + { + name: 'Seaking', + valid: true, + }, + { + name: 'Staryu', + valid: true, + }, + { + name: 'Starmie', + valid: true, + }, + { + name: 'Mr. Mime', + valid: true, + }, + { + name: 'Scyther', + valid: true, + }, + { + name: 'Jynx', + valid: true, + }, + { + name: 'Electabuzz', + valid: true, + }, + { + name: 'Magmar', + valid: true, + }, + { + name: 'Pinsir', + valid: true, + }, + { + name: 'Tauros', + valid: true, + }, + { + name: 'Magikarp', + valid: true, + }, + { + name: 'Gyarados', + valid: true, + }, + { + name: 'Lapras', + valid: true, + }, + { + name: 'Ditto', + valid: true, + }, + { + name: 'Eevee', + valid: true, + }, + { + name: 'Vaporeon', + valid: true, + }, + { + name: 'Jolteon', + valid: true, + }, + { + name: 'Flareon', + valid: true, + }, + { + name: 'Porygon', + valid: true, + }, + { + name: 'Omanyte', + valid: true, + }, + { + name: 'Omastar', + valid: true, + }, + { + name: 'Kabuto', + valid: true, + }, + { + name: 'Kabutops', + valid: true, + }, + { + name: 'Aerodactyl', + valid: true, + }, + { + name: 'Snorlax', + valid: true, + }, + { + name: 'Articuno', + valid: false, + }, + { + name: 'Zapdos', + valid: false, + }, + { + name: 'Moltres', + valid: false, + }, + { + name: 'Dratini', + valid: true, + }, + { + name: 'Dragonair', + valid: true, + }, + { + name: 'Dragonite', + valid: true, + }, + { + name: 'Mewtwo', + valid: false, + }, + { + name: 'Mew', + valid: false, + }, + { + name: 'Chikorita', + valid: true, + }, + { + name: 'Bayleef', + valid: true, + }, + { + name: 'Meganium', + valid: true, + }, + { + name: 'Cyndaquil', + valid: true, + }, + { + name: 'Quilava', + valid: true, + }, + { + name: 'Typhlosion', + valid: true, + }, + { + name: 'Totodile', + valid: true, + }, + { + name: 'Croconaw', + valid: true, + }, + { + name: 'Feraligatr', + valid: true, + }, + { + name: 'Sentret', + valid: true, + }, + { + name: 'Furret', + valid: true, + }, + { + name: 'Hoothoot', + valid: true, + }, + { + name: 'Noctowl', + valid: true, + }, + { + name: 'Ledyba', + valid: true, + }, + { + name: 'Ledian', + valid: true, + }, + { + name: 'Spinarak', + valid: true, + }, + { + name: 'Ariados', + valid: true, + }, + { + name: 'Crobat', + valid: true, + }, + { + name: 'Chinchou', + valid: true, + }, + { + name: 'Lanturn', + valid: true, + }, + { + name: 'Pichu', + valid: true, + }, + { + name: 'Cleffa', + valid: true, + }, + { + name: 'Igglybuff', + valid: true, + }, + { + name: 'Togepi', + valid: true, + }, + { + name: 'Togetic', + valid: true, + }, + { + name: 'Natu', + valid: true, + }, + { + name: 'Xatu', + valid: true, + }, + { + name: 'Mareep', + valid: true, + }, + { + name: 'Flaaffy', + valid: true, + }, + { + name: 'Ampharos', + valid: true, + }, + { + name: 'Bellossom', + valid: true, + }, + { + name: 'Marill', + valid: true, + }, + { + name: 'Azumarill', + valid: true, + }, + { + name: 'Sudowoodo', + valid: true, + }, + { + name: 'Politoed', + valid: true, + }, + { + name: 'Hoppip', + valid: true, + }, + { + name: 'Skiploom', + valid: true, + }, + { + name: 'Jumpluff', + valid: true, + }, + { + name: 'Aipom', + valid: true, + }, + { + name: 'Sunkern', + valid: true, + }, + { + name: 'Sunflora', + valid: true, + }, + { + name: 'Yanma', + valid: true, + }, + { + name: 'Wooper', + valid: true, + }, + { + name: 'Quagsire', + valid: true, + }, + { + name: 'Espeon', + valid: true, + }, + { + name: 'Umbreon', + valid: true, + }, + { + name: 'Murkrow', + valid: true, + }, + { + name: 'Slowking', + valid: true, + }, + { + name: 'Misdreavus', + valid: true, + }, + { + name: 'Unown (A)', + valid: false, + }, + { + name: 'Unown (B)', + valid: false, + }, + { + name: 'Unown (C)', + valid: false, + }, + { + name: 'Unown (D)', + valid: false, + }, + { + name: 'Unown (E)', + valid: false, + }, + { + name: 'Unown (F)', + valid: false, + }, + { + name: 'Unown (G)', + valid: false, + }, + { + name: 'Unown (H)', + valid: false, + }, + { + name: 'Unown (I)', + valid: false, + }, + { + name: 'Unown (J)', + valid: false, + }, + { + name: 'Unown (K)', + valid: false, + }, + { + name: 'Unown (L)', + valid: false, + }, + { + name: 'Unown (M)', + valid: false, + }, + { + name: 'Unown (N)', + valid: false, + }, + { + name: 'Unown (O)', + valid: false, + }, + { + name: 'Unown (P)', + valid: false, + }, + { + name: 'Unown (Q)', + valid: false, + }, + { + name: 'Unown (R)', + valid: false, + }, + { + name: 'Unown (S)', + valid: false, + }, + { + name: 'Unown (T)', + valid: false, + }, + { + name: 'Unown (U)', + valid: false, + }, + { + name: 'Unown (V)', + valid: false, + }, + { + name: 'Unown (W)', + valid: false, + }, + { + name: 'Unown (X)', + valid: false, + }, + { + name: 'Unown (Y)', + valid: false, + }, + { + name: 'Unown (Z)', + valid: false, + }, + { + name: 'Wobbuffet', + valid: true, + }, + { + name: 'Girafarig', + valid: true, + }, + { + name: 'Pineco', + valid: true, + }, + { + name: 'Forretress', + valid: true, + }, + { + name: 'Dunsparce', + valid: true, + }, + { + name: 'Gligar', + valid: true, + }, + { + name: 'Steelix', + valid: true, + }, + { + name: 'Snubbull', + valid: true, + }, + { + name: 'Granbull', + valid: true, + }, + { + name: 'Qwilfish', + valid: true, + }, + { + name: 'Scizor', + valid: true, + }, + { + name: 'Shuckle', + valid: true, + }, + { + name: 'Heracross', + valid: true, + }, + { + name: 'Sneasel', + valid: true, + }, + { + name: 'Teddiursa', + valid: true, + }, + { + name: 'Ursaring', + valid: true, + }, + { + name: 'Slugma', + valid: true, + }, + { + name: 'Magcargo', + valid: true, + }, + { + name: 'Swinub', + valid: true, + }, + { + name: 'Piloswine', + valid: true, + }, + { + name: 'Corsola', + valid: true, + }, + { + name: 'Remoraid', + valid: true, + }, + { + name: 'Octillery', + valid: true, + }, + { + name: 'Delibird', + valid: true, + }, + { + name: 'Mantine', + valid: true, + }, + { + name: 'Skarmory', + valid: true, + }, + { + name: 'Houndour', + valid: true, + }, + { + name: 'Houndoom', + valid: true, + }, + { + name: 'Kingdra', + valid: true, + }, + { + name: 'Phanpy', + valid: true, + }, + { + name: 'Donphan', + valid: true, + }, + { + name: 'Porygon2', + valid: true, + }, + { + name: 'Stantler', + valid: true, + }, + { + name: 'Smeargle', + valid: true, + }, + { + name: 'Tyrogue', + valid: true, + }, + { + name: 'Hitmontop', + valid: true, + }, + { + name: 'Smoochum', + valid: true, + }, + { + name: 'Elekid', + valid: true, + }, + { + name: 'Magby', + valid: true, + }, + { + name: 'Miltank', + valid: true, + }, + { + name: 'Blissey', + valid: true, + }, + { + name: 'Raikou', + valid: false, + }, + { + name: 'Entei', + valid: false, + }, + { + name: 'Suicune', + valid: false, + }, + { + name: 'Larvitar', + valid: true, + }, + { + name: 'Pupitar', + valid: true, + }, + { + name: 'Tyranitar', + valid: true, + }, + { + name: 'Lugia', + valid: false, + }, + { + name: 'Ho-Oh', + valid: false, + }, + { + name: 'Celebi', + valid: false, + }, + { + name: 'Treecko', + valid: true, + }, + { + name: 'Grovyle', + valid: true, + }, + { + name: 'Sceptile', + valid: true, + }, + { + name: 'Torchic', + valid: true, + }, + { + name: 'Combusken', + valid: true, + }, + { + name: 'Blaziken', + valid: true, + }, + { + name: 'Mudkip', + valid: true, + }, + { + name: 'Marshtomp', + valid: true, + }, + { + name: 'Swampert', + valid: true, + }, + { + name: 'Poochyena', + valid: true, + }, + { + name: 'Mightyena', + valid: true, + }, + { + name: 'Zigzagoon', + valid: true, + }, + { + name: 'Linoone', + valid: true, + }, + { + name: 'Wurmple', + valid: true, + }, + { + name: 'Silcoon', + valid: false, + }, + { + name: 'Beautifly', + valid: true, + }, + { + name: 'Cascoon', + valid: false, + }, + { + name: 'Dustox', + valid: true, + }, + { + name: 'Lotad', + valid: true, + }, + { + name: 'Lombre', + valid: true, + }, + { + name: 'Ludicolo', + valid: true, + }, + { + name: 'Seedot', + valid: true, + }, + { + name: 'Nuzleaf', + valid: true, + }, + { + name: 'Shiftry', + valid: true, + }, + { + name: 'Taillow', + valid: true, + }, + { + name: 'Swellow', + valid: true, + }, + { + name: 'Wingull', + valid: true, + }, + { + name: 'Pelipper', + valid: true, + }, + { + name: 'Ralts', + valid: true, + }, + { + name: 'Kirlia', + valid: true, + }, + { + name: 'Gardevoir', + valid: false, + }, + { + name: 'Surskit', + valid: true, + }, + { + name: 'Masquerain', + valid: true, + }, + { + name: 'Shroomish', + valid: true, + }, + { + name: 'Breloom', + valid: true, + }, + { + name: 'Slakoth', + valid: true, + }, + { + name: 'Vigoroth', + valid: true, + }, + { + name: 'Slaking', + valid: true, + }, + { + name: 'Nincada', + valid: true, + }, + { + name: 'Ninjask', + valid: true, + }, + { + name: 'Shedinja', + valid: true, + }, + { + name: 'Whismur', + valid: true, + }, + { + name: 'Loudred', + valid: true, + }, + { + name: 'Exploud', + valid: true, + }, + { + name: 'Makuhita', + valid: true, + }, + { + name: 'Hariyama', + valid: true, + }, + { + name: 'Azurill', + valid: true, + }, + { + name: 'Nosepass', + valid: true, + }, + { + name: 'Skitty', + valid: true, + }, + { + name: 'Delcatty', + valid: true, + }, + { + name: 'Sableye', + valid: true, + }, + { + name: 'Mawile', + valid: true, + }, + { + name: 'Aron', + valid: true, + }, + { + name: 'Lairon', + valid: true, + }, + { + name: 'Aggron', + valid: true, + }, + { + name: 'Meditite', + valid: true, + }, + { + name: 'Medicham', + valid: true, + }, + { + name: 'Electrike', + valid: true, + }, + { + name: 'Manectric', + valid: true, + }, + { + name: 'Plusle', + valid: true, + }, + { + name: 'Minun', + valid: true, + }, + { + name: 'Volbeat', + valid: true, + }, + { + name: 'Illumise', + valid: true, + }, + { + name: 'Roselia', + valid: true, + }, + { + name: 'Gulpin', + valid: true, + }, + { + name: 'Swalot', + valid: true, + }, + { + name: 'Carvanha', + valid: true, + }, + { + name: 'Sharpedo', + valid: true, + }, + { + name: 'Wailmer', + valid: true, + }, + { + name: 'Wailord', + valid: true, + }, + { + name: 'Numel', + valid: true, + }, + { + name: 'Camerupt', + valid: true, + }, + { + name: 'Torkoal', + valid: true, + }, + { + name: 'Spoink', + valid: true, + }, + { + name: 'Grumpig', + valid: true, + }, + { + name: 'Spinda', + valid: true, + }, + { + name: 'Trapinch', + valid: true, + }, + { + name: 'Vibrava', + valid: true, + }, + { + name: 'Flygon', + valid: true, + }, + { + name: 'Cacnea', + valid: true, + }, + { + name: 'Cacturne', + valid: true, + }, + { + name: 'Swablu', + valid: true, + }, + { + name: 'Altaria', + valid: true, + }, + { + name: 'Zangoose', + valid: true, + }, + { + name: 'Seviper', + valid: true, + }, + { + name: 'Lunatone', + valid: true, + }, + { + name: 'Solrock', + valid: true, + }, + { + name: 'Barboach', + valid: true, + }, + { + name: 'Whiscash', + valid: true, + }, + { + name: 'Corphish', + valid: true, + }, + { + name: 'Crawdaunt', + valid: true, + }, + { + name: 'Baltoy', + valid: true, + }, + { + name: 'Claydol', + valid: true, + }, + { + name: 'Lileep', + valid: true, + }, + { + name: 'Cradily', + valid: true, + }, + { + name: 'Anorith', + valid: true, + }, + { + name: 'Armaldo', + valid: true, + }, + { + name: 'Feebas', + valid: true, + }, + { + name: 'Milotic', + valid: true, + }, + { + name: 'Castform', + valid: false, + }, + { + name: 'Castform (Water)', + valid: false, + }, + { + name: 'Castform (Fire)', + valid: false, + }, + { + name: 'Castform (Ice)', + valid: false, + }, + { + name: 'Kecleon', + valid: false, + }, + { + name: 'Shuppet', + valid: true, + }, + { + name: 'Banette', + valid: true, + }, + { + name: 'Duskull', + valid: true, + }, + { + name: 'Dusclops', + valid: true, + }, + { + name: 'Tropius', + valid: true, + }, + { + name: 'Chimecho', + valid: true, + }, + { + name: 'Absol', + valid: true, + }, + { + name: 'Wynaut', + valid: true, + }, + { + name: 'Snorunt', + valid: true, + }, + { + name: 'Glalie', + valid: true, + }, + { + name: 'Spheal', + valid: true, + }, + { + name: 'Sealeo', + valid: true, + }, + { + name: 'Walrein', + valid: true, + }, + { + name: 'Clamperl', + valid: true, + }, + { + name: 'Huntail', + valid: true, + }, + { + name: 'Gorebyss', + valid: true, + }, + { + name: 'Relicanth', + valid: true, + }, + { + name: 'Luvdisc', + valid: true, + }, + { + name: 'Bagon', + valid: true, + }, + { + name: 'Shelgon', + valid: true, + }, + { + name: 'Salamence', + valid: true, + }, + { + name: 'Beldum', + valid: true, + }, + { + name: 'Metang', + valid: true, + }, + { + name: 'Metagross', + valid: true, + }, + { + name: 'Regirock', + valid: false, + }, + { + name: 'Regice', + valid: false, + }, + { + name: 'Registeel', + valid: false, + }, + { + name: 'Latias', + valid: false, + }, + { + name: 'Latios', + valid: false, + }, + { + name: 'Kyogre', + valid: false, + }, + { + name: 'Groudon', + valid: false, + }, + { + name: 'Rayquaza', + valid: false, + }, + { + name: 'Jirachi', + valid: false, + }, + { + name: 'Deoxys (Normal)', + valid: false, + }, + { + name: 'Unown (!)', + valid: false, + }, + { + name: 'Unown (?)', + valid: false, + }, + { + name: 'Deoxys (Defense)', + valid: false, + }, + { + name: 'Deoxys (Attack)', + valid: false, + }, + { + name: 'Deoxys (Speed)', + valid: false, + }, + { + name: 'Munchlax', + valid: false, + }, + { + name: 'Decoy', + valid: false, + }, + { + name: 'Statue', + valid: false, + }, + { + name: 'Rayquaza', + valid: false, + }, + ], + dungeons: [ + { + name: 'Tiny Woods', + floors: 3, + items: [55, 66, 105], + difficulties: [1, 1, 1], + valid: true, + }, + { + name: 'Thunderwave Cave', + floors: 5, + items: [7, 55, 66, 67, 69, 72, 82, 105], + difficulties: [1, 1, 1, 1, 1], + valid: true, + }, + { + name: 'Mt. Steel', + floors: 9, + items: [7, 55, 66, 67, 72, 77, 86, 92, 105, 182, 183, 184, 189, 200, 218], + difficulties: [1, 1, 1, 1, 1, 1, 1, 1, 1], + valid: true, + }, + { + name: 'Sinister Woods', + floors: 13, + items: [ + 55, 58, 63, 66, 67, 72, 77, 82, 86, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 105, 182, 183, 184, 188, 200, 201, + 202, 218, + ], + difficulties: [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + valid: true, + }, + { + name: 'Silent Chasm', + floors: 9, + items: [ + 7, 19, 33, 55, 63, 66, 67, 72, 77, 82, 86, 87, 88, 90, 92, 94, 96, 98, 99, 100, 105, 182, 183, 184, 200, 201, + 202, 218, + ], + difficulties: [2, 2, 2, 2, 2, 2, 2, 3, 3], + valid: true, + }, + { + name: 'Mt. Thunder', + floors: 10, + items: [ + 7, 19, 25, 33, 55, 66, 67, 72, 77, 82, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 101, 105, 129, 130, 133, 134, + 136, 143, 144, 145, 151, 152, 154, 155, 158, 164, 165, 166, 167, 168, 169, 170, 232, + ], + difficulties: [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], + valid: true, + }, + { + name: 'Mt. Thunder Peak', + floors: 3, + items: [55, 72, 77, 86, 87, 89, 90, 91, 92, 93, 94, 95, 98, 102, 105], + difficulties: [3, 3, 3], + valid: true, + }, + { + name: 'Great Canyon', + floors: 12, + items: [ + 7, 19, 33, 55, 63, 66, 67, 72, 77, 82, 86, 87, 90, 91, 92, 93, 94, 95, 96, 98, 102, 105, 129, 130, 133, 134, + 136, 143, 144, 145, 151, 152, 154, 155, 158, 164, 165, 166, 167, 168, 169, 170, 232, + ], + difficulties: [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + valid: true, + }, + { + name: 'Lapis Cave', + floors: 14, + items: [ + 7, 19, 20, 25, 31, 55, 66, 67, 72, 77, 82, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 102, 105, 129, 130, 133, + 134, 136, 143, 144, 145, 151, 152, 154, 155, 158, 164, 165, 166, 167, 168, 169, 170, 232, + ], + difficulties: [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + valid: true, + }, + { + name: 'Mt. Blaze', + floors: 12, + items: [ + 7, 19, 33, 87, 92, 93, 94, 98, 101, 102, 105, 129, 130, 133, 134, 136, 143, 144, 145, 151, 152, 154, 155, 158, + 164, 165, 166, 167, 168, 169, 170, 232, + ], + difficulties: [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + valid: true, + }, + { + name: 'Mt. Blaze Peak', + floors: 3, + items: [87, 105], + difficulties: [4, 4, 4], + valid: true, + }, + { + name: 'Frosty Forest', + floors: 9, + items: [ + 7, 19, 20, 31, 33, 55, 66, 67, 72, 77, 82, 86, 88, 90, 91, 92, 93, 94, 95, 96, 101, 102, 105, 129, 130, 133, + 134, 136, 143, 144, 145, 151, 152, 154, 155, 158, 164, 165, 166, 167, 168, 169, 170, 232, + ], + difficulties: [4, 4, 4, 4, 4, 5, 5, 5, 5], + valid: true, + }, + { + name: 'Frosty Grotto', + floors: 5, + items: [55, 58, 67, 77, 88, 91, 105], + difficulties: [5, 5, 5, 5, 5], + valid: true, + }, + { + name: 'Mt. Freeze', + floors: 15, + items: [ + 2, 7, 10, 19, 20, 21, 31, 33, 55, 58, 66, 67, 72, 77, 82, 86, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100, 101, + 102, 105, 129, 130, 133, 134, 136, 137, 143, 144, 145, 148, 151, 152, 154, 155, 158, 164, 165, 166, 167, 168, + 169, 170, 232, + ], + difficulties: [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + valid: true, + }, + { + name: 'Mt. Freeze Peak', + floors: 5, + items: [55, 58, 67, 77, 86, 88, 90, 91, 92, 93, 94, 95, 96, 98, 102, 105], + difficulties: [5, 5, 5, 5, 5], + valid: true, + }, + { + name: 'Magma Cavern', + floors: 23, + items: [ + 2, 3, 7, 10, 12, 17, 18, 19, 20, 21, 22, 25, 29, 31, 33, 82, 87, 98, 101, 102, 105, 125, 129, 130, 133, 134, + 136, 143, 144, 145, 146, 148, 150, 151, 152, 154, 155, 158, 159, 162, 164, 165, 166, 167, 168, 169, 170, 232, + ], + difficulties: [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6], + valid: true, + }, + { + name: 'Magma Cavern Pit', + floors: 3, + items: [105], + difficulties: [6, 6, 6], + valid: true, + }, + { + name: 'Sky Tower', + floors: 25, + items: [ + 2, 3, 10, 12, 17, 18, 19, 20, 21, 22, 25, 29, 31, 33, 35, 82, 91, 93, 95, 98, 99, 105, 125, 128, 129, 130, 133, + 134, 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 157, 158, 159, 162, 164, 165, 166, + 167, 168, 169, 170, 232, + ], + difficulties: [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6], + valid: true, + }, + { + name: 'Sky Tower Summit', + floors: 9, + items: [ + 10, 12, 16, 17, 18, 19, 20, 21, 22, 29, 31, 33, 35, 105, 125, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, + 145, 146, 148, 150, 151, 152, 153, 154, 155, 157, 158, 159, 162, 164, 165, 166, 167, 168, 169, 170, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7], + valid: true, + }, + { + name: 'Stormy Sea', + floors: 40, + items: [ + 7, 10, 11, 12, 13, 17, 18, 19, 20, 21, 22, 25, 30, 31, 35, 44, 53, 55, 61, 65, 66, 67, 68, 69, 71, 72, 77, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 105, 125, 128, 129, 130, 133, 134, 136, 137, + 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 164, 165, 166, 167, 168, 169, 170, + 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, + ], + valid: true, + }, + { + name: 'Silver Trench', + floors: 99, + items: [ + 2, 3, 7, 10, 11, 12, 13, 17, 18, 19, 20, 21, 22, 25, 30, 31, 35, 44, 53, 55, 63, 66, 67, 68, 69, 71, 77, 84, 88, + 105, 125, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, + 218, + ], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, + ], + valid: true, + }, + { + name: 'Meteor Cave', + floors: 20, + items: [105], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + valid: true, + }, + { + name: 'Mt. Freeze Peak', + floors: 4, + items: [55, 58, 67, 77, 86, 88, 90, 91, 92, 93, 94, 95, 96, 98, 102, 105], + difficulties: [5, 5, 5, 5], + valid: true, + }, + { + name: 'Western Cave', + floors: 99, + items: [53, 55, 58, 63, 66, 67, 68, 69, 72, 77, 78, 79, 80, 81, 105, 123], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, + ], + valid: true, + }, + { + name: 'Boss 3', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Boss 4', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Wish Cave', + floors: 99, + items: [ + 1, 2, 3, 7, 9, 10, 11, 12, 13, 15, 17, 18, 19, 20, 21, 22, 24, 27, 29, 30, 31, 33, 34, 35, 38, 42, 43, 44, 45, + 53, 55, 56, 57, 58, 61, 63, 64, 65, 66, 67, 68, 69, 71, 72, 75, 76, 77, 85, 105, 125, 128, 129, 130, 133, 134, + 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 173, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 195, 196, 197, 199, 200, 201, 202, 203, 204, 207, 208, 211, 212, 213, 214, 218, 219, 221, 222, 223, 232, + ], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, + ], + valid: true, + }, + { + name: 'Buried Relic', + floors: 99, + items: [ + 1, 2, 3, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 24, 27, 29, 30, 31, 33, 34, 35, 38, 42, 44, 45, + 53, 55, 56, 57, 58, 61, 63, 64, 65, 66, 67, 68, 69, 71, 72, 75, 76, 77, 82, 105, 125, 128, 129, 130, 133, 134, + 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 173, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 195, 196, 197, 199, 200, 201, 202, 203, 204, 207, 208, 211, 212, 214, 218, 219, 221, 222, 223, 232, + ], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, + ], + valid: true, + }, + { + name: 'Pitfall Valley', + floors: 25, + items: [ + 2, 3, 7, 10, 12, 16, 17, 18, 19, 20, 21, 22, 25, 29, 30, 31, 53, 55, 58, 63, 64, 65, 66, 67, 72, 77, 105, 125, + 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 162, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, + 218, 232, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9], + valid: true, + }, + { + name: 'Northern Range', + floors: 25, + items: [ + 2, 3, 7, 10, 12, 16, 17, 18, 19, 20, 21, 22, 25, 29, 30, 31, 53, 55, 58, 63, 64, 65, 66, 67, 72, 77, 105, 125, + 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 162, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, + 218, 232, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9], + valid: true, + }, + { + name: 'Boss 9', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Desert Region', + floors: 20, + items: [ + 7, 10, 19, 20, 21, 25, 31, 105, 123, 125, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, 148, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, 184, 189, + 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + valid: true, + }, + { + name: 'Southern Cavern', + floors: 50, + items: [ + 7, 14, 15, 16, 17, 24, 27, 29, 30, 33, 34, 38, 53, 55, 66, 67, 83, 105, 115, 125, 128, 129, 130, 133, 134, 136, + 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 164, 165, 166, 167, + 168, 169, 170, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + ], + valid: true, + }, + { + name: 'Wyvern Hill', + floors: 30, + items: [ + 1, 2, 3, 7, 14, 15, 16, 17, 24, 27, 29, 30, 33, 34, 38, 44, 53, 55, 57, 58, 59, 61, 63, 64, 65, 66, 67, 68, 69, + 71, 72, 75, 76, 77, 83, 105, 117, 125, 126, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, 148, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, 184, + 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9], + valid: true, + }, + { + name: 'Fiery Field', + floors: 30, + items: [ + 1, 2, 3, 7, 14, 15, 16, 17, 24, 27, 29, 30, 33, 34, 38, 53, 55, 57, 58, 59, 61, 63, 64, 65, 66, 67, 68, 69, 71, + 72, 75, 76, 77, 78, 79, 80, 81, 82, 105, 113, 125, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, + 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, + 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9], + valid: true, + }, + { + name: 'Northwind Field', + floors: 30, + items: [ + 1, 2, 3, 7, 14, 15, 16, 17, 24, 27, 29, 30, 33, 34, 38, 53, 55, 57, 58, 59, 61, 63, 64, 65, 66, 67, 68, 69, 71, + 72, 75, 76, 77, 78, 79, 80, 81, 82, 105, 114, 125, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, + 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, + 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9], + valid: true, + }, + { + name: 'Solar Cave', + floors: 20, + items: [ + 1, 7, 10, 11, 12, 13, 17, 18, 30, 31, 34, 35, 44, 45, 53, 55, 64, 66, 67, 72, 77, 105, 111, 112, 123, 125, 128, + 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 162, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + 232, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + valid: true, + }, + { + name: 'Lightning Field', + floors: 30, + items: [ + 1, 2, 3, 7, 14, 15, 16, 17, 24, 27, 29, 30, 33, 34, 38, 53, 55, 57, 58, 59, 61, 63, 64, 65, 66, 67, 68, 69, 71, + 72, 75, 76, 77, 78, 79, 80, 81, 82, 105, 108, 125, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, + 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, + 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9], + valid: true, + }, + { + name: 'Darknight Relic', + floors: 15, + items: [ + 1, 2, 3, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 27, 29, 30, 31, 32, 33, 34, 35, 38, 39, + 40, 41, 42, 44, 45, 53, 55, 58, 63, 66, 67, 68, 69, 72, 77, 84, 105, 125, 128, 129, 130, 133, 134, 136, 137, + 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 157, 158, 159, 162, 164, 165, 166, 167, 168, 169, + 170, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], + valid: true, + }, + { + name: 'Wondrous Sea', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Murky Cave', + floors: 19, + items: [105], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + valid: true, + }, + { + name: 'Grand Sea', + floors: 30, + items: [ + 7, 8, 10, 12, 13, 16, 17, 19, 20, 21, 22, 24, 25, 27, 29, 31, 32, 35, 38, 39, 40, 53, 59, 61, 67, 68, 69, 105, + 125, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 213, + 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + valid: true, + }, + { + name: 'Uproar Forest', + floors: 10, + items: [53, 55, 66, 67, 72, 82, 89, 97, 104, 105], + difficulties: [5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + valid: true, + }, + { + name: 'Oddity Cave', + floors: 15, + items: [ + 7, 19, 30, 33, 34, 53, 55, 63, 66, 67, 72, 77, 82, 86, 87, 88, 90, 92, 94, 96, 98, 99, 100, 105, 156, 180, 182, + 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], + valid: true, + }, + { + name: 'Remains Island', + floors: 20, + items: [ + 7, 19, 30, 33, 34, 53, 55, 63, 66, 67, 72, 77, 82, 86, 87, 88, 90, 92, 94, 96, 98, 99, 100, 105, 156, 180, 182, + 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8], + valid: true, + }, + { + name: 'Marvelous Sea', + floors: 20, + items: [ + 7, 8, 10, 12, 13, 16, 17, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31, 32, 35, 38, 39, 40, 53, 59, 61, 67, 68, 69, + 105, 156, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8], + valid: true, + }, + { + name: 'Fantasy Strait', + floors: 30, + items: [ + 7, 8, 10, 12, 13, 16, 17, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31, 32, 35, 38, 39, 40, 53, 59, 61, 67, 68, 69, + 105, 156, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9], + valid: true, + }, + { + name: 'Rock Path', + floors: 4, + items: [ + 7, 53, 55, 64, 66, 67, 72, 77, 83, 105, 156, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, + 218, + ], + difficulties: [1, 1, 1, 1], + valid: true, + }, + { + name: 'Snow Path', + floors: 4, + items: [ + 7, 53, 55, 64, 66, 67, 72, 77, 82, 105, 156, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, + 218, + ], + difficulties: [1, 1, 1, 1], + valid: true, + }, + { + name: 'Autopilot', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'D50', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'D51', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Dojo Registration', + floors: 69, + items: [ + 53, 55, 58, 66, 67, 71, 72, 77, 82, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + ], + difficulties: [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + ], + valid: true, + }, + { + name: 'Howling Forest', + floors: 15, + items: [ + 53, 55, 58, 59, 61, 63, 66, 67, 68, 72, 75, 76, 82, 89, 90, 92, 94, 97, 105, 125, 128, 129, 130, 133, 134, 136, + 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 162, 164, 165, 166, 167, + 168, 169, 170, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, 232, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], + valid: true, + }, + { + name: 'D54', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Fantasy Strait', + floors: 19, + items: [ + 1, 2, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 30, 31, 32, 33, 34, + 35, 37, 38, 39, 40, 41, 42, 44, 45, 46, 53, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 156, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, 218, + ], + difficulties: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + valid: true, + }, + { + name: 'Waterfall Pond', + floors: 19, + items: [8, 53, 55, 66, 67, 71, 72, 77, 105], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], + valid: true, + }, + { + name: 'Unown Relic', + floors: 11, + items: [ + 7, 8, 53, 55, 65, 66, 67, 71, 77, 105, 156, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, 202, 204, 205, + 218, + ], + difficulties: [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7], + valid: true, + }, + { + name: 'Joyous Tower', + floors: 99, + items: [ + 1, 2, 3, 7, 8, 10, 14, 15, 16, 17, 18, 19, 20, 21, 22, 27, 31, 33, 34, 35, 39, 40, 41, 43, 44, 53, 55, 56, 58, + 59, 61, 63, 64, 65, 66, 67, 68, 69, 71, 72, 74, 77, 78, 79, 80, 81, 83, 85, 105, 125, 128, 129, 130, 131, 133, + 134, 135, 136, 137, 140, 142, 143, 144, 145, 146, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 195, 196, 197, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 211, 212, 213, 214, 215, 217, 218, 219, + 221, 222, 223, 232, + ], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, + ], + valid: true, + }, + { + name: 'Far-off Sea', + floors: 75, + items: [ + 7, 8, 10, 12, 13, 16, 17, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31, 32, 35, 38, 39, 40, 53, 59, 61, 67, 68, 69, + 105, 109, 110, 123, 125, 128, 129, 130, 133, 134, 136, 137, 140, 143, 144, 145, 146, 148, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 164, 165, 166, 167, 168, 169, 170, 180, 182, 183, 184, 189, 191, 192, 193, 200, 201, + 202, 204, 205, 218, + ], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, + ], + valid: true, + }, + { + name: 'Mt. Faraway', + floors: 40, + items: [59, 61, 64, 67, 68, 69, 72, 105], + difficulties: [ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, + ], + valid: true, + }, + { + name: 'D61', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Purity Forest', + floors: 99, + items: [ + 1, 2, 3, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 30, 31, 32, 33, 34, 35, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 53, 55, 56, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, + 75, 76, 77, 82, 83, 84, 105, 125, 128, 129, 130, 131, 133, 134, 135, 136, 137, 140, 142, 143, 144, 145, 146, + 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 173, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 211, 212, 213, 214, 215, 217, 218, 219, 221, 222, 223, 232, + ], + difficulties: [ + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, + ], + valid: true, + }, + { + name: 'Out on Rescue', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: '???', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Tiny Woods', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Unknown World', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Frosty Grotto', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Howling Forest', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Pokémon Square', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Pokémon Square', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Rescue Team Base', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Rescue Team Base', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: '****agb-slot ', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Client Pokémon', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Normal Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Fire Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Water Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Grass Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Electric Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Ice Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Fighting Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Ground Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Flying Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Psychic Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Poison Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Bug Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Rock Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Ghost Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Dragon Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Dark Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Steel Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Team Shifty', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Team Constrictor', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Team Hydro', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Team Rumblerock', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Rescue Team 2', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + { + name: 'Rescue Team Maze', + floors: 0, + items: [], + difficulties: [], + valid: false, + }, + ], + items: [ + { + name: '', + valid: false, + }, + { + name: 'Stick', + valid: true, + }, + { + name: 'Iron Thorn', + valid: true, + }, + { + name: 'Silver Spike', + valid: true, + }, + { + name: 'Gold Fang', + valid: true, + }, + { + name: 'Cacnea Spike', + valid: true, + }, + { + name: 'Corsola Twig', + valid: true, + }, + { + name: 'Gravelerock', + valid: true, + }, + { + name: 'Geo Pebble', + valid: true, + }, + { + name: 'Mobile Scarf', + valid: true, + }, + { + name: 'Heal Ribbon', + valid: true, + }, + { + name: 'Twist Band', + valid: true, + }, + { + name: 'Scope Lens', + valid: true, + }, + { + name: 'Patsy Band', + valid: true, + }, + { + name: 'No-Stick Cap', + valid: true, + }, + { + name: 'Pierce Band', + valid: true, + }, + { + name: 'Joy Ribbon', + valid: true, + }, + { + name: 'X-Ray Specs', + valid: true, + }, + { + name: 'Persim Band', + valid: true, + }, + { + name: 'Power Band', + valid: true, + }, + { + name: 'Pecha Scarf', + valid: true, + }, + { + name: 'Insomniscope', + valid: true, + }, + { + name: 'Warp Scarf', + valid: true, + }, + { + name: 'Tight Belt', + valid: true, + }, + { + name: 'Sneak Scarf', + valid: true, + }, + { + name: 'Gold Ribbon', + valid: true, + }, + { + name: 'Goggle Specs', + valid: true, + }, + { + name: 'Diet Ribbon', + valid: true, + }, + { + name: 'Trap Scarf', + valid: true, + }, + { + name: 'Racket Band', + valid: true, + }, + { + name: 'Def. Scarf', + valid: true, + }, + { + name: 'Stamina Band', + valid: true, + }, + { + name: 'Plain Ribbon', + valid: true, + }, + { + name: 'Special Band', + valid: true, + }, + { + name: 'Zinc Band', + valid: true, + }, + { + name: 'Detect Band', + valid: true, + }, + { + name: 'Alert Specs', + valid: false, + }, + { + name: 'Dodge Scarf', + valid: true, + }, + { + name: 'Bounce Band', + valid: true, + }, + { + name: 'Curve Band', + valid: true, + }, + { + name: 'Whiff Specs', + valid: true, + }, + { + name: 'No-Aim Scope', + valid: true, + }, + { + name: 'Lockon Specs', + valid: true, + }, + { + name: 'Munch Belt', + valid: true, + }, + { + name: 'Pass Scarf', + valid: true, + }, + { + name: 'Weather Band', + valid: true, + }, + { + name: 'Friend Bow', + valid: true, + }, + { + name: 'Beauty Scarf', + valid: true, + }, + { + name: 'Sun Ribbon', + valid: true, + }, + { + name: 'Lunar Ribbon', + valid: true, + }, + { + name: 'Ring D', + valid: false, + }, + { + name: 'Ring E', + valid: false, + }, + { + name: 'Ring F', + valid: false, + }, + { + name: 'Heal Seed', + valid: true, + }, + { + name: 'Wish Stone', + valid: true, + }, + { + name: 'Oran Berry', + valid: true, + }, + { + name: 'Sitrus Berry', + valid: true, + }, + { + name: 'Eyedrop Seed', + valid: true, + }, + { + name: 'Reviver Seed', + valid: true, + }, + { + name: 'Blinker Seed', + valid: true, + }, + { + name: 'Doom Seed', + valid: true, + }, + { + name: 'Allure Seed', + valid: true, + }, + { + name: 'Life Seed', + valid: true, + }, + { + name: 'Rawst Berry', + valid: true, + }, + { + name: 'Hunger Seed', + valid: true, + }, + { + name: 'Quick Seed', + valid: true, + }, + { + name: 'Pecha Berry', + valid: true, + }, + { + name: 'Cheri Berry', + valid: true, + }, + { + name: 'Totter Seed', + valid: true, + }, + { + name: 'Sleep Seed', + valid: true, + }, + { + name: 'Plain Seed', + valid: true, + }, + { + name: 'Warp Seed', + valid: true, + }, + { + name: 'Blast Seed', + valid: true, + }, + { + name: 'Ginseng', + valid: true, + }, + { + name: 'Joy Seed', + valid: true, + }, + { + name: 'Chesto Berry', + valid: true, + }, + { + name: 'Stun Seed', + valid: true, + }, + { + name: 'Max Elixir', + valid: true, + }, + { + name: 'Protein', + valid: true, + }, + { + name: 'Calcium', + valid: true, + }, + { + name: 'Iron', + valid: true, + }, + { + name: 'Zinc', + valid: true, + }, + { + name: 'Apple', + valid: true, + }, + { + name: 'Big Apple', + valid: true, + }, + { + name: 'Grimy Food', + valid: true, + }, + { + name: 'Huge Apple', + valid: true, + }, + { + name: 'White Gummi', + valid: true, + }, + { + name: 'Red Gummi', + valid: true, + }, + { + name: 'Blue Gummi', + valid: true, + }, + { + name: 'Grass Gummi', + valid: true, + }, + { + name: 'Yellow Gummi', + valid: true, + }, + { + name: 'Clear Gummi', + valid: true, + }, + { + name: 'Orange Gummi', + valid: true, + }, + { + name: 'Pink Gummi', + valid: true, + }, + { + name: 'Brown Gummi', + valid: true, + }, + { + name: 'Sky Gummi', + valid: true, + }, + { + name: 'Gold Gummi', + valid: true, + }, + { + name: 'Green Gummi', + valid: true, + }, + { + name: 'Gray Gummi', + valid: true, + }, + { + name: 'Purple Gummi', + valid: true, + }, + { + name: 'Royal Gummi', + valid: true, + }, + { + name: 'Black Gummi', + valid: true, + }, + { + name: 'Silver Gummi', + valid: true, + }, + { + name: 'Banana', + valid: true, + }, + { + name: 'Chestnut', + valid: true, + }, + { + name: 'POKé', + valid: false, + }, + { + name: 'Upgrade', + valid: true, + }, + { + name: "King's Rock", + valid: true, + }, + { + name: 'Thunderstone', + valid: true, + }, + { + name: 'Deepseascale', + valid: true, + }, + { + name: 'Deepseatooth', + valid: true, + }, + { + name: 'Sun Stone', + valid: true, + }, + { + name: 'Moon Stone', + valid: true, + }, + { + name: 'Fire Stone', + valid: true, + }, + { + name: 'Water Stone', + valid: true, + }, + { + name: 'Metal Coat', + valid: true, + }, + { + name: 'Leaf Stone', + valid: true, + }, + { + name: 'Dragon Scale', + valid: true, + }, + { + name: 'Link Cable', + valid: true, + }, + { + name: 'Ice Part', + valid: true, + }, + { + name: 'Steel Part', + valid: true, + }, + { + name: 'Rock Part', + valid: true, + }, + { + name: 'Music Box', + valid: true, + }, + { + name: 'Key', + valid: true, + }, + { + name: 'Used TM', + valid: true, + }, + { + name: 'Focus Punch', + valid: true, + }, + { + name: 'Dragon Claw', + valid: true, + }, + { + name: 'Water Pulse', + valid: true, + }, + { + name: 'Calm Mind', + valid: true, + }, + { + name: 'Roar', + valid: true, + }, + { + name: 'Toxic', + valid: true, + }, + { + name: 'Hail Orb', + valid: true, + }, + { + name: 'Bulk Up', + valid: true, + }, + { + name: 'Bullet Seed', + valid: true, + }, + { + name: 'Hidden Power', + valid: true, + }, + { + name: 'Sunny Orb', + valid: true, + }, + { + name: 'Taunt', + valid: true, + }, + { + name: 'Ice Beam', + valid: true, + }, + { + name: 'Blizzard', + valid: true, + }, + { + name: 'Hyper Beam', + valid: true, + }, + { + name: 'Light Screen', + valid: true, + }, + { + name: 'Protect', + valid: true, + }, + { + name: 'Rainy Orb', + valid: true, + }, + { + name: 'Giga Drain', + valid: true, + }, + { + name: 'Safeguard', + valid: true, + }, + { + name: 'Frustration', + valid: true, + }, + { + name: 'Solarbeam', + valid: true, + }, + { + name: 'Iron Tail', + valid: true, + }, + { + name: 'Thunderbolt', + valid: true, + }, + { + name: 'Thunder', + valid: true, + }, + { + name: 'Earthquake', + valid: true, + }, + { + name: 'Return', + valid: true, + }, + { + name: 'Dig', + valid: true, + }, + { + name: 'Psychic', + valid: true, + }, + { + name: 'Shadow Ball', + valid: true, + }, + { + name: 'Brick Break', + valid: true, + }, + { + name: 'Evasion Orb', + valid: true, + }, + { + name: 'Reflect', + valid: true, + }, + { + name: 'Shock Wave', + valid: true, + }, + { + name: 'Flamethrower', + valid: true, + }, + { + name: 'Sludge Bomb', + valid: true, + }, + { + name: 'Sandy Orb', + valid: true, + }, + { + name: 'Fire Blast', + valid: true, + }, + { + name: 'Rocky Orb', + valid: true, + }, + { + name: 'Aerial Ace', + valid: true, + }, + { + name: 'Torment', + valid: true, + }, + { + name: 'Facade', + valid: true, + }, + { + name: 'Secret Power', + valid: true, + }, + { + name: 'Rest', + valid: true, + }, + { + name: 'Attract', + valid: true, + }, + { + name: 'Thief', + valid: true, + }, + { + name: 'Steel Wing', + valid: true, + }, + { + name: 'Skill Swap', + valid: true, + }, + { + name: 'Snatch Orb', + valid: true, + }, + { + name: 'Overheat', + valid: true, + }, + { + name: 'Wide Slash', + valid: true, + }, + { + name: 'Excavate', + valid: false, + }, + { + name: 'Spin Slash', + valid: false, + }, + { + name: 'See-Trap Orb', + valid: true, + }, + { + name: 'Mug Orb', + valid: true, + }, + { + name: 'Rebound Orb', + valid: true, + }, + { + name: 'Lob Orb', + valid: true, + }, + { + name: 'Switcher Orb', + valid: true, + }, + { + name: 'Blowback Orb', + valid: true, + }, + { + name: 'Warp Orb', + valid: true, + }, + { + name: 'Transfer Orb', + valid: true, + }, + { + name: 'Slow Orb', + valid: true, + }, + { + name: 'Quick Orb', + valid: true, + }, + { + name: 'Luminous Orb', + valid: true, + }, + { + name: 'Petrify Orb', + valid: true, + }, + { + name: 'Stayaway Orb', + valid: true, + }, + { + name: 'Pounce Orb', + valid: true, + }, + { + name: 'Trawl Orb', + valid: true, + }, + { + name: 'Cleanse Orb', + valid: true, + }, + { + name: 'Observer Orb', + valid: false, + }, + { + name: 'Decoy Orb', + valid: true, + }, + { + name: 'Slumber Orb', + valid: true, + }, + { + name: 'Totter Orb', + valid: true, + }, + { + name: 'Two-Edge Orb', + valid: true, + }, + { + name: 'Silence Orb', + valid: true, + }, + { + name: 'Escape Orb', + valid: true, + }, + { + name: 'Scanner Orb', + valid: true, + }, + { + name: 'Radar Orb', + valid: true, + }, + { + name: 'Drought Orb', + valid: true, + }, + { + name: 'Trapbust Orb', + valid: true, + }, + { + name: 'Rollcall Orb', + valid: true, + }, + { + name: 'Invisify Orb', + valid: true, + }, + { + name: 'One-Shot Orb', + valid: true, + }, + { + name: 'Identify Orb', + valid: true, + }, + { + name: 'Vacuum-Cut', + valid: true, + }, + { + name: 'Reviver Orb', + valid: false, + }, + { + name: 'Shocker Orb', + valid: true, + }, + { + name: 'Sizebust Orb', + valid: true, + }, + { + name: 'One-Room Orb', + valid: true, + }, + { + name: 'Fill-In Orb', + valid: true, + }, + { + name: 'Trapper Orb', + valid: true, + }, + { + name: 'Possess Orb', + valid: false, + }, + { + name: 'Itemizer Orb', + valid: true, + }, + { + name: 'Hurl Orb', + valid: true, + }, + { + name: 'Mobile Orb', + valid: true, + }, + { + name: 'Toss Orb', + valid: false, + }, + { + name: 'Stairs Orb', + valid: true, + }, + { + name: 'Longtoss Orb', + valid: true, + }, + { + name: 'Pierce Orb', + valid: true, + }, + { + name: 'Cut', + valid: true, + }, + { + name: 'Fly', + valid: true, + }, + { + name: 'Surf', + valid: true, + }, + { + name: 'Strength', + valid: true, + }, + { + name: 'Flash', + valid: true, + }, + { + name: 'Rock Smash', + valid: true, + }, + { + name: 'Waterfall', + valid: true, + }, + { + name: 'Dive', + valid: true, + }, + { + name: 'Link Box', + valid: true, + }, + { + name: 'Switch Box', + valid: false, + }, + { + name: 'Weavile Fig', + valid: true, + }, + { + name: 'Mime Jr. Fig', + valid: true, + }, + { + name: 'Beatup Orb', + valid: false, + }, + { + name: 'G Machine 6', + valid: false, + }, + { + name: 'G Machine 7', + valid: false, + }, + { + name: 'G Machine 8', + valid: false, + }, + ], +}; +export default RomData; diff --git a/src/lib/generators/rt/utils.ts b/src/lib/generators/rt/utils.ts new file mode 100755 index 0000000..e82bd44 --- /dev/null +++ b/src/lib/generators/rt/utils.ts @@ -0,0 +1,16 @@ +// prettier-ignore +export const characters = [ + '?', '6', '7', 'N', 'P', 'R', '8', '9', + 'F', '0', '+', '…', 'S', 'T', 'X', 'Y', + '4', '5', 'M', 'C', 'H', 'J', '-', 'K', + '1', '2', '!', '♀', '3', 'Q', '♂', 'W', +]; + +export function checksum(code: number[]): number { + let sum = 0; + for (let i = 0; i < code.length; i++) { + sum += code[i] + i + 1; + sum &= 0xff; + } + return sum; +} diff --git a/src/lib/generators/rt/wm/generate.ts b/src/lib/generators/rt/wm/generate.ts new file mode 100755 index 0000000..62de49b --- /dev/null +++ b/src/lib/generators/rt/wm/generate.ts @@ -0,0 +1,125 @@ +import { BitstreamReader, BitstreamWriter } from '../../bitstream'; +import { characters, checksum } from '../utils'; +import Data from '../data'; + +function shuffle(password: string[]): string[] { + const newPassword: string[] = []; + const shuffledIndexes = [12, 20, 9, 17, 4, 15, 1, 23, 3, 7, 19, 14, 0, 5, 21, 6, 8, 18, 11, 2, 10, 13, 22, 16]; + for (let i = 0; i < shuffledIndexes.length; i++) { + newPassword[i] = password[shuffledIndexes[i]]; + } + return newPassword; +} + +function bitsToChars(password: number[]): string[] { + return password.map((num) => characters[num]); +} + +function bitunpack(bits: number[]): number[] { + const unpacked: number[] = []; + const reader = new BitstreamReader(bits, 8); + while (reader.remaining()) { + unpacked.push(reader.read(5)); + } + return unpacked; +} + +interface WondermailData { + missionType: number; + clientPokemon: number; + targetPokemon: number; + itemToFindOrDeliver?: number; + rewardType: number; + itemReward?: number; + friendAreaReward?: number; + dungeon: number; + floor: number; +} + +export function serialize(data: WondermailData) { + const writer = new BitstreamWriter(8); + writer.write(5, 4); // Mail type + writer.write(data.missionType, 3); + writer.write(0, 4); // Unknown + writer.write(data.clientPokemon, 9); + writer.write(data.targetPokemon || data.clientPokemon, 9); + writer.write(data.itemToFindOrDeliver || 9, 8); + writer.write(data.rewardType, 4); + writer.write(data.itemReward || 9, 8); + writer.write(data.friendAreaReward || 0, 6); + for (let i = 0; i < 3; i++) writer.write(255, 8); // Flavor text + writer.write(data.dungeon, 7); + writer.write(data.floor, 7); + writer.write(0, 19); // Pad to 14 bytes + + const code = writer.finish(); + code.unshift(checksum(code)); + const bits = bitunpack(code); + const chars = bitsToChars(bits); + const shuffled = shuffle(chars); + return shuffled.join(''); +} + +export function generateWondermail( + missionType: number, + clientPokemon: number, + targetPokemon: number, + dungeon: number, + floor: number, + itemToFindOrDeliver?: number, + itemReward?: number, + moneyReward?: boolean, + friendAreaReward?: number +) { + if (!Data.pokemon.get(clientPokemon).valid) throw new Error('Invalid client Pokemon'); + if (missionType === 1 || missionType === 2) { + if (!Data.pokemon.get(targetPokemon).valid) throw new Error('Invalid target Pokemon'); + } + + const dungeonData = Data.dungeons.get(dungeon); + if (!dungeonData.valid) throw new Error('Invalid dungeon'); + if (floor < 1 || floor > dungeonData.floors) throw new Error('Invalid floor'); + + if (missionType === 3 || missionType === 4) { + if (!itemToFindOrDeliver) throw new Error('Item to find/deliver is required for this mission type'); + const itemToFindOrDeliverData = Data.items.get(itemToFindOrDeliver); + if ( + !itemToFindOrDeliverData.valid || + (missionType === 3 && !dungeonData.items.includes(itemToFindOrDeliverData.index)) + ) { + throw new Error('Invalid item to find/deliver'); + } + } else { + itemToFindOrDeliver = 9; + } + + if (itemReward && !Data.items.get(itemReward).valid) throw new Error('Invalid item reward'); + if (friendAreaReward) { + if (![10, 14, 35, 36].includes(friendAreaReward)) throw new Error('Invalid Friend Area reward'); + if (Data.dungeons.getDifficulty(dungeonData, floor, missionType) === 0) { + throw new Error('The mission must have at least D difficulty to recieve a Friend Area reward'); + } + } + + let rewardType = 5; + if (friendAreaReward) { + rewardType = 9; + itemReward = 9; + } else if (itemReward) { + rewardType = moneyReward ? 6 : 8; + friendAreaReward = 0; + } + + const data: WondermailData = { + missionType, + clientPokemon, + targetPokemon, + itemToFindOrDeliver, + rewardType, + itemReward, + friendAreaReward, + dungeon, + floor, + }; + return serialize(data); +} diff --git a/src/lib/generators/rt/wm/read.ts b/src/lib/generators/rt/wm/read.ts new file mode 100755 index 0000000..4a72fd4 --- /dev/null +++ b/src/lib/generators/rt/wm/read.ts @@ -0,0 +1,121 @@ +import { BitstreamReader } from '../../bitstream'; +import { characters, checksum } from '../utils'; + +/** + * Convert password string to array, then + * validates that all characters of the password are valid + * and replaces common unicode characters with the less common ones + * (m,# -> ♂ | f,% -> ♀ | . -> …) + */ +function sanitizePassword(password: string): string[] { + password = password.replace(/\s/g, ''); + if (password.length !== 24) throw new Error('Password must be exatly 24 characters long'); + const sanitized: string[] = []; + for (let char of password) { + char = char.replace('.', '…').replace('m', '♂').replace('#', '♂').replace('f', '♀').replace('%', '♀'); + + if (characters.includes(char)) { + sanitized.push(char); + } else { + throw new Error(`Invalid character: ${char}`); + } + } + return sanitized; +} + +/** + * Unshuffles the 24 character password based on a predefined lookup table + */ +function unshuffle(password: string[]): string[] { + const newPassword: string[] = []; + const shuffledIndexes = [12, 20, 9, 17, 4, 15, 1, 23, 3, 7, 19, 14, 0, 5, 21, 6, 8, 18, 11, 2, 10, 13, 22, 16]; + for (let i = 0; i < shuffledIndexes.length; i++) { + newPassword[shuffledIndexes[i]] = password[i]; + } + return newPassword; +} + +/** + * Converts individual characters of the password to a 5 byte number + */ +function charsToBits(password: string[]): number[] { + return password.map((char) => characters.indexOf(char)); +} + +/** + * Bitpack bits into 8 bytes + */ +function bitpack(bits: number[]): number[] { + const newCode: number[] = []; + const reader = new BitstreamReader(bits, 5); + while (reader.remaining()) { + newCode.push(reader.read(8)); + } + return newCode; +} + +/** + * Data structure of a wondermail + */ +interface WondermailData { + inclChecksum: number; + calcChecksum: number; + mailType: number; + missionType: number; + unknown1: number; + client: number; + target: number; + itemToFindOrDeliver: number; + rewardType: number; + itemReward: number; + friendAreaReward: number; + messageTitle: number; + messageBody: [number, number]; + dungeon: number; + floor: number; +} + +function deserialize(password: string): WondermailData { + const sanitized = sanitizePassword(password); + const unshuffled = unshuffle(sanitized); + const bits = charsToBits(unshuffled); + const code = bitpack(bits); + + const reader = new BitstreamReader(code.slice(1), 8); + + const inclChecksum = code[0]; + const calcChecksum = checksum(code.slice(1)); + + const mailType = reader.read(4); + const missionType = reader.read(3); + const unknown1 = reader.read(4); + const client = reader.read(9); + const target = reader.read(9); + const itemToFindOrDeliver = reader.read(8); + const rewardType = reader.read(4); + const itemReward = reader.read(8); + const friendAreaReward = reader.read(6); + const messageTitle = reader.read(8); + const messageBody: [number, number] = [reader.read(8), reader.read(8)]; + const dungeon = reader.read(7); + const floor = reader.read(7); + + const data: WondermailData = { + inclChecksum, + calcChecksum, + mailType, + missionType, + unknown1, + client, + target, + itemToFindOrDeliver, + rewardType, + itemReward, + friendAreaReward, + messageTitle, + messageBody, + dungeon, + floor, + }; + return data; +} diff --git a/src/lib/generators/rtdx/data.ts b/src/lib/generators/rtdx/data.ts index ab45478..44aeb33 100755 --- a/src/lib/generators/rtdx/data.ts +++ b/src/lib/generators/rtdx/data.ts @@ -27,9 +27,9 @@ function toID(str?: string): string { return str.toLowerCase().replace(/[^a-z0-9]+/g, ''); } -export const Data = { +const Data = { pokemon: { - all: function () { + all() { const pokemonList: PokemonData[] = []; for (const [i, pokemon] of RomData.pokemon.entries()) { let pokemonName = pokemon.name; @@ -62,7 +62,7 @@ export const Data = { } return pokemonList; }, - get: function (indexOrName: number | string) { + get(indexOrName: number | string) { let pokemon: PokemonData | undefined; if (typeof indexOrName === 'number') { pokemon = this.all().find((p) => p.valid && p.index === indexOrName); @@ -73,7 +73,7 @@ export const Data = { pokemon = { const: '', name: '', - index: 0, + index: -1, valid: false, }; } @@ -82,7 +82,7 @@ export const Data = { }, dungeons: { - all: function () { + all() { const dungeons: DungeonData[] = []; for (const [i, dungeon] of RomData.dungeons.entries()) { const index = parseInt(dungeon.const.slice(1)); @@ -96,7 +96,7 @@ export const Data = { } return dungeons; }, - get: function (indexOrName: number | string) { + get(indexOrName: number | string) { let dungeon: DungeonData | undefined; if (typeof indexOrName === 'number') { dungeon = this.all().find((d) => d.valid && d.index === indexOrName); @@ -106,7 +106,7 @@ export const Data = { if (!dungeon) { dungeon = { name: '', - index: 0, + index: -1, floors: 0, ascending: false, valid: false, @@ -120,3 +120,4 @@ export const Data = { charmap_text: RomData.charmap_text, crc32table: RomData.crc32table, }; +export default Data; diff --git a/src/lib/generators/rtdx/generate.ts b/src/lib/generators/rtdx/generate.ts index 92cb260..cfe9c19 100755 --- a/src/lib/generators/rtdx/generate.ts +++ b/src/lib/generators/rtdx/generate.ts @@ -1,7 +1,7 @@ import { BitstreamReader, BitstreamWriter } from '../bitstream'; import { symbols, checksum, RNG } from './utils'; import { read } from './read'; -import { Data } from './data'; +import Data from './data'; /** * Dhuffles the password symbols diff --git a/src/lib/generators/rtdx/index.ts b/src/lib/generators/rtdx/index.ts index 9526633..5bb31b6 100755 --- a/src/lib/generators/rtdx/index.ts +++ b/src/lib/generators/rtdx/index.ts @@ -1,3 +1,3 @@ export { read } from './read'; export { generateRescue, generateRevival } from './generate'; -export { Data } from './data'; +export { default as data } from './data'; diff --git a/src/lib/generators/rtdx/read.ts b/src/lib/generators/rtdx/read.ts index 3a47aaf..647ffa9 100755 --- a/src/lib/generators/rtdx/read.ts +++ b/src/lib/generators/rtdx/read.ts @@ -1,6 +1,6 @@ import { BitstreamReader } from '../bitstream'; import { checksum, crc32, RNG, symbols } from './utils'; -import { Data } from './data'; +import Data from './data'; /** * Splits code string into array diff --git a/src/lib/generators/rtdx/utils.ts b/src/lib/generators/rtdx/utils.ts index 6c409ac..245c0df 100755 --- a/src/lib/generators/rtdx/utils.ts +++ b/src/lib/generators/rtdx/utils.ts @@ -18,7 +18,7 @@ export const symbols = [ ]; export function checksum(code: number[]) { - let sum = code[0] + let sum = code[0]; for (let x = 1; x < Math.floor((code.length - 1) / 2) * 2; x += 2) { sum += code[x] | (code[x + 1] << 8); } @@ -26,12 +26,12 @@ export function checksum(code: number[]) { sum += code[code.length - 1]; } - sum = ((sum >> 16) & 0xFFFF) + (sum & 0xFFFF); + sum = ((sum >> 16) & 0xffff) + (sum & 0xffff); sum += sum >> 16; - sum = ((sum >> 8) & 0xFF) + (sum & 0xFF); + sum = ((sum >> 8) & 0xff) + (sum & 0xff); sum += sum >> 8; - sum &= 0xFF; - sum ^= 0xFF; + sum &= 0xff; + sum ^= 0xff; return sum; } diff --git a/src/routes/(rt)/rt-wondermail/+page.svelte b/src/routes/(rt)/rt-wondermail/+page.svelte new file mode 100644 index 0000000..10b9864 --- /dev/null +++ b/src/routes/(rt)/rt-wondermail/+page.svelte @@ -0,0 +1,182 @@ + + +