Give the grammar a cosmetic axis, and import Alcremie's sweets
The smogon side serves 62 Alcremie animations the build has never made, alcremie-caramel-swirl-berry and its kin, one per cream and sweet. PS models the sweet nowhere in pokedex.js, so spriteFiles() will never name one, and nothing under src/ has ever held one: they live on that server and nowhere else, which is what --delete-after would have taken. The sweet cannot ride inside -o. The two readings of a name disagree about where the cream's words divide, `caramel-swirl` against `caramelswirl`, but agree about the boundary in front of the sweet, `-berry` for both. Fold the sweet into the forme and whichever reading you spell it for, the other one comes out wrong. So -k carries it, published after the forme and before the variant flags, and formatFilename now leads with every part publishedName spells rather than with -o alone, for the reason it always led with -o: a forme's sprites should sort together. The art comes from play.pokemonshowdown.com/sprites/ani, which serves all 54 combinations the games draw, at the 54x73 the creams here already use. Of the 62 on the smogon server, 8 are <cream>-strawberry: strawberry is the default sweet, spelled as the bare cream both upstream and in the list chatot keeps, so nothing asks for those and they go with the other leftovers. Vanilla cream ships as an explicit -ovanilla_cream, because PS's base Alcremie publishes as `alcremie` while the sweets are named off the cream. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@@ -4,8 +4,8 @@
|
||||
//
|
||||
// kind s specie, i item, x literal (Egg, Substitute, ...)
|
||||
// name the encoded name, [a-z0-9_]+
|
||||
// flags -o forme -b back -s shiny -a asymmetrical -f female
|
||||
// -g gmax or -g<game> -v<vendor> -c<slot>
|
||||
// flags -o forme -k cosmetic -b back -s shiny -a asymmetrical
|
||||
// -f female -g gmax or -g<game> -v<vendor> -c<slot>
|
||||
//
|
||||
// A name is encoded rather than spelled, because the two places these sprites
|
||||
// are published disagree about what a word boundary is: smogon writes
|
||||
@@ -48,12 +48,23 @@ export function psid(e: string): string {
|
||||
|
||||
// A published name: the name and its forme joined with a dash, then the
|
||||
// variant flags, which both sides spell the same way.
|
||||
//
|
||||
// A cosmetic is its own component rather than part of the forme, because the
|
||||
// two readings disagree about where a forme's words divide but not about the
|
||||
// boundary in front of the cosmetic. Alcremie's cream is `caramel-swirl` for
|
||||
// smogon and `caramelswirl` for PS, while its sweet is `-berry` for both; fold
|
||||
// the sweet into the forme and whichever reading you spell it for, the other
|
||||
// one comes out wrong.
|
||||
export function publishedName(sn: SpriteFilename, part: (e: string) => string): string {
|
||||
let name = part(sn.name);
|
||||
let forme = sn.extra.get('o');
|
||||
if (forme) {
|
||||
name += `-${part(forme)}`;
|
||||
}
|
||||
let cosmetic = sn.extra.get('k');
|
||||
if (cosmetic) {
|
||||
name += `-${part(cosmetic)}`;
|
||||
}
|
||||
if (sn.extra.has('f')) {
|
||||
name += '-f';
|
||||
}
|
||||
@@ -119,19 +130,25 @@ export function parseFilename(s: string): SpriteFilename {
|
||||
return {kind, name: first.slice(1), extra};
|
||||
}
|
||||
|
||||
// The flags publishedName() spells into the name, in the order it spells them.
|
||||
const NAME_PARTS = ['o', 'k'];
|
||||
|
||||
export function formatFilename(si: InputSpriteFilename): string {
|
||||
let s = `${si.kind}${si.name}`;
|
||||
|
||||
// The forme leads, so a forme's whole set of sprites sorts together
|
||||
// instead of interleaving with the base forme's by flag letter.
|
||||
let forme = si.extra?.get('o');
|
||||
if (forme !== undefined) {
|
||||
s += `-o${forme}`;
|
||||
// The parts of the name lead, in the order they are published, so a
|
||||
// forme's whole set of sprites sorts together instead of interleaving with
|
||||
// the base forme's by flag letter.
|
||||
for (let k of NAME_PARTS) {
|
||||
let v = si.extra?.get(k);
|
||||
if (v !== undefined) {
|
||||
s += `-${k}${v}`;
|
||||
}
|
||||
}
|
||||
|
||||
let extra = [];
|
||||
for (let [k, v] of si.extra?.entries() ?? []) {
|
||||
if (k !== 'o') {
|
||||
if (!NAME_PARTS.includes(k)) {
|
||||
extra.push(`-${k}${v}`);
|
||||
}
|
||||
}
|
||||
|
||||
BIN
src/models/salcremie-ocaramel_swirl-kberry.gif
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
src/models/salcremie-ocaramel_swirl-kclover.gif
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
src/models/salcremie-ocaramel_swirl-kflower.gif
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
src/models/salcremie-ocaramel_swirl-klove.gif
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
src/models/salcremie-ocaramel_swirl-kribbon.gif
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
src/models/salcremie-ocaramel_swirl-kstar.gif
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
src/models/salcremie-olemon_cream-kberry.gif
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
src/models/salcremie-olemon_cream-kclover.gif
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
src/models/salcremie-olemon_cream-kflower.gif
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
src/models/salcremie-olemon_cream-klove.gif
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
src/models/salcremie-olemon_cream-kribbon.gif
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
src/models/salcremie-olemon_cream-kstar.gif
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
src/models/salcremie-omatcha_cream-kberry.gif
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
src/models/salcremie-omatcha_cream-kclover.gif
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
src/models/salcremie-omatcha_cream-kflower.gif
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
src/models/salcremie-omatcha_cream-klove.gif
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
src/models/salcremie-omatcha_cream-kribbon.gif
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
src/models/salcremie-omatcha_cream-kstar.gif
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
src/models/salcremie-omint_cream-kberry.gif
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
src/models/salcremie-omint_cream-kclover.gif
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
src/models/salcremie-omint_cream-kflower.gif
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
src/models/salcremie-omint_cream-klove.gif
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
src/models/salcremie-omint_cream-kribbon.gif
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
src/models/salcremie-omint_cream-kstar.gif
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
src/models/salcremie-orainbow_swirl-kberry.gif
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
src/models/salcremie-orainbow_swirl-kclover.gif
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
src/models/salcremie-orainbow_swirl-kflower.gif
Normal file
|
After Width: | Height: | Size: 117 KiB |
BIN
src/models/salcremie-orainbow_swirl-klove.gif
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
src/models/salcremie-orainbow_swirl-kribbon.gif
Normal file
|
After Width: | Height: | Size: 117 KiB |
BIN
src/models/salcremie-orainbow_swirl-kstar.gif
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
src/models/salcremie-oruby_cream-kberry.gif
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
src/models/salcremie-oruby_cream-kclover.gif
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
src/models/salcremie-oruby_cream-kflower.gif
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
src/models/salcremie-oruby_cream-klove.gif
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
src/models/salcremie-oruby_cream-kribbon.gif
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
src/models/salcremie-oruby_cream-kstar.gif
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
src/models/salcremie-oruby_swirl-kberry.gif
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
src/models/salcremie-oruby_swirl-kclover.gif
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
src/models/salcremie-oruby_swirl-kflower.gif
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
src/models/salcremie-oruby_swirl-klove.gif
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
src/models/salcremie-oruby_swirl-kribbon.gif
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
src/models/salcremie-oruby_swirl-kstar.gif
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
src/models/salcremie-osalted_cream-kberry.gif
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
src/models/salcremie-osalted_cream-kclover.gif
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
src/models/salcremie-osalted_cream-kflower.gif
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
src/models/salcremie-osalted_cream-klove.gif
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
src/models/salcremie-osalted_cream-kribbon.gif
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
src/models/salcremie-osalted_cream-kstar.gif
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
src/models/salcremie-ovanilla_cream-kberry.gif
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
src/models/salcremie-ovanilla_cream-kclover.gif
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
src/models/salcremie-ovanilla_cream-kflower.gif
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
src/models/salcremie-ovanilla_cream-klove.gif
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
src/models/salcremie-ovanilla_cream-kribbon.gif
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
src/models/salcremie-ovanilla_cream-kstar.gif
Normal file
|
After Width: | Height: | Size: 102 KiB |