mirror of
https://github.com/smogon/sprites.git
synced 2026-09-11 03:26:00 -05:00
Delete the PS build and the pokemon-showdown tooling
deploy.json5 has two targets, assets and smogon. ps.build.ts has none: nothing
it produces has shipped from this repo, and the ani/ rsync it was written for
lives in the README as an example. Everything it pulled along came with it.
tools/sheet is its montage tool and had no other caller.
ps-pokemon.dexnums.mjs, 1125 generated lines, existed only to hand its sheet a
dex number after data/species.json went away. tools/spritedata/{dexnums,names,
pokedex,rename}.ts all read a pokemon-showdown checkout, which is a dependency
nothing in either surviving deploy has.
The branch ps-build points at the commit before this, so it is one checkout
away if the PS side ever comes back.
tools/deploy/coverage.ts is the exception and moves rather than goes. It reads
no PS data and generates no table; it reports what a deploy would delete off
the server, which is what makes --delete-after safe to run, and it only lived
in tools/spritedata because that is where I put it.
Both remaining deploys materialize unchanged: xy/ 1651 names, xyicons/ 1556,
assets byte for byte. psid() keeps its caller in the smogdex sheet, which still
needs PS's spelling of a name even with the PS deploy gone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -65,7 +65,7 @@ reuses the build's digests. All state lives in `.build/`.
|
||||
$ pnpm build # build every deploy's rules, GC stale state
|
||||
$ pnpm deploy # list the deploys in deploy.json5
|
||||
$ pnpm deploy assets # run a named deploy
|
||||
$ node tools/deploy/index.ts build ps.build.ts # build one deploy's rules
|
||||
$ node tools/deploy/index.ts build smogon.build.ts # build one deploy's rules
|
||||
$ node tools/deploy/index.ts run smogon.build.ts -o deploy/smogon
|
||||
$ node tools/deploy/index.ts inspect src/minisprites/items/ileftovers.png -o /tmp/out
|
||||
```
|
||||
@@ -99,10 +99,10 @@ for eyeballing what would ship.
|
||||
{subset: ["**"], cmd: "smogonctl assets upload sprites"},
|
||||
],
|
||||
},
|
||||
ps: {
|
||||
buildFile: "ps.build.ts",
|
||||
smogon: {
|
||||
buildFile: "smogon.build.ts",
|
||||
deploy: [
|
||||
{subset: ["ani/**"], dir: true, cmd: "rsync -a %d/ani/ ps:sprites/ani/"},
|
||||
{subset: ["xy/**"], dir: true, cmd: "rsync -a --delete-after %d/xy/ smogon:/smog2/sprites/xy"},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -58,12 +58,6 @@ importers:
|
||||
specifier: ^3.0.0
|
||||
version: 3.2.0
|
||||
|
||||
tools/sheet:
|
||||
dependencies:
|
||||
'@types/node':
|
||||
specifier: ^24.10.7
|
||||
version: 24.13.3
|
||||
|
||||
tools/smogdexspritesheet:
|
||||
dependencies:
|
||||
'@smogon/sprite-data':
|
||||
@@ -79,18 +73,6 @@ importers:
|
||||
specifier: ^3.4.1
|
||||
version: 3.5.1
|
||||
|
||||
tools/spritedata:
|
||||
dependencies:
|
||||
'@smogon/sprite-data':
|
||||
specifier: workspace:*
|
||||
version: link:../../data/lib
|
||||
'@smogon/sprite-root':
|
||||
specifier: workspace:*
|
||||
version: link:../../lib/root
|
||||
'@types/node':
|
||||
specifier: ^24.10.7
|
||||
version: 24.13.3
|
||||
|
||||
tools/trim:
|
||||
dependencies:
|
||||
'@types/node':
|
||||
|
||||
@@ -1,580 +0,0 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import * as spritedata from '@smogon/sprite-data/index.ts';
|
||||
import root from '@smogon/sprite-root/index.ts';
|
||||
|
||||
const itemsDir = path.join(root, "src/minisprites/items");
|
||||
|
||||
// Derived from pokemon-showdown/data/items.ts
|
||||
const ITEMS = {
|
||||
"absorbbulb": 2,
|
||||
"adamantorb": 4,
|
||||
"aguavberry": 5,
|
||||
"airballoon": 6,
|
||||
"apicotberry": 10,
|
||||
"armorfossil": 12,
|
||||
"aspearberry": 13,
|
||||
//"burntberry": 13,
|
||||
"babiriberry": 17,
|
||||
"belueberry": 21,
|
||||
"berryjuice": 22,
|
||||
"bignugget": 27,
|
||||
"bigroot": 29,
|
||||
"bindingband": 31,
|
||||
"blackbelt": 32,
|
||||
"blacksludge": 34,
|
||||
"blackglasses": 35,
|
||||
"blueorb": 41,
|
||||
"blukberry": 44,
|
||||
"brightpowder": 51,
|
||||
"buggem": 53,
|
||||
"burndrive": 54,
|
||||
"cellbattery": 60,
|
||||
"charcoal": 61,
|
||||
"chartiberry": 62,
|
||||
"cheriberry": 63,
|
||||
//"przcureberry": 63,
|
||||
"cherishball": 64,
|
||||
"chestoberry": 65,
|
||||
//"mintberry": 65,
|
||||
"chilanberry": 66,
|
||||
"chilldrive": 67,
|
||||
"choiceband": 68,
|
||||
"choicescarf": 69,
|
||||
"choicespecs": 70,
|
||||
"chopleberry": 71,
|
||||
"clawfossil": 72,
|
||||
"cobaberry": 76,
|
||||
"colburberry": 78,
|
||||
"cornnberry": 81,
|
||||
"coverfossil": 85,
|
||||
"custapberry": 86,
|
||||
"damprock": 88,
|
||||
"darkgem": 89,
|
||||
"dawnstone": 92,
|
||||
"deepseascale": 93,
|
||||
"deepseatooth": 94,
|
||||
"destinyknot": 95,
|
||||
"diveball": 101,
|
||||
"domefossil": 102,
|
||||
"dousedrive": 103,
|
||||
"dracoplate": 105,
|
||||
"dragonfang": 106,
|
||||
"dragongem": 107,
|
||||
"dragonscale": 108,
|
||||
"dreadplate": 110,
|
||||
"dreamball": 111,
|
||||
"dubiousdisc": 113,
|
||||
"durinberry": 114,
|
||||
"duskball": 115,
|
||||
"duskstone": 116,
|
||||
"earthplate": 117,
|
||||
"ejectbutton": 118,
|
||||
"electirizer": 119,
|
||||
"electricgem": 120,
|
||||
"enigmaberry": 124,
|
||||
"eviolite": 130,
|
||||
"expertbelt": 132,
|
||||
"fastball": 137,
|
||||
"fightinggem": 139,
|
||||
"figyberry": 140,
|
||||
"firegem": 141,
|
||||
"firestone": 142,
|
||||
"fistplate": 143,
|
||||
"flameorb": 145,
|
||||
"flameplate": 146,
|
||||
"floatstone": 147,
|
||||
"flyinggem": 149,
|
||||
"focusband": 150,
|
||||
"focussash": 151,
|
||||
"friendball": 153,
|
||||
"fullincense": 155,
|
||||
"ganlonberry": 158,
|
||||
"ghostgem": 161,
|
||||
"grassgem": 172,
|
||||
"greatball": 174,
|
||||
"grepaberry": 178,
|
||||
"gripclaw": 179,
|
||||
"griseousorb": 180,
|
||||
"groundgem": 182,
|
||||
"habanberry": 185,
|
||||
"hardstone": 187,
|
||||
"healball": 188,
|
||||
"heatrock": 193,
|
||||
"heavyball": 194,
|
||||
"helixfossil": 195,
|
||||
"hondewberry": 213,
|
||||
"iapapaberry": 217,
|
||||
"icegem": 218,
|
||||
"icicleplate": 220,
|
||||
"icyrock": 221,
|
||||
"insectplate": 223,
|
||||
"ironball": 224,
|
||||
"ironplate": 225,
|
||||
"jabocaberry": 230,
|
||||
"kasibberry": 233,
|
||||
"kebiaberry": 234,
|
||||
"kelpsyberry": 235,
|
||||
"kingsrock": 236,
|
||||
"laggingtail": 237,
|
||||
"lansatberry": 238,
|
||||
"laxincense": 240,
|
||||
"leafstone": 241,
|
||||
"leftovers": 242,
|
||||
"leppaberry": 244,
|
||||
//"mysteryberry": 244,
|
||||
"levelball": 246,
|
||||
"liechiberry": 248,
|
||||
"lifeorb": 249,
|
||||
"lightball": 251,
|
||||
"lightclay": 252,
|
||||
"loveball": 258,
|
||||
"luckypunch": 261,
|
||||
"lumberry": 262,
|
||||
//"miracleberry": 262,
|
||||
"lureball": 264,
|
||||
"lustrousorb": 265,
|
||||
"luxuryball": 266,
|
||||
"machobrace": 269,
|
||||
"magmarizer": 272,
|
||||
"magnet": 273,
|
||||
"magoberry": 274,
|
||||
"magostberry": 275,
|
||||
"masterball": 276,
|
||||
"meadowplate": 282,
|
||||
"mentalherb": 285,
|
||||
"metalcoat": 286,
|
||||
"metalpowder": 287,
|
||||
"metronome": 289,
|
||||
"micleberry": 290,
|
||||
"mindplate": 291,
|
||||
"miracleseed": 292,
|
||||
"moonball": 294,
|
||||
"moonstone": 295,
|
||||
"muscleband": 297,
|
||||
"mysticwater": 300,
|
||||
"nanabberry": 302,
|
||||
"nestball": 303,
|
||||
"netball": 304,
|
||||
"nevermeltice": 305,
|
||||
"nomelberry": 306,
|
||||
"normalgem": 307,
|
||||
"strangeball": 308,
|
||||
"occaberry": 311,
|
||||
"oddincense": 312,
|
||||
"oldamber": 314,
|
||||
"oranberry": 319,
|
||||
//"berry": 319,
|
||||
"ovalstone": 321,
|
||||
"pamtreberry": 323,
|
||||
"parkball": 325,
|
||||
"passhoberry": 329,
|
||||
"payapaberry": 330,
|
||||
"pechaberry": 333,
|
||||
//"psncureberry": 333,
|
||||
"persimberry": 334,
|
||||
//"bitterberry": 334,
|
||||
"petayaberry": 335,
|
||||
"pinapberry": 337,
|
||||
"plumefossil": 339,
|
||||
"poisonbarb": 343,
|
||||
"poisongem": 344,
|
||||
"pokeball": 345,
|
||||
"pomegberry": 351,
|
||||
"poweranklet": 354,
|
||||
"powerband": 355,
|
||||
"powerbelt": 356,
|
||||
"powerbracer": 357,
|
||||
"powerherb": 358,
|
||||
"powerlens": 359,
|
||||
"powerweight": 360,
|
||||
"premierball": 363,
|
||||
"prismscale": 365,
|
||||
"protector": 367,
|
||||
"psychicgem": 369,
|
||||
"qualotberry": 371,
|
||||
"quickball": 372,
|
||||
"quickclaw": 373,
|
||||
"quickpowder": 374,
|
||||
"rabutaberry": 375,
|
||||
"rarebone": 379,
|
||||
"rawstberry": 381,
|
||||
//"iceberry": 381,
|
||||
"razorclaw": 382,
|
||||
"razorfang": 383,
|
||||
"razzberry": 384,
|
||||
"reapercloth": 385,
|
||||
"redcard": 387,
|
||||
"berserkgene": 388,
|
||||
"redorb": 390,
|
||||
"repeatball": 401,
|
||||
"mail": 403,
|
||||
"rindoberry": 409,
|
||||
"ringtarget": 410,
|
||||
"rockgem": 415,
|
||||
"rockincense": 416,
|
||||
"rockyhelmet": 417,
|
||||
"rootfossil": 418,
|
||||
"roseincense": 419,
|
||||
"rowapberry": 420,
|
||||
"safariball": 425,
|
||||
"salacberry": 426,
|
||||
"scopelens": 429,
|
||||
"seaincense": 430,
|
||||
"sharpbeak": 436,
|
||||
"shedshell": 437,
|
||||
"shellbell": 438,
|
||||
"shinystone": 439,
|
||||
"shockdrive": 442,
|
||||
"shucaberry": 443,
|
||||
"silkscarf": 444,
|
||||
//"pinkbow": 444,
|
||||
//"polkadotbow": 444,
|
||||
"silverpowder": 447,
|
||||
"sitrusberry": 448,
|
||||
//"goldberry": 448,
|
||||
"skullfossil": 449,
|
||||
"skyplate": 450,
|
||||
"smoothrock": 453,
|
||||
"softsand": 456,
|
||||
"souldew": 459,
|
||||
"spelltag": 461,
|
||||
"spelonberry": 462,
|
||||
"splashplate": 463,
|
||||
"spookyplate": 464,
|
||||
"sportball": 465,
|
||||
"starfberry": 472,
|
||||
"steelgem": 473,
|
||||
"leek": 475,
|
||||
//"stick": 475,
|
||||
"stickybarb": 476,
|
||||
"stoneplate": 477,
|
||||
"sunstone": 480,
|
||||
"tamatoberry": 486,
|
||||
"tangaberry": 487,
|
||||
"thickclub": 491,
|
||||
"thunderstone": 492,
|
||||
"timerball": 494,
|
||||
"toxicorb": 515,
|
||||
"toxicplate": 516,
|
||||
"twistedspoon": 520,
|
||||
"ultraball": 521,
|
||||
"upgrade": 523,
|
||||
"wacanberry": 526,
|
||||
"watergem": 528,
|
||||
"waterstone": 529,
|
||||
"watmelberry": 530,
|
||||
"waveincense": 531,
|
||||
"wepearberry": 533,
|
||||
"whiteherb": 535,
|
||||
"widelens": 537,
|
||||
"wikiberry": 538,
|
||||
"wiseglasses": 539,
|
||||
"yacheberry": 567,
|
||||
"zapplate": 572,
|
||||
"zoomlens": 574,
|
||||
"abomasite": 575,
|
||||
"absolite": 576,
|
||||
"aerodactylite": 577,
|
||||
"crucibellite": 577,
|
||||
"aggronite": 578,
|
||||
"alakazite": 579,
|
||||
"ampharosite": 580,
|
||||
"assaultvest": 581,
|
||||
"banettite": 582,
|
||||
"blastoisinite": 583,
|
||||
"blazikenite": 584,
|
||||
"charizarditex": 585,
|
||||
"charizarditey": 586,
|
||||
"gardevoirite": 587,
|
||||
"gengarite": 588,
|
||||
// FIXME garchompite & gyaradosite should not be same spritenum
|
||||
"garchompite": 589,
|
||||
"gyaradosite": 589,
|
||||
"heracronite": 590,
|
||||
"houndoominite": 591,
|
||||
"kangaskhanite": 592,
|
||||
"keeberry": 593,
|
||||
"lucarionite": 594,
|
||||
"luminousmoss": 595,
|
||||
"manectite": 596,
|
||||
"marangaberry": 597,
|
||||
"mawilite": 598,
|
||||
"medichamite": 599,
|
||||
"mewtwonitex": 600,
|
||||
"mewtwonitey": 601,
|
||||
"pinsirite": 602,
|
||||
"roseliberry": 603,
|
||||
"safetygoggles": 604,
|
||||
"scizorite": 605,
|
||||
"snowball": 606,
|
||||
"tyranitarite": 607,
|
||||
"venusaurite": 608,
|
||||
"weaknesspolicy": 609,
|
||||
"pixieplate": 610,
|
||||
"fairygem": 611,
|
||||
"swampertite": 612,
|
||||
"sceptilite": 613,
|
||||
"sablenite": 614,
|
||||
"altarianite": 615,
|
||||
"galladite": 616,
|
||||
"audinite": 617,
|
||||
"metagrossite": 618,
|
||||
"sharpedonite": 619,
|
||||
"slowbronite": 620,
|
||||
"steelixite": 621,
|
||||
"pidgeotite": 622,
|
||||
"glalitite": 623,
|
||||
"diancite": 624,
|
||||
"cameruptite": 625,
|
||||
"lopunnite": 626,
|
||||
"salamencite": 627,
|
||||
"beedrillite": 628,
|
||||
"latiasite": 629,
|
||||
"latiosite": 630,
|
||||
"normaliumz": 631,
|
||||
"firiumz": 632,
|
||||
"wateriumz": 633,
|
||||
"electriumz": 634,
|
||||
"grassiumz": 635,
|
||||
"iciumz": 636,
|
||||
"fightiniumz": 637,
|
||||
"poisoniumz": 638,
|
||||
"groundiumz": 639,
|
||||
"flyiniumz": 640,
|
||||
"psychiumz": 641,
|
||||
"buginiumz": 642,
|
||||
"rockiumz": 643,
|
||||
"ghostiumz": 644,
|
||||
"dragoniumz": 645,
|
||||
"darkiniumz": 646,
|
||||
"steeliumz": 647,
|
||||
"fairiumz": 648,
|
||||
"pikaniumz": 649,
|
||||
"decidiumz": 650,
|
||||
"inciniumz": 651,
|
||||
"primariumz": 652,
|
||||
"tapuniumz": 653,
|
||||
"marshadiumz": 654,
|
||||
"aloraichiumz": 655,
|
||||
"snorliumz": 656,
|
||||
"eeviumz": 657,
|
||||
"mewniumz": 658,
|
||||
"pikashuniumz": 659,
|
||||
"adrenalineorb": 660,
|
||||
"beastball": 661,
|
||||
"terrainextender": 662,
|
||||
"protectivepads": 663,
|
||||
"electricseed": 664,
|
||||
"psychicseed": 665,
|
||||
"mistyseed": 666,
|
||||
"grassyseed": 667,
|
||||
"fightingmemory": 668,
|
||||
"flyingmemory": 669,
|
||||
"poisonmemory": 670,
|
||||
"groundmemory": 671,
|
||||
"rockmemory": 672,
|
||||
"bugmemory": 673,
|
||||
"ghostmemory": 674,
|
||||
"steelmemory": 675,
|
||||
"firememory": 676,
|
||||
"watermemory": 677,
|
||||
"grassmemory": 678,
|
||||
"electricmemory": 679,
|
||||
"psychicmemory": 680,
|
||||
"icememory": 681,
|
||||
"dragonmemory": 682,
|
||||
"darkmemory": 683,
|
||||
"fairymemory": 684,
|
||||
"solganiumz": 685,
|
||||
"lunaliumz": 686,
|
||||
"ultranecroziumz": 687,
|
||||
"mimikiumz": 688,
|
||||
"lycaniumz": 689,
|
||||
"kommoniumz": 690,
|
||||
"sachet": 691,
|
||||
"whippeddream": 692,
|
||||
"icestone": 693,
|
||||
"jawfossil": 694,
|
||||
"sailfossil": 695,
|
||||
"bottlecap": 696,
|
||||
"goldbottlecap": 697,
|
||||
"rustedsword": 698,
|
||||
"rustedshield": 699,
|
||||
"fossilizedbird": 700,
|
||||
"fossilizedfish": 701,
|
||||
"fossilizeddrake": 702,
|
||||
"fossilizeddino": 703,
|
||||
"strawberrysweet": 704,
|
||||
"lovesweet": 705,
|
||||
"berrysweet": 706,
|
||||
"cloversweet": 707,
|
||||
"flowersweet": 708,
|
||||
"starsweet": 709,
|
||||
"ribbonsweet": 710,
|
||||
"sweetapple": 711,
|
||||
"tartapple": 712,
|
||||
"throatspray": 713,
|
||||
"ejectpack": 714,
|
||||
"heavydutyboots": 715,
|
||||
"blunderpolicy": 716,
|
||||
"roomservice": 717,
|
||||
"utilityumbrella": 718,
|
||||
"crackedpot": 719,
|
||||
"chippedpot": 720,
|
||||
"tr00": 721,
|
||||
"tr01": 721,
|
||||
"tr13": 721,
|
||||
"tr14": 721,
|
||||
"tr19": 721,
|
||||
"tr20": 721,
|
||||
"tr26": 721,
|
||||
"tr27": 721,
|
||||
"tr29": 721,
|
||||
"tr30": 721,
|
||||
"tr35": 721,
|
||||
"tr42": 721,
|
||||
"tr85": 721,
|
||||
"tr07": 722,
|
||||
"tr21": 722,
|
||||
"tr39": 722,
|
||||
"tr48": 722,
|
||||
"tr53": 722,
|
||||
"tr56": 722,
|
||||
"tr64": 722,
|
||||
"tr99": 722,
|
||||
"tr66": 723,
|
||||
"tr89": 723,
|
||||
"tr22": 724,
|
||||
"tr54": 724,
|
||||
"tr57": 724,
|
||||
"tr73": 724,
|
||||
"tr78": 724,
|
||||
"tr91": 724,
|
||||
"tr10": 725,
|
||||
"tr23": 725,
|
||||
"tr67": 725,
|
||||
"tr87": 725,
|
||||
"tr94": 725,
|
||||
"tr63": 726,
|
||||
"tr75": 726,
|
||||
"tr76": 726,
|
||||
"tr18": 727,
|
||||
"tr28": 727,
|
||||
"tr60": 727,
|
||||
"tr61": 727,
|
||||
"tr96": 727,
|
||||
"tr33": 728,
|
||||
"tr31": 729,
|
||||
"tr46": 729,
|
||||
"tr52": 729,
|
||||
"tr70": 729,
|
||||
"tr74": 729,
|
||||
"tr79": 729,
|
||||
"tr02": 730,
|
||||
"tr15": 730,
|
||||
"tr36": 730,
|
||||
"tr41": 730,
|
||||
"tr43": 730,
|
||||
"tr55": 730,
|
||||
"tr88": 730,
|
||||
"tr03": 731,
|
||||
"tr04": 731,
|
||||
"tr16": 731,
|
||||
"tr45": 731,
|
||||
"tr84": 731,
|
||||
"tr98": 731,
|
||||
"tr50": 732,
|
||||
"tr59": 732,
|
||||
"tr65": 732,
|
||||
"tr71": 732,
|
||||
"tr72": 732,
|
||||
"tr77": 732,
|
||||
"tr08": 733,
|
||||
"tr09": 733,
|
||||
"tr80": 733,
|
||||
"tr86": 733,
|
||||
"tr11": 734,
|
||||
"tr12": 734,
|
||||
"tr17": 734,
|
||||
"tr25": 734,
|
||||
"tr34": 734,
|
||||
"tr38": 734,
|
||||
"tr40": 734,
|
||||
"tr44": 734,
|
||||
"tr49": 734,
|
||||
"tr69": 734,
|
||||
"tr82": 734,
|
||||
"tr83": 734,
|
||||
"tr97": 734,
|
||||
"tr05": 735,
|
||||
"tr06": 735,
|
||||
"tr24": 736,
|
||||
"tr47": 736,
|
||||
"tr51": 736,
|
||||
"tr62": 736,
|
||||
"tr32": 737,
|
||||
"tr37": 737,
|
||||
"tr58": 737,
|
||||
"tr68": 737,
|
||||
"tr81": 737,
|
||||
"tr93": 737,
|
||||
"tr95": 737,
|
||||
"tr90": 738,
|
||||
"tr92": 738,
|
||||
"galaricacuff": 739,
|
||||
"galaricawreath": 740,
|
||||
"adamantcrystal": 741,
|
||||
"lustrousglobe": 742,
|
||||
"griseouscore": 743,
|
||||
"maliciousarmor": 744,
|
||||
"boosterenergy": 745,
|
||||
"abilityshield": 746,
|
||||
"clearamulet": 747,
|
||||
"mirrorherb": 748,
|
||||
"punchingglove": 749,
|
||||
"covertcloak": 750,
|
||||
"loadeddice": 751,
|
||||
"vilevial": 752,
|
||||
"auspiciousarmor": 753,
|
||||
"fairyfeather": 754,
|
||||
"syrupyapple": 755,
|
||||
"unremarkableteacup": 756,
|
||||
"masterpieceteacup": 757,
|
||||
"cornerstonemask": 758,
|
||||
"wellspringmask": 759,
|
||||
"hearthflamemask": 760,
|
||||
"metalalloy": 761,
|
||||
};
|
||||
|
||||
const found = new Map;
|
||||
|
||||
for (const filename of fs.readdirSync(itemsDir)) {
|
||||
const sn = spritedata.parseFilename(path.parse(filename).name);
|
||||
if (sn.kind !== 'i') continue;
|
||||
for (const name of [sn.name, ...spritedata.ITEM_ALIASES[sn.name] ?? []]) {
|
||||
found.set(spritedata.psid(name), path.join(itemsDir, filename));
|
||||
}
|
||||
}
|
||||
|
||||
const entries = [];
|
||||
|
||||
for (const [id, num] of Object.entries(ITEMS)) {
|
||||
const filename = found.get(id);
|
||||
if (!filename)
|
||||
throw new Error(`can't find: ${id}`);
|
||||
entries[num] = filename;
|
||||
}
|
||||
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
if (entries[i] === undefined)
|
||||
entries[i] = null;
|
||||
}
|
||||
|
||||
export default {
|
||||
width: 24,
|
||||
height: 24,
|
||||
tile: 16,
|
||||
entries
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,727 +0,0 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import * as spritedata from '@smogon/sprite-data/index.ts';
|
||||
import root from '@smogon/sprite-root/index.ts';
|
||||
|
||||
import {DEX_NUMS} from './ps-pokemon.dexnums.mjs';
|
||||
|
||||
const srcDir = path.join(root, "src");
|
||||
const spritesDir = path.join(srcDir, "minisprites/pokemon/gen6");
|
||||
|
||||
// Derived from pokemon-showdown-client/src/battle-dex-data.ts
|
||||
const BattlePokemonIconIndexes = {
|
||||
unknown: 0,
|
||||
|
||||
// alt forms
|
||||
egg: 1032 + 1,
|
||||
pikachubelle: 1032 + 2,
|
||||
pikachulibre: 1032 + 3,
|
||||
pikachuphd: 1032 + 4,
|
||||
pikachupopstar: 1032 + 5,
|
||||
pikachurockstar: 1032 + 6,
|
||||
pikachucosplay: 1032 + 7,
|
||||
unownexclamation: 1032 + 8,
|
||||
unownquestion: 1032 + 9,
|
||||
unownb: 1032 + 10,
|
||||
unownc: 1032 + 11,
|
||||
unownd: 1032 + 12,
|
||||
unowne: 1032 + 13,
|
||||
unownf: 1032 + 14,
|
||||
unowng: 1032 + 15,
|
||||
unownh: 1032 + 16,
|
||||
unowni: 1032 + 17,
|
||||
unownj: 1032 + 18,
|
||||
unownk: 1032 + 19,
|
||||
unownl: 1032 + 20,
|
||||
unownm: 1032 + 21,
|
||||
unownn: 1032 + 22,
|
||||
unowno: 1032 + 23,
|
||||
unownp: 1032 + 24,
|
||||
unownq: 1032 + 25,
|
||||
unownr: 1032 + 26,
|
||||
unowns: 1032 + 27,
|
||||
unownt: 1032 + 28,
|
||||
unownu: 1032 + 29,
|
||||
unownv: 1032 + 30,
|
||||
unownw: 1032 + 31,
|
||||
unownx: 1032 + 32,
|
||||
unowny: 1032 + 33,
|
||||
unownz: 1032 + 34,
|
||||
castformrainy: 1032 + 35,
|
||||
castformsnowy: 1032 + 36,
|
||||
castformsunny: 1032 + 37,
|
||||
deoxysattack: 1032 + 38,
|
||||
deoxysdefense: 1032 + 39,
|
||||
deoxysspeed: 1032 + 40,
|
||||
burmysandy: 1032 + 41,
|
||||
burmytrash: 1032 + 42,
|
||||
wormadamsandy: 1032 + 43,
|
||||
wormadamtrash: 1032 + 44,
|
||||
cherrimsunshine: 1032 + 45,
|
||||
shelloseast: 1032 + 46,
|
||||
gastrodoneast: 1032 + 47,
|
||||
rotomfan: 1032 + 48,
|
||||
rotomfrost: 1032 + 49,
|
||||
rotomheat: 1032 + 50,
|
||||
rotommow: 1032 + 51,
|
||||
rotomwash: 1032 + 52,
|
||||
giratinaorigin: 1032 + 53,
|
||||
shayminsky: 1032 + 54,
|
||||
unfezantf: 1032 + 55,
|
||||
basculinbluestriped: 1032 + 56,
|
||||
darmanitanzen: 1032 + 57,
|
||||
deerlingautumn: 1032 + 58,
|
||||
deerlingsummer: 1032 + 59,
|
||||
deerlingwinter: 1032 + 60,
|
||||
sawsbuckautumn: 1032 + 61,
|
||||
sawsbucksummer: 1032 + 62,
|
||||
sawsbuckwinter: 1032 + 63,
|
||||
frillishf: 1032 + 64,
|
||||
jellicentf: 1032 + 65,
|
||||
tornadustherian: 1032 + 66,
|
||||
thundurustherian: 1032 + 67,
|
||||
landorustherian: 1032 + 68,
|
||||
kyuremblack: 1032 + 69,
|
||||
kyuremwhite: 1032 + 70,
|
||||
keldeoresolute: 1032 + 71,
|
||||
meloettapirouette: 1032 + 72,
|
||||
vivillonarchipelago: 1032 + 73,
|
||||
vivilloncontinental: 1032 + 74,
|
||||
vivillonelegant: 1032 + 75,
|
||||
vivillonfancy: 1032 + 76,
|
||||
vivillongarden: 1032 + 77,
|
||||
vivillonhighplains: 1032 + 78,
|
||||
vivillonicysnow: 1032 + 79,
|
||||
vivillonjungle: 1032 + 80,
|
||||
vivillonmarine: 1032 + 81,
|
||||
vivillonmodern: 1032 + 82,
|
||||
vivillonmonsoon: 1032 + 83,
|
||||
vivillonocean: 1032 + 84,
|
||||
vivillonpokeball: 1032 + 85,
|
||||
vivillonpolar: 1032 + 86,
|
||||
vivillonriver: 1032 + 87,
|
||||
vivillonsandstorm: 1032 + 88,
|
||||
vivillonsavanna: 1032 + 89,
|
||||
vivillonsun: 1032 + 90,
|
||||
vivillontundra: 1032 + 91,
|
||||
pyroarf: 1032 + 92,
|
||||
flabebeblue: 1032 + 93,
|
||||
flabebeorange: 1032 + 94,
|
||||
flabebewhite: 1032 + 95,
|
||||
flabebeyellow: 1032 + 96,
|
||||
floetteblue: 1032 + 97,
|
||||
floetteeternal: 1032 + 98,
|
||||
floetteorange: 1032 + 99,
|
||||
floettewhite: 1032 + 100,
|
||||
floetteyellow: 1032 + 101,
|
||||
florgesblue: 1032 + 102,
|
||||
florgesorange: 1032 + 103,
|
||||
florgeswhite: 1032 + 104,
|
||||
florgesyellow: 1032 + 105,
|
||||
furfroudandy: 1032 + 106,
|
||||
furfroudebutante: 1032 + 107,
|
||||
furfroudiamond: 1032 + 108,
|
||||
furfrouheart: 1032 + 109,
|
||||
furfroukabuki: 1032 + 110,
|
||||
furfroulareine: 1032 + 111,
|
||||
furfroumatron: 1032 + 112,
|
||||
furfroupharaoh: 1032 + 113,
|
||||
furfroustar: 1032 + 114,
|
||||
meowsticf: 1032 + 115,
|
||||
aegislashblade: 1032 + 116,
|
||||
xerneasneutral: 1032 + 117,
|
||||
hoopaunbound: 1032 + 118,
|
||||
rattataalola: 1032 + 119,
|
||||
raticatealola: 1032 + 120,
|
||||
raichualola: 1032 + 121,
|
||||
sandshrewalola: 1032 + 122,
|
||||
sandslashalola: 1032 + 123,
|
||||
vulpixalola: 1032 + 124,
|
||||
ninetalesalola: 1032 + 125,
|
||||
diglettalola: 1032 + 126,
|
||||
dugtrioalola: 1032 + 127,
|
||||
meowthalola: 1032 + 128,
|
||||
persianalola: 1032 + 129,
|
||||
geodudealola: 1032 + 130,
|
||||
graveleralola: 1032 + 131,
|
||||
golemalola: 1032 + 132,
|
||||
grimeralola: 1032 + 133,
|
||||
mukalola: 1032 + 134,
|
||||
exeggutoralola: 1032 + 135,
|
||||
marowakalola: 1032 + 136,
|
||||
greninjaash: 1032 + 137,
|
||||
zygarde10: 1032 + 138,
|
||||
zygardecomplete: 1032 + 139,
|
||||
oricoriopompom: 1032 + 140,
|
||||
oricoriopau: 1032 + 141,
|
||||
oricoriosensu: 1032 + 142,
|
||||
lycanrocmidnight: 1032 + 143,
|
||||
wishiwashischool: 1032 + 144,
|
||||
miniormeteor: 1032 + 145,
|
||||
miniororange: 1032 + 146,
|
||||
minioryellow: 1032 + 147,
|
||||
miniorgreen: 1032 + 148,
|
||||
miniorblue: 1032 + 149,
|
||||
miniorindigo: 1032 + 150,
|
||||
miniorviolet: 1032 + 151,
|
||||
magearnaoriginal: 1032 + 152,
|
||||
pikachuoriginal: 1032 + 153,
|
||||
pikachuhoenn: 1032 + 154,
|
||||
pikachusinnoh: 1032 + 155,
|
||||
pikachuunova: 1032 + 156,
|
||||
pikachukalos: 1032 + 157,
|
||||
pikachualola: 1032 + 158,
|
||||
pikachupartner: 1032 + 159,
|
||||
lycanrocdusk: 1032 + 160,
|
||||
necrozmaduskmane: 1032 + 161,
|
||||
necrozmadawnwings: 1032 + 162,
|
||||
necrozmaultra: 1032 + 163,
|
||||
pikachustarter: 1032 + 164,
|
||||
eeveestarter: 1032 + 165,
|
||||
meowthgalar: 1032 + 166,
|
||||
ponytagalar: 1032 + 167,
|
||||
rapidashgalar: 1032 + 168,
|
||||
farfetchdgalar: 1032 + 169,
|
||||
weezinggalar: 1032 + 170,
|
||||
mrmimegalar: 1032 + 171,
|
||||
corsolagalar: 1032 + 172,
|
||||
zigzagoongalar: 1032 + 173,
|
||||
linoonegalar: 1032 + 174,
|
||||
darumakagalar: 1032 + 175,
|
||||
darmanitangalar: 1032 + 176,
|
||||
darmanitangalarzen: 1032 + 177,
|
||||
yamaskgalar: 1032 + 178,
|
||||
stunfiskgalar: 1032 + 179,
|
||||
cramorantgulping: 1032 + 180,
|
||||
cramorantgorging: 1032 + 181,
|
||||
toxtricitylowkey: 1032 + 182,
|
||||
alcremierubycream: 1032 + 183,
|
||||
alcremiematchacream: 1032 + 184,
|
||||
alcremiemintcream: 1032 + 185,
|
||||
alcremielemoncream: 1032 + 186,
|
||||
alcremiesaltedcream: 1032 + 187,
|
||||
alcremierubyswirl: 1032 + 188,
|
||||
alcremiecaramelswirl: 1032 + 189,
|
||||
alcremierainbowswirl: 1032 + 190,
|
||||
eiscuenoice: 1032 + 191,
|
||||
indeedeef: 1032 + 192,
|
||||
morpekohangry: 1032 + 193,
|
||||
zaciancrowned: 1032 + 194,
|
||||
zamazentacrowned: 1032 + 195,
|
||||
slowpokegalar: 1032 + 196,
|
||||
slowbrogalar: 1032 + 197,
|
||||
zarudedada: 1032 + 198,
|
||||
pikachuworld: 1032 + 199,
|
||||
articunogalar: 1032 + 200,
|
||||
zapdosgalar: 1032 + 201,
|
||||
moltresgalar: 1032 + 202,
|
||||
slowkinggalar: 1032 + 203,
|
||||
calyrexice: 1032 + 204,
|
||||
calyrexshadow: 1032 + 205,
|
||||
growlithehisui: 1032 + 206,
|
||||
arcaninehisui: 1032 + 207,
|
||||
voltorbhisui: 1032 + 208,
|
||||
electrodehisui: 1032 + 209,
|
||||
typhlosionhisui: 1032 + 210,
|
||||
qwilfishhisui: 1032 + 211,
|
||||
sneaselhisui: 1032 + 212,
|
||||
samurotthisui: 1032 + 213,
|
||||
lilliganthisui: 1032 + 214,
|
||||
zoruahisui: 1032 + 215,
|
||||
zoroarkhisui: 1032 + 216,
|
||||
braviaryhisui: 1032 + 217,
|
||||
sliggoohisui: 1032 + 218,
|
||||
goodrahisui: 1032 + 219,
|
||||
avalugghisui: 1032 + 220,
|
||||
decidueyehisui: 1032 + 221,
|
||||
basculegionf: 1032 + 222,
|
||||
enamorustherian: 1032 + 223,
|
||||
taurospaldeacombat: 1032 + 224,
|
||||
taurospaldeablaze: 1032 + 225,
|
||||
taurospaldeaaqua: 1032 + 226,
|
||||
wooperpaldea: 1032 + 227,
|
||||
oinkolognef: 1032 + 228,
|
||||
palafinhero: 1032 + 229,
|
||||
mausholdfour: 1032 + 230,
|
||||
tatsugiridroopy: 1032 + 231,
|
||||
tatsugiristretchy: 1032 + 232,
|
||||
squawkabillyblue: 1032 + 233,
|
||||
squawkabillyyellow: 1032 + 234,
|
||||
squawkabillywhite: 1032 + 235,
|
||||
gimmighoulroaming: 1032 + 236,
|
||||
dialgaorigin: 1032 + 237,
|
||||
palkiaorigin: 1032 + 238,
|
||||
basculinwhitestriped: 1032 + 239,
|
||||
ursalunabloodmoon: 1032 + 240,
|
||||
ogerponwellspring: 1032 + 241,
|
||||
ogerponhearthflame: 1032 + 242,
|
||||
ogerponcornerstone: 1032 + 243,
|
||||
terapagosterastal: 1032 + 244,
|
||||
terapagosstellar: 1032 + 245,
|
||||
|
||||
arceusbug: 1032 + 246,
|
||||
arceusdark: 1032 + 247,
|
||||
arceusdragon: 1032 + 248,
|
||||
arceuselectric: 1032 + 249,
|
||||
arceusfairy: 1032 + 250,
|
||||
arceusfighting: 1032 + 251,
|
||||
arceusfire: 1032 + 252,
|
||||
arceusflying: 1032 + 253,
|
||||
arceusghost: 1032 + 254,
|
||||
arceusgrass: 1032 + 255,
|
||||
arceusground: 1032 + 256,
|
||||
arceusice: 1032 + 257,
|
||||
arceuspoison: 1032 + 258,
|
||||
arceuspsychic: 1032 + 259,
|
||||
arceusrock: 1032 + 260,
|
||||
arceussteel: 1032 + 261,
|
||||
arceuswater: 1032 + 262,
|
||||
|
||||
genesectdouse: 1032 + 263,
|
||||
genesectshock: 1032 + 264,
|
||||
genesectburn: 1032 + 265,
|
||||
genesectchill: 1032 + 266,
|
||||
|
||||
silvallybug: 1032 + 267,
|
||||
silvallydark: 1032 + 268,
|
||||
silvallydragon: 1032 + 269,
|
||||
silvallyelectric: 1032 + 270,
|
||||
silvallyfairy: 1032 + 271,
|
||||
silvallyfighting: 1032 + 272,
|
||||
silvallyfire: 1032 + 273,
|
||||
silvallyflying: 1032 + 274,
|
||||
silvallyghost: 1032 + 275,
|
||||
silvallygrass: 1032 + 276,
|
||||
silvallyground: 1032 + 277,
|
||||
silvallyice: 1032 + 278,
|
||||
silvallypoison: 1032 + 279,
|
||||
silvallypsychic: 1032 + 280,
|
||||
silvallyrock: 1032 + 281,
|
||||
silvallysteel: 1032 + 282,
|
||||
silvallywater: 1032 + 283,
|
||||
|
||||
// alt forms with duplicate icons
|
||||
// greninjabond: 658,
|
||||
// gumshoostotem: 735,
|
||||
// raticatealolatotem: 1032 + 120,
|
||||
// marowakalolatotem: 1032 + 136,
|
||||
// araquanidtotem: 752,
|
||||
// lurantistotem: 754,
|
||||
// salazzletotem: 758,
|
||||
// vikavolttotem: 738,
|
||||
// togedemarutotem: 777,
|
||||
// mimikyutotem: 778,
|
||||
// mimikyubustedtotem: 778,
|
||||
// ribombeetotem: 743,
|
||||
// kommoototem: 784,
|
||||
// toxtricitylowkeygmax: 1320 + 69,
|
||||
sinisteaantique: 854,
|
||||
polteageistantique: 855,
|
||||
urshifurapidstrike: 892,
|
||||
dudunsparcethreesegment: 982,
|
||||
poltchageistartisan: 1012,
|
||||
sinistchamasterpiece: 1013,
|
||||
ogerpontealtera: 1017,
|
||||
ogerponwellspringtera: 1032 + 241,
|
||||
ogerponhearthflametera: 1032 + 242,
|
||||
ogerponcornerstonetera: 1032 + 243,
|
||||
|
||||
// Mega/G-Max
|
||||
venusaurmega: 1320 + 0,
|
||||
charizardmegax: 1320 + 1,
|
||||
charizardmegay: 1320 + 2,
|
||||
blastoisemega: 1320 + 3,
|
||||
beedrillmega: 1320 + 4,
|
||||
pidgeotmega: 1320 + 5,
|
||||
alakazammega: 1320 + 6,
|
||||
slowbromega: 1320 + 7,
|
||||
gengarmega: 1320 + 8,
|
||||
kangaskhanmega: 1320 + 9,
|
||||
pinsirmega: 1320 + 10,
|
||||
gyaradosmega: 1320 + 11,
|
||||
aerodactylmega: 1320 + 12,
|
||||
mewtwomegax: 1320 + 13,
|
||||
mewtwomegay: 1320 + 14,
|
||||
ampharosmega: 1320 + 15,
|
||||
steelixmega: 1320 + 16,
|
||||
scizormega: 1320 + 17,
|
||||
heracrossmega: 1320 + 18,
|
||||
houndoommega: 1320 + 19,
|
||||
tyranitarmega: 1320 + 20,
|
||||
sceptilemega: 1320 + 21,
|
||||
blazikenmega: 1320 + 22,
|
||||
swampertmega: 1320 + 23,
|
||||
gardevoirmega: 1320 + 24,
|
||||
sableyemega: 1320 + 25,
|
||||
mawilemega: 1320 + 26,
|
||||
aggronmega: 1320 + 27,
|
||||
medichammega: 1320 + 28,
|
||||
manectricmega: 1320 + 29,
|
||||
sharpedomega: 1320 + 30,
|
||||
cameruptmega: 1320 + 31,
|
||||
altariamega: 1320 + 32,
|
||||
banettemega: 1320 + 33,
|
||||
absolmega: 1320 + 34,
|
||||
glaliemega: 1320 + 35,
|
||||
salamencemega: 1320 + 36,
|
||||
metagrossmega: 1320 + 37,
|
||||
latiasmega: 1320 + 38,
|
||||
latiosmega: 1320 + 39,
|
||||
kyogreprimal: 1320 + 40,
|
||||
groudonprimal: 1320 + 41,
|
||||
rayquazamega: 1320 + 42,
|
||||
lopunnymega: 1320 + 43,
|
||||
garchompmega: 1320 + 44,
|
||||
lucariomega: 1320 + 45,
|
||||
abomasnowmega: 1320 + 46,
|
||||
gallademega: 1320 + 47,
|
||||
audinomega: 1320 + 48,
|
||||
dianciemega: 1320 + 49,
|
||||
charizardgmax: 1320 + 50,
|
||||
butterfreegmax: 1320 + 51,
|
||||
pikachugmax: 1320 + 52,
|
||||
meowthgmax: 1320 + 53,
|
||||
machampgmax: 1320 + 54,
|
||||
gengargmax: 1320 + 55,
|
||||
kinglergmax: 1320 + 56,
|
||||
laprasgmax: 1320 + 57,
|
||||
eeveegmax: 1320 + 58,
|
||||
snorlaxgmax: 1320 + 59,
|
||||
garbodorgmax: 1320 + 60,
|
||||
melmetalgmax: 1320 + 61,
|
||||
corviknightgmax: 1320 + 62,
|
||||
orbeetlegmax: 1320 + 63,
|
||||
drednawgmax: 1320 + 64,
|
||||
coalossalgmax: 1320 + 65,
|
||||
flapplegmax: 1320 + 66,
|
||||
appletungmax: 1320 + 67,
|
||||
sandacondagmax: 1320 + 68,
|
||||
toxtricitygmax: 1320 + 69,
|
||||
centiskorchgmax: 1320 + 70,
|
||||
hatterenegmax: 1320 + 71,
|
||||
grimmsnarlgmax: 1320 + 72,
|
||||
alcremiegmax: 1320 + 73,
|
||||
copperajahgmax: 1320 + 74,
|
||||
duraludongmax: 1320 + 75,
|
||||
eternatuseternamax: 1320 + 76,
|
||||
venusaurgmax: 1320 + 77,
|
||||
blastoisegmax: 1320 + 78,
|
||||
rillaboomgmax: 1320 + 79,
|
||||
cinderacegmax: 1320 + 80,
|
||||
inteleongmax: 1320 + 81,
|
||||
urshifugmax: 1320 + 82,
|
||||
urshifurapidstrikegmax: 1320 + 83,
|
||||
clefablemega: 1320 + 84,
|
||||
victreebelmega: 1320 + 85,
|
||||
starmiemega: 1320 + 86,
|
||||
dragonitemega: 1320 + 87,
|
||||
meganiummega: 1320 + 88,
|
||||
feraligatrmega: 1320 + 89,
|
||||
skarmorymega: 1320 + 90,
|
||||
froslassmega: 1320 + 91,
|
||||
emboarmega: 1320 + 92,
|
||||
excadrillmega: 1320 + 93,
|
||||
scolipedemega: 1320 + 94,
|
||||
scraftymega: 1320 + 95,
|
||||
eelektrossmega: 1320 + 96,
|
||||
chandeluremega: 1320 + 97,
|
||||
chesnaughtmega: 1320 + 98,
|
||||
delphoxmega: 1320 + 99,
|
||||
greninjamega: 1320 + 100,
|
||||
pyroarmega: 1320 + 101,
|
||||
floettemega: 1320 + 102,
|
||||
malamarmega: 1320 + 103,
|
||||
barbaraclemega: 1320 + 104,
|
||||
dragalgemega: 1320 + 105,
|
||||
hawluchamega: 1320 + 106,
|
||||
zygardemega: 1320 + 107,
|
||||
drampamega: 1320 + 108,
|
||||
falinksmega: 1320 + 109,
|
||||
raichumegax: 1320 + 110,
|
||||
raichumegay: 1320 + 111,
|
||||
chimechomega: 1320 + 112,
|
||||
absolmegaz: 1320 + 113,
|
||||
staraptormega: 1320 + 114,
|
||||
garchompmegaz: 1320 + 115,
|
||||
lucariomegaz: 1320 + 116,
|
||||
heatranmega: 1320 + 117,
|
||||
darkraimega: 1320 + 118,
|
||||
golurkmega: 1320 + 119,
|
||||
meowsticmmega: 1320 + 120,
|
||||
meowsticfmega: 1320 + 120,
|
||||
crabominablemega: 1320 + 121,
|
||||
golisopodmega: 1320 + 122,
|
||||
magearnamega: 1320 + 123,
|
||||
magearnaoriginalmega: 1320 + 124,
|
||||
zeraoramega: 1320 + 125,
|
||||
scovillainmega: 1320 + 126,
|
||||
glimmoramega: 1320 + 127,
|
||||
tatsugiricurlymega: 1320 + 128,
|
||||
tatsugiridroopymega: 1320 + 129,
|
||||
tatsugiristretchymega: 1320 + 130,
|
||||
baxcaliburmega: 1320 + 131,
|
||||
|
||||
// CAP
|
||||
syclant: 1560 + 0,
|
||||
revenankh: 1560 + 1,
|
||||
pyroak: 1560 + 2,
|
||||
fidgit: 1560 + 3,
|
||||
stratagem: 1560 + 4,
|
||||
arghonaut: 1560 + 5,
|
||||
kitsunoh: 1560 + 6,
|
||||
cyclohm: 1560 + 7,
|
||||
colossoil: 1560 + 8,
|
||||
krilowatt: 1560 + 9,
|
||||
voodoom: 1560 + 10,
|
||||
tomohawk: 1560 + 11,
|
||||
necturna: 1560 + 12,
|
||||
mollux: 1560 + 13,
|
||||
aurumoth: 1560 + 14,
|
||||
malaconda: 1560 + 15,
|
||||
cawmodore: 1560 + 16,
|
||||
volkraken: 1560 + 17,
|
||||
plasmanta: 1560 + 18,
|
||||
naviathan: 1560 + 19,
|
||||
crucibelle: 1560 + 20,
|
||||
crucibellemega: 1560 + 21,
|
||||
kerfluffle: 1560 + 22,
|
||||
pajantom: 1560 + 23,
|
||||
jumbao: 1560 + 24,
|
||||
caribolt: 1560 + 25,
|
||||
smokomodo: 1560 + 26,
|
||||
snaelstrom: 1560 + 27,
|
||||
equilibra: 1560 + 28,
|
||||
astrolotl: 1560 + 29,
|
||||
miasmaw: 1560 + 30,
|
||||
chromera: 1560 + 31,
|
||||
venomicon: 1560 + 32,
|
||||
venomiconepilogue: 1560 + 33,
|
||||
saharaja: 1560 + 34,
|
||||
hemogoblin: 1560 + 35,
|
||||
syclar: 1560 + 36,
|
||||
embirch: 1560 + 37,
|
||||
flarelm: 1560 + 38,
|
||||
breezi: 1560 + 39,
|
||||
scratchet: 1560 + 40,
|
||||
necturine: 1560 + 41,
|
||||
cupra: 1560 + 42,
|
||||
argalis: 1560 + 43,
|
||||
brattler: 1560 + 44,
|
||||
cawdet: 1560 + 45,
|
||||
volkritter: 1560 + 46,
|
||||
snugglow: 1560 + 47,
|
||||
floatoy: 1560 + 48,
|
||||
caimanoe: 1560 + 49,
|
||||
pluffle: 1560 + 50,
|
||||
rebble: 1560 + 51,
|
||||
tactite: 1560 + 52,
|
||||
privatyke: 1560 + 53,
|
||||
nohface: 1560 + 54,
|
||||
monohm: 1560 + 55,
|
||||
duohm: 1560 + 56,
|
||||
protowatt: 1560 + 57,
|
||||
voodoll: 1560 + 58,
|
||||
mumbao: 1560 + 59,
|
||||
fawnifer: 1560 + 60,
|
||||
electrelk: 1560 + 61,
|
||||
smogecko: 1560 + 62,
|
||||
smoguana: 1560 + 63,
|
||||
swirlpool: 1560 + 64,
|
||||
coribalis: 1560 + 65,
|
||||
justyke: 1560 + 66,
|
||||
solotl: 1560 + 67,
|
||||
miasmite: 1560 + 68,
|
||||
dorsoil: 1560 + 69,
|
||||
saharascal: 1560 + 70,
|
||||
ababo: 1560 + 71,
|
||||
scattervein: 1560 + 72,
|
||||
cresceidon: 1560 + 73,
|
||||
chuggalong: 1560 + 74,
|
||||
shox: 1560 + 75,
|
||||
chuggon: 1560 + 76,
|
||||
draggalong: 1560 + 77,
|
||||
ramnarok: 1560 + 78,
|
||||
ramnarokradiant: 1560 + 79,
|
||||
flox: 1560 + 80,
|
||||
obliteryx: 1560 + 81,
|
||||
};
|
||||
|
||||
const BattlePokemonIconIndexesLeft = {
|
||||
pikachubelle: 1452 + 0,
|
||||
pikachupopstar: 1452 + 1,
|
||||
clefairy: 1452 + 2,
|
||||
clefable: 1452 + 3,
|
||||
jigglypuff: 1452 + 4,
|
||||
wigglytuff: 1452 + 5,
|
||||
dugtrioalola: 1452 + 6,
|
||||
poliwhirl: 1452 + 7,
|
||||
poliwrath: 1452 + 8,
|
||||
mukalola: 1452 + 9,
|
||||
kingler: 1452 + 10,
|
||||
croconaw: 1452 + 11,
|
||||
cleffa: 1452 + 12,
|
||||
igglybuff: 1452 + 13,
|
||||
politoed: 1452 + 14,
|
||||
unownb: 1452 + 15,
|
||||
unownc: 1452 + 16,
|
||||
unownd: 1452 + 17,
|
||||
unowne: 1452 + 18,
|
||||
unownf: 1452 + 19,
|
||||
unowng: 1452 + 20,
|
||||
unownh: 1452 + 21,
|
||||
unownj: 1452 + 22,
|
||||
unownk: 1452 + 23,
|
||||
unownl: 1452 + 24,
|
||||
unownm: 1452 + 25,
|
||||
unownn: 1452 + 26,
|
||||
unownp: 1452 + 27,
|
||||
unownq: 1452 + 28,
|
||||
unownquestion: 1452 + 29,
|
||||
unownr: 1452 + 30,
|
||||
unowns: 1452 + 31,
|
||||
unownt: 1452 + 32,
|
||||
unownv: 1452 + 33,
|
||||
unownz: 1452 + 34,
|
||||
sneasel: 1452 + 35,
|
||||
teddiursa: 1452 + 36,
|
||||
roselia: 1452 + 37,
|
||||
zangoose: 1452 + 38,
|
||||
seviper: 1452 + 39,
|
||||
castformsnowy: 1452 + 40,
|
||||
absolmega: 1452 + 41,
|
||||
absol: 1452 + 42,
|
||||
regirock: 1452 + 43,
|
||||
torterra: 1452 + 44,
|
||||
budew: 1452 + 45,
|
||||
roserade: 1452 + 46,
|
||||
magmortar: 1452 + 47,
|
||||
togekiss: 1452 + 48,
|
||||
rotomwash: 1452 + 49,
|
||||
shayminsky: 1452 + 50,
|
||||
emboar: 1452 + 51,
|
||||
pansear: 1452 + 52,
|
||||
simisear: 1452 + 53,
|
||||
drilbur: 1452 + 54,
|
||||
excadrill: 1452 + 55,
|
||||
sawk: 1452 + 56,
|
||||
lilligant: 1452 + 57,
|
||||
garbodor: 1452 + 58,
|
||||
solosis: 1452 + 59,
|
||||
vanilluxe: 1452 + 60,
|
||||
amoonguss: 1452 + 61,
|
||||
klink: 1452 + 62,
|
||||
klang: 1452 + 63,
|
||||
klinklang: 1452 + 64,
|
||||
litwick: 1452 + 65,
|
||||
golett: 1452 + 66,
|
||||
golurk: 1452 + 67,
|
||||
kyuremblack: 1452 + 68,
|
||||
kyuremwhite: 1452 + 69,
|
||||
kyurem: 1452 + 70,
|
||||
keldeoresolute: 1452 + 71,
|
||||
meloetta: 1452 + 72,
|
||||
greninja: 1452 + 73,
|
||||
// greninjabond: 1452 + 73,
|
||||
greninjaash: 1452 + 74,
|
||||
furfroudebutante: 1452 + 75,
|
||||
barbaracle: 1452 + 76,
|
||||
clauncher: 1452 + 77,
|
||||
clawitzer: 1452 + 78,
|
||||
sylveon: 1452 + 79,
|
||||
klefki: 1452 + 80,
|
||||
zygarde: 1452 + 81,
|
||||
zygarde10: 1452 + 82,
|
||||
zygardecomplete: 1452 + 83,
|
||||
dartrix: 1452 + 84,
|
||||
steenee: 1452 + 85,
|
||||
tsareena: 1452 + 86,
|
||||
comfey: 1452 + 87,
|
||||
miniormeteor: 1452 + 88,
|
||||
minior: 1452 + 89,
|
||||
miniororange: 1452 + 90,
|
||||
minioryellow: 1452 + 91,
|
||||
miniorgreen: 1452 + 92,
|
||||
miniorblue: 1452 + 93,
|
||||
miniorviolet: 1452 + 94,
|
||||
miniorindigo: 1452 + 95,
|
||||
dhelmise: 1452 + 96,
|
||||
necrozma: 1452 + 97,
|
||||
marshadow: 1452 + 98,
|
||||
pikachuoriginal: 1452 + 99,
|
||||
pikachupartner: 1452 + 100,
|
||||
necrozmaduskmane: 1452 + 101,
|
||||
necrozmadawnwings: 1452 + 102,
|
||||
necrozmaultra: 1452 + 103,
|
||||
stakataka: 1452 + 104,
|
||||
blacephalon: 1452 + 105,
|
||||
};
|
||||
|
||||
const entries = [];
|
||||
|
||||
let errors = [];
|
||||
|
||||
// Need to figure out how to remove this readdir; tup doesn't like it
|
||||
for (const name of fs.readdirSync(spritesDir)) {
|
||||
const parsed = path.parse(name);
|
||||
const sn = spritedata.parseFilename(parsed.name);
|
||||
|
||||
// PS runs a name and its forme together, unlike the published sprite name.
|
||||
let id = spritedata.psid(sn.name) + spritedata.psid(sn.extra.get("o") ?? '');
|
||||
|
||||
if (sn.extra.has("f")) id += 'f';
|
||||
if (sn.extra.has("g")) id += 'gmax';
|
||||
|
||||
let index;
|
||||
if (sn.extra.has("a")) {
|
||||
index = BattlePokemonIconIndexesLeft[id];
|
||||
BattlePokemonIconIndexesLeft[id] = 'found';
|
||||
} else {
|
||||
index = BattlePokemonIconIndexes[id];
|
||||
BattlePokemonIconIndexes[id] = 'found';
|
||||
}
|
||||
|
||||
if (index === undefined) {
|
||||
// A base species sits at the slot named by its dex number; only alt
|
||||
// formes need the hand-kept table above.
|
||||
if (sn.kind === 's' && !sn.extra.has("o")) {
|
||||
index = DEX_NUMS[spritedata.psid(sn.name)];
|
||||
} else {
|
||||
errors.push(`can't find ${name}`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
entries[index] = path.join(spritesDir, name);
|
||||
}
|
||||
|
||||
for (const [id, num] of Object.entries(BattlePokemonIconIndexes)) {
|
||||
if (num !== 'found') {
|
||||
errors.push(`didn't find ${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const [id, num] of Object.entries(BattlePokemonIconIndexesLeft)) {
|
||||
if (num !== 'found') {
|
||||
errors.push(`didn't find left ${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
for (let error of errors) {
|
||||
console.error(error);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
if (entries[i] === undefined)
|
||||
entries[i] = null;
|
||||
}
|
||||
|
||||
export default {
|
||||
width: 40,
|
||||
height: 30,
|
||||
tile: 12,
|
||||
entries
|
||||
};
|
||||
@@ -1,318 +0,0 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {fileURLToPath} from 'url';
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// Derived from pokemon-showdown-client/src/battle-dex-data.ts
|
||||
const BattleAvatarNumbers = {
|
||||
1: 'lucas',
|
||||
2: 'dawn',
|
||||
3: 'youngster-gen4',
|
||||
4: 'lass-gen4dp',
|
||||
5: 'camper',
|
||||
6: 'picnicker',
|
||||
7: 'bugcatcher',
|
||||
8: 'aromalady',
|
||||
9: 'twins-gen4dp',
|
||||
10: 'hiker-gen4',
|
||||
11: 'battlegirl-gen4',
|
||||
12: 'fisherman-gen4',
|
||||
13: 'cyclist-gen4',
|
||||
14: 'cyclistf-gen4',
|
||||
15: 'blackbelt-gen4dp',
|
||||
16: 'artist-gen4',
|
||||
17: 'pokemonbreeder-gen4',
|
||||
18: 'pokemonbreederf-gen4',
|
||||
19: 'cowgirl',
|
||||
20: 'jogger',
|
||||
21: 'pokefan-gen4',
|
||||
22: 'pokefanf-gen4',
|
||||
23: 'pokekid',
|
||||
24: 'youngcouple-gen4dp',
|
||||
25: 'acetrainer-gen4dp',
|
||||
26: 'acetrainerf-gen4dp',
|
||||
27: 'waitress-gen4',
|
||||
28: 'veteran-gen4',
|
||||
29: 'ninjaboy',
|
||||
30: 'dragontamer',
|
||||
31: 'birdkeeper-gen4dp',
|
||||
32: 'doubleteam',
|
||||
33: 'richboy-gen4',
|
||||
34: 'lady-gen4',
|
||||
35: 'gentleman-gen4dp',
|
||||
36: 'madame-gen4dp',
|
||||
37: 'beauty-gen4dp',
|
||||
38: 'collector',
|
||||
39: 'policeman-gen4',
|
||||
40: 'pokemonranger-gen4',
|
||||
41: 'pokemonrangerf-gen4',
|
||||
42: 'scientist-gen4dp',
|
||||
43: 'swimmer-gen4dp',
|
||||
44: 'swimmerf-gen4dp',
|
||||
45: 'tuber',
|
||||
46: 'tuberf',
|
||||
47: 'sailor',
|
||||
48: 'sisandbro',
|
||||
49: 'ruinmaniac',
|
||||
50: 'psychic-gen4',
|
||||
51: 'psychicf-gen4',
|
||||
52: 'gambler',
|
||||
53: 'guitarist-gen4',
|
||||
54: 'acetrainersnow',
|
||||
55: 'acetrainersnowf',
|
||||
56: 'skier',
|
||||
57: 'skierf-gen4dp',
|
||||
58: 'roughneck-gen4',
|
||||
59: 'clown',
|
||||
60: 'worker-gen4',
|
||||
61: 'schoolkid-gen4dp',
|
||||
62: 'schoolkidf-gen4',
|
||||
63: 'roark',
|
||||
64: 'barry',
|
||||
65: 'byron',
|
||||
66: 'aaron',
|
||||
67: 'bertha',
|
||||
68: 'flint',
|
||||
69: 'lucian',
|
||||
70: 'cynthia-gen4',
|
||||
71: 'bellepa',
|
||||
72: 'rancher',
|
||||
73: 'mars',
|
||||
74: 'galacticgrunt',
|
||||
75: 'gardenia',
|
||||
76: 'crasherwake',
|
||||
77: 'maylene',
|
||||
78: 'fantina',
|
||||
79: 'candice',
|
||||
80: 'volkner',
|
||||
81: 'parasollady-gen4',
|
||||
82: 'waiter-gen4dp',
|
||||
83: 'interviewers',
|
||||
84: 'cameraman',
|
||||
85: 'reporter',
|
||||
86: 'idol',
|
||||
87: 'cyrus',
|
||||
88: 'jupiter',
|
||||
89: 'saturn',
|
||||
90: 'galacticgruntf',
|
||||
91: 'argenta',
|
||||
92: 'palmer',
|
||||
93: 'thorton',
|
||||
94: 'buck',
|
||||
95: 'darach',
|
||||
96: 'marley',
|
||||
97: 'mira',
|
||||
98: 'cheryl',
|
||||
99: 'riley',
|
||||
100: 'dahlia',
|
||||
101: 'ethan',
|
||||
102: 'lyra',
|
||||
103: 'twins-gen4',
|
||||
104: 'lass-gen4',
|
||||
105: 'acetrainer-gen4',
|
||||
106: 'acetrainerf-gen4',
|
||||
107: 'juggler',
|
||||
108: 'sage',
|
||||
109: 'li',
|
||||
110: 'gentleman-gen4',
|
||||
111: 'teacher',
|
||||
112: 'beauty',
|
||||
113: 'birdkeeper',
|
||||
114: 'swimmer-gen4',
|
||||
115: 'swimmerf-gen4',
|
||||
116: 'kimonogirl',
|
||||
117: 'scientist-gen4',
|
||||
118: 'acetrainercouple',
|
||||
119: 'youngcouple',
|
||||
120: 'supernerd',
|
||||
121: 'medium',
|
||||
122: 'schoolkid-gen4',
|
||||
123: 'blackbelt-gen4',
|
||||
124: 'pokemaniac',
|
||||
125: 'firebreather',
|
||||
126: 'burglar',
|
||||
127: 'biker-gen4',
|
||||
128: 'skierf',
|
||||
129: 'boarder',
|
||||
130: 'rocketgrunt',
|
||||
131: 'rocketgruntf',
|
||||
132: 'archer',
|
||||
133: 'ariana',
|
||||
134: 'proton',
|
||||
135: 'petrel',
|
||||
136: 'eusine',
|
||||
137: 'lucas-gen4pt',
|
||||
138: 'dawn-gen4pt',
|
||||
139: 'madame-gen4',
|
||||
140: 'waiter-gen4',
|
||||
141: 'falkner',
|
||||
142: 'bugsy',
|
||||
143: 'whitney',
|
||||
144: 'morty',
|
||||
145: 'chuck',
|
||||
146: 'jasmine',
|
||||
147: 'pryce',
|
||||
148: 'clair',
|
||||
149: 'will',
|
||||
150: 'koga',
|
||||
151: 'bruno',
|
||||
152: 'karen',
|
||||
153: 'lance',
|
||||
154: 'brock',
|
||||
155: 'misty',
|
||||
156: 'ltsurge',
|
||||
157: 'erika',
|
||||
158: 'janine',
|
||||
159: 'sabrina',
|
||||
160: 'blaine',
|
||||
161: 'blue',
|
||||
162: 'red',
|
||||
163: 'red',
|
||||
164: 'silver',
|
||||
165: 'giovanni',
|
||||
166: 'unknownf',
|
||||
167: 'unknown',
|
||||
168: 'unknown',
|
||||
169: 'hilbert',
|
||||
170: 'hilda',
|
||||
171: 'youngster',
|
||||
172: 'lass',
|
||||
173: 'schoolkid',
|
||||
174: 'schoolkidf',
|
||||
175: 'smasher',
|
||||
176: 'linebacker',
|
||||
177: 'waiter',
|
||||
178: 'waitress',
|
||||
179: 'chili',
|
||||
180: 'cilan',
|
||||
181: 'cress',
|
||||
182: 'nurseryaide',
|
||||
183: 'preschoolerf',
|
||||
184: 'preschooler',
|
||||
185: 'twins',
|
||||
186: 'pokemonbreeder',
|
||||
187: 'pokemonbreederf',
|
||||
188: 'lenora',
|
||||
189: 'burgh',
|
||||
190: 'elesa',
|
||||
191: 'clay',
|
||||
192: 'skyla',
|
||||
193: 'pokemonranger',
|
||||
194: 'pokemonrangerf',
|
||||
195: 'worker',
|
||||
196: 'backpacker',
|
||||
197: 'backpackerf',
|
||||
198: 'fisherman',
|
||||
199: 'musician',
|
||||
200: 'dancer',
|
||||
201: 'harlequin',
|
||||
202: 'artist',
|
||||
203: 'baker',
|
||||
204: 'psychic',
|
||||
205: 'psychicf',
|
||||
206: 'cheren',
|
||||
207: 'bianca',
|
||||
208: 'plasmagrunt-gen5bw',
|
||||
209: 'n',
|
||||
210: 'richboy',
|
||||
211: 'lady',
|
||||
212: 'pilot',
|
||||
213: 'workerice',
|
||||
214: 'hoopster',
|
||||
215: 'scientistf',
|
||||
216: 'clerkf',
|
||||
217: 'acetrainerf',
|
||||
218: 'acetrainer',
|
||||
219: 'blackbelt',
|
||||
220: 'scientist',
|
||||
221: 'striker',
|
||||
222: 'brycen',
|
||||
223: 'iris',
|
||||
224: 'drayden',
|
||||
225: 'roughneck',
|
||||
226: 'janitor',
|
||||
227: 'pokefan',
|
||||
228: 'pokefanf',
|
||||
229: 'doctor',
|
||||
230: 'nurse',
|
||||
231: 'hooligans',
|
||||
232: 'battlegirl',
|
||||
233: 'parasollady',
|
||||
234: 'clerk',
|
||||
235: 'clerk-boss',
|
||||
236: 'backers',
|
||||
237: 'backersf',
|
||||
238: 'veteran',
|
||||
239: 'veteranf',
|
||||
240: 'biker',
|
||||
241: 'infielder',
|
||||
242: 'hiker',
|
||||
243: 'madame',
|
||||
244: 'gentleman',
|
||||
245: 'plasmagruntf-gen5bw',
|
||||
246: 'shauntal',
|
||||
247: 'marshal',
|
||||
248: 'grimsley',
|
||||
249: 'caitlin',
|
||||
250: 'ghetsis-gen5bw',
|
||||
251: 'depotagent',
|
||||
252: 'swimmer',
|
||||
253: 'swimmerf',
|
||||
254: 'policeman',
|
||||
255: 'maid',
|
||||
256: 'ingo',
|
||||
257: 'alder',
|
||||
258: 'cyclist',
|
||||
259: 'cyclistf',
|
||||
260: 'cynthia',
|
||||
261: 'emmet',
|
||||
262: 'hilbert-dueldisk',
|
||||
263: 'hilda-dueldisk',
|
||||
264: 'hugh',
|
||||
265: 'rosa',
|
||||
266: 'nate',
|
||||
267: 'colress',
|
||||
268: 'beauty-gen5bw2',
|
||||
269: 'ghetsis',
|
||||
270: 'plasmagrunt',
|
||||
271: 'plasmagruntf',
|
||||
272: 'iris-gen5bw2',
|
||||
273: 'brycenman',
|
||||
274: 'shadowtriad',
|
||||
275: 'rood',
|
||||
276: 'zinzolin',
|
||||
277: 'cheren-gen5bw2',
|
||||
278: 'marlon',
|
||||
279: 'roxie',
|
||||
280: 'roxanne',
|
||||
281: 'brawly',
|
||||
282: 'wattson',
|
||||
283: 'flannery',
|
||||
284: 'norman',
|
||||
285: 'winona',
|
||||
286: 'tate',
|
||||
287: 'liza',
|
||||
288: 'juan',
|
||||
289: 'guitarist',
|
||||
290: 'steven',
|
||||
291: 'wallace',
|
||||
292: 'bellelba',
|
||||
293: 'benga',
|
||||
// Not in the existing trainer sheet...
|
||||
// 294: 'ash',
|
||||
}
|
||||
|
||||
|
||||
const entries = [];
|
||||
|
||||
for (const [num, id] of Object.entries(BattleAvatarNumbers)) {
|
||||
entries[num - 1] = path.join(__dirname, "src/canonical/trainers", id + ".png");
|
||||
}
|
||||
|
||||
export default {
|
||||
width: 80,
|
||||
height: 80,
|
||||
tile: 16,
|
||||
entries
|
||||
};
|
||||
125
ps.build.ts
125
ps.build.ts
@@ -1,125 +0,0 @@
|
||||
|
||||
import * as spritedata from '@smogon/sprite-data/index.ts';
|
||||
|
||||
import {gen10Modelslike} from './rules/modelslike.ts';
|
||||
import type {Sprite} from './rules/publish.ts';
|
||||
import {forEachRule, rule} from './tools/build/artifact.ts';
|
||||
import {PNG_DETERMINISTIC, base, compresspng, pad, spriteglob} from './tools/build/helpers.ts';
|
||||
import {type DeployCtx, deploy} from './tools/deploy/api.ts';
|
||||
|
||||
// PS spritesheets. The sheet tools readdir the minisprite dirs and read the
|
||||
// ids off the filenames, baking those names into the sheet layout, hence
|
||||
// nameSensitive.
|
||||
|
||||
let sheetDeps = [
|
||||
'data/lib/index.ts',
|
||||
'lib/root/index.ts',
|
||||
'tools/sheet/index.ts',
|
||||
];
|
||||
|
||||
rule('ps-pokemon.sheet.mjs', {
|
||||
display: 'ps pokemon sheet',
|
||||
nameSensitive: true,
|
||||
deps: ['src/minisprites/pokemon/gen6/*', 'ps-pokemon.dexnums.mjs', ...sheetDeps],
|
||||
cmds: ['node tools/sheet/index.ts %f %o', compresspng({config: 'SPRITESHEET'})],
|
||||
}, 'pokemonicons-sheet.png');
|
||||
|
||||
// TODO: reenable when trainers are moved
|
||||
// rule("ps-trainers.sheet.mjs", {
|
||||
// display: "ps trainers sheet",
|
||||
// nameSensitive: true,
|
||||
// cmds: ["node tools/sheet/index.ts %f %o", compresspng({config: "SPRITESHEET"})],
|
||||
// }, "trainers-sheet.png");
|
||||
|
||||
rule('ps-items.sheet.mjs', {
|
||||
display: 'ps items sheet',
|
||||
nameSensitive: true,
|
||||
deps: ['src/minisprites/items/*', ...sheetDeps],
|
||||
cmds: ['node tools/sheet/index.ts %f %o', compresspng({config: 'SPRITESHEET'})],
|
||||
}, 'itemicons-sheet.png');
|
||||
|
||||
// PS pokeball icons; input order is the sheet order.
|
||||
|
||||
rule([
|
||||
'src/_uncategorized/noncanonical/ui/battle/Ball-Normal.png',
|
||||
'src/_uncategorized/noncanonical/ui/battle/Ball-Sick.png',
|
||||
'src/_uncategorized/noncanonical/ui/battle/Ball-Null.png',
|
||||
], {
|
||||
display: 'pokemonicons-pokeball-sheet',
|
||||
cmds: [
|
||||
`magick convert ${PNG_DETERMINISTIC} -background transparent -gravity center -extent 40x30 %f +append %o`,
|
||||
compresspng({config: 'SPRITESHEET'}),
|
||||
],
|
||||
}, 'pokemonicons-pokeball-sheet.png');
|
||||
|
||||
// Padded Dex, plus missing CAPs backfilled from the gen5/model gifs.
|
||||
|
||||
let dex = forEachRule('src/dex/*', {
|
||||
display: 'pad dex %f',
|
||||
cmds: [pad({w: 120, h: 120}), compresspng({config: 'DEX'})],
|
||||
}, '%b');
|
||||
|
||||
let dexSet = new Set(dex.map(base));
|
||||
let dexMissing = [];
|
||||
for (let file of spriteglob(['src/sprites/gen5/*.gif', 'src/models/*.gif'], {b: false, s: false})) {
|
||||
if (!dexSet.has(base(file))) {
|
||||
dexMissing.push(file);
|
||||
dexSet.add(base(file));
|
||||
}
|
||||
}
|
||||
|
||||
forEachRule(dexMissing, {
|
||||
display: 'missing dex %B',
|
||||
cmds: [
|
||||
`magick convert "%f[0]" ${PNG_DETERMINISTIC} -trim %o`,
|
||||
`magick mogrify ${PNG_DETERMINISTIC} -background transparent -gravity center -resize "120x120>" -extent 120x120 %o`,
|
||||
compresspng({config: 'DEX'}),
|
||||
],
|
||||
}, '%B.png');
|
||||
|
||||
// ani/: the models plus champions backfill, under PS ids.
|
||||
|
||||
let aniChampions = gen10Modelslike();
|
||||
|
||||
deploy(async ctx => {
|
||||
let seenModels = new Set<string>();
|
||||
|
||||
for (let f of await ctx.list('src/models')) {
|
||||
seenModels.add(f.name);
|
||||
psSpritecopy(ctx, f, 'ani');
|
||||
}
|
||||
|
||||
for (let f of aniChampions) {
|
||||
if (seenModels.has(f.name)) {
|
||||
continue;
|
||||
}
|
||||
seenModels.add(f.name);
|
||||
psSpritecopy(ctx, f, 'ani');
|
||||
}
|
||||
|
||||
// TODO: ship the padded dex, sheets, trainers, types/categories when
|
||||
// the PS deploy is revived; the rules above keep them building.
|
||||
});
|
||||
|
||||
// PS runs the words of a name together, where the smogon aliases dash them.
|
||||
function psSpritecopy(ctx: DeployCtx, f: Sprite, dir: string): void {
|
||||
let sn = spritedata.parseFilename(f.name);
|
||||
|
||||
// Skip asymmetrical for now
|
||||
if (sn.extra.has('a') || sn.extra.has('b') || sn.extra.has('s')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sn.kind !== 's') {
|
||||
// Skip this, we don't use Unknown/Substitute
|
||||
return;
|
||||
}
|
||||
|
||||
let name = spritedata.publishedName(sn, spritedata.psid);
|
||||
|
||||
if (f.ext === null) {
|
||||
throw new Error(`Sprite ${f.name} has no extension`);
|
||||
}
|
||||
ctx.copy(f, `${dir}/${name}.${f.ext}`);
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ Formes ride in `-o`, so `Charizard-Mega-X`'s back sprite is
|
||||
`scharizard-omega_x-b.gif` and every Charizard is `scharizard-*`. The forme
|
||||
comes first so a forme's sprites sort together.
|
||||
|
||||
`tools/spritedata/names.ts` prints every filename pokemon-showdown implies, if
|
||||
you need to check a directory against it.
|
||||
`tools/deploy/coverage.ts` prints what a deploy would delete off the server, if
|
||||
you need to check the build against what is actually being served.
|
||||
|
||||
# Flags
|
||||
|
||||
|
||||
@@ -11,9 +11,6 @@ import {spawnSync} from 'node:child_process';
|
||||
// when these two sets published through Manifest, and the pre-rename spellings
|
||||
// below that nothing has asked for in years. Anything else is a hole in the
|
||||
// build, and this finds it before rsync does.
|
||||
//
|
||||
// names.ts answers the same question against pokemon-showdown; this one
|
||||
// answers it against what is actually being served.
|
||||
|
||||
let dir = process.argv[2];
|
||||
let remote = process.argv[3] ?? 'smogon:/smog2/sprites';
|
||||
@@ -57,7 +54,7 @@ for (let set of ['xy', 'xyicons']) {
|
||||
|
||||
let stamped = 0;
|
||||
let backlog = 0;
|
||||
let unexplained = [];
|
||||
let unexplained: string[] = [];
|
||||
for (let line of rsync.stdout.split('\n')) {
|
||||
let m = /^\*deleting +(.*)$/.exec(line);
|
||||
if (!m) continue;
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
import * as cp from 'node:child_process';
|
||||
import * as path from 'node:path';
|
||||
|
||||
let sheetjs = process.argv[2];
|
||||
let dest = process.argv[3];
|
||||
|
||||
if (!sheetjs || !dest) {
|
||||
throw new Error(`node tools/sheet <file.sheet.js> <dest>`);
|
||||
}
|
||||
|
||||
// Must have file:/// for Windows
|
||||
let {default: sheet} = await import(path.join('file:///', process.cwd(), sheetjs));
|
||||
|
||||
for (let i = 0; i < sheet.entries.length; i++) {
|
||||
if (sheet.entries[i] === undefined)
|
||||
throw new Error(`gap: ${i}`);
|
||||
if (sheet.entries[i] === null) {
|
||||
// ImageMagick blank entry
|
||||
sheet.entries[i] = 'xc:transparent';
|
||||
}
|
||||
}
|
||||
|
||||
// Write list of filenames to stdin, Windows can't handle large cli arg lists.
|
||||
// Before we wrote a tmp file and deleted it afterwards, but apparently tup
|
||||
// can't track unlinkSync on Windows?
|
||||
let proc = cp.spawn('magick', [
|
||||
'montage',
|
||||
'@-',
|
||||
// Keep sheet bytes deterministic for the content-addressed build.
|
||||
'-define', 'png:exclude-chunks=date,time',
|
||||
'-background', 'transparent',
|
||||
'-geometry', `${sheet.width}x${sheet.height}>`,
|
||||
'-gravity', 'center',
|
||||
'-tile', `${sheet.tile}x`,
|
||||
'-depth', '8',
|
||||
dest
|
||||
], {
|
||||
stdio: ['pipe', 'inherit', 'inherit']
|
||||
});
|
||||
|
||||
// Write one at a time to avoid "malloc(): corrupted top size" error
|
||||
for (let entry of sheet.entries) {
|
||||
if (!proc.stdin.write(entry + "\n")) {
|
||||
// imagick doesn't like it when it receives the input too fast. This
|
||||
// seems to avoid a realloc() invalid next size error.
|
||||
await new Promise(resolve => {
|
||||
proc.stdin.once('drain', resolve);
|
||||
});
|
||||
}
|
||||
}
|
||||
proc.stdin.end();
|
||||
|
||||
proc.on('exit', (code, signal) => {
|
||||
if (code || signal) {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@types/node": "^24.10.7"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig-base"
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
import {createRequire} from 'node:module';
|
||||
import * as path from 'node:path';
|
||||
|
||||
// Regenerates ps-pokemon.dexnums.mjs from a pokemon-showdown checkout:
|
||||
//
|
||||
// node tools/spritedata/dexnums.ts ~/smogon/pokemon-showdown > ps-pokemon.dexnums.mjs
|
||||
//
|
||||
// The PS icon sheet puts a base species at the slot named by its dex number,
|
||||
// and only alt formes need the hand-kept index table in ps-pokemon.sheet.mjs.
|
||||
|
||||
type PokedexEntry = {
|
||||
num: number,
|
||||
name: string,
|
||||
baseSpecies?: string
|
||||
};
|
||||
|
||||
let ps = process.argv[2];
|
||||
if (!ps) {
|
||||
throw new Error('usage: node tools/spritedata/dexnums.ts <pokemon-showdown checkout>');
|
||||
}
|
||||
|
||||
let require = createRequire(import.meta.url);
|
||||
let {Pokedex} = require(path.resolve(ps, 'dist/data/pokedex.js')) as
|
||||
{Pokedex: Record<string, PokedexEntry>};
|
||||
|
||||
let out = '';
|
||||
out += '// Generated by tools/spritedata/dexnums.ts; do not edit.\n';
|
||||
out += '// PS id of every base species -> its national dex number.\n\n';
|
||||
out += 'export const DEX_NUMS = {\n';
|
||||
for (let {num, name, baseSpecies} of Object.values(Pokedex)) {
|
||||
if (baseSpecies) continue;
|
||||
out += `\t${name.toLowerCase().replace(/[^a-z0-9]+/g, '')}: ${num},\n`;
|
||||
}
|
||||
out += '};\n';
|
||||
|
||||
process.stdout.write(out);
|
||||
@@ -1,20 +0,0 @@
|
||||
import {formatFilename} from '@smogon/sprite-data/index.ts';
|
||||
|
||||
import {spriteFiles} from './pokedex.ts';
|
||||
|
||||
// Every sprite filename pokemon-showdown implies, one per line:
|
||||
//
|
||||
// node tools/spritedata/names.ts ~/smogon/pokemon-showdown | sort > /tmp/want
|
||||
// ls src/models | sed 's/\.[^.]*$//' | cut -d- -f1 | sort -u > /tmp/have
|
||||
//
|
||||
// Nothing in the build validates a filename any more, so this is how you check
|
||||
// a directory against the source of truth.
|
||||
|
||||
let ps = process.argv[2];
|
||||
if (!ps) {
|
||||
throw new Error('usage: node tools/spritedata/names.ts <pokemon-showdown checkout>');
|
||||
}
|
||||
|
||||
for (let file of spriteFiles(ps)) {
|
||||
process.stdout.write(`${formatFilename(file)}\n`);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@smogon/sprite-data": "workspace:*",
|
||||
"@smogon/sprite-root": "workspace:*",
|
||||
"@types/node": "^24.10.7"
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
import {createRequire} from 'node:module';
|
||||
import * as path from 'node:path';
|
||||
|
||||
import {encode, type InputSpriteFilename} from '@smogon/sprite-data/index.ts';
|
||||
|
||||
// Everything the sprite tree wants from a pokemon-showdown checkout: which
|
||||
// sprites should exist, and what each one is called.
|
||||
|
||||
export type Specie = {
|
||||
num: number,
|
||||
formeNum: number,
|
||||
base: string,
|
||||
forme: string
|
||||
};
|
||||
|
||||
export type Item = {
|
||||
num: number,
|
||||
names: string[]
|
||||
};
|
||||
|
||||
type PokedexEntry = {
|
||||
num: number,
|
||||
name: string,
|
||||
baseSpecies?: string,
|
||||
formeOrder?: string[]
|
||||
};
|
||||
|
||||
type ItemsEntry = {
|
||||
num: number,
|
||||
name: string
|
||||
};
|
||||
|
||||
function load<T>(ps: string, file: string, key: string): Record<string, T> {
|
||||
let require = createRequire(import.meta.url);
|
||||
let mod = require(path.resolve(ps, 'dist/data', file)) as Record<string, Record<string, T>>;
|
||||
let table = mod[key];
|
||||
if (table === undefined) {
|
||||
throw new Error(`${file} has no ${key} export; is ${ps} built?`);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
export function species(ps: string): Specie[] {
|
||||
let out: Specie[] = [];
|
||||
for (let {num, name, baseSpecies, formeOrder} of Object.values(load<PokedexEntry>(ps, 'pokedex.js', 'Pokedex'))) {
|
||||
// Formes are enumerated from their base species, not on their own.
|
||||
if (baseSpecies) continue;
|
||||
for (let [formeNum, formeName] of (formeOrder ?? [name]).entries()) {
|
||||
// Gmax is a flag, not a forme.
|
||||
if (formeName.endsWith('-Gmax')) continue;
|
||||
out.push({num, formeNum, base: name, forme: formeName.slice(name.length + 1)});
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export function items(ps: string): Item[] {
|
||||
// One sprite per item number, so items sharing a number share a sprite and
|
||||
// collect their names: Aspear Berry is also Burnt Berry.
|
||||
let byNum = new Map<number, Item>();
|
||||
for (let {num, name} of Object.values(load<ItemsEntry>(ps, 'items.js', 'Items'))) {
|
||||
let item = byNum.get(num);
|
||||
if (item) {
|
||||
item.names.push(name);
|
||||
} else {
|
||||
byNum.set(num, {num, names: [name]});
|
||||
}
|
||||
}
|
||||
return [...byNum.values()];
|
||||
}
|
||||
|
||||
// The filename each sprite should have. PS's formeOrder repeats a name where
|
||||
// the games gave one forme several slots (Zygarde's Power Construct pair,
|
||||
// Minior's seven meteors), and nothing in the data tells those apart, so the
|
||||
// lowest slot keeps the bare name and the rest carry the slot in -c.
|
||||
export function spriteFiles(ps: string): InputSpriteFilename[] {
|
||||
let out: InputSpriteFilename[] = [];
|
||||
let seen = new Set<string>();
|
||||
|
||||
for (let {formeNum, base, forme} of species(ps)) {
|
||||
let name = encode(base);
|
||||
let extra = new Map<string, string>();
|
||||
if (forme) {
|
||||
extra.set('o', encode(forme));
|
||||
}
|
||||
let key = `${name}-${extra.get('o') ?? ''}`;
|
||||
if (seen.has(key)) {
|
||||
extra.set('c', String(formeNum));
|
||||
}
|
||||
seen.add(key);
|
||||
out.push({kind: 's', name, extra});
|
||||
}
|
||||
|
||||
for (let {names} of items(ps)) {
|
||||
out.push({kind: 'i', name: encode(names[0]!)});
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
|
||||
import {encode, formatFilename, parseFilename, type InputSpriteFilename} from '@smogon/sprite-data/index.ts';
|
||||
import root from '@smogon/sprite-root/index.ts';
|
||||
|
||||
import {items, species, spriteFiles} from './pokedex.ts';
|
||||
|
||||
// One-off: renames src/ off the packed numeric ids onto encoded names.
|
||||
//
|
||||
// node tools/spritedata/rename.ts ~/smogon/pokemon-showdown [--dry-run]
|
||||
//
|
||||
// Kept for the record rather than for reuse. The old id packed the dex number
|
||||
// and the forme index into one number, `s((|num| << 5) + formeNum)` with bit 29
|
||||
// marking the negative nums CAP and fakemon use, and `i(|num|)` for items;
|
||||
// src/previews/gen8 wrote the same number with no prefix at all. Reconstruct
|
||||
// those here and map each to the name the file should have had.
|
||||
|
||||
let ps = process.argv[2];
|
||||
let dryRun = process.argv.includes('--dry-run');
|
||||
if (!ps) {
|
||||
throw new Error('usage: node tools/spritedata/rename.ts <pokemon-showdown checkout> [--dry-run]');
|
||||
}
|
||||
|
||||
function legacy(num: number, formeNum: number): number {
|
||||
let sid = (Math.abs(num) << 5) + formeNum;
|
||||
return num < 0 ? sid | (1 << 29) : sid;
|
||||
}
|
||||
|
||||
// spriteFiles() lists species then items, each in the order its own reader
|
||||
// yields, so the ids line up positionally.
|
||||
let files = spriteFiles(ps);
|
||||
let sids = [
|
||||
...species(ps).map(s => `s${legacy(s.num, s.formeNum)}`),
|
||||
...items(ps).map(i => `i${i.num < 0 ? Math.abs(i.num) | (1 << 29) : i.num}`),
|
||||
];
|
||||
if (sids.length !== files.length) {
|
||||
throw new Error(`${sids.length} ids for ${files.length} sprites`);
|
||||
}
|
||||
|
||||
let byId = new Map<string, InputSpriteFilename>();
|
||||
for (let [i, sid] of sids.entries()) {
|
||||
byId.set(sid, files[i]!);
|
||||
}
|
||||
|
||||
let renames: [string, string][] = [];
|
||||
let missing = new Set<string>();
|
||||
|
||||
function walk(dir: string): void {
|
||||
for (let ent of fs.readdirSync(dir, {withFileTypes: true})) {
|
||||
let p = path.join(dir, ent.name);
|
||||
if (ent.isDirectory()) {
|
||||
// Its own naming scheme, and nothing parses it.
|
||||
if (path.basename(p) !== '_uncategorized') walk(p);
|
||||
continue;
|
||||
}
|
||||
if (path.extname(p) === '.md') continue;
|
||||
|
||||
let ext = path.extname(ent.name);
|
||||
let stem = ent.name.slice(0, -ext.length);
|
||||
let [id, ...flags] = stem.split('-');
|
||||
|
||||
let file: InputSpriteFilename;
|
||||
if (id!.startsWith('x')) {
|
||||
file = {kind: 'x', name: encode(id!.slice(1))};
|
||||
} else {
|
||||
let found = byId.get(/^[0-9]+$/.test(id!) ? `s${id}` : id!);
|
||||
if (!found) {
|
||||
missing.add(id!);
|
||||
continue;
|
||||
}
|
||||
file = found;
|
||||
}
|
||||
|
||||
let extra = new Map(file.extra);
|
||||
for (let flag of flags) {
|
||||
extra.set(flag.charAt(0), flag.slice(1));
|
||||
}
|
||||
let renamed = formatFilename({kind: file.kind, name: file.name, extra}) + ext;
|
||||
if (renamed !== ent.name) {
|
||||
renames.push([p, path.join(dir, renamed)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
walk(path.join(root, 'src'));
|
||||
|
||||
if (missing.size) {
|
||||
throw new Error(`no sprite for ${[...missing].join(', ')}`);
|
||||
}
|
||||
|
||||
let taken = new Set(renames.map(([, to]) => to));
|
||||
if (taken.size !== renames.length) {
|
||||
throw new Error('renames collide');
|
||||
}
|
||||
|
||||
for (let [from, to] of renames) {
|
||||
if (!dryRun) fs.renameSync(from, to);
|
||||
}
|
||||
process.stderr.write(`${dryRun ? 'would rename' : 'renamed'} ${renames.length} files\n`);
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig-base",
|
||||
"references": [
|
||||
{"path": "../../data/lib"},
|
||||
{"path": "../../lib/root"}
|
||||
]
|
||||
}
|
||||
@@ -4,9 +4,7 @@
|
||||
{"path": "./tsconfig.json"},
|
||||
{"path": "tools/build"},
|
||||
{"path": "tools/deploy"},
|
||||
{"path": "tools/sheet"},
|
||||
{"path": "tools/smogdexspritesheet"},
|
||||
{"path": "tools/spritedata"},
|
||||
{"path": "tools/trim"},
|
||||
{"path": "lib/root"},
|
||||
{"path": "data/lib"},
|
||||
|
||||
Reference in New Issue
Block a user