mirror of
https://github.com/smogon/sprites.git
synced 2026-09-11 11:35:35 -05:00
Fall back to the nearest forme with an icon
xyicons/ is built from src/minisprites/pokemon/gen6 alone, which holds no totem, no Mimikyu-Busted and no Gourgeist or Pumpkaboo size forme. Nor does anywhere else in the tree: home/ has the size formes as 70x112 HOME renders against gen6's 20x26 XY icons, and no directory anywhere has a totem icon at all. There is nothing upstream to take either, since PS ships icons as one dexnum-indexed sheet rather than as files per name. That is because the games drew those formes no icon of their own. PS's client sends each to the nearest forme that has art, and ps-pokemon.sheet.mjs already carries the list, commented out, under "alt forms with duplicate icons". Walk the same chain rather than leave 22 names 404ing. The chain cannot be read off a published name, since a base name carries dashes too (kommo-o, mr-mime, porygon-z), and dropping one word blindly strands Toxtricity-Low-Key on a Toxtricity-Low that does not exist. So tools/spritedata/formes.ts writes data/lib/formes.ts, pointing each forme at the longest run of its leading words that names a forme of its own, and at the base species otherwise. xyicons/ gains 22: the 12 totems, Mimikyu-Busted, the six Gourgeist and Pumpkaboo sizes, Greninja-Bond, Rockruff-Dusk and Pichu-Spiky-Eared. Each is byte for byte the sprite it fell back to. Togedemaru-Totem is among them and the server has never had it, so that one is a gain rather than a restoration. Only this set walks the chain; xy/ has real art for all 22. The species PS keeps but nobody ever drew, missingno and the 15 pokestar entries, have no ancestor with an icon and so still get nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
418
data/lib/formes.ts
Normal file
418
data/lib/formes.ts
Normal file
@@ -0,0 +1,418 @@
|
||||
// Generated by tools/spritedata/formes.ts; do not edit.
|
||||
// Each forme's published name -> the name it falls back on for art.
|
||||
|
||||
export const FORME_PARENTS: Record<string, string> = {
|
||||
'venusaur-mega': 'venusaur',
|
||||
'charizard-mega-x': 'charizard',
|
||||
'charizard-mega-y': 'charizard',
|
||||
'blastoise-mega': 'blastoise',
|
||||
'beedrill-mega': 'beedrill',
|
||||
'pidgeot-mega': 'pidgeot',
|
||||
'rattata-alola': 'rattata',
|
||||
'raticate-alola': 'raticate',
|
||||
'raticate-alola-totem': 'raticate-alola',
|
||||
'pikachu-original': 'pikachu',
|
||||
'pikachu-hoenn': 'pikachu',
|
||||
'pikachu-sinnoh': 'pikachu',
|
||||
'pikachu-unova': 'pikachu',
|
||||
'pikachu-kalos': 'pikachu',
|
||||
'pikachu-alola': 'pikachu',
|
||||
'pikachu-partner': 'pikachu',
|
||||
'pikachu-starter': 'pikachu',
|
||||
'pikachu-world': 'pikachu',
|
||||
'pikachu-rock-star': 'pikachu',
|
||||
'pikachu-belle': 'pikachu',
|
||||
'pikachu-pop-star': 'pikachu',
|
||||
'pikachu-phd': 'pikachu',
|
||||
'pikachu-libre': 'pikachu',
|
||||
'pikachu-cosplay': 'pikachu',
|
||||
'raichu-alola': 'raichu',
|
||||
'raichu-mega-x': 'raichu',
|
||||
'raichu-mega-y': 'raichu',
|
||||
'sandshrew-alola': 'sandshrew',
|
||||
'sandslash-alola': 'sandslash',
|
||||
'clefable-mega': 'clefable',
|
||||
'vulpix-alola': 'vulpix',
|
||||
'ninetales-alola': 'ninetales',
|
||||
'diglett-alola': 'diglett',
|
||||
'dugtrio-alola': 'dugtrio',
|
||||
'meowth-alola': 'meowth',
|
||||
'meowth-galar': 'meowth',
|
||||
'persian-alola': 'persian',
|
||||
'growlithe-hisui': 'growlithe',
|
||||
'arcanine-hisui': 'arcanine',
|
||||
'alakazam-mega': 'alakazam',
|
||||
'victreebel-mega': 'victreebel',
|
||||
'geodude-alola': 'geodude',
|
||||
'graveler-alola': 'graveler',
|
||||
'golem-alola': 'golem',
|
||||
'ponyta-galar': 'ponyta',
|
||||
'rapidash-galar': 'rapidash',
|
||||
'slowpoke-galar': 'slowpoke',
|
||||
'slowbro-mega': 'slowbro',
|
||||
'slowbro-galar': 'slowbro',
|
||||
'farfetchd-galar': 'farfetchd',
|
||||
'grimer-alola': 'grimer',
|
||||
'muk-alola': 'muk',
|
||||
'gengar-mega': 'gengar',
|
||||
'voltorb-hisui': 'voltorb',
|
||||
'electrode-hisui': 'electrode',
|
||||
'exeggutor-alola': 'exeggutor',
|
||||
'marowak-alola': 'marowak',
|
||||
'marowak-alola-totem': 'marowak-alola',
|
||||
'weezing-galar': 'weezing',
|
||||
'kangaskhan-mega': 'kangaskhan',
|
||||
'starmie-mega': 'starmie',
|
||||
'mr-mime-galar': 'mr-mime',
|
||||
'pinsir-mega': 'pinsir',
|
||||
'tauros-paldea-combat': 'tauros',
|
||||
'tauros-paldea-blaze': 'tauros',
|
||||
'tauros-paldea-aqua': 'tauros',
|
||||
'gyarados-mega': 'gyarados',
|
||||
'eevee-starter': 'eevee',
|
||||
'aerodactyl-mega': 'aerodactyl',
|
||||
'articuno-galar': 'articuno',
|
||||
'zapdos-galar': 'zapdos',
|
||||
'moltres-galar': 'moltres',
|
||||
'dragonite-mega': 'dragonite',
|
||||
'mewtwo-mega-x': 'mewtwo',
|
||||
'mewtwo-mega-y': 'mewtwo',
|
||||
'meganium-mega': 'meganium',
|
||||
'typhlosion-hisui': 'typhlosion',
|
||||
'feraligatr-mega': 'feraligatr',
|
||||
'pichu-spiky-eared': 'pichu',
|
||||
'ampharos-mega': 'ampharos',
|
||||
'wooper-paldea': 'wooper',
|
||||
'slowking-galar': 'slowking',
|
||||
'unown-b': 'unown',
|
||||
'unown-c': 'unown',
|
||||
'unown-d': 'unown',
|
||||
'unown-e': 'unown',
|
||||
'unown-f': 'unown',
|
||||
'unown-g': 'unown',
|
||||
'unown-h': 'unown',
|
||||
'unown-i': 'unown',
|
||||
'unown-j': 'unown',
|
||||
'unown-k': 'unown',
|
||||
'unown-l': 'unown',
|
||||
'unown-m': 'unown',
|
||||
'unown-n': 'unown',
|
||||
'unown-o': 'unown',
|
||||
'unown-p': 'unown',
|
||||
'unown-q': 'unown',
|
||||
'unown-r': 'unown',
|
||||
'unown-s': 'unown',
|
||||
'unown-t': 'unown',
|
||||
'unown-u': 'unown',
|
||||
'unown-v': 'unown',
|
||||
'unown-w': 'unown',
|
||||
'unown-x': 'unown',
|
||||
'unown-y': 'unown',
|
||||
'unown-z': 'unown',
|
||||
'unown-exclamation': 'unown',
|
||||
'unown-question': 'unown',
|
||||
'steelix-mega': 'steelix',
|
||||
'qwilfish-hisui': 'qwilfish',
|
||||
'scizor-mega': 'scizor',
|
||||
'heracross-mega': 'heracross',
|
||||
'sneasel-hisui': 'sneasel',
|
||||
'corsola-galar': 'corsola',
|
||||
'skarmory-mega': 'skarmory',
|
||||
'houndoom-mega': 'houndoom',
|
||||
'tyranitar-mega': 'tyranitar',
|
||||
'sceptile-mega': 'sceptile',
|
||||
'blaziken-mega': 'blaziken',
|
||||
'swampert-mega': 'swampert',
|
||||
'zigzagoon-galar': 'zigzagoon',
|
||||
'linoone-galar': 'linoone',
|
||||
'gardevoir-mega': 'gardevoir',
|
||||
'sableye-mega': 'sableye',
|
||||
'mawile-mega': 'mawile',
|
||||
'aggron-mega': 'aggron',
|
||||
'medicham-mega': 'medicham',
|
||||
'manectric-mega': 'manectric',
|
||||
'sharpedo-mega': 'sharpedo',
|
||||
'camerupt-mega': 'camerupt',
|
||||
'altaria-mega': 'altaria',
|
||||
'castform-sunny': 'castform',
|
||||
'castform-rainy': 'castform',
|
||||
'castform-snowy': 'castform',
|
||||
'banette-mega': 'banette',
|
||||
'chimecho-mega': 'chimecho',
|
||||
'absol-mega': 'absol',
|
||||
'absol-mega-z': 'absol-mega',
|
||||
'glalie-mega': 'glalie',
|
||||
'salamence-mega': 'salamence',
|
||||
'metagross-mega': 'metagross',
|
||||
'latias-mega': 'latias',
|
||||
'latios-mega': 'latios',
|
||||
'kyogre-primal': 'kyogre',
|
||||
'groudon-primal': 'groudon',
|
||||
'rayquaza-mega': 'rayquaza',
|
||||
'deoxys-attack': 'deoxys',
|
||||
'deoxys-defense': 'deoxys',
|
||||
'deoxys-speed': 'deoxys',
|
||||
'staraptor-mega': 'staraptor',
|
||||
'burmy-sandy': 'burmy',
|
||||
'burmy-trash': 'burmy',
|
||||
'wormadam-sandy': 'wormadam',
|
||||
'wormadam-trash': 'wormadam',
|
||||
'cherrim-sunshine': 'cherrim',
|
||||
'shellos-east': 'shellos',
|
||||
'gastrodon-east': 'gastrodon',
|
||||
'lopunny-mega': 'lopunny',
|
||||
'garchomp-mega': 'garchomp',
|
||||
'garchomp-mega-z': 'garchomp-mega',
|
||||
'lucario-mega': 'lucario',
|
||||
'lucario-mega-z': 'lucario-mega',
|
||||
'abomasnow-mega': 'abomasnow',
|
||||
'gallade-mega': 'gallade',
|
||||
'froslass-mega': 'froslass',
|
||||
'rotom-heat': 'rotom',
|
||||
'rotom-wash': 'rotom',
|
||||
'rotom-frost': 'rotom',
|
||||
'rotom-fan': 'rotom',
|
||||
'rotom-mow': 'rotom',
|
||||
'dialga-origin': 'dialga',
|
||||
'palkia-origin': 'palkia',
|
||||
'heatran-mega': 'heatran',
|
||||
'giratina-origin': 'giratina',
|
||||
'darkrai-mega': 'darkrai',
|
||||
'shaymin-sky': 'shaymin',
|
||||
'arceus-fighting': 'arceus',
|
||||
'arceus-flying': 'arceus',
|
||||
'arceus-poison': 'arceus',
|
||||
'arceus-ground': 'arceus',
|
||||
'arceus-rock': 'arceus',
|
||||
'arceus-bug': 'arceus',
|
||||
'arceus-ghost': 'arceus',
|
||||
'arceus-steel': 'arceus',
|
||||
'arceus-fire': 'arceus',
|
||||
'arceus-water': 'arceus',
|
||||
'arceus-grass': 'arceus',
|
||||
'arceus-electric': 'arceus',
|
||||
'arceus-psychic': 'arceus',
|
||||
'arceus-ice': 'arceus',
|
||||
'arceus-dragon': 'arceus',
|
||||
'arceus-dark': 'arceus',
|
||||
'arceus-fairy': 'arceus',
|
||||
'emboar-mega': 'emboar',
|
||||
'samurott-hisui': 'samurott',
|
||||
'excadrill-mega': 'excadrill',
|
||||
'audino-mega': 'audino',
|
||||
'scolipede-mega': 'scolipede',
|
||||
'lilligant-hisui': 'lilligant',
|
||||
'basculin-blue-striped': 'basculin',
|
||||
'basculin-white-striped': 'basculin',
|
||||
'darumaka-galar': 'darumaka',
|
||||
'darmanitan-zen': 'darmanitan',
|
||||
'darmanitan-galar': 'darmanitan',
|
||||
'darmanitan-galar-zen': 'darmanitan-galar',
|
||||
'scrafty-mega': 'scrafty',
|
||||
'yamask-galar': 'yamask',
|
||||
'zorua-hisui': 'zorua',
|
||||
'zoroark-hisui': 'zoroark',
|
||||
'deerling-summer': 'deerling',
|
||||
'deerling-autumn': 'deerling',
|
||||
'deerling-winter': 'deerling',
|
||||
'sawsbuck-summer': 'sawsbuck',
|
||||
'sawsbuck-autumn': 'sawsbuck',
|
||||
'sawsbuck-winter': 'sawsbuck',
|
||||
'eelektross-mega': 'eelektross',
|
||||
'chandelure-mega': 'chandelure',
|
||||
'stunfisk-galar': 'stunfisk',
|
||||
'golurk-mega': 'golurk',
|
||||
'braviary-hisui': 'braviary',
|
||||
'tornadus-therian': 'tornadus',
|
||||
'thundurus-therian': 'thundurus',
|
||||
'landorus-therian': 'landorus',
|
||||
'kyurem-white': 'kyurem',
|
||||
'kyurem-black': 'kyurem',
|
||||
'keldeo-resolute': 'keldeo',
|
||||
'meloetta-pirouette': 'meloetta',
|
||||
'genesect-douse': 'genesect',
|
||||
'genesect-shock': 'genesect',
|
||||
'genesect-burn': 'genesect',
|
||||
'genesect-chill': 'genesect',
|
||||
'chesnaught-mega': 'chesnaught',
|
||||
'delphox-mega': 'delphox',
|
||||
'greninja-bond': 'greninja',
|
||||
'greninja-ash': 'greninja',
|
||||
'greninja-mega': 'greninja',
|
||||
'vivillon-icy-snow': 'vivillon',
|
||||
'vivillon-polar': 'vivillon',
|
||||
'vivillon-tundra': 'vivillon',
|
||||
'vivillon-continental': 'vivillon',
|
||||
'vivillon-garden': 'vivillon',
|
||||
'vivillon-elegant': 'vivillon',
|
||||
'vivillon-modern': 'vivillon',
|
||||
'vivillon-marine': 'vivillon',
|
||||
'vivillon-archipelago': 'vivillon',
|
||||
'vivillon-high-plains': 'vivillon',
|
||||
'vivillon-sandstorm': 'vivillon',
|
||||
'vivillon-river': 'vivillon',
|
||||
'vivillon-monsoon': 'vivillon',
|
||||
'vivillon-savanna': 'vivillon',
|
||||
'vivillon-sun': 'vivillon',
|
||||
'vivillon-ocean': 'vivillon',
|
||||
'vivillon-jungle': 'vivillon',
|
||||
'vivillon-fancy': 'vivillon',
|
||||
'vivillon-pokeball': 'vivillon',
|
||||
'pyroar-mega': 'pyroar',
|
||||
'flabebe-yellow': 'flabebe',
|
||||
'flabebe-orange': 'flabebe',
|
||||
'flabebe-blue': 'flabebe',
|
||||
'flabebe-white': 'flabebe',
|
||||
'floette-yellow': 'floette',
|
||||
'floette-orange': 'floette',
|
||||
'floette-blue': 'floette',
|
||||
'floette-white': 'floette',
|
||||
'floette-eternal': 'floette',
|
||||
'floette-mega': 'floette',
|
||||
'florges-yellow': 'florges',
|
||||
'florges-orange': 'florges',
|
||||
'florges-blue': 'florges',
|
||||
'florges-white': 'florges',
|
||||
'furfrou-heart': 'furfrou',
|
||||
'furfrou-star': 'furfrou',
|
||||
'furfrou-diamond': 'furfrou',
|
||||
'furfrou-debutante': 'furfrou',
|
||||
'furfrou-matron': 'furfrou',
|
||||
'furfrou-dandy': 'furfrou',
|
||||
'furfrou-la-reine': 'furfrou',
|
||||
'furfrou-kabuki': 'furfrou',
|
||||
'furfrou-pharaoh': 'furfrou',
|
||||
'meowstic-f': 'meowstic',
|
||||
'meowstic-m-mega': 'meowstic',
|
||||
'meowstic-f-mega': 'meowstic-f',
|
||||
'aegislash-blade': 'aegislash',
|
||||
'malamar-mega': 'malamar',
|
||||
'barbaracle-mega': 'barbaracle',
|
||||
'dragalge-mega': 'dragalge',
|
||||
'hawlucha-mega': 'hawlucha',
|
||||
'sliggoo-hisui': 'sliggoo',
|
||||
'goodra-hisui': 'goodra',
|
||||
'pumpkaboo-small': 'pumpkaboo',
|
||||
'pumpkaboo-large': 'pumpkaboo',
|
||||
'pumpkaboo-super': 'pumpkaboo',
|
||||
'gourgeist-small': 'gourgeist',
|
||||
'gourgeist-large': 'gourgeist',
|
||||
'gourgeist-super': 'gourgeist',
|
||||
'avalugg-hisui': 'avalugg',
|
||||
'xerneas-neutral': 'xerneas',
|
||||
'zygarde-10': 'zygarde',
|
||||
'zygarde-complete': 'zygarde',
|
||||
'zygarde-mega': 'zygarde',
|
||||
'diancie-mega': 'diancie',
|
||||
'hoopa-unbound': 'hoopa',
|
||||
'decidueye-hisui': 'decidueye',
|
||||
'gumshoos-totem': 'gumshoos',
|
||||
'vikavolt-totem': 'vikavolt',
|
||||
'crabominable-mega': 'crabominable',
|
||||
'oricorio-pom-pom': 'oricorio',
|
||||
'oricorio-pau': 'oricorio',
|
||||
'oricorio-sensu': 'oricorio',
|
||||
'ribombee-totem': 'ribombee',
|
||||
'rockruff-dusk': 'rockruff',
|
||||
'lycanroc-midnight': 'lycanroc',
|
||||
'lycanroc-dusk': 'lycanroc',
|
||||
'wishiwashi-school': 'wishiwashi',
|
||||
'araquanid-totem': 'araquanid',
|
||||
'lurantis-totem': 'lurantis',
|
||||
'salazzle-totem': 'salazzle',
|
||||
'golisopod-mega': 'golisopod',
|
||||
'silvally-fighting': 'silvally',
|
||||
'silvally-flying': 'silvally',
|
||||
'silvally-poison': 'silvally',
|
||||
'silvally-ground': 'silvally',
|
||||
'silvally-rock': 'silvally',
|
||||
'silvally-bug': 'silvally',
|
||||
'silvally-ghost': 'silvally',
|
||||
'silvally-steel': 'silvally',
|
||||
'silvally-fire': 'silvally',
|
||||
'silvally-water': 'silvally',
|
||||
'silvally-grass': 'silvally',
|
||||
'silvally-electric': 'silvally',
|
||||
'silvally-psychic': 'silvally',
|
||||
'silvally-ice': 'silvally',
|
||||
'silvally-dragon': 'silvally',
|
||||
'silvally-dark': 'silvally',
|
||||
'silvally-fairy': 'silvally',
|
||||
'minior-meteor': 'minior',
|
||||
'minior-orange': 'minior',
|
||||
'minior-yellow': 'minior',
|
||||
'minior-green': 'minior',
|
||||
'minior-blue': 'minior',
|
||||
'minior-indigo': 'minior',
|
||||
'minior-violet': 'minior',
|
||||
'togedemaru-totem': 'togedemaru',
|
||||
'mimikyu-busted': 'mimikyu',
|
||||
'mimikyu-totem': 'mimikyu',
|
||||
'mimikyu-busted-totem': 'mimikyu-busted',
|
||||
'drampa-mega': 'drampa',
|
||||
'kommo-o-totem': 'kommo-o',
|
||||
'necrozma-dusk-mane': 'necrozma',
|
||||
'necrozma-dawn-wings': 'necrozma',
|
||||
'necrozma-ultra': 'necrozma',
|
||||
'magearna-original': 'magearna',
|
||||
'magearna-mega': 'magearna',
|
||||
'magearna-original-mega': 'magearna-original',
|
||||
'zeraora-mega': 'zeraora',
|
||||
'cramorant-gulping': 'cramorant',
|
||||
'cramorant-gorging': 'cramorant',
|
||||
'toxtricity-low-key': 'toxtricity',
|
||||
'sinistea-antique': 'sinistea',
|
||||
'polteageist-antique': 'polteageist',
|
||||
'alcremie-ruby-cream': 'alcremie',
|
||||
'alcremie-matcha-cream': 'alcremie',
|
||||
'alcremie-mint-cream': 'alcremie',
|
||||
'alcremie-lemon-cream': 'alcremie',
|
||||
'alcremie-salted-cream': 'alcremie',
|
||||
'alcremie-ruby-swirl': 'alcremie',
|
||||
'alcremie-caramel-swirl': 'alcremie',
|
||||
'alcremie-rainbow-swirl': 'alcremie',
|
||||
'falinks-mega': 'falinks',
|
||||
'eiscue-noice': 'eiscue',
|
||||
'indeedee-f': 'indeedee',
|
||||
'morpeko-hangry': 'morpeko',
|
||||
'zacian-crowned': 'zacian',
|
||||
'zamazenta-crowned': 'zamazenta',
|
||||
'eternatus-eternamax': 'eternatus',
|
||||
'urshifu-rapid-strike': 'urshifu',
|
||||
'zarude-dada': 'zarude',
|
||||
'calyrex-ice': 'calyrex',
|
||||
'calyrex-shadow': 'calyrex',
|
||||
'ursaluna-bloodmoon': 'ursaluna',
|
||||
'basculegion-f': 'basculegion',
|
||||
'enamorus-therian': 'enamorus',
|
||||
'oinkologne-f': 'oinkologne',
|
||||
'maushold-four': 'maushold',
|
||||
'squawkabilly-blue': 'squawkabilly',
|
||||
'squawkabilly-yellow': 'squawkabilly',
|
||||
'squawkabilly-white': 'squawkabilly',
|
||||
'scovillain-mega': 'scovillain',
|
||||
'palafin-hero': 'palafin',
|
||||
'glimmora-mega': 'glimmora',
|
||||
'tatsugiri-droopy': 'tatsugiri',
|
||||
'tatsugiri-stretchy': 'tatsugiri',
|
||||
'tatsugiri-curly-mega': 'tatsugiri',
|
||||
'tatsugiri-droopy-mega': 'tatsugiri-droopy',
|
||||
'tatsugiri-stretchy-mega': 'tatsugiri-stretchy',
|
||||
'dudunsparce-three-segment': 'dudunsparce',
|
||||
'baxcalibur-mega': 'baxcalibur',
|
||||
'gimmighoul-roaming': 'gimmighoul',
|
||||
'poltchageist-artisan': 'poltchageist',
|
||||
'sinistcha-masterpiece': 'sinistcha',
|
||||
'ogerpon-wellspring': 'ogerpon',
|
||||
'ogerpon-hearthflame': 'ogerpon',
|
||||
'ogerpon-cornerstone': 'ogerpon',
|
||||
'ogerpon-teal-tera': 'ogerpon',
|
||||
'ogerpon-wellspring-tera': 'ogerpon-wellspring',
|
||||
'ogerpon-hearthflame-tera': 'ogerpon-hearthflame',
|
||||
'ogerpon-cornerstone-tera': 'ogerpon-cornerstone',
|
||||
'terapagos-terastal': 'terapagos',
|
||||
'terapagos-stellar': 'terapagos',
|
||||
'crucibelle-mega': 'crucibelle',
|
||||
'venomicon-epilogue': 'venomicon',
|
||||
'ramnarok-radiant': 'ramnarok',
|
||||
};
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
import {FORME_PARENTS} from '@smogon/sprite-data/formes.ts';
|
||||
|
||||
import {gen10Modelslike} from './rules/modelslike.ts';
|
||||
import {type Sprite, publishedNames} from './rules/publish.ts';
|
||||
import {forEachRule} from './tools/build/artifact.ts';
|
||||
@@ -75,8 +77,31 @@ let xyIcons = forEachRule('src/minisprites/pokemon/gen6/*.png', {
|
||||
}, '%b');
|
||||
|
||||
deploy(ctx => {
|
||||
let byName = new Map<string, Sprite>();
|
||||
for (let f of xyIcons) {
|
||||
smogonSpritecopy(ctx, f, 'xyicons', publishedNames(f));
|
||||
for (let name of publishedNames(f)) {
|
||||
byName.set(name, f);
|
||||
}
|
||||
}
|
||||
// The games drew no icon for some formes, so PS's own sheet sends them to
|
||||
// the nearest one that has art: Gourgeist-Super to Gourgeist,
|
||||
// Mimikyu-Busted-Totem to Mimikyu-Busted and on to Mimikyu. Walk the same
|
||||
// chain, so a name the data knows gets an icon rather than a 404. Only
|
||||
// this set needs it, since xy/ has real art for every one of them.
|
||||
for (let name of Object.keys(FORME_PARENTS)) {
|
||||
if (byName.has(name)) {
|
||||
continue;
|
||||
}
|
||||
for (let p = FORME_PARENTS[name]; p !== undefined; p = FORME_PARENTS[p]) {
|
||||
let f = byName.get(p);
|
||||
if (f) {
|
||||
byName.set(name, f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let [name, f] of byName) {
|
||||
smogonSpritecopy(ctx, f, 'xyicons', [name]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
79
tools/spritedata/formes.ts
Normal file
79
tools/spritedata/formes.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import {encode, publishedName, smogon} from '@smogon/sprite-data/index.ts';
|
||||
|
||||
import {species} from './pokedex.ts';
|
||||
|
||||
// Regenerates data/lib/formes.ts from a pokemon-showdown checkout:
|
||||
//
|
||||
// node tools/spritedata/formes.ts ~/smogon/pokemon-showdown > data/lib/formes.ts
|
||||
//
|
||||
// The games drew some formes no art of their own, and a set that has none
|
||||
// falls back on the nearest forme it is a refinement of, up to the base
|
||||
// species: PS's own icon sheet points Gourgeist-Super at Gourgeist's slot and
|
||||
// Mimikyu-Busted-Totem at Mimikyu's. That chain can't be recovered from a
|
||||
// published name alone, since a base name carries dashes too (kommo-o,
|
||||
// mr-mime, porygon-z), so it is written down here.
|
||||
//
|
||||
// The parent is the longest run of leading words that names a forme of its
|
||||
// own, and the base species otherwise. Dropping one word blindly would strand
|
||||
// Toxtricity-Low-Key on a Toxtricity-Low that does not exist.
|
||||
|
||||
let ps = process.argv[2];
|
||||
if (!ps) {
|
||||
throw new Error('usage: node tools/spritedata/formes.ts <pokemon-showdown checkout>');
|
||||
}
|
||||
|
||||
// `forme` comes in encoded; `base` does not.
|
||||
function published(base: string, forme: string): string {
|
||||
let extra = new Map<string, string>();
|
||||
if (forme) {
|
||||
extra.set('o', forme);
|
||||
}
|
||||
return publishedName({kind: 's', name: encode(base), extra}, smogon);
|
||||
}
|
||||
|
||||
let all = species(ps);
|
||||
|
||||
// Which formes each base species actually has, so a parent can be checked.
|
||||
let formes = new Map<string, Set<string>>();
|
||||
for (let {base, forme} of all) {
|
||||
let set = formes.get(base);
|
||||
if (!set) {
|
||||
set = new Set();
|
||||
formes.set(base, set);
|
||||
}
|
||||
set.add(encode(forme));
|
||||
}
|
||||
|
||||
function parent(base: string, forme: string): string {
|
||||
let words = forme.split('_');
|
||||
for (let n = words.length - 1; n > 0; n--) {
|
||||
let shorter = words.slice(0, n).join('_');
|
||||
if (formes.get(base)?.has(shorter)) {
|
||||
return shorter;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
let out = '';
|
||||
out += '// Generated by tools/spritedata/formes.ts; do not edit.\n';
|
||||
out += "// Each forme's published name -> the name it falls back on for art.\n\n";
|
||||
out += 'export const FORME_PARENTS: Record<string, string> = {\n';
|
||||
|
||||
let seen = new Set<string>();
|
||||
for (let {base, forme} of all) {
|
||||
if (!forme) {
|
||||
continue;
|
||||
}
|
||||
let name = published(base, encode(forme));
|
||||
// Where formeOrder gives one name to several slots, they share a parent.
|
||||
if (seen.has(name)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(name);
|
||||
out += ` '${name}': '${published(base, parent(base, encode(forme)))}',\n`;
|
||||
}
|
||||
|
||||
out += '};\n';
|
||||
|
||||
process.stdout.write(out);
|
||||
Reference in New Issue
Block a user