diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 70dc2bfa502..e40b18eb69b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,8 +1,12 @@ -name: Deploy +name: Deploy Main on: - push: {} - pull_request: {} + push: + branches: + - main + pull_request: + branches: + - main jobs: deploy: @@ -22,7 +26,7 @@ jobs: env: NODE_ENV: production - name: Set up SSH - if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch + if: github.event_name == 'push' && github.ref_name == 'main' run: | mkdir ~/.ssh echo "${{ secrets.SSH_PUBLIC_KEY }}" > ~/.ssh/id_ed25519.pub @@ -30,12 +34,12 @@ jobs: chmod 600 ~/.ssh/* ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts - name: Deploy build on server - if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch + if: github.event_name == 'push' && github.ref_name == 'main' run: | rsync --del --no-times --checksum -vrm dist/* ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_DIR }} ssh -t ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "~/prmanifest --inpath ${{ secrets.DESTINATION_DIR }} --outpath ${{ secrets.DESTINATION_DIR }}/manifest.json" - name: Purge Cloudflare Cache - if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch + if: github.event_name == 'push' && github.ref_name == 'main' id: purge-cache uses: NathanVaughn/actions-cloudflare-purge@v3.1.0 with: diff --git a/README.md b/README.md index da10290d51d..866687d54b7 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,12 @@ If you have the motivation and experience with Typescript/Javascript (or are wil 2. Run `npm run start:dev` to locally run the project in `localhost:8000` #### Linting -We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script. +We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script. To view the complete rules, check out the [eslint.config.js](./eslint.config.js) file. + +### 📚 Documentation +You can find the auto-generated documentation [here](https://pagefaultgames.github.io/pokerogue/main/index.html). +For information on enemy AI, check out the [enemy-ai.md](./docs/enemy-ai.md) file. +For detailed guidelines on documenting your code, refer to the [comments.md](./docs/comments.md) file. ### ❔ FAQ diff --git a/create-test-boilerplate.js b/create-test-boilerplate.js index 5f4bbc41198..a365999c623 100644 --- a/create-test-boilerplate.js +++ b/create-test-boilerplate.js @@ -49,7 +49,7 @@ async function promptFileName(selectedType) { { type: "input", name: "userInput", - message: `Please provide a file name for the ${selectedType} test:`, + message: `Please provide the name of the ${selectedType}:`, }, ]); @@ -110,7 +110,7 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("${description}", () => { let phaserGame: Phaser.Game; @@ -129,15 +129,22 @@ describe("${description}", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.SPLASH]) + .moveset([ Moves.SPLASH ]) + .ability(Abilities.BALL_FETCH) .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH); }); - it("test case", async () => { - // await game.classicMode.startBattle([Species.MAGIKARP]); - // game.move.select(Moves.SPLASH); + it("should do X", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("BerryPhase"); + + expect(true).toBe(true); }); }); `; diff --git a/eslint.config.js b/eslint.config.js index 80e9e67b525..2f2b466c66f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,5 @@ import tseslint from '@typescript-eslint/eslint-plugin'; -import stylisticTs from '@stylistic/eslint-plugin-ts' +import stylisticTs from '@stylistic/eslint-plugin-ts'; import parser from '@typescript-eslint/parser'; import importX from 'eslint-plugin-import-x'; @@ -16,15 +16,15 @@ export default [ '@typescript-eslint': tseslint }, rules: { - "eqeqeq": ["error", "always"], // Enforces the use of === and !== instead of == and != - "indent": ["error", 2], // Enforces a 2-space indentation + "eqeqeq": ["error", "always"], // Enforces the use of `===` and `!==` instead of `==` and `!=` + "indent": ["error", 2, { "SwitchCase": 1 }], // Enforces a 2-space indentation, enforces indentation of `case ...:` statements "quotes": ["error", "double"], // Enforces the use of double quotes for strings - "no-var": "error", // Disallows the use of var, enforcing let or const instead - "prefer-const": "error", // Prefers the use of const for variables that are never reassigned + "no-var": "error", // Disallows the use of `var`, enforcing `let` or `const` instead + "prefer-const": "error", // Enforces the use of `const` for variables that are never reassigned "no-undef": "off", // Disables the rule that disallows the use of undeclared variables (TypeScript handles this) "@typescript-eslint/no-unused-vars": [ "error", { "args": "none", // Allows unused function parameters. Useful for functions with specific signatures where not all parameters are always used. - "ignoreRestSiblings": true // Allows unused variables that are part of a rest property in object destructuring. Useful for excluding certain properties from an object while using the rest. + "ignoreRestSiblings": true // Allows unused variables that are part of a rest property in object destructuring. Useful for excluding certain properties from an object while using the others. }], "eol-last": ["error", "always"], // Enforces at least one newline at the end of files "@stylistic/ts/semi": ["error", "always"], // Requires semicolons for TypeScript-specific syntax @@ -32,15 +32,20 @@ export default [ "no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax "brace-style": "off", // Note: you must disable the base rule as it can report incorrect errors "curly": ["error", "all"], // Enforces the use of curly braces for all control statements - "@stylistic/ts/brace-style": ["error", "1tbs"], + "@stylistic/ts/brace-style": ["error", "1tbs"], // Enforces the following brace style: https://eslint.style/rules/js/brace-style#_1tbs "no-trailing-spaces": ["error", { // Disallows trailing whitespace at the end of lines "skipBlankLines": false, // Enforces the rule even on blank lines "ignoreComments": false // Enforces the rule on lines containing comments }], "space-before-blocks": ["error", "always"], // Enforces a space before blocks "keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords - "comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after comma + "comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after commas "import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json + "array-bracket-spacing": ["error", "always", { "objectsInArrays": false, "arraysInArrays": false }], // Enforces consistent spacing inside array brackets + "object-curly-spacing": ["error", "always", { "arraysInObjects": false, "objectsInObjects": false }], // Enforces consistent spacing inside braces of object literals, destructuring assignments, and import/export specifiers + "computed-property-spacing": ["error", "never" ], // Enforces consistent spacing inside computed property brackets + "space-infix-ops": ["error", { "int32Hint": false }], // Enforces spacing around infix operators + "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], // Disallows multiple empty lines } } ] diff --git a/global.d.ts b/global.d.ts new file mode 100644 index 00000000000..f4dfa7d4cb2 --- /dev/null +++ b/global.d.ts @@ -0,0 +1,14 @@ +import type { SetupServerApi } from "msw/node"; + +export {}; + +declare global { + /** + * Only used in testing. + * Can technically be undefined/null but for ease of use we are going to assume it is always defined. + * Used to load i18n files exclusively. + * + * To set up your own server in a test see `game_data.test.ts` + */ + var i18nServer: SetupServerApi; +} diff --git a/package-lock.json b/package-lock.json index f633d427d6d..9e512884922 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,13 @@ { "name": "pokemon-rogue-battle", - "version": "1.0.4", + "version": "1.1.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.0.4", + "version": "1.1.6", + "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", "crypto-js": "^4.2.0", diff --git a/package.json b/package.json index d8d7f5e8db8..f106fb1a773 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.0.4", + "version": "1.1.6", "type": "module", "scripts": { "start": "vite", @@ -20,7 +20,7 @@ "depcruise": "depcruise src", "depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg", "create-test": "node ./create-test-boilerplate.js", - "postinstall": "npx lefthook install && npx lefthook run post-merge" + "postinstall": "npx lefthook install && npx lefthook run post-merge" }, "devDependencies": { "@eslint/js": "^9.3.0", diff --git a/public/audio/cry/718-10-complete.m4a b/public/audio/cry/718-10-complete.m4a new file mode 100644 index 00000000000..94d95360553 Binary files /dev/null and b/public/audio/cry/718-10-complete.m4a differ diff --git a/public/fonts/pokemon-emerald-pro.ttf b/public/fonts/pokemon-emerald-pro.ttf index 509bd1aae86..84e49ebbc40 100644 Binary files a/public/fonts/pokemon-emerald-pro.ttf and b/public/fonts/pokemon-emerald-pro.ttf differ diff --git a/public/images/events/halloween2024-event-de.png b/public/images/events/halloween2024-event-de.png new file mode 100644 index 00000000000..a56053c73cc Binary files /dev/null and b/public/images/events/halloween2024-event-de.png differ diff --git a/public/images/events/halloween2024-event-en.png b/public/images/events/halloween2024-event-en.png new file mode 100644 index 00000000000..3886fa796ae Binary files /dev/null and b/public/images/events/halloween2024-event-en.png differ diff --git a/public/images/events/halloween2024-event-es.png b/public/images/events/halloween2024-event-es.png new file mode 100644 index 00000000000..dc9bac86cd0 Binary files /dev/null and b/public/images/events/halloween2024-event-es.png differ diff --git a/public/images/events/halloween2024-event-fr.png b/public/images/events/halloween2024-event-fr.png new file mode 100644 index 00000000000..21df18c7471 Binary files /dev/null and b/public/images/events/halloween2024-event-fr.png differ diff --git a/public/images/events/halloween2024-event-it.png b/public/images/events/halloween2024-event-it.png new file mode 100644 index 00000000000..ce2316b2ce5 Binary files /dev/null and b/public/images/events/halloween2024-event-it.png differ diff --git a/public/images/events/halloween2024-event-ja.png b/public/images/events/halloween2024-event-ja.png new file mode 100644 index 00000000000..363f3b33b0d Binary files /dev/null and b/public/images/events/halloween2024-event-ja.png differ diff --git a/public/images/events/halloween2024-event-ko.png b/public/images/events/halloween2024-event-ko.png new file mode 100644 index 00000000000..3f52526a296 Binary files /dev/null and b/public/images/events/halloween2024-event-ko.png differ diff --git a/public/images/events/halloween2024-event-pt-BR.png b/public/images/events/halloween2024-event-pt-BR.png new file mode 100644 index 00000000000..764a9c1daa9 Binary files /dev/null and b/public/images/events/halloween2024-event-pt-BR.png differ diff --git a/public/images/events/halloween2024-event-zh-CN.png b/public/images/events/halloween2024-event-zh-CN.png new file mode 100644 index 00000000000..c2096a05d98 Binary files /dev/null and b/public/images/events/halloween2024-event-zh-CN.png differ diff --git a/public/images/items.json b/public/images/items.json index 779823d1293..9d84476a8a0 100644 --- a/public/images/items.json +++ b/public/images/items.json @@ -3353,12 +3353,12 @@ "rotated": false, "trimmed": true, "sourceSize": { - "w": 24, - "h": 23 + "w": 32, + "h": 32 }, "spriteSourceSize": { - "x": 1, - "y": 1, + "x": 5, + "y": 5, "w": 22, "h": 21 }, @@ -3416,12 +3416,12 @@ "rotated": false, "trimmed": true, "sourceSize": { - "w": 24, - "h": 24 + "w": 32, + "h": 32 }, "spriteSourceSize": { - "x": 1, - "y": 2, + "x": 5, + "y": 7, "w": 22, "h": 19 }, @@ -6583,7 +6583,7 @@ } }, { - "filename": "rb", + "filename": "pb_silver", "rotated": false, "trimmed": true, "sourceSize": { @@ -6666,6 +6666,27 @@ "h": 19 } }, + { + "filename": "rb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 254, + "y": 320, + "w": 20, + "h": 20 + } + }, { "filename": "smooth_meteorite", "rotated": false, @@ -6680,27 +6701,6 @@ "w": 20, "h": 20 }, - "frame": { - "x": 254, - "y": 320, - "w": 20, - "h": 20 - } - }, - { - "filename": "strange_ball", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, "frame": { "x": 274, "y": 325, @@ -6709,7 +6709,7 @@ } }, { - "filename": "ub", + "filename": "strange_ball", "rotated": false, "trimmed": true, "sourceSize": { @@ -6751,7 +6751,7 @@ } }, { - "filename": "apicot_berry", + "filename": "ub", "rotated": false, "trimmed": true, "sourceSize": { @@ -6761,13 +6761,13 @@ "spriteSourceSize": { "x": 6, "y": 6, - "w": 19, + "w": 20, "h": 20 }, "frame": { "x": 221, "y": 337, - "w": 19, + "w": 20, "h": 20 } }, @@ -6793,7 +6793,7 @@ } }, { - "filename": "big_mushroom", + "filename": "apicot_berry", "rotated": false, "trimmed": true, "sourceSize": { @@ -6804,13 +6804,13 @@ "x": 6, "y": 6, "w": 19, - "h": 19 + "h": 20 }, "frame": { "x": 343, "y": 287, "w": 19, - "h": 19 + "h": 20 } }, { @@ -6834,6 +6834,27 @@ "h": 20 } }, + { + "filename": "big_mushroom", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 19 + }, + "frame": { + "x": 318, + "y": 306, + "w": 19, + "h": 19 + } + }, { "filename": "hard_stone", "rotated": false, @@ -6849,33 +6870,12 @@ "h": 20 }, "frame": { - "x": 318, - "y": 306, + "x": 314, + "y": 325, "w": 19, "h": 20 } }, - { - "filename": "miracle_seed", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 19, - "h": 19 - }, - "frame": { - "x": 337, - "y": 306, - "w": 19, - "h": 19 - } - }, { "filename": "wl_ability_urge", "rotated": false, @@ -6891,12 +6891,33 @@ "h": 18 }, "frame": { - "x": 314, - "y": 326, + "x": 337, + "y": 307, "w": 20, "h": 18 } }, + { + "filename": "miracle_seed", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 19, + "h": 19 + }, + "frame": { + "x": 333, + "y": 325, + "w": 19, + "h": 19 + } + }, { "filename": "wl_antidote", "rotated": false, @@ -6912,12 +6933,54 @@ "h": 18 }, "frame": { - "x": 356, + "x": 357, "y": 307, "w": 20, "h": 18 } }, + { + "filename": "wl_awakening", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 352, + "y": 325, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_burn_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 241, + "y": 340, + "w": 20, + "h": 18 + } + }, { "filename": "golden_egg", "rotated": false, @@ -6933,33 +6996,12 @@ "h": 20 }, "frame": { - "x": 376, - "y": 307, + "x": 372, + "y": 325, "w": 17, "h": 20 } }, - { - "filename": "wl_awakening", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 393, - "y": 241, - "w": 20, - "h": 18 - } - }, { "filename": "toxic_orb", "rotated": false, @@ -6975,96 +7017,12 @@ "h": 18 }, "frame": { - "x": 413, - "y": 258, + "x": 377, + "y": 307, "w": 18, "h": 18 } }, - { - "filename": "wl_burn_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 393, - "y": 259, - "w": 20, - "h": 18 - } - }, - { - "filename": "ampharosite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 377, - "y": 243, - "w": 16, - "h": 16 - } - }, - { - "filename": "audinite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 377, - "y": 259, - "w": 16, - "h": 16 - } - }, - { - "filename": "relic_gold", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 15, - "h": 11 - }, - "frame": { - "x": 377, - "y": 275, - "w": 15, - "h": 11 - } - }, { "filename": "lucky_egg", "rotated": false, @@ -7080,8 +7038,8 @@ "h": 20 }, "frame": { - "x": 381, - "y": 286, + "x": 389, + "y": 325, "w": 17, "h": 20 } @@ -7101,8 +7059,8 @@ "h": 18 }, "frame": { - "x": 398, - "y": 277, + "x": 352, + "y": 343, "w": 20, "h": 18 } @@ -7122,8 +7080,8 @@ "h": 18 }, "frame": { - "x": 398, - "y": 295, + "x": 372, + "y": 345, "w": 20, "h": 18 } @@ -7143,8 +7101,8 @@ "h": 18 }, "frame": { - "x": 393, - "y": 313, + "x": 392, + "y": 345, "w": 20, "h": 18 } @@ -7164,14 +7122,14 @@ "h": 18 }, "frame": { - "x": 240, - "y": 340, + "x": 378, + "y": 241, "w": 20, "h": 18 } }, { - "filename": "banettite", + "filename": "relic_gold", "rotated": false, "trimmed": true, "sourceSize": { @@ -7179,16 +7137,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 + "x": 9, + "y": 11, + "w": 15, + "h": 11 }, "frame": { - "x": 413, - "y": 313, - "w": 16, - "h": 16 + "x": 398, + "y": 241, + "w": 15, + "h": 11 } }, { @@ -7206,8 +7164,8 @@ "h": 18 }, "frame": { - "x": 202, - "y": 358, + "x": 377, + "y": 259, "w": 20, "h": 18 } @@ -7227,8 +7185,8 @@ "h": 18 }, "frame": { - "x": 201, - "y": 376, + "x": 381, + "y": 277, "w": 20, "h": 18 } @@ -7248,8 +7206,8 @@ "h": 18 }, "frame": { - "x": 201, - "y": 394, + "x": 397, + "y": 259, "w": 20, "h": 18 } @@ -7269,33 +7227,12 @@ "h": 18 }, "frame": { - "x": 201, - "y": 412, + "x": 401, + "y": 277, "w": 20, "h": 18 } }, - { - "filename": "beedrillite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 222, - "y": 357, - "w": 16, - "h": 16 - } - }, { "filename": "wl_ice_heal", "rotated": false, @@ -7311,14 +7248,14 @@ "h": 18 }, "frame": { - "x": 238, - "y": 358, + "x": 395, + "y": 295, "w": 20, "h": 18 } }, { - "filename": "blastoisinite", + "filename": "ampharosite", "rotated": false, "trimmed": true, "sourceSize": { @@ -7332,8 +7269,29 @@ "h": 16 }, "frame": { - "x": 222, - "y": 373, + "x": 415, + "y": 295, + "w": 16, + "h": 16 + } + }, + { + "filename": "audinite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 415, + "y": 311, "w": 16, "h": 16 } @@ -7353,12 +7311,33 @@ "h": 18 }, "frame": { - "x": 221, - "y": 389, + "x": 406, + "y": 327, "w": 20, "h": 18 } }, + { + "filename": "banettite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 412, + "y": 345, + "w": 16, + "h": 16 + } + }, { "filename": "wl_item_urge", "rotated": false, @@ -7375,7 +7354,7 @@ }, "frame": { "x": 221, - "y": 407, + "y": 357, "w": 20, "h": 18 } @@ -7396,7 +7375,7 @@ }, "frame": { "x": 241, - "y": 376, + "y": 358, "w": 20, "h": 18 } @@ -7416,8 +7395,8 @@ "h": 18 }, "frame": { - "x": 241, - "y": 394, + "x": 201, + "y": 360, "w": 20, "h": 18 } @@ -7437,8 +7416,8 @@ "h": 18 }, "frame": { - "x": 241, - "y": 412, + "x": 201, + "y": 378, "w": 20, "h": 18 } @@ -7458,8 +7437,8 @@ "h": 18 }, "frame": { - "x": 258, - "y": 358, + "x": 221, + "y": 375, "w": 20, "h": 18 } @@ -7479,8 +7458,8 @@ "h": 18 }, "frame": { - "x": 261, - "y": 376, + "x": 201, + "y": 396, "w": 20, "h": 18 } @@ -7500,8 +7479,8 @@ "h": 18 }, "frame": { - "x": 261, - "y": 394, + "x": 221, + "y": 393, "w": 20, "h": 18 } @@ -7521,8 +7500,8 @@ "h": 18 }, "frame": { - "x": 261, - "y": 412, + "x": 241, + "y": 376, "w": 20, "h": 18 } @@ -7542,12 +7521,33 @@ "h": 18 }, "frame": { - "x": 278, - "y": 345, + "x": 241, + "y": 394, "w": 20, "h": 18 } }, + { + "filename": "beedrillite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 201, + "y": 414, + "w": 16, + "h": 16 + } + }, { "filename": "wl_super_potion", "rotated": false, @@ -7563,12 +7563,33 @@ "h": 18 }, "frame": { - "x": 298, + "x": 261, "y": 345, "w": 20, "h": 18 } }, + { + "filename": "blastoisinite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 261, + "y": 363, + "w": 16, + "h": 16 + } + }, { "filename": "blazikenite", "rotated": false, @@ -7584,8 +7605,8 @@ "h": 16 }, "frame": { - "x": 318, - "y": 344, + "x": 281, + "y": 345, "w": 16, "h": 16 } @@ -7605,8 +7626,8 @@ "h": 16 }, "frame": { - "x": 334, - "y": 326, + "x": 261, + "y": 379, "w": 16, "h": 16 } @@ -7626,8 +7647,8 @@ "h": 16 }, "frame": { - "x": 334, - "y": 342, + "x": 297, + "y": 345, "w": 16, "h": 16 } @@ -7647,8 +7668,8 @@ "h": 16 }, "frame": { - "x": 350, - "y": 325, + "x": 261, + "y": 395, "w": 16, "h": 16 } @@ -7668,8 +7689,8 @@ "h": 16 }, "frame": { - "x": 350, - "y": 341, + "x": 313, + "y": 345, "w": 16, "h": 16 } @@ -7689,8 +7710,8 @@ "h": 16 }, "frame": { - "x": 366, - "y": 327, + "x": 217, + "y": 414, "w": 16, "h": 16 } @@ -7710,8 +7731,8 @@ "h": 16 }, "frame": { - "x": 366, - "y": 343, + "x": 233, + "y": 412, "w": 16, "h": 16 } @@ -7731,8 +7752,8 @@ "h": 16 }, "frame": { - "x": 382, - "y": 331, + "x": 249, + "y": 412, "w": 16, "h": 16 } @@ -7752,8 +7773,8 @@ "h": 16 }, "frame": { - "x": 398, - "y": 331, + "x": 265, + "y": 411, "w": 16, "h": 16 } @@ -7773,8 +7794,8 @@ "h": 16 }, "frame": { - "x": 414, - "y": 329, + "x": 329, + "y": 345, "w": 16, "h": 16 } @@ -7794,8 +7815,8 @@ "h": 16 }, "frame": { - "x": 382, - "y": 347, + "x": 277, + "y": 363, "w": 16, "h": 16 } @@ -7815,8 +7836,8 @@ "h": 16 }, "frame": { - "x": 398, - "y": 347, + "x": 277, + "y": 379, "w": 16, "h": 16 } @@ -7836,8 +7857,8 @@ "h": 16 }, "frame": { - "x": 414, - "y": 345, + "x": 277, + "y": 395, "w": 16, "h": 16 } @@ -7857,8 +7878,8 @@ "h": 16 }, "frame": { - "x": 281, - "y": 363, + "x": 293, + "y": 361, "w": 16, "h": 16 } @@ -7878,8 +7899,8 @@ "h": 16 }, "frame": { - "x": 281, - "y": 379, + "x": 309, + "y": 361, "w": 16, "h": 16 } @@ -7899,8 +7920,8 @@ "h": 16 }, "frame": { - "x": 297, - "y": 363, + "x": 293, + "y": 377, "w": 16, "h": 16 } @@ -7920,8 +7941,8 @@ "h": 16 }, "frame": { - "x": 281, - "y": 395, + "x": 325, + "y": 361, "w": 16, "h": 16 } @@ -7941,8 +7962,8 @@ "h": 16 }, "frame": { - "x": 297, - "y": 379, + "x": 293, + "y": 393, "w": 16, "h": 16 } @@ -7961,6 +7982,90 @@ "w": 16, "h": 16 }, + "frame": { + "x": 309, + "y": 377, + "w": 16, + "h": 16 + } + }, + { + "filename": "mawilite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 309, + "y": 393, + "w": 16, + "h": 16 + } + }, + { + "filename": "medichamite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 325, + "y": 377, + "w": 16, + "h": 16 + } + }, + { + "filename": "metagrossite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 325, + "y": 393, + "w": 16, + "h": 16 + } + }, + { + "filename": "mewtwonite_x", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, "frame": { "x": 281, "y": 411, @@ -7968,90 +8073,6 @@ "h": 16 } }, - { - "filename": "mawilite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 297, - "y": 395, - "w": 16, - "h": 16 - } - }, - { - "filename": "medichamite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 297, - "y": 411, - "w": 16, - "h": 16 - } - }, - { - "filename": "metagrossite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 313, - "y": 363, - "w": 16, - "h": 16 - } - }, - { - "filename": "mewtwonite_x", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 313, - "y": 379, - "w": 16, - "h": 16 - } - }, { "filename": "mewtwonite_y", "rotated": false, @@ -8067,8 +8088,8 @@ "h": 16 }, "frame": { - "x": 313, - "y": 395, + "x": 297, + "y": 409, "w": 16, "h": 16 } @@ -8089,7 +8110,7 @@ }, "frame": { "x": 313, - "y": 411, + "y": 409, "w": 16, "h": 16 } @@ -8109,8 +8130,8 @@ "h": 16 }, "frame": { - "x": 350, - "y": 357, + "x": 329, + "y": 409, "w": 16, "h": 16 } @@ -8130,8 +8151,8 @@ "h": 16 }, "frame": { - "x": 366, - "y": 359, + "x": 341, + "y": 361, "w": 16, "h": 16 } @@ -8151,8 +8172,8 @@ "h": 16 }, "frame": { - "x": 334, - "y": 358, + "x": 341, + "y": 377, "w": 16, "h": 16 } @@ -8172,8 +8193,8 @@ "h": 16 }, "frame": { - "x": 382, - "y": 363, + "x": 341, + "y": 393, "w": 16, "h": 16 } @@ -8193,8 +8214,8 @@ "h": 16 }, "frame": { - "x": 398, - "y": 363, + "x": 345, + "y": 409, "w": 16, "h": 16 } @@ -8214,7 +8235,7 @@ "h": 16 }, "frame": { - "x": 414, + "x": 412, "y": 361, "w": 16, "h": 16 @@ -8235,8 +8256,8 @@ "h": 16 }, "frame": { - "x": 329, - "y": 374, + "x": 357, + "y": 363, "w": 16, "h": 16 } @@ -8256,8 +8277,8 @@ "h": 16 }, "frame": { - "x": 329, - "y": 390, + "x": 357, + "y": 379, "w": 16, "h": 16 } @@ -8277,8 +8298,8 @@ "h": 16 }, "frame": { - "x": 329, - "y": 406, + "x": 373, + "y": 363, "w": 16, "h": 16 } @@ -8298,8 +8319,8 @@ "h": 16 }, "frame": { - "x": 345, - "y": 374, + "x": 373, + "y": 379, "w": 16, "h": 16 } @@ -8319,8 +8340,8 @@ "h": 16 }, "frame": { - "x": 345, - "y": 390, + "x": 389, + "y": 363, "w": 16, "h": 16 } @@ -8340,8 +8361,8 @@ "h": 16 }, "frame": { - "x": 345, - "y": 406, + "x": 389, + "y": 379, "w": 16, "h": 16 } @@ -8361,8 +8382,8 @@ "h": 16 }, "frame": { - "x": 361, - "y": 375, + "x": 405, + "y": 377, "w": 16, "h": 16 } @@ -8383,7 +8404,7 @@ }, "frame": { "x": 361, - "y": 391, + "y": 395, "w": 16, "h": 16 } @@ -8403,8 +8424,8 @@ "h": 16 }, "frame": { - "x": 361, - "y": 407, + "x": 377, + "y": 395, "w": 16, "h": 16 } @@ -8415,6 +8436,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:934ea4080bad980d4fea720cc771f133:ed564bc47b79b15a763de57045178e88:110e074689c9edd2c54833ce2e4d9270$" + "smartupdate": "$TexturePacker:SmartUpdate:d91a46c431ace3f09f5ca68916a2171e:1e84369d9a13e1416fa58028d629d116:110e074689c9edd2c54833ce2e4d9270$" } } diff --git a/public/images/items.png b/public/images/items.png index 5f032b30cfb..cb4f8fa7d06 100644 Binary files a/public/images/items.png and b/public/images/items.png differ diff --git a/public/images/items/berry_juice.png b/public/images/items/berry_juice.png index c0986b804f9..127fa458906 100644 Binary files a/public/images/items/berry_juice.png and b/public/images/items/berry_juice.png differ diff --git a/public/images/items/black_sludge.png b/public/images/items/black_sludge.png index 39684a40310..37aa31de43e 100644 Binary files a/public/images/items/black_sludge.png and b/public/images/items/black_sludge.png differ diff --git a/public/images/items/pb_silver.png b/public/images/items/pb_silver.png new file mode 100644 index 00000000000..f60a8348a94 Binary files /dev/null and b/public/images/items/pb_silver.png differ diff --git a/public/images/pokemon/1012-counterfeit.png b/public/images/pokemon/1012-counterfeit.png index 2482debd312..32d9c1790c9 100644 Binary files a/public/images/pokemon/1012-counterfeit.png and b/public/images/pokemon/1012-counterfeit.png differ diff --git a/public/images/pokemon/1013-unremarkable.png b/public/images/pokemon/1013-unremarkable.png index a70954685ed..aaf57aa1a02 100644 Binary files a/public/images/pokemon/1013-unremarkable.png and b/public/images/pokemon/1013-unremarkable.png differ diff --git a/public/images/pokemon/154.png b/public/images/pokemon/154.png index 74370115aa6..7547d4c573a 100644 Binary files a/public/images/pokemon/154.png and b/public/images/pokemon/154.png differ diff --git a/public/images/pokemon/172-spiky.png b/public/images/pokemon/172-spiky.png index 2a02c6fb268..f74c6574344 100644 Binary files a/public/images/pokemon/172-spiky.png and b/public/images/pokemon/172-spiky.png differ diff --git a/public/images/pokemon/172.png b/public/images/pokemon/172.png index 435ebbe4c63..9e96ff34936 100644 Binary files a/public/images/pokemon/172.png and b/public/images/pokemon/172.png differ diff --git a/public/images/pokemon/194.png b/public/images/pokemon/194.png index 589c2ae155a..d126190685b 100644 Binary files a/public/images/pokemon/194.png and b/public/images/pokemon/194.png differ diff --git a/public/images/pokemon/198.png b/public/images/pokemon/198.png index 3d6c15f1a1d..5a310216129 100644 Binary files a/public/images/pokemon/198.png and b/public/images/pokemon/198.png differ diff --git a/public/images/pokemon/2026.png b/public/images/pokemon/2026.png index 78c881eb10d..fde7405f65a 100644 Binary files a/public/images/pokemon/2026.png and b/public/images/pokemon/2026.png differ diff --git a/public/images/pokemon/25-beauty-cosplay.png b/public/images/pokemon/25-beauty-cosplay.png index a0c4c5717b2..0db73184c8e 100644 Binary files a/public/images/pokemon/25-beauty-cosplay.png and b/public/images/pokemon/25-beauty-cosplay.png differ diff --git a/public/images/pokemon/25-cool-cosplay.png b/public/images/pokemon/25-cool-cosplay.png index 209509f12fc..123ae257598 100644 Binary files a/public/images/pokemon/25-cool-cosplay.png and b/public/images/pokemon/25-cool-cosplay.png differ diff --git a/public/images/pokemon/25-cosplay.png b/public/images/pokemon/25-cosplay.png index 9a70984cc8b..217ab730cc4 100644 Binary files a/public/images/pokemon/25-cosplay.png and b/public/images/pokemon/25-cosplay.png differ diff --git a/public/images/pokemon/25-cute-cosplay.png b/public/images/pokemon/25-cute-cosplay.png index 5c4adce2304..17fdfd32609 100644 Binary files a/public/images/pokemon/25-cute-cosplay.png and b/public/images/pokemon/25-cute-cosplay.png differ diff --git a/public/images/pokemon/25-gigantamax.png b/public/images/pokemon/25-gigantamax.png index b9f3f037788..e39511341a3 100644 Binary files a/public/images/pokemon/25-gigantamax.png and b/public/images/pokemon/25-gigantamax.png differ diff --git a/public/images/pokemon/25-partner.png b/public/images/pokemon/25-partner.png index 7b1104a3a55..f1cb33f9701 100644 Binary files a/public/images/pokemon/25-partner.png and b/public/images/pokemon/25-partner.png differ diff --git a/public/images/pokemon/25-smart-cosplay.png b/public/images/pokemon/25-smart-cosplay.png index edafa4d2a21..603837dd34f 100644 Binary files a/public/images/pokemon/25-smart-cosplay.png and b/public/images/pokemon/25-smart-cosplay.png differ diff --git a/public/images/pokemon/25-tough-cosplay.png b/public/images/pokemon/25-tough-cosplay.png index ecadee4ff27..380269b87e7 100644 Binary files a/public/images/pokemon/25-tough-cosplay.png and b/public/images/pokemon/25-tough-cosplay.png differ diff --git a/public/images/pokemon/25.png b/public/images/pokemon/25.png index 7b1104a3a55..f1cb33f9701 100644 Binary files a/public/images/pokemon/25.png and b/public/images/pokemon/25.png differ diff --git a/public/images/pokemon/26.png b/public/images/pokemon/26.png index ae0a7aeab62..f2cdf63c718 100644 Binary files a/public/images/pokemon/26.png and b/public/images/pokemon/26.png differ diff --git a/public/images/pokemon/275.png b/public/images/pokemon/275.png index 07a6fe725ad..61f98ed1655 100644 Binary files a/public/images/pokemon/275.png and b/public/images/pokemon/275.png differ diff --git a/public/images/pokemon/276.png b/public/images/pokemon/276.png index 1b24f59d105..a191440497c 100644 Binary files a/public/images/pokemon/276.png and b/public/images/pokemon/276.png differ diff --git a/public/images/pokemon/277.png b/public/images/pokemon/277.png index 3c4475e5fce..2ec0b9b8a9a 100644 Binary files a/public/images/pokemon/277.png and b/public/images/pokemon/277.png differ diff --git a/public/images/pokemon/281.json b/public/images/pokemon/281.json index 8e865cdc935..cb1a43f256f 100644 --- a/public/images/pokemon/281.json +++ b/public/images/pokemon/281.json @@ -399,13 +399,13 @@ "x": 0, "y": 6, "w": 36, - "h": 55 + "h": 54 }, "frame": { "x": 72, "y": 55, "w": 36, - "h": 55 + "h": 54 } }, { @@ -420,13 +420,13 @@ "x": 0, "y": 6, "w": 36, - "h": 55 + "h": 54 }, "frame": { "x": 72, "y": 55, "w": 36, - "h": 55 + "h": 54 } }, { diff --git a/public/images/pokemon/359-mega.png b/public/images/pokemon/359-mega.png index 99e95151b79..9c026d78779 100644 Binary files a/public/images/pokemon/359-mega.png and b/public/images/pokemon/359-mega.png differ diff --git a/public/images/pokemon/359.png b/public/images/pokemon/359.png index bb02f52637e..e5a1d168ad2 100644 Binary files a/public/images/pokemon/359.png and b/public/images/pokemon/359.png differ diff --git a/public/images/pokemon/379.png b/public/images/pokemon/379.png index dd430eb9d70..3a4185ffaf6 100644 Binary files a/public/images/pokemon/379.png and b/public/images/pokemon/379.png differ diff --git a/public/images/pokemon/390.png b/public/images/pokemon/390.png index 7bd6fd2de90..e96b6631c8a 100644 Binary files a/public/images/pokemon/390.png and b/public/images/pokemon/390.png differ diff --git a/public/images/pokemon/391.png b/public/images/pokemon/391.png index 480894c9373..bb6abefada7 100644 Binary files a/public/images/pokemon/391.png and b/public/images/pokemon/391.png differ diff --git a/public/images/pokemon/392.png b/public/images/pokemon/392.png index 5c65d92889b..b65da9eecb4 100644 Binary files a/public/images/pokemon/392.png and b/public/images/pokemon/392.png differ diff --git a/public/images/pokemon/40.png b/public/images/pokemon/40.png index 4d2cc4f1d60..e6b59c51bfe 100644 Binary files a/public/images/pokemon/40.png and b/public/images/pokemon/40.png differ diff --git a/public/images/pokemon/430.png b/public/images/pokemon/430.png index 07aca365e02..5ed0fb19c20 100644 Binary files a/public/images/pokemon/430.png and b/public/images/pokemon/430.png differ diff --git a/public/images/pokemon/436.json b/public/images/pokemon/436.json index dc6c1d23770..6206c5e66cb 100644 --- a/public/images/pokemon/436.json +++ b/public/images/pokemon/436.json @@ -1,2666 +1,1019 @@ -{ - "textures": [ - { - "image": "436.png", - "format": "RGBA8888", - "size": { - "w": 97, - "h": 97 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 1, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 1, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0097.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0098.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0101.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0102.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0105.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0106.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0107.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 17, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0108.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 17, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0111.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0112.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0113.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 15, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0114.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 15, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0115.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0116.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0117.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0118.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0119.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0120.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0121.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0122.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0123.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0124.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0125.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0126.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 32, - "h": 39 - }, - "frame": { - "x": 33, - "y": 0, - "w": 32, - "h": 39 - } - }, - { - "filename": "0096.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 32, - "h": 39 - }, - "frame": { - "x": 33, - "y": 0, - "w": 32, - "h": 39 - } - }, - { - "filename": "0103.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 15, - "y": 9, - "w": 32, - "h": 39 - }, - "frame": { - "x": 65, - "y": 0, - "w": 32, - "h": 39 - } - }, - { - "filename": "0104.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 15, - "y": 9, - "w": 32, - "h": 39 - }, - "frame": { - "x": 65, - "y": 0, - "w": 32, - "h": 39 - } - }, - { - "filename": "0099.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 33, - "h": 38 - }, - "frame": { - "x": 0, - "y": 39, - "w": 33, - "h": 38 - } - }, - { - "filename": "0100.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 33, - "h": 38 - }, - "frame": { - "x": 0, - "y": 39, - "w": 33, - "h": 38 - } - }, - { - "filename": "0109.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 21, - "w": 33, - "h": 38 - }, - "frame": { - "x": 33, - "y": 39, - "w": 33, - "h": 38 - } - }, - { - "filename": "0110.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 21, - "w": 33, - "h": 38 - }, - "frame": { - "x": 33, - "y": 39, - "w": 33, - "h": 38 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:2b46b60048375cd75fb24de5f2dd05a3:de64de523e63943f7f5dc5a59d03e108:0a3bacf3d680738b160c4c8ace3cda59$" - } -} +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0005.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0008.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0009.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0010.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0011.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0012.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0014.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0015.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0018.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0019.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0020.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0021.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0022.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0023.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0024.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0025.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0026.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0027.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0028.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0029.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0030.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0031.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0032.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0033.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0034.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0035.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0036.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0037.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0038.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0039.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0040.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0041.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0042.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0043.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0044.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0045.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0046.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0047.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0048.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0049.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0050.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0051.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0052.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0053.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0054.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0055.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0056.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0057.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0058.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0059.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 6, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0060.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 6, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0061.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0062.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0063.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0064.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0065.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0066.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0067.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0068.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0069.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0070.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0071.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0072.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0073.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0074.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0075.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0076.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0077.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 4, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0078.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 4, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0079.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 3, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0080.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 3, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0081.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 4, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0082.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 4, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0083.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0084.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0085.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0086.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0087.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0088.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0089.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0090.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0091.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0092.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0093.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0094.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0095.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 5, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0096.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 5, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0097.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0098.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0099.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 0, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0100.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 0, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0101.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 5, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0102.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 5, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0103.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0104.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0105.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 15, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0106.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 15, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0107.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 18, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0108.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 18, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0109.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 22, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0110.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 22, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0111.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 19, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0112.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 19, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0113.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0114.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0115.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0116.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0117.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0118.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0119.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0120.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0121.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0122.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0123.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0124.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0125.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0126.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "436.png", + "format": "RGBA8888", + "size": { "w": 31, "h": 37 }, + "scale": "1" + } +} diff --git a/public/images/pokemon/436.png b/public/images/pokemon/436.png index 1ca185baecd..0308cb7303a 100644 Binary files a/public/images/pokemon/436.png and b/public/images/pokemon/436.png differ diff --git a/public/images/pokemon/451.json b/public/images/pokemon/451.json index 3a320a87c61..0e99c96f876 100644 --- a/public/images/pokemon/451.json +++ b/public/images/pokemon/451.json @@ -1,715 +1,2330 @@ -{ "frames": [ - { - "filename": "0001.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0002.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0003.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0004.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0005.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0006.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0007.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0008.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0009.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0010.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0011.png", - "frame": { "x": 68, "y": 0, "w": 64, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 64, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0012.png", - "frame": { "x": 68, "y": 0, "w": 64, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 64, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0013.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0014.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0015.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0016.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0017.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0018.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0019.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0020.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0021.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0022.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0023.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0024.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0025.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0026.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0027.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0028.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0029.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0030.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0031.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0032.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0033.png", - "frame": { "x": 68, "y": 0, "w": 64, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 64, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0034.png", - "frame": { "x": 68, "y": 0, "w": 64, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 64, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0035.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0036.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0037.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0038.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0039.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0040.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0041.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0042.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0043.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0044.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0045.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0046.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0047.png", - "frame": { "x": 232, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0048.png", - "frame": { "x": 232, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0049.png", - "frame": { "x": 117, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0050.png", - "frame": { "x": 117, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0051.png", - "frame": { "x": 117, "y": 42, "w": 60, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 60, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0052.png", - "frame": { "x": 117, "y": 42, "w": 60, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 60, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0053.png", - "frame": { "x": 132, "y": 0, "w": 63, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 63, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0054.png", - "frame": { "x": 132, "y": 0, "w": 63, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 63, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0055.png", - "frame": { "x": 0, "y": 0, "w": 68, "h": 40 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 6, "w": 68, "h": 40 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0056.png", - "frame": { "x": 0, "y": 0, "w": 68, "h": 40 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 6, "w": 68, "h": 40 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0057.png", - "frame": { "x": 195, "y": 0, "w": 63, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 63, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0058.png", - "frame": { "x": 195, "y": 0, "w": 63, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 63, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0059.png", - "frame": { "x": 258, "y": 0, "w": 61, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 61, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0060.png", - "frame": { "x": 258, "y": 0, "w": 61, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 61, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0061.png", - "frame": { "x": 58, "y": 42, "w": 59, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 59, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0062.png", - "frame": { "x": 58, "y": 42, "w": 59, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 59, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0063.png", - "frame": { "x": 0, "y": 40, "w": 58, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 58, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0064.png", - "frame": { "x": 0, "y": 40, "w": 58, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 58, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0065.png", - "frame": { "x": 177, "y": 84, "w": 55, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 55, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0066.png", - "frame": { "x": 177, "y": 84, "w": 55, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 55, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0067.png", - "frame": { "x": 0, "y": 129, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0068.png", - "frame": { "x": 0, "y": 129, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0069.png", - "frame": { "x": 112, "y": 129, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0070.png", - "frame": { "x": 112, "y": 129, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0071.png", - "frame": { "x": 167, "y": 130, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0072.png", - "frame": { "x": 167, "y": 130, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0073.png", - "frame": { "x": 0, "y": 173, "w": 54, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 54, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0074.png", - "frame": { "x": 0, "y": 173, "w": 54, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 54, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0075.png", - "frame": { "x": 54, "y": 177, "w": 52, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 52, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0076.png", - "frame": { "x": 54, "y": 177, "w": 52, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 52, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0077.png", - "frame": { "x": 210, "y": 176, "w": 53, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 2, "w": 53, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0078.png", - "frame": { "x": 210, "y": 176, "w": 53, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 2, "w": 53, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0079.png", - "frame": { "x": 158, "y": 174, "w": 52, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 52, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0080.png", - "frame": { "x": 158, "y": 174, "w": 52, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 52, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0081.png", - "frame": { "x": 222, "y": 131, "w": 53, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 53, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0082.png", - "frame": { "x": 222, "y": 131, "w": 53, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 53, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0083.png", - "frame": { "x": 275, "y": 132, "w": 53, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 53, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0084.png", - "frame": { "x": 275, "y": 132, "w": 53, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 53, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0085.png", - "frame": { "x": 55, "y": 131, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0086.png", - "frame": { "x": 55, "y": 131, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0087.png", - "frame": { "x": 107, "y": 173, "w": 51, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 51, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0088.png", - "frame": { "x": 107, "y": 173, "w": 51, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 51, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - } - ], - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.8.1-x64", - "image": "451.png", - "format": "I8", - "size": { "w": 339, "h": 221 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "451.png", + "format": "RGBA8888", + "size": { + "w": 281, + "h": 281 + }, + "scale": 1, + "frames": [ + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 69, + "h": 41 + }, + "frame": { + "x": 0, + "y": 0, + "w": 69, + "h": 41 + } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 69, + "h": 41 + }, + "frame": { + "x": 0, + "y": 0, + "w": 69, + "h": 41 + } + }, + { + "filename": "0077.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 69, + "h": 41 + }, + "frame": { + "x": 0, + "y": 0, + "w": 69, + "h": 41 + } + }, + { + "filename": "0078.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 69, + "h": 41 + }, + "frame": { + "x": 0, + "y": 0, + "w": 69, + "h": 41 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0054.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0057.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0058.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 66, + "h": 43 + }, + "frame": { + "x": 132, + "y": 0, + "w": 66, + "h": 43 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 66, + "h": 43 + }, + "frame": { + "x": 132, + "y": 0, + "w": 66, + "h": 43 + } + }, + { + "filename": "0055.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 66, + "h": 43 + }, + "frame": { + "x": 132, + "y": 0, + "w": 66, + "h": 43 + } + }, + { + "filename": "0056.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 66, + "h": 43 + }, + "frame": { + "x": 132, + "y": 0, + "w": 66, + "h": 43 + } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 198, + "y": 0, + "w": 65, + "h": 43 + } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 198, + "y": 0, + "w": 65, + "h": 43 + } + }, + { + "filename": "0075.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 198, + "y": 0, + "w": 65, + "h": 43 + } + }, + { + "filename": "0076.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 198, + "y": 0, + "w": 65, + "h": 43 + } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 0, + "y": 41, + "w": 65, + "h": 43 + } + }, + { + "filename": "0036.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 0, + "y": 41, + "w": 65, + "h": 43 + } + }, + { + "filename": "0079.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 0, + "y": 41, + "w": 65, + "h": 43 + } + }, + { + "filename": "0080.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 0, + "y": 41, + "w": 65, + "h": 43 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0059.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0060.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 62, + "h": 44 + }, + "frame": { + "x": 126, + "y": 43, + "w": 62, + "h": 44 + } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 62, + "h": 44 + }, + "frame": { + "x": 126, + "y": 43, + "w": 62, + "h": 44 + } + }, + { + "filename": "0073.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 62, + "h": 44 + }, + "frame": { + "x": 126, + "y": 43, + "w": 62, + "h": 44 + } + }, + { + "filename": "0074.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 62, + "h": 44 + }, + "frame": { + "x": 126, + "y": 43, + "w": 62, + "h": 44 + } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 2, + "w": 63, + "h": 44 + }, + "frame": { + "x": 188, + "y": 43, + "w": 63, + "h": 44 + } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 2, + "w": 63, + "h": 44 + }, + "frame": { + "x": 188, + "y": 43, + "w": 63, + "h": 44 + } + }, + { + "filename": "0081.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 2, + "w": 63, + "h": 44 + }, + "frame": { + "x": 188, + "y": 43, + "w": 63, + "h": 44 + } + }, + { + "filename": "0082.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 2, + "w": 63, + "h": 44 + }, + "frame": { + "x": 188, + "y": 43, + "w": 63, + "h": 44 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0061.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0062.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 59, + "y": 87, + "w": 59, + "h": 45 + } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 59, + "y": 87, + "w": 59, + "h": 45 + } + }, + { + "filename": "0071.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 59, + "y": 87, + "w": 59, + "h": 45 + } + }, + { + "filename": "0072.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 59, + "y": 87, + "w": 59, + "h": 45 + } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 1, + "w": 61, + "h": 45 + }, + "frame": { + "x": 118, + "y": 87, + "w": 61, + "h": 45 + } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 1, + "w": 61, + "h": 45 + }, + "frame": { + "x": 118, + "y": 87, + "w": 61, + "h": 45 + } + }, + { + "filename": "0083.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 1, + "w": 61, + "h": 45 + }, + "frame": { + "x": 118, + "y": 87, + "w": 61, + "h": 45 + } + }, + { + "filename": "0084.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 1, + "w": 61, + "h": 45 + }, + "frame": { + "x": 118, + "y": 87, + "w": 61, + "h": 45 + } + }, + { + "filename": "0089.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 179, + "y": 87, + "w": 57, + "h": 45 + } + }, + { + "filename": "0090.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 179, + "y": 87, + "w": 57, + "h": 45 + } + }, + { + "filename": "0091.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 0, + "y": 129, + "w": 57, + "h": 45 + } + }, + { + "filename": "0092.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 0, + "y": 129, + "w": 57, + "h": 45 + } + }, + { + "filename": "0093.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 57, + "y": 132, + "w": 57, + "h": 45 + } + }, + { + "filename": "0094.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 57, + "y": 132, + "w": 57, + "h": 45 + } + }, + { + "filename": "0095.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 56, + "h": 45 + }, + "frame": { + "x": 114, + "y": 132, + "w": 56, + "h": 45 + } + }, + { + "filename": "0096.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 56, + "h": 45 + }, + "frame": { + "x": 114, + "y": 132, + "w": 56, + "h": 45 + } + }, + { + "filename": "0097.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 54, + "h": 45 + }, + "frame": { + "x": 170, + "y": 132, + "w": 54, + "h": 45 + } + }, + { + "filename": "0098.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 54, + "h": 45 + }, + "frame": { + "x": 170, + "y": 132, + "w": 54, + "h": 45 + } + }, + { + "filename": "0099.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 0, + "y": 1, + "w": 54, + "h": 45 + }, + "frame": { + "x": 224, + "y": 132, + "w": 54, + "h": 45 + } + }, + { + "filename": "0100.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 0, + "y": 1, + "w": 54, + "h": 45 + }, + "frame": { + "x": 224, + "y": 132, + "w": 54, + "h": 45 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0065.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0066.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0067.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0068.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0063.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0064.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 111, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 111, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0069.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 111, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0070.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 111, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 60, + "h": 46 + }, + "frame": { + "x": 168, + "y": 177, + "w": 60, + "h": 46 + } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 60, + "h": 46 + }, + "frame": { + "x": 168, + "y": 177, + "w": 60, + "h": 46 + } + }, + { + "filename": "0085.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 60, + "h": 46 + }, + "frame": { + "x": 168, + "y": 177, + "w": 60, + "h": 46 + } + }, + { + "filename": "0086.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 60, + "h": 46 + }, + "frame": { + "x": 168, + "y": 177, + "w": 60, + "h": 46 + } + }, + { + "filename": "0109.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 53, + "h": 46 + }, + "frame": { + "x": 228, + "y": 177, + "w": 53, + "h": 46 + } + }, + { + "filename": "0110.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 53, + "h": 46 + }, + "frame": { + "x": 228, + "y": 177, + "w": 53, + "h": 46 + } + }, + { + "filename": "0101.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 220, + "w": 54, + "h": 46 + } + }, + { + "filename": "0102.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 220, + "w": 54, + "h": 46 + } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 223, + "w": 57, + "h": 46 + } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 223, + "w": 57, + "h": 46 + } + }, + { + "filename": "0087.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 223, + "w": 57, + "h": 46 + } + }, + { + "filename": "0088.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 223, + "w": 57, + "h": 46 + } + }, + { + "filename": "0103.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 111, + "y": 223, + "w": 55, + "h": 46 + } + }, + { + "filename": "0104.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 111, + "y": 223, + "w": 55, + "h": 46 + } + }, + { + "filename": "0105.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 166, + "y": 223, + "w": 55, + "h": 46 + } + }, + { + "filename": "0106.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 166, + "y": 223, + "w": 55, + "h": 46 + } + }, + { + "filename": "0107.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 221, + "y": 223, + "w": 54, + "h": 46 + } + }, + { + "filename": "0108.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 221, + "y": 223, + "w": 54, + "h": 46 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:e303c68c1876b77078f3e1fd4372a4ce:84139d6b94cea0f3c45dbd8fa7109c3d:c79e17c206de27e3b7f1ce96f7df8e51$" + } } diff --git a/public/images/pokemon/451.png b/public/images/pokemon/451.png index 716e8a08041..fac8f5a0170 100644 Binary files a/public/images/pokemon/451.png and b/public/images/pokemon/451.png differ diff --git a/public/images/pokemon/455.png b/public/images/pokemon/455.png index 9518bc019fe..731abfec4e6 100644 Binary files a/public/images/pokemon/455.png and b/public/images/pokemon/455.png differ diff --git a/public/images/pokemon/486.png b/public/images/pokemon/486.png index aaee1287a47..328ed80c995 100644 Binary files a/public/images/pokemon/486.png and b/public/images/pokemon/486.png differ diff --git a/public/images/pokemon/501.png b/public/images/pokemon/501.png index ac4c5d9fbf0..79a012cadd5 100644 Binary files a/public/images/pokemon/501.png and b/public/images/pokemon/501.png differ diff --git a/public/images/pokemon/502.png b/public/images/pokemon/502.png index 8a7c2636894..ef1291a2520 100644 Binary files a/public/images/pokemon/502.png and b/public/images/pokemon/502.png differ diff --git a/public/images/pokemon/503.png b/public/images/pokemon/503.png index d9cf94f3c6f..3571e64156c 100644 Binary files a/public/images/pokemon/503.png and b/public/images/pokemon/503.png differ diff --git a/public/images/pokemon/528.png b/public/images/pokemon/528.png index d1806f17f70..fd6e0c54a77 100644 Binary files a/public/images/pokemon/528.png and b/public/images/pokemon/528.png differ diff --git a/public/images/pokemon/587.png b/public/images/pokemon/587.png index 409b423c13b..6a870170219 100644 Binary files a/public/images/pokemon/587.png and b/public/images/pokemon/587.png differ diff --git a/public/images/pokemon/590.png b/public/images/pokemon/590.png index 2cf97f1fe69..0908b46cd83 100644 Binary files a/public/images/pokemon/590.png and b/public/images/pokemon/590.png differ diff --git a/public/images/pokemon/591.png b/public/images/pokemon/591.png index 179e3b4160f..a294749149f 100644 Binary files a/public/images/pokemon/591.png and b/public/images/pokemon/591.png differ diff --git a/public/images/pokemon/616.png b/public/images/pokemon/616.png index 5d4e04e31fd..aff43388faf 100644 Binary files a/public/images/pokemon/616.png and b/public/images/pokemon/616.png differ diff --git a/public/images/pokemon/6503.png b/public/images/pokemon/6503.png index 906fcb9115b..71d6e27d855 100644 Binary files a/public/images/pokemon/6503.png and b/public/images/pokemon/6503.png differ diff --git a/public/images/pokemon/656.png b/public/images/pokemon/656.png index 1f0f181712b..b653616955d 100644 Binary files a/public/images/pokemon/656.png and b/public/images/pokemon/656.png differ diff --git a/public/images/pokemon/657.png b/public/images/pokemon/657.png index 8c0f2b9a15f..031c9404805 100644 Binary files a/public/images/pokemon/657.png and b/public/images/pokemon/657.png differ diff --git a/public/images/pokemon/658-ash.json b/public/images/pokemon/658-ash.json index 8fbe19f5ccb..c2b8eede9ef 100644 --- a/public/images/pokemon/658-ash.json +++ b/public/images/pokemon/658-ash.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "658-ash.png", - "format": "RGBA8888", - "size": { - "w": 79, - "h": 79 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 79, - "h": 74 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 0, - "w": 79, - "h": 74 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:936f62fa49ba4d6e402bb2e2eaf2afd0:ed00ba047a44b4bf1309bc147dd000e3:bfbf521a5c7bd80bcd95a96d9789c0dd$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 79, "h": 74 }, + "scale": "1" + } } diff --git a/public/images/pokemon/658-ash.png b/public/images/pokemon/658-ash.png index 8daaaa02063..a122df859bd 100644 Binary files a/public/images/pokemon/658-ash.png and b/public/images/pokemon/658-ash.png differ diff --git a/public/images/pokemon/658.json b/public/images/pokemon/658.json index 4fd918e0f50..219645ec240 100644 --- a/public/images/pokemon/658.json +++ b/public/images/pokemon/658.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "658.png", - "format": "RGBA8888", - "size": { - "w": 75, - "h": 75 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 65 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 65 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 65 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:e0b10df331bd4ce6760edab61dee144b:061561c45beff89a92bf0158d065204f:5affcab976148657d36bf4ff3410f92d$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 85, "h": 67 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 85, "h": 67 }, + "sourceSize": { "w": 85, "h": 67 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 85, "h": 67 }, + "scale": "1" + } } diff --git a/public/images/pokemon/658.png b/public/images/pokemon/658.png index 095b8c0039d..ed730c8b81c 100644 Binary files a/public/images/pokemon/658.png and b/public/images/pokemon/658.png differ diff --git a/public/images/pokemon/6706.png b/public/images/pokemon/6706.png index 44f627acd10..e967b550871 100644 Binary files a/public/images/pokemon/6706.png and b/public/images/pokemon/6706.png differ diff --git a/public/images/pokemon/676-dandy.png b/public/images/pokemon/676-dandy.png index 1e9f9b7bb2c..54e36574b2a 100644 Binary files a/public/images/pokemon/676-dandy.png and b/public/images/pokemon/676-dandy.png differ diff --git a/public/images/pokemon/676-debutante.png b/public/images/pokemon/676-debutante.png index 92390b17f34..30d5bcafec5 100644 Binary files a/public/images/pokemon/676-debutante.png and b/public/images/pokemon/676-debutante.png differ diff --git a/public/images/pokemon/676-diamond.png b/public/images/pokemon/676-diamond.png index 3915b78ec26..953581d7bb7 100644 Binary files a/public/images/pokemon/676-diamond.png and b/public/images/pokemon/676-diamond.png differ diff --git a/public/images/pokemon/676-heart.png b/public/images/pokemon/676-heart.png index 99327208605..9e6950cc36c 100644 Binary files a/public/images/pokemon/676-heart.png and b/public/images/pokemon/676-heart.png differ diff --git a/public/images/pokemon/676-kabuki.png b/public/images/pokemon/676-kabuki.png index c4f6473c75b..0d7323a520c 100644 Binary files a/public/images/pokemon/676-kabuki.png and b/public/images/pokemon/676-kabuki.png differ diff --git a/public/images/pokemon/676-la-reine.png b/public/images/pokemon/676-la-reine.png index e649e6d74c8..c2f0eb72d75 100644 Binary files a/public/images/pokemon/676-la-reine.png and b/public/images/pokemon/676-la-reine.png differ diff --git a/public/images/pokemon/676-matron.png b/public/images/pokemon/676-matron.png index 98142c41661..1f93b11a277 100644 Binary files a/public/images/pokemon/676-matron.png and b/public/images/pokemon/676-matron.png differ diff --git a/public/images/pokemon/676-pharaoh.png b/public/images/pokemon/676-pharaoh.png index cced072318b..e0f48c46bab 100644 Binary files a/public/images/pokemon/676-pharaoh.png and b/public/images/pokemon/676-pharaoh.png differ diff --git a/public/images/pokemon/676-star.png b/public/images/pokemon/676-star.png index 7a1044bda75..566aa713aee 100644 Binary files a/public/images/pokemon/676-star.png and b/public/images/pokemon/676-star.png differ diff --git a/public/images/pokemon/682.png b/public/images/pokemon/682.png index 41ecd482b14..2a83ceedaa9 100644 Binary files a/public/images/pokemon/682.png and b/public/images/pokemon/682.png differ diff --git a/public/images/pokemon/683.png b/public/images/pokemon/683.png index bf559a07929..1b16b038c51 100644 Binary files a/public/images/pokemon/683.png and b/public/images/pokemon/683.png differ diff --git a/public/images/pokemon/684.png b/public/images/pokemon/684.png index 8bf8f765465..a3f7e544f89 100644 Binary files a/public/images/pokemon/684.png and b/public/images/pokemon/684.png differ diff --git a/public/images/pokemon/685.png b/public/images/pokemon/685.png index 521b7560182..957cd5d815b 100644 Binary files a/public/images/pokemon/685.png and b/public/images/pokemon/685.png differ diff --git a/public/images/pokemon/688.json b/public/images/pokemon/688.json index 84ec62d4211..3d9aa902a54 100644 --- a/public/images/pokemon/688.json +++ b/public/images/pokemon/688.json @@ -1,41 +1,18 @@ -{ - "textures": [ - { - "image": "688.png", - "format": "RGBA8888", - "size": { - "w": 52, - "h": 52 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 41, - "h": 52 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 52 - }, - "frame": { - "x": 0, - "y": 0, - "w": 41, - "h": 52 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:f328f72c414efc6cf463a1254afa75ac:50168e1a7077626f41bdaf5d0b35af74:176060351d0044923af938ba7932a6ef$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 64, "h": 63 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 63 }, + "sourceSize": { "w": 64, "h": 63 } + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 64, "h": 63 }, + "scale": "1" + } } diff --git a/public/images/pokemon/688.png b/public/images/pokemon/688.png index 2ac1b5d5fb1..2e65d4beb6f 100644 Binary files a/public/images/pokemon/688.png and b/public/images/pokemon/688.png differ diff --git a/public/images/pokemon/689.json b/public/images/pokemon/689.json index 2ff881f55c0..488ef54de71 100644 --- a/public/images/pokemon/689.json +++ b/public/images/pokemon/689.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "689.png", - "format": "RGBA8888", - "size": { - "w": 86, - "h": 86 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 86, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 86, - "h": 79 - }, - "frame": { - "x": 0, - "y": 0, - "w": 86, - "h": 79 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:1825183d2cc847c000400501e055918b:af535bb92b1490f3ab69be674b3b6fe0:bd0c58ecddcb4af9a0c6e7b39821d971$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 82 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 82 }, + "sourceSize": { "w": 79, "h": 82 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 79, "h": 82 }, + "scale": "1" + } } diff --git a/public/images/pokemon/689.png b/public/images/pokemon/689.png index 75fa0b474d7..1ec1bcec98a 100644 Binary files a/public/images/pokemon/689.png and b/public/images/pokemon/689.png differ diff --git a/public/images/pokemon/894.png b/public/images/pokemon/894.png index ea82d8bd82e..5f5b0535e8a 100644 Binary files a/public/images/pokemon/894.png and b/public/images/pokemon/894.png differ diff --git a/public/images/pokemon/945.png b/public/images/pokemon/945.png index 280ad17b152..74c43b6d32e 100644 Binary files a/public/images/pokemon/945.png and b/public/images/pokemon/945.png differ diff --git a/public/images/pokemon/back/1012-counterfeit.png b/public/images/pokemon/back/1012-counterfeit.png index 8ab1941187d..e6deb02c70c 100644 Binary files a/public/images/pokemon/back/1012-counterfeit.png and b/public/images/pokemon/back/1012-counterfeit.png differ diff --git a/public/images/pokemon/back/1013-unremarkable.png b/public/images/pokemon/back/1013-unremarkable.png index b8532d049fc..479f0e51cff 100644 Binary files a/public/images/pokemon/back/1013-unremarkable.png and b/public/images/pokemon/back/1013-unremarkable.png differ diff --git a/public/images/pokemon/back/172-spiky.png b/public/images/pokemon/back/172-spiky.png index 37b2d401f17..d038e0d3661 100644 Binary files a/public/images/pokemon/back/172-spiky.png and b/public/images/pokemon/back/172-spiky.png differ diff --git a/public/images/pokemon/back/172.png b/public/images/pokemon/back/172.png index 9f4c8f4f1bd..775a42dd948 100644 Binary files a/public/images/pokemon/back/172.png and b/public/images/pokemon/back/172.png differ diff --git a/public/images/pokemon/back/198.png b/public/images/pokemon/back/198.png index dbae4ffdfed..dc92c8b1d59 100644 Binary files a/public/images/pokemon/back/198.png and b/public/images/pokemon/back/198.png differ diff --git a/public/images/pokemon/back/2026.png b/public/images/pokemon/back/2026.png index 4e1e16c6207..1f0411ffcd8 100644 Binary files a/public/images/pokemon/back/2026.png and b/public/images/pokemon/back/2026.png differ diff --git a/public/images/pokemon/back/25-beauty-cosplay.png b/public/images/pokemon/back/25-beauty-cosplay.png index 30c51863f9f..8a57b642aa7 100644 Binary files a/public/images/pokemon/back/25-beauty-cosplay.png and b/public/images/pokemon/back/25-beauty-cosplay.png differ diff --git a/public/images/pokemon/back/25-cool-cosplay.png b/public/images/pokemon/back/25-cool-cosplay.png index fe8e67a27cd..1c9528eb350 100644 Binary files a/public/images/pokemon/back/25-cool-cosplay.png and b/public/images/pokemon/back/25-cool-cosplay.png differ diff --git a/public/images/pokemon/back/25-cosplay.png b/public/images/pokemon/back/25-cosplay.png index 54c1dca4925..38e573f5784 100644 Binary files a/public/images/pokemon/back/25-cosplay.png and b/public/images/pokemon/back/25-cosplay.png differ diff --git a/public/images/pokemon/back/25-cute-cosplay.png b/public/images/pokemon/back/25-cute-cosplay.png index 9436bad0863..64b180067d5 100644 Binary files a/public/images/pokemon/back/25-cute-cosplay.png and b/public/images/pokemon/back/25-cute-cosplay.png differ diff --git a/public/images/pokemon/back/25-gigantamax.png b/public/images/pokemon/back/25-gigantamax.png index 70bf85129da..c80b3d5d486 100644 Binary files a/public/images/pokemon/back/25-gigantamax.png and b/public/images/pokemon/back/25-gigantamax.png differ diff --git a/public/images/pokemon/back/25-partner.png b/public/images/pokemon/back/25-partner.png index 8085a963e28..ae6133aefff 100644 Binary files a/public/images/pokemon/back/25-partner.png and b/public/images/pokemon/back/25-partner.png differ diff --git a/public/images/pokemon/back/25-smart-cosplay.png b/public/images/pokemon/back/25-smart-cosplay.png index 81a6d938154..6f23b7f4df0 100644 Binary files a/public/images/pokemon/back/25-smart-cosplay.png and b/public/images/pokemon/back/25-smart-cosplay.png differ diff --git a/public/images/pokemon/back/25-tough-cosplay.png b/public/images/pokemon/back/25-tough-cosplay.png index e70757866a5..cfc9392efe8 100644 Binary files a/public/images/pokemon/back/25-tough-cosplay.png and b/public/images/pokemon/back/25-tough-cosplay.png differ diff --git a/public/images/pokemon/back/25.png b/public/images/pokemon/back/25.png index 8085a963e28..ae6133aefff 100644 Binary files a/public/images/pokemon/back/25.png and b/public/images/pokemon/back/25.png differ diff --git a/public/images/pokemon/back/26.png b/public/images/pokemon/back/26.png index 21b3a5fa9c1..454c581edae 100644 Binary files a/public/images/pokemon/back/26.png and b/public/images/pokemon/back/26.png differ diff --git a/public/images/pokemon/back/276.png b/public/images/pokemon/back/276.png index 64c4a4d22ee..fef264f004e 100644 Binary files a/public/images/pokemon/back/276.png and b/public/images/pokemon/back/276.png differ diff --git a/public/images/pokemon/back/277.png b/public/images/pokemon/back/277.png index 0e173bc54fb..ced72a75a73 100644 Binary files a/public/images/pokemon/back/277.png and b/public/images/pokemon/back/277.png differ diff --git a/public/images/pokemon/back/379.png b/public/images/pokemon/back/379.png index 586a19a5916..b4f282d5989 100644 Binary files a/public/images/pokemon/back/379.png and b/public/images/pokemon/back/379.png differ diff --git a/public/images/pokemon/back/390.png b/public/images/pokemon/back/390.png index 65b5595cfbe..d6dcc990c48 100644 Binary files a/public/images/pokemon/back/390.png and b/public/images/pokemon/back/390.png differ diff --git a/public/images/pokemon/back/391.png b/public/images/pokemon/back/391.png index e89d79720ab..9b41cd2bd89 100644 Binary files a/public/images/pokemon/back/391.png and b/public/images/pokemon/back/391.png differ diff --git a/public/images/pokemon/back/392.png b/public/images/pokemon/back/392.png index e15396669ce..2e7466294da 100644 Binary files a/public/images/pokemon/back/392.png and b/public/images/pokemon/back/392.png differ diff --git a/public/images/pokemon/back/430.png b/public/images/pokemon/back/430.png index 6c0fc8a5166..383685fa816 100644 Binary files a/public/images/pokemon/back/430.png and b/public/images/pokemon/back/430.png differ diff --git a/public/images/pokemon/back/436.json b/public/images/pokemon/back/436.json index 78014a69936..3342cc6577c 100644 --- a/public/images/pokemon/back/436.json +++ b/public/images/pokemon/back/436.json @@ -1,2666 +1,1019 @@ -{ - "textures": [ - { - "image": "436.png", - "format": "RGBA8888", - "size": { - "w": 100, - "h": 100 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0097.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 0, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0098.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 0, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0101.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0102.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0105.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 1, - "y": 14, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0106.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 1, - "y": 14, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0107.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 17, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0108.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 17, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0111.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 18, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0112.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 18, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0113.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 15, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0114.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 15, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0115.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0116.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0117.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0118.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0119.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0120.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0121.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0122.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0123.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0124.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0125.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0126.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 15, - "y": 4, - "w": 33, - "h": 40 - }, - "frame": { - "x": 34, - "y": 0, - "w": 33, - "h": 40 - } - }, - { - "filename": "0096.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 15, - "y": 4, - "w": 33, - "h": 40 - }, - "frame": { - "x": 34, - "y": 0, - "w": 33, - "h": 40 - } - }, - { - "filename": "0103.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 0, - "y": 9, - "w": 33, - "h": 40 - }, - "frame": { - "x": 67, - "y": 0, - "w": 33, - "h": 40 - } - }, - { - "filename": "0104.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 0, - "y": 9, - "w": 33, - "h": 40 - }, - "frame": { - "x": 67, - "y": 0, - "w": 33, - "h": 40 - } - }, - { - "filename": "0099.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 34, - "h": 39 - }, - "frame": { - "x": 0, - "y": 40, - "w": 34, - "h": 39 - } - }, - { - "filename": "0100.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 34, - "h": 39 - }, - "frame": { - "x": 0, - "y": 40, - "w": 34, - "h": 39 - } - }, - { - "filename": "0109.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 21, - "w": 34, - "h": 39 - }, - "frame": { - "x": 34, - "y": 40, - "w": 34, - "h": 39 - } - }, - { - "filename": "0110.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 21, - "w": 34, - "h": 39 - }, - "frame": { - "x": 34, - "y": 40, - "w": 34, - "h": 39 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:6e466fdd2b62b8024ea52be04133391d:67fd60bf8d57184b168ae25f93bafcc2:0a3bacf3d680738b160c4c8ace3cda59$" - } -} +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0005.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0008.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0009.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0010.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0011.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0012.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0014.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0015.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0018.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0019.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0020.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0021.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0022.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0023.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0024.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0025.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0026.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0027.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0028.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0029.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0030.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0031.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0032.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0033.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0034.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0035.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0036.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0037.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0038.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0039.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0040.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0041.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0042.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0043.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0044.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0045.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0046.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0047.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0048.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0049.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0050.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0051.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0052.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0053.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0054.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0055.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0056.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0057.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0058.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0059.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 6, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0060.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 6, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0061.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0062.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0063.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0064.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0065.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0066.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0067.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0068.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0069.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0070.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0071.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0072.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0073.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0074.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0075.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0076.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0077.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 4, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0078.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 4, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0079.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 3, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0080.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 3, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0081.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 4, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0082.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 4, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0083.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0084.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0085.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0086.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0087.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0088.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0089.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0090.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0091.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0092.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0093.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0094.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0095.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 5, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0096.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 5, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0097.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 1, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0098.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 1, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0099.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 0, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0100.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 0, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0101.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 5, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0102.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 5, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0103.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0104.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0105.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 15, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0106.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 15, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0107.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 18, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0108.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 18, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0109.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 22, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0110.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 22, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0111.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 19, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0112.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 19, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0113.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0114.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0115.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0116.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0117.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0118.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0119.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0120.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0121.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0122.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0123.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0124.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0125.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0126.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "436.png", + "format": "I8", + "size": { "w": 32, "h": 38 }, + "scale": "1" + } +} diff --git a/public/images/pokemon/back/436.png b/public/images/pokemon/back/436.png index de9a217f0cf..5d08304bff1 100644 Binary files a/public/images/pokemon/back/436.png and b/public/images/pokemon/back/436.png differ diff --git a/public/images/pokemon/back/455.png b/public/images/pokemon/back/455.png index 116faf6f090..2191905e2ce 100644 Binary files a/public/images/pokemon/back/455.png and b/public/images/pokemon/back/455.png differ diff --git a/public/images/pokemon/back/486.png b/public/images/pokemon/back/486.png index 041b03e5790..4df438f6320 100644 Binary files a/public/images/pokemon/back/486.png and b/public/images/pokemon/back/486.png differ diff --git a/public/images/pokemon/back/502.png b/public/images/pokemon/back/502.png index 4857186bd7e..5225cb803e0 100644 Binary files a/public/images/pokemon/back/502.png and b/public/images/pokemon/back/502.png differ diff --git a/public/images/pokemon/back/503.png b/public/images/pokemon/back/503.png index 96a901b2bdc..8b38780da27 100644 Binary files a/public/images/pokemon/back/503.png and b/public/images/pokemon/back/503.png differ diff --git a/public/images/pokemon/back/527.png b/public/images/pokemon/back/527.png index 61eab42c767..ce061ffe60a 100644 Binary files a/public/images/pokemon/back/527.png and b/public/images/pokemon/back/527.png differ diff --git a/public/images/pokemon/back/528.png b/public/images/pokemon/back/528.png index 1b7733cd4db..81fc8414dd8 100644 Binary files a/public/images/pokemon/back/528.png and b/public/images/pokemon/back/528.png differ diff --git a/public/images/pokemon/back/587.png b/public/images/pokemon/back/587.png index e7304b754ce..8932c1f480a 100644 Binary files a/public/images/pokemon/back/587.png and b/public/images/pokemon/back/587.png differ diff --git a/public/images/pokemon/back/590.png b/public/images/pokemon/back/590.png index 9874d4e216d..6e7685b2ced 100644 Binary files a/public/images/pokemon/back/590.png and b/public/images/pokemon/back/590.png differ diff --git a/public/images/pokemon/back/591.png b/public/images/pokemon/back/591.png index af87fdf527e..2f2d9f34f08 100644 Binary files a/public/images/pokemon/back/591.png and b/public/images/pokemon/back/591.png differ diff --git a/public/images/pokemon/back/616.png b/public/images/pokemon/back/616.png index 751eaf485da..7033e50a0dd 100644 Binary files a/public/images/pokemon/back/616.png and b/public/images/pokemon/back/616.png differ diff --git a/public/images/pokemon/back/6503.png b/public/images/pokemon/back/6503.png index 3953d5d6c66..c88de28046e 100644 Binary files a/public/images/pokemon/back/6503.png and b/public/images/pokemon/back/6503.png differ diff --git a/public/images/pokemon/back/656.png b/public/images/pokemon/back/656.png index 5f6ce42c63b..62362337762 100644 Binary files a/public/images/pokemon/back/656.png and b/public/images/pokemon/back/656.png differ diff --git a/public/images/pokemon/back/657.png b/public/images/pokemon/back/657.png index c7655a643b2..1e61b595e49 100644 Binary files a/public/images/pokemon/back/657.png and b/public/images/pokemon/back/657.png differ diff --git a/public/images/pokemon/back/658-ash.json b/public/images/pokemon/back/658-ash.json index 4ddab1765b2..51a722070b3 100644 --- a/public/images/pokemon/back/658-ash.json +++ b/public/images/pokemon/back/658-ash.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "658-ash.png", - "format": "RGBA8888", - "size": { - "w": 73, - "h": 73 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 73, - "h": 69 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 73, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 73, - "h": 69 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4f38801bb3afeda5faff04bdcf6a666f:0c78ce2715e7510bf55da0a92b42661c:bfbf521a5c7bd80bcd95a96d9789c0dd$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 73, "h": 73 }, + "scale": "1" + } } diff --git a/public/images/pokemon/back/658-ash.png b/public/images/pokemon/back/658-ash.png index e574e888fac..382b06fd6cb 100644 Binary files a/public/images/pokemon/back/658-ash.png and b/public/images/pokemon/back/658-ash.png differ diff --git a/public/images/pokemon/back/658.json b/public/images/pokemon/back/658.json index 119002876a6..050b63e3592 100644 --- a/public/images/pokemon/back/658.json +++ b/public/images/pokemon/back/658.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "658.png", - "format": "RGBA8888", - "size": { - "w": 77, - "h": 77 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 77, - "h": 65 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 77, - "h": 65 - }, - "frame": { - "x": 0, - "y": 0, - "w": 77, - "h": 65 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:acdb9925f3f23b947504eec7cc28c92d:1a13d9d418f6c107bb9e5d621d9154bb:5affcab976148657d36bf4ff3410f92d$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 77, "h": 77 }, + "scale": "1" + } } diff --git a/public/images/pokemon/back/658.png b/public/images/pokemon/back/658.png index a8128e1c73f..ea24d9a6336 100644 Binary files a/public/images/pokemon/back/658.png and b/public/images/pokemon/back/658.png differ diff --git a/public/images/pokemon/back/6706.png b/public/images/pokemon/back/6706.png index e7620078a5b..82c64e98535 100644 Binary files a/public/images/pokemon/back/6706.png and b/public/images/pokemon/back/6706.png differ diff --git a/public/images/pokemon/back/676-dandy.png b/public/images/pokemon/back/676-dandy.png index f8052549668..8a4f26e17b2 100644 Binary files a/public/images/pokemon/back/676-dandy.png and b/public/images/pokemon/back/676-dandy.png differ diff --git a/public/images/pokemon/back/676-debutante.png b/public/images/pokemon/back/676-debutante.png index 507ea4addbe..bed3f323a6b 100644 Binary files a/public/images/pokemon/back/676-debutante.png and b/public/images/pokemon/back/676-debutante.png differ diff --git a/public/images/pokemon/back/676-diamond.png b/public/images/pokemon/back/676-diamond.png index 9498e4e75be..436d9b6dbde 100644 Binary files a/public/images/pokemon/back/676-diamond.png and b/public/images/pokemon/back/676-diamond.png differ diff --git a/public/images/pokemon/back/676-heart.png b/public/images/pokemon/back/676-heart.png index 49c83c6c113..57d472c3834 100644 Binary files a/public/images/pokemon/back/676-heart.png and b/public/images/pokemon/back/676-heart.png differ diff --git a/public/images/pokemon/back/676-kabuki.png b/public/images/pokemon/back/676-kabuki.png index 2aa6fccce61..d602c607643 100644 Binary files a/public/images/pokemon/back/676-kabuki.png and b/public/images/pokemon/back/676-kabuki.png differ diff --git a/public/images/pokemon/back/676-la-reine.png b/public/images/pokemon/back/676-la-reine.png index 2147e5cab01..de1b1a15b90 100644 Binary files a/public/images/pokemon/back/676-la-reine.png and b/public/images/pokemon/back/676-la-reine.png differ diff --git a/public/images/pokemon/back/676-matron.png b/public/images/pokemon/back/676-matron.png index 38092e4fefe..e01a8f273af 100644 Binary files a/public/images/pokemon/back/676-matron.png and b/public/images/pokemon/back/676-matron.png differ diff --git a/public/images/pokemon/back/676-pharaoh.png b/public/images/pokemon/back/676-pharaoh.png index a7ca046406f..13952c58c68 100644 Binary files a/public/images/pokemon/back/676-pharaoh.png and b/public/images/pokemon/back/676-pharaoh.png differ diff --git a/public/images/pokemon/back/676-star.png b/public/images/pokemon/back/676-star.png index 9b082488381..5b188f33498 100644 Binary files a/public/images/pokemon/back/676-star.png and b/public/images/pokemon/back/676-star.png differ diff --git a/public/images/pokemon/back/682.png b/public/images/pokemon/back/682.png index a801a3be1d4..60f869b2f2c 100644 Binary files a/public/images/pokemon/back/682.png and b/public/images/pokemon/back/682.png differ diff --git a/public/images/pokemon/back/683.png b/public/images/pokemon/back/683.png index 2183bc34796..38247067a25 100644 Binary files a/public/images/pokemon/back/683.png and b/public/images/pokemon/back/683.png differ diff --git a/public/images/pokemon/back/684.png b/public/images/pokemon/back/684.png index 1ba17e86bac..3f02f312123 100644 Binary files a/public/images/pokemon/back/684.png and b/public/images/pokemon/back/684.png differ diff --git a/public/images/pokemon/back/685.png b/public/images/pokemon/back/685.png index b1a18694193..eab453253cc 100644 Binary files a/public/images/pokemon/back/685.png and b/public/images/pokemon/back/685.png differ diff --git a/public/images/pokemon/back/688.json b/public/images/pokemon/back/688.json index 872fbc1f9db..d9f30db34a8 100644 --- a/public/images/pokemon/back/688.json +++ b/public/images/pokemon/back/688.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "688.png", - "format": "RGBA8888", - "size": { - "w": 52, - "h": 52 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 41, - "h": 52 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 52 - }, - "frame": { - "x": 0, - "y": 0, - "w": 41, - "h": 52 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:ea462f2b1b46327e3b8fcb7ec5e44f08:2d2598cc03dec73182dbea237ad83b34:176060351d0044923af938ba7932a6ef$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 51, "h": 65 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 51, "h": 65 }, + "sourceSize": { "w": 51, "h": 65 } + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "688.png", + "format": "I8", + "size": { "w": 51, "h": 65 }, + "scale": "1" + } } diff --git a/public/images/pokemon/back/688.png b/public/images/pokemon/back/688.png index 33602c624a7..bb22ceed75e 100644 Binary files a/public/images/pokemon/back/688.png and b/public/images/pokemon/back/688.png differ diff --git a/public/images/pokemon/back/894.png b/public/images/pokemon/back/894.png index 337cba1cc71..b4cc4974ce2 100644 Binary files a/public/images/pokemon/back/894.png and b/public/images/pokemon/back/894.png differ diff --git a/public/images/pokemon/back/945.png b/public/images/pokemon/back/945.png index a89963b7cc3..6359f2cd77a 100644 Binary files a/public/images/pokemon/back/945.png and b/public/images/pokemon/back/945.png differ diff --git a/public/images/pokemon/back/female/198.png b/public/images/pokemon/back/female/198.png index 4f3f5d5c1a4..01489a05fb0 100644 Binary files a/public/images/pokemon/back/female/198.png and b/public/images/pokemon/back/female/198.png differ diff --git a/public/images/pokemon/back/female/25-beauty-cosplay.png b/public/images/pokemon/back/female/25-beauty-cosplay.png index b33e374aa6d..161cc301f7b 100644 Binary files a/public/images/pokemon/back/female/25-beauty-cosplay.png and b/public/images/pokemon/back/female/25-beauty-cosplay.png differ diff --git a/public/images/pokemon/back/female/25-cool-cosplay.png b/public/images/pokemon/back/female/25-cool-cosplay.png index e672040eaab..d10328785c8 100644 Binary files a/public/images/pokemon/back/female/25-cool-cosplay.png and b/public/images/pokemon/back/female/25-cool-cosplay.png differ diff --git a/public/images/pokemon/back/female/25-cosplay.png b/public/images/pokemon/back/female/25-cosplay.png index 2ebb0fe2285..644aec70f50 100644 Binary files a/public/images/pokemon/back/female/25-cosplay.png and b/public/images/pokemon/back/female/25-cosplay.png differ diff --git a/public/images/pokemon/back/female/25-cute-cosplay.png b/public/images/pokemon/back/female/25-cute-cosplay.png index 998a41f7396..552d816e142 100644 Binary files a/public/images/pokemon/back/female/25-cute-cosplay.png and b/public/images/pokemon/back/female/25-cute-cosplay.png differ diff --git a/public/images/pokemon/back/female/25-partner.png b/public/images/pokemon/back/female/25-partner.png index 97ceaa8bb2f..e65e58ec131 100644 Binary files a/public/images/pokemon/back/female/25-partner.png and b/public/images/pokemon/back/female/25-partner.png differ diff --git a/public/images/pokemon/back/female/25-smart-cosplay.png b/public/images/pokemon/back/female/25-smart-cosplay.png index 983f49e7024..c84c0b556aa 100644 Binary files a/public/images/pokemon/back/female/25-smart-cosplay.png and b/public/images/pokemon/back/female/25-smart-cosplay.png differ diff --git a/public/images/pokemon/back/female/25-tough-cosplay.png b/public/images/pokemon/back/female/25-tough-cosplay.png index a043231f172..73be0c8fb85 100644 Binary files a/public/images/pokemon/back/female/25-tough-cosplay.png and b/public/images/pokemon/back/female/25-tough-cosplay.png differ diff --git a/public/images/pokemon/back/female/25.png b/public/images/pokemon/back/female/25.png index 97ceaa8bb2f..e65e58ec131 100644 Binary files a/public/images/pokemon/back/female/25.png and b/public/images/pokemon/back/female/25.png differ diff --git a/public/images/pokemon/back/female/26.png b/public/images/pokemon/back/female/26.png index 40d39589660..2a6a3e41b2f 100644 Binary files a/public/images/pokemon/back/female/26.png and b/public/images/pokemon/back/female/26.png differ diff --git a/public/images/pokemon/back/shiny/378.png b/public/images/pokemon/back/shiny/378.png index ecaa26564c3..7bb24f1edfe 100644 Binary files a/public/images/pokemon/back/shiny/378.png and b/public/images/pokemon/back/shiny/378.png differ diff --git a/public/images/pokemon/back/shiny/436.json b/public/images/pokemon/back/shiny/436.json index 4091e1a2e49..3342cc6577c 100644 --- a/public/images/pokemon/back/shiny/436.json +++ b/public/images/pokemon/back/shiny/436.json @@ -1,2666 +1,1019 @@ -{ - "textures": [ - { - "image": "436.png", - "format": "RGBA8888", - "size": { - "w": 100, - "h": 100 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 5, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0097.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 0, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0098.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 11, - "y": 0, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0101.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0102.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0105.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 1, - "y": 14, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0106.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 1, - "y": 14, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0107.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 17, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0108.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 4, - "y": 17, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0111.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 18, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0112.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 8, - "y": 18, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0113.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 15, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0114.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 15, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0115.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0116.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 6, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0117.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0118.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0119.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0120.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0121.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0122.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 8, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0123.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0124.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0125.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0126.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 34, - "h": 40 - }, - "frame": { - "x": 0, - "y": 0, - "w": 34, - "h": 40 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 15, - "y": 4, - "w": 33, - "h": 40 - }, - "frame": { - "x": 34, - "y": 0, - "w": 33, - "h": 40 - } - }, - { - "filename": "0096.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 15, - "y": 4, - "w": 33, - "h": 40 - }, - "frame": { - "x": 34, - "y": 0, - "w": 33, - "h": 40 - } - }, - { - "filename": "0103.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 0, - "y": 9, - "w": 33, - "h": 40 - }, - "frame": { - "x": 67, - "y": 0, - "w": 33, - "h": 40 - } - }, - { - "filename": "0104.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 0, - "y": 9, - "w": 33, - "h": 40 - }, - "frame": { - "x": 67, - "y": 0, - "w": 33, - "h": 40 - } - }, - { - "filename": "0099.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 34, - "h": 39 - }, - "frame": { - "x": 0, - "y": 40, - "w": 34, - "h": 39 - } - }, - { - "filename": "0100.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 34, - "h": 39 - }, - "frame": { - "x": 0, - "y": 40, - "w": 34, - "h": 39 - } - }, - { - "filename": "0109.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 21, - "w": 34, - "h": 39 - }, - "frame": { - "x": 34, - "y": 40, - "w": 34, - "h": 39 - } - }, - { - "filename": "0110.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 48, - "h": 60 - }, - "spriteSourceSize": { - "x": 9, - "y": 21, - "w": 34, - "h": 39 - }, - "frame": { - "x": 34, - "y": 40, - "w": 34, - "h": 39 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:810e866f20256a6beca964ab2fe2f997:4d42b12e9664d852f2391c8b56845681:0a3bacf3d680738b160c4c8ace3cda59$" - } -} +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0005.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0008.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0009.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0010.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0011.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0012.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0014.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0015.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0018.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0019.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0020.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0021.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0022.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0023.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0024.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0025.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0026.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0027.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0028.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0029.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0030.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0031.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0032.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0033.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0034.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0035.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0036.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0037.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0038.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0039.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0040.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0041.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0042.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0043.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0044.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0045.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0046.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0047.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0048.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0049.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0050.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0051.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0052.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0053.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0054.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0055.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0056.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0057.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0058.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0059.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 6, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0060.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 6, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0061.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0062.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0063.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0064.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0065.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0066.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0067.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0068.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0069.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0070.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0071.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0072.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0073.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0074.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0075.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0076.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0077.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 4, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0078.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 4, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0079.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 3, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0080.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 3, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0081.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 4, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0082.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 4, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0083.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0084.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0085.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0086.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0087.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0088.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 12, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0089.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0090.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0091.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0092.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0093.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0094.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0095.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 5, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0096.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 5, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0097.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 1, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0098.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 1, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0099.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 0, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0100.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 0, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0101.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 5, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0102.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 5, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0103.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0104.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0105.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 15, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0106.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 15, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0107.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 18, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0108.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 18, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0109.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 22, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0110.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 22, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0111.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 19, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0112.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 19, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0113.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0114.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0115.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0116.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0117.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0118.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0119.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0120.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0121.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0122.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0123.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0124.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 11, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0125.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + }, + { + "filename": "0126.png", + "frame": { "x": 0, "y": 0, "w": 32, "h": 38 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 32, "h": 38 }, + "sourceSize": { "w": 48, "h": 60 } + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "436.png", + "format": "I8", + "size": { "w": 32, "h": 38 }, + "scale": "1" + } +} diff --git a/public/images/pokemon/back/shiny/436.png b/public/images/pokemon/back/shiny/436.png index b3d6dc4df61..d766a912555 100644 Binary files a/public/images/pokemon/back/shiny/436.png and b/public/images/pokemon/back/shiny/436.png differ diff --git a/public/images/pokemon/back/shiny/658-ash.json b/public/images/pokemon/back/shiny/658-ash.json index a796ad08246..51a722070b3 100644 --- a/public/images/pokemon/back/shiny/658-ash.json +++ b/public/images/pokemon/back/shiny/658-ash.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "658-ash.png", - "format": "RGBA8888", - "size": { - "w": 73, - "h": 73 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 73, - "h": 69 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 73, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 73, - "h": 69 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:d474b821316a87dfe09b397bdc2db5ef:497de0c2ec59ceba163e870b3226c76c:bfbf521a5c7bd80bcd95a96d9789c0dd$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 73, "h": 73 }, + "scale": "1" + } } diff --git a/public/images/pokemon/back/shiny/658-ash.png b/public/images/pokemon/back/shiny/658-ash.png index e41efb2c7ad..6e10e834731 100644 Binary files a/public/images/pokemon/back/shiny/658-ash.png and b/public/images/pokemon/back/shiny/658-ash.png differ diff --git a/public/images/pokemon/back/shiny/658.json b/public/images/pokemon/back/shiny/658.json index cc5d3c5b9ff..050b63e3592 100644 --- a/public/images/pokemon/back/shiny/658.json +++ b/public/images/pokemon/back/shiny/658.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "658.png", - "format": "RGBA8888", - "size": { - "w": 77, - "h": 77 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 77, - "h": 65 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 77, - "h": 65 - }, - "frame": { - "x": 0, - "y": 0, - "w": 77, - "h": 65 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:5891f87a78022cde3402e7d9714cc7bf:756360084290e39c139e3fef91c81759:5affcab976148657d36bf4ff3410f92d$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 77, "h": 77 }, + "scale": "1" + } } diff --git a/public/images/pokemon/back/shiny/658.png b/public/images/pokemon/back/shiny/658.png index 8b7f9c7e4fb..21519b6a145 100644 Binary files a/public/images/pokemon/back/shiny/658.png and b/public/images/pokemon/back/shiny/658.png differ diff --git a/public/images/pokemon/back/shiny/688.json b/public/images/pokemon/back/shiny/688.json index 56cf47aab5a..d9f30db34a8 100644 --- a/public/images/pokemon/back/shiny/688.json +++ b/public/images/pokemon/back/shiny/688.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "688.png", - "format": "RGBA8888", - "size": { - "w": 52, - "h": 52 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 41, - "h": 52 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 52 - }, - "frame": { - "x": 0, - "y": 0, - "w": 41, - "h": 52 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:0261b6c9242bba728fcfbfc515875b27:de0d9ddceed9311b33ae50ba86e969d1:176060351d0044923af938ba7932a6ef$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 51, "h": 65 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 51, "h": 65 }, + "sourceSize": { "w": 51, "h": 65 } + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "688.png", + "format": "I8", + "size": { "w": 51, "h": 65 }, + "scale": "1" + } } diff --git a/public/images/pokemon/back/shiny/688.png b/public/images/pokemon/back/shiny/688.png index c4aff6eb12d..bfff80c4925 100644 Binary files a/public/images/pokemon/back/shiny/688.png and b/public/images/pokemon/back/shiny/688.png differ diff --git a/public/images/pokemon/back/shiny/944.png b/public/images/pokemon/back/shiny/944.png index 24957073d46..a33c2a39c2f 100644 Binary files a/public/images/pokemon/back/shiny/944.png and b/public/images/pokemon/back/shiny/944.png differ diff --git a/public/images/pokemon/back/shiny/945.png b/public/images/pokemon/back/shiny/945.png index a1cc685f008..38be3590480 100644 Binary files a/public/images/pokemon/back/shiny/945.png and b/public/images/pokemon/back/shiny/945.png differ diff --git a/public/images/pokemon/exp/2026.png b/public/images/pokemon/exp/2026.png index 80ac591cd62..718fb8957b3 100644 Binary files a/public/images/pokemon/exp/2026.png and b/public/images/pokemon/exp/2026.png differ diff --git a/public/images/pokemon/exp/359-mega.png b/public/images/pokemon/exp/359-mega.png index 8b6d0dd2b4a..10787a35a8b 100644 Binary files a/public/images/pokemon/exp/359-mega.png and b/public/images/pokemon/exp/359-mega.png differ diff --git a/public/images/pokemon/exp/6503.png b/public/images/pokemon/exp/6503.png index 28d3a366fef..d1a698254cb 100644 Binary files a/public/images/pokemon/exp/6503.png and b/public/images/pokemon/exp/6503.png differ diff --git a/public/images/pokemon/exp/656.png b/public/images/pokemon/exp/656.png index 4f4af590a45..7afec8b08ee 100644 Binary files a/public/images/pokemon/exp/656.png and b/public/images/pokemon/exp/656.png differ diff --git a/public/images/pokemon/exp/657.png b/public/images/pokemon/exp/657.png index 6cfff5af3f7..404fb30a2b2 100644 Binary files a/public/images/pokemon/exp/657.png and b/public/images/pokemon/exp/657.png differ diff --git a/public/images/pokemon/exp/658-ash.json b/public/images/pokemon/exp/658-ash.json index f3a02cb1774..52dbac8366a 100644 --- a/public/images/pokemon/exp/658-ash.json +++ b/public/images/pokemon/exp/658-ash.json @@ -1,671 +1,299 @@ -{ - "textures": [ - { - "image": "658-ash.png", - "format": "RGBA8888", - "size": { - "w": 150, - "h": 150 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 66, - "w": 75, - "h": 66 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 66, - "w": 75, - "h": 66 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 66, - "w": 75, - "h": 66 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 66, - "w": 75, - "h": 66 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:cfb009f1af61ea752bdb3266bffd0fd0:e1abe8d09d1fe3c1ec758293b0a4bed5:f09eeed5adc5ec50aec50218e03662c2$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 79, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 79, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 79, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 79, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0018.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0019.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0020.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0021.png", + "frame": { "x": 79, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0022.png", + "frame": { "x": 79, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0023.png", + "frame": { "x": 79, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0024.png", + "frame": { "x": 79, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0025.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0026.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0027.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0028.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0029.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0030.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0031.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0032.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "image": "658-ash.png", + "format": "I8", + "size": { "w": 237, "h": 148 }, + "scale": "1" + } } diff --git a/public/images/pokemon/exp/658-ash.png b/public/images/pokemon/exp/658-ash.png index 5d80ca1ad0e..6bb84f3e4fd 100644 Binary files a/public/images/pokemon/exp/658-ash.png and b/public/images/pokemon/exp/658-ash.png differ diff --git a/public/images/pokemon/exp/658.png b/public/images/pokemon/exp/658.png index ab2e30592f6..83b2f5fab89 100644 Binary files a/public/images/pokemon/exp/658.png and b/public/images/pokemon/exp/658.png differ diff --git a/public/images/pokemon/exp/662.png b/public/images/pokemon/exp/662.png index 090e6e4c91f..e47863f724b 100644 Binary files a/public/images/pokemon/exp/662.png and b/public/images/pokemon/exp/662.png differ diff --git a/public/images/pokemon/exp/6706.png b/public/images/pokemon/exp/6706.png index ea745dfb04b..77b10183ec7 100644 Binary files a/public/images/pokemon/exp/6706.png and b/public/images/pokemon/exp/6706.png differ diff --git a/public/images/pokemon/exp/682.png b/public/images/pokemon/exp/682.png index 35ab3a5c315..104dc143677 100644 Binary files a/public/images/pokemon/exp/682.png and b/public/images/pokemon/exp/682.png differ diff --git a/public/images/pokemon/exp/683.png b/public/images/pokemon/exp/683.png index 5e8ff5acd30..d657a0ee5fd 100644 Binary files a/public/images/pokemon/exp/683.png and b/public/images/pokemon/exp/683.png differ diff --git a/public/images/pokemon/exp/684.png b/public/images/pokemon/exp/684.png index d7d6b29f730..84f06ee4f3c 100644 Binary files a/public/images/pokemon/exp/684.png and b/public/images/pokemon/exp/684.png differ diff --git a/public/images/pokemon/exp/685.png b/public/images/pokemon/exp/685.png index cfccc4f119b..2a1ab94bc22 100644 Binary files a/public/images/pokemon/exp/685.png and b/public/images/pokemon/exp/685.png differ diff --git a/public/images/pokemon/exp/705.png b/public/images/pokemon/exp/705.png index 3413bcd9fa3..670e8be5d51 100644 Binary files a/public/images/pokemon/exp/705.png and b/public/images/pokemon/exp/705.png differ diff --git a/public/images/pokemon/exp/894.png b/public/images/pokemon/exp/894.png index 4879a1ca5ec..749eec38e5e 100644 Binary files a/public/images/pokemon/exp/894.png and b/public/images/pokemon/exp/894.png differ diff --git a/public/images/pokemon/exp/945.png b/public/images/pokemon/exp/945.png index 074c03fda29..b50e1a9af52 100644 Binary files a/public/images/pokemon/exp/945.png and b/public/images/pokemon/exp/945.png differ diff --git a/public/images/pokemon/exp/back/2026.png b/public/images/pokemon/exp/back/2026.png index 007e4bee3e0..0624bb2c5e7 100644 Binary files a/public/images/pokemon/exp/back/2026.png and b/public/images/pokemon/exp/back/2026.png differ diff --git a/public/images/pokemon/exp/back/359-mega.png b/public/images/pokemon/exp/back/359-mega.png index 4ba1dd3ff81..1659752a571 100644 Binary files a/public/images/pokemon/exp/back/359-mega.png and b/public/images/pokemon/exp/back/359-mega.png differ diff --git a/public/images/pokemon/exp/back/6503.png b/public/images/pokemon/exp/back/6503.png index f5a2395826a..39b93590981 100644 Binary files a/public/images/pokemon/exp/back/6503.png and b/public/images/pokemon/exp/back/6503.png differ diff --git a/public/images/pokemon/exp/back/656.png b/public/images/pokemon/exp/back/656.png index 3a7b6fcec5c..99119d2e96e 100644 Binary files a/public/images/pokemon/exp/back/656.png and b/public/images/pokemon/exp/back/656.png differ diff --git a/public/images/pokemon/exp/back/657.png b/public/images/pokemon/exp/back/657.png index 7484a85289c..72e8367e10d 100644 Binary files a/public/images/pokemon/exp/back/657.png and b/public/images/pokemon/exp/back/657.png differ diff --git a/public/images/pokemon/exp/back/658-ash.json b/public/images/pokemon/exp/back/658-ash.json index 9c2e394a89d..8e360497b8d 100644 --- a/public/images/pokemon/exp/back/658-ash.json +++ b/public/images/pokemon/exp/back/658-ash.json @@ -1,188 +1,155 @@ -{ - "textures": [ - { - "image": "658-ash.png", - "format": "RGBA8888", - "size": { - "w": 150, - "h": 150 - }, - "scale": 1, - "frames": [ - { - "filename": "0003.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 61 - }, - "frame": { - "x": 0, - "y": 62, - "w": 75, - "h": 61 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 61 - }, - "frame": { - "x": 75, - "y": 62, - "w": 75, - "h": 61 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:0121f3850f8a57a4a046524a1a5974dd:168ffc856b6fea872641e8672304766c:f09eeed5adc5ec50aec50218e03662c2$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 0, "y": 73, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 0, "y": 73, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 0, "y": 73, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 0, "y": 73, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "image": "658-ash.png", + "format": "I8", + "size": { "w": 146, "h": 146 }, + "scale": "1" + } } diff --git a/public/images/pokemon/exp/back/658-ash.png b/public/images/pokemon/exp/back/658-ash.png index 8921ea65270..5d8794a1c0f 100644 Binary files a/public/images/pokemon/exp/back/658-ash.png and b/public/images/pokemon/exp/back/658-ash.png differ diff --git a/public/images/pokemon/exp/back/658.json b/public/images/pokemon/exp/back/658.json index 2fa50a7d23f..453f6c16dc6 100644 --- a/public/images/pokemon/exp/back/658.json +++ b/public/images/pokemon/exp/back/658.json @@ -1,188 +1,92 @@ -{ - "textures": [ - { - "image": "658.png", - "format": "RGBA8888", - "size": { - "w": 150, - "h": 150 - }, - "scale": 1, - "frames": [ - { - "filename": "0003.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 61 - }, - "frame": { - "x": 0, - "y": 62, - "w": 75, - "h": 61 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 61 - }, - "frame": { - "x": 0, - "y": 62, - "w": 75, - "h": 61 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:63845d55db2350ed7cd6956836dc9510:7129df11a518cdd74572c2016d5f8ed8:5affcab976148657d36bf4ff3410f92d$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 77, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 77, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 77, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 77, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 77, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 77, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "image": "658.png", + "format": "I8", + "size": { "w": 154, "h": 154 }, + "scale": "1" + } } diff --git a/public/images/pokemon/exp/back/658.png b/public/images/pokemon/exp/back/658.png index edcfa15b9f3..07b9084c43e 100644 Binary files a/public/images/pokemon/exp/back/658.png and b/public/images/pokemon/exp/back/658.png differ diff --git a/public/images/pokemon/exp/back/662.png b/public/images/pokemon/exp/back/662.png index e2a3111062f..4e6a3c88277 100644 Binary files a/public/images/pokemon/exp/back/662.png and b/public/images/pokemon/exp/back/662.png differ diff --git a/public/images/pokemon/exp/back/6706.png b/public/images/pokemon/exp/back/6706.png index 4bda5b08d10..7842bbbffad 100644 Binary files a/public/images/pokemon/exp/back/6706.png and b/public/images/pokemon/exp/back/6706.png differ diff --git a/public/images/pokemon/exp/back/682.png b/public/images/pokemon/exp/back/682.png index 9f713bfb828..d926cdc22a8 100644 Binary files a/public/images/pokemon/exp/back/682.png and b/public/images/pokemon/exp/back/682.png differ diff --git a/public/images/pokemon/exp/back/683.png b/public/images/pokemon/exp/back/683.png index 76aa9914d20..e65d213eaf2 100644 Binary files a/public/images/pokemon/exp/back/683.png and b/public/images/pokemon/exp/back/683.png differ diff --git a/public/images/pokemon/exp/back/684.png b/public/images/pokemon/exp/back/684.png index a58d2c77eb8..517cc69f8ee 100644 Binary files a/public/images/pokemon/exp/back/684.png and b/public/images/pokemon/exp/back/684.png differ diff --git a/public/images/pokemon/exp/back/685.png b/public/images/pokemon/exp/back/685.png index c791e4e92d7..d05cf54fb63 100644 Binary files a/public/images/pokemon/exp/back/685.png and b/public/images/pokemon/exp/back/685.png differ diff --git a/public/images/pokemon/exp/back/894.png b/public/images/pokemon/exp/back/894.png index c83851c2d54..e82e8dc0183 100644 Binary files a/public/images/pokemon/exp/back/894.png and b/public/images/pokemon/exp/back/894.png differ diff --git a/public/images/pokemon/exp/back/944.png b/public/images/pokemon/exp/back/944.png index 1f4139b4128..5162fa285be 100644 Binary files a/public/images/pokemon/exp/back/944.png and b/public/images/pokemon/exp/back/944.png differ diff --git a/public/images/pokemon/exp/back/945.png b/public/images/pokemon/exp/back/945.png index 98e56cc2468..74d4e56a598 100644 Binary files a/public/images/pokemon/exp/back/945.png and b/public/images/pokemon/exp/back/945.png differ diff --git a/public/images/pokemon/exp/back/shiny/658-ash.json b/public/images/pokemon/exp/back/shiny/658-ash.json index db9e546af7f..8e360497b8d 100644 --- a/public/images/pokemon/exp/back/shiny/658-ash.json +++ b/public/images/pokemon/exp/back/shiny/658-ash.json @@ -1,188 +1,155 @@ -{ - "textures": [ - { - "image": "658-ash.png", - "format": "RGBA8888", - "size": { - "w": 150, - "h": 150 - }, - "scale": 1, - "frames": [ - { - "filename": "0003.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 61 - }, - "frame": { - "x": 0, - "y": 62, - "w": 75, - "h": 61 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 61 - }, - "frame": { - "x": 75, - "y": 62, - "w": 75, - "h": 61 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:d9855568004fd93bcd73aa782894b172:d7e4656a720ccca08a26ed4485129bb3:f09eeed5adc5ec50aec50218e03662c2$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 0, "y": 73, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 0, "y": 73, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 0, "y": 73, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 0, "y": 73, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 73, "y": 0, "w": 73, "h": 73 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 }, + "sourceSize": { "w": 73, "h": 73 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "image": "658-ash.png", + "format": "I8", + "size": { "w": 146, "h": 146 }, + "scale": "1" + } } diff --git a/public/images/pokemon/exp/back/shiny/658-ash.png b/public/images/pokemon/exp/back/shiny/658-ash.png index a2a53dbdbc7..3269d435c94 100644 Binary files a/public/images/pokemon/exp/back/shiny/658-ash.png and b/public/images/pokemon/exp/back/shiny/658-ash.png differ diff --git a/public/images/pokemon/exp/back/shiny/658.json b/public/images/pokemon/exp/back/shiny/658.json index 8dc315c768e..453f6c16dc6 100644 --- a/public/images/pokemon/exp/back/shiny/658.json +++ b/public/images/pokemon/exp/back/shiny/658.json @@ -1,188 +1,92 @@ -{ - "textures": [ - { - "image": "658.png", - "format": "RGBA8888", - "size": { - "w": 150, - "h": 150 - }, - "scale": 1, - "frames": [ - { - "filename": "0003.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 62 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 62 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 61 - }, - "frame": { - "x": 0, - "y": 62, - "w": 75, - "h": 61 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 62 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 61 - }, - "frame": { - "x": 0, - "y": 62, - "w": 75, - "h": 61 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:661efcc0c742bc0d4b4e26900a59332f:d0aa0f579971d046660bf77b4044aa35:5affcab976148657d36bf4ff3410f92d$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 77, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 77, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 77, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 77, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 77, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 77, "y": 0, "w": 77, "h": 77 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 }, + "sourceSize": { "w": 77, "h": 77 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "image": "658.png", + "format": "I8", + "size": { "w": 154, "h": 154 }, + "scale": "1" + } } diff --git a/public/images/pokemon/exp/back/shiny/658.png b/public/images/pokemon/exp/back/shiny/658.png index 416f1145463..bb0ee7accdf 100644 Binary files a/public/images/pokemon/exp/back/shiny/658.png and b/public/images/pokemon/exp/back/shiny/658.png differ diff --git a/public/images/pokemon/exp/back/shiny/662.png b/public/images/pokemon/exp/back/shiny/662.png index b4e6c703eab..e662b3198a6 100644 Binary files a/public/images/pokemon/exp/back/shiny/662.png and b/public/images/pokemon/exp/back/shiny/662.png differ diff --git a/public/images/pokemon/exp/back/shiny/944.png b/public/images/pokemon/exp/back/shiny/944.png index a0d96282076..060e8a99545 100644 Binary files a/public/images/pokemon/exp/back/shiny/944.png and b/public/images/pokemon/exp/back/shiny/944.png differ diff --git a/public/images/pokemon/exp/back/shiny/945.png b/public/images/pokemon/exp/back/shiny/945.png index dabe70fdb31..71644f57479 100644 Binary files a/public/images/pokemon/exp/back/shiny/945.png and b/public/images/pokemon/exp/back/shiny/945.png differ diff --git a/public/images/pokemon/exp/shiny/658-ash.json b/public/images/pokemon/exp/shiny/658-ash.json index 5101079ce90..52dbac8366a 100644 --- a/public/images/pokemon/exp/shiny/658-ash.json +++ b/public/images/pokemon/exp/shiny/658-ash.json @@ -1,671 +1,299 @@ -{ - "textures": [ - { - "image": "658-ash.png", - "format": "RGBA8888", - "size": { - "w": 150, - "h": 150 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 75, - "y": 0, - "w": 75, - "h": 66 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 66, - "w": 75, - "h": 66 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 66, - "w": 75, - "h": 66 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 66, - "w": 75, - "h": 66 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 66 - }, - "frame": { - "x": 0, - "y": 66, - "w": 75, - "h": 66 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 75, - "h": 66 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 75, - "h": 65 - }, - "frame": { - "x": 75, - "y": 66, - "w": 75, - "h": 65 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:0875c2204eeabc96bd1f034bcc69210b:e1abe8d09d1fe3c1ec758293b0a4bed5:f09eeed5adc5ec50aec50218e03662c2$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 79, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 79, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 79, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 79, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0018.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0019.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0020.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0021.png", + "frame": { "x": 79, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0022.png", + "frame": { "x": 79, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0023.png", + "frame": { "x": 79, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0024.png", + "frame": { "x": 79, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0025.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0026.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0027.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0028.png", + "frame": { "x": 158, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0029.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0030.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0031.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + }, + { + "filename": "0032.png", + "frame": { "x": 0, "y": 74, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "image": "658-ash.png", + "format": "I8", + "size": { "w": 237, "h": 148 }, + "scale": "1" + } } diff --git a/public/images/pokemon/exp/shiny/658-ash.png b/public/images/pokemon/exp/shiny/658-ash.png index 5d80ca1ad0e..5b25ec9e021 100644 Binary files a/public/images/pokemon/exp/shiny/658-ash.png and b/public/images/pokemon/exp/shiny/658-ash.png differ diff --git a/public/images/pokemon/exp/shiny/658.png b/public/images/pokemon/exp/shiny/658.png index 999bc74c659..e7278458f2c 100644 Binary files a/public/images/pokemon/exp/shiny/658.png and b/public/images/pokemon/exp/shiny/658.png differ diff --git a/public/images/pokemon/exp/shiny/662.png b/public/images/pokemon/exp/shiny/662.png index ec0100f3e96..e45e79556c5 100644 Binary files a/public/images/pokemon/exp/shiny/662.png and b/public/images/pokemon/exp/shiny/662.png differ diff --git a/public/images/pokemon/exp/shiny/684.png b/public/images/pokemon/exp/shiny/684.png index 96fbea5e395..ed7b392cd6d 100644 Binary files a/public/images/pokemon/exp/shiny/684.png and b/public/images/pokemon/exp/shiny/684.png differ diff --git a/public/images/pokemon/exp/shiny/944.png b/public/images/pokemon/exp/shiny/944.png index fdb0f2ecb68..ee13a988a2b 100644 Binary files a/public/images/pokemon/exp/shiny/944.png and b/public/images/pokemon/exp/shiny/944.png differ diff --git a/public/images/pokemon/exp/shiny/945.png b/public/images/pokemon/exp/shiny/945.png index 9b938dfcfdd..3dba64c6ee8 100644 Binary files a/public/images/pokemon/exp/shiny/945.png and b/public/images/pokemon/exp/shiny/945.png differ diff --git a/public/images/pokemon/female/154.png b/public/images/pokemon/female/154.png index 4921f1556aa..f671d6b75aa 100644 Binary files a/public/images/pokemon/female/154.png and b/public/images/pokemon/female/154.png differ diff --git a/public/images/pokemon/female/194.png b/public/images/pokemon/female/194.png index 39c18727c2d..c0066f051ee 100644 Binary files a/public/images/pokemon/female/194.png and b/public/images/pokemon/female/194.png differ diff --git a/public/images/pokemon/female/198.png b/public/images/pokemon/female/198.png index 29bf2a296a5..9cead4fcbe0 100644 Binary files a/public/images/pokemon/female/198.png and b/public/images/pokemon/female/198.png differ diff --git a/public/images/pokemon/female/25-beauty-cosplay.png b/public/images/pokemon/female/25-beauty-cosplay.png index 018d0011254..26887468559 100644 Binary files a/public/images/pokemon/female/25-beauty-cosplay.png and b/public/images/pokemon/female/25-beauty-cosplay.png differ diff --git a/public/images/pokemon/female/25-cool-cosplay.png b/public/images/pokemon/female/25-cool-cosplay.png index 5936a9042ed..ae1e7c76d44 100644 Binary files a/public/images/pokemon/female/25-cool-cosplay.png and b/public/images/pokemon/female/25-cool-cosplay.png differ diff --git a/public/images/pokemon/female/25-cosplay.png b/public/images/pokemon/female/25-cosplay.png index 1f8f381419b..145d32e5130 100644 Binary files a/public/images/pokemon/female/25-cosplay.png and b/public/images/pokemon/female/25-cosplay.png differ diff --git a/public/images/pokemon/female/25-cute-cosplay.png b/public/images/pokemon/female/25-cute-cosplay.png index f559198f7ac..675a141b0fd 100644 Binary files a/public/images/pokemon/female/25-cute-cosplay.png and b/public/images/pokemon/female/25-cute-cosplay.png differ diff --git a/public/images/pokemon/female/25-partner.png b/public/images/pokemon/female/25-partner.png index e500db2a3be..8ce8d01c937 100644 Binary files a/public/images/pokemon/female/25-partner.png and b/public/images/pokemon/female/25-partner.png differ diff --git a/public/images/pokemon/female/25-smart-cosplay.png b/public/images/pokemon/female/25-smart-cosplay.png index b5c979e78ec..8306fb17dea 100644 Binary files a/public/images/pokemon/female/25-smart-cosplay.png and b/public/images/pokemon/female/25-smart-cosplay.png differ diff --git a/public/images/pokemon/female/25-tough-cosplay.png b/public/images/pokemon/female/25-tough-cosplay.png index 2896e27c8a9..a12d4a40a88 100644 Binary files a/public/images/pokemon/female/25-tough-cosplay.png and b/public/images/pokemon/female/25-tough-cosplay.png differ diff --git a/public/images/pokemon/female/25.png b/public/images/pokemon/female/25.png index e500db2a3be..8ce8d01c937 100644 Binary files a/public/images/pokemon/female/25.png and b/public/images/pokemon/female/25.png differ diff --git a/public/images/pokemon/female/26.png b/public/images/pokemon/female/26.png index 3f8c46ac761..242785a81cc 100644 Binary files a/public/images/pokemon/female/26.png and b/public/images/pokemon/female/26.png differ diff --git a/public/images/pokemon/female/275.png b/public/images/pokemon/female/275.png index 7f251793a15..c3c358716b2 100644 Binary files a/public/images/pokemon/female/275.png and b/public/images/pokemon/female/275.png differ diff --git a/public/images/pokemon/icons/1/25-beauty-cosplay.png b/public/images/pokemon/icons/1/25-beauty-cosplay.png index 19fd467ebd7..f9b6f3dcc82 100644 Binary files a/public/images/pokemon/icons/1/25-beauty-cosplay.png and b/public/images/pokemon/icons/1/25-beauty-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25-cool-cosplay.png b/public/images/pokemon/icons/1/25-cool-cosplay.png index 7d1b0954524..6436dff6dbb 100644 Binary files a/public/images/pokemon/icons/1/25-cool-cosplay.png and b/public/images/pokemon/icons/1/25-cool-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25-cosplay.png b/public/images/pokemon/icons/1/25-cosplay.png index 74f0b993ce4..580805ef797 100644 Binary files a/public/images/pokemon/icons/1/25-cosplay.png and b/public/images/pokemon/icons/1/25-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25-cute-cosplay.png b/public/images/pokemon/icons/1/25-cute-cosplay.png index 76488be18fe..71822acab8b 100644 Binary files a/public/images/pokemon/icons/1/25-cute-cosplay.png and b/public/images/pokemon/icons/1/25-cute-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25-gigantamax.png b/public/images/pokemon/icons/1/25-gigantamax.png index ee10d68fd92..8650a88a62e 100644 Binary files a/public/images/pokemon/icons/1/25-gigantamax.png and b/public/images/pokemon/icons/1/25-gigantamax.png differ diff --git a/public/images/pokemon/icons/1/25-smart-cosplay.png b/public/images/pokemon/icons/1/25-smart-cosplay.png index 7eb69c5a17e..90aba5ddbf0 100644 Binary files a/public/images/pokemon/icons/1/25-smart-cosplay.png and b/public/images/pokemon/icons/1/25-smart-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25-tough-cosplay.png b/public/images/pokemon/icons/1/25-tough-cosplay.png index 45c95ada80e..18101b5b497 100644 Binary files a/public/images/pokemon/icons/1/25-tough-cosplay.png and b/public/images/pokemon/icons/1/25-tough-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25s-beauty-cosplay.png b/public/images/pokemon/icons/1/25s-beauty-cosplay.png index 19fd467ebd7..3b524dfcb06 100644 Binary files a/public/images/pokemon/icons/1/25s-beauty-cosplay.png and b/public/images/pokemon/icons/1/25s-beauty-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25s-cool-cosplay.png b/public/images/pokemon/icons/1/25s-cool-cosplay.png index 7d1b0954524..0a3fc2d11ac 100644 Binary files a/public/images/pokemon/icons/1/25s-cool-cosplay.png and b/public/images/pokemon/icons/1/25s-cool-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25s-cosplay.png b/public/images/pokemon/icons/1/25s-cosplay.png index 74f0b993ce4..218977fd454 100644 Binary files a/public/images/pokemon/icons/1/25s-cosplay.png and b/public/images/pokemon/icons/1/25s-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25s-cute-cosplay.png b/public/images/pokemon/icons/1/25s-cute-cosplay.png index 76488be18fe..07df252aeb9 100644 Binary files a/public/images/pokemon/icons/1/25s-cute-cosplay.png and b/public/images/pokemon/icons/1/25s-cute-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25s-smart-cosplay.png b/public/images/pokemon/icons/1/25s-smart-cosplay.png index 7eb69c5a17e..5742bb2718a 100644 Binary files a/public/images/pokemon/icons/1/25s-smart-cosplay.png and b/public/images/pokemon/icons/1/25s-smart-cosplay.png differ diff --git a/public/images/pokemon/icons/1/25s-tough-cosplay.png b/public/images/pokemon/icons/1/25s-tough-cosplay.png index 45c95ada80e..7e49d494573 100644 Binary files a/public/images/pokemon/icons/1/25s-tough-cosplay.png and b/public/images/pokemon/icons/1/25s-tough-cosplay.png differ diff --git a/public/images/pokemon/icons/2/172s.png b/public/images/pokemon/icons/2/172s.png index 27a11014758..a1def7089ba 100644 Binary files a/public/images/pokemon/icons/2/172s.png and b/public/images/pokemon/icons/2/172s.png differ diff --git a/public/images/pokemon/icons/2/198-f.png b/public/images/pokemon/icons/2/198-f.png new file mode 100644 index 00000000000..bfc3e9bea4c Binary files /dev/null and b/public/images/pokemon/icons/2/198-f.png differ diff --git a/public/images/pokemon/icons/2/198s-f.png b/public/images/pokemon/icons/2/198s-f.png new file mode 100644 index 00000000000..ccc258cafac Binary files /dev/null and b/public/images/pokemon/icons/2/198s-f.png differ diff --git a/public/images/pokemon/icons/3/350s.png b/public/images/pokemon/icons/3/350s.png index eaed5c4bd11..4f5de9f5d57 100644 Binary files a/public/images/pokemon/icons/3/350s.png and b/public/images/pokemon/icons/3/350s.png differ diff --git a/public/images/pokemon/icons/3/378s.png b/public/images/pokemon/icons/3/378s.png index e2fc99bbc87..b52709493e7 100644 Binary files a/public/images/pokemon/icons/3/378s.png and b/public/images/pokemon/icons/3/378s.png differ diff --git a/public/images/pokemon/icons/7/2026.png b/public/images/pokemon/icons/7/2026.png index 5bc49abc790..cd8db24dd8b 100644 Binary files a/public/images/pokemon/icons/7/2026.png and b/public/images/pokemon/icons/7/2026.png differ diff --git a/public/images/pokemon/icons/7/2026s.png b/public/images/pokemon/icons/7/2026s.png index ecc11b878ab..94ce33a124f 100644 Binary files a/public/images/pokemon/icons/7/2026s.png and b/public/images/pokemon/icons/7/2026s.png differ diff --git a/public/images/pokemon/icons/9/1012-artisan.png b/public/images/pokemon/icons/9/1012-artisan.png index 96a215e47de..0eed79df1f2 100644 Binary files a/public/images/pokemon/icons/9/1012-artisan.png and b/public/images/pokemon/icons/9/1012-artisan.png differ diff --git a/public/images/pokemon/icons/9/1012-counterfeit.png b/public/images/pokemon/icons/9/1012-counterfeit.png index ff79d615db7..0eed79df1f2 100644 Binary files a/public/images/pokemon/icons/9/1012-counterfeit.png and b/public/images/pokemon/icons/9/1012-counterfeit.png differ diff --git a/public/images/pokemon/icons/9/1013-unremarkable.png b/public/images/pokemon/icons/9/1013-unremarkable.png index 3aa144b6d5c..9f4ec0cce34 100644 Binary files a/public/images/pokemon/icons/9/1013-unremarkable.png and b/public/images/pokemon/icons/9/1013-unremarkable.png differ diff --git a/public/images/pokemon/icons/variant/1/102_2.png b/public/images/pokemon/icons/variant/1/102_2.png new file mode 100644 index 00000000000..9d96f087919 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/102_2.png differ diff --git a/public/images/pokemon/icons/variant/1/102_3.png b/public/images/pokemon/icons/variant/1/102_3.png new file mode 100644 index 00000000000..65272284ea8 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/102_3.png differ diff --git a/public/images/pokemon/icons/variant/1/103_2.png b/public/images/pokemon/icons/variant/1/103_2.png new file mode 100644 index 00000000000..046d2b1bb6a Binary files /dev/null and b/public/images/pokemon/icons/variant/1/103_2.png differ diff --git a/public/images/pokemon/icons/variant/1/103_3.png b/public/images/pokemon/icons/variant/1/103_3.png new file mode 100644 index 00000000000..b68fdd50318 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/103_3.png differ diff --git a/public/images/pokemon/icons/variant/1/128_2.png b/public/images/pokemon/icons/variant/1/128_2.png new file mode 100644 index 00000000000..0a44d5bbfad Binary files /dev/null and b/public/images/pokemon/icons/variant/1/128_2.png differ diff --git a/public/images/pokemon/icons/variant/1/128_3.png b/public/images/pokemon/icons/variant/1/128_3.png new file mode 100644 index 00000000000..8f6b25c2c18 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/128_3.png differ diff --git a/public/images/pokemon/icons/variant/1/133-partner_2.png b/public/images/pokemon/icons/variant/1/133-partner_2.png new file mode 100644 index 00000000000..3e082ae0bd4 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/133-partner_2.png differ diff --git a/public/images/pokemon/icons/variant/1/133-partner_3.png b/public/images/pokemon/icons/variant/1/133-partner_3.png new file mode 100644 index 00000000000..57c969d855c Binary files /dev/null and b/public/images/pokemon/icons/variant/1/133-partner_3.png differ diff --git a/public/images/pokemon/icons/variant/1/133_2.png b/public/images/pokemon/icons/variant/1/133_2.png index 7ab496699f7..b17979df07a 100644 Binary files a/public/images/pokemon/icons/variant/1/133_2.png and b/public/images/pokemon/icons/variant/1/133_2.png differ diff --git a/public/images/pokemon/icons/variant/1/133_3.png b/public/images/pokemon/icons/variant/1/133_3.png index f999dd0fff7..fa4d99879ae 100644 Binary files a/public/images/pokemon/icons/variant/1/133_3.png and b/public/images/pokemon/icons/variant/1/133_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25-beauty-cosplay_2.png b/public/images/pokemon/icons/variant/1/25-beauty-cosplay_2.png new file mode 100644 index 00000000000..19c61af5069 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-beauty-cosplay_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25-beauty-cosplay_3.png b/public/images/pokemon/icons/variant/1/25-beauty-cosplay_3.png new file mode 100644 index 00000000000..1da79229795 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-beauty-cosplay_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25-cool-cosplay_2.png b/public/images/pokemon/icons/variant/1/25-cool-cosplay_2.png new file mode 100644 index 00000000000..8dc1e27acab Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-cool-cosplay_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25-cool-cosplay_3.png b/public/images/pokemon/icons/variant/1/25-cool-cosplay_3.png new file mode 100644 index 00000000000..7a603219649 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-cool-cosplay_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25-cosplay_2.png b/public/images/pokemon/icons/variant/1/25-cosplay_2.png new file mode 100644 index 00000000000..c47e9ef7d18 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-cosplay_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25-cosplay_3.png b/public/images/pokemon/icons/variant/1/25-cosplay_3.png new file mode 100644 index 00000000000..16332db9041 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-cosplay_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25-cute-cosplay_2.png b/public/images/pokemon/icons/variant/1/25-cute-cosplay_2.png new file mode 100644 index 00000000000..3f606da7bb0 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-cute-cosplay_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25-cute-cosplay_3.png b/public/images/pokemon/icons/variant/1/25-cute-cosplay_3.png new file mode 100644 index 00000000000..8560b6f04b5 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-cute-cosplay_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25-gigantamax_2.png b/public/images/pokemon/icons/variant/1/25-gigantamax_2.png new file mode 100644 index 00000000000..6bc267b55fa Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-gigantamax_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25-gigantamax_3.png b/public/images/pokemon/icons/variant/1/25-gigantamax_3.png new file mode 100644 index 00000000000..8c4ff760bcd Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-gigantamax_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25-partner_2.png b/public/images/pokemon/icons/variant/1/25-partner_2.png new file mode 100644 index 00000000000..eaa2cfb610f Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-partner_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25-partner_3.png b/public/images/pokemon/icons/variant/1/25-partner_3.png new file mode 100644 index 00000000000..1faf330ef51 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-partner_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25-smart-cosplay_2.png b/public/images/pokemon/icons/variant/1/25-smart-cosplay_2.png new file mode 100644 index 00000000000..4ecae1f73a2 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-smart-cosplay_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25-smart-cosplay_3.png b/public/images/pokemon/icons/variant/1/25-smart-cosplay_3.png new file mode 100644 index 00000000000..ea41daf34e6 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-smart-cosplay_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25-tough-cosplay_2.png b/public/images/pokemon/icons/variant/1/25-tough-cosplay_2.png new file mode 100644 index 00000000000..3f7072c4138 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-tough-cosplay_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25-tough-cosplay_3.png b/public/images/pokemon/icons/variant/1/25-tough-cosplay_3.png new file mode 100644 index 00000000000..e671ff98639 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25-tough-cosplay_3.png differ diff --git a/public/images/pokemon/icons/variant/1/25_2.png b/public/images/pokemon/icons/variant/1/25_2.png new file mode 100644 index 00000000000..5e987ffe777 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25_2.png differ diff --git a/public/images/pokemon/icons/variant/1/25_3.png b/public/images/pokemon/icons/variant/1/25_3.png new file mode 100644 index 00000000000..b04af012bec Binary files /dev/null and b/public/images/pokemon/icons/variant/1/25_3.png differ diff --git a/public/images/pokemon/icons/variant/1/26_2.png b/public/images/pokemon/icons/variant/1/26_2.png new file mode 100644 index 00000000000..f21ebe42b16 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/26_2.png differ diff --git a/public/images/pokemon/icons/variant/1/26_3.png b/public/images/pokemon/icons/variant/1/26_3.png new file mode 100644 index 00000000000..adbe9c212b3 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/26_3.png differ diff --git a/public/images/pokemon/icons/variant/1/39_2.png b/public/images/pokemon/icons/variant/1/39_2.png new file mode 100644 index 00000000000..f4b85b201cf Binary files /dev/null and b/public/images/pokemon/icons/variant/1/39_2.png differ diff --git a/public/images/pokemon/icons/variant/1/39_3.png b/public/images/pokemon/icons/variant/1/39_3.png new file mode 100644 index 00000000000..137f3dc083c Binary files /dev/null and b/public/images/pokemon/icons/variant/1/39_3.png differ diff --git a/public/images/pokemon/icons/variant/1/40_2.png b/public/images/pokemon/icons/variant/1/40_2.png new file mode 100644 index 00000000000..09ffdcd5757 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/40_2.png differ diff --git a/public/images/pokemon/icons/variant/1/40_3.png b/public/images/pokemon/icons/variant/1/40_3.png new file mode 100644 index 00000000000..09333136c19 Binary files /dev/null and b/public/images/pokemon/icons/variant/1/40_3.png differ diff --git a/public/images/pokemon/icons/variant/1/42_1.png b/public/images/pokemon/icons/variant/1/42_1.png index 17c82d9dd9e..91d7fae345d 100644 Binary files a/public/images/pokemon/icons/variant/1/42_1.png and b/public/images/pokemon/icons/variant/1/42_1.png differ diff --git a/public/images/pokemon/icons/variant/1/42_2.png b/public/images/pokemon/icons/variant/1/42_2.png index 91d7fae345d..17c82d9dd9e 100644 Binary files a/public/images/pokemon/icons/variant/1/42_2.png and b/public/images/pokemon/icons/variant/1/42_2.png differ diff --git a/public/images/pokemon/icons/variant/2/152_2.png b/public/images/pokemon/icons/variant/2/152_2.png new file mode 100644 index 00000000000..3815a4dbf49 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/152_2.png differ diff --git a/public/images/pokemon/icons/variant/2/152_3.png b/public/images/pokemon/icons/variant/2/152_3.png new file mode 100644 index 00000000000..be0fffab10c Binary files /dev/null and b/public/images/pokemon/icons/variant/2/152_3.png differ diff --git a/public/images/pokemon/icons/variant/2/153_2.png b/public/images/pokemon/icons/variant/2/153_2.png new file mode 100644 index 00000000000..020fc80d8b9 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/153_2.png differ diff --git a/public/images/pokemon/icons/variant/2/153_3.png b/public/images/pokemon/icons/variant/2/153_3.png new file mode 100644 index 00000000000..681acfa2db1 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/153_3.png differ diff --git a/public/images/pokemon/icons/variant/2/154-f_2.png b/public/images/pokemon/icons/variant/2/154-f_2.png new file mode 100644 index 00000000000..5ba8c458cf5 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/154-f_2.png differ diff --git a/public/images/pokemon/icons/variant/2/154-f_3.png b/public/images/pokemon/icons/variant/2/154-f_3.png new file mode 100644 index 00000000000..c278d045c38 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/154-f_3.png differ diff --git a/public/images/pokemon/icons/variant/2/154_2.png b/public/images/pokemon/icons/variant/2/154_2.png new file mode 100644 index 00000000000..323e2331a77 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/154_2.png differ diff --git a/public/images/pokemon/icons/variant/2/154_3.png b/public/images/pokemon/icons/variant/2/154_3.png new file mode 100644 index 00000000000..aef1e4d633e Binary files /dev/null and b/public/images/pokemon/icons/variant/2/154_3.png differ diff --git a/public/images/pokemon/icons/variant/2/158_2.png b/public/images/pokemon/icons/variant/2/158_2.png new file mode 100644 index 00000000000..c6b75ed6c20 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/158_2.png differ diff --git a/public/images/pokemon/icons/variant/2/158_3.png b/public/images/pokemon/icons/variant/2/158_3.png new file mode 100644 index 00000000000..073e3faa2e2 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/158_3.png differ diff --git a/public/images/pokemon/icons/variant/2/159_2.png b/public/images/pokemon/icons/variant/2/159_2.png new file mode 100644 index 00000000000..95d74728073 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/159_2.png differ diff --git a/public/images/pokemon/icons/variant/2/159_3.png b/public/images/pokemon/icons/variant/2/159_3.png new file mode 100644 index 00000000000..a73818d0c3a Binary files /dev/null and b/public/images/pokemon/icons/variant/2/159_3.png differ diff --git a/public/images/pokemon/icons/variant/2/160_2.png b/public/images/pokemon/icons/variant/2/160_2.png new file mode 100644 index 00000000000..7b7ba6e7231 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/160_2.png differ diff --git a/public/images/pokemon/icons/variant/2/160_3.png b/public/images/pokemon/icons/variant/2/160_3.png new file mode 100644 index 00000000000..62a4ab22fd2 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/160_3.png differ diff --git a/public/images/pokemon/icons/variant/2/167_2.png b/public/images/pokemon/icons/variant/2/167_2.png new file mode 100644 index 00000000000..a6bd15c0eef Binary files /dev/null and b/public/images/pokemon/icons/variant/2/167_2.png differ diff --git a/public/images/pokemon/icons/variant/2/167_3.png b/public/images/pokemon/icons/variant/2/167_3.png new file mode 100644 index 00000000000..88d84eec2a9 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/167_3.png differ diff --git a/public/images/pokemon/icons/variant/2/168_2.png b/public/images/pokemon/icons/variant/2/168_2.png new file mode 100644 index 00000000000..cf34c26be21 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/168_2.png differ diff --git a/public/images/pokemon/icons/variant/2/168_3.png b/public/images/pokemon/icons/variant/2/168_3.png new file mode 100644 index 00000000000..7a62c58d299 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/168_3.png differ diff --git a/public/images/pokemon/icons/variant/2/170_2.png b/public/images/pokemon/icons/variant/2/170_2.png new file mode 100644 index 00000000000..1ecdfda6eb8 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/170_2.png differ diff --git a/public/images/pokemon/icons/variant/2/170_3.png b/public/images/pokemon/icons/variant/2/170_3.png new file mode 100644 index 00000000000..01cb78568ed Binary files /dev/null and b/public/images/pokemon/icons/variant/2/170_3.png differ diff --git a/public/images/pokemon/icons/variant/2/171_2.png b/public/images/pokemon/icons/variant/2/171_2.png new file mode 100644 index 00000000000..3ff5792e2d2 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/171_2.png differ diff --git a/public/images/pokemon/icons/variant/2/171_3.png b/public/images/pokemon/icons/variant/2/171_3.png new file mode 100644 index 00000000000..11a3996da80 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/171_3.png differ diff --git a/public/images/pokemon/icons/variant/2/172-spiky_2.png b/public/images/pokemon/icons/variant/2/172-spiky_2.png new file mode 100644 index 00000000000..b293ee3283a Binary files /dev/null and b/public/images/pokemon/icons/variant/2/172-spiky_2.png differ diff --git a/public/images/pokemon/icons/variant/2/172-spiky_3.png b/public/images/pokemon/icons/variant/2/172-spiky_3.png new file mode 100644 index 00000000000..ff9a4229421 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/172-spiky_3.png differ diff --git a/public/images/pokemon/icons/variant/2/172_2.png b/public/images/pokemon/icons/variant/2/172_2.png new file mode 100644 index 00000000000..4fa282f9297 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/172_2.png differ diff --git a/public/images/pokemon/icons/variant/2/172_3.png b/public/images/pokemon/icons/variant/2/172_3.png new file mode 100644 index 00000000000..95f0c9bdc6d Binary files /dev/null and b/public/images/pokemon/icons/variant/2/172_3.png differ diff --git a/public/images/pokemon/icons/variant/2/174_2.png b/public/images/pokemon/icons/variant/2/174_2.png new file mode 100644 index 00000000000..e7ffddb1f57 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/174_2.png differ diff --git a/public/images/pokemon/icons/variant/2/174_3.png b/public/images/pokemon/icons/variant/2/174_3.png new file mode 100644 index 00000000000..58d98aab99a Binary files /dev/null and b/public/images/pokemon/icons/variant/2/174_3.png differ diff --git a/public/images/pokemon/icons/variant/2/194_2.png b/public/images/pokemon/icons/variant/2/194_2.png new file mode 100644 index 00000000000..043c11ce065 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/194_2.png differ diff --git a/public/images/pokemon/icons/variant/2/194_3.png b/public/images/pokemon/icons/variant/2/194_3.png new file mode 100644 index 00000000000..f5d792b141f Binary files /dev/null and b/public/images/pokemon/icons/variant/2/194_3.png differ diff --git a/public/images/pokemon/icons/variant/2/195_2.png b/public/images/pokemon/icons/variant/2/195_2.png new file mode 100644 index 00000000000..7fd5ba2792f Binary files /dev/null and b/public/images/pokemon/icons/variant/2/195_2.png differ diff --git a/public/images/pokemon/icons/variant/2/195_3.png b/public/images/pokemon/icons/variant/2/195_3.png new file mode 100644 index 00000000000..99da4dfe12e Binary files /dev/null and b/public/images/pokemon/icons/variant/2/195_3.png differ diff --git a/public/images/pokemon/icons/variant/2/198-f_2.png b/public/images/pokemon/icons/variant/2/198-f_2.png new file mode 100644 index 00000000000..35e5c2e75ea Binary files /dev/null and b/public/images/pokemon/icons/variant/2/198-f_2.png differ diff --git a/public/images/pokemon/icons/variant/2/198-f_3.png b/public/images/pokemon/icons/variant/2/198-f_3.png new file mode 100644 index 00000000000..f2920cd1d0e Binary files /dev/null and b/public/images/pokemon/icons/variant/2/198-f_3.png differ diff --git a/public/images/pokemon/icons/variant/2/198_2.png b/public/images/pokemon/icons/variant/2/198_2.png new file mode 100644 index 00000000000..35e5c2e75ea Binary files /dev/null and b/public/images/pokemon/icons/variant/2/198_2.png differ diff --git a/public/images/pokemon/icons/variant/2/198_3.png b/public/images/pokemon/icons/variant/2/198_3.png new file mode 100644 index 00000000000..f2920cd1d0e Binary files /dev/null and b/public/images/pokemon/icons/variant/2/198_3.png differ diff --git a/public/images/pokemon/icons/variant/2/211_2.png b/public/images/pokemon/icons/variant/2/211_2.png new file mode 100644 index 00000000000..c042910bc17 Binary files /dev/null and b/public/images/pokemon/icons/variant/2/211_2.png differ diff --git a/public/images/pokemon/icons/variant/2/211_3.png b/public/images/pokemon/icons/variant/2/211_3.png new file mode 100644 index 00000000000..3548893b6ec Binary files /dev/null and b/public/images/pokemon/icons/variant/2/211_3.png differ diff --git a/public/images/pokemon/icons/variant/3/255_2.png b/public/images/pokemon/icons/variant/3/255_2.png index adf8c6ea8bc..b40b8f1607c 100644 Binary files a/public/images/pokemon/icons/variant/3/255_2.png and b/public/images/pokemon/icons/variant/3/255_2.png differ diff --git a/public/images/pokemon/icons/variant/3/255_3.png b/public/images/pokemon/icons/variant/3/255_3.png index 6ed47e69afa..2ae8ef351f5 100644 Binary files a/public/images/pokemon/icons/variant/3/255_3.png and b/public/images/pokemon/icons/variant/3/255_3.png differ diff --git a/public/images/pokemon/icons/variant/3/256_2.png b/public/images/pokemon/icons/variant/3/256_2.png index b372f1ff981..43919a2db06 100644 Binary files a/public/images/pokemon/icons/variant/3/256_2.png and b/public/images/pokemon/icons/variant/3/256_2.png differ diff --git a/public/images/pokemon/icons/variant/3/256_3.png b/public/images/pokemon/icons/variant/3/256_3.png index 0c529f838ba..bb1cbfe0809 100644 Binary files a/public/images/pokemon/icons/variant/3/256_3.png and b/public/images/pokemon/icons/variant/3/256_3.png differ diff --git a/public/images/pokemon/icons/variant/3/257_3.png b/public/images/pokemon/icons/variant/3/257_3.png index c7853c73d4f..cccaab5db12 100644 Binary files a/public/images/pokemon/icons/variant/3/257_3.png and b/public/images/pokemon/icons/variant/3/257_3.png differ diff --git a/public/images/pokemon/icons/variant/3/276_2.png b/public/images/pokemon/icons/variant/3/276_2.png new file mode 100644 index 00000000000..d7e8a3aa9ca Binary files /dev/null and b/public/images/pokemon/icons/variant/3/276_2.png differ diff --git a/public/images/pokemon/icons/variant/3/276_3.png b/public/images/pokemon/icons/variant/3/276_3.png new file mode 100644 index 00000000000..b9cfa276eb2 Binary files /dev/null and b/public/images/pokemon/icons/variant/3/276_3.png differ diff --git a/public/images/pokemon/icons/variant/3/277_2.png b/public/images/pokemon/icons/variant/3/277_2.png new file mode 100644 index 00000000000..f4d58f259c3 Binary files /dev/null and b/public/images/pokemon/icons/variant/3/277_2.png differ diff --git a/public/images/pokemon/icons/variant/3/277_3.png b/public/images/pokemon/icons/variant/3/277_3.png new file mode 100644 index 00000000000..69ccce9069b Binary files /dev/null and b/public/images/pokemon/icons/variant/3/277_3.png differ diff --git a/public/images/pokemon/icons/variant/3/359-mega_2.png b/public/images/pokemon/icons/variant/3/359-mega_2.png new file mode 100644 index 00000000000..35290c15aa9 Binary files /dev/null and b/public/images/pokemon/icons/variant/3/359-mega_2.png differ diff --git a/public/images/pokemon/icons/variant/3/359-mega_3.png b/public/images/pokemon/icons/variant/3/359-mega_3.png new file mode 100644 index 00000000000..5a3250b944d Binary files /dev/null and b/public/images/pokemon/icons/variant/3/359-mega_3.png differ diff --git a/public/images/pokemon/icons/variant/3/359_2.png b/public/images/pokemon/icons/variant/3/359_2.png new file mode 100644 index 00000000000..0fa229141fd Binary files /dev/null and b/public/images/pokemon/icons/variant/3/359_2.png differ diff --git a/public/images/pokemon/icons/variant/3/359_3.png b/public/images/pokemon/icons/variant/3/359_3.png new file mode 100644 index 00000000000..54ba72028ac Binary files /dev/null and b/public/images/pokemon/icons/variant/3/359_3.png differ diff --git a/public/images/pokemon/icons/variant/3/377_2.png b/public/images/pokemon/icons/variant/3/377_2.png new file mode 100644 index 00000000000..f90f337c32e Binary files /dev/null and b/public/images/pokemon/icons/variant/3/377_2.png differ diff --git a/public/images/pokemon/icons/variant/3/377_3.png b/public/images/pokemon/icons/variant/3/377_3.png new file mode 100644 index 00000000000..0957178662a Binary files /dev/null and b/public/images/pokemon/icons/variant/3/377_3.png differ diff --git a/public/images/pokemon/variant/back/6706_2.png b/public/images/pokemon/icons/variant/3/378_1.png similarity index 56% rename from public/images/pokemon/variant/back/6706_2.png rename to public/images/pokemon/icons/variant/3/378_1.png index e52f1af4ba5..32bc37d9e33 100644 Binary files a/public/images/pokemon/variant/back/6706_2.png and b/public/images/pokemon/icons/variant/3/378_1.png differ diff --git a/public/images/pokemon/icons/variant/3/378_2.png b/public/images/pokemon/icons/variant/3/378_2.png new file mode 100644 index 00000000000..9f310bc92c8 Binary files /dev/null and b/public/images/pokemon/icons/variant/3/378_2.png differ diff --git a/public/images/pokemon/icons/variant/3/378_3.png b/public/images/pokemon/icons/variant/3/378_3.png new file mode 100644 index 00000000000..45afe9a71a9 Binary files /dev/null and b/public/images/pokemon/icons/variant/3/378_3.png differ diff --git a/public/images/pokemon/icons/variant/3/379_2.png b/public/images/pokemon/icons/variant/3/379_2.png new file mode 100644 index 00000000000..ad928fd752e Binary files /dev/null and b/public/images/pokemon/icons/variant/3/379_2.png differ diff --git a/public/images/pokemon/icons/variant/3/379_3.png b/public/images/pokemon/icons/variant/3/379_3.png new file mode 100644 index 00000000000..acb86b4f665 Binary files /dev/null and b/public/images/pokemon/icons/variant/3/379_3.png differ diff --git a/public/images/pokemon/icons/variant/3/427_2.png b/public/images/pokemon/icons/variant/3/427_2.png deleted file mode 100644 index ceaf11acb48..00000000000 Binary files a/public/images/pokemon/icons/variant/3/427_2.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/3/427_3.png b/public/images/pokemon/icons/variant/3/427_3.png deleted file mode 100644 index 5972f5e9489..00000000000 Binary files a/public/images/pokemon/icons/variant/3/427_3.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/3/428-mega_2.png b/public/images/pokemon/icons/variant/3/428-mega_2.png deleted file mode 100644 index 32c3293a796..00000000000 Binary files a/public/images/pokemon/icons/variant/3/428-mega_2.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/3/428_2.png b/public/images/pokemon/icons/variant/3/428_2.png deleted file mode 100644 index 5b325f3256a..00000000000 Binary files a/public/images/pokemon/icons/variant/3/428_2.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/3/429_1.png b/public/images/pokemon/icons/variant/3/429_1.png deleted file mode 100644 index 667f389f5c1..00000000000 Binary files a/public/images/pokemon/icons/variant/3/429_1.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/3/429_2.png b/public/images/pokemon/icons/variant/3/429_2.png deleted file mode 100644 index 85cd47bd85f..00000000000 Binary files a/public/images/pokemon/icons/variant/3/429_2.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/3/429_3.png b/public/images/pokemon/icons/variant/3/429_3.png deleted file mode 100644 index bb9b2384514..00000000000 Binary files a/public/images/pokemon/icons/variant/3/429_3.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/3/475-mega_3.png b/public/images/pokemon/icons/variant/3/475-mega_3.png deleted file mode 100644 index c067c36c836..00000000000 Binary files a/public/images/pokemon/icons/variant/3/475-mega_3.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/3/475_3.png b/public/images/pokemon/icons/variant/3/475_3.png deleted file mode 100644 index 4a8f5bdb56d..00000000000 Binary files a/public/images/pokemon/icons/variant/3/475_3.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/4/390_2.png b/public/images/pokemon/icons/variant/4/390_2.png new file mode 100644 index 00000000000..f29d3561210 Binary files /dev/null and b/public/images/pokemon/icons/variant/4/390_2.png differ diff --git a/public/images/pokemon/icons/variant/4/390_3.png b/public/images/pokemon/icons/variant/4/390_3.png new file mode 100644 index 00000000000..7634f2e8639 Binary files /dev/null and b/public/images/pokemon/icons/variant/4/390_3.png differ diff --git a/public/images/pokemon/icons/variant/4/391_2.png b/public/images/pokemon/icons/variant/4/391_2.png new file mode 100644 index 00000000000..470de43c7bc Binary files /dev/null and b/public/images/pokemon/icons/variant/4/391_2.png differ diff --git a/public/images/pokemon/icons/variant/4/391_3.png b/public/images/pokemon/icons/variant/4/391_3.png new file mode 100644 index 00000000000..8996fdb025c Binary files /dev/null and b/public/images/pokemon/icons/variant/4/391_3.png differ diff --git a/public/images/pokemon/icons/variant/4/392_2.png b/public/images/pokemon/icons/variant/4/392_2.png new file mode 100644 index 00000000000..0550a20e94d Binary files /dev/null and b/public/images/pokemon/icons/variant/4/392_2.png differ diff --git a/public/images/pokemon/icons/variant/4/392_3.png b/public/images/pokemon/icons/variant/4/392_3.png new file mode 100644 index 00000000000..7a66926b533 Binary files /dev/null and b/public/images/pokemon/icons/variant/4/392_3.png differ diff --git a/public/images/pokemon/icons/variant/4/427_2.png b/public/images/pokemon/icons/variant/4/427_2.png index 1b5d9271624..ceaf11acb48 100644 Binary files a/public/images/pokemon/icons/variant/4/427_2.png and b/public/images/pokemon/icons/variant/4/427_2.png differ diff --git a/public/images/pokemon/icons/variant/4/427_3.png b/public/images/pokemon/icons/variant/4/427_3.png index a3f90ea6dfa..5972f5e9489 100644 Binary files a/public/images/pokemon/icons/variant/4/427_3.png and b/public/images/pokemon/icons/variant/4/427_3.png differ diff --git a/public/images/pokemon/icons/variant/4/428-mega_2.png b/public/images/pokemon/icons/variant/4/428-mega_2.png index 43dfa05d438..32c3293a796 100644 Binary files a/public/images/pokemon/icons/variant/4/428-mega_2.png and b/public/images/pokemon/icons/variant/4/428-mega_2.png differ diff --git a/public/images/pokemon/icons/variant/4/428_2.png b/public/images/pokemon/icons/variant/4/428_2.png index 1e42720c78b..5b325f3256a 100644 Binary files a/public/images/pokemon/icons/variant/4/428_2.png and b/public/images/pokemon/icons/variant/4/428_2.png differ diff --git a/public/images/pokemon/icons/variant/4/429_1.png b/public/images/pokemon/icons/variant/4/429_1.png index 7354a6a6be7..667f389f5c1 100644 Binary files a/public/images/pokemon/icons/variant/4/429_1.png and b/public/images/pokemon/icons/variant/4/429_1.png differ diff --git a/public/images/pokemon/icons/variant/4/429_2.png b/public/images/pokemon/icons/variant/4/429_2.png index 9ec7cd5e76e..85cd47bd85f 100644 Binary files a/public/images/pokemon/icons/variant/4/429_2.png and b/public/images/pokemon/icons/variant/4/429_2.png differ diff --git a/public/images/pokemon/icons/variant/4/429_3.png b/public/images/pokemon/icons/variant/4/429_3.png index 48f7068ced8..bb9b2384514 100644 Binary files a/public/images/pokemon/icons/variant/4/429_3.png and b/public/images/pokemon/icons/variant/4/429_3.png differ diff --git a/public/images/pokemon/icons/variant/4/430_2.png b/public/images/pokemon/icons/variant/4/430_2.png new file mode 100644 index 00000000000..8026dd75141 Binary files /dev/null and b/public/images/pokemon/icons/variant/4/430_2.png differ diff --git a/public/images/pokemon/icons/variant/4/430_3.png b/public/images/pokemon/icons/variant/4/430_3.png new file mode 100644 index 00000000000..d83a4f349f0 Binary files /dev/null and b/public/images/pokemon/icons/variant/4/430_3.png differ diff --git a/public/images/pokemon/icons/variant/4/455_2.png b/public/images/pokemon/icons/variant/4/455_2.png new file mode 100644 index 00000000000..206ba13205f Binary files /dev/null and b/public/images/pokemon/icons/variant/4/455_2.png differ diff --git a/public/images/pokemon/icons/variant/4/455_3.png b/public/images/pokemon/icons/variant/4/455_3.png new file mode 100644 index 00000000000..199976e2f67 Binary files /dev/null and b/public/images/pokemon/icons/variant/4/455_3.png differ diff --git a/public/images/pokemon/icons/variant/4/486_2.png b/public/images/pokemon/icons/variant/4/486_2.png new file mode 100644 index 00000000000..d13c4861a4b Binary files /dev/null and b/public/images/pokemon/icons/variant/4/486_2.png differ diff --git a/public/images/pokemon/icons/variant/4/486_3.png b/public/images/pokemon/icons/variant/4/486_3.png new file mode 100644 index 00000000000..cf33b01869a Binary files /dev/null and b/public/images/pokemon/icons/variant/4/486_3.png differ diff --git a/public/images/pokemon/icons/variant/5/501_2.png b/public/images/pokemon/icons/variant/5/501_2.png new file mode 100644 index 00000000000..d92f57a8399 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/501_2.png differ diff --git a/public/images/pokemon/icons/variant/5/501_3.png b/public/images/pokemon/icons/variant/5/501_3.png new file mode 100644 index 00000000000..50bbb59a545 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/501_3.png differ diff --git a/public/images/pokemon/icons/variant/5/502_2.png b/public/images/pokemon/icons/variant/5/502_2.png new file mode 100644 index 00000000000..3d327da2129 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/502_2.png differ diff --git a/public/images/pokemon/icons/variant/5/502_3.png b/public/images/pokemon/icons/variant/5/502_3.png new file mode 100644 index 00000000000..a10810daed9 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/502_3.png differ diff --git a/public/images/pokemon/icons/variant/5/503_2.png b/public/images/pokemon/icons/variant/5/503_2.png new file mode 100644 index 00000000000..b3611139d87 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/503_2.png differ diff --git a/public/images/pokemon/icons/variant/5/503_3.png b/public/images/pokemon/icons/variant/5/503_3.png new file mode 100644 index 00000000000..da3aa967ab5 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/503_3.png differ diff --git a/public/images/pokemon/icons/variant/5/527_2.png b/public/images/pokemon/icons/variant/5/527_2.png new file mode 100644 index 00000000000..3a0b284bfde Binary files /dev/null and b/public/images/pokemon/icons/variant/5/527_2.png differ diff --git a/public/images/pokemon/icons/variant/5/527_3.png b/public/images/pokemon/icons/variant/5/527_3.png new file mode 100644 index 00000000000..39b54a23b1e Binary files /dev/null and b/public/images/pokemon/icons/variant/5/527_3.png differ diff --git a/public/images/pokemon/icons/variant/5/528_2.png b/public/images/pokemon/icons/variant/5/528_2.png new file mode 100644 index 00000000000..4d209760134 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/528_2.png differ diff --git a/public/images/pokemon/icons/variant/5/528_3.png b/public/images/pokemon/icons/variant/5/528_3.png new file mode 100644 index 00000000000..1c887443660 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/528_3.png differ diff --git a/public/images/pokemon/icons/variant/5/587_2.png b/public/images/pokemon/icons/variant/5/587_2.png new file mode 100644 index 00000000000..1e522a31676 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/587_2.png differ diff --git a/public/images/pokemon/icons/variant/5/587_3.png b/public/images/pokemon/icons/variant/5/587_3.png new file mode 100644 index 00000000000..c26066605cd Binary files /dev/null and b/public/images/pokemon/icons/variant/5/587_3.png differ diff --git a/public/images/pokemon/icons/variant/5/588_2.png b/public/images/pokemon/icons/variant/5/588_2.png new file mode 100644 index 00000000000..df99218cedd Binary files /dev/null and b/public/images/pokemon/icons/variant/5/588_2.png differ diff --git a/public/images/pokemon/icons/variant/5/588_3.png b/public/images/pokemon/icons/variant/5/588_3.png new file mode 100644 index 00000000000..3d9277308c7 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/588_3.png differ diff --git a/public/images/pokemon/icons/variant/5/589_2.png b/public/images/pokemon/icons/variant/5/589_2.png new file mode 100644 index 00000000000..ada32c980c1 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/589_2.png differ diff --git a/public/images/pokemon/icons/variant/5/589_3.png b/public/images/pokemon/icons/variant/5/589_3.png new file mode 100644 index 00000000000..1f612c4e8a5 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/589_3.png differ diff --git a/public/images/pokemon/icons/variant/5/590_2.png b/public/images/pokemon/icons/variant/5/590_2.png new file mode 100644 index 00000000000..66c3767024b Binary files /dev/null and b/public/images/pokemon/icons/variant/5/590_2.png differ diff --git a/public/images/pokemon/icons/variant/5/590_3.png b/public/images/pokemon/icons/variant/5/590_3.png new file mode 100644 index 00000000000..d18ccb42e21 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/590_3.png differ diff --git a/public/images/pokemon/icons/variant/5/591_2.png b/public/images/pokemon/icons/variant/5/591_2.png new file mode 100644 index 00000000000..dad56af2559 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/591_2.png differ diff --git a/public/images/pokemon/icons/variant/5/591_3.png b/public/images/pokemon/icons/variant/5/591_3.png new file mode 100644 index 00000000000..a407a14b83a Binary files /dev/null and b/public/images/pokemon/icons/variant/5/591_3.png differ diff --git a/public/images/pokemon/icons/variant/5/616_2.png b/public/images/pokemon/icons/variant/5/616_2.png new file mode 100644 index 00000000000..88e45da0238 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/616_2.png differ diff --git a/public/images/pokemon/icons/variant/5/616_3.png b/public/images/pokemon/icons/variant/5/616_3.png new file mode 100644 index 00000000000..b1767da8fdd Binary files /dev/null and b/public/images/pokemon/icons/variant/5/616_3.png differ diff --git a/public/images/pokemon/icons/variant/5/617_2.png b/public/images/pokemon/icons/variant/5/617_2.png new file mode 100644 index 00000000000..fff02c3f344 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/617_2.png differ diff --git a/public/images/pokemon/icons/variant/5/617_3.png b/public/images/pokemon/icons/variant/5/617_3.png new file mode 100644 index 00000000000..b3f05f31db2 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/617_3.png differ diff --git a/public/images/pokemon/icons/variant/5/621_2.png b/public/images/pokemon/icons/variant/5/621_2.png new file mode 100644 index 00000000000..dbaa26325d8 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/621_2.png differ diff --git a/public/images/pokemon/icons/variant/5/621_3.png b/public/images/pokemon/icons/variant/5/621_3.png new file mode 100644 index 00000000000..190ffb11dc3 Binary files /dev/null and b/public/images/pokemon/icons/variant/5/621_3.png differ diff --git a/public/images/pokemon/icons/variant/6/656_2.png b/public/images/pokemon/icons/variant/6/656_2.png new file mode 100644 index 00000000000..612386a5d1e Binary files /dev/null and b/public/images/pokemon/icons/variant/6/656_2.png differ diff --git a/public/images/pokemon/icons/variant/6/656_3.png b/public/images/pokemon/icons/variant/6/656_3.png new file mode 100644 index 00000000000..575cf3aef3a Binary files /dev/null and b/public/images/pokemon/icons/variant/6/656_3.png differ diff --git a/public/images/pokemon/icons/variant/6/657_2.png b/public/images/pokemon/icons/variant/6/657_2.png new file mode 100644 index 00000000000..9f26c5f85bf Binary files /dev/null and b/public/images/pokemon/icons/variant/6/657_2.png differ diff --git a/public/images/pokemon/icons/variant/6/657_3.png b/public/images/pokemon/icons/variant/6/657_3.png new file mode 100644 index 00000000000..fde76bb8d1c Binary files /dev/null and b/public/images/pokemon/icons/variant/6/657_3.png differ diff --git a/public/images/pokemon/icons/variant/6/658-ash_2.png b/public/images/pokemon/icons/variant/6/658-ash_2.png new file mode 100644 index 00000000000..b788b336efe Binary files /dev/null and b/public/images/pokemon/icons/variant/6/658-ash_2.png differ diff --git a/public/images/pokemon/icons/variant/6/658-ash_3.png b/public/images/pokemon/icons/variant/6/658-ash_3.png new file mode 100644 index 00000000000..52ac4fe0ede Binary files /dev/null and b/public/images/pokemon/icons/variant/6/658-ash_3.png differ diff --git a/public/images/pokemon/icons/variant/6/658_2.png b/public/images/pokemon/icons/variant/6/658_2.png new file mode 100644 index 00000000000..eaf9da8a9ce Binary files /dev/null and b/public/images/pokemon/icons/variant/6/658_2.png differ diff --git a/public/images/pokemon/icons/variant/6/658_3.png b/public/images/pokemon/icons/variant/6/658_3.png new file mode 100644 index 00000000000..027dda592f0 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/658_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-dandy_2.png b/public/images/pokemon/icons/variant/6/676-dandy_2.png new file mode 100644 index 00000000000..2fb1a1a01b6 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-dandy_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-dandy_3.png b/public/images/pokemon/icons/variant/6/676-dandy_3.png new file mode 100644 index 00000000000..ac05ae8dd3a Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-dandy_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-debutante_2.png b/public/images/pokemon/icons/variant/6/676-debutante_2.png new file mode 100644 index 00000000000..9ec13ca1964 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-debutante_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-debutante_3.png b/public/images/pokemon/icons/variant/6/676-debutante_3.png new file mode 100644 index 00000000000..aef6da0a1fd Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-debutante_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-diamond_2.png b/public/images/pokemon/icons/variant/6/676-diamond_2.png new file mode 100644 index 00000000000..1406640a69c Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-diamond_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-diamond_3.png b/public/images/pokemon/icons/variant/6/676-diamond_3.png new file mode 100644 index 00000000000..ccf477d6819 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-diamond_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-heart_2.png b/public/images/pokemon/icons/variant/6/676-heart_2.png new file mode 100644 index 00000000000..7f3607f8579 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-heart_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-heart_3.png b/public/images/pokemon/icons/variant/6/676-heart_3.png new file mode 100644 index 00000000000..e8256f783ba Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-heart_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-kabuki_2.png b/public/images/pokemon/icons/variant/6/676-kabuki_2.png new file mode 100644 index 00000000000..ea78810582a Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-kabuki_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-kabuki_3.png b/public/images/pokemon/icons/variant/6/676-kabuki_3.png new file mode 100644 index 00000000000..f8501bec610 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-kabuki_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-la-reine_2.png b/public/images/pokemon/icons/variant/6/676-la-reine_2.png new file mode 100644 index 00000000000..5d4cb6bbea0 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-la-reine_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-la-reine_3.png b/public/images/pokemon/icons/variant/6/676-la-reine_3.png new file mode 100644 index 00000000000..57488ba17e2 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-la-reine_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-matron_2.png b/public/images/pokemon/icons/variant/6/676-matron_2.png new file mode 100644 index 00000000000..e7bd18d5a10 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-matron_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-matron_3.png b/public/images/pokemon/icons/variant/6/676-matron_3.png new file mode 100644 index 00000000000..a8870d9ed20 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-matron_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-pharaoh_2.png b/public/images/pokemon/icons/variant/6/676-pharaoh_2.png new file mode 100644 index 00000000000..96d60fa6d4c Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-pharaoh_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-pharaoh_3.png b/public/images/pokemon/icons/variant/6/676-pharaoh_3.png new file mode 100644 index 00000000000..db2de83c8ef Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-pharaoh_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676-star_2.png b/public/images/pokemon/icons/variant/6/676-star_2.png new file mode 100644 index 00000000000..e2a58c698f6 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-star_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676-star_3.png b/public/images/pokemon/icons/variant/6/676-star_3.png new file mode 100644 index 00000000000..7c4fdc4efb1 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676-star_3.png differ diff --git a/public/images/pokemon/icons/variant/6/676_2.png b/public/images/pokemon/icons/variant/6/676_2.png new file mode 100644 index 00000000000..56bcc1a7a34 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676_2.png differ diff --git a/public/images/pokemon/icons/variant/6/676_3.png b/public/images/pokemon/icons/variant/6/676_3.png new file mode 100644 index 00000000000..accb6f96f66 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/676_3.png differ diff --git a/public/images/pokemon/icons/variant/6/682_2.png b/public/images/pokemon/icons/variant/6/682_2.png new file mode 100644 index 00000000000..59c05cce665 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/682_2.png differ diff --git a/public/images/pokemon/icons/variant/6/682_3.png b/public/images/pokemon/icons/variant/6/682_3.png new file mode 100644 index 00000000000..a7c73e94eef Binary files /dev/null and b/public/images/pokemon/icons/variant/6/682_3.png differ diff --git a/public/images/pokemon/icons/variant/6/683_2.png b/public/images/pokemon/icons/variant/6/683_2.png new file mode 100644 index 00000000000..7f64665f9d7 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/683_2.png differ diff --git a/public/images/pokemon/icons/variant/6/683_3.png b/public/images/pokemon/icons/variant/6/683_3.png new file mode 100644 index 00000000000..b09a0be5fd2 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/683_3.png differ diff --git a/public/images/pokemon/icons/variant/6/684_2.png b/public/images/pokemon/icons/variant/6/684_2.png new file mode 100644 index 00000000000..2fccca23416 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/684_2.png differ diff --git a/public/images/pokemon/icons/variant/6/684_3.png b/public/images/pokemon/icons/variant/6/684_3.png new file mode 100644 index 00000000000..9c09475db49 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/684_3.png differ diff --git a/public/images/pokemon/icons/variant/6/685_2.png b/public/images/pokemon/icons/variant/6/685_2.png new file mode 100644 index 00000000000..8f52850dd2d Binary files /dev/null and b/public/images/pokemon/icons/variant/6/685_2.png differ diff --git a/public/images/pokemon/icons/variant/6/685_3.png b/public/images/pokemon/icons/variant/6/685_3.png new file mode 100644 index 00000000000..ebad502551e Binary files /dev/null and b/public/images/pokemon/icons/variant/6/685_3.png differ diff --git a/public/images/pokemon/icons/variant/6/688_2.png b/public/images/pokemon/icons/variant/6/688_2.png new file mode 100644 index 00000000000..6fe8ba9c770 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/688_2.png differ diff --git a/public/images/pokemon/icons/variant/6/688_3.png b/public/images/pokemon/icons/variant/6/688_3.png new file mode 100644 index 00000000000..9586c3203a9 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/688_3.png differ diff --git a/public/images/pokemon/icons/variant/6/689_2.png b/public/images/pokemon/icons/variant/6/689_2.png new file mode 100644 index 00000000000..66305ef69e8 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/689_2.png differ diff --git a/public/images/pokemon/icons/variant/6/689_3.png b/public/images/pokemon/icons/variant/6/689_3.png new file mode 100644 index 00000000000..2bdfea0ddd0 Binary files /dev/null and b/public/images/pokemon/icons/variant/6/689_3.png differ diff --git a/public/images/pokemon/icons/variant/7/2026_2.png b/public/images/pokemon/icons/variant/7/2026_2.png new file mode 100644 index 00000000000..3b939a6c1fc Binary files /dev/null and b/public/images/pokemon/icons/variant/7/2026_2.png differ diff --git a/public/images/pokemon/icons/variant/7/2026_3.png b/public/images/pokemon/icons/variant/7/2026_3.png new file mode 100644 index 00000000000..f530b9cfcb3 Binary files /dev/null and b/public/images/pokemon/icons/variant/7/2026_3.png differ diff --git a/public/images/pokemon/icons/variant/7/2103_2.png b/public/images/pokemon/icons/variant/7/2103_2.png new file mode 100644 index 00000000000..d3795c35070 Binary files /dev/null and b/public/images/pokemon/icons/variant/7/2103_2.png differ diff --git a/public/images/pokemon/icons/variant/7/2103_3.png b/public/images/pokemon/icons/variant/7/2103_3.png new file mode 100644 index 00000000000..e24ba1eb917 Binary files /dev/null and b/public/images/pokemon/icons/variant/7/2103_3.png differ diff --git a/public/images/pokemon/icons/variant/7/807_2.png b/public/images/pokemon/icons/variant/7/807_2.png new file mode 100644 index 00000000000..6e070af347d Binary files /dev/null and b/public/images/pokemon/icons/variant/7/807_2.png differ diff --git a/public/images/pokemon/icons/variant/7/807_3.png b/public/images/pokemon/icons/variant/7/807_3.png new file mode 100644 index 00000000000..19e59272f86 Binary files /dev/null and b/public/images/pokemon/icons/variant/7/807_3.png differ diff --git a/public/images/pokemon/icons/variant/8/6503_2.png b/public/images/pokemon/icons/variant/8/6503_2.png new file mode 100644 index 00000000000..0098615187e Binary files /dev/null and b/public/images/pokemon/icons/variant/8/6503_2.png differ diff --git a/public/images/pokemon/icons/variant/8/6503_3.png b/public/images/pokemon/icons/variant/8/6503_3.png new file mode 100644 index 00000000000..64428182df0 Binary files /dev/null and b/public/images/pokemon/icons/variant/8/6503_3.png differ diff --git a/public/images/pokemon/icons/variant/8/851-gigantamax.png b/public/images/pokemon/icons/variant/8/851-gigantamax.png new file mode 100644 index 00000000000..e757af7b4fa Binary files /dev/null and b/public/images/pokemon/icons/variant/8/851-gigantamax.png differ diff --git a/public/images/pokemon/icons/variant/8/851-gigantamax_2.png b/public/images/pokemon/icons/variant/8/851-gigantamax_2.png new file mode 100644 index 00000000000..081d8284b3d Binary files /dev/null and b/public/images/pokemon/icons/variant/8/851-gigantamax_2.png differ diff --git a/public/images/pokemon/icons/variant/8/851-gigantamax_3.png b/public/images/pokemon/icons/variant/8/851-gigantamax_3.png new file mode 100644 index 00000000000..6d26a7395f2 Binary files /dev/null and b/public/images/pokemon/icons/variant/8/851-gigantamax_3.png differ diff --git a/public/images/pokemon/icons/variant/8/851s-gigantamax.png b/public/images/pokemon/icons/variant/8/851s-gigantamax.png new file mode 100644 index 00000000000..73fb57b8a5a Binary files /dev/null and b/public/images/pokemon/icons/variant/8/851s-gigantamax.png differ diff --git a/public/images/pokemon/icons/variant/8/894_2.png b/public/images/pokemon/icons/variant/8/894_2.png new file mode 100644 index 00000000000..2b4754d56a0 Binary files /dev/null and b/public/images/pokemon/icons/variant/8/894_2.png differ diff --git a/public/images/pokemon/icons/variant/8/894_3.png b/public/images/pokemon/icons/variant/8/894_3.png new file mode 100644 index 00000000000..cc5baef46cc Binary files /dev/null and b/public/images/pokemon/icons/variant/8/894_3.png differ diff --git a/public/images/pokemon/icons/variant/8/895_2.png b/public/images/pokemon/icons/variant/8/895_2.png new file mode 100644 index 00000000000..bdacf0683ee Binary files /dev/null and b/public/images/pokemon/icons/variant/8/895_2.png differ diff --git a/public/images/pokemon/icons/variant/8/895_3.png b/public/images/pokemon/icons/variant/8/895_3.png new file mode 100644 index 00000000000..9ac023e2e89 Binary files /dev/null and b/public/images/pokemon/icons/variant/8/895_3.png differ diff --git a/public/images/pokemon/icons/variant/8/909_2.png b/public/images/pokemon/icons/variant/8/909_2.png deleted file mode 100644 index 73f71bd49d3..00000000000 Binary files a/public/images/pokemon/icons/variant/8/909_2.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/8/909_3.png b/public/images/pokemon/icons/variant/8/909_3.png deleted file mode 100644 index 5fb79e5b917..00000000000 Binary files a/public/images/pokemon/icons/variant/8/909_3.png and /dev/null differ diff --git a/public/images/pokemon/icons/variant/8/1003_2.png b/public/images/pokemon/icons/variant/9/1003_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/1003_2.png rename to public/images/pokemon/icons/variant/9/1003_2.png diff --git a/public/images/pokemon/icons/variant/8/1003_3.png b/public/images/pokemon/icons/variant/9/1003_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/1003_3.png rename to public/images/pokemon/icons/variant/9/1003_3.png diff --git a/public/images/pokemon/icons/variant/8/1006_2.png b/public/images/pokemon/icons/variant/9/1006_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/1006_2.png rename to public/images/pokemon/icons/variant/9/1006_2.png diff --git a/public/images/pokemon/icons/variant/8/1006_3.png b/public/images/pokemon/icons/variant/9/1006_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/1006_3.png rename to public/images/pokemon/icons/variant/9/1006_3.png diff --git a/public/images/pokemon/icons/variant/8/1010_2.png b/public/images/pokemon/icons/variant/9/1010_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/1010_2.png rename to public/images/pokemon/icons/variant/9/1010_2.png diff --git a/public/images/pokemon/icons/variant/8/1010_3.png b/public/images/pokemon/icons/variant/9/1010_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/1010_3.png rename to public/images/pokemon/icons/variant/9/1010_3.png diff --git a/public/images/pokemon/icons/variant/9/1012-counterfeit_2.png b/public/images/pokemon/icons/variant/9/1012-counterfeit_2.png new file mode 100644 index 00000000000..19fa8603c69 Binary files /dev/null and b/public/images/pokemon/icons/variant/9/1012-counterfeit_2.png differ diff --git a/public/images/pokemon/icons/variant/9/1012-counterfeit_3.png b/public/images/pokemon/icons/variant/9/1012-counterfeit_3.png new file mode 100644 index 00000000000..04f74b0fd3a Binary files /dev/null and b/public/images/pokemon/icons/variant/9/1012-counterfeit_3.png differ diff --git a/public/images/pokemon/icons/variant/9/1013-unremarkable_2.png b/public/images/pokemon/icons/variant/9/1013-unremarkable_2.png new file mode 100644 index 00000000000..3588b5e2641 Binary files /dev/null and b/public/images/pokemon/icons/variant/9/1013-unremarkable_2.png differ diff --git a/public/images/pokemon/icons/variant/9/1013-unremarkable_3.png b/public/images/pokemon/icons/variant/9/1013-unremarkable_3.png new file mode 100644 index 00000000000..acdb6716ab8 Binary files /dev/null and b/public/images/pokemon/icons/variant/9/1013-unremarkable_3.png differ diff --git a/public/images/pokemon/icons/variant/9/909_2.png b/public/images/pokemon/icons/variant/9/909_2.png index 95cf5e14d4e..73f71bd49d3 100644 Binary files a/public/images/pokemon/icons/variant/9/909_2.png and b/public/images/pokemon/icons/variant/9/909_2.png differ diff --git a/public/images/pokemon/icons/variant/9/909_3.png b/public/images/pokemon/icons/variant/9/909_3.png index d4d7a9593a4..5fb79e5b917 100644 Binary files a/public/images/pokemon/icons/variant/9/909_3.png and b/public/images/pokemon/icons/variant/9/909_3.png differ diff --git a/public/images/pokemon/icons/variant/8/912_2.png b/public/images/pokemon/icons/variant/9/912_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/912_2.png rename to public/images/pokemon/icons/variant/9/912_2.png diff --git a/public/images/pokemon/icons/variant/8/912_3.png b/public/images/pokemon/icons/variant/9/912_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/912_3.png rename to public/images/pokemon/icons/variant/9/912_3.png diff --git a/public/images/pokemon/icons/variant/8/913_2.png b/public/images/pokemon/icons/variant/9/913_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/913_2.png rename to public/images/pokemon/icons/variant/9/913_2.png diff --git a/public/images/pokemon/icons/variant/8/913_3.png b/public/images/pokemon/icons/variant/9/913_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/913_3.png rename to public/images/pokemon/icons/variant/9/913_3.png diff --git a/public/images/pokemon/icons/variant/8/914_2.png b/public/images/pokemon/icons/variant/9/914_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/914_2.png rename to public/images/pokemon/icons/variant/9/914_2.png diff --git a/public/images/pokemon/icons/variant/8/914_3.png b/public/images/pokemon/icons/variant/9/914_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/914_3.png rename to public/images/pokemon/icons/variant/9/914_3.png diff --git a/public/images/pokemon/icons/variant/8/940_2.png b/public/images/pokemon/icons/variant/9/940_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/940_2.png rename to public/images/pokemon/icons/variant/9/940_2.png diff --git a/public/images/pokemon/icons/variant/8/940_3.png b/public/images/pokemon/icons/variant/9/940_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/940_3.png rename to public/images/pokemon/icons/variant/9/940_3.png diff --git a/public/images/pokemon/icons/variant/8/941_2.png b/public/images/pokemon/icons/variant/9/941_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/941_2.png rename to public/images/pokemon/icons/variant/9/941_2.png diff --git a/public/images/pokemon/icons/variant/8/941_3.png b/public/images/pokemon/icons/variant/9/941_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/941_3.png rename to public/images/pokemon/icons/variant/9/941_3.png diff --git a/public/images/pokemon/variant/back/6706_3.png b/public/images/pokemon/icons/variant/9/944_2.png similarity index 56% rename from public/images/pokemon/variant/back/6706_3.png rename to public/images/pokemon/icons/variant/9/944_2.png index fb780d01499..70af4937c8f 100644 Binary files a/public/images/pokemon/variant/back/6706_3.png and b/public/images/pokemon/icons/variant/9/944_2.png differ diff --git a/public/images/pokemon/variant/6706_2.png b/public/images/pokemon/icons/variant/9/944_3.png similarity index 51% rename from public/images/pokemon/variant/6706_2.png rename to public/images/pokemon/icons/variant/9/944_3.png index 7cf1495d1a3..ef7618c9a9c 100644 Binary files a/public/images/pokemon/variant/6706_2.png and b/public/images/pokemon/icons/variant/9/944_3.png differ diff --git a/public/images/pokemon/variant/6706_3.png b/public/images/pokemon/icons/variant/9/945_2.png similarity index 51% rename from public/images/pokemon/variant/6706_3.png rename to public/images/pokemon/icons/variant/9/945_2.png index 001cab641f1..5a4a7c6ebe5 100644 Binary files a/public/images/pokemon/variant/6706_3.png and b/public/images/pokemon/icons/variant/9/945_2.png differ diff --git a/public/images/pokemon/icons/variant/9/945_3.png b/public/images/pokemon/icons/variant/9/945_3.png new file mode 100644 index 00000000000..1dad94c543c Binary files /dev/null and b/public/images/pokemon/icons/variant/9/945_3.png differ diff --git a/public/images/pokemon/icons/variant/8/953_2.png b/public/images/pokemon/icons/variant/9/953_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/953_2.png rename to public/images/pokemon/icons/variant/9/953_2.png diff --git a/public/images/pokemon/icons/variant/8/953_3.png b/public/images/pokemon/icons/variant/9/953_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/953_3.png rename to public/images/pokemon/icons/variant/9/953_3.png diff --git a/public/images/pokemon/icons/variant/8/954_2.png b/public/images/pokemon/icons/variant/9/954_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/954_2.png rename to public/images/pokemon/icons/variant/9/954_2.png diff --git a/public/images/pokemon/icons/variant/8/954_3.png b/public/images/pokemon/icons/variant/9/954_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/954_3.png rename to public/images/pokemon/icons/variant/9/954_3.png diff --git a/public/images/pokemon/icons/variant/8/981_2.png b/public/images/pokemon/icons/variant/9/981_2.png similarity index 100% rename from public/images/pokemon/icons/variant/8/981_2.png rename to public/images/pokemon/icons/variant/9/981_2.png diff --git a/public/images/pokemon/icons/variant/8/981_3.png b/public/images/pokemon/icons/variant/9/981_3.png similarity index 100% rename from public/images/pokemon/icons/variant/8/981_3.png rename to public/images/pokemon/icons/variant/9/981_3.png diff --git a/public/images/pokemon/shiny/194.png b/public/images/pokemon/shiny/194.png index 2e33bbfd005..38800a7d545 100644 Binary files a/public/images/pokemon/shiny/194.png and b/public/images/pokemon/shiny/194.png differ diff --git a/public/images/pokemon/shiny/275.png b/public/images/pokemon/shiny/275.png index fee57d64804..de8271cdbd2 100644 Binary files a/public/images/pokemon/shiny/275.png and b/public/images/pokemon/shiny/275.png differ diff --git a/public/images/pokemon/shiny/281.json b/public/images/pokemon/shiny/281.json index 684be77edf9..64e10c7f9a6 100644 --- a/public/images/pokemon/shiny/281.json +++ b/public/images/pokemon/shiny/281.json @@ -399,13 +399,13 @@ "x": 0, "y": 6, "w": 36, - "h": 55 + "h": 54 }, "frame": { "x": 72, "y": 55, "w": 36, - "h": 55 + "h": 54 } }, { @@ -420,13 +420,13 @@ "x": 0, "y": 6, "w": 36, - "h": 55 + "h": 54 }, "frame": { "x": 72, "y": 55, "w": 36, - "h": 55 + "h": 54 } }, { diff --git a/public/images/pokemon/shiny/378.png b/public/images/pokemon/shiny/378.png index 62322276ec1..7674ac1873a 100644 Binary files a/public/images/pokemon/shiny/378.png and b/public/images/pokemon/shiny/378.png differ diff --git a/public/images/pokemon/shiny/436.json b/public/images/pokemon/shiny/436.json index 945a840b477..6206c5e66cb 100644 --- a/public/images/pokemon/shiny/436.json +++ b/public/images/pokemon/shiny/436.json @@ -1,2666 +1,1019 @@ -{ - "textures": [ - { - "image": "436.png", - "format": "RGBA8888", - "size": { - "w": 97, - "h": 97 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 1, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 2, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 1, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 1, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0097.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0098.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0101.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0102.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0105.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0106.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0107.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 17, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0108.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 10, - "y": 17, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0111.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0112.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0113.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 15, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0114.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 15, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0115.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0116.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0117.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0118.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0119.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0120.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0121.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0122.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 8, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0123.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0124.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0125.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0126.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 12, - "w": 33, - "h": 39 - }, - "frame": { - "x": 0, - "y": 0, - "w": 33, - "h": 39 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 32, - "h": 39 - }, - "frame": { - "x": 33, - "y": 0, - "w": 32, - "h": 39 - } - }, - { - "filename": "0096.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 32, - "h": 39 - }, - "frame": { - "x": 33, - "y": 0, - "w": 32, - "h": 39 - } - }, - { - "filename": "0103.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 15, - "y": 9, - "w": 32, - "h": 39 - }, - "frame": { - "x": 65, - "y": 0, - "w": 32, - "h": 39 - } - }, - { - "filename": "0104.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 15, - "y": 9, - "w": 32, - "h": 39 - }, - "frame": { - "x": 65, - "y": 0, - "w": 32, - "h": 39 - } - }, - { - "filename": "0099.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 33, - "h": 38 - }, - "frame": { - "x": 0, - "y": 39, - "w": 33, - "h": 38 - } - }, - { - "filename": "0100.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 33, - "h": 38 - }, - "frame": { - "x": 0, - "y": 39, - "w": 33, - "h": 38 - } - }, - { - "filename": "0109.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 21, - "w": 33, - "h": 38 - }, - "frame": { - "x": 33, - "y": 39, - "w": 33, - "h": 38 - } - }, - { - "filename": "0110.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 47, - "h": 59 - }, - "spriteSourceSize": { - "x": 5, - "y": 21, - "w": 33, - "h": 38 - }, - "frame": { - "x": 33, - "y": 39, - "w": 33, - "h": 38 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:de8b910298717773b7a2a224a56b3553:df42ff52dc55f342b76506445413ffee:0a3bacf3d680738b160c4c8ace3cda59$" - } -} +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0005.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0008.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0009.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0010.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0011.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0012.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0014.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0015.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0018.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0019.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0020.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0021.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0022.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0023.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0024.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0025.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0026.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0027.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0028.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0029.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0030.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0031.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0032.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0033.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0034.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0035.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0036.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0037.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0038.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0039.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0040.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0041.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0042.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0043.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0044.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0045.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0046.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0047.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0048.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0049.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0050.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0051.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0052.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0053.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0054.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0055.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0056.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0057.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0058.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0059.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 6, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0060.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 6, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0061.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0062.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0063.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0064.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0065.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0066.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0067.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0068.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0069.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0070.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0071.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0072.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0073.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0074.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0075.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0076.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0077.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 4, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0078.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 5, "y": 4, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0079.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 3, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0080.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 3, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0081.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 4, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0082.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 4, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0083.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0084.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0085.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0086.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0087.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0088.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 12, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0089.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0090.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0091.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0092.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0093.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0094.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0095.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 5, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0096.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 5, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0097.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0098.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0099.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 0, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0100.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 0, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0101.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 5, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0102.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 5, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0103.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0104.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 16, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0105.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 15, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0106.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 14, "y": 15, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0107.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 18, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0108.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 18, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0109.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 22, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0110.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 6, "y": 22, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0111.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 19, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0112.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 7, "y": 19, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0113.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0114.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 16, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0115.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0116.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 9, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0117.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0118.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 10, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0119.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0120.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 7, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0121.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0122.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 9, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0123.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0124.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 11, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0125.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + }, + { + "filename": "0126.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 37 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 8, "y": 13, "w": 31, "h": 37 }, + "sourceSize": { "w": 47, "h": 59 } + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "436.png", + "format": "RGBA8888", + "size": { "w": 31, "h": 37 }, + "scale": "1" + } +} diff --git a/public/images/pokemon/shiny/436.png b/public/images/pokemon/shiny/436.png index 59003ba85dc..87263bbbe6c 100644 Binary files a/public/images/pokemon/shiny/436.png and b/public/images/pokemon/shiny/436.png differ diff --git a/public/images/pokemon/shiny/451.json b/public/images/pokemon/shiny/451.json index 3a320a87c61..f492cdbcb04 100644 --- a/public/images/pokemon/shiny/451.json +++ b/public/images/pokemon/shiny/451.json @@ -1,715 +1,2330 @@ -{ "frames": [ - { - "filename": "0001.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0002.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0003.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0004.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0005.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0006.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0007.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0008.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0009.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0010.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0011.png", - "frame": { "x": 68, "y": 0, "w": 64, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 64, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0012.png", - "frame": { "x": 68, "y": 0, "w": 64, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 64, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0013.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0014.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0015.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0016.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0017.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0018.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0019.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0020.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0021.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0022.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0023.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0024.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0025.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0026.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0027.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0028.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0029.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0030.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0031.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0032.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0033.png", - "frame": { "x": 68, "y": 0, "w": 64, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 64, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0034.png", - "frame": { "x": 68, "y": 0, "w": 64, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 64, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0035.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0036.png", - "frame": { "x": 177, "y": 42, "w": 61, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 61, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0037.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0038.png", - "frame": { "x": 238, "y": 43, "w": 59, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 59, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0039.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0040.png", - "frame": { "x": 0, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0041.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0042.png", - "frame": { "x": 57, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0043.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0044.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0045.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0046.png", - "frame": { "x": 287, "y": 86, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0047.png", - "frame": { "x": 232, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0048.png", - "frame": { "x": 232, "y": 86, "w": 55, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 55, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0049.png", - "frame": { "x": 117, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0050.png", - "frame": { "x": 117, "y": 85, "w": 57, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 57, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0051.png", - "frame": { "x": 117, "y": 42, "w": 60, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 60, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0052.png", - "frame": { "x": 117, "y": 42, "w": 60, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 60, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0053.png", - "frame": { "x": 132, "y": 0, "w": 63, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 63, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0054.png", - "frame": { "x": 132, "y": 0, "w": 63, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 63, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0055.png", - "frame": { "x": 0, "y": 0, "w": 68, "h": 40 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 6, "w": 68, "h": 40 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0056.png", - "frame": { "x": 0, "y": 0, "w": 68, "h": 40 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 6, "w": 68, "h": 40 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0057.png", - "frame": { "x": 195, "y": 0, "w": 63, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 63, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0058.png", - "frame": { "x": 195, "y": 0, "w": 63, "h": 42 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 63, "h": 42 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0059.png", - "frame": { "x": 258, "y": 0, "w": 61, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 61, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0060.png", - "frame": { "x": 258, "y": 0, "w": 61, "h": 43 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 61, "h": 43 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0061.png", - "frame": { "x": 58, "y": 42, "w": 59, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 59, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0062.png", - "frame": { "x": 58, "y": 42, "w": 59, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 59, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0063.png", - "frame": { "x": 0, "y": 40, "w": 58, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 58, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0064.png", - "frame": { "x": 0, "y": 40, "w": 58, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 58, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0065.png", - "frame": { "x": 177, "y": 84, "w": 55, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 55, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0066.png", - "frame": { "x": 177, "y": 84, "w": 55, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 55, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0067.png", - "frame": { "x": 0, "y": 129, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0068.png", - "frame": { "x": 0, "y": 129, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0069.png", - "frame": { "x": 112, "y": 129, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0070.png", - "frame": { "x": 112, "y": 129, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0071.png", - "frame": { "x": 167, "y": 130, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0072.png", - "frame": { "x": 167, "y": 130, "w": 55, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 55, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0073.png", - "frame": { "x": 0, "y": 173, "w": 54, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 54, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0074.png", - "frame": { "x": 0, "y": 173, "w": 54, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 54, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0075.png", - "frame": { "x": 54, "y": 177, "w": 52, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 52, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0076.png", - "frame": { "x": 54, "y": 177, "w": 52, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 2, "w": 52, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0077.png", - "frame": { "x": 210, "y": 176, "w": 53, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 2, "w": 53, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0078.png", - "frame": { "x": 210, "y": 176, "w": 53, "h": 44 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 2, "w": 53, "h": 44 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0079.png", - "frame": { "x": 158, "y": 174, "w": 52, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 52, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0080.png", - "frame": { "x": 158, "y": 174, "w": 52, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 1, "w": 52, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0081.png", - "frame": { "x": 222, "y": 131, "w": 53, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 53, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0082.png", - "frame": { "x": 222, "y": 131, "w": 53, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 53, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0083.png", - "frame": { "x": 275, "y": 132, "w": 53, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 53, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0084.png", - "frame": { "x": 275, "y": 132, "w": 53, "h": 45 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 53, "h": 45 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0085.png", - "frame": { "x": 55, "y": 131, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0086.png", - "frame": { "x": 55, "y": 131, "w": 52, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 52, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0087.png", - "frame": { "x": 107, "y": 173, "w": 51, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 51, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - }, - { - "filename": "0088.png", - "frame": { "x": 107, "y": 173, "w": 51, "h": 46 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 51, "h": 46 }, - "sourceSize": { "w": 71, "h": 46 } - } - ], - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.8.1-x64", - "image": "451.png", - "format": "I8", - "size": { "w": 339, "h": 221 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "451.png", + "format": "RGBA8888", + "size": { + "w": 281, + "h": 281 + }, + "scale": 1, + "frames": [ + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 69, + "h": 41 + }, + "frame": { + "x": 0, + "y": 0, + "w": 69, + "h": 41 + } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 69, + "h": 41 + }, + "frame": { + "x": 0, + "y": 0, + "w": 69, + "h": 41 + } + }, + { + "filename": "0077.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 69, + "h": 41 + }, + "frame": { + "x": 0, + "y": 0, + "w": 69, + "h": 41 + } + }, + { + "filename": "0078.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 69, + "h": 41 + }, + "frame": { + "x": 0, + "y": 0, + "w": 69, + "h": 41 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0054.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0057.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0058.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 63, + "h": 43 + }, + "frame": { + "x": 69, + "y": 0, + "w": 63, + "h": 43 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 66, + "h": 43 + }, + "frame": { + "x": 132, + "y": 0, + "w": 66, + "h": 43 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 66, + "h": 43 + }, + "frame": { + "x": 132, + "y": 0, + "w": 66, + "h": 43 + } + }, + { + "filename": "0055.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 66, + "h": 43 + }, + "frame": { + "x": 132, + "y": 0, + "w": 66, + "h": 43 + } + }, + { + "filename": "0056.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 66, + "h": 43 + }, + "frame": { + "x": 132, + "y": 0, + "w": 66, + "h": 43 + } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 198, + "y": 0, + "w": 65, + "h": 43 + } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 198, + "y": 0, + "w": 65, + "h": 43 + } + }, + { + "filename": "0075.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 198, + "y": 0, + "w": 65, + "h": 43 + } + }, + { + "filename": "0076.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 198, + "y": 0, + "w": 65, + "h": 43 + } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 0, + "y": 41, + "w": 65, + "h": 43 + } + }, + { + "filename": "0036.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 0, + "y": 41, + "w": 65, + "h": 43 + } + }, + { + "filename": "0079.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 0, + "y": 41, + "w": 65, + "h": 43 + } + }, + { + "filename": "0080.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 65, + "h": 43 + }, + "frame": { + "x": 0, + "y": 41, + "w": 65, + "h": 43 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0059.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0060.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 61, + "h": 44 + }, + "frame": { + "x": 65, + "y": 43, + "w": 61, + "h": 44 + } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 62, + "h": 44 + }, + "frame": { + "x": 126, + "y": 43, + "w": 62, + "h": 44 + } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 62, + "h": 44 + }, + "frame": { + "x": 126, + "y": 43, + "w": 62, + "h": 44 + } + }, + { + "filename": "0073.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 62, + "h": 44 + }, + "frame": { + "x": 126, + "y": 43, + "w": 62, + "h": 44 + } + }, + { + "filename": "0074.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 62, + "h": 44 + }, + "frame": { + "x": 126, + "y": 43, + "w": 62, + "h": 44 + } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 2, + "w": 63, + "h": 44 + }, + "frame": { + "x": 188, + "y": 43, + "w": 63, + "h": 44 + } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 2, + "w": 63, + "h": 44 + }, + "frame": { + "x": 188, + "y": 43, + "w": 63, + "h": 44 + } + }, + { + "filename": "0081.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 2, + "w": 63, + "h": 44 + }, + "frame": { + "x": 188, + "y": 43, + "w": 63, + "h": 44 + } + }, + { + "filename": "0082.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 2, + "w": 63, + "h": 44 + }, + "frame": { + "x": 188, + "y": 43, + "w": 63, + "h": 44 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0061.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0062.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 0, + "y": 84, + "w": 59, + "h": 45 + } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 59, + "y": 87, + "w": 59, + "h": 45 + } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 59, + "y": 87, + "w": 59, + "h": 45 + } + }, + { + "filename": "0071.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 59, + "y": 87, + "w": 59, + "h": 45 + } + }, + { + "filename": "0072.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 59, + "h": 45 + }, + "frame": { + "x": 59, + "y": 87, + "w": 59, + "h": 45 + } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 1, + "w": 61, + "h": 45 + }, + "frame": { + "x": 118, + "y": 87, + "w": 61, + "h": 45 + } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 1, + "w": 61, + "h": 45 + }, + "frame": { + "x": 118, + "y": 87, + "w": 61, + "h": 45 + } + }, + { + "filename": "0083.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 1, + "w": 61, + "h": 45 + }, + "frame": { + "x": 118, + "y": 87, + "w": 61, + "h": 45 + } + }, + { + "filename": "0084.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 1, + "w": 61, + "h": 45 + }, + "frame": { + "x": 118, + "y": 87, + "w": 61, + "h": 45 + } + }, + { + "filename": "0089.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 179, + "y": 87, + "w": 57, + "h": 45 + } + }, + { + "filename": "0090.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 179, + "y": 87, + "w": 57, + "h": 45 + } + }, + { + "filename": "0091.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 0, + "y": 129, + "w": 57, + "h": 45 + } + }, + { + "filename": "0092.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 0, + "y": 129, + "w": 57, + "h": 45 + } + }, + { + "filename": "0093.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 57, + "y": 132, + "w": 57, + "h": 45 + } + }, + { + "filename": "0094.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 57, + "h": 45 + }, + "frame": { + "x": 57, + "y": 132, + "w": 57, + "h": 45 + } + }, + { + "filename": "0095.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 56, + "h": 45 + }, + "frame": { + "x": 114, + "y": 132, + "w": 56, + "h": 45 + } + }, + { + "filename": "0096.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 56, + "h": 45 + }, + "frame": { + "x": 114, + "y": 132, + "w": 56, + "h": 45 + } + }, + { + "filename": "0097.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 54, + "h": 45 + }, + "frame": { + "x": 170, + "y": 132, + "w": 54, + "h": 45 + } + }, + { + "filename": "0098.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 54, + "h": 45 + }, + "frame": { + "x": 170, + "y": 132, + "w": 54, + "h": 45 + } + }, + { + "filename": "0099.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 0, + "y": 1, + "w": 54, + "h": 45 + }, + "frame": { + "x": 224, + "y": 132, + "w": 54, + "h": 45 + } + }, + { + "filename": "0100.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 0, + "y": 1, + "w": 54, + "h": 45 + }, + "frame": { + "x": 224, + "y": 132, + "w": 54, + "h": 45 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0065.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0066.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0067.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0068.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 174, + "w": 54, + "h": 46 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0063.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0064.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 111, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 111, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0069.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 111, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0070.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 111, + "y": 177, + "w": 57, + "h": 46 + } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 60, + "h": 46 + }, + "frame": { + "x": 168, + "y": 177, + "w": 60, + "h": 46 + } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 60, + "h": 46 + }, + "frame": { + "x": 168, + "y": 177, + "w": 60, + "h": 46 + } + }, + { + "filename": "0085.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 60, + "h": 46 + }, + "frame": { + "x": 168, + "y": 177, + "w": 60, + "h": 46 + } + }, + { + "filename": "0086.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 60, + "h": 46 + }, + "frame": { + "x": 168, + "y": 177, + "w": 60, + "h": 46 + } + }, + { + "filename": "0109.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 53, + "h": 46 + }, + "frame": { + "x": 228, + "y": 177, + "w": 53, + "h": 46 + } + }, + { + "filename": "0110.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 6, + "y": 0, + "w": 53, + "h": 46 + }, + "frame": { + "x": 228, + "y": 177, + "w": 53, + "h": 46 + } + }, + { + "filename": "0101.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 220, + "w": 54, + "h": 46 + } + }, + { + "filename": "0102.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 0, + "y": 220, + "w": 54, + "h": 46 + } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 223, + "w": 57, + "h": 46 + } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 223, + "w": 57, + "h": 46 + } + }, + { + "filename": "0087.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 223, + "w": 57, + "h": 46 + } + }, + { + "filename": "0088.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 57, + "h": 46 + }, + "frame": { + "x": 54, + "y": 223, + "w": 57, + "h": 46 + } + }, + { + "filename": "0103.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 111, + "y": 223, + "w": 55, + "h": 46 + } + }, + { + "filename": "0104.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 2, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 111, + "y": 223, + "w": 55, + "h": 46 + } + }, + { + "filename": "0105.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 166, + "y": 223, + "w": 55, + "h": 46 + } + }, + { + "filename": "0106.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 3, + "y": 0, + "w": 55, + "h": 46 + }, + "frame": { + "x": 166, + "y": 223, + "w": 55, + "h": 46 + } + }, + { + "filename": "0107.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 221, + "y": 223, + "w": 54, + "h": 46 + } + }, + { + "filename": "0108.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 71, + "h": 46 + }, + "spriteSourceSize": { + "x": 5, + "y": 0, + "w": 54, + "h": 46 + }, + "frame": { + "x": 221, + "y": 223, + "w": 54, + "h": 46 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:9097bf5ffed4b93401c65aa14299faaa:d22b7c7f6e33b1453fda428e689d4529:c79e17c206de27e3b7f1ce96f7df8e51$" + } } diff --git a/public/images/pokemon/shiny/451.png b/public/images/pokemon/shiny/451.png index 4f8120ce668..69d165c9ae8 100644 Binary files a/public/images/pokemon/shiny/451.png and b/public/images/pokemon/shiny/451.png differ diff --git a/public/images/pokemon/shiny/658-ash.json b/public/images/pokemon/shiny/658-ash.json index 7ac419b1686..c2b8eede9ef 100644 --- a/public/images/pokemon/shiny/658-ash.json +++ b/public/images/pokemon/shiny/658-ash.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "658-ash.png", - "format": "RGBA8888", - "size": { - "w": 79, - "h": 79 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 79, - "h": 74 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 0, - "w": 79, - "h": 74 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:3dd081ba5490f090a73de8423aac2f6b:f088fafaea755476f2abf488e7340cab:bfbf521a5c7bd80bcd95a96d9789c0dd$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 }, + "sourceSize": { "w": 79, "h": 74 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 79, "h": 74 }, + "scale": "1" + } } diff --git a/public/images/pokemon/shiny/658-ash.png b/public/images/pokemon/shiny/658-ash.png index 0d65f0bb900..f5de608708e 100644 Binary files a/public/images/pokemon/shiny/658-ash.png and b/public/images/pokemon/shiny/658-ash.png differ diff --git a/public/images/pokemon/shiny/658.json b/public/images/pokemon/shiny/658.json index 92f9b29175c..219645ec240 100644 --- a/public/images/pokemon/shiny/658.json +++ b/public/images/pokemon/shiny/658.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "658.png", - "format": "RGBA8888", - "size": { - "w": 75, - "h": 75 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 75, - "h": 65 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 75, - "h": 65 - }, - "frame": { - "x": 0, - "y": 0, - "w": 75, - "h": 65 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:be07c062265a19e890f1e2d2d1b5527d:ad4583a5a0498c496e9a93574c55ee03:5affcab976148657d36bf4ff3410f92d$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 85, "h": 67 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 85, "h": 67 }, + "sourceSize": { "w": 85, "h": 67 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 85, "h": 67 }, + "scale": "1" + } } diff --git a/public/images/pokemon/shiny/658.png b/public/images/pokemon/shiny/658.png index 6fb80fd57cc..100d2a02f4a 100644 Binary files a/public/images/pokemon/shiny/658.png and b/public/images/pokemon/shiny/658.png differ diff --git a/public/images/pokemon/shiny/688.json b/public/images/pokemon/shiny/688.json index 8d34a857f65..3d9aa902a54 100644 --- a/public/images/pokemon/shiny/688.json +++ b/public/images/pokemon/shiny/688.json @@ -1,41 +1,18 @@ -{ - "textures": [ - { - "image": "688.png", - "format": "RGBA8888", - "size": { - "w": 52, - "h": 52 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 41, - "h": 52 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 52 - }, - "frame": { - "x": 0, - "y": 0, - "w": 41, - "h": 52 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:e78487a241bfd62ebbe53b20c731d2c3:77b6de2bb0929c9cd5328c501256413b:176060351d0044923af938ba7932a6ef$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 64, "h": 63 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 63 }, + "sourceSize": { "w": 64, "h": 63 } + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 64, "h": 63 }, + "scale": "1" + } } diff --git a/public/images/pokemon/shiny/688.png b/public/images/pokemon/shiny/688.png index e87b981aa45..42565cb09b2 100644 Binary files a/public/images/pokemon/shiny/688.png and b/public/images/pokemon/shiny/688.png differ diff --git a/public/images/pokemon/shiny/689.json b/public/images/pokemon/shiny/689.json index c388441a207..488ef54de71 100644 --- a/public/images/pokemon/shiny/689.json +++ b/public/images/pokemon/shiny/689.json @@ -1,41 +1,19 @@ -{ - "textures": [ - { - "image": "689.png", - "format": "RGBA8888", - "size": { - "w": 86, - "h": 86 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 86, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 86, - "h": 79 - }, - "frame": { - "x": 0, - "y": 0, - "w": 86, - "h": 79 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:182cf1643b5020735212d8aa4db1c48e:ceb6ea59b420d8893e991d5545fbb7c7:bd0c58ecddcb4af9a0c6e7b39821d971$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 79, "h": 82 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 82 }, + "sourceSize": { "w": 79, "h": 82 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "format": "I8", + "size": { "w": 79, "h": 82 }, + "scale": "1" + } } diff --git a/public/images/pokemon/shiny/689.png b/public/images/pokemon/shiny/689.png index faf533459d0..c58ed341e75 100644 Binary files a/public/images/pokemon/shiny/689.png and b/public/images/pokemon/shiny/689.png differ diff --git a/public/images/pokemon/shiny/944.png b/public/images/pokemon/shiny/944.png index 5b5a264755f..e410629b535 100644 Binary files a/public/images/pokemon/shiny/944.png and b/public/images/pokemon/shiny/944.png differ diff --git a/public/images/pokemon/shiny/945.png b/public/images/pokemon/shiny/945.png index f458bf630d6..ab3fb485bb2 100644 Binary files a/public/images/pokemon/shiny/945.png and b/public/images/pokemon/shiny/945.png differ diff --git a/public/images/pokemon/shiny/female/194.png b/public/images/pokemon/shiny/female/194.png index 01c071ee41d..23e55c52190 100644 Binary files a/public/images/pokemon/shiny/female/194.png and b/public/images/pokemon/shiny/female/194.png differ diff --git a/public/images/pokemon/shiny/female/275.png b/public/images/pokemon/shiny/female/275.png index c8f9a90b721..a0571493279 100644 Binary files a/public/images/pokemon/shiny/female/275.png and b/public/images/pokemon/shiny/female/275.png differ diff --git a/public/images/pokemon/variant/1012-counterfeit.json b/public/images/pokemon/variant/1012-counterfeit.json new file mode 100644 index 00000000000..114c3811ba1 --- /dev/null +++ b/public/images/pokemon/variant/1012-counterfeit.json @@ -0,0 +1,44 @@ +{ + "1": { + "5d9e4a": "dda08a", + "a09750": "acbedf", + "423232": "626a96", + "827b74": "848fb8", + "613f19": "7b86ad", + "ccc374": "def7ff", + "a7ba72": "c87079", + "c1b9ae": "c8ddf1", + "69441b": "3a44a4", + "878278": "8a96c0", + "f7da67": "94386a", + "78c463": "f7dfc5", + "ede9e4": "f5fdff", + "261919": "222078", + "396725": "b0654a", + "251b1b": "404ec8", + "4d3635": "174593", + "87847e": "a1b0e6", + "4c3a3a": "667fe9" + }, + "2": { + "5d9e4a": "978dc7", + "a09750": "1b2556", + "423232": "020109", + "827b74": "6fbb45", + "613f19": "0d1030", + "ccc374": "242f66", + "a7ba72": "647c9a", + "c1b9ae": "111039", + "69441b": "44244b", + "878278": "070722", + "f7da67": "0f5627", + "78c463": "c3b4e0", + "ede9e4": "212b5e", + "261919": "1c0b1f", + "396725": "7a5aa7", + "251b1b": "37183f", + "4d3635": "aae16c", + "87847e": "443666", + "4c3a3a": "563f5b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/1013-unremarkable.json b/public/images/pokemon/variant/1013-unremarkable.json new file mode 100644 index 00000000000..cd988febd87 --- /dev/null +++ b/public/images/pokemon/variant/1013-unremarkable.json @@ -0,0 +1,48 @@ +{ + "1": { + "5d9e4a": "dda08a", + "786354": "7987bd", + "403030": "1c4b9c", + "7b8764": "c58c85", + "ccc374": "eefbff", + "a7ba72": "b75267", + "7b6f6c": "939ec4", + "c1b9ae": "cbe1f5", + "69441b": "3a44a4", + "342405": "616a8a", + "78c463": "f7dfc5", + "453636": "667fe9", + "988975": "acbedf", + "295217": "b0654a", + "e6e1db": "e6f9ff", + "9e8574": "b36171", + "251b1b": "404ec8", + "6a5b20": "8a96c0", + "a09750": "c3d7eb", + "291a0d": "222078", + "f7da67": "94386a" + }, + "2": { + "5d9e4a": "978dc7", + "786354": "5fb352", + "403030": "aae16c", + "7b8764": "716d99", + "ccc374": "263665", + "a7ba72": "647c9a", + "7b6f6c": "0f102d", + "c1b9ae": "111039", + "69441b": "44244b", + "342405": "08081f", + "78c463": "c3b4e0", + "453636": "563f5b", + "988975": "212e57", + "295217": "7a5aa7", + "e6e1db": "212b5e", + "9e8574": "585d81", + "251b1b": "37183f", + "6a5b20": "0b0c21", + "a09750": "131238", + "291a0d": "170d26", + "f7da67": "0f5627" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/102.json b/public/images/pokemon/variant/102.json new file mode 100644 index 00000000000..987f6046458 --- /dev/null +++ b/public/images/pokemon/variant/102.json @@ -0,0 +1,20 @@ +{ + "1": { + "ffce4a": "cea573", + "e69c00": "a0694c", + "ffe6ce": "7ae49f", + "943131": "193662", + "ffb58c": "369b96", + "ef8463": "26647e", + "ffd6ad": "4fba94" + }, + "2": { + "ffce4a": "92394b", + "e69c00": "6d2341", + "ffe6ce": "ebb6f8", + "943131": "414189", + "ffb58c": "9475ce", + "ef8463": "6c5fb6", + "ffd6ad": "b98fe4" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/103.json b/public/images/pokemon/variant/103.json new file mode 100644 index 00000000000..2b6a1f13f79 --- /dev/null +++ b/public/images/pokemon/variant/103.json @@ -0,0 +1,28 @@ +{ + "1": { + "ffde6b": "a3c4ed", + "e6ad5a": "869fdc", + "8c7342": "283f5b", + "73ad31": "dea44c", + "526329": "c8592a", + "9cd64a": "f4e774", + "a56b21": "6072ba", + "b59c4a": "426378", + "734210": "373e85", + "ffefa5": "d3efff", + "524210": "131d33" + }, + "2": { + "ffde6b": "eb748d", + "e6ad5a": "c84e7f", + "8c7342": "d59cba", + "73ad31": "3d324b", + "526329": "1f1a31", + "9cd64a": "6a5b73", + "a56b21": "83295f", + "b59c4a": "ffdbe7", + "734210": "4e1044", + "ffefa5": "ffa29d", + "524210": "925b81" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/128.json b/public/images/pokemon/variant/128.json new file mode 100644 index 00000000000..cd6a7d64f3a --- /dev/null +++ b/public/images/pokemon/variant/128.json @@ -0,0 +1,32 @@ +{ + "1": { + "dea54a": "56b393", + "634a31": "173e0d", + "9c9cad": "997059", + "e6c57b": "8fcaaa", + "4a3a29": "072b05", + "8c6321": "215c72", + "8c6b52": "355816", + "b58431": "2e8a85", + "ad8c73": "5f722a", + "3a3a4a": "4d2324", + "6b6b84": "75413b", + "cecede": "c2a082", + "523a10": "102d4b" + }, + "2": { + "dea54a": "872b3b", + "634a31": "bc9681", + "9c9cad": "edda95", + "e6c57b": "a84d52", + "4a3a29": "966959", + "8c6321": "461029", + "8c6b52": "d6c3aa", + "b58431": "5e172e", + "ad8c73": "faf9ed", + "3a3a4a": "996537", + "6b6b84": "cca45e", + "cecede": "fffcc1", + "523a10": "2f0e21" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/152.json b/public/images/pokemon/variant/152.json new file mode 100644 index 00000000000..f3c1d446fa7 --- /dev/null +++ b/public/images/pokemon/variant/152.json @@ -0,0 +1,28 @@ +{ + "1": { + "efffc5": "f7f1fb", + "849452": "7373b4", + "c52929": "77b3af", + "b5ce6b": "aca1d7", + "d6f78c": "ded2f1", + "84e631": "8074fa", + "ef7b7b": "9bd5c1", + "6bb529": "6f4be2", + "425a19": "505d8d", + "426319": "5d2398", + "638c29": "6633bc" + }, + "2": { + "efffc5": "f4b2ad", + "849452": "a62775", + "c52929": "4eac60", + "b5ce6b": "c83c74", + "d6f78c": "e7617d", + "84e631": "feeeaf", + "ef7b7b": "71cf71", + "6bb529": "f0d187", + "425a19": "801a69", + "426319": "b4814b", + "638c29": "d8a864" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/153.json b/public/images/pokemon/variant/153.json new file mode 100644 index 00000000000..3456ca16513 --- /dev/null +++ b/public/images/pokemon/variant/153.json @@ -0,0 +1,28 @@ +{ + "1": { + "ffff8c": "cbe0fa", + "a58419": "5961ce", + "6b5200": "493fa6", + "ad3100": "47d0d1", + "8cbd31": "8251dc", + "debd29": "7b8ce6", + "527b08": "4d36be", + "6b9c10": "6740c9", + "295208": "232699", + "f7e64a": "a2bbf8", + "d68c52": "80f5e6" + }, + "2": { + "ffff8c": "f5c095", + "a58419": "a8244d", + "6b5200": "891b4f", + "ad3100": "439227", + "8cbd31": "fae084", + "debd29": "ca333d", + "527b08": "e8bc5e", + "6b9c10": "edc870", + "295208": "c58c48", + "f7e64a": "ea704a", + "d68c52": "8ec349" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/154.json b/public/images/pokemon/variant/154.json new file mode 100644 index 00000000000..90311122029 --- /dev/null +++ b/public/images/pokemon/variant/154.json @@ -0,0 +1,30 @@ +{ + "1": { + "634a00": "519aa7", + "f7a59c": "739ed4", + "e6ad00": "7bcfc6", + "ff3a5a": "3542a7", + "ffde21": "b1f2dc", + "ce213a": "27217d", + "63bd42": "9d86d9", + "bdff7b": "dadffe", + "7b103a": "23124e", + "107b31": "8057b2", + "fefefe": "9cfeff", + "9ce652": "b7afee" + }, + "2": { + "634a00": "488939", + "f7a59c": "fff6a9", + "e6ad00": "6bac4b", + "ff3a5a": "f9db74", + "ffde21": "92c462", + "ce213a": "e5b650", + "63bd42": "a31f60", + "bdff7b": "f57382", + "7b103a": "b7873b", + "107b31": "761858", + "fefefe": "ffffee", + "9ce652": "cd3b6b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/158.json b/public/images/pokemon/variant/158.json new file mode 100644 index 00000000000..779c7ea69b4 --- /dev/null +++ b/public/images/pokemon/variant/158.json @@ -0,0 +1,27 @@ +{ + "1": { + "7b1900": "4f0332", + "6bb5e6": "dd8e59", + "94d6ff": "fdc17e", + "ffc552": "99d4d9", + "ad8429": "4798ab", + "3184c5": "ae5139", + "e67b7b": "749e9e", + "b54a52": "1d5d6c", + "ce4221": "772c52", + "315a84": "73131e" + }, + "2": { + "000000": "ffffff", + "7b1900": "a66b14", + "6bb5e6": "97ac5b", + "94d6ff": "ccd198", + "ffc552": "2f5365", + "ad8429": "1c314f", + "3184c5": "4f854a", + "e67b7b": "e4b843", + "b54a52": "c48b27", + "ce4221": "ce8c20", + "315a84": "2b4a30" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/159.json b/public/images/pokemon/variant/159.json new file mode 100644 index 00000000000..c6563e4204c --- /dev/null +++ b/public/images/pokemon/variant/159.json @@ -0,0 +1,33 @@ +{ + "1": { + "3a4a84": "973027", + "e64221": "749e9e", + "ce293a": "682c4e", + "5aade6": "e5a354", + "84ceff": "ffcf72", + "cebd63": "56b3bd", + "ffe68c": "a9e4e5", + "840008": "4f1037", + "3184c5": "cd6537", + "6b5200": "085d75", + "840009": "1d5d6c", + "ff8c84": "926877", + "f7525a": "774860" + }, + "2": { + "000000": "ffffff", + "3a4a84": "26472b", + "e64221": "e4b843", + "ce293a": "ce8c20", + "5aade6": "8fa54e", + "84ceff": "c2c78a", + "cebd63": "1c314f", + "ffe68c": "2f5365", + "840008": "a66b14", + "3184c5": "468040", + "6b5200": "112034", + "840009": "c48b27", + "ff8c84": "fff284", + "f7525a": "f3b649" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/160.json b/public/images/pokemon/variant/160.json new file mode 100644 index 00000000000..adb897ae5f5 --- /dev/null +++ b/public/images/pokemon/variant/160.json @@ -0,0 +1,27 @@ +{ + "1": { + "8cd6ff": "ffcf72", + "6b5200": "085d75", + "5ab5f7": "eda857", + "cebd63": "56b3bd", + "ffe68c": "a9e4e5", + "840008": "4f1037", + "294a8c": "973027", + "3a8cce": "d26738", + "ff8c84": "926877", + "f7525a": "774860" + }, + "2": { + "000000": "ffffff", + "8cd6ff": "d1d692", + "6b5200": "112034", + "5ab5f7": "9ab350", + "cebd63": "1c314f", + "ffe68c": "2f5365", + "840008": "a66b14", + "294a8c": "274c2d", + "3a8cce": "498a42", + "ff8c84": "fff284", + "f7525a": "f3b649" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/167.json b/public/images/pokemon/variant/167.json new file mode 100644 index 00000000000..20f954a4a55 --- /dev/null +++ b/public/images/pokemon/variant/167.json @@ -0,0 +1,31 @@ +{ + "1": { + "52b56b": "e06c19", + "b5424a": "861d1d", + "ef5a5a": "b92222", + "7b3142": "651218", + "c5b519": "3f2e71", + "314a10": "732202", + "846b29": "231a58", + "8ce631": "f1b940", + "527b29": "d54f19", + "ffe64a": "624095", + "adef63": "f5da68" + }, + "2": { + "52b56b": "8c2848", + "b5424a": "1f1d3f", + "bdc5c5": "a1b7de", + "ef5a5a": "313659", + "7b3142": "181729", + "c5b519": "7d95b9", + "314a10": "481229", + "846b29": "565e8d", + "8ce631": "b54158", + "527b29": "6a1b37", + "ffe64a": "aac3d6", + "ffffff": "cde6fc", + "6b6b73": "62657d", + "adef63": "dd7081" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/168.json b/public/images/pokemon/variant/168.json new file mode 100644 index 00000000000..4c8fcf5f4f5 --- /dev/null +++ b/public/images/pokemon/variant/168.json @@ -0,0 +1,32 @@ +{ + "1": { + "c54242": "62b943", + "6b5219": "043435", + "63319c": "af4900", + "9c5ac5": "e28220", + "bdbdbd": "b5d3dc", + "ffffff": "fffef9", + "ff8c73": "dce24b", + "c5b54a": "15463c", + "ff5a4a": "a8d919", + "ffde42": "186c45", + "8c2100": "317945", + "bd84e6": "f1b940", + "6b6b6b": "552718" + }, + "2": { + "c54242": "7ca5c6", + "6b5219": "161437", + "63319c": "291013", + "9c5ac5": "96304a", + "bdbdbd": "c09fa1", + "ffffff": "fae8e7", + "ff8c73": "c4e8e7", + "c5b54a": "1f2150", + "ff5a4a": "a3c8d1", + "ffde42": "313b60", + "8c2100": "2d3d72", + "bd84e6": "c8545d", + "6b6b6b": "3e538a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/170.json b/public/images/pokemon/variant/170.json new file mode 100644 index 00000000000..c83ca6836db --- /dev/null +++ b/public/images/pokemon/variant/170.json @@ -0,0 +1,34 @@ +{ + "1": { + "08295a": "691f03", + "ffce52": "a1dbba", + "b50000": "efde5a", + "94cee6": "ffeabf", + "295294": "a14713", + "ffef84": "ccffd7", + "5a73c5": "bf6924", + "c59400": "609a8a", + "522919": "052b38", + "ffffde": "f2fff5", + "7bbde6": "f6e37f", + "846352": "45757a", + "6ba5e6": "dda13d", + "e6b529": "84bda9" + }, + "2": { + "08295a": "1b072f", + "ffce52": "e25765", + "b50000": "f0d050", + "94cee6": "a15b8d", + "295294": "321648", + "ffef84": "f97f7f", + "5a73c5": "441e56", + "c59400": "931b3c", + "522919": "720b3a", + "ffffde": "ffc4be", + "7bbde6": "89498d", + "846352": "720b3a", + "6ba5e6": "693373", + "e6b529": "b62b51" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/171.json b/public/images/pokemon/variant/171.json new file mode 100644 index 00000000000..8a9cafe4265 --- /dev/null +++ b/public/images/pokemon/variant/171.json @@ -0,0 +1,30 @@ +{ + "1": { + "a5314a": "bf882c", + "4a7bce": "bc3c4c", + "423110": "05333a", + "ef635a": "efde5a", + "7badef": "f6907f", + "a5ceff": "fbcdb3", + "e6b552": "82ca4f", + "6394e6": "e86062", + "ffde63": "c3e875", + "ad9442": "2a8d3d", + "293173": "872341", + "7b634a": "0c5540" + }, + "2": { + "a5314a": "c3851d", + "4a7bce": "9781b3", + "423110": "040529", + "ef635a": "f0d050", + "7badef": "eecfed", + "a5ceff": "fbf5fa", + "e6b552": "3294b8", + "6394e6": "c5a5d0", + "ffde63": "4dd5d9", + "ad9442": "23689e", + "293173": "4b426c", + "7b634a": "0c1d4c" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/172-spiky.json b/public/images/pokemon/variant/172-spiky.json new file mode 100644 index 00000000000..81a1d9bdcd6 --- /dev/null +++ b/public/images/pokemon/variant/172-spiky.json @@ -0,0 +1,30 @@ +{ + "1": { + "f7ef94": "c4e3c3", + "7d1c1c": "992424", + "e77b94": "bd4d5e", + "e36481": "d45976", + "292929": "242424", + "c5ad10": "6cab9a", + "845a29": "45818a", + "f7e652": "a3d1a8", + "a57b08": "5ca390", + "634a10": "30536b" + }, + "2": { + "f7ef94": "8aa5ad", + "7d1c1c": "c38218", + "212131": "d48d61", + "e77b94": "f5dd94", + "e36481": "b35b6d", + "292929": "242424", + "c5ad10": "4a6a90", + "845a29": "283567", + "8c2121": "772c49", + "424252": "e7c17c", + "f7e652": "7095ab", + "171721": "9a4440", + "a57b08": "486a8e", + "634a10": "2f335b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/172.json b/public/images/pokemon/variant/172.json new file mode 100644 index 00000000000..7df41b99457 --- /dev/null +++ b/public/images/pokemon/variant/172.json @@ -0,0 +1,29 @@ +{ + "1": { + "f7ef94": "c4e3c3", + "a57b08": "5ca390", + "d1667f": "d45976", + "e77b94": "bd4d5e", + "292929": "242424", + "c5ad10": "6cab9a", + "845a29": "45818a", + "f7e652": "a3d1a8", + "7d1c1c": "992424", + "634a10": "30536b" + }, + "2": { + "f7ef94": "8aa5ad", + "a57b08": "486a8e", + "d1667f": "b35b6d", + "8c2121": "772c49", + "e77b94": "f5dd94", + "c5ad10": "4a6a90", + "845a29": "283567", + "212131": "d48d61", + "424252": "e7c17c", + "f7e652": "7095ab", + "7d1c1c": "c38218", + "171721": "9a4440", + "634a10": "2f335b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/174.json b/public/images/pokemon/variant/174.json new file mode 100644 index 00000000000..65b9af81dde --- /dev/null +++ b/public/images/pokemon/variant/174.json @@ -0,0 +1,20 @@ +{ + "1": { + "9c1952": "3a6472", + "e6849c": "81c2b8", + "bd0000": "f18fc4", + "630000": "6f305b", + "b55273": "43737d", + "e62910": "ae93d9", + "ffced6": "e5ffec", + "ffadbd": "c5ebd5" + }, + "2": { + "9c1952": "9c5200", + "e6849c": "f5c45b", + "b55273": "a16b30", + "e62910": "c43f3f", + "ffced6": "fff9bf", + "ffadbd": "f5e884" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/194.json b/public/images/pokemon/variant/194.json new file mode 100644 index 00000000000..47604b8228d --- /dev/null +++ b/public/images/pokemon/variant/194.json @@ -0,0 +1,24 @@ +{ + "1": { + "104a84": "7a150a", + "b54242": "23768d", + "ff6b73": "52c1e0", + "633a6b": "204954", + "3a7bc5": "d5682e", + "ef73e6": "81e2f7", + "73bdff": "ffc355", + "d65ad6": "65b1c2", + "529ce6": "e8983d" + }, + "2": { + "104a84": "180d42", + "b54242": "b96228", + "ff6b73": "e9cb52", + "633a6b": "80301c", + "3a7bc5": "3f377e", + "ef73e6": "e9cb52", + "73bdff": "5c66c4", + "d65ad6": "cf933b", + "529ce6": "564daa" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/195.json b/public/images/pokemon/variant/195.json new file mode 100644 index 00000000000..3bf5ea7844a --- /dev/null +++ b/public/images/pokemon/variant/195.json @@ -0,0 +1,26 @@ +{ + "1": { + "ade6ff": "f6dfa8", + "84d6f7": "ed9e4f", + "f7f7f7": "fffbea", + "637ba5": "936e66", + "639cbd": "dc6a4d", + "3194a5": "81e2f7", + "19423a": "204954", + "425284": "b03844", + "195a6b": "54aec2", + "6b5a8c": "23768d" + }, + "2": { + "ade6ff": "9864c2", + "84d6f7": "724ba7", + "f7f7f7": "e8b6ff", + "637ba5": "6f2d4b", + "639cbd": "493a8d", + "3194a5": "e9cb52", + "19423a": "b96228", + "425284": "240830", + "195a6b": "cf933b", + "6b5a8c": "80301c" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/198.json b/public/images/pokemon/variant/198.json new file mode 100644 index 00000000000..ab9084619f3 --- /dev/null +++ b/public/images/pokemon/variant/198.json @@ -0,0 +1,34 @@ +{ + "1": { + "d94352": "7a101c", + "314263": "462b20", + "d64252": "b3986b", + "73293a": "755237", + "ffad8c": "ad2e24", + "73283a": "630c17", + "d6404f": "8c1b23", + "efd684": "a6a6b3", + "42639c": "694c30", + "5a4a21": "25253b", + "292942": "2a1512", + "b59c21": "57566f", + "752a3c": "4d0419", + "d6bd52": "838098" + }, + "2": { + "d94352": "5939a9", + "314263": "0e4333", + "d64252": "bc4b84", + "73293a": "7b2363", + "ffad8c": "b164e6", + "73283a": "630c17", + "d6404f": "8c1b23", + "efd684": "c2723a", + "42639c": "1d6e47", + "5a4a21": "4e1915", + "292942": "091e16", + "b59c21": "85412d", + "752a3c": "1e1764", + "d6bd52": "9a5524" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/2026.json b/public/images/pokemon/variant/2026.json new file mode 100644 index 00000000000..995e3a1a6e8 --- /dev/null +++ b/public/images/pokemon/variant/2026.json @@ -0,0 +1,34 @@ +{ + "1": { + "e3882d": "3d7375", + "965821": "2f4e6b", + "846b5b": "467f85", + "fffdfb": "d6d9ca", + "552720": "142c48", + "602c24": "162f4b", + "fef443": "c48081", + "b45f25": "2d5261", + "fef652": "eb999a", + "1a73cc": "b85346", + "174680": "2b1307", + "e9be14": "945c7b", + "646124": "492652", + "9c5430": "1d3a57", + "ecd8b7": "b4c2a5" + }, + "2": { + "e3882d": "d3b06f", + "965821": "9cb3ca", + "846b5b": "202746", + "fffdfb": "6d8297", + "552720": "43617f", + "fef443": "3a5873", + "b45f25": "bd8551", + "fef652": "faee9e", + "1a73cc": "c26400", + "174680": "2b0606", + "e9be14": "1a3551", + "646124": "122140", + "ecd8b7": "5a6f90" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/2103.json b/public/images/pokemon/variant/2103.json new file mode 100644 index 00000000000..2e97727835a --- /dev/null +++ b/public/images/pokemon/variant/2103.json @@ -0,0 +1,28 @@ +{ + "1": { + "2f9934": "dea44c", + "9f6b41": "426378", + "70442e": "283f5b", + "e6ac5a": "869fdc", + "522f16": "131d33", + "9cbd4a": "9977dd", + "fff68b": "a3c4ed", + "36cc36": "f4e774", + "2d5826": "c8592a", + "7b5210": "373e85", + "ffffcd": "d3efff" + }, + "2": { + "2f9934": "3d324b", + "9f6b41": "ffdbe7", + "70442e": "d59cba", + "e6ac5a": "c84e7f", + "522f16": "925b81", + "9cbd4a": "824a96", + "fff68b": "eb748d", + "36cc36": "6a5b73", + "2d5826": "1f1a31", + "7b5210": "4e1044", + "ffffcd": "ffa29d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/211.json b/public/images/pokemon/variant/211.json new file mode 100644 index 00000000000..cc2b3ba9209 --- /dev/null +++ b/public/images/pokemon/variant/211.json @@ -0,0 +1,28 @@ +{ + "1": { + "940000": "1c6449", + "194a52": "321128", + "dede94": "f1c17c", + "428494": "80294b", + "c5c57b": "dc9565", + "a5ad6b": "ad6643", + "3a6363": "611a42", + "d65263": "48be87", + "ffa594": "9ee79b", + "6b5231": "6d2c2c", + "73adb5": "a0415e" + }, + "2": { + "940000": "385881", + "194a52": "1c2f5b", + "dede94": "365492", + "428494": "60abdc", + "c5c57b": "2b3e7b", + "a5ad6b": "1e275b", + "3a6363": "396796", + "d65263": "a9cfd7", + "ffa594": "cafefd", + "6b5231": "181f46", + "73adb5": "8bd9ee" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25-beauty-cosplay.json b/public/images/pokemon/variant/25-beauty-cosplay.json new file mode 100644 index 00000000000..0e5a6a1bad2 --- /dev/null +++ b/public/images/pokemon/variant/25-beauty-cosplay.json @@ -0,0 +1,49 @@ +{ + "1": { + "c52119": "ad4e76", + "5e5e6b": "6c6e60", + "f7e652": "a3d1a8", + "52525a": "4f454c", + "cecab9": "cfc8aa", + "e65137": "c95578", + "fffabf": "f4f7ab", + "b52821": "ad4469", + "292929": "1e1526", + "39509d": "47449c", + "f7e860": "f2ea50", + "e65a42": "cf6182", + "4d88c4": "7976c6", + "f7bd21": "79b5a5", + "2d276d": "2f2768", + "242323": "282030", + "585861": "443e6c", + "fff7a5": "c4e3c3", + "9c5200": "315c75", + "f7cc2f": "f7bd21", + "fffdea": "f8ffe3" + }, + "2": { + "c52119": "ebc67c", + "5e5e6b": "8a2554", + "f7e652": "577b98", + "52525a": "f1b571", + "cecab9": "b84084", + "e65137": "b95b6e", + "fffabf": "f5efd1", + "b52821": "6a253f", + "292929": "a45233", + "39509d": "9ec4cd", + "f7e860": "eddc78", + "e65a42": "eedd9c", + "4d88c4": "e4f6f1", + "f7bd21": "486689", + "2d276d": "454a61", + "242323": "282030", + "585861": "3f4246", + "fff7a5": "7b96aa", + "9c5200": "283361", + "965b0e": "96500e", + "f7cc2f": "d5ac44", + "fffdea": "ea82a6" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25-cool-cosplay.json b/public/images/pokemon/variant/25-cool-cosplay.json new file mode 100644 index 00000000000..de4a138b690 --- /dev/null +++ b/public/images/pokemon/variant/25-cool-cosplay.json @@ -0,0 +1,49 @@ +{ + "1": { + "171717": "2a1d36", + "e8b127": "f5ca2f", + "52525a": "55555e", + "c52119": "ad4e76", + "842222": "7b1f18", + "f7e652": "a3d1a8", + "fff7a5": "c4e3c3", + "2baf23": "76a848", + "f7bd21": "79b5a5", + "e65a42": "cf6182", + "ba2b23": "b73850", + "f5e193": "f4f7ab", + "e66953": "b95b6e", + "6f6c8e": "656f86", + "a6adb6": "a5b0b6", + "8c4e22": "965b0e", + "9c5200": "1c4f75", + "c43129": "6a253f", + "d95b45": "cf6887", + "45484d": "443e6c", + "3b3b40": "4a3e46", + "292929": "272b2b" + }, + "2": { + "171717": "a45233", + "e8b127": "e7b432", + "52525a": "8f4b32", + "c52119": "ebc67c", + "842222": "1e1e43", + "f7e652": "577b98", + "fff7a5": "7b96aa", + "2baf23": "572626", + "f7bd21": "445f8a", + "e65a42": "eedd9c", + "ba2b23": "2c2c47", + "f5e193": "eadbb3", + "e66953": "b95b6e", + "6f6c8e": "cf752b", + "a6adb6": "f0b541", + "8c4e22": "b1632b", + "9c5200": "22325c", + "c43129": "6a253f", + "d95b45": "3a3f5e", + "3b3b40": "f1b571", + "292929": "7d3833" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25-cosplay.json b/public/images/pokemon/variant/25-cosplay.json new file mode 100644 index 00000000000..e324c094019 --- /dev/null +++ b/public/images/pokemon/variant/25-cosplay.json @@ -0,0 +1,36 @@ +{ + "1": { + "f7e652": "a3d1a8", + "212121": "30263b", + "c43129": "6a253f", + "171717": "1e1526", + "292929": "282030", + "e65a42": "cf6182", + "c52119": "ad4e76", + "42424a": "443e6c", + "fff7a5": "c4e3c3", + "f7bd21": "79b5a5", + "45454a": "4f454c", + "9c5200": "315c75", + "633108": "09406b", + "e66953": "b95b6e", + "de9400": "338087" + }, + "2": { + "f7e652": "577b98", + "212121": "d8805b", + "c43129": "6a253f", + "171717": "a45233", + "292929": "282030", + "e65a42": "eedd9c", + "c52119": "ebc67c", + "42424a": "3f4246", + "fff7a5": "7b96aa", + "f7bd21": "445f8a", + "45454a": "f1b571", + "9c5200": "23345e", + "633108": "22244f", + "e66953": "b95b6e", + "de9400": "324472" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25-cute-cosplay.json b/public/images/pokemon/variant/25-cute-cosplay.json new file mode 100644 index 00000000000..251530a0892 --- /dev/null +++ b/public/images/pokemon/variant/25-cute-cosplay.json @@ -0,0 +1,53 @@ +{ + "1": { + "e65a42": "cf6182", + "cf4770": "cf4a59", + "52525a": "30263b", + "c52119": "ad4e76", + "292929": "30263b", + "fff7a5": "f0eaa8", + "9c5200": "255e8a", + "752bd0": "5452b7", + "e66953": "b95b6e", + "c43129": "6a253f", + "42424a": "443e6c", + "f7e652": "a3d1a8", + "ea82a6": "e8848e", + "29292a": "1e1526", + "f3bace": "f2bbbb", + "853247": "85323c", + "52525c": "bab699", + "fff7a6": "c4e3c3", + "101011": "101010", + "baa998": "bab699", + "f7bd21": "79b5a5", + "101010": "1e1526", + "52525b": "4f454c" + }, + "2": { + "e65a42": "eedd9c", + "cf4770": "739b55", + "52525a": "d8805b", + "52525d": "d3ab5a", + "c52119": "ebc67c", + "292929": "d8805b", + "fff7a5": "ebe7b7", + "9c5200": "1e2d52", + "752bd0": "7751c2", + "e66953": "b95b6e", + "c43129": "6a253f", + "42424a": "373d45", + "f7e652": "577b98", + "ea82a6": "a4b95f", + "29292a": "a45233", + "f3bace": "c5cc85", + "853247": "254b30", + "52525c": "706053", + "fff7a6": "7b96aa", + "101011": "101010", + "baa998": "d3ab5a", + "f7bd21": "445f8a", + "101010": "a45233", + "52525b": "f1b571" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25-gigantamax.json b/public/images/pokemon/variant/25-gigantamax.json new file mode 100644 index 00000000000..554b93c5bfa --- /dev/null +++ b/public/images/pokemon/variant/25-gigantamax.json @@ -0,0 +1,35 @@ +{ + "1": { + "212121": "1e1526", + "c52018": "ad4e76", + "f6e652": "a3d1a8", + "f6bd20": "79b5a5", + "fff9c2": "b8ffd9", + "e65a41": "cf6182", + "de9400": "338087", + "623108": "09406b", + "fff6a4": "c4e3c3", + "292929": "282030", + "323133": "30263b", + "f8fc4b": "5bc28b", + "9c5200": "315c75", + "41414a": "4f454c", + "61616d": "443e6c" + }, + "2": { + "212121": "a45233", + "c52018": "ebc67c", + "f6e652": "577b98", + "f6bd20": "445f8a", + "fff9c2": "83b1d2", + "e65a41": "eedd9c", + "de9400": "324472", + "623108": "09406b", + "fff6a4": "7b96aa", + "323133": "d8805b", + "695d65": "737383", + "f8fc4b": "326a9f", + "9c5200": "23345e", + "41414a": "d99362" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25-partner.json b/public/images/pokemon/variant/25-partner.json new file mode 100644 index 00000000000..4363facf947 --- /dev/null +++ b/public/images/pokemon/variant/25-partner.json @@ -0,0 +1,36 @@ +{ + "1": { + "212121": "30263b", + "c52119": "ad4e76", + "fff7a5": "c4e3c3", + "f7e652": "a3d1a8", + "633108": "09406b", + "de9400": "338087", + "42424a": "443e6c", + "c43129": "6a253f", + "45454a": "4f454c", + "9c5200": "315c75", + "e66953": "b95b6e", + "e65a42": "cf6182", + "171717": "1e1526", + "f7bd21": "79b5a5", + "292929": "282030" + }, + "2": { + "212121": "d8805b", + "c52119": "ebc67c", + "fff7a5": "7b96aa", + "f7e652": "577b98", + "633108": "22244f", + "de9400": "324472", + "42424a": "3f4246", + "c43129": "6a253f", + "45454a": "f1b571", + "9c5200": "23345e", + "e66953": "b95b6e", + "e65a42": "eedd9c", + "171717": "a45233", + "f7bd21": "445f8a", + "292929": "282030" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25-smart-cosplay.json b/public/images/pokemon/variant/25-smart-cosplay.json new file mode 100644 index 00000000000..4ba98883f16 --- /dev/null +++ b/public/images/pokemon/variant/25-smart-cosplay.json @@ -0,0 +1,42 @@ +{ + "1": { + "212121": "30263b", + "b7a599": "bab699", + "60b553": "76a848", + "366635": "3e5b2f", + "e35252": "d16b9a", + "c52119": "ad4e76", + "292929": "272b2b", + "9c5200": "315c75", + "f7e652": "a3d1a8", + "95635b": "91685f", + "171717": "1e1526", + "ba2525": "993f70", + "e65a42": "cf6182", + "54545c": "55555e", + "52525a": "4f454c", + "fffdea": "f8ffe3", + "f7bd21": "79b5a5", + "5f3434": "573b38" + }, + "2": { + "212121": "d8805b", + "b7a599": "a7b6b9", + "60b553": "dfb053", + "366635": "ab5130", + "e35252": "3a3f5e", + "c52119": "ebc67c", + "292929": "202937", + "9c5200": "23345e", + "f7e652": "577b98", + "95635b": "a09ea3", + "171717": "a45233", + "ba2525": "2b2b45", + "e65a42": "eedd9c", + "54545c": "45525c", + "52525a": "f1b571", + "fffdea": "f2f0df", + "f7bd21": "445f8a", + "5f3434": "666060" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25-tough-cosplay.json b/public/images/pokemon/variant/25-tough-cosplay.json new file mode 100644 index 00000000000..620ac882643 --- /dev/null +++ b/public/images/pokemon/variant/25-tough-cosplay.json @@ -0,0 +1,43 @@ +{ + "1": { + "e37511": "d1694f", + "bf2629": "bf3638", + "303030": "30263b", + "b8282b": "753652", + "8d2b1d": "8e2525", + "424242": "443e6c", + "c52119": "ad4e76", + "292929": "1e1526", + "f7bd21": "79b5a5", + "fbab33": "de9764", + "db4a37": "ad4c60", + "e65a42": "cf6182", + "9c5200": "315c75", + "db5b42": "cf6a59", + "52525a": "4f454c", + "cecab9": "cfc8aa", + "f7e652": "a3d1a8" + }, + "2": { + "e37511": "644794", + "bf2629": "8e6fa1", + "f8ffe3": "e8e3e4", + "303030": "d8805b", + "b8282b": "6a253f", + "8d2b1d": "242866", + "424242": "3f4246", + "c52119": "e8be68", + "292929": "a45233", + "f7bd21": "445f8a", + "fbab33": "845ea1", + "db4a37": "b95b6e", + "e65a42": "edda8c", + "9c5200": "23345e", + "db5b42": "624780", + "52525a": "f1b571", + "4d4d4d": "2b3340", + "272b2b": "162231", + "cecab9": "cfc0c3", + "f7e652": "577b98" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/25.json b/public/images/pokemon/variant/25.json new file mode 100644 index 00000000000..0542587ba6d --- /dev/null +++ b/public/images/pokemon/variant/25.json @@ -0,0 +1,36 @@ +{ + "1": { + "42424a": "443e6c", + "fff7a5": "c4e3c3", + "c52119": "ad4e76", + "de9400": "338087", + "e65a42": "cf6182", + "f7e652": "a3d1a8", + "e66953": "b95b6e", + "45454a": "4f454c", + "292929": "282030", + "c43129": "6a253f", + "212121": "30263b", + "171717": "1e1526", + "f7bd21": "79b5a5", + "9c5200": "315c75", + "633108": "09406b" + }, + "2": { + "42424a": "3f4246", + "fff7a5": "7b96aa", + "c52119": "ebc67c", + "de9400": "324472", + "e65a42": "eedd9c", + "f7e652": "577b98", + "e66953": "b95b6e", + "45454a": "f1b571", + "292929": "282030", + "c43129": "6a253f", + "212121": "d8805b", + "171717": "a45233", + "f7bd21": "445f8a", + "9c5200": "23345e", + "633108": "22244f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/26.json b/public/images/pokemon/variant/26.json new file mode 100644 index 00000000000..c078c38570f --- /dev/null +++ b/public/images/pokemon/variant/26.json @@ -0,0 +1,36 @@ +{ + "1": { + "ffefd6": "c8d4ba", + "bd1908": "ad4e76", + "944242": "395a80", + "bd5a31": "386d82", + "e6bd84": "a4bda7", + "ffbd00": "b3596b", + "5a2929": "293059", + "3a3a42": "30263b", + "8c6310": "8c3c4c", + "ffde5a": "cf7878", + "8d5911": "983e50", + "734231": "6e2f33", + "63636b": "4f454c", + "de7b31": "539190", + "f7ad29": "76a68b" + }, + "2": { + "ffefd6": "cfc4b5", + "542127": "905331", + "bd1908": "a44c5d", + "944242": "2d3b80", + "bd5a31": "375681", + "e6bd84": "a6b5ab", + "ffbd00": "f3cf91", + "5a2929": "202a60", + "8c6310": "c79b5a", + "ffde5a": "f2e4b6", + "8d5911": "dea96e", + "734231": "bd8447", + "de7b31": "4d6f98", + "f7ad29": "6385ab", + "643034": "2e4685" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/276.json b/public/images/pokemon/variant/276.json new file mode 100644 index 00000000000..d7c6c1268ec --- /dev/null +++ b/public/images/pokemon/variant/276.json @@ -0,0 +1,32 @@ +{ + "1": { + "bdbdce": "26523c", + "ffffff": "3c6a3d", + "efbd63": "e7a562", + "524a29": "4b210d", + "bdbdcd": "b5b5d5", + "a57331": "784524", + "212952": "12223d", + "3a3a31": "3e3e3e", + "314a7b": "1a385a", + "e69410": "bc7532", + "943a52": "ad8634", + "5a6b9c": "2a596b", + "ce5273": "cebf49" + }, + "2": { + "bdbdce": "453f63", + "ffffff": "635d81", + "efbd63": "89787c", + "524a29": "381f2c", + "bdbdcd": "b5b5d5", + "a57331": "4a323a", + "212952": "191222", + "3a3a31": "442c34", + "314a7b": "282037", + "e69410": "63414f", + "943a52": "8ec08b", + "5a6b9c": "3c2f48", + "ce5273": "bcd59d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/277.json b/public/images/pokemon/variant/277.json new file mode 100644 index 00000000000..84d689cab9a --- /dev/null +++ b/public/images/pokemon/variant/277.json @@ -0,0 +1,34 @@ +{ + "1": { + "dea531": "bc7532", + "425a7b": "2a596b", + "ffffff": "3c6a3d", + "b5b5d6": "26523c", + "9c3152": "ad8634", + "945a10": "784524", + "5a5a5a": "b58251", + "63213a": "603c1d", + "c55a73": "cebf49", + "31313a": "89572a", + "e6b563": "e7a562", + "524221": "4b210d", + "292952": "12223d", + "294263": "1a385a" + }, + "2": { + "dea531": "63414f", + "425a7b": "3c2f48", + "ffffff": "635d81", + "b5b5d6": "453f63", + "9c3152": "8ec08b", + "945a10": "4a323a", + "5a5a5a": "5d454d", + "63213a": "5d9469", + "c55a73": "bcd59d", + "31313a": "442c34", + "e6b563": "89787c", + "524221": "381f2c", + "292952": "191222", + "294263": "282037" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/359-mega.json b/public/images/pokemon/variant/359-mega.json new file mode 100644 index 00000000000..3e76a8e6ee6 --- /dev/null +++ b/public/images/pokemon/variant/359-mega.json @@ -0,0 +1,30 @@ +{ + "1": { + "273535": "2b3266", + "7b2931": "c9824b", + "414a6a": "421e4a", + "b4b4d5": "458196", + "cd2920": "f7c26d", + "293939": "27122b", + "fdfdfd": "61a8ab", + "525a7b": "59274e", + "d5deee": "589aa6", + "737bac": "874267", + "8b8bac": "3b6987", + "626283": "2a3163" + }, + "2": { + "273535": "420918", + "7b2931": "0f4391", + "414a6a": "b39279", + "b4b4d5": "752f40", + "cd2920": "2a96ce", + "293939": "996e5f", + "fdfdfd": "9e363b", + "525a7b": "e0c79f", + "d5deee": "8f2f41", + "737bac": "f5f1cb", + "8b8bac": "59213b", + "626283": "42122d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/359.json b/public/images/pokemon/variant/359.json new file mode 100644 index 00000000000..936b3567c67 --- /dev/null +++ b/public/images/pokemon/variant/359.json @@ -0,0 +1,34 @@ +{ + "1": { + "424a6b": "421e4a", + "293a3a": "27122b", + "ce2921": "f7c26d", + "7b2931": "c9824b", + "ff7b73": "fff291", + "737bad": "874267", + "d6deef": "589aa6", + "283838": "101f30", + "525a7b": "612b54", + "b5b5d6": "458196", + "636384": "2a3163", + "7179ab": "2b3266", + "ffffff": "61a8ab", + "8c8cad": "3b6987" + }, + "2": { + "424a6b": "b39279", + "293a3a": "996e5f", + "ce2921": "2a96ce", + "7b2931": "0f4391", + "ff7b73": "96eeff", + "737bad": "f5f1cb", + "d6deef": "8f2f41", + "283838": "31101f", + "525a7b": "e0c79f", + "b5b5d6": "752f40", + "636384": "42122d", + "7179ab": "7d1d36", + "ffffff": "9e363b", + "8c8cad": "59213b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/377.json b/public/images/pokemon/variant/377.json new file mode 100644 index 00000000000..84f8851b9a8 --- /dev/null +++ b/public/images/pokemon/variant/377.json @@ -0,0 +1,28 @@ +{ + "1": { + "b54200": "13512f", + "efad6b": "aac669", + "948c73": "2e4e7b", + "cec5ad": "4d8ba8", + "bd633a": "22773f", + "ef733a": "72b645", + "ef843a": "56963a", + "524a29": "182238", + "e6dead": "659db5", + "b5ad94": "3d6d8d", + "efe6de": "84c7ca" + }, + "2": { + "b54200": "3d0933", + "efad6b": "a54c5e", + "948c73": "262847", + "cec5ad": "303353", + "bd633a": "561934", + "ef733a": "c1271f", + "ef843a": "722a41", + "524a29": "161129", + "e6dead": "383e6a", + "b5ad94": "394170", + "efe6de": "4d5784" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/378.json b/public/images/pokemon/variant/378.json new file mode 100644 index 00000000000..c7d2816a024 --- /dev/null +++ b/public/images/pokemon/variant/378.json @@ -0,0 +1,38 @@ +{ + "0": { + "ffffff": "d7b6f1", + "293a7b": "101238", + "9cceff": "6f66a7", + "ceb521": "ca5846", + "6bb5d6": "414184", + "ffffad": "ffd6a7", + "ffe600": "e58b64", + "5a84ad": "282e64", + "3a6b8c": "191d4c", + "bdefff": "9983c4" + }, + "1": { + "6bb5d6": "bf344a", + "bdefff": "ffb88d", + "293a7b": "400b1c", + "ffe600": "7a5d98", + "5a84ad": "981d43", + "ffffff": "fff7d3", + "ffffad": "c39bd0", + "ceb521": "43356c", + "3a6b8c": "64132c", + "9cceff": "eb5d56" + }, + "2": { + "6bb5d6": "323232", + "bdefff": "5b5b5b", + "293a7b": "100f17", + "ffe600": "73e6f6", + "5a84ad": "212121", + "ffffff": "8c8c8c", + "ffffad": "e5fffd", + "ceb521": "319ce2", + "3a6b8c": "14131a", + "9cceff": "424242" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/379.json b/public/images/pokemon/variant/379.json new file mode 100644 index 00000000000..926acc7d987 --- /dev/null +++ b/public/images/pokemon/variant/379.json @@ -0,0 +1,30 @@ +{ + "1": { + "4a5a5a": "34366f", + "ff4242": "5cbed3", + "3a4252": "292960", + "ff9ca5": "d2d3c9", + "d6ced6": "cc9c65", + "b5adad": "a66f52", + "ffffff": "fff3aa", + "dedede": "f0d185", + "848c84": "4c5c91", + "4a4a4a": "533329", + "84847b": "80503b", + "bdbdbd": "7a9ee5" + }, + "2": { + "4a5a5a": "df8533", + "ff4242": "1e1e1e", + "3a4252": "e29631", + "ff9ca5": "a0a0a0", + "d6ced6": "cd5521", + "b5adad": "ad2d1e", + "ffffff": "ffb056", + "dedede": "e87537", + "848c84": "ffcd49", + "4a4a4a": "521328", + "84847b": "81222b", + "bdbdbd": "ffff7e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/39.json b/public/images/pokemon/variant/39.json new file mode 100644 index 00000000000..c72887bdf9d --- /dev/null +++ b/public/images/pokemon/variant/39.json @@ -0,0 +1,26 @@ +{ + "1": { + "d63a31": "f18fc4", + "a53100": "6f305b", + "ffada5": "c5ebd5", + "e67384": "81c2b8", + "10b5ef": "a17ed9", + "ffcec5": "e5ffec", + "104a8c": "393178", + "1973c5": "604ea1", + "a51021": "3a6472", + "6b5263": "153427", + "ceefff": "d9d3e3" + }, + "2": { + "ffada5": "f5e884", + "e67384": "f5c45b", + "10b5ef": "d14b4b", + "ffcec5": "fff9bf", + "104a8c": "8a2f2f", + "1973c5": "c45c54", + "a51021": "9c5200", + "6b5263": "737454", + "ceefff": "ffe9ed" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/390.json b/public/images/pokemon/variant/390.json new file mode 100644 index 00000000000..ba0119974de --- /dev/null +++ b/public/images/pokemon/variant/390.json @@ -0,0 +1,34 @@ +{ + "1": { + "e63131": "1db978", + "b56b29": "64464d", + "9c3131": "174c48", + "947308": "a86256", + "7b4210": "382029", + "ef6b6b": "5db95b", + "ffd631": "eafe67", + "f06e6e": "81dc3f", + "ffe6ad": "edc6a4", + "7e4410": "994943", + "ffad52": "a88d8d", + "e63a42": "2d8766", + "de8400": "876766", + "deb552": "cc9176" + }, + "2": { + "e63131": "b5b0f3", + "b56b29": "293b69", + "9c3131": "422e6f", + "947308": "818596", + "7b4210": "171f46", + "ef6b6b": "cb96e5", + "ffd631": "f3f8fe", + "f06e6e": "cbcfff", + "ffe6ad": "d3d5e0", + "7e4410": "626678", + "ffad52": "6995b5", + "e63a42": "8457b0", + "de8400": "3e5f8a", + "deb552": "a5a9b8" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/391.json b/public/images/pokemon/variant/391.json new file mode 100644 index 00000000000..c3503dec40a --- /dev/null +++ b/public/images/pokemon/variant/391.json @@ -0,0 +1,40 @@ +{ + "1": { + "8c7342": "994943", + "dfe5e7": "dac99d", + "c59463": "cc9176", + "cf3419": "2d8766", + "9c5219": "64464d", + "ffffff": "faf7d4", + "735a10": "a86256", + "cf2b19": "c9537e", + "ffce47": "f69044", + "efa542": "cd5528", + "ffce42": "eafe67", + "1052b5": "751a2f", + "1073de": "cc3140", + "6b3a08": "382029", + "d68c29": "876766", + "ce4219": "1db978", + "efce94": "edc6a4" + }, + "2": { + "8c7342": "818596", + "dfe5e7": "dca15d", + "c59463": "a5a9b8", + "cf3419": "8457b0", + "9c5219": "293b69", + "ffffff": "ffe175", + "735a10": "626678", + "cf2b19": "552b94", + "ffce47": "e8fdff", + "efa542": "b0cbd4", + "ffce42": "f3f8fe", + "1052b5": "e09f2f", + "1073de": "ffd745", + "6b3a08": "171f46", + "d68c29": "3e5f8a", + "ce4219": "b5b0f3", + "efce94": "d3d5e0" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/392.json b/public/images/pokemon/variant/392.json new file mode 100644 index 00000000000..78a9777736a --- /dev/null +++ b/public/images/pokemon/variant/392.json @@ -0,0 +1,54 @@ +{ + "1": { + "000000": "ffffff", + "a96442": "1a8251", + "a56240": "10916d", + "e68c5a": "876766", + "6b3a10": "382029", + "cfa423": "c9601e", + "bdc5de": "dac99d", + "a56342": "64464d", + "c9a022": "b7e350", + "737384": "9f8876", + "e63a42": "1db978", + "c59c21": "cd5528", + "875d08": "b03813", + "ffde4a": "e8a82a", + "ffde52": "f69044", + "e6353e": "2d8766", + "19427b": "581225", + "f88c49": "5db95b", + "ffffff": "faf7d4", + "845a08": "9b2719", + "3a73a5": "972733", + "f78c4a": "81dc3f", + "ffde4d": "eafe67", + "842931": "174c48" + }, + "2": { + "000000": "ffffff", + "a96442": "4c2985", + "a56240": "9595db", + "e68c5a": "3e5f8a", + "6b3a10": "171f46", + "cfa423": "c8af9b", + "bdc5de": "dca15d", + "a56342": "293b69", + "c9a022": "cbd0e3", + "737384": "a15a34", + "e63a42": "b5b0f3", + "c59c21": "a0c0cd", + "875d08": "8a5954", + "ffde4a": "fff8e5", + "ffde52": "e8fdff", + "e6353e": "8457b0", + "19427b": "4d5196", + "f88c49": "cb96e5", + "ffffff": "ffe175", + "845a08": "617995", + "3a73a5": "9c96e2", + "f78c4a": "cbcfff", + "ffde4d": "f3f8fe", + "842931": "422e6f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/40.json b/public/images/pokemon/variant/40.json new file mode 100644 index 00000000000..9ec866694ca --- /dev/null +++ b/public/images/pokemon/variant/40.json @@ -0,0 +1,27 @@ +{ + "1": { + "737373": "1f2e3b", + "ffb3db": "f18fc4", + "9c6b21": "153139", + "8c4242": "3a6472", + "52a58c": "a17ed9", + "f77b94": "81c2b8", + "734219": "214f4f", + "ffadbd": "c5ebd5", + "ce6b63": "82b8a9", + "215a63": "393178" + }, + "2": { + "737373": "3b1f24", + "e6dee6": "bc4e24", + "9c6b21": "612719", + "8c4242": "9c5200", + "52a58c": "c45c54", + "f77b94": "f5c45b", + "ffffff": "d07439", + "734219": "68311a", + "ffadbd": "f5e884", + "ce6b63": "e6a54c", + "215a63": "8a2f2f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/430.json b/public/images/pokemon/variant/430.json new file mode 100644 index 00000000000..e6771e34524 --- /dev/null +++ b/public/images/pokemon/variant/430.json @@ -0,0 +1,40 @@ +{ + "1": { + "31313a": "1d1d2b", + "efeff7": "b9382d", + "8c313a": "b3986b", + "5a5a3a": "1e1e2c", + "545454": "3c3b4d", + "29213a": "271b1a", + "3a5a9c": "694c30", + "8c3039": "9e2933", + "de5057": "bd392d", + "a3a3b5": "60606c", + "a5a5b5": "7a1e21", + "de525a": "f3e3b3", + "4a2121": "755237", + "ad943a": "3f3e50", + "3a3a5a": "422e26", + "525252": "380514", + "f7de3a": "61616d" + }, + "2": { + "31313a": "521a16", + "efeff7": "975bc2", + "8c313a": "bc4b84", + "5a5a3a": "4e1915", + "545454": "87432e", + "29213a": "091e16", + "3a5a9c": "1d6e47", + "8c3039": "9e2933", + "de5057": "bd392d", + "a3a3b5": "c4743b", + "a5a5b5": "4f358e", + "de525a": "f17f9c", + "4a2121": "7b2363", + "ad943a": "85412d", + "3a3a5a": "0e4333", + "525252": "1c1754", + "f7de3a": "c2723a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/455.json b/public/images/pokemon/variant/455.json new file mode 100644 index 00000000000..1483b02ef5b --- /dev/null +++ b/public/images/pokemon/variant/455.json @@ -0,0 +1,35 @@ +{ + "1": { + "f7ce31": "7c5d53", + "c59c31": "4d3432", + "9c214a": "451e14", + "2b453d": "523b3c", + "3a5a3a": "b34a82", + "5a6342": "826660", + "8c9452": "b89d8c", + "846b31": "301e20", + "bdc57b": "efd9ba", + "422919": "300c0c", + "e62919": "775331", + "63843a": "e880ab", + "29423a": "7e3b67", + "8f9653": "e2b0bc" + }, + "2": { + "f7ce31": "518078", + "ffffff": "affffe", + "c59c31": "244a45", + "9c214a": "1e4340", + "2b453d": "151926", + "3a5a3a": "37818a", + "5a6342": "2d304e", + "8c9452": "424d6e", + "846b31": "122e2f", + "bdc57b": "6679a1", + "422919": "0d2626", + "e62919": "406b64", + "63843a": "74ddcd", + "29423a": "123247", + "8f9653": "3d909b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/486.json b/public/images/pokemon/variant/486.json new file mode 100644 index 00000000000..32082b03337 --- /dev/null +++ b/public/images/pokemon/variant/486.json @@ -0,0 +1,41 @@ +{ + "1": { + "364859": "611d2a", + "adadc5": "ca7426", + "374859": "6b76a4", + "3a4a5a": "5e1e33", + "4aa563": "e2f2ff", + "5f6d7d": "7b2a19", + "ef7b8c": "7741a1", + "b5bdc5": "0d6696", + "5ac5f7": "5f94d9", + "d6ced6": "e89b34", + "3c4d5e": "3f031d", + "ffffff": "eb8746", + "21846b": "90a7cd", + "fafafa": "ffc245", + "c59c52": "a12612", + "f7d65a": "ce5129", + "7b6321": "3d021b", + "8c94ad": "13081a" + }, + "2": { + "364859": "24293f", + "adadc5": "4f673a", + "374859": "2f1a18", + "3a4a5a": "3b1930", + "4aa563": "755648", + "5f6d7d": "374427", + "ef7b8c": "811745", + "b5bdc5": "f1c832", + "5ac5f7": "d3271a", + "d6ced6": "6e884b", + "ffffff": "a8afaf", + "21846b": "492f29", + "fafafa": "88b06f", + "c59c52": "5d717a", + "f7d65a": "8f9b9e", + "7b6321": "384751", + "8c94ad": "494922" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/501.json b/public/images/pokemon/variant/501.json new file mode 100644 index 00000000000..e70d0319842 --- /dev/null +++ b/public/images/pokemon/variant/501.json @@ -0,0 +1,33 @@ +{ + "1": { + "c59429": "ff9ef3", + "efce84": "f2d5ee", + "294252": "241e44", + "c49529": "b73891", + "215a63": "1e1a35", + "c5c5ce": "e3c2ca", + "4a6bad": "9660d1", + "21949c": "373049", + "29bdc5": "5d4a70", + "8c5a31": "af62ac", + "31426b": "4b349e", + "8a5830": "681d49" + }, + "2": { + "8c8c9c": "8f7491", + "c59429": "4e8787", + "efce84": "8abfb1", + "4a4a4a": "715b72", + "294252": "104432", + "c49529": "4e8787", + "215a63": "000000", + "c5c5ce": "ba9bc1", + "4a6bad": "589787", + "21949c": "321e1e", + "ffffff": "f5e9f4", + "29bdc5": "5e3e38", + "8c5a31": "0c4848", + "31426b": "3c706b", + "8a5830": "0c4848" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/502.json b/public/images/pokemon/variant/502.json new file mode 100644 index 00000000000..4227d277216 --- /dev/null +++ b/public/images/pokemon/variant/502.json @@ -0,0 +1,33 @@ +{ + "1": { + "7b5a10": "d877cd", + "31528c": "9d5bc9", + "4a4a4a": "20193d", + "efd68c": "f2d5ee", + "293a6b": "503e8e", + "c5525a": "b73891", + "52bdbd": "624060", + "c59429": "ff9ef3", + "733a3a": "6b1d42", + "313131": "120f33", + "315a73": "1e1624", + "218c94": "39273d", + "fffdfd": "ebb9c4" + }, + "2": { + "7b5a10": "0d5656", + "31528c": "5e3e38", + "4a4a4a": "2c3940", + "efd68c": "63c7bd", + "293a6b": "321e1e", + "c5525a": "519785", + "52bdbd": "8b7566", + "c59429": "488383", + "733a3a": "377667", + "313131": "1f2b36", + "315a73": "483026", + "218c94": "684f44", + "fffdfd": "ffffc2", + "ffffff": "ffffc2" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/503.json b/public/images/pokemon/variant/503.json new file mode 100644 index 00000000000..16447be5cca --- /dev/null +++ b/public/images/pokemon/variant/503.json @@ -0,0 +1,37 @@ +{ + "1": { + "84a5a5": "563785", + "4a4a4a": "5e283e", + "215a9c": "4c234a", + "c5c5ce": "b57ea1", + "8aa3a3": "a05982", + "d65263": "b73891", + "8da8a8": "a58b90", + "7b6342": "975fad", + "fffeff": "ebb9c4", + "213a63": "28142c", + "4a4a4c": "6b3e51", + "d6c57b": "f2d5ee", + "5a7373": "332a59", + "ad945a": "db87d1" + }, + "2": { + "84a5a5": "41857b", + "4a4a4a": "c2700d", + "215a9c": "5e3e38", + "c5c5ce": "efa838", + "8aa3a3": "d3a51f", + "d65263": "41857b", + "8da8a8": "bdbdbd", + "7b6342": "0d5656", + "fdfdff": "ffffff", + "fffeff": "f9df58", + "213a63": "321e1e", + "4a4a4c": "c2700d", + "d6c57b": "63c7bd", + "5a7373": "2a5c57", + "9ab2af": "2a5c57", + "494644": "1a5451", + "ad945a": "488383" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/527.json b/public/images/pokemon/variant/527.json new file mode 100644 index 00000000000..460a954874f --- /dev/null +++ b/public/images/pokemon/variant/527.json @@ -0,0 +1,28 @@ +{ + "1": { + "191921": "24224f", + "424a5a": "866ca1", + "6b94ad": "6e315e", + "f7adb5": "8ffff9", + "73adc5": "853d6f", + "292931": "55457a", + "ce2942": "a3ffed", + "8c4a52": "4874b8", + "84193a": "5fd4d0", + "c56b7b": "6bc7e8", + "4a6b7b": "361538", + "addef7": "914a6e" + }, + "2": { + "191921": "45234d", + "424a5a": "bf3f75", + "6b94ad": "db843d", + "f7adb5": "b682e0", + "73adc5": "e8b04f", + "292931": "8c2961", + "8c4a52": "393582", + "c56b7b": "7b5ebf", + "4a6b7b": "994d22", + "addef7": "f7e05c" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/528.json b/public/images/pokemon/variant/528.json new file mode 100644 index 00000000000..86dd66a4344 --- /dev/null +++ b/public/images/pokemon/variant/528.json @@ -0,0 +1,38 @@ +{ + "1": { + "bdbdce": "76debd", + "313131": "55457a", + "ceefff": "a6ffd7", + "425aa5": "451b41", + "4a4a52": "866ca1", + "2b2b2b": "2b4182", + "2e2e2e": "2f1236", + "f7a59c": "8ffff9", + "317b94": "6e315e", + "54546d": "582253", + "de8c84": "6bc7e8", + "19a5ce": "914a6e", + "944a4a": "4874b8", + "494950": "3b53a3", + "6b7b84": "439ca1", + "363636": "2e6f7a" + }, + "2": { + "bdbdce": "db843d", + "313131": "701c4c", + "ceefff": "f7e05c", + "425aa5": "d6a178", + "4a4a52": "bf3f75", + "2b2b2b": "1d1c4f", + "2e2e2e": "a6705e", + "f7a59c": "b682e0", + "317b94": "e0b49a", + "54546d": "a87354", + "de8c84": "7b5ebf", + "19a5ce": "f9fae3", + "944a4a": "393582", + "494950": "1b1f4d", + "6b7b84": "994d22", + "363636": "6b2314" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/587.json b/public/images/pokemon/variant/587.json new file mode 100644 index 00000000000..34831752444 --- /dev/null +++ b/public/images/pokemon/variant/587.json @@ -0,0 +1,33 @@ +{ + "1": { + "d6a531": "a84223", + "fffbf6": "8bd5dc", + "917d53": "16223d", + "ffd600": "d55b19", + "313131": "1d352a", + "212121": "091814", + "b58c08": "681c0e", + "cec5ad": "5a9fbf", + "6b5a31": "3b1c1b", + "a09478": "406da4", + "414141": "2b5d3f", + "434141": "2b5d3f" + }, + "2": { + "c56b63": "5046a7", + "d6a531": "6597cd", + "fffbf6": "c4658e", + "917d53": "321832", + "ffd600": "8bcaee", + "943a42": "462060", + "313131": "372a5b", + "212121": "15132f", + "e69484": "8166c6", + "b58c08": "4879af", + "cec5ad": "9b4072", + "6b5a31": "28273d", + "a09478": "7b3760", + "414141": "5e3a86", + "434141": "5e3a86" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/588.json b/public/images/pokemon/variant/588.json new file mode 100644 index 00000000000..86aa0e118f7 --- /dev/null +++ b/public/images/pokemon/variant/588.json @@ -0,0 +1,33 @@ +{ + "1": { + "213a5a": "2f185b", + "316bff": "8150a7", + "73d6ff": "e8aa48", + "313131": "38131d", + "736321": "8188b0", + "c55200": "b9262c", + "528cff": "c682d6", + "b59c19": "b8c5e5", + "4a4a4a": "64242d", + "000000": "ffffff", + "3a5284": "492c72", + "ffde19": "eef5ff", + "4294ad": "cd6a31" + }, + "2": { + "213a5a": "44446f", + "316bff": "d2cdeb", + "73d6ff": "ffe28d", + "313131": "182138", + "736321": "6f1b34", + "c55200": "ffe8c3", + "528cff": "f9f3ff", + "ce5263": "df6b99", + "b59c19": "a42641", + "4a4a4a": "28334f", + "000000": "ffffff", + "3a5284": "7777a7", + "ffde19": "d0413f", + "4294ad": "d9a35c" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/589.json b/public/images/pokemon/variant/589.json new file mode 100644 index 00000000000..486088d13d3 --- /dev/null +++ b/public/images/pokemon/variant/589.json @@ -0,0 +1,32 @@ +{ + "1": { + "c5c5c5": "f9c347", + "ef2952": "eb8343", + "e65a10": "614593", + "bd2152": "c44126", + "736321": "7b8bb3", + "840808": "931119", + "000000": "ffffff", + "6b6b6b": "b34516", + "bd9c19": "b8c5e5", + "195abd": "7436a4", + "94949c": "dc862d", + "ffde19": "eef5ff", + "3a424a": "69130d" + }, + "2": { + "c5c5c5": "6e8e99", + "ef2952": "f7efff", + "e65a10": "ffe8c3", + "bd2152": "beb7df", + "736321": "6f1b34", + "840808": "72709e", + "000000": "ffffff", + "6b6b6b": "293a52", + "bd9c19": "a42641", + "195abd": "4f3d33", + "94949c": "3f6372", + "ffde19": "d0413f", + "3a424a": "1b253d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/590.json b/public/images/pokemon/variant/590.json new file mode 100644 index 00000000000..d17924e966c --- /dev/null +++ b/public/images/pokemon/variant/590.json @@ -0,0 +1,30 @@ +{ + "1": { + "826b61": "348999", + "9c3a3a": "71de8c", + "846b63": "348999", + "6b4a31": "0d9999", + "684b30": "0d9999", + "422929": "0a5870", + "9c3a7b": "88af70", + "de5a52": "e6ffc1", + "d6639c": "f4ebba", + "7b3131": "49ad77", + "c5b59c": "47d1b5", + "fff7e6": "afecc6" + }, + "2": { + "826b61": "86b8cc", + "9c3a3a": "e098cd", + "846b63": "404f6b", + "6b4a31": "f2f7f9", + "684b30": "2b5caf", + "422929": "b9d9e5", + "9c3a7b": "b1c4dd", + "de5a52": "ffbfcb", + "d6639c": "f2f7f9", + "7b3131": "ce88bb", + "c5b59c": "498cd3", + "fff7e6": "6ac2e2" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/591.json b/public/images/pokemon/variant/591.json new file mode 100644 index 00000000000..d0290501b39 --- /dev/null +++ b/public/images/pokemon/variant/591.json @@ -0,0 +1,42 @@ +{ + "1": { + "423231": "0c7588", + "533f3a": "094164", + "604740": "0b7f79", + "6b314a": "49ad77", + "423131": "0a5870", + "8c735a": "348999", + "cec5c5": "afecc6", + "634b42": "094164", + "9c9484": "47d1b5", + "423331": "0c7588", + "634c42": "348999", + "291919": "094164", + "ad3163": "71de8c", + "de8ca5": "d8cfa0", + "634a42": "0d9999", + "6b314c": "749660", + "ffadce": "f4ebba", + "de528c": "e6ffc1" + }, + "2": { + "423231": "404f6b", + "533f3a": "223656", + "604740": "3b6aa0", + "6b314a": "ad629a", + "423131": "9bb6c1", + "8c735a": "2b5caf", + "cec5c5": "6ac2e2", + "634b42": "223656", + "9c9484": "56a1e2", + "423331": "9bb6c1", + "634c42": "3f7dc7", + "291919": "5e718e", + "ad3163": "e098cd", + "de8ca5": "b1c4dd", + "634a42": "f2f7f9", + "6b314c": "65788e", + "ffadce": "f4f8f9", + "de528c": "ffbfcb" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/616.json b/public/images/pokemon/variant/616.json new file mode 100644 index 00000000000..184360b3734 --- /dev/null +++ b/public/images/pokemon/variant/616.json @@ -0,0 +1,30 @@ +{ + "1": { + "3a8442": "4e3671", + "42bd31": "775998", + "313131": "491722", + "c5c5d6": "f9c347", + "9494ad": "dc862d", + "ff4a7b": "6ba779", + "630021": "204b4f", + "b5214a": "346c65", + "de3163": "4a8474", + "000000": "ffffff", + "29315a": "69130d", + "5a5a7b": "b34516" + }, + "2": { + "3a8442": "dfa75c", + "42bd31": "fff07e", + "313131": "171e2f", + "c5c5d6": "6e8e99", + "9494ad": "3f6372", + "ff4a7b": "8cb0d6", + "630021": "2e3469", + "b5214a": "4f62a4", + "de3163": "6b8bbf", + "000000": "ffffff", + "29315a": "1b253d", + "5a5a7b": "293a52" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/617.json b/public/images/pokemon/variant/617.json new file mode 100644 index 00000000000..7c2951b5571 --- /dev/null +++ b/public/images/pokemon/variant/617.json @@ -0,0 +1,30 @@ +{ + "1": { + "ffffff": "fff47e", + "a5846b": "5a6675", + "42b55a": "4e3671", + "c53a6b": "427b6b", + "bdbdce": "df9847", + "527b42": "362658", + "732931": "214c49", + "ff4a7b": "6ba779", + "6b84c5": "eef5ff", + "3a2919": "192638", + "000000": "ffffff", + "293a6b": "69719e", + "5a6384": "b8c5e5" + }, + "2": { + "a5846b": "637974", + "42b55a": "415c69", + "c53a6b": "dcaa47", + "527b42": "1d2a3b", + "732931": "8a5727", + "ff4a7b": "ffee72", + "6b84c5": "b43d40", + "3a2919": "2a2235", + "000000": "ffffff", + "293a6b": "461b2e", + "5a6384": "7b2c3d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/621.json b/public/images/pokemon/variant/621.json new file mode 100644 index 00000000000..1c347dcadc8 --- /dev/null +++ b/public/images/pokemon/variant/621.json @@ -0,0 +1,28 @@ +{ + "1": { + "d6bd6b": "ac8b5e", + "940042": "1a2248", + "635231": "605127", + "104a8c": "7e231b", + "8c7b5a": "73654b", + "efc500": "5c7886", + "103163": "601111", + "521031": "0f1330", + "d60042": "26335d", + "316bad": "a13b2c", + "d65273": "be5b5e" + }, + "2": { + "d6bd6b": "ffbc30", + "940042": "177297", + "635231": "be6e18", + "104a8c": "c9bb9a", + "8c7b5a": "da8921", + "efc500": "ffd437", + "103163": "a0896b", + "521031": "0f4973", + "d60042": "24aec0", + "316bad": "e3ddbd", + "d65273": "c583a5" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/6503.json b/public/images/pokemon/variant/6503.json new file mode 100644 index 00000000000..c6cc21b45db --- /dev/null +++ b/public/images/pokemon/variant/6503.json @@ -0,0 +1,34 @@ +{ + "1": { + "282f62": "f7d9de", + "c4c5cf": "e3c2ca", + "84a4a7": "563785", + "a82c47": "d45b9e", + "8aa3a3": "6b415b", + "494a48": "3d2439", + "1d3962": "28142c", + "d75063": "b73891", + "1e224e": "dc95ae", + "1e5b9b": "4d244b", + "181531": "a26579", + "6b1c34": "8f3396", + "597471": "332a59", + "8da8a8": "a58b90" + }, + "2": { + "282f62": "efdfee", + "c4c5cf": "232d2e", + "84a4a7": "41857b", + "a82c47": "8abfb1", + "8aa3a3": "181f20", + "faf9f9": "2c3940", + "494a48": "0b0f18", + "1d3962": "321e1e", + "d75063": "8f65d8", + "1e224e": "ba9bc1", + "1e5b9b": "5e3e38", + "181531": "715b72", + "6b1c34": "6d9d9a", + "597471": "2a5c57" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/656.json b/public/images/pokemon/variant/656.json new file mode 100644 index 00000000000..68743a4c9f1 --- /dev/null +++ b/public/images/pokemon/variant/656.json @@ -0,0 +1,32 @@ +{ + "1": { + "838394": "4d7dc5", + "62ace6": "8363af", + "7bcdff": "9c75c2", + "ffec8c": "ddfff9", + "a1a1c4": "7ab7ec", + "c9b241": "97d6e2", + "dfcf77": "bae7e8", + "174592": "37408c", + "fdfdfd": "b1e5ff", + "9c9cc5": "5385c7", + "cdcde6": "7eb7e8", + "396a83": "362864", + "5a94cd": "7054a4" + }, + "2": { + "838394": "cc6845", + "62ace6": "c44848", + "7bcdff": "dd6155", + "ffec8c": "ddfff9", + "a1a1c4": "f7c685", + "c9b241": "97d6e2", + "dfcf77": "bae7e8", + "174592": "198158", + "fdfdfd": "fff4bd", + "9c9cc5": "c96a48", + "cdcde6": "f7b785", + "396a83": "5c0d33", + "5a94cd": "a92f3f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/657.json b/public/images/pokemon/variant/657.json new file mode 100644 index 00000000000..773b4d2efc1 --- /dev/null +++ b/public/images/pokemon/variant/657.json @@ -0,0 +1,32 @@ +{ + "1": { + "f8f8f8": "8dcfff", + "efc653": "abd7db", + "737373": "0f3f82", + "0b566a": "281f52", + "ffec72": "c9fff5", + "002c58": "1c0726", + "bfbfbf": "4386df", + "006ba6": "4e1852", + "009dd5": "61255e", + "0b4a7a": "340f3d", + "e1a03a": "78c7c7", + "41ccf5": "7755a7", + "2896b5": "4b3578" + }, + "2": { + "f8f8f8": "fff6c7", + "efc653": "abd7db", + "737373": "df6a50", + "0b566a": "7e1628", + "ffec72": "ddfff9", + "002c58": "0c3b54", + "bfbfbf": "ffc996", + "006ba6": "239c91", + "009dd5": "37b8ac", + "0b4a7a": "156f78", + "e1a03a": "86abbb", + "41ccf5": "dd7355", + "2896b5": "a92f3a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/658-ash.json b/public/images/pokemon/variant/658-ash.json new file mode 100644 index 00000000000..29b5bd2560b --- /dev/null +++ b/public/images/pokemon/variant/658-ash.json @@ -0,0 +1,44 @@ +{ + "1": { + "265595": "432b6c", + "3f4447": "466698", + "de3431": "3fca9f", + "f8f8f8": "a1e9f0", + "7b282e": "0e3e81", + "6b1d1d": "206d74", + "4ebdd9": "41a7b0", + "bfb169": "165e78", + "bfbfbf": "8cc7d4", + "ffb2bf": "b7e9ff", + "bf4c60": "4386df", + "fff0a6": "271f4c", + "3e7acc": "6b4592", + "18335c": "170738", + "f2798d": "8dcfff", + "f01818": "39b88f", + "7ddeff": "7ddcd6", + "268794": "1c3e58", + "282c35": "271f4c" + }, + "2": { + "265595": "cc7251", + "3f4447": "466698", + "de3431": "9ceec6", + "f8f8f8": "89d2b8", + "7b282e": "152a5c", + "6b1d1d": "356e8d", + "4ebdd9": "2f6e74", + "bfb169": "431022", + "bfbfbf": "8cc7d4", + "ffb2bf": "86d6b6", + "bf4c60": "32738b", + "fff0a6": "4d2637", + "3e7acc": "ecbb7a", + "18335c": "9f2727", + "f2798d": "5eb4a9", + "f01818": "ffe88d", + "7ddeff": "46988d", + "268794": "1c3e58", + "282c35": "4d2637" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/658.json b/public/images/pokemon/variant/658.json new file mode 100644 index 00000000000..25a6dad359d --- /dev/null +++ b/public/images/pokemon/variant/658.json @@ -0,0 +1,34 @@ +{ + "1": { + "ffb2bf": "b7e9ff", + "bf4c60": "4386df", + "66d9ff": "7ddcd6", + "3d61cc": "6b4592", + "fff0a6": "208698", + "c92e2e": "73c5ff", + "937f69": "406695", + "c2c1bc": "89b0d7", + "f2798d": "8dcfff", + "f7f7f7": "d8ffff", + "2e4999": "432b6c", + "bfb169": "165e78", + "803340": "0e3e81", + "1b2a59": "170738" + }, + "2": { + "ffb2bf": "86d6b6", + "bf4c60": "32738b", + "66d9ff": "48968c", + "3d61cc": "ecbb7a", + "fff0a6": "652240", + "c92e2e": "63bf9b", + "937f69": "466698", + "c2c1bc": "8cc7d4", + "f2798d": "5eb4a9", + "f7f7f7": "d7eff4", + "2e4999": "cc7251", + "bfb169": "431022", + "803340": "152a5c", + "1b2a59": "9f2727" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/6706.json b/public/images/pokemon/variant/6706.json new file mode 100644 index 00000000000..2b9ead28219 --- /dev/null +++ b/public/images/pokemon/variant/6706.json @@ -0,0 +1,40 @@ +{ + "1": { + "566678": "0e6296", + "e0e4f4": "513981", + "625287": "4e4094", + "536273": "1f1233", + "988b98": "b24c86", + "9170b9": "8b69c3", + "c4cce1": "3b235c", + "e6d3e9": "f1a4c5", + "bfacc1": "da75a5", + "515f70": "197497", + "c5cee3": "63cee1", + "8e96aa": "301848", + "8b93a6": "3aa8c4", + "80737f": "8a2166", + "4b454f": "6f1357", + "36404c": "0c5474", + "b791f2": "c7a1e5" + }, + "2": { + "566678": "8e480b", + "e0e4f4": "176463", + "625287": "274159", + "536273": "02262c", + "988b98": "2a6563", + "9170b9": "2f667c", + "c4cce1": "0d484a", + "e6d3e9": "9cead8", + "bfacc1": "5db6a9", + "515f70": "a34205", + "c5cee3": "f7af58", + "8e96aa": "073338", + "8b93a6": "d27e26", + "80737f": "2b736f", + "4b454f": "194f51", + "36404c": "842401", + "b791f2": "4a9699" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/6706_3.json b/public/images/pokemon/variant/6706_3.json deleted file mode 100644 index 615ca90e004..00000000000 --- a/public/images/pokemon/variant/6706_3.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "textures": [ - { - "image": "6706_3.png", - "format": "RGBA8888", - "size": { - "w": 82, - "h": 82 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 82, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 82, - "h": 72 - }, - "frame": { - "x": 0, - "y": 0, - "w": 82, - "h": 72 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:02eb46aa66ac70df612e129b7801a85c:a77cca14b23f4f3aece64d1a82449a0f:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-dandy.json b/public/images/pokemon/variant/676-dandy.json new file mode 100644 index 00000000000..ac18c8446d9 --- /dev/null +++ b/public/images/pokemon/variant/676-dandy.json @@ -0,0 +1,30 @@ +{ + "1": { + "594d46": "788087", + "30552b": "423839", + "b8bcaf": "5e0f16", + "f1f2ee": "8a1d1d", + "376277": "4f8fe3", + "9c9f94": "42090e", + "4b4b46": "2b040f", + "508a3c": "aa9999", + "816e64": "a6afb3", + "6eb92b": "eddddd", + "453434": "313439" + }, + "2": { + "594d46": "9c7aca", + "30552b": "6a102e", + "b8bcaf": "ce9ede", + "f1f2ee": "e6c3f8", + "376277": "314173", + "fe3c31": "8362b4", + "9c9f94": "ad76bc", + "4b4b46": "6b3f77", + "508a3c": "ac254b", + "a83c31": "473085", + "816e64": "ae95dc", + "6eb92b": "e44a62", + "453434": "593173" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-debutante.json b/public/images/pokemon/variant/676-debutante.json new file mode 100644 index 00000000000..bf3d0dfe212 --- /dev/null +++ b/public/images/pokemon/variant/676-debutante.json @@ -0,0 +1,30 @@ +{ + "1": { + "594d46": "788087", + "376277": "4f8fe3", + "9c9f94": "42090e", + "f8f9f7": "8a1d1d", + "dfb76a": "aa9999", + "4b4b46": "2b040f", + "bcc0b3": "5e0f16", + "453434": "313439", + "816e64": "a6afb3", + "ac6d40": "423839", + "fbf588": "e3d6d6" + }, + "2": { + "594d46": "48a7d0", + "376277": "717171", + "fe3c31": "762ea8", + "9c9f94": "122a39", + "f8f9f7": "0e728e", + "dfb76a": "c6a65c", + "4b4b46": "021a2f", + "bcc0b3": "0b4b68", + "453434": "122a39", + "a83c31": "521073", + "816e64": "74ccec", + "ac6d40": "684d24", + "fbf588": "ffe998" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-diamond.json b/public/images/pokemon/variant/676-diamond.json new file mode 100644 index 00000000000..72e19d6a853 --- /dev/null +++ b/public/images/pokemon/variant/676-diamond.json @@ -0,0 +1,28 @@ +{ + "1": { + "594d46": "788087", + "aa3e2b": "423839", + "b8bcaf": "5e0f16", + "f1f2ee": "8a1d1d", + "376277": "4f8fe3", + "645e55": "2b040f", + "d95b37": "aa9999", + "e68a4d": "eddddd", + "453434": "313439", + "816e64": "a6afb3" + }, + "2": { + "594d46": "bd9462", + "aa3e2b": "642c0a", + "b8bcaf": "319c6a", + "f1f2ee": "6abd81", + "376277": "c56e34", + "fe3c31": "b37e47", + "645e55": "1b684b", + "d95b37": "935927", + "e68a4d": "b37e47", + "453434": "6c4b2d", + "a83c31": "642c0a", + "816e64": "eed59c" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-heart.json b/public/images/pokemon/variant/676-heart.json new file mode 100644 index 00000000000..895b5b49e99 --- /dev/null +++ b/public/images/pokemon/variant/676-heart.json @@ -0,0 +1,28 @@ +{ + "1": { + "594d46": "788087", + "f18598": "48474c", + "b8bcaf": "5e0f16", + "f1f2ee": "8a1d1d", + "e0546c": "2a2a2f", + "376277": "4f8fe3", + "645e55": "2b040f", + "453434": "313439", + "816e64": "a6afb3", + "a73f4f": "19181f" + }, + "2": { + "594d46": "aca49c", + "f18598": "5f5953", + "b8bcaf": "bfc7e8", + "f1f2ee": "e4eafc", + "e0546c": "4c413c", + "376277": "1b1c21", + "fe3c31": "9475de", + "645e55": "7a81b7", + "453434": "837373", + "a83c31": "7249b7", + "816e64": "dadace", + "a73f4f": "2c2320" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-kabuki.json b/public/images/pokemon/variant/676-kabuki.json new file mode 100644 index 00000000000..9d57fc830be --- /dev/null +++ b/public/images/pokemon/variant/676-kabuki.json @@ -0,0 +1,36 @@ +{ + "1": { + "816e64": "a6afb3", + "8f2121": "19181f", + "b01a1a": "2a2a2f", + "d02f2e": "262629", + "594d46": "788087", + "f44b3d": "48474c", + "376277": "4f8fe3", + "68675c": "2b040f", + "453434": "313439", + "8a7d79": "a6afb3", + "9c9f94": "42090e", + "534343": "313439", + "bcc0b3": "5e0f16", + "f1f2ee": "8a1d1d" + }, + "2": { + "816e64": "506e7b", + "8f2121": "1b1d39", + "b01a1a": "305d9e", + "d02f2e": "48578e", + "594d46": "3e5368", + "f66559": "9890ec", + "f44b3d": "4c89d9", + "376277": "436ca1", + "68675c": "192b42", + "453434": "17242f", + "8a7d79": "425a70", + "9c9f94": "468197", + "534343": "233342", + "bcc0b3": "549ab8", + "f1f2ee": "6bcfd9", + "b32524": "8067c6" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-la-reine.json b/public/images/pokemon/variant/676-la-reine.json new file mode 100644 index 00000000000..ae73038cfb2 --- /dev/null +++ b/public/images/pokemon/variant/676-la-reine.json @@ -0,0 +1,32 @@ +{ + "1": { + "816e64": "a6afb3", + "31a7bb": "aa9999", + "594d46": "788087", + "2f7387": "423839", + "453434": "313439", + "4b4b46": "2b040f", + "8a7d79": "a6afb3", + "9c9f94": "42090e", + "376277": "4f8fe3", + "56d1d8": "eddddd", + "bcc0b3": "5e0f16", + "f1f2ee": "8a1d1d" + }, + "2": { + "816e64": "973721", + "a83c31": "3041b7", + "31a7bb": "e3b876", + "594d46": "711e1e", + "2f7387": "8e673e", + "453434": "360608", + "4b4b46": "550b0c", + "8a7d79": "a11e24", + "9c9f94": "c63b31", + "376277": "221755", + "56d1d8": "ffec9b", + "bcc0b3": "d9533c", + "f1f2ee": "ee724b", + "fe3c31": "4b77e1" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-matron.json b/public/images/pokemon/variant/676-matron.json new file mode 100644 index 00000000000..8fdf48c14a8 --- /dev/null +++ b/public/images/pokemon/variant/676-matron.json @@ -0,0 +1,30 @@ +{ + "1": { + "594d46": "788087", + "b8bcaf": "5e0f16", + "873a5b": "19181f", + "376277": "4f8fe3", + "9c9f94": "42090e", + "f8f9f7": "8a1d1d", + "d07da9": "48474c", + "5f5951": "2b040f", + "816e64": "a6afb3", + "453434": "313439", + "b95b83": "2a2a2f" + }, + "2": { + "594d46": "d0b5b5", + "b8bcaf": "d95e7e", + "873a5b": "1b447b", + "376277": "2246aa", + "fe3c31": "64edf3", + "9c9f94": "bd4d6a", + "f8f9f7": "fa8c9f", + "d07da9": "64c8f3", + "5f5951": "8a2843", + "a83c31": "45a6d0", + "816e64": "e3d6d6", + "453434": "715456", + "b95b83": "528fcc" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-pharaoh.json b/public/images/pokemon/variant/676-pharaoh.json new file mode 100644 index 00000000000..cf6694aa348 --- /dev/null +++ b/public/images/pokemon/variant/676-pharaoh.json @@ -0,0 +1,30 @@ +{ + "1": { + "594d46": "788087", + "25559c": "2a2a2f", + "217fc4": "48474c", + "f1f2ee": "8a1d1d", + "376277": "4f8fe3", + "9c9f94": "42090e", + "bcc0b3": "5e0f16", + "68675c": "2b040f", + "453434": "313439", + "816e64": "a6afb3", + "243a6f": "19181f" + }, + "2": { + "594d46": "1c1c30", + "25559c": "d0902d", + "217fc4": "eed552", + "f1f2ee": "5e5e75", + "376277": "5e0808", + "fe3c31": "ec4d3e", + "9c9f94": "332b48", + "bcc0b3": "3b3955", + "68675c": "17122f", + "453434": "130b1c", + "a83c31": "a11717", + "816e64": "312c42", + "243a6f": "a15317" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676-star.json b/public/images/pokemon/variant/676-star.json new file mode 100644 index 00000000000..e0b0e330676 --- /dev/null +++ b/public/images/pokemon/variant/676-star.json @@ -0,0 +1,28 @@ +{ + "1": { + "594d46": "788087", + "376277": "4f8fe3", + "645e55": "2b040f", + "b8bcaf": "5e0f16", + "3e8ebf": "2a2a2f", + "f1f2ee": "8a1d1d", + "453434": "313439", + "3a5078": "19181f", + "816e64": "a6afb3", + "7dc2e8": "48474c" + }, + "2": { + "594d46": "d7bc4d", + "376277": "647bb1", + "fe3c31": "b5e0f3", + "645e55": "848e75", + "a83c31": "6192aa", + "b8bcaf": "d6dec2", + "3e8ebf": "ac802f", + "f1f2ee": "fcfef5", + "453434": "836329", + "3a5078": "613d11", + "816e64": "f7e784", + "7dc2e8": "cdac4a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/676.json b/public/images/pokemon/variant/676.json new file mode 100644 index 00000000000..8c9199960c9 --- /dev/null +++ b/public/images/pokemon/variant/676.json @@ -0,0 +1,21 @@ +{ + "1": { + "bcbca8": "5e0f16", + "606056": "2b040f", + "8e8e7b": "42090e", + "f2f2da": "8a1d1d", + "3f6273": "4f8fe3", + "494340": "788087", + "736b67": "a6afb3" + }, + "2": { + "bcbca8": "a4624a", + "cc2929": "3a240e", + "606056": "4a281b", + "8e8e7b": "805145", + "f2f2da": "c18960", + "3f6273": "4a281b", + "494340": "e6c594", + "736b67": "ffe6ac" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/682.json b/public/images/pokemon/variant/682.json new file mode 100644 index 00000000000..03337345194 --- /dev/null +++ b/public/images/pokemon/variant/682.json @@ -0,0 +1,26 @@ +{ + "1": { + "661f1f": "cd6132", + "bf5f9f": "7c48a1", + "6b3962": "30185d", + "cc7087": "318759", + "993d80": "4f297e", + "ff99b3": "48ab61", + "f24949": "ffa24f", + "7f4d59": "20644e" + }, + "2": { + "661f1f": "daa235", + "bf5f9f": "f0ebdd", + "6b3962": "b89477", + "cc7087": "c3561a", + "993d80": "d2bfa1", + "ff99b3": "da7e29", + "a6a6a6": "503851", + "f24949": "ffe664", + "e5e5e5": "6b4767", + "737373": "422f46", + "4d4d4d": "332539", + "7f4d59": "a23812" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/683.json b/public/images/pokemon/variant/683.json new file mode 100644 index 00000000000..42abc0856ad --- /dev/null +++ b/public/images/pokemon/variant/683.json @@ -0,0 +1,32 @@ +{ + "1": { + "661f1f": "b64d29", + "cc7087": "318759", + "ff99b3": "48ab61", + "fff0a6": "fec04b", + "f24949": "ffa24f", + "6b3962": "30185d", + "e5c37e": "d6872c", + "993d80": "4f297e", + "404040": "2c283b", + "b33636": "f4863f", + "7f4d59": "20644e", + "bf5f9f": "7c48a1" + }, + "2": { + "661f1f": "c78925", + "cc7087": "c3561a", + "ff99b3": "da7e29", + "fff0a6": "6d8719", + "a6a6a6": "503851", + "f24949": "ffe664", + "6b3962": "b89477", + "e5c37e": "376d11", + "993d80": "d2bfa1", + "e5e5e5": "6b4767", + "404040": "2a2234", + "b33636": "f0c150", + "7f4d59": "a23812", + "bf5f9f": "f0ebdd" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/684.json b/public/images/pokemon/variant/684.json new file mode 100644 index 00000000000..df4240c57d6 --- /dev/null +++ b/public/images/pokemon/variant/684.json @@ -0,0 +1,24 @@ +{ + "1": { + "805963": "2d0c42", + "661a2d": "205025", + "e53964": "689b52", + "ffccd9": "814db1", + "f8f8f8": "caff90", + "cc99a6": "613b84", + "fff2f2": "f39f62", + "7b5760": "b13924", + "ccadad": "df6b40" + }, + "2": { + "805963": "679baa", + "661a2d": "26061b", + "e53964": "612747", + "ffccd9": "cbf6da", + "f8f8f8": "e4819d", + "cc99a6": "93d6ce", + "fff2f2": "746998", + "7b5760": "3c2f51", + "ccadad": "4b4876" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/685.json b/public/images/pokemon/variant/685.json new file mode 100644 index 00000000000..99d52263178 --- /dev/null +++ b/public/images/pokemon/variant/685.json @@ -0,0 +1,28 @@ +{ + "1": { + "f8f8f8": "caff90", + "661a2d": "13391c", + "7b5760": "b13924", + "a62949": "26592b", + "ffccd9": "8961c6", + "ff8ca9": "8dbe6d", + "cc99a6": "613b84", + "e53964": "689b52", + "fff2f2": "f39f62", + "ccadad": "df6b40", + "805963": "2d0c42" + }, + "2": { + "f8f8f8": "e4819d", + "661a2d": "26061b", + "7b5760": "3c2f51", + "a62949": "441838", + "ffccd9": "cbf6da", + "ff8ca9": "8c4264", + "cc99a6": "93d6ce", + "e53964": "612747", + "fff2f2": "746998", + "ccadad": "4b4876", + "805963": "679baa" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/688.json b/public/images/pokemon/variant/688.json new file mode 100644 index 00000000000..e5749f6bb3f --- /dev/null +++ b/public/images/pokemon/variant/688.json @@ -0,0 +1,33 @@ +{ + "1": { + "5890b0": "a9582e", + "385860": "70240f", + "372e27": "220a56", + "6b503b": "373295", + "d0d0d0": "d3bc8c", + "c0e0e8": "e8d37b", + "8a6d45": "4557b5", + "101010": "37160a", + "b7653f": "459aac", + "fcffff": "e8e5c6", + "808080": "7c582e", + "88c0c8": "cd8a50", + "ef8955": "70cccf" + }, + "2": { + "5890b0": "4b0038", + "385860": "2c052a", + "372e27": "1e1324", + "6b503b": "ba9fba", + "d0d0d0": "7eac4e", + "c0e0e8": "a74083", + "8a6d45": "f6eefc", + "101010": "0a391b", + "b7653f": "332149", + "fcffff": "caea77", + "f8f8f8": "ffffff", + "808080": "2a5524", + "88c0c8": "731f5c", + "ef8955": "4a376e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/689.json b/public/images/pokemon/variant/689.json new file mode 100644 index 00000000000..cd6db09c8d2 --- /dev/null +++ b/public/images/pokemon/variant/689.json @@ -0,0 +1,31 @@ +{ + "1": { + "bfeaff": "e8d37b", + "f2f2f2": "e8e5c6", + "5b8da6": "8d5030", + "595959": "7c582e", + "403410": "220a56", + "3f6273": "672e1e", + "b3b3b3": "d3bc8c", + "cc7f70": "459aac", + "85b4cc": "cd8a50", + "ff9f8c": "70cccf", + "66541f": "373295", + "997e2e": "4557b5" + }, + "2": { + "bfeaff": "a74083", + "f2f2f2": "caea77", + "5b8da6": "4b0038", + "595959": "2a5524", + "403410": "3f2a4b", + "3f6273": "3e073b", + "b3b3b3": "7eac4e", + "cc7f70": "332149", + "85b4cc": "731f5c", + "f8f8f8": "dbaf67", + "ff9f8c": "4a376e", + "66541f": "ccb6cc", + "997e2e": "f6eefc" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/807.json b/public/images/pokemon/variant/807.json new file mode 100644 index 00000000000..bfb72f3cd42 --- /dev/null +++ b/public/images/pokemon/variant/807.json @@ -0,0 +1,28 @@ +{ + "1": { + "ef8a4e": "4f7bb6", + "484f57": "243058", + "000000": "ffffff", + "727678": "3e5277", + "2759a5": "736599", + "5bd0f2": "ebceff", + "daa936": "5a96b6", + "9d682d": "3c648d", + "f9e455": "7fc7d9", + "2394d8": "b298d8", + "31343e": "14193f" + }, + "2": { + "ef8a4e": "834b95", + "484f57": "cda4cb", + "000000": "ffffff", + "727678": "e8cae3", + "2759a5": "a4378a", + "5bd0f2": "e17197", + "daa936": "331b53", + "9d682d": "1d1044", + "f9e455": "56306f", + "2394d8": "c05192", + "31343e": "a981b1" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/894.json b/public/images/pokemon/variant/894.json new file mode 100644 index 00000000000..99756eea4d5 --- /dev/null +++ b/public/images/pokemon/variant/894.json @@ -0,0 +1,28 @@ +{ + "1": { + "fffbfc": "fefaef", + "e5ee1a": "6ad7f3", + "8eacdd": "caffd1", + "7d542a": "2769aa", + "fefac7": "dffff6", + "bc8b2f": "124b78", + "fffbfb": "dffff6", + "2e3967": "357b84", + "4e7cc9": "9bf1c4", + "375395": "5fcaad", + "ff9dc2": "2c3072", + "d7ad0d": "45a3d6" + }, + "2": { + "e5ee1a": "d4ffd0", + "8eacdd": "c693d8", + "7d542a": "429877", + "fefac7": "ffffff", + "bc8b2f": "2a6f5d", + "2e3967": "514199", + "4e7cc9": "b67cd6", + "375395": "815bad", + "ff9dc2": "382875", + "d7ad0d": "7cd395" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/895.json b/public/images/pokemon/variant/895.json new file mode 100644 index 00000000000..90e3ec96f99 --- /dev/null +++ b/public/images/pokemon/variant/895.json @@ -0,0 +1,32 @@ +{ + "1": { + "641e2c": "722123", + "b63650": "bc623e", + "872c3c": "93372d", + "608d99": "fae5bf", + "2b3d40": "754f47", + "2261ca": "561a5b", + "4b6f78": "f1d4b6", + "e05276": "ef8429", + "242e35": "512c25", + "f27a99": "efb55a", + "76dff5": "ffe8f7", + "3f545f": "ad8473", + "139ee1": "9b407f" + }, + "2": { + "641e2c": "15553b", + "b63650": "3bb349", + "872c3c": "227843", + "608d99": "9b7ebc", + "2b3d40": "241951", + "2261ca": "640e0b", + "4b6f78": "5a4382", + "e05276": "8aea41", + "242e35": "0f0c1e", + "f27a99": "dfff75", + "76dff5": "fffcdf", + "3f545f": "3a2a67", + "139ee1": "98301c" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/944.json b/public/images/pokemon/variant/944.json new file mode 100644 index 00000000000..56fc21986f7 --- /dev/null +++ b/public/images/pokemon/variant/944.json @@ -0,0 +1,42 @@ +{ + "1": { + "b5eab2": "75a0d0", + "d4eac7": "8bcfe5", + "bdb2bd": "53a164", + "ceceb7": "3ec295", + "726766": "4f985c", + "4a4860": "372869", + "8ce1b2": "6383c4", + "564a49": "286943", + "000000": "ffffff", + "4ca391": "3a4a8a", + "a571e6": "ffe269", + "774d9b": "d09139", + "97859b": "3f8d59", + "afc6d8": "8056a7", + "efeee1": "88eeab", + "869fad": "5e4090", + "918772": "1c9b8d", + "3a2b2f": "18493f" + }, + "2": { + "b5eab2": "a9c6dc", + "d4eac7": "e2f8ff", + "bdb2bd": "78b0c2", + "ceceb7": "abc1df", + "726766": "5386b9", + "4a4860": "4f133f", + "8ce1b2": "8397c4", + "564a49": "2c4f8a", + "000000": "ffffff", + "4ca391": "6974ad", + "a571e6": "4c5372", + "774d9b": "2c2c46", + "97859b": "5582a4", + "afc6d8": "c23f4f", + "efeee1": "e2f3ff", + "869fad": "902a4b", + "918772": "6777aa", + "3a2b2f": "1e3072" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/945.json b/public/images/pokemon/variant/945.json new file mode 100644 index 00000000000..e22743030f9 --- /dev/null +++ b/public/images/pokemon/variant/945.json @@ -0,0 +1,53 @@ +{ + "1": { + "403f4f": "357747", + "1f2635": "1c193d", + "dcdcc3": "5ddcb2", + "282434": "14463f", + "ebe4e2": "ade273", + "a491a4": "499833", + "e6e2e1": "fffbf3", + "671544": "0f4e67", + "584698": "18153d", + "134175": "a74d2a", + "4f483f": "1b727b", + "323d4a": "2e2452", + "000000": "ffffff", + "8ac2a2": "1a355d", + "d73875": "29ad89", + "e0ebf1": "7ddfee", + "2481b0": "d09139", + "4b616b": "473869", + "38bdda": "ffe269", + "695575": "16613d", + "aca699": "2db3a4", + "8d2151": "157375", + "cedaaa": "2f5b7b" + }, + "2": { + "403f4f": "3b6b9e", + "1f2635": "3b091c", + "dcdcc3": "edf0f1", + "282434": "2d427e", + "ebe4e2": "c23f4f", + "a491a4": "902a4b", + "e6e2e1": "ebf4f9", + "671544": "223969", + "584698": "1f1e43", + "134175": "1c182f", + "4f483f": "5d7487", + "323d4a": "580f1d", + "000000": "ffffff", + "a599a8": "bf888f", + "8ac2a2": "8397c4", + "7c6a84": "965b6f", + "d73875": "68adca", + "2481b0": "2c2c46", + "4b616b": "8a2029", + "38bdda": "494e64", + "695575": "4f133f", + "aca699": "acbfc7", + "8d2151": "4676aa", + "cedaaa": "bad4e8" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/_masterlist.json b/public/images/pokemon/variant/_masterlist.json index a93fd220b1f..11f8e9cb7ec 100644 --- a/public/images/pokemon/variant/_masterlist.json +++ b/public/images/pokemon/variant/_masterlist.json @@ -1,11113 +1,2474 @@ { - "1": [ - 0, - 1, - 1 - ], - "2": [ - 0, - 2, - 1 - ], - "3-gigantamax": [ - 0, - 1, - 1 - ], - "3-mega": [ - 0, - 2, - 2 - ], - "3": [ - 0, - 1, - 1 - ], - "4": [ - 0, - 1, - 1 - ], - "5": [ - 0, - 1, - 1 - ], - "6-mega-x": [ - 0, - 1, - 2 - ], - "6-gigantamax": [ - 0, - 1, - 2 - ], - "6-mega-y": [ - 0, - 1, - 2 - ], - "6": [ - 0, - 2, - 2 - ], - "7": [ - 0, - 2, - 2 - ], - "8": [ - 0, - 2, - 2 - ], - "9-gigantamax": [ - 0, - 1, - 2 - ], - "9-mega": [ - 0, - 2, - 2 - ], - "9": [ - 0, - 2, - 2 - ], - "19": [ - 0, - 1, - 1 - ], - "20": [ - 0, - 1, - 1 - ], - "23": [ - 0, - 1, - 1 - ], - "24": [ - 0, - 1, - 1 - ], - "29": [ - 0, - 1, - 1 - ], - "30": [ - 0, - 1, - 1 - ], - "31": [ - 1, - 1, - 1 - ], - "35": [ - 0, - 1, - 2 - ], - "36": [ - 0, - 1, - 1 - ], - "37": [ - 0, - 1, - 1 - ], - "38": [ - 0, - 1, - 1 - ], - "41": [ - 0, - 1, - 1 - ], - "42": [ - 0, - 1, - 1 - ], - "43": [ - 0, - 1, - 1 - ], - "44": [ - 0, - 1, - 1 - ], - "45": [ - 0, - 1, - 1 - ], - "46": [ - 1, - 1, - 1 - ], - "47": [ - 1, - 1, - 1 - ], - "50": [ - 0, - 1, - 1 - ], - "51": [ - 0, - 1, - 1 - ], - "52-gigantamax": [ - 1, - 1, - 1 - ], - "52": [ - 1, - 1, - 1 - ], - "53": [ - 1, - 1, - 1 - ], - "56": [ - 1, - 2, - 2 - ], - "57": [ - 2, - 2, - 2 - ], - "69": [ - 0, - 2, - 2 - ], - "70": [ - 0, - 1, - 1 - ], - "71": [ - 0, - 1, - 1 - ], - "77": [ - 0, - 1, - 1 - ], - "78": [ - 0, - 1, - 1 - ], - "79": [ - 1, - 1, - 1 - ], - "80": [ - 0, - 1, - 1 - ], - "80-mega": [ - 0, - 1, - 1 - ], - "81": [ - 0, - 1, - 1 - ], - "82": [ - 0, - 1, - 1 - ], - "83": [ - 0, - 2, - 2 - ], - "84": [ - 1, - 1, - 1 - ], - "85": [ - 1, - 1, - 1 - ], - "86": [ - 1, - 1, - 1 - ], - "87": [ - 1, - 1, - 1 - ], - "92": [ - 2, - 2, - 2 - ], - "93": [ - 1, - 1, - 1 - ], - "94-gigantamax": [ - 1, - 2, - 2 - ], - "94-mega": [ - 2, - 2, - 2 - ], - "94": [ - 1, - 1, - 1 - ], - "98": [ - 0, - 1, - 1 - ], - "99": [ - 0, - 1, - 1 - ], - "99-gigantamax": [ - 0, - 1, - 1 - ], - "100": [ - 0, - 1, - 1 - ], - "101": [ - 0, - 1, - 1 - ], - "111": [ - 0, - 1, - 1 - ], - "112": [ - 0, - 1, - 1 - ], - "113": [ - 2, - 2, - 2 - ], - "114": [ - 0, - 1, - 1 - ], - "116": [ - 0, - 1, - 1 - ], - "117": [ - 0, - 1, - 1 - ], - "118": [ - 1, - 1, - 1 - ], - "119": [ - 1, - 1, - 1 - ], - "120": [ - 0, - 1, - 1 - ], - "121": [ - 0, - 1, - 1 - ], - "123": [ - 1, - 1, - 1 - ], - "125": [ - 1, - 1, - 2 - ], - "126": [ - 0, - 2, - 1 - ], - "127-mega": [ - 0, - 1, - 1 - ], - "127": [ - 0, - 1, - 1 - ], - "129": [ - 0, - 1, - 1 - ], - "130-mega": [ - 0, - 1, - 1 - ], - "130": [ - 0, - 1, - 1 - ], - "131-gigantamax": [ - 0, - 1, - 1 - ], - "131": [ - 0, - 1, - 1 - ], - "132": [ - 0, - 1, - 1 - ], - "133": [ - 0, - 1, - 1 - ], - "133-partner": [ - 0, - 1, - 1 - ], - "134": [ - 0, - 1, - 1 - ], - "135": [ - 1, - 1, - 1 - ], - "136": [ - 1, - 1, - 1 - ], - "137": [ - 0, - 1, - 1 - ], - "138": [ - 0, - 1, - 1 - ], - "139": [ - 0, - 1, - 2 - ], - "140": [ - 0, - 1, - 1 - ], - "141": [ - 0, - 2, - 2 - ], - "142-mega": [ - 0, - 1, - 1 - ], - "142": [ - 0, - 1, - 1 - ], - "144": [ - 1, - 2, - 2 - ], - "145": [ - 1, - 1, - 1 - ], - "146": [ - 1, - 1, - 1 - ], - "147": [ - 0, - 1, - 1 - ], - "148": [ - 0, - 1, - 1 - ], - "149": [ - 0, - 1, - 1 - ], - "150-mega-x": [ - 0, - 1, - 1 - ], - "150-mega-y": [ - 0, - 1, - 1 - ], - "150": [ - 0, - 1, - 1 - ], - "151": [ - 0, - 1, - 1 - ], - "161": [ - 0, - 1, - 2 - ], - "162": [ - 0, - 1, - 1 - ], - "163": [ - 0, - 1, - 1 - ], - "164": [ - 0, - 2, - 2 - ], - "169": [ - 0, - 1, - 1 - ], - "173": [ - 0, - 1, - 2 - ], - "175": [ - 1, - 1, - 1 - ], - "176": [ - 1, - 1, - 1 - ], - "177": [ - 0, - 1, - 1 - ], - "178": [ - 0, - 2, - 2 - ], - "179": [ - 0, - 1, - 1 - ], - "180": [ - 0, - 2, - 2 - ], - "181-mega": [ - 0, - 1, - 2 - ], - "181": [ - 0, - 1, - 1 - ], - "182": [ - 0, - 1, - 1 - ], - "183": [ - 0, - 1, - 2 - ], - "184": [ - 0, - 2, - 2 - ], - "185": [ - 0, - 1, - 1 - ], - "190": [ - 0, - 1, - 1 - ], - "193": [ - 0, - 1, - 1 - ], - "196": [ - 1, - 1, - 1 - ], - "197": [ - 0, - 1, - 1 - ], - "199": [ - 2, - 1, - 1 - ], - "200": [ - 1, - 1, - 1 - ], - "201-m": [ - 0, - 1, - 1 - ], - "201-question": [ - 0, - 1, - 1 - ], - "201-j": [ - 0, - 1, - 1 - ], - "201-l": [ - 0, - 1, - 1 - ], - "201-h": [ - 0, - 1, - 1 - ], - "201-x": [ - 0, - 1, - 1 - ], - "201-exclamation": [ - 0, - 1, - 1 - ], - "201-q": [ - 0, - 1, - 1 - ], - "201-s": [ - 0, - 1, - 1 - ], - "201-c": [ - 0, - 1, - 1 - ], - "201-u": [ - 0, - 1, - 1 - ], - "201-t": [ - 0, - 1, - 1 - ], - "201-z": [ - 0, - 1, - 1 - ], - "201-d": [ - 0, - 1, - 1 - ], - "201-b": [ - 0, - 1, - 1 - ], - "201-g": [ - 0, - 1, - 1 - ], - "201-k": [ - 0, - 1, - 1 - ], - "201-i": [ - 0, - 1, - 1 - ], - "201-p": [ - 0, - 1, - 1 - ], - "201-e": [ - 0, - 1, - 1 - ], - "201-y": [ - 0, - 1, - 1 - ], - "201-r": [ - 0, - 1, - 1 - ], - "201-f": [ - 0, - 1, - 1 - ], - "201-n": [ - 0, - 1, - 1 - ], - "201-v": [ - 0, - 1, - 1 - ], - "201-a": [ - 0, - 1, - 1 - ], - "201-w": [ - 0, - 1, - 1 - ], - "201-o": [ - 0, - 1, - 1 - ], - "203": [ - 0, - 1, - 1 - ], - "206": [ - 0, - 1, - 1 - ], - "207": [ - 0, - 1, - 1 - ], - "212-mega": [ - 1, - 1, - 1 - ], - "212": [ - 1, - 1, - 1 - ], - "213": [ - 0, - 1, - 1 - ], - "215": [ - 0, - 1, - 1 - ], - "216": [ - 1, - 1, - 1 - ], - "217": [ - 1, - 1, - 1 - ], - "222": [ - 0, - 1, - 1 - ], - "226": [ - 0, - 2, - 2 - ], - "227": [ - 0, - 1, - 1 - ], - "228": [ - 0, - 1, - 1 - ], - "229": [ - 0, - 1, - 1 - ], - "229-mega": [ - 0, - 1, - 1 - ], - "230": [ - 0, - 1, - 1 - ], - "231": [ - 0, - 1, - 1 - ], - "232": [ - 0, - 1, - 1 - ], - "233": [ - 0, - 1, - 1 - ], - "235": [ - 0, - 1, - 1 - ], - "239": [ - 1, - 1, - 2 - ], - "240": [ - 0, - 1, - 1 - ], - "242": [ - 2, - 2, - 2 - ], - "243": [ - 0, - 1, - 1 - ], - "244": [ - 0, - 2, - 2 - ], - "245": [ - 0, - 1, - 1 - ], - "246": [ - 0, - 1, - 1 - ], - "247": [ - 0, - 1, - 1 - ], - "248": [ - 0, - 1, - 1 - ], - "248-mega": [ - 0, - 2, - 1 - ], - "249": [ - 0, - 2, - 2 - ], - "250": [ - 0, - 2, - 2 - ], - "251": [ - 0, - 1, - 1 - ], - "255": [ - 0, - 1, - 1 - ], - "256": [ - 0, - 1, - 1 - ], - "257": [ - 0, - 1, - 2 - ], - "257-mega": [ - 0, - 1, - 1 - ], - "261": [ - 0, - 1, - 1 - ], - "262": [ - 0, - 1, - 1 - ], - "263": [ - 0, - 1, - 1 - ], - "264": [ - 0, - 1, - 1 - ], - "278": [ - 1, - 1, - 1 - ], - "279": [ - 1, - 1, - 1 - ], - "280": [ - 0, - 1, - 1 - ], - "281": [ - 0, - 1, - 1 - ], - "282-mega": [ - 0, - 2, - 2 - ], - "282": [ - 0, - 1, - 1 - ], - "285": [ - 0, - 1, - 1 - ], - "286": [ - 0, - 1, - 1 - ], - "290": [ - 1, - 1, - 1 - ], - "291": [ - 2, - 2, - 2 - ], - "292": [ - 2, - 1, - 2 - ], - "298": [ - 0, - 2, - 2 - ], - "300": [ - 1, - 1, - 1 - ], - "301": [ - 1, - 1, - 1 - ], - "302": [ - 0, - 1, - 1 - ], - "302-mega": [ - 0, - 1, - 1 - ], - "303-mega": [ - 1, - 1, - 1 - ], - "303": [ - 0, - 1, - 1 - ], - "304": [ - 1, - 1, - 1 - ], - "305": [ - 1, - 1, - 1 - ], - "306-mega": [ - 1, - 1, - 1 - ], - "306": [ - 1, - 1, - 1 - ], - "307": [ - 0, - 1, - 1 - ], - "308-mega": [ - 0, - 1, - 1 - ], - "308": [ - 0, - 2, - 1 - ], - "309": [ - 0, - 1, - 1 - ], - "310-mega": [ - 0, - 1, - 1 - ], - "310": [ - 0, - 1, - 1 - ], - "311": [ - 1, - 1, - 1 - ], - "312": [ - 0, - 1, - 1 - ], - "315": [ - 0, - 1, - 1 - ], - "320": [ - 0, - 1, - 1 - ], - "321": [ - 0, - 1, - 1 - ], - "327": [ - 0, - 1, - 1 - ], - "328": [ - 0, - 1, - 1 - ], - "329": [ - 0, - 1, - 2 - ], - "330": [ - 0, - 1, - 1 - ], - "333": [ - 0, - 1, - 1 - ], - "334-mega": [ - 0, - 2, - 1 - ], - "334": [ - 0, - 2, - 2 - ], - "335": [ - 0, - 2, - 2 - ], - "336": [ - 0, - 1, - 1 - ], - "337": [ - 0, - 1, - 1 - ], - "338": [ - 0, - 1, - 1 - ], - "339": [ - 0, - 1, - 1 - ], - "340": [ - 0, - 1, - 2 - ], - "341": [ - 0, - 2, - 2 - ], - "342": [ - 0, - 2, - 2 - ], - "351-rainy": [ - 1, - 2, - 2 - ], - "351-snowy": [ - 1, - 1, - 1 - ], - "351-sunny": [ - 1, - 2, - 2 - ], - "351": [ - 0, - 2, - 2 - ], - "352": [ - 1, - 1, - 1 - ], - "353": [ - 0, - 1, - 1 - ], - "354": [ - 0, - 1, - 1 - ], - "354-mega": [ - 0, - 1, - 1 - ], - "357": [ - 0, - 1, - 1 - ], - "358": [ - 2, - 1, - 1 - ], - "361": [ - 0, - 1, - 1 - ], - "362": [ - 0, - 2, - 2 - ], - "362-mega": [ - 0, - 1, - 1 - ], - "369": [ - 0, - 1, - 1 - ], - "370": [ - 0, - 1, - 1 - ], - "371": [ - 0, - 1, - 1 - ], - "372": [ - 0, - 1, - 1 - ], - "373-mega": [ - 0, - 2, - 2 - ], - "373": [ - 0, - 1, - 1 - ], - "374": [ - 0, - 1, - 1 - ], - "375": [ - 0, - 1, - 1 - ], - "376-mega": [ - 0, - 1, - 1 - ], - "376": [ - 0, - 1, - 1 - ], - "380-mega": [ - 0, - 1, - 1 - ], - "380": [ - 0, - 1, - 1 - ], - "381-mega": [ - 0, - 1, - 1 - ], - "381": [ - 0, - 1, - 1 - ], - "382-primal": [ - 0, - 1, - 1 - ], - "382": [ - 0, - 1, - 1 - ], - "383-primal": [ - 0, - 1, - 1 - ], - "383": [ - 0, - 1, - 1 - ], - "384-mega": [ - 0, - 2, - 1 - ], - "384": [ - 0, - 1, - 1 - ], - "385": [ - 1, - 1, - 1 - ], - "387": [ - 0, - 1, - 1 - ], - "388": [ - 0, - 1, - 1 - ], - "389": [ - 0, - 1, - 1 - ], - "393": [ - 0, - 1, - 1 - ], - "394": [ - 0, - 1, - 1 - ], - "395": [ - 0, - 1, - 1 - ], - "399": [ - 0, - 1, - 1 - ], - "400": [ - 0, - 1, - 1 - ], - "401": [ - 0, - 1, - 1 - ], - "402": [ - 0, - 1, - 1 - ], - "406": [ - 0, - 1, - 1 - ], - "407": [ - 0, - 1, - 1 - ], - "412-sandy": [ - 2, - 2, - 2 - ], - "412-plant": [ - 1, - 1, - 1 - ], - "412-trash": [ - 1, - 1, - 1 - ], - "413-plant": [ - 2, - 2, - 2 - ], - "413-trash": [ - 1, - 1, - 1 - ], - "413-sandy": [ - 1, - 1, - 1 - ], - "414": [ - 0, - 1, - 1 - ], - "418": [ - 0, - 1, - 1 - ], - "419": [ - 0, - 1, - 1 - ], - "422-west": [ - 1, - 1, - 1 - ], - "422-east": [ - 1, - 1, - 1 - ], - "423-west": [ - 1, - 1, - 1 - ], - "423-east": [ - 1, - 1, - 1 - ], - "424": [ - 0, - 1, - 1 - ], - "425": [ - 0, - 1, - 1 - ], - "426": [ - 0, - 1, - 1 - ], - "427": [ - 0, - 1, - 1 - ], - "428-mega": [ - 0, - 1, - 1 - ], - "428": [ - 0, - 1, - 1 - ], - "429": [ - 1, - 1, - 1 - ], - "433": [ - 1, - 1, - 1 - ], - "436": [ - 0, - 1, - 1 - ], - "437": [ - 0, - 1, - 1 - ], - "438": [ - 0, - 1, - 1 - ], - "440": [ - 1, - 1, - 2 - ], - "441": [ - 0, - 1, - 1 - ], - "442": [ - 0, - 1, - 1 - ], - "443": [ - 1, - 1, - 1 - ], - "444": [ - 1, - 1, - 1 - ], - "445-mega": [ - 1, - 1, - 1 - ], - "445": [ - 1, - 1, - 1 - ], - "447": [ - 1, - 1, - 1 - ], - "448-mega": [ - 1, - 1, - 1 - ], - "448": [ - 1, - 1, - 1 - ], - "453": [ - 0, - 1, - 1 - ], - "454": [ - 0, - 1, - 1 - ], - "456": [ - 0, - 1, - 1 - ], - "457": [ - 0, - 1, - 1 - ], - "458": [ - 0, - 1, - 1 - ], - "461": [ - 0, - 1, - 1 - ], - "462": [ - 0, - 1, - 1 - ], - "464": [ - 0, - 1, - 1 - ], - "465": [ - 0, - 1, - 1 - ], - "466": [ - 1, - 1, - 2 - ], - "467": [ - 0, - 1, - 1 - ], - "468": [ - 1, - 1, - 1 - ], - "469": [ - 0, - 1, - 1 - ], - "470": [ - 1, - 1, - 1 - ], - "471": [ - 1, - 2, - 2 - ], - "472": [ - 0, - 1, - 1 - ], - "474": [ - 0, - 1, - 1 - ], - "475-mega": [ - 0, - 2, - 2 - ], - "475": [ - 0, - 1, - 1 - ], - "478": [ - 0, - 2, - 1 - ], - "479-heat": [ - 0, - 1, - 1 - ], - "479-wash": [ - 0, - 1, - 1 - ], - "479-mow": [ - 0, - 1, - 1 - ], - "479-frost": [ - 0, - 1, - 1 - ], - "479": [ - 0, - 1, - 1 - ], - "479-fan": [ - 0, - 1, - 1 - ], - "480": [ - 1, - 1, - 1 - ], - "481": [ - 1, - 1, - 1 - ], - "482": [ - 1, - 1, - 1 - ], - "485": [ - 0, - 1, - 1 - ], - "487-altered": [ - 0, - 1, - 1 - ], - "487-origin": [ - 0, - 1, - 1 - ], - "488": [ - 0, - 1, - 1 - ], - "489": [ - 1, - 1, - 1 - ], - "490": [ - 1, - 1, - 1 - ], - "491": [ - 0, - 1, - 1 - ], - "492-land": [ - 0, - 2, - 1 - ], - "492-sky": [ - 0, - 1, - 1 - ], - "494": [ - 0, - 1, - 1 - ], - "495": [ - 0, - 1, - 1 - ], - "496": [ - 0, - 1, - 1 - ], - "497": [ - 0, - 1, - 1 - ], - "517": [ - 0, - 1, - 1 - ], - "518": [ - 0, - 1, - 1 - ], - "524": [ - 0, - 1, - 1 - ], - "525": [ - 0, - 1, - 1 - ], - "526": [ - 0, - 2, - 2 - ], - "529": [ - 0, - 2, - 2 - ], - "530": [ - 0, - 2, - 2 - ], - "531": [ - 0, - 1, - 1 - ], - "531-mega": [ - 0, - 1, - 1 - ], - "532": [ - 0, - 1, - 1 - ], - "533": [ - 0, - 1, - 1 - ], - "534": [ - 0, - 1, - 1 - ], - "538": [ - 0, - 1, - 1 - ], - "539": [ - 0, - 2, - 2 - ], - "540": [ - 0, - 1, - 1 - ], - "541": [ - 0, - 1, - 1 - ], - "542": [ - 0, - 1, - 1 - ], - "543": [ - 0, - 1, - 2 - ], - "544": [ - 0, - 1, - 2 - ], - "545": [ - 0, - 1, - 1 - ], - "546": [ - 0, - 1, - 1 - ], - "547": [ - 0, - 1, - 1 - ], - "548": [ - 1, - 1, - 1 - ], - "549": [ - 0, - 1, - 2 - ], - "551": [ - 0, - 1, - 1 - ], - "552": [ - 0, - 1, - 1 - ], - "553": [ - 0, - 1, - 1 - ], - "556": [ - 0, - 1, - 1 - ], - "559": [ - 1, - 1, - 1 - ], - "560": [ - 1, - 1, - 1 - ], - "562": [ - 0, - 1, - 1 - ], - "563": [ - 0, - 1, - 1 - ], - "568": [ - 0, - 2, - 2 - ], - "569-gigantamax": [ - 0, - 1, - 1 - ], - "569": [ - 0, - 1, - 1 - ], - "570": [ - 0, - 1, - 1 - ], - "571": [ - 0, - 1, - 1 - ], - "572": [ - 0, - 1, - 1 - ], - "577": [ - 1, - 1, - 1 - ], - "578": [ - 1, - 1, - 1 - ], - "579": [ - 1, - 1, - 1 - ], - "585-autumn": [ - 2, - 0, - 0 - ], - "585-spring": [ - 2, - 0, - 0 - ], - "585-summer": [ - 2, - 0, - 0 - ], - "585-winter": [ - 2, - 0, - 0 - ], - "586-autumn": [ - 1, - 0, - 0 - ], - "586-spring": [ - 1, - 0, - 0 - ], - "586-summer": [ - 1, - 0, - 0 - ], - "586-winter": [ - 1, - 0, - 0 - ], - "592": [ - 0, - 1, - 2 - ], - "593": [ - 0, - 1, - 1 - ], - "594": [ - 0, - 1, - 2 - ], - "595": [ - 0, - 1, - 1 - ], - "596": [ - 0, - 1, - 1 - ], - "602": [ - 0, - 1, - 1 - ], - "603": [ - 0, - 1, - 1 - ], - "604": [ - 0, - 1, - 1 - ], - "605": [ - 1, - 1, - 1 - ], - "606": [ - 1, - 1, - 1 - ], - "607": [ - 0, - 1, - 1 - ], - "608": [ - 0, - 1, - 1 - ], - "609": [ - 0, - 1, - 1 - ], - "610": [ - 0, - 1, - 1 - ], - "611": [ - 0, - 1, - 1 - ], - "612": [ - 0, - 1, - 2 - ], - "618": [ - 0, - 1, - 1 - ], - "619": [ - 0, - 1, - 1 - ], - "620": [ - 0, - 1, - 1 - ], - "622": [ - 0, - 1, - 1 - ], - "623": [ - 0, - 1, - 1 - ], - "631": [ - 0, - 2, - 2 - ], - "632": [ - 0, - 1, - 1 - ], - "633": [ - 0, - 1, - 1 - ], - "634": [ - 0, - 1, - 1 - ], - "635": [ - 0, - 1, - 1 - ], - "636": [ - 0, - 1, - 1 - ], - "637": [ - 0, - 1, - 1 - ], - "640": [ - 0, - 1, - 1 - ], - "647-resolute": [ - 0, - 1, - 1 - ], - "647-ordinary": [ - 0, - 1, - 1 - ], - "648-aria": [ - 0, - 1, - 1 - ], - "648-pirouette": [ - 0, - 1, - 1 - ], - "649-burn": [ - 0, - 1, - 1 - ], - "649-chill": [ - 0, - 1, - 1 - ], - "649-douse": [ - 0, - 1, - 1 - ], - "649-shock": [ - 0, - 1, - 1 - ], - "649": [ - 0, - 1, - 1 - ], - "653": [ - 0, - 1, - 1 - ], - "654": [ - 0, - 1, - 1 - ], - "655": [ - 0, - 1, - 1 - ], - "664": [ - 0, - 1, - 1 - ], - "665": [ - 0, - 1, - 1 - ], - "666-archipelago": [ - 0, - 1, - 1 - ], - "666-continental": [ - 0, - 1, - 2 - ], - "666-elegant": [ - 0, - 1, - 1 - ], - "666-fancy": [ - 0, - 2, - 2 - ], - "666-garden": [ - 0, - 1, - 1 - ], - "666-high-plains": [ - 0, - 1, - 1 - ], - "666-icy-snow": [ - 0, - 1, - 1 - ], - "666-jungle": [ - 0, - 1, - 1 - ], - "666-marine": [ - 0, - 1, - 1 - ], - "666-meadow": [ - 0, - 1, - 1 - ], - "666-modern": [ - 0, - 1, - 1 - ], - "666-monsoon": [ - 0, - 1, - 1 - ], - "666-ocean": [ - 0, - 1, - 1 - ], - "666-poke-ball": [ - 0, - 1, - 2 - ], - "666-polar": [ - 0, - 1, - 1 - ], - "666-river": [ - 0, - 2, - 1 - ], - "666-sandstorm": [ - 0, - 1, - 1 - ], - "666-savanna": [ - 0, - 1, - 1 - ], - "666-sun": [ - 0, - 1, - 1 - ], - "666-tundra": [ - 0, - 1, - 1 - ], - "669-red": [ - 0, - 2, - 1 - ], - "669-blue": [ - 0, - 2, - 2 - ], - "669-white": [ - 0, - 1, - 1 - ], - "669-yellow": [ - 0, - 2, - 1 - ], - "669-orange": [ - 0, - 2, - 1 - ], - "670-white": [ - 0, - 2, - 2 - ], - "670-blue": [ - 0, - 2, - 2 - ], - "670-orange": [ - 0, - 2, - 2 - ], - "670-red": [ - 0, - 2, - 2 - ], - "670-yellow": [ - 0, - 2, - 2 - ], - "671-red": [ - 0, - 1, - 2 - ], - "671-blue": [ - 0, - 1, - 2 - ], - "671-yellow": [ - 0, - 1, - 2 - ], - "671-white": [ - 0, - 1, - 2 - ], - "671-orange": [ - 0, - 1, - 1 - ], - "672": [ - 0, - 1, - 2 - ], - "673": [ - 0, - 1, - 1 - ], - "677": [ - 0, - 1, - 1 - ], - "678-female": [ - 0, - 1, - 1 - ], - "678": [ - 0, - 1, - 1 - ], - "690": [ - 0, - 1, - 1 - ], - "691": [ - 0, - 1, - 1 - ], - "696": [ - 0, - 1, - 1 - ], - "697": [ - 0, - 1, - 1 - ], - "698": [ - 0, - 1, - 1 - ], - "699": [ - 0, - 1, - 1 - ], - "700": [ - 0, - 1, - 1 - ], - "702": [ - 0, - 1, - 1 - ], - "703": [ - 0, - 1, - 1 - ], - "704": [ - 0, - 1, - 1 - ], - "705": [ - 0, - 1, - 1 - ], - "706": [ - 0, - 1, - 1 - ], - "708": [ - 0, - 1, - 1 - ], - "709": [ - 0, - 1, - 1 - ], - "710": [ - 0, - 1, - 1 - ], - "711": [ - 1, - 1, - 1 - ], - "712": [ - 0, - 1, - 1 - ], - "713": [ - 0, - 1, - 1 - ], - "714": [ - 0, - 1, - 1 - ], - "715": [ - 0, - 2, - 2 - ], - "716-active": [ - 0, - 1, - 1 - ], - "716-neutral": [ - 0, - 1, - 1 - ], - "717": [ - 0, - 1, - 1 - ], - "720-unbound": [ - 1, - 1, - 1 - ], - "720": [ - 1, - 1, - 1 - ], - "728": [ - 0, - 1, - 1 - ], - "729": [ - 0, - 1, - 1 - ], - "730": [ - 0, - 1, - 1 - ], - "734": [ - 0, - 1, - 1 - ], - "735": [ - 0, - 1, - 1 - ], - "742": [ - 0, - 2, - 2 - ], - "743": [ - 0, - 2, - 2 - ], - "747": [ - 0, - 1, - 1 - ], - "748": [ - 0, - 1, - 1 - ], - "751": [ - 0, - 1, - 1 - ], - "752": [ - 0, - 1, - 1 - ], - "753": [ - 0, - 1, - 1 - ], - "754": [ - 0, - 1, - 1 - ], - "755": [ - 0, - 1, - 1 - ], - "756": [ - 0, - 1, - 2 - ], - "761": [ - 0, - 1, - 1 - ], - "762": [ - 0, - 1, - 1 - ], - "763": [ - 0, - 1, - 1 - ], - "767": [ - 0, - 1, - 1 - ], - "768": [ - 0, - 1, - 1 - ], - "771": [ - 0, - 1, - 1 - ], - "772": [ - 0, - 1, - 1 - ], - "773-fighting": [ - 0, - 1, - 1 - ], - "773-psychic": [ - 0, - 1, - 1 - ], - "773-poison": [ - 0, - 1, - 1 - ], - "773-ground": [ - 0, - 1, - 1 - ], - "773-ghost": [ - 0, - 1, - 1 - ], - "773-steel": [ - 0, - 1, - 1 - ], - "773-rock": [ - 0, - 1, - 1 - ], - "773-grass": [ - 0, - 1, - 1 - ], - "773-dragon": [ - 0, - 1, - 1 - ], - "773-bug": [ - 0, - 1, - 1 - ], - "773-ice": [ - 0, - 1, - 1 - ], - "773-dark": [ - 0, - 1, - 1 - ], - "773": [ - 0, - 1, - 1 - ], - "773-fairy": [ - 0, - 1, - 1 - ], - "773-water": [ - 0, - 1, - 1 - ], - "773-electric": [ - 0, - 1, - 1 - ], - "773-flying": [ - 0, - 1, - 1 - ], - "773-fire": [ - 0, - 1, - 1 - ], - "776": [ - 0, - 1, - 1 - ], - "777": [ - 0, - 1, - 1 - ], - "778-busted": [ - 0, - 1, - 1 - ], - "778-disguised": [ - 0, - 1, - 1 - ], - "779": [ - 0, - 1, - 1 - ], - "789": [ - 1, - 1, - 1 - ], - "790": [ - 0, - 1, - 1 - ], - "791-radiant-sun": [ - 0, - 1, - 1 - ], - "791": [ - 2, - 1, - 1 - ], - "792-full-moon": [ - 0, - 1, - 1 - ], - "792": [ - 0, - 1, - 1 - ], - "793": [ - 0, - 1, - 1 - ], - "797": [ - 0, - 1, - 1 - ], - "798": [ - 0, - 1, - 1 - ], - "800-dawn-wings": [ - 0, - 1, - 1 - ], - "800-dusk-mane": [ - 0, - 1, - 1 - ], - "800-ultra": [ - 0, - 1, - 1 - ], - "800": [ - 0, - 1, - 1 - ], - "802": [ - 1, - 1, - 1 - ], - "803": [ - 0, - 1, - 1 - ], - "804": [ - 0, - 1, - 1 - ], - "808": [ - 0, - 1, - 1 - ], - "809-gigantamax": [ - 0, - 1, - 1 - ], - "809": [ - 0, - 1, - 1 - ], - "816": [ - 0, - 1, - 1 - ], - "817": [ - 0, - 1, - 1 - ], - "818-gigantamax": [ - 1, - 1, - 1 - ], - "818": [ - 0, - 1, - 1 - ], - "821": [ - 0, - 1, - 1 - ], - "822": [ - 0, - 1, - 1 - ], - "823-gigantamax": [ - 0, - 2, - 2 - ], - "823": [ - 0, - 1, - 1 - ], - "829": [ - 0, - 1, - 1 - ], - "830": [ - 0, - 1, - 1 - ], - "835": [ - 0, - 1, - 1 - ], - "836": [ - 0, - 2, - 2 - ], - "850": [ - 0, - 1, - 1 - ], - "851-gigantamax": [ - 0, - 1, - 1 - ], - "851": [ - 0, - 1, - 1 - ], - "854": [ - 0, - 1, - 1 - ], - "855": [ - 0, - 1, - 1 - ], - "856": [ - 0, - 1, - 1 - ], - "857": [ - 0, - 2, - 2 - ], - "858-gigantamax": [ - 0, - 1, - 1 - ], - "858": [ - 0, - 1, - 1 - ], - "859": [ - 0, - 2, - 2 - ], - "860": [ - 0, - 1, - 1 - ], - "861-gigantamax": [ - 0, - 1, - 1 - ], - "861": [ - 0, - 1, - 1 - ], - "862": [ - 0, - 1, - 1 - ], - "863": [ - 0, - 1, - 1 - ], - "864": [ - 0, - 1, - 1 - ], - "867": [ - 0, - 1, - 1 - ], - "872": [ - 1, - 1, - 1 - ], - "873": [ - 1, - 1, - 1 - ], - "876-female": [ - 0, - 1, - 1 - ], - "876": [ - 0, - 1, - 1 - ], - "877-hangry": [ - 1, - 1, - 1 - ], - "877": [ - 1, - 1, - 1 - ], - "880": [ - 0, - 1, - 1 - ], - "881": [ - 0, - 1, - 1 - ], - "882": [ - 0, - 1, - 1 - ], - "883": [ - 0, - 1, - 1 - ], - "884-gigantamax": [ - 0, - 1, - 1 - ], - "884": [ - 0, - 1, - 1 - ], - "885": [ - 1, - 1, - 1 - ], - "886": [ - 1, - 1, - 1 - ], - "887": [ - 2, - 1, - 1 - ], - "888": [ - 0, - 1, - 1 - ], - "888-crowned": [ - 0, - 1, - 1 - ], - "889": [ - 0, - 1, - 1 - ], - "889-crowned": [ - 0, - 1, - 1 - ], - "890-eternamax": [ - 0, - 1, - 1 - ], - "890": [ - 0, - 1, - 1 - ], - "891": [ - 1, - 1, - 1 - ], - "892-gigantamax-rapid": [ - 1, - 2, - 2 - ], - "892-rapid-strike": [ - 1, - 1, - 1 - ], - "892": [ - 1, - 1, - 1 - ], - "892-gigantamax-single": [ - 1, - 2, - 2 - ], - "896": [ - 1, - 1, - 1 - ], - "897": [ - 2, - 1, - 1 - ], - "898": [ - 1, - 1, - 1 - ], - "898-ice": [ - 1, - 1, - 1 - ], - "898-shadow": [ - 1, - 1, - 1 - ], - "900": [ - 0, - 1, - 1 - ], - "901": [ - 0, - 1, - 2 - ], - "903": [ - 0, - 1, - 1 - ], - "909": [ - 0, - 2, - 2 - ], - "910": [ - 0, - 2, - 2 - ], - "911": [ - 0, - 1, - 1 - ], - "912": [ - 0, - 1, - 1 - ], - "913": [ - 0, - 2, - 2 - ], - "914": [ - 0, - 2, - 1 - ], - "919": [ - 1, - 1, - 1 - ], - "920": [ - 2, - 2, - 2 - ], - "924": [ - 1, - 1, - 1 - ], - "925-four": [ - 1, - 1, - 1 - ], - "925-three": [ - 1, - 1, - 1 - ], - "932": [ - 0, - 1, - 2 - ], - "933": [ - 0, - 1, - 1 - ], - "934": [ - 0, - 1, - 1 - ], - "935": [ - 2, - 2, - 2 - ], - "936": [ - 2, - 2, - 2 - ], - "937": [ - 2, - 2, - 2 - ], - "940": [ - 0, - 1, - 1 - ], - "941": [ - 0, - 1, - 1 - ], - "948": [ - 0, - 1, - 1 - ], - "949": [ - 0, - 1, - 1 - ], - "951": [ - 0, - 1, - 1 - ], - "952": [ - 0, - 1, - 1 - ], - "953": [ - 0, - 1, - 1 - ], - "954": [ - 0, - 1, - 1 - ], - "957": [ - 1, - 2, - 2 - ], - "958": [ - 2, - 2, - 1 - ], - "959": [ - 2, - 2, - 2 - ], - "962": [ - 1, - 1, - 1 - ], - "967": [ - 0, - 1, - 1 - ], - "968": [ - 0, - 2, - 2 - ], - "969": [ - 0, - 1, - 1 - ], - "970": [ - 0, - 1, - 1 - ], - "973": [ - 2, - 2, - 2 - ], - "974": [ - 0, - 1, - 1 - ], - "975": [ - 0, - 2, - 2 - ], - "978-curly": [ - 0, - 2, - 2 - ], - "978-droopy": [ - 0, - 2, - 2 - ], - "978-stretchy": [ - 0, - 2, - 2 - ], - "979": [ - 2, - 2, - 2 - ], - "981": [ - 0, - 1, - 1 - ], - "982": [ - 0, - 1, - 1 - ], - "982-three-segment": [ - 0, - 1, - 1 - ], - "987": [ - 1, - 1, - 1 - ], - "988": [ - 0, - 1, - 2 - ], - "993": [ - 0, - 1, - 1 - ], - "994": [ - 0, - 1, - 1 - ], - "995": [ - 0, - 1, - 1 - ], - "996": [ - 0, - 1, - 1 - ], - "997": [ - 0, - 1, - 1 - ], - "998": [ - 0, - 1, - 1 - ], - "999": [ - 1, - 1, - 1 - ], - "1000": [ - 1, - 1, - 1 - ], - "1001": [ - 0, - 1, - 1 - ], - "1003": [ - 0, - 1, - 1 - ], - "1004": [ - 0, - 1, - 1 - ], - "1006": [ - 0, - 2, - 1 - ], - "1007-apex-build": [ - 0, - 2, - 2 - ], - "1008-ultimate-mode": [ - 1, - 1, - 1 - ], - "1010": [ - 0, - 1, - 1 - ], - "1018": [ - 0, - 1, - 1 - ], - "1022": [ - 0, - 1, - 1 - ], - "1023": [ - 0, - 1, - 1 - ], - "2027": [ - 0, - 1, - 1 - ], - "2028": [ - 0, - 1, - 1 - ], - "2052": [ - 0, - 1, - 1 - ], - "2053": [ - 0, - 1, - 1 - ], - "2670": [ - 0, - 1, - 1 - ], - "4052": [ - 0, - 1, - 1 - ], - "4077": [ - 0, - 1, - 1 - ], - "4078": [ - 0, - 1, - 1 - ], - "4079": [ - 0, - 1, - 1 - ], - "4080": [ - 2, - 1, - 1 - ], - "4144": [ - 0, - 1, - 1 - ], - "4145": [ - 0, - 1, - 1 - ], - "4146": [ - 0, - 1, - 1 - ], - "4199": [ - 2, - 1, - 1 - ], - "4222": [ - 0, - 1, - 1 - ], - "4263": [ - 0, - 1, - 1 - ], - "4264": [ - 0, - 1, - 1 - ], - "4562": [ - 0, - 1, - 1 - ], - "6100": [ - 0, - 1, - 1 - ], - "6101": [ - 0, - 1, - 1 - ], - "6215": [ - 0, - 1, - 1 - ], - "6549": [ - 0, - 1, - 1 - ], - "6570": [ - 0, - 1, - 1 - ], - "6571": [ - 0, - 1, - 1 - ], - "6705": [ - 0, - 1, - 1 - ], - "6706": [ - 0, - 2, - 2 - ], - "6713": [ - 0, - 1, - 1 - ], - "8901": [ - 1, - 1, - 1 - ], + "1": [0, 1, 1], + "2": [0, 2, 1], + "3-gigantamax": [0, 1, 1], + "3-mega": [0, 2, 2], + "3": [0, 1, 1], + "4": [0, 1, 1], + "5": [0, 1, 1], + "6-mega-x": [0, 1, 2], + "6-gigantamax": [0, 1, 2], + "6-mega-y": [0, 1, 2], + "6": [0, 2, 2], + "7": [0, 2, 2], + "8": [0, 2, 2], + "9-gigantamax": [0, 1, 2], + "9-mega": [0, 2, 2], + "9": [0, 2, 2], + "19": [0, 1, 1], + "20": [0, 1, 1], + "23": [0, 1, 1], + "24": [0, 1, 1], + "25": [0, 1, 1], + "25-beauty-cosplay": [0, 1, 1], + "25-cool-cosplay": [0, 1, 1], + "25-cosplay": [0, 1, 1], + "25-cute-cosplay": [0, 1, 1], + "25-gigantamax": [0, 1, 1], + "25-partner": [0, 1, 1], + "25-smart-cosplay": [0, 1, 1], + "25-tough-cosplay": [0, 1, 1], + "26": [0, 1, 1], + "29": [0, 1, 1], + "30": [0, 1, 1], + "31": [1, 1, 1], + "35": [0, 1, 2], + "36": [0, 1, 1], + "37": [0, 1, 1], + "38": [0, 1, 1], + "39": [0, 1, 1], + "40": [0, 1, 1], + "41": [0, 1, 1], + "42": [0, 1, 1], + "43": [0, 1, 1], + "44": [0, 1, 1], + "45": [0, 1, 1], + "46": [1, 1, 1], + "47": [1, 1, 1], + "50": [0, 1, 1], + "51": [0, 1, 1], + "52-gigantamax": [1, 1, 1], + "52": [1, 1, 1], + "53": [1, 1, 1], + "56": [1, 2, 2], + "57": [2, 2, 2], + "69": [0, 2, 2], + "70": [0, 1, 1], + "71": [0, 1, 1], + "77": [0, 1, 1], + "78": [0, 1, 1], + "79": [1, 1, 1], + "80": [0, 1, 1], + "80-mega": [0, 1, 1], + "81": [0, 1, 1], + "82": [0, 1, 1], + "83": [0, 2, 2], + "84": [1, 1, 1], + "85": [1, 1, 1], + "86": [1, 1, 1], + "87": [1, 1, 1], + "92": [2, 2, 2], + "93": [1, 1, 1], + "94-gigantamax": [1, 2, 2], + "94-mega": [2, 2, 2], + "94": [1, 1, 1], + "98": [0, 1, 1], + "99": [0, 1, 1], + "99-gigantamax": [0, 1, 1], + "100": [0, 1, 1], + "101": [0, 1, 1], + "102": [0, 1, 1], + "103": [0, 1, 1], + "111": [0, 1, 1], + "112": [0, 1, 1], + "113": [2, 2, 2], + "114": [0, 1, 1], + "116": [0, 1, 1], + "117": [0, 1, 1], + "118": [1, 1, 1], + "119": [1, 1, 1], + "120": [0, 1, 1], + "121": [0, 1, 1], + "123": [1, 1, 1], + "125": [1, 1, 2], + "126": [0, 2, 1], + "127-mega": [0, 1, 1], + "127": [0, 1, 1], + "128": [0, 1, 1], + "129": [0, 1, 1], + "130-mega": [0, 1, 1], + "130": [0, 1, 1], + "131-gigantamax": [0, 1, 1], + "131": [0, 1, 1], + "132": [0, 1, 1], + "133": [0, 1, 1], + "133-partner": [0, 1, 1], + "134": [0, 1, 1], + "135": [1, 1, 1], + "136": [1, 1, 1], + "137": [0, 1, 1], + "138": [0, 1, 1], + "139": [0, 1, 2], + "140": [0, 1, 1], + "141": [0, 2, 2], + "142-mega": [0, 1, 1], + "142": [0, 1, 1], + "144": [1, 2, 2], + "145": [1, 1, 1], + "146": [1, 1, 1], + "147": [0, 1, 1], + "148": [0, 1, 1], + "149": [0, 1, 1], + "150-mega-x": [0, 1, 1], + "150-mega-y": [0, 1, 1], + "150": [0, 1, 1], + "151": [0, 1, 1], + "152": [0, 1, 1], + "153": [0, 1, 1], + "154": [0, 1, 1], + "158": [0, 1, 1], + "159": [0, 1, 1], + "160": [0, 1, 1], + "161": [0, 1, 2], + "162": [0, 1, 1], + "163": [0, 1, 1], + "164": [0, 2, 2], + "167": [0, 1, 1], + "168": [0, 1, 1], + "169": [0, 1, 1], + "170": [0, 1, 1], + "171": [0, 1, 1], + "172": [0, 1, 1], + "172-spiky": [0, 1, 1], + "173": [0, 1, 2], + "174": [0, 1, 1], + "175": [1, 1, 1], + "176": [1, 1, 1], + "177": [0, 1, 1], + "178": [0, 2, 2], + "179": [0, 1, 1], + "180": [0, 2, 2], + "181-mega": [0, 1, 2], + "181": [0, 1, 1], + "182": [0, 1, 1], + "183": [0, 1, 2], + "184": [0, 2, 2], + "185": [0, 1, 1], + "190": [0, 1, 1], + "193": [0, 1, 1], + "194": [0, 1, 1], + "195": [0, 1, 1], + "196": [1, 1, 1], + "197": [0, 1, 1], + "198": [0, 1, 1], + "199": [2, 1, 1], + "200": [1, 1, 1], + "201-m": [0, 1, 1], + "201-question": [0, 1, 1], + "201-j": [0, 1, 1], + "201-l": [0, 1, 1], + "201-h": [0, 1, 1], + "201-x": [0, 1, 1], + "201-exclamation": [0, 1, 1], + "201-q": [0, 1, 1], + "201-s": [0, 1, 1], + "201-c": [0, 1, 1], + "201-u": [0, 1, 1], + "201-t": [0, 1, 1], + "201-z": [0, 1, 1], + "201-d": [0, 1, 1], + "201-b": [0, 1, 1], + "201-g": [0, 1, 1], + "201-k": [0, 1, 1], + "201-i": [0, 1, 1], + "201-p": [0, 1, 1], + "201-e": [0, 1, 1], + "201-y": [0, 1, 1], + "201-r": [0, 1, 1], + "201-f": [0, 1, 1], + "201-n": [0, 1, 1], + "201-v": [0, 1, 1], + "201-a": [0, 1, 1], + "201-w": [0, 1, 1], + "201-o": [0, 1, 1], + "203": [0, 1, 1], + "206": [0, 1, 1], + "207": [0, 1, 1], + "211": [0, 1, 1], + "212-mega": [1, 1, 1], + "212": [1, 1, 1], + "213": [0, 1, 1], + "215": [0, 1, 1], + "216": [1, 1, 1], + "217": [1, 1, 1], + "222": [0, 1, 1], + "226": [0, 2, 2], + "227": [0, 1, 1], + "228": [0, 1, 1], + "229": [0, 1, 1], + "229-mega": [0, 1, 1], + "230": [0, 1, 1], + "231": [0, 1, 1], + "232": [0, 1, 1], + "233": [0, 1, 1], + "235": [0, 1, 1], + "239": [1, 1, 2], + "240": [0, 1, 1], + "242": [2, 2, 2], + "243": [0, 1, 1], + "244": [0, 2, 2], + "245": [0, 1, 1], + "246": [0, 1, 1], + "247": [0, 1, 1], + "248": [0, 1, 1], + "248-mega": [0, 2, 1], + "249": [0, 2, 2], + "250": [0, 2, 2], + "251": [0, 1, 1], + "255": [0, 1, 1], + "256": [0, 1, 1], + "257": [0, 1, 2], + "257-mega": [0, 1, 1], + "261": [0, 1, 1], + "262": [0, 1, 1], + "263": [0, 1, 1], + "264": [0, 1, 1], + "276": [0, 1, 1], + "277": [0, 1, 1], + "278": [1, 1, 1], + "279": [1, 1, 1], + "280": [0, 1, 1], + "281": [0, 1, 1], + "282-mega": [0, 2, 2], + "282": [0, 1, 1], + "285": [0, 1, 1], + "286": [0, 1, 1], + "290": [1, 1, 1], + "291": [2, 2, 2], + "292": [2, 1, 2], + "298": [0, 2, 2], + "300": [1, 1, 1], + "301": [1, 1, 1], + "302": [0, 1, 1], + "302-mega": [0, 1, 1], + "303-mega": [1, 1, 1], + "303": [0, 1, 1], + "304": [1, 1, 1], + "305": [1, 1, 1], + "306-mega": [1, 1, 1], + "306": [1, 1, 1], + "307": [0, 1, 1], + "308-mega": [0, 1, 1], + "308": [0, 2, 1], + "309": [0, 1, 1], + "310-mega": [0, 1, 1], + "310": [0, 1, 1], + "311": [1, 1, 1], + "312": [0, 1, 1], + "315": [0, 1, 1], + "320": [0, 1, 1], + "321": [0, 1, 1], + "327": [0, 1, 1], + "328": [0, 1, 1], + "329": [0, 1, 2], + "330": [0, 1, 1], + "333": [0, 1, 1], + "334-mega": [0, 2, 1], + "334": [0, 2, 2], + "335": [0, 2, 2], + "336": [0, 1, 1], + "337": [0, 1, 1], + "338": [0, 1, 1], + "339": [0, 1, 1], + "340": [0, 1, 2], + "341": [0, 2, 2], + "342": [0, 2, 2], + "351-rainy": [1, 2, 2], + "351-snowy": [1, 1, 1], + "351-sunny": [1, 2, 2], + "351": [0, 2, 2], + "352": [1, 1, 1], + "353": [0, 1, 1], + "354": [0, 1, 1], + "354-mega": [0, 1, 1], + "357": [0, 1, 1], + "358": [2, 1, 1], + "359": [0, 1, 1], + "359-mega": [0, 1, 1], + "361": [0, 1, 1], + "362": [0, 2, 2], + "362-mega": [0, 1, 1], + "369": [0, 1, 1], + "370": [0, 1, 1], + "371": [0, 1, 1], + "372": [0, 1, 1], + "373-mega": [0, 2, 2], + "373": [0, 1, 1], + "374": [0, 1, 1], + "375": [0, 1, 1], + "376-mega": [0, 1, 1], + "376": [0, 1, 1], + "377": [0, 1, 1], + "378": [1, 1, 1], + "379": [0, 1, 1], + "380-mega": [0, 1, 1], + "380": [0, 1, 1], + "381-mega": [0, 1, 1], + "381": [0, 1, 1], + "382-primal": [0, 1, 1], + "382": [0, 1, 1], + "383-primal": [0, 1, 1], + "383": [0, 1, 1], + "384-mega": [0, 2, 1], + "384": [0, 1, 1], + "385": [1, 1, 1], + "387": [0, 1, 1], + "388": [0, 1, 1], + "389": [0, 1, 1], + "390": [0, 1, 1], + "391": [0, 1, 1], + "392": [0, 1, 1], + "393": [0, 1, 1], + "394": [0, 1, 1], + "395": [0, 1, 1], + "399": [0, 1, 1], + "400": [0, 1, 1], + "401": [0, 1, 1], + "402": [0, 1, 1], + "406": [0, 1, 1], + "407": [0, 1, 1], + "412-sandy": [2, 2, 2], + "412-plant": [1, 1, 1], + "412-trash": [1, 1, 1], + "413-plant": [2, 2, 2], + "413-trash": [1, 1, 1], + "413-sandy": [1, 1, 1], + "414": [0, 1, 1], + "418": [0, 1, 1], + "419": [0, 1, 1], + "422-west": [1, 1, 1], + "422-east": [1, 1, 1], + "423-west": [1, 1, 1], + "423-east": [1, 1, 1], + "424": [0, 1, 1], + "425": [0, 1, 1], + "426": [0, 1, 1], + "427": [0, 1, 1], + "428-mega": [0, 1, 1], + "428": [0, 1, 1], + "429": [1, 1, 1], + "430": [0, 1, 1], + "433": [1, 1, 1], + "436": [0, 1, 1], + "437": [0, 1, 1], + "438": [0, 1, 1], + "440": [1, 1, 2], + "441": [0, 1, 1], + "442": [0, 1, 1], + "443": [1, 1, 1], + "444": [1, 1, 1], + "445-mega": [1, 1, 1], + "445": [1, 1, 1], + "447": [1, 1, 1], + "448-mega": [1, 1, 1], + "448": [1, 1, 1], + "453": [0, 1, 1], + "454": [0, 1, 1], + "455": [0, 1, 1], + "456": [0, 1, 1], + "457": [0, 1, 1], + "458": [0, 1, 1], + "461": [0, 1, 1], + "462": [0, 1, 1], + "464": [0, 1, 1], + "465": [0, 1, 1], + "466": [1, 1, 2], + "467": [0, 1, 1], + "468": [1, 1, 1], + "469": [0, 1, 1], + "470": [1, 1, 1], + "471": [1, 2, 2], + "472": [0, 1, 1], + "474": [0, 1, 1], + "475-mega": [0, 2, 2], + "475": [0, 1, 1], + "478": [0, 2, 1], + "479-heat": [0, 1, 1], + "479-wash": [0, 1, 1], + "479-mow": [0, 1, 1], + "479-frost": [0, 1, 1], + "479": [0, 1, 1], + "479-fan": [0, 1, 1], + "480": [1, 1, 1], + "481": [1, 1, 1], + "482": [1, 1, 1], + "485": [0, 1, 1], + "486": [0, 1, 1], + "487-altered": [0, 1, 1], + "487-origin": [0, 1, 1], + "488": [0, 1, 1], + "489": [1, 1, 1], + "490": [1, 1, 1], + "491": [0, 1, 1], + "492-land": [0, 2, 1], + "492-sky": [0, 1, 1], + "494": [0, 1, 1], + "495": [0, 1, 1], + "496": [0, 1, 1], + "497": [0, 1, 1], + "501": [0, 1, 1], + "502": [0, 1, 1], + "503": [0, 1, 1], + "517": [0, 1, 1], + "518": [0, 1, 1], + "524": [0, 1, 1], + "525": [0, 1, 1], + "526": [0, 2, 2], + "527": [0, 1, 1], + "528": [0, 1, 1], + "529": [0, 2, 2], + "530": [0, 2, 2], + "531": [0, 1, 1], + "531-mega": [0, 1, 1], + "532": [0, 1, 1], + "533": [0, 1, 1], + "534": [0, 1, 1], + "538": [0, 1, 1], + "539": [0, 2, 2], + "540": [0, 1, 1], + "541": [0, 1, 1], + "542": [0, 1, 1], + "543": [0, 1, 2], + "544": [0, 1, 2], + "545": [0, 1, 1], + "546": [0, 1, 1], + "547": [0, 1, 1], + "548": [1, 1, 1], + "549": [0, 1, 2], + "551": [0, 1, 1], + "552": [0, 1, 1], + "553": [0, 1, 1], + "556": [0, 1, 1], + "559": [1, 1, 1], + "560": [1, 1, 1], + "562": [0, 1, 1], + "563": [0, 1, 1], + "568": [0, 2, 2], + "569-gigantamax": [0, 1, 1], + "569": [0, 1, 1], + "570": [0, 1, 1], + "571": [0, 1, 1], + "572": [0, 1, 1], + "577": [1, 1, 1], + "578": [1, 1, 1], + "579": [1, 1, 1], + "585-autumn": [2, 0, 0], + "585-spring": [2, 0, 0], + "585-summer": [2, 0, 0], + "585-winter": [2, 0, 0], + "586-autumn": [1, 0, 0], + "586-spring": [1, 0, 0], + "586-summer": [1, 0, 0], + "586-winter": [1, 0, 0], + "587": [0, 1, 1], + "588": [0, 1, 1], + "589": [0, 1, 1], + "590": [0, 1, 1], + "591": [0, 1, 1], + "592": [0, 1, 2], + "593": [0, 1, 1], + "594": [0, 1, 2], + "595": [0, 1, 1], + "596": [0, 1, 1], + "602": [0, 1, 1], + "603": [0, 1, 1], + "604": [0, 1, 1], + "605": [1, 1, 1], + "606": [1, 1, 1], + "607": [0, 1, 1], + "608": [0, 1, 1], + "609": [0, 1, 1], + "610": [0, 1, 1], + "611": [0, 1, 1], + "612": [0, 1, 2], + "616": [0, 1, 1], + "617": [0, 1, 1], + "618": [0, 1, 1], + "619": [0, 1, 1], + "620": [0, 1, 1], + "621": [0, 1, 1], + "622": [0, 1, 1], + "623": [0, 1, 1], + "631": [0, 2, 2], + "632": [0, 1, 1], + "633": [0, 1, 1], + "634": [0, 1, 1], + "635": [0, 1, 1], + "636": [0, 1, 1], + "637": [0, 1, 1], + "640": [0, 1, 1], + "647-resolute": [0, 1, 1], + "647-ordinary": [0, 1, 1], + "648-aria": [0, 1, 1], + "648-pirouette": [0, 1, 1], + "649-burn": [0, 1, 1], + "649-chill": [0, 1, 1], + "649-douse": [0, 1, 1], + "649-shock": [0, 1, 1], + "649": [0, 1, 1], + "653": [0, 1, 1], + "654": [0, 1, 1], + "655": [0, 1, 1], + "656": [0, 1, 1], + "657": [0, 1, 1], + "658": [0, 1, 1], + "658-ash": [0, 1, 1], + "664": [0, 1, 1], + "665": [0, 1, 1], + "666-archipelago": [0, 1, 1], + "666-continental": [0, 1, 2], + "666-elegant": [0, 1, 1], + "666-fancy": [0, 2, 2], + "666-garden": [0, 1, 1], + "666-high-plains": [0, 1, 1], + "666-icy-snow": [0, 1, 1], + "666-jungle": [0, 1, 1], + "666-marine": [0, 1, 1], + "666-meadow": [0, 1, 1], + "666-modern": [0, 1, 1], + "666-monsoon": [0, 1, 1], + "666-ocean": [0, 1, 1], + "666-poke-ball": [0, 1, 2], + "666-polar": [0, 1, 1], + "666-river": [0, 2, 1], + "666-sandstorm": [0, 1, 1], + "666-savanna": [0, 1, 1], + "666-sun": [0, 1, 1], + "666-tundra": [0, 1, 1], + "669-red": [0, 2, 1], + "669-blue": [0, 2, 2], + "669-white": [0, 1, 1], + "669-yellow": [0, 2, 1], + "669-orange": [0, 2, 1], + "670-white": [0, 2, 2], + "670-blue": [0, 2, 2], + "670-orange": [0, 2, 2], + "670-red": [0, 2, 2], + "670-yellow": [0, 2, 2], + "671-red": [0, 1, 2], + "671-blue": [0, 1, 2], + "671-yellow": [0, 1, 2], + "671-white": [0, 1, 2], + "671-orange": [0, 1, 1], + "672": [0, 1, 2], + "673": [0, 1, 1], + "676": [0, 1, 1], + "676-dandy": [0, 1, 1], + "676-debutante": [0, 1, 1], + "676-diamond": [0, 1, 1], + "676-heart": [0, 1, 1], + "676-kabuki": [0, 1, 1], + "676-la-reine": [0, 1, 1], + "676-matron": [0, 1, 1], + "676-pharaoh": [0, 1, 1], + "676-star": [0, 1, 1], + "677": [0, 1, 1], + "678-female": [0, 1, 1], + "678": [0, 1, 1], + "682": [0, 1, 1], + "683": [0, 1, 1], + "684": [0, 1, 1], + "685": [0, 1, 1], + "688": [0, 1, 1], + "689": [0, 1, 1], + "690": [0, 1, 1], + "691": [0, 1, 1], + "696": [0, 1, 1], + "697": [0, 1, 1], + "698": [0, 1, 1], + "699": [0, 1, 1], + "700": [0, 1, 1], + "702": [0, 1, 1], + "703": [0, 1, 1], + "704": [0, 1, 1], + "705": [0, 1, 1], + "706": [0, 1, 1], + "708": [0, 1, 1], + "709": [0, 1, 1], + "710": [0, 1, 1], + "711": [1, 1, 1], + "712": [0, 1, 1], + "713": [0, 1, 1], + "714": [0, 1, 1], + "715": [0, 2, 2], + "716-active": [0, 1, 1], + "716-neutral": [0, 1, 1], + "717": [0, 1, 1], + "720-unbound": [1, 1, 1], + "720": [1, 1, 1], + "728": [0, 1, 1], + "729": [0, 1, 1], + "730": [0, 1, 1], + "734": [0, 1, 1], + "735": [0, 1, 1], + "742": [0, 2, 2], + "743": [0, 2, 2], + "747": [0, 1, 1], + "748": [0, 1, 1], + "751": [0, 1, 1], + "752": [0, 1, 1], + "753": [0, 1, 1], + "754": [0, 1, 1], + "755": [0, 1, 1], + "756": [0, 1, 2], + "761": [0, 1, 1], + "762": [0, 1, 1], + "763": [0, 1, 1], + "767": [0, 1, 1], + "768": [0, 1, 1], + "771": [0, 1, 1], + "772": [0, 1, 1], + "773-fighting": [0, 1, 1], + "773-psychic": [0, 1, 1], + "773-poison": [0, 1, 1], + "773-ground": [0, 1, 1], + "773-ghost": [0, 1, 1], + "773-steel": [0, 1, 1], + "773-rock": [0, 1, 1], + "773-grass": [0, 1, 1], + "773-dragon": [0, 1, 1], + "773-bug": [0, 1, 1], + "773-ice": [0, 1, 1], + "773-dark": [0, 1, 1], + "773": [0, 1, 1], + "773-fairy": [0, 1, 1], + "773-water": [0, 1, 1], + "773-electric": [0, 1, 1], + "773-flying": [0, 1, 1], + "773-fire": [0, 1, 1], + "776": [0, 1, 1], + "777": [0, 1, 1], + "778-busted": [0, 1, 1], + "778-disguised": [0, 1, 1], + "779": [0, 1, 1], + "789": [1, 1, 1], + "790": [0, 1, 1], + "791-radiant-sun": [0, 1, 1], + "791": [2, 1, 1], + "792-full-moon": [0, 1, 1], + "792": [0, 1, 1], + "793": [0, 1, 1], + "797": [0, 1, 1], + "798": [0, 1, 1], + "800-dawn-wings": [0, 1, 1], + "800-dusk-mane": [0, 1, 1], + "800-ultra": [0, 1, 1], + "800": [0, 1, 1], + "802": [1, 1, 1], + "803": [0, 1, 1], + "804": [0, 1, 1], + "807": [0, 1, 1], + "808": [0, 1, 1], + "809-gigantamax": [0, 1, 1], + "809": [0, 1, 1], + "816": [0, 1, 1], + "817": [0, 1, 1], + "818-gigantamax": [1, 1, 1], + "818": [0, 1, 1], + "821": [0, 1, 1], + "822": [0, 1, 1], + "823-gigantamax": [0, 2, 2], + "823": [0, 1, 1], + "829": [0, 1, 1], + "830": [0, 1, 1], + "835": [0, 1, 1], + "836": [0, 2, 2], + "850": [0, 1, 1], + "851-gigantamax": [0, 1, 1], + "851": [0, 1, 1], + "854": [0, 1, 1], + "855": [0, 1, 1], + "856": [0, 1, 1], + "857": [0, 2, 2], + "858-gigantamax": [0, 1, 1], + "858": [0, 1, 1], + "859": [0, 2, 2], + "860": [0, 1, 1], + "861-gigantamax": [0, 1, 1], + "861": [0, 1, 1], + "862": [0, 1, 1], + "863": [0, 1, 1], + "864": [0, 1, 1], + "867": [0, 1, 1], + "872": [1, 1, 1], + "873": [1, 1, 1], + "876-female": [0, 1, 1], + "876": [0, 1, 1], + "877-hangry": [1, 1, 1], + "877": [1, 1, 1], + "880": [0, 1, 1], + "881": [0, 1, 1], + "882": [0, 1, 1], + "883": [0, 1, 1], + "884-gigantamax": [0, 1, 1], + "884": [0, 1, 1], + "885": [1, 1, 1], + "886": [1, 1, 1], + "887": [2, 1, 1], + "888": [0, 1, 1], + "888-crowned": [0, 1, 1], + "889": [0, 1, 1], + "889-crowned": [0, 1, 1], + "890-eternamax": [0, 1, 1], + "890": [0, 1, 1], + "891": [1, 1, 1], + "892-gigantamax-rapid": [1, 2, 2], + "892-rapid-strike": [1, 1, 1], + "892": [1, 1, 1], + "892-gigantamax-single": [1, 2, 2], + "894": [0, 1, 1], + "895": [0, 1, 1], + "896": [1, 1, 1], + "897": [2, 1, 1], + "898": [1, 1, 1], + "898-ice": [1, 1, 1], + "898-shadow": [1, 1, 1], + "900": [0, 1, 1], + "901": [0, 1, 2], + "903": [0, 1, 1], + "909": [0, 2, 2], + "910": [0, 2, 2], + "911": [0, 1, 1], + "912": [0, 1, 1], + "913": [0, 2, 2], + "914": [0, 2, 1], + "919": [1, 1, 1], + "920": [2, 2, 2], + "924": [1, 1, 1], + "925-four": [1, 1, 1], + "925-three": [1, 1, 1], + "932": [0, 1, 2], + "933": [0, 1, 1], + "934": [0, 1, 1], + "935": [2, 2, 2], + "936": [2, 2, 2], + "937": [2, 2, 2], + "940": [0, 1, 1], + "941": [0, 1, 1], + "944": [0, 1, 1], + "945": [0, 1, 1], + "948": [0, 1, 1], + "949": [0, 1, 1], + "951": [0, 1, 1], + "952": [0, 1, 1], + "953": [0, 1, 1], + "954": [0, 1, 1], + "957": [1, 2, 2], + "958": [2, 2, 1], + "959": [2, 2, 2], + "962": [1, 1, 1], + "967": [0, 1, 1], + "968": [0, 2, 2], + "969": [0, 1, 1], + "970": [0, 1, 1], + "973": [2, 2, 2], + "974": [0, 1, 1], + "975": [0, 2, 2], + "978-curly": [0, 2, 2], + "978-droopy": [0, 2, 2], + "978-stretchy": [0, 2, 2], + "979": [2, 2, 2], + "981": [0, 1, 1], + "982": [0, 1, 1], + "982-three-segment": [0, 1, 1], + "987": [1, 1, 1], + "988": [0, 1, 2], + "993": [0, 1, 1], + "994": [0, 1, 1], + "995": [0, 1, 1], + "996": [0, 1, 1], + "997": [0, 1, 1], + "998": [0, 1, 1], + "999": [1, 1, 1], + "1000": [1, 1, 1], + "1001": [0, 1, 1], + "1003": [0, 1, 1], + "1004": [0, 1, 1], + "1006": [0, 2, 1], + "1007-apex-build": [0, 2, 2], + "1008-ultimate-mode": [1, 1, 1], + "1010": [0, 1, 1], + "1012-counterfeit": [0, 1, 1], + "1013-unremarkable": [0, 1, 1], + "1018": [0, 1, 1], + "1022": [0, 1, 1], + "1023": [0, 1, 1], + "2026": [0, 1, 1], + "2027": [0, 1, 1], + "2028": [0, 1, 1], + "2052": [0, 1, 1], + "2053": [0, 1, 1], + "2103": [0, 1, 1], + "2670": [0, 1, 1], + "4052": [0, 1, 1], + "4077": [0, 1, 1], + "4078": [0, 1, 1], + "4079": [0, 1, 1], + "4080": [2, 1, 1], + "4144": [0, 1, 1], + "4145": [0, 1, 1], + "4146": [0, 1, 1], + "4199": [2, 1, 1], + "4222": [0, 1, 1], + "4263": [0, 1, 1], + "4264": [0, 1, 1], + "4562": [0, 1, 1], + "6100": [0, 1, 1], + "6101": [0, 1, 1], + "6215": [0, 1, 1], + "6503": [0, 1, 1], + "6549": [0, 1, 1], + "6570": [0, 1, 1], + "6571": [0, 1, 1], + "6705": [0, 1, 1], + "6706": [0, 1, 1], + "6713": [0, 1, 1], + "8901": [1, 1, 1], "female": { - "3": [ - 0, - 2, - 1 - ], - "19": [ - 0, - 1, - 1 - ], - "20": [ - 0, - 1, - 1 - ], - "41": [ - 0, - 1, - 1 - ], - "42": [ - 0, - 1, - 1 - ], - "44": [ - 0, - 1, - 1 - ], - "45": [ - 0, - 1, - 1 - ], - "84": [ - 1, - 1, - 1 - ], - "85": [ - 1, - 1, - 1 - ], - "111": [ - 0, - 1, - 1 - ], - "112": [ - 0, - 1, - 1 - ], - "118": [ - 0, - 1, - 1 - ], - "119": [ - 0, - 1, - 1 - ], - "123": [ - 1, - 1, - 1 - ], - "129": [ - 0, - 1, - 1 - ], - "130": [ - 0, - 1, - 1 - ], - "178": [ - 0, - 2, - 2 - ], - "185": [ - 0, - 1, - 1 - ], - "190": [ - 0, - 1, - 1 - ], - "203": [ - 0, - 1, - 1 - ], - "207": [ - 0, - 1, - 1 - ], - "215": [ - 0, - 1, - 1 - ], - "217": [ - 1, - 1, - 1 - ], - "229": [ - 0, - 1, - 1 - ], - "232": [ - 0, - 1, - 1 - ], - "255": [ - 0, - 1, - 1 - ], - "256": [ - 0, - 1, - 1 - ], - "257": [ - 0, - 1, - 1 - ], - "307": [ - 0, - 1, - 1 - ], - "308": [ - 0, - 1, - 1 - ], - "315": [ - 0, - 1, - 1 - ], - "369": [ - 0, - 1, - 1 - ], - "399": [ - 0, - 1, - 1 - ], - "400": [ - 0, - 1, - 1 - ], - "401": [ - 0, - 1, - 1 - ], - "402": [ - 0, - 2, - 2 - ], - "407": [ - 0, - 1, - 1 - ], - "418": [ - 0, - 1, - 1 - ], - "419": [ - 0, - 2, - 1 - ], - "424": [ - 0, - 1, - 1 - ], - "443": [ - 1, - 1, - 1 - ], - "444": [ - 1, - 1, - 1 - ], - "445": [ - 1, - 1, - 1 - ], - "453": [ - 0, - 1, - 1 - ], - "454": [ - 0, - 1, - 1 - ], - "456": [ - 0, - 1, - 1 - ], - "457": [ - 0, - 1, - 1 - ], - "461": [ - 0, - 1, - 1 - ], - "464": [ - 0, - 1, - 1 - ], - "465": [ - 0, - 1, - 1 - ], - "592": [ - 1, - 1, - 1 - ], - "593": [ - 1, - 1, - 1 - ], - "6215": [ - 0, - 1, - 1 - ] + "3": [0, 2, 1], + "19": [0, 1, 1], + "20": [0, 1, 1], + "25": [0, 1, 1], + "25-beauty-cosplay": [0, 1, 1], + "25-cool-cosplay": [0, 1, 1], + "25-cosplay": [0, 1, 1], + "25-cute-cosplay": [0, 1, 1], + "25-partner": [0, 1, 1], + "25-smart-cosplay": [0, 1, 1], + "25-tough-cosplay": [0, 1, 1], + "26": [0, 1, 1], + "41": [0, 1, 1], + "42": [0, 1, 1], + "44": [0, 1, 1], + "45": [0, 1, 1], + "84": [1, 1, 1], + "85": [1, 1, 1], + "111": [0, 1, 1], + "112": [0, 1, 1], + "118": [0, 1, 1], + "119": [0, 1, 1], + "123": [1, 1, 1], + "129": [0, 1, 1], + "130": [0, 1, 1], + "154": [0, 1, 1], + "178": [0, 2, 2], + "185": [0, 1, 1], + "190": [0, 1, 1], + "194": [0, 1, 1], + "195": [0, 1, 1], + "198": [0, 1, 1], + "203": [0, 1, 1], + "207": [0, 1, 1], + "215": [0, 1, 1], + "217": [1, 1, 1], + "229": [0, 1, 1], + "232": [0, 1, 1], + "255": [0, 1, 1], + "256": [0, 1, 1], + "257": [0, 1, 1], + "307": [0, 1, 1], + "308": [0, 1, 1], + "315": [0, 1, 1], + "369": [0, 1, 1], + "399": [0, 1, 1], + "400": [0, 1, 1], + "401": [0, 1, 1], + "402": [0, 2, 2], + "407": [0, 1, 1], + "418": [0, 1, 1], + "419": [0, 2, 1], + "424": [0, 1, 1], + "443": [1, 1, 1], + "444": [1, 1, 1], + "445": [1, 1, 1], + "453": [0, 1, 1], + "454": [0, 1, 1], + "456": [0, 1, 1], + "457": [0, 1, 1], + "461": [0, 1, 1], + "464": [0, 1, 1], + "465": [0, 1, 1], + "592": [1, 1, 1], + "593": [1, 1, 1], + "6215": [0, 1, 1] }, "back": { - "1": [ - 0, - 1, - 1 - ], - "2": [ - 0, - 1, - 1 - ], - "3-gigantamax": [ - 0, - 1, - 1 - ], - "3-mega": [ - 0, - 2, - 2 - ], - "3": [ - 0, - 1, - 1 - ], - "4": [ - 0, - 1, - 1 - ], - "5": [ - 0, - 1, - 1 - ], - "6-mega-x": [ - 0, - 1, - 2 - ], - "6-gigantamax": [ - 0, - 1, - 2 - ], - "6-mega-y": [ - 0, - 1, - 2 - ], - "6": [ - 0, - 2, - 2 - ], - "7": [ - 0, - 2, - 2 - ], - "8": [ - 0, - 2, - 2 - ], - "9-gigantamax": [ - 0, - 1, - 2 - ], - "9-mega": [ - 0, - 2, - 2 - ], - "9": [ - 0, - 2, - 2 - ], - "19": [ - 0, - 1, - 1 - ], - "20": [ - 0, - 1, - 1 - ], - "23": [ - 0, - 1, - 1 - ], - "24": [ - 0, - 1, - 1 - ], - "29": [ - 0, - 1, - 1 - ], - "30": [ - 0, - 1, - 1 - ], - "31": [ - 1, - 1, - 1 - ], - "35": [ - 0, - 1, - 1 - ], - "36": [ - 0, - 2, - 1 - ], - "37": [ - 0, - 1, - 1 - ], - "38": [ - 0, - 1, - 1 - ], - "41": [ - 0, - 1, - 1 - ], - "42": [ - 0, - 1, - 1 - ], - "43": [ - 0, - 1, - 1 - ], - "44": [ - 0, - 1, - 1 - ], - "45": [ - 0, - 1, - 1 - ], - "46": [ - 1, - 1, - 1 - ], - "47": [ - 1, - 1, - 1 - ], - "50": [ - 0, - 1, - 1 - ], - "51": [ - 0, - 1, - 1 - ], - "52-gigantamax": [ - 1, - 1, - 1 - ], - "52": [ - 1, - 1, - 1 - ], - "53": [ - 1, - 1, - 1 - ], - "56": [ - 1, - 1, - 1 - ], - "57": [ - 1, - 1, - 1 - ], - "69": [ - 0, - 1, - 1 - ], - "70": [ - 0, - 1, - 1 - ], - "71": [ - 0, - 1, - 1 - ], - "77": [ - 0, - 1, - 1 - ], - "78": [ - 0, - 1, - 1 - ], - "79": [ - 1, - 1, - 1 - ], - "80": [ - 0, - 1, - 1 - ], - "80-mega": [ - 0, - 1, - 1 - ], - "81": [ - 0, - 1, - 1 - ], - "82": [ - 0, - 1, - 1 - ], - "83": [ - 0, - 2, - 2 - ], - "84": [ - 1, - 1, - 1 - ], - "85": [ - 1, - 1, - 1 - ], - "86": [ - 1, - 1, - 1 - ], - "87": [ - 1, - 1, - 1 - ], - "92": [ - 2, - 2, - 2 - ], - "93": [ - 1, - 1, - 1 - ], - "94-gigantamax": [ - 1, - 1, - 1 - ], - "94-mega": [ - 1, - 1, - 1 - ], - "94": [ - 1, - 1, - 1 - ], - "98": [ - 0, - 1, - 1 - ], - "99": [ - 0, - 1, - 1 - ], - "99-gigantamax": [ - 0, - 1, - 1 - ], - "100": [ - 0, - 1, - 1 - ], - "101": [ - 0, - 1, - 1 - ], - "111": [ - 0, - 1, - 1 - ], - "112": [ - 0, - 1, - 1 - ], - "113": [ - 1, - 1, - 1 - ], - "114": [ - 0, - 1, - 1 - ], - "116": [ - 0, - 1, - 1 - ], - "117": [ - 0, - 1, - 1 - ], - "118": [ - 1, - 1, - 1 - ], - "119": [ - 1, - 1, - 1 - ], - "120": [ - 0, - 1, - 1 - ], - "121": [ - 0, - 1, - 1 - ], - "123": [ - 1, - 1, - 1 - ], - "125": [ - 1, - 1, - 2 - ], - "126": [ - 0, - 2, - 1 - ], - "127-mega": [ - 0, - 1, - 1 - ], - "127": [ - 0, - 1, - 1 - ], - "129": [ - 0, - 1, - 1 - ], - "130-mega": [ - 0, - 1, - 1 - ], - "130": [ - 0, - 1, - 1 - ], - "131-gigantamax": [ - 0, - 1, - 1 - ], - "131": [ - 0, - 1, - 1 - ], - "132": [ - 0, - 1, - 1 - ], - "133": [ - 0, - 1, - 1 - ], - "133-partner": [ - 0, - 1, - 1 - ], - "134": [ - 0, - 1, - 1 - ], - "135": [ - 1, - 1, - 1 - ], - "136": [ - 1, - 1, - 1 - ], - "137": [ - 0, - 1, - 1 - ], - "138": [ - 0, - 1, - 1 - ], - "139": [ - 0, - 1, - 1 - ], - "140": [ - 0, - 1, - 1 - ], - "141": [ - 0, - 1, - 1 - ], - "142-mega": [ - 0, - 1, - 1 - ], - "142": [ - 0, - 1, - 1 - ], - "144": [ - 1, - 1, - 1 - ], - "145": [ - 1, - 1, - 1 - ], - "146": [ - 1, - 1, - 1 - ], - "147": [ - 0, - 1, - 1 - ], - "148": [ - 0, - 1, - 1 - ], - "149": [ - 0, - 1, - 1 - ], - "150-mega-x": [ - 0, - 1, - 1 - ], - "150-mega-y": [ - 0, - 1, - 1 - ], - "150": [ - 0, - 1, - 1 - ], - "151": [ - 0, - 1, - 1 - ], - "161": [ - 0, - 1, - 1 - ], - "162": [ - 0, - 1, - 1 - ], - "163": [ - 0, - 1, - 1 - ], - "164": [ - 0, - 1, - 1 - ], - "169": [ - 0, - 1, - 1 - ], - "173": [ - 0, - 1, - 1 - ], - "175": [ - 1, - 1, - 1 - ], - "176": [ - 1, - 1, - 1 - ], - "177": [ - 0, - 1, - 1 - ], - "178": [ - 0, - 2, - 2 - ], - "179": [ - 0, - 1, - 1 - ], - "180": [ - 0, - 1, - 2 - ], - "181-mega": [ - 0, - 1, - 2 - ], - "181": [ - 0, - 1, - 1 - ], - "182": [ - 0, - 1, - 1 - ], - "183": [ - 0, - 1, - 1 - ], - "184": [ - 0, - 1, - 1 - ], - "185": [ - 0, - 1, - 1 - ], - "190": [ - 0, - 1, - 1 - ], - "193": [ - 0, - 1, - 1 - ], - "196": [ - 1, - 1, - 1 - ], - "197": [ - 0, - 1, - 1 - ], - "199": [ - 2, - 1, - 1 - ], - "200": [ - 1, - 2, - 2 - ], - "201-m": [ - 0, - 1, - 1 - ], - "201-question": [ - 0, - 1, - 1 - ], - "201-j": [ - 0, - 1, - 1 - ], - "201-l": [ - 0, - 1, - 1 - ], - "201-h": [ - 0, - 1, - 1 - ], - "201-x": [ - 0, - 1, - 1 - ], - "201-exclamation": [ - 0, - 1, - 1 - ], - "201-q": [ - 0, - 1, - 1 - ], - "201-s": [ - 0, - 1, - 1 - ], - "201-c": [ - 0, - 1, - 1 - ], - "201-u": [ - 0, - 1, - 1 - ], - "201-t": [ - 0, - 1, - 1 - ], - "201-z": [ - 0, - 1, - 1 - ], - "201-d": [ - 0, - 1, - 1 - ], - "201-b": [ - 0, - 1, - 1 - ], - "201-g": [ - 0, - 1, - 1 - ], - "201-k": [ - 0, - 1, - 1 - ], - "201-i": [ - 0, - 1, - 1 - ], - "201-p": [ - 0, - 1, - 1 - ], - "201-e": [ - 0, - 1, - 1 - ], - "201-y": [ - 0, - 1, - 1 - ], - "201-r": [ - 0, - 1, - 1 - ], - "201-f": [ - 0, - 1, - 1 - ], - "201-n": [ - 0, - 1, - 1 - ], - "201-v": [ - 0, - 1, - 1 - ], - "201-a": [ - 0, - 1, - 1 - ], - "201-w": [ - 0, - 1, - 1 - ], - "201-o": [ - 0, - 1, - 1 - ], - "203": [ - 0, - 1, - 1 - ], - "206": [ - 0, - 1, - 1 - ], - "207": [ - 0, - 1, - 1 - ], - "212-mega": [ - 1, - 2, - 1 - ], - "212": [ - 1, - 1, - 1 - ], - "213": [ - 0, - 1, - 1 - ], - "215": [ - 0, - 1, - 1 - ], - "216": [ - 1, - 1, - 1 - ], - "217": [ - 1, - 1, - 1 - ], - "222": [ - 0, - 1, - 1 - ], - "226": [ - 0, - 1, - 1 - ], - "227": [ - 0, - 1, - 1 - ], - "228": [ - 0, - 1, - 1 - ], - "229": [ - 0, - 1, - 1 - ], - "229-mega": [ - 0, - 1, - 1 - ], - "230": [ - 0, - 1, - 1 - ], - "231": [ - 0, - 1, - 1 - ], - "232": [ - 0, - 1, - 1 - ], - "233": [ - 0, - 1, - 1 - ], - "235": [ - 0, - 1, - 1 - ], - "239": [ - 1, - 1, - 2 - ], - "240": [ - 0, - 1, - 1 - ], - "242": [ - 1, - 1, - 1 - ], - "243": [ - 0, - 1, - 1 - ], - "244": [ - 0, - 2, - 2 - ], - "245": [ - 0, - 1, - 1 - ], - "246": [ - 0, - 1, - 1 - ], - "247": [ - 0, - 1, - 1 - ], - "248": [ - 0, - 1, - 1 - ], - "248-mega": [ - 0, - 1, - 1 - ], - "249": [ - 0, - 1, - 1 - ], - "250": [ - 0, - 1, - 1 - ], - "251": [ - 0, - 1, - 1 - ], - "255": [ - 0, - 1, - 1 - ], - "256": [ - 0, - 1, - 1 - ], - "257": [ - 0, - 1, - 1 - ], - "257-mega": [ - 0, - 1, - 1 - ], - "261": [ - 0, - 1, - 1 - ], - "262": [ - 0, - 1, - 1 - ], - "263": [ - 0, - 1, - 1 - ], - "264": [ - 0, - 1, - 1 - ], - "278": [ - 1, - 1, - 1 - ], - "279": [ - 1, - 1, - 1 - ], - "280": [ - 0, - 1, - 1 - ], - "281": [ - 0, - 1, - 1 - ], - "282-mega": [ - 0, - 1, - 1 - ], - "282": [ - 0, - 1, - 1 - ], - "285": [ - 0, - 1, - 1 - ], - "286": [ - 0, - 1, - 1 - ], - "290": [ - 1, - 1, - 1 - ], - "291": [ - 2, - 2, - 2 - ], - "292": [ - 2, - 2, - 2 - ], - "298": [ - 0, - 1, - 1 - ], - "300": [ - 1, - 1, - 1 - ], - "301": [ - 1, - 1, - 1 - ], - "302": [ - 0, - 1, - 1 - ], - "302-mega": [ - 0, - 1, - 1 - ], - "303-mega": [ - 1, - 1, - 1 - ], - "303": [ - 1, - 1, - 1 - ], - "304": [ - 1, - 1, - 1 - ], - "305": [ - 1, - 1, - 1 - ], - "306-mega": [ - 1, - 1, - 1 - ], - "306": [ - 1, - 1, - 1 - ], - "307": [ - 0, - 1, - 1 - ], - "308-mega": [ - 0, - 1, - 1 - ], - "308": [ - 0, - 1, - 1 - ], - "309": [ - 0, - 1, - 1 - ], - "310-mega": [ - 0, - 1, - 1 - ], - "310": [ - 0, - 1, - 1 - ], - "311": [ - 1, - 1, - 1 - ], - "312": [ - 0, - 1, - 1 - ], - "315": [ - 0, - 1, - 1 - ], - "320": [ - 0, - 1, - 1 - ], - "321": [ - 0, - 1, - 1 - ], - "327": [ - 0, - 1, - 1 - ], - "328": [ - 0, - 1, - 1 - ], - "329": [ - 0, - 1, - 1 - ], - "330": [ - 0, - 1, - 1 - ], - "333": [ - 0, - 1, - 1 - ], - "334-mega": [ - 0, - 1, - 1 - ], - "334": [ - 0, - 1, - 1 - ], - "335": [ - 0, - 2, - 2 - ], - "336": [ - 0, - 1, - 1 - ], - "337": [ - 0, - 1, - 1 - ], - "338": [ - 0, - 1, - 1 - ], - "339": [ - 0, - 2, - 1 - ], - "340": [ - 0, - 1, - 2 - ], - "341": [ - 0, - 1, - 1 - ], - "342": [ - 0, - 2, - 2 - ], - "351-rainy": [ - 1, - 1, - 1 - ], - "351-snowy": [ - 1, - 1, - 1 - ], - "351-sunny": [ - 1, - 1, - 2 - ], - "351": [ - 0, - 1, - 1 - ], - "352": [ - 1, - 1, - 1 - ], - "353": [ - 0, - 1, - 1 - ], - "354": [ - 0, - 1, - 1 - ], - "354-mega": [ - 0, - 1, - 1 - ], - "357": [ - 0, - 1, - 1 - ], - "358": [ - 1, - 1, - 1 - ], - "361": [ - 0, - 1, - 1 - ], - "362": [ - 0, - 1, - 1 - ], - "362-mega": [ - 0, - 1, - 1 - ], - "369": [ - 0, - 2, - 2 - ], - "370": [ - 0, - 2, - 2 - ], - "371": [ - 0, - 1, - 1 - ], - "372": [ - 0, - 1, - 1 - ], - "373-mega": [ - 0, - 1, - 1 - ], - "373": [ - 0, - 1, - 1 - ], - "374": [ - 0, - 1, - 1 - ], - "375": [ - 0, - 1, - 1 - ], - "376-mega": [ - 0, - 1, - 1 - ], - "376": [ - 0, - 1, - 1 - ], - "380-mega": [ - 0, - 1, - 1 - ], - "380": [ - 0, - 1, - 1 - ], - "381-mega": [ - 0, - 1, - 1 - ], - "381": [ - 0, - 1, - 1 - ], - "382-primal": [ - 0, - 1, - 1 - ], - "382": [ - 0, - 1, - 1 - ], - "383-primal": [ - 0, - 1, - 1 - ], - "383": [ - 0, - 1, - 1 - ], - "384-mega": [ - 0, - 1, - 1 - ], - "384": [ - 0, - 1, - 1 - ], - "385": [ - 1, - 1, - 1 - ], - "387": [ - 0, - 2, - 1 - ], - "388": [ - 0, - 1, - 1 - ], - "389": [ - 0, - 1, - 1 - ], - "393": [ - 0, - 1, - 1 - ], - "394": [ - 0, - 1, - 1 - ], - "395": [ - 0, - 1, - 1 - ], - "399": [ - 0, - 2, - 1 - ], - "400": [ - 0, - 1, - 1 - ], - "401": [ - 0, - 1, - 1 - ], - "402": [ - 0, - 1, - 1 - ], - "406": [ - 0, - 1, - 1 - ], - "407": [ - 0, - 1, - 1 - ], - "412-sandy": [ - 2, - 2, - 2 - ], - "412-plant": [ - 1, - 1, - 1 - ], - "412-trash": [ - 1, - 1, - 1 - ], - "413-plant": [ - 1, - 1, - 1 - ], - "413-trash": [ - 1, - 1, - 1 - ], - "413-sandy": [ - 1, - 1, - 1 - ], - "414": [ - 0, - 1, - 1 - ], - "418": [ - 0, - 1, - 1 - ], - "419": [ - 0, - 1, - 1 - ], - "422-west": [ - 1, - 1, - 1 - ], - "422-east": [ - 1, - 1, - 1 - ], - "423-west": [ - 1, - 1, - 1 - ], - "423-east": [ - 1, - 1, - 1 - ], - "424": [ - 0, - 1, - 1 - ], - "425": [ - 0, - 1, - 1 - ], - "426": [ - 0, - 1, - 1 - ], - "427": [ - 0, - 1, - 1 - ], - "428-mega": [ - 0, - 1, - 1 - ], - "428": [ - 0, - 1, - 1 - ], - "429": [ - 1, - 1, - 1 - ], - "433": [ - 1, - 1, - 1 - ], - "436": [ - 0, - 1, - 1 - ], - "437": [ - 0, - 1, - 1 - ], - "438": [ - 0, - 1, - 1 - ], - "440": [ - 1, - 1, - 1 - ], - "441": [ - 0, - 1, - 2 - ], - "442": [ - 0, - 1, - 1 - ], - "443": [ - 1, - 1, - 1 - ], - "444": [ - 1, - 1, - 1 - ], - "445-mega": [ - 1, - 1, - 1 - ], - "445": [ - 1, - 1, - 1 - ], - "447": [ - 1, - 1, - 1 - ], - "448-mega": [ - 1, - 1, - 1 - ], - "448": [ - 1, - 1, - 1 - ], - "453": [ - 0, - 1, - 1 - ], - "454": [ - 0, - 1, - 1 - ], - "456": [ - 0, - 1, - 1 - ], - "457": [ - 0, - 2, - 1 - ], - "458": [ - 0, - 2, - 2 - ], - "461": [ - 0, - 1, - 1 - ], - "462": [ - 0, - 1, - 1 - ], - "464": [ - 0, - 1, - 1 - ], - "465": [ - 0, - 1, - 1 - ], - "466": [ - 2, - 1, - 1 - ], - "467": [ - 0, - 1, - 1 - ], - "468": [ - 1, - 1, - 1 - ], - "469": [ - 0, - 1, - 1 - ], - "470": [ - 2, - 2, - 1 - ], - "471": [ - 1, - 1, - 1 - ], - "472": [ - 0, - 1, - 1 - ], - "474": [ - 0, - 1, - 1 - ], - "475-mega": [ - 0, - 2, - 2 - ], - "475": [ - 0, - 1, - 1 - ], - "478": [ - 0, - 2, - 1 - ], - "479-heat": [ - 0, - 1, - 1 - ], - "479-wash": [ - 0, - 1, - 1 - ], - "479-mow": [ - 0, - 1, - 1 - ], - "479-frost": [ - 0, - 1, - 1 - ], - "479": [ - 0, - 1, - 1 - ], - "479-fan": [ - 0, - 1, - 1 - ], - "480": [ - 1, - 1, - 1 - ], - "481": [ - 1, - 1, - 1 - ], - "482": [ - 1, - 1, - 1 - ], - "485": [ - 0, - 1, - 1 - ], - "487-altered": [ - 0, - 1, - 1 - ], - "487-origin": [ - 0, - 1, - 1 - ], - "488": [ - 0, - 1, - 1 - ], - "489": [ - 1, - 1, - 1 - ], - "490": [ - 1, - 1, - 1 - ], - "491": [ - 0, - 1, - 1 - ], - "492-land": [ - 0, - 1, - 1 - ], - "492-sky": [ - 0, - 1, - 1 - ], - "494": [ - 0, - 1, - 1 - ], - "495": [ - 0, - 1, - 1 - ], - "496": [ - 0, - 1, - 1 - ], - "497": [ - 0, - 1, - 1 - ], - "517": [ - 0, - 1, - 1 - ], - "518": [ - 0, - 1, - 1 - ], - "524": [ - 0, - 1, - 1 - ], - "525": [ - 0, - 1, - 1 - ], - "526": [ - 0, - 1, - 1 - ], - "529": [ - 0, - 2, - 2 - ], - "530": [ - 0, - 1, - 2 - ], - "531": [ - 0, - 1, - 1 - ], - "531-mega": [ - 0, - 1, - 1 - ], - "532": [ - 0, - 1, - 1 - ], - "533": [ - 0, - 1, - 1 - ], - "534": [ - 0, - 1, - 1 - ], - "538": [ - 0, - 1, - 1 - ], - "539": [ - 0, - 2, - 2 - ], - "540": [ - 0, - 1, - 1 - ], - "541": [ - 0, - 1, - 1 - ], - "542": [ - 0, - 1, - 1 - ], - "543": [ - 0, - 1, - 1 - ], - "544": [ - 0, - 1, - 1 - ], - "545": [ - 0, - 1, - 1 - ], - "546": [ - 0, - 1, - 1 - ], - "547": [ - 0, - 1, - 1 - ], - "548": [ - 1, - 1, - 1 - ], - "549": [ - 0, - 1, - 1 - ], - "551": [ - 0, - 1, - 1 - ], - "552": [ - 0, - 1, - 1 - ], - "553": [ - 0, - 1, - 1 - ], - "556": [ - 0, - 1, - 1 - ], - "559": [ - 1, - 1, - 1 - ], - "560": [ - 1, - 1, - 1 - ], - "562": [ - 0, - 1, - 1 - ], - "563": [ - 0, - 1, - 1 - ], - "568": [ - 0, - 1, - 1 - ], - "569-gigantamax": [ - 0, - 1, - 1 - ], - "569": [ - 0, - 1, - 1 - ], - "570": [ - 0, - 1, - 1 - ], - "571": [ - 0, - 1, - 1 - ], - "572": [ - 0, - 1, - 1 - ], - "577": [ - 1, - 1, - 1 - ], - "578": [ - 1, - 1, - 1 - ], - "579": [ - 1, - 1, - 1 - ], - "585-autumn": [ - 2, - 0, - 0 - ], - "585-spring": [ - 2, - 0, - 0 - ], - "585-summer": [ - 1, - 0, - 0 - ], - "585-winter": [ - 2, - 0, - 0 - ], - "586-autumn": [ - 1, - 0, - 0 - ], - "586-spring": [ - 1, - 0, - 0 - ], - "586-summer": [ - 1, - 0, - 0 - ], - "586-winter": [ - 1, - 0, - 0 - ], - "592": [ - 0, - 1, - 2 - ], - "593": [ - 0, - 1, - 1 - ], - "594": [ - 0, - 1, - 2 - ], - "595": [ - 0, - 1, - 1 - ], - "596": [ - 0, - 1, - 1 - ], - "602": [ - 0, - 1, - 1 - ], - "603": [ - 0, - 1, - 1 - ], - "604": [ - 0, - 1, - 1 - ], - "605": [ - 1, - 1, - 1 - ], - "606": [ - 1, - 1, - 1 - ], - "607": [ - 0, - 1, - 1 - ], - "608": [ - 0, - 1, - 1 - ], - "609": [ - 0, - 1, - 1 - ], - "610": [ - 0, - 1, - 1 - ], - "611": [ - 0, - 1, - 1 - ], - "612": [ - 0, - 1, - 1 - ], - "618": [ - 0, - 2, - 2 - ], - "619": [ - 0, - 1, - 1 - ], - "620": [ - 0, - 1, - 1 - ], - "622": [ - 0, - 1, - 1 - ], - "623": [ - 0, - 1, - 1 - ], - "631": [ - 0, - 2, - 2 - ], - "632": [ - 0, - 1, - 1 - ], - "633": [ - 0, - 1, - 1 - ], - "634": [ - 0, - 1, - 1 - ], - "635": [ - 0, - 1, - 1 - ], - "636": [ - 0, - 1, - 1 - ], - "637": [ - 0, - 1, - 1 - ], - "640": [ - 0, - 1, - 1 - ], - "641-incarnate": [ - 0, - 0, - 0 - ], - "641-therian": [ - 0, - 0, - 0 - ], - "642-incarnate": [ - 0, - 0, - 0 - ], - "642-therian": [ - 0, - 0, - 0 - ], - "645-incarnate": [ - 0, - 0, - 0 - ], - "645-therian": [ - 0, - 0, - 0 - ], - "647-resolute": [ - 0, - 1, - 1 - ], - "647-ordinary": [ - 0, - 1, - 1 - ], - "648-aria": [ - 0, - 1, - 1 - ], - "648-pirouette": [ - 0, - 1, - 1 - ], - "649-burn": [ - 0, - 1, - 1 - ], - "649-chill": [ - 0, - 1, - 1 - ], - "649-douse": [ - 0, - 1, - 1 - ], - "649-shock": [ - 0, - 1, - 1 - ], - "649": [ - 0, - 1, - 1 - ], - "653": [ - 0, - 1, - 1 - ], - "654": [ - 0, - 1, - 1 - ], - "655": [ - 0, - 1, - 1 - ], - "664": [ - 0, - 1, - 1 - ], - "665": [ - 0, - 1, - 1 - ], - "666-archipelago": [ - 0, - 1, - 1 - ], - "666-continental": [ - 0, - 1, - 1 - ], - "666-elegant": [ - 0, - 1, - 1 - ], - "666-fancy": [ - 0, - 2, - 2 - ], - "666-garden": [ - 0, - 1, - 1 - ], - "666-high-plains": [ - 0, - 1, - 1 - ], - "666-icy-snow": [ - 0, - 1, - 1 - ], - "666-jungle": [ - 0, - 1, - 1 - ], - "666-marine": [ - 0, - 1, - 1 - ], - "666-meadow": [ - 0, - 1, - 1 - ], - "666-modern": [ - 0, - 1, - 1 - ], - "666-monsoon": [ - 0, - 1, - 1 - ], - "666-ocean": [ - 0, - 1, - 1 - ], - "666-poke-ball": [ - 0, - 1, - 1 - ], - "666-polar": [ - 0, - 1, - 1 - ], - "666-river": [ - 0, - 2, - 1 - ], - "666-sandstorm": [ - 0, - 1, - 1 - ], - "666-savanna": [ - 0, - 1, - 1 - ], - "666-sun": [ - 0, - 1, - 1 - ], - "666-tundra": [ - 0, - 1, - 1 - ], - "669-red": [ - 0, - 1, - 1 - ], - "669-blue": [ - 0, - 1, - 1 - ], - "669-white": [ - 0, - 1, - 1 - ], - "669-yellow": [ - 0, - 1, - 1 - ], - "669-orange": [ - 0, - 1, - 1 - ], - "670-white": [ - 0, - 1, - 1 - ], - "670-blue": [ - 0, - 1, - 1 - ], - "670-orange": [ - 0, - 1, - 1 - ], - "670-red": [ - 0, - 1, - 1 - ], - "670-yellow": [ - 0, - 1, - 1 - ], - "671-red": [ - 0, - 1, - 1 - ], - "671-blue": [ - 0, - 1, - 1 - ], - "671-yellow": [ - 0, - 1, - 1 - ], - "671-white": [ - 0, - 1, - 1 - ], - "671-orange": [ - 0, - 1, - 1 - ], - "672": [ - 0, - 1, - 1 - ], - "673": [ - 0, - 1, - 1 - ], - "677": [ - 0, - 1, - 1 - ], - "678-female": [ - 0, - 1, - 1 - ], - "678": [ - 0, - 1, - 1 - ], - "690": [ - 0, - 1, - 1 - ], - "691": [ - 0, - 1, - 1 - ], - "696": [ - 0, - 1, - 1 - ], - "697": [ - 0, - 1, - 1 - ], - "698": [ - 0, - 1, - 1 - ], - "699": [ - 0, - 1, - 1 - ], - "700": [ - 0, - 1, - 1 - ], - "702": [ - 0, - 1, - 1 - ], - "703": [ - 0, - 1, - 1 - ], - "704": [ - 0, - 1, - 1 - ], - "705": [ - 0, - 1, - 1 - ], - "706": [ - 0, - 1, - 1 - ], - "708": [ - 0, - 1, - 1 - ], - "709": [ - 0, - 1, - 1 - ], - "710": [ - 0, - 1, - 1 - ], - "711": [ - 1, - 1, - 1 - ], - "712": [ - 0, - 1, - 1 - ], - "713": [ - 0, - 1, - 1 - ], - "714": [ - 0, - 1, - 1 - ], - "715": [ - 0, - 2, - 2 - ], - "716-active": [ - 0, - 1, - 1 - ], - "716-neutral": [ - 0, - 1, - 1 - ], - "717": [ - 0, - 1, - 1 - ], - "720-unbound": [ - 1, - 1, - 1 - ], - "720": [ - 1, - 1, - 1 - ], - "728": [ - 0, - 1, - 1 - ], - "729": [ - 0, - 1, - 1 - ], - "730": [ - 0, - 1, - 1 - ], - "734": [ - 0, - 1, - 1 - ], - "735": [ - 0, - 1, - 1 - ], - "742": [ - 0, - 2, - 2 - ], - "743": [ - 0, - 2, - 2 - ], - "747": [ - 0, - 1, - 1 - ], - "748": [ - 0, - 1, - 1 - ], - "751": [ - 0, - 1, - 1 - ], - "752": [ - 0, - 1, - 1 - ], - "753": [ - 0, - 1, - 1 - ], - "754": [ - 0, - 2, - 2 - ], - "755": [ - 0, - 1, - 1 - ], - "756": [ - 0, - 1, - 1 - ], - "761": [ - 0, - 1, - 1 - ], - "762": [ - 0, - 1, - 1 - ], - "763": [ - 0, - 1, - 1 - ], - "767": [ - 0, - 1, - 1 - ], - "768": [ - 0, - 1, - 1 - ], - "771": [ - 0, - 1, - 1 - ], - "772": [ - 0, - 1, - 1 - ], - "773-fighting": [ - 0, - 1, - 1 - ], - "773-psychic": [ - 0, - 1, - 1 - ], - "773-poison": [ - 0, - 1, - 1 - ], - "773-ground": [ - 0, - 1, - 1 - ], - "773-ghost": [ - 0, - 1, - 1 - ], - "773-steel": [ - 0, - 1, - 1 - ], - "773-rock": [ - 0, - 1, - 1 - ], - "773-grass": [ - 0, - 1, - 1 - ], - "773-dragon": [ - 0, - 1, - 1 - ], - "773-bug": [ - 0, - 1, - 1 - ], - "773-ice": [ - 0, - 1, - 1 - ], - "773-dark": [ - 0, - 1, - 1 - ], - "773": [ - 0, - 1, - 1 - ], - "773-fairy": [ - 0, - 1, - 1 - ], - "773-water": [ - 0, - 1, - 1 - ], - "773-electric": [ - 0, - 1, - 1 - ], - "773-flying": [ - 0, - 1, - 1 - ], - "773-fire": [ - 0, - 1, - 1 - ], - "776": [ - 0, - 1, - 1 - ], - "777": [ - 0, - 1, - 1 - ], - "778-busted": [ - 0, - 1, - 1 - ], - "778-disguised": [ - 0, - 1, - 1 - ], - "779": [ - 0, - 1, - 1 - ], - "789": [ - 1, - 1, - 1 - ], - "790": [ - 0, - 1, - 1 - ], - "791-radiant-sun": [ - 0, - 1, - 1 - ], - "791": [ - 2, - 1, - 1 - ], - "792-full-moon": [ - 0, - 1, - 1 - ], - "792": [ - 0, - 1, - 1 - ], - "793": [ - 0, - 1, - 1 - ], - "797": [ - 0, - 1, - 1 - ], - "798": [ - 0, - 1, - 1 - ], - "800-dawn-wings": [ - 0, - 1, - 1 - ], - "800-dusk-mane": [ - 0, - 1, - 1 - ], - "800-ultra": [ - 0, - 1, - 1 - ], - "800": [ - 0, - 1, - 1 - ], - "802": [ - 1, - 1, - 1 - ], - "803": [ - 0, - 1, - 1 - ], - "804": [ - 0, - 1, - 1 - ], - "808": [ - 0, - 1, - 1 - ], - "809-gigantamax": [ - 0, - 1, - 1 - ], - "809": [ - 0, - 1, - 1 - ], - "816": [ - 0, - 1, - 1 - ], - "817": [ - 0, - 1, - 1 - ], - "818-gigantamax": [ - 1, - 1, - 1 - ], - "818": [ - 0, - 1, - 1 - ], - "821": [ - 0, - 1, - 1 - ], - "822": [ - 0, - 1, - 1 - ], - "823-gigantamax": [ - 0, - 2, - 2 - ], - "823": [ - 0, - 1, - 1 - ], - "829": [ - 0, - 1, - 1 - ], - "830": [ - 0, - 1, - 1 - ], - "835": [ - 0, - 1, - 1 - ], - "836": [ - 0, - 1, - 1 - ], - "850": [ - 0, - 1, - 1 - ], - "851-gigantamax": [ - 0, - 1, - 1 - ], - "851": [ - 0, - 1, - 1 - ], - "854": [ - 0, - 1, - 1 - ], - "855": [ - 0, - 1, - 1 - ], - "856": [ - 0, - 1, - 1 - ], - "857": [ - 0, - 2, - 2 - ], - "858-gigantamax": [ - 0, - 1, - 1 - ], - "858": [ - 0, - 1, - 1 - ], - "859": [ - 0, - 1, - 1 - ], - "860": [ - 0, - 1, - 1 - ], - "861-gigantamax": [ - 0, - 1, - 1 - ], - "861": [ - 0, - 1, - 1 - ], - "862": [ - 0, - 1, - 1 - ], - "863": [ - 0, - 1, - 1 - ], - "864": [ - 0, - 1, - 1 - ], - "867": [ - 0, - 1, - 1 - ], - "872": [ - 1, - 1, - 1 - ], - "873": [ - 1, - 1, - 1 - ], - "876-female": [ - 0, - 1, - 1 - ], - "876": [ - 0, - 1, - 1 - ], - "877-hangry": [ - 1, - 1, - 1 - ], - "877": [ - 1, - 1, - 1 - ], - "880": [ - 0, - 1, - 1 - ], - "881": [ - 0, - 2, - 2 - ], - "882": [ - 0, - 1, - 1 - ], - "883": [ - 0, - 1, - 1 - ], - "884-gigantamax": [ - 0, - 1, - 1 - ], - "884": [ - 0, - 1, - 1 - ], - "885": [ - 1, - 1, - 1 - ], - "886": [ - 1, - 1, - 1 - ], - "887": [ - 1, - 1, - 1 - ], - "888": [ - 0, - 1, - 1 - ], - "888-crowned": [ - 0, - 1, - 1 - ], - "889": [ - 0, - 1, - 1 - ], - "889-crowned": [ - 0, - 1, - 1 - ], - "890-eternamax": [ - 0, - 1, - 1 - ], - "890": [ - 0, - 1, - 1 - ], - "891": [ - 1, - 1, - 1 - ], - "892-gigantamax-rapid": [ - 1, - 2, - 2 - ], - "892-rapid-strike": [ - 1, - 1, - 1 - ], - "892": [ - 1, - 1, - 1 - ], - "892-gigantamax-single": [ - 1, - 2, - 2 - ], - "896": [ - 1, - 1, - 1 - ], - "897": [ - 1, - 1, - 1 - ], - "898": [ - 1, - 1, - 1 - ], - "898-ice": [ - 1, - 1, - 1 - ], - "898-shadow": [ - 1, - 1, - 1 - ], - "900": [ - 0, - 1, - 1 - ], - "901": [ - 0, - 1, - 1 - ], - "903": [ - 0, - 1, - 1 - ], - "909": [ - 0, - 1, - 1 - ], - "910": [ - 0, - 2, - 2 - ], - "911": [ - 0, - 1, - 1 - ], - "912": [ - 0, - 1, - 1 - ], - "913": [ - 0, - 1, - 1 - ], - "914": [ - 0, - 1, - 1 - ], - "919": [ - 1, - 1, - 1 - ], - "920": [ - 1, - 1, - 1 - ], - "924": [ - 1, - 1, - 1 - ], - "925-four": [ - 1, - 1, - 1 - ], - "925-three": [ - 1, - 1, - 1 - ], - "932": [ - 0, - 1, - 1 - ], - "933": [ - 0, - 1, - 1 - ], - "934": [ - 0, - 1, - 1 - ], - "935": [ - 2, - 2, - 2 - ], - "936": [ - 1, - 1, - 1 - ], - "937": [ - 1, - 1, - 1 - ], - "940": [ - 0, - 1, - 1 - ], - "941": [ - 0, - 1, - 1 - ], - "948": [ - 0, - 1, - 1 - ], - "949": [ - 0, - 1, - 1 - ], - "951": [ - 0, - 1, - 1 - ], - "952": [ - 0, - 1, - 1 - ], - "953": [ - 0, - 1, - 1 - ], - "954": [ - 0, - 1, - 1 - ], - "957": [ - 1, - 1, - 1 - ], - "958": [ - 1, - 1, - 1 - ], - "959": [ - 1, - 1, - 1 - ], - "962": [ - 1, - 1, - 1 - ], - "967": [ - 0, - 1, - 1 - ], - "968": [ - 0, - 1, - 1 - ], - "969": [ - 0, - 1, - 1 - ], - "970": [ - 0, - 1, - 1 - ], - "973": [ - 1, - 1, - 1 - ], - "974": [ - 0, - 1, - 1 - ], - "975": [ - 0, - 1, - 1 - ], - "978-curly": [ - 0, - 2, - 2 - ], - "978-droopy": [ - 0, - 2, - 2 - ], - "978-stretchy": [ - 0, - 1, - 1 - ], - "979": [ - 1, - 1, - 1 - ], - "981": [ - 0, - 1, - 1 - ], - "982": [ - 0, - 1, - 2 - ], - "982-three-segment": [ - 0, - 1, - 2 - ], - "987": [ - 1, - 1, - 1 - ], - "988": [ - 0, - 1, - 1 - ], - "993": [ - 0, - 1, - 1 - ], - "994": [ - 0, - 1, - 1 - ], - "995": [ - 0, - 1, - 1 - ], - "996": [ - 0, - 1, - 1 - ], - "997": [ - 0, - 1, - 1 - ], - "998": [ - 0, - 1, - 1 - ], - "999": [ - 1, - 1, - 1 - ], - "1000": [ - 1, - 1, - 1 - ], - "1001": [ - 0, - 1, - 1 - ], - "1003": [ - 0, - 1, - 1 - ], - "1004": [ - 0, - 1, - 1 - ], - "1006": [ - 0, - 2, - 1 - ], - "1007-apex-build": [ - 0, - 2, - 2 - ], - "1008-ultimate-mode": [ - 1, - 1, - 1 - ], - "1010": [ - 0, - 1, - 1 - ], - "1018": [ - 0, - 1, - 1 - ], - "1022": [ - 0, - 2, - 2 - ], - "1023": [ - 0, - 1, - 1 - ], - "2027": [ - 0, - 1, - 1 - ], - "2028": [ - 0, - 1, - 1 - ], - "2052": [ - 0, - 1, - 1 - ], - "2053": [ - 0, - 1, - 1 - ], - "2670": [ - 0, - 1, - 1 - ], - "4052": [ - 0, - 1, - 1 - ], - "4077": [ - 0, - 1, - 1 - ], - "4078": [ - 0, - 1, - 1 - ], - "4079": [ - 0, - 1, - 1 - ], - "4080": [ - 2, - 1, - 1 - ], - "4144": [ - 0, - 1, - 1 - ], - "4145": [ - 0, - 1, - 1 - ], - "4146": [ - 0, - 1, - 1 - ], - "4199": [ - 2, - 1, - 1 - ], - "4222": [ - 0, - 1, - 1 - ], - "4263": [ - 0, - 1, - 1 - ], - "4264": [ - 0, - 1, - 1 - ], - "4562": [ - 0, - 1, - 1 - ], - "6100": [ - 0, - 1, - 1 - ], - "6101": [ - 0, - 1, - 1 - ], - "6215": [ - 0, - 1, - 1 - ], - "6549": [ - 0, - 1, - 1 - ], - "6570": [ - 0, - 1, - 1 - ], - "6571": [ - 0, - 1, - 1 - ], - "6705": [ - 0, - 1, - 1 - ], - "6706": [ - 0, - 2, - 2 - ], - "6713": [ - 0, - 1, - 1 - ], - "8901": [ - 1, - 1, - 1 - ], + "1": [0, 1, 1], + "2": [0, 1, 1], + "3-gigantamax": [0, 1, 1], + "3-mega": [0, 2, 2], + "3": [0, 1, 1], + "4": [0, 1, 1], + "5": [0, 1, 1], + "6-mega-x": [0, 1, 2], + "6-gigantamax": [0, 1, 2], + "6-mega-y": [0, 1, 2], + "6": [0, 2, 2], + "7": [0, 2, 2], + "8": [0, 2, 2], + "9-gigantamax": [0, 1, 2], + "9-mega": [0, 2, 2], + "9": [0, 2, 2], + "19": [0, 1, 1], + "20": [0, 1, 1], + "23": [0, 1, 1], + "24": [0, 1, 1], + "25": [0, 1, 1], + "25-beauty-cosplay": [0, 1, 1], + "25-cool-cosplay": [0, 1, 1], + "25-cosplay": [0, 1, 1], + "25-cute-cosplay": [0, 1, 1], + "25-gigantamax": [0, 1, 1], + "25-partner": [0, 1, 1], + "25-smart-cosplay": [0, 1, 1], + "25-tough-cosplay": [0, 1, 1], + "26": [0, 1, 1], + "29": [0, 1, 1], + "30": [0, 1, 1], + "31": [1, 1, 1], + "35": [0, 1, 1], + "36": [0, 2, 1], + "37": [0, 1, 1], + "38": [0, 1, 1], + "39": [0, 1, 1], + "40": [0, 1, 1], + "41": [0, 1, 1], + "42": [0, 1, 1], + "43": [0, 1, 1], + "44": [0, 1, 1], + "45": [0, 1, 1], + "46": [1, 1, 1], + "47": [1, 1, 1], + "50": [0, 1, 1], + "51": [0, 1, 1], + "52-gigantamax": [1, 1, 1], + "52": [1, 1, 1], + "53": [1, 1, 1], + "56": [1, 1, 1], + "57": [1, 1, 1], + "69": [0, 1, 1], + "70": [0, 1, 1], + "71": [0, 1, 1], + "77": [0, 1, 1], + "78": [0, 1, 1], + "79": [1, 1, 1], + "80": [0, 1, 1], + "80-mega": [0, 1, 1], + "81": [0, 1, 1], + "82": [0, 1, 1], + "83": [0, 2, 2], + "84": [1, 1, 1], + "85": [1, 1, 1], + "86": [1, 1, 1], + "87": [1, 1, 1], + "92": [2, 2, 2], + "93": [1, 1, 1], + "94-gigantamax": [1, 1, 1], + "94-mega": [1, 1, 1], + "94": [1, 1, 1], + "98": [0, 1, 1], + "99": [0, 1, 1], + "99-gigantamax": [0, 1, 1], + "100": [0, 1, 1], + "101": [0, 1, 1], + "102": [0, 1, 1], + "103": [0, 1, 1], + "111": [0, 1, 1], + "112": [0, 1, 1], + "113": [1, 1, 1], + "114": [0, 1, 1], + "116": [0, 1, 1], + "117": [0, 1, 1], + "118": [1, 1, 1], + "119": [1, 1, 1], + "120": [0, 1, 1], + "121": [0, 1, 1], + "123": [1, 1, 1], + "125": [1, 1, 2], + "126": [0, 2, 1], + "127-mega": [0, 1, 1], + "127": [0, 1, 1], + "128": [0, 1, 1], + "129": [0, 1, 1], + "130-mega": [0, 1, 1], + "130": [0, 1, 1], + "131-gigantamax": [0, 1, 1], + "131": [0, 1, 1], + "132": [0, 1, 1], + "133": [0, 1, 1], + "133-partner": [0, 1, 1], + "134": [0, 1, 1], + "135": [1, 1, 1], + "136": [1, 1, 1], + "137": [0, 1, 1], + "138": [0, 1, 1], + "139": [0, 1, 1], + "140": [0, 1, 1], + "141": [0, 1, 1], + "142-mega": [0, 1, 1], + "142": [0, 1, 1], + "144": [1, 1, 1], + "145": [1, 1, 1], + "146": [1, 1, 1], + "147": [0, 1, 1], + "148": [0, 1, 1], + "149": [0, 1, 1], + "150-mega-x": [0, 1, 1], + "150-mega-y": [0, 1, 1], + "150": [0, 1, 1], + "151": [0, 1, 1], + "152": [0, 1, 1], + "153": [0, 1, 1], + "154": [0, 1, 1], + "158": [0, 1, 1], + "159": [0, 1, 1], + "160": [0, 1, 1], + "161": [0, 1, 1], + "162": [0, 1, 1], + "163": [0, 1, 1], + "164": [0, 1, 1], + "167": [0, 1, 1], + "168": [0, 1, 1], + "169": [0, 1, 1], + "170": [0, 1, 1], + "171": [0, 1, 1], + "172": [0, 1, 1], + "172-spiky": [0, 1, 1], + "173": [0, 1, 1], + "174": [0, 1, 1], + "175": [1, 1, 1], + "176": [1, 1, 1], + "177": [0, 1, 1], + "178": [0, 2, 2], + "179": [0, 1, 1], + "180": [0, 1, 2], + "181-mega": [0, 1, 2], + "181": [0, 1, 1], + "182": [0, 1, 1], + "183": [0, 1, 1], + "184": [0, 1, 1], + "185": [0, 1, 1], + "190": [0, 1, 1], + "193": [0, 1, 1], + "194": [0, 1, 1], + "195": [0, 1, 1], + "196": [1, 1, 1], + "197": [0, 1, 1], + "198": [0, 1, 1], + "199": [2, 1, 1], + "200": [1, 2, 2], + "201-m": [0, 1, 1], + "201-question": [0, 1, 1], + "201-j": [0, 1, 1], + "201-l": [0, 1, 1], + "201-h": [0, 1, 1], + "201-x": [0, 1, 1], + "201-exclamation": [0, 1, 1], + "201-q": [0, 1, 1], + "201-s": [0, 1, 1], + "201-c": [0, 1, 1], + "201-u": [0, 1, 1], + "201-t": [0, 1, 1], + "201-z": [0, 1, 1], + "201-d": [0, 1, 1], + "201-b": [0, 1, 1], + "201-g": [0, 1, 1], + "201-k": [0, 1, 1], + "201-i": [0, 1, 1], + "201-p": [0, 1, 1], + "201-e": [0, 1, 1], + "201-y": [0, 1, 1], + "201-r": [0, 1, 1], + "201-f": [0, 1, 1], + "201-n": [0, 1, 1], + "201-v": [0, 1, 1], + "201-a": [0, 1, 1], + "201-w": [0, 1, 1], + "201-o": [0, 1, 1], + "203": [0, 1, 1], + "206": [0, 1, 1], + "207": [0, 1, 1], + "211": [0, 1, 1], + "212-mega": [1, 2, 1], + "212": [1, 1, 1], + "213": [0, 1, 1], + "215": [0, 1, 1], + "216": [1, 1, 1], + "217": [1, 1, 1], + "222": [0, 1, 1], + "226": [0, 1, 1], + "227": [0, 1, 1], + "228": [0, 1, 1], + "229": [0, 1, 1], + "229-mega": [0, 1, 1], + "230": [0, 1, 1], + "231": [0, 1, 1], + "232": [0, 1, 1], + "233": [0, 1, 1], + "235": [0, 1, 1], + "239": [1, 1, 2], + "240": [0, 1, 1], + "242": [1, 1, 1], + "243": [0, 1, 1], + "244": [0, 2, 2], + "245": [0, 1, 1], + "246": [0, 1, 1], + "247": [0, 1, 1], + "248": [0, 1, 1], + "248-mega": [0, 1, 1], + "249": [0, 1, 1], + "250": [0, 1, 1], + "251": [0, 1, 1], + "255": [0, 1, 1], + "256": [0, 1, 1], + "257": [0, 1, 1], + "257-mega": [0, 1, 1], + "261": [0, 1, 1], + "262": [0, 1, 1], + "263": [0, 1, 1], + "264": [0, 1, 1], + "276": [0, 1, 1], + "277": [0, 1, 1], + "278": [1, 1, 1], + "279": [1, 1, 1], + "280": [0, 1, 1], + "281": [0, 1, 1], + "282-mega": [0, 1, 1], + "282": [0, 1, 1], + "285": [0, 1, 1], + "286": [0, 1, 1], + "290": [1, 1, 1], + "291": [2, 2, 2], + "292": [2, 2, 2], + "298": [0, 1, 1], + "300": [1, 1, 1], + "301": [1, 1, 1], + "302": [0, 1, 1], + "302-mega": [0, 1, 1], + "303-mega": [1, 1, 1], + "303": [1, 1, 1], + "304": [1, 1, 1], + "305": [1, 1, 1], + "306-mega": [1, 1, 1], + "306": [1, 1, 1], + "307": [0, 1, 1], + "308-mega": [0, 1, 1], + "308": [0, 1, 1], + "309": [0, 1, 1], + "310-mega": [0, 1, 1], + "310": [0, 1, 1], + "311": [1, 1, 1], + "312": [0, 1, 1], + "315": [0, 1, 1], + "320": [0, 1, 1], + "321": [0, 1, 1], + "327": [0, 1, 1], + "328": [0, 1, 1], + "329": [0, 1, 1], + "330": [0, 1, 1], + "333": [0, 1, 1], + "334-mega": [0, 1, 1], + "334": [0, 1, 1], + "335": [0, 2, 2], + "336": [0, 1, 1], + "337": [0, 1, 1], + "338": [0, 1, 1], + "339": [0, 2, 1], + "340": [0, 1, 2], + "341": [0, 1, 1], + "342": [0, 2, 2], + "351-rainy": [1, 1, 1], + "351-snowy": [1, 1, 1], + "351-sunny": [1, 1, 2], + "351": [0, 1, 1], + "352": [1, 1, 1], + "353": [0, 1, 1], + "354": [0, 1, 1], + "354-mega": [0, 1, 1], + "357": [0, 1, 1], + "358": [1, 1, 1], + "359": [0, 1, 1], + "359-mega": [0, 1, 1], + "361": [0, 1, 1], + "362": [0, 1, 1], + "362-mega": [0, 1, 1], + "369": [0, 2, 2], + "370": [0, 2, 2], + "371": [0, 1, 1], + "372": [0, 1, 1], + "373-mega": [0, 1, 1], + "373": [0, 1, 1], + "374": [0, 1, 1], + "375": [0, 1, 1], + "376-mega": [0, 1, 1], + "376": [0, 1, 1], + "377": [0, 1, 1], + "378": [1, 1, 1], + "379": [0, 1, 1], + "380-mega": [0, 1, 1], + "380": [0, 1, 1], + "381-mega": [0, 1, 1], + "381": [0, 1, 1], + "382-primal": [0, 1, 1], + "382": [0, 1, 1], + "383-primal": [0, 1, 1], + "383": [0, 1, 1], + "384-mega": [0, 1, 1], + "384": [0, 1, 1], + "385": [1, 1, 1], + "387": [0, 2, 1], + "388": [0, 1, 1], + "389": [0, 1, 1], + "390": [0, 1, 1], + "391": [0, 1, 1], + "392": [0, 1, 1], + "393": [0, 1, 1], + "394": [0, 1, 1], + "395": [0, 1, 1], + "399": [0, 2, 1], + "400": [0, 1, 1], + "401": [0, 1, 1], + "402": [0, 1, 1], + "406": [0, 1, 1], + "407": [0, 1, 1], + "412-sandy": [2, 2, 2], + "412-plant": [1, 1, 1], + "412-trash": [1, 1, 1], + "413-plant": [1, 1, 1], + "413-trash": [1, 1, 1], + "413-sandy": [1, 1, 1], + "414": [0, 1, 1], + "418": [0, 1, 1], + "419": [0, 1, 1], + "422-west": [1, 1, 1], + "422-east": [1, 1, 1], + "423-west": [1, 1, 1], + "423-east": [1, 1, 1], + "424": [0, 1, 1], + "425": [0, 1, 1], + "426": [0, 1, 1], + "427": [0, 1, 1], + "428-mega": [0, 1, 1], + "428": [0, 1, 1], + "429": [1, 1, 1], + "430": [0, 1, 1], + "433": [1, 1, 1], + "436": [0, 1, 1], + "437": [0, 1, 1], + "438": [0, 1, 1], + "440": [1, 1, 1], + "441": [0, 1, 2], + "442": [0, 1, 1], + "443": [1, 1, 1], + "444": [1, 1, 1], + "445-mega": [1, 1, 1], + "445": [1, 1, 1], + "447": [1, 1, 1], + "448-mega": [1, 1, 1], + "448": [1, 1, 1], + "453": [0, 1, 1], + "454": [0, 1, 1], + "455": [0, 1, 1], + "456": [0, 1, 1], + "457": [0, 2, 1], + "458": [0, 2, 2], + "461": [0, 1, 1], + "462": [0, 1, 1], + "464": [0, 1, 1], + "465": [0, 1, 1], + "466": [2, 1, 1], + "467": [0, 1, 1], + "468": [1, 1, 1], + "469": [0, 1, 1], + "470": [2, 2, 1], + "471": [1, 1, 1], + "472": [0, 1, 1], + "474": [0, 1, 1], + "475-mega": [0, 2, 2], + "475": [0, 1, 1], + "478": [0, 2, 1], + "479-heat": [0, 1, 1], + "479-wash": [0, 1, 1], + "479-mow": [0, 1, 1], + "479-frost": [0, 1, 1], + "479": [0, 1, 1], + "479-fan": [0, 1, 1], + "480": [1, 1, 1], + "481": [1, 1, 1], + "482": [1, 1, 1], + "485": [0, 1, 1], "486": [0, 1 , 1 + ] ,"487-altered": [0, 1, 1], + "487-origin": [0, 1, 1], + "488": [0, 1, 1], + "489": [1, 1, 1], + "490": [1, 1, 1], + "491": [0, 1, 1], + "492-land": [0, 1, 1], + "492-sky": [0, 1, 1], + "494": [0, 1, 1], + "495": [0, 1, 1], + "496": [0, 1, 1], + "497": [0, 1, 1], + "501": [0, 1, 1], + "502": [0, 1, 1], + "503": [0, 1, 1], + "517": [0, 1, 1], + "518": [0, 1, 1], + "524": [0, 1, 1], + "525": [0, 1, 1], + "526": [0, 1, 1], + "527": [0, 1, 1], + "528": [0, 1, 1], + "529": [0, 2, 2], + "530": [0, 1, 2], + "531": [0, 1, 1], + "531-mega": [0, 1, 1], + "532": [0, 1, 1], + "533": [0, 1, 1], + "534": [0, 1, 1], + "538": [0, 1, 1], + "539": [0, 2, 2], + "540": [0, 1, 1], + "541": [0, 1, 1], + "542": [0, 1, 1], + "543": [0, 1, 1], + "544": [0, 1, 1], + "545": [0, 1, 1], + "546": [0, 1, 1], + "547": [0, 1, 1], + "548": [1, 1, 1], + "549": [0, 1, 1], + "551": [0, 1, 1], + "552": [0, 1, 1], + "553": [0, 1, 1], + "556": [0, 1, 1], + "559": [1, 1, 1], + "560": [1, 1, 1], + "562": [0, 1, 1], + "563": [0, 1, 1], + "568": [0, 1, 1], + "569-gigantamax": [0, 1, 1], + "569": [0, 1, 1], + "570": [0, 1, 1], + "571": [0, 1, 1], + "572": [0, 1, 1], + "577": [1, 1, 1], + "578": [1, 1, 1], + "579": [1, 1, 1], + "585-autumn": [2, 0, 0], + "585-spring": [2, 0, 0], + "585-summer": [1, 0, 0], + "585-winter": [2, 0, 0], + "586-autumn": [1, 0, 0], + "586-spring": [1, 0, 0], + "586-summer": [1, 0, 0], + "586-winter": [1, 0, 0], + "587": [0, 1, 1], + "588": [0, 1, 1], + "589": [0, 1, 1], + "590": [0, 1, 1], + "591": [0, 1, 1], + "592": [0, 1, 2], + "593": [0, 1, 1], + "594": [0, 1, 2], + "595": [0, 1, 1], + "596": [0, 1, 1], + "602": [0, 1, 1], + "603": [0, 1, 1], + "604": [0, 1, 1], + "605": [1, 1, 1], + "606": [1, 1, 1], + "607": [0, 1, 1], + "608": [0, 1, 1], + "609": [0, 1, 1], + "610": [0, 1, 1], + "611": [0, 1, 1], + "612": [0, 1, 1], + "616": [0, 1, 1], + "617": [0, 1, 1], + "618": [0, 2, 2], + "619": [0, 1, 1], + "620": [0, 1, 1], + "621": [0, 1, 1], + "622": [0, 1, 1], + "623": [0, 1, 1], + "631": [0, 2, 2], + "632": [0, 1, 1], + "633": [0, 1, 1], + "634": [0, 1, 1], + "635": [0, 1, 1], + "636": [0, 1, 1], + "637": [0, 1, 1], + "640": [0, 1, 1], + "641-incarnate": [0, 0, 0], + "641-therian": [0, 0, 0], + "642-incarnate": [0, 0, 0], + "642-therian": [0, 0, 0], + "645-incarnate": [0, 0, 0], + "645-therian": [0, 0, 0], + "647-resolute": [0, 1, 1], + "647-ordinary": [0, 1, 1], + "648-aria": [0, 1, 1], + "648-pirouette": [0, 1, 1], + "649-burn": [0, 1, 1], + "649-chill": [0, 1, 1], + "649-douse": [0, 1, 1], + "649-shock": [0, 1, 1], + "649": [0, 1, 1], + "653": [0, 1, 1], + "654": [0, 1, 1], + "655": [0, 1, 1], + "656": [0, 1, 1], + "657": [0, 1, 1], + "658": [0, 1, 1], + "658-ash": [0, 1, 1], + "664": [0, 1, 1], + "665": [0, 1, 1], + "666-archipelago": [0, 1, 1], + "666-continental": [0, 1, 1], + "666-elegant": [0, 1, 1], + "666-fancy": [0, 2, 2], + "666-garden": [0, 1, 1], + "666-high-plains": [0, 1, 1], + "666-icy-snow": [0, 1, 1], + "666-jungle": [0, 1, 1], + "666-marine": [0, 1, 1], + "666-meadow": [0, 1, 1], + "666-modern": [0, 1, 1], + "666-monsoon": [0, 1, 1], + "666-ocean": [0, 1, 1], + "666-poke-ball": [0, 1, 1], + "666-polar": [0, 1, 1], + "666-river": [0, 2, 1], + "666-sandstorm": [0, 1, 1], + "666-savanna": [0, 1, 1], + "666-sun": [0, 1, 1], + "666-tundra": [0, 1, 1], + "669-red": [0, 1, 1], + "669-blue": [0, 1, 1], + "669-white": [0, 1, 1], + "669-yellow": [0, 1, 1], + "669-orange": [0, 1, 1], + "670-white": [0, 1, 1], + "670-blue": [0, 1, 1], + "670-orange": [0, 1, 1], + "670-red": [0, 1, 1], + "670-yellow": [0, 1, 1], + "671-red": [0, 1, 1], + "671-blue": [0, 1, 1], + "671-yellow": [0, 1, 1], + "671-white": [0, 1, 1], + "671-orange": [0, 1, 1], + "672": [0, 1, 1], + "673": [0, 1, 1], + "676": [0, 1, 1], + "676-dandy": [0, 1, 1], + "676-debutante": [0, 1, 1], + "676-diamond": [0, 1, 1], + "676-heart": [0, 1, 1], + "676-kabuki": [0, 1, 1], + "676-la-reine": [0, 1, 1], + "676-matron": [0, 1, 1], + "676-pharaoh": [0, 1, 1], + "676-star": [0, 1, 1], + "677": [0, 1, 1], + "678-female": [0, 1, 1], + "678": [0, 1, 1], + "682": [0, 1, 1], + "683": [0, 1, 1], + "684": [0, 1, 1], + "685": [0, 1, 1], + "688": [0, 1, 1], + "689": [0, 1, 1], + "690": [0, 1, 1], + "691": [0, 1, 1], + "696": [0, 1, 1], + "697": [0, 1, 1], + "698": [0, 1, 1], + "699": [0, 1, 1], + "700": [0, 1, 1], + "702": [0, 1, 1], + "703": [0, 1, 1], + "704": [0, 1, 1], + "705": [0, 1, 1], + "706": [0, 1, 1], + "708": [0, 1, 1], + "709": [0, 1, 1], + "710": [0, 1, 1], + "711": [1, 1, 1], + "712": [0, 1, 1], + "713": [0, 1, 1], + "714": [0, 1, 1], + "715": [0, 2, 2], + "716-active": [0, 1, 1], + "716-neutral": [0, 1, 1], + "717": [0, 1, 1], + "720-unbound": [1, 1, 1], + "720": [1, 1, 1], + "728": [0, 1, 1], + "729": [0, 1, 1], + "730": [0, 1, 1], + "734": [0, 1, 1], + "735": [0, 1, 1], + "742": [0, 2, 2], + "743": [0, 2, 2], + "747": [0, 1, 1], + "748": [0, 1, 1], + "751": [0, 1, 1], + "752": [0, 1, 1], + "753": [0, 1, 1], + "754": [0, 2, 2], + "755": [0, 1, 1], + "756": [0, 1, 1], + "761": [0, 1, 1], + "762": [0, 1, 1], + "763": [0, 1, 1], + "767": [0, 1, 1], + "768": [0, 1, 1], + "771": [0, 1, 1], + "772": [0, 1, 1], + "773-fighting": [0, 1, 1], + "773-psychic": [0, 1, 1], + "773-poison": [0, 1, 1], + "773-ground": [0, 1, 1], + "773-ghost": [0, 1, 1], + "773-steel": [0, 1, 1], + "773-rock": [0, 1, 1], + "773-grass": [0, 1, 1], + "773-dragon": [0, 1, 1], + "773-bug": [0, 1, 1], + "773-ice": [0, 1, 1], + "773-dark": [0, 1, 1], + "773": [0, 1, 1], + "773-fairy": [0, 1, 1], + "773-water": [0, 1, 1], + "773-electric": [0, 1, 1], + "773-flying": [0, 1, 1], + "773-fire": [0, 1, 1], + "776": [0, 1, 1], + "777": [0, 1, 1], + "778-busted": [0, 1, 1], + "778-disguised": [0, 1, 1], + "779": [0, 1, 1], + "789": [1, 1, 1], + "790": [0, 1, 1], + "791-radiant-sun": [0, 1, 1], + "791": [2, 1, 1], + "792-full-moon": [0, 1, 1], + "792": [0, 1, 1], + "793": [0, 1, 1], + "797": [0, 1, 1], + "798": [0, 1, 1], + "800-dawn-wings": [0, 1, 1], + "800-dusk-mane": [0, 1, 1], + "800-ultra": [0, 1, 1], + "800": [0, 1, 1], + "802": [1, 1, 1], + "803": [0, 1, 1], + "804": [0, 1, 1], + "807": [0, 1, 1], + "808": [0, 1, 1], + "809-gigantamax": [0, 1, 1], + "809": [0, 1, 1], + "816": [0, 1, 1], + "817": [0, 1, 1], + "818-gigantamax": [1, 1, 1], + "818": [0, 1, 1], + "821": [0, 1, 1], + "822": [0, 1, 1], + "823-gigantamax": [0, 2, 2], + "823": [0, 1, 1], + "829": [0, 1, 1], + "830": [0, 1, 1], + "835": [0, 1, 1], + "836": [0, 1, 1], + "850": [0, 1, 1], + "851-gigantamax": [0, 1, 1], + "851": [0, 1, 1], + "854": [0, 1, 1], + "855": [0, 1, 1], + "856": [0, 1, 1], + "857": [0, 2, 2], + "858-gigantamax": [0, 1, 1], + "858": [0, 1, 1], + "859": [0, 1, 1], + "860": [0, 1, 1], + "861-gigantamax": [0, 1, 1], + "861": [0, 1, 1], + "862": [0, 1, 1], + "863": [0, 1, 1], + "864": [0, 1, 1], + "867": [0, 1, 1], + "872": [1, 1, 1], + "873": [1, 1, 1], + "876-female": [0, 1, 1], + "876": [0, 1, 1], + "877-hangry": [1, 1, 1], + "877": [1, 1, 1], + "880": [0, 1, 1], + "881": [0, 2, 2], + "882": [0, 1, 1], + "883": [0, 1, 1], + "884-gigantamax": [0, 1, 1], + "884": [0, 1, 1], + "885": [1, 1, 1], + "886": [1, 1, 1], + "887": [1, 1, 1], + "888": [0, 1, 1], + "888-crowned": [0, 1, 1], + "889": [0, 1, 1], + "889-crowned": [0, 1, 1], + "890-eternamax": [0, 1, 1], + "890": [0, 1, 1], + "891": [1, 1, 1], + "892-gigantamax-rapid": [1, 2, 2], + "892-rapid-strike": [1, 1, 1], + "892": [1, 1, 1], + "892-gigantamax-single": [1, 2, 2], + "894": [0, 1, 1], + "895": [0, 1, 1], + "896": [1, 1, 1], + "897": [1, 1, 1], + "898": [1, 1, 1], + "898-ice": [1, 1, 1], + "898-shadow": [1, 1, 1], + "900": [0, 1, 1], + "901": [0, 1, 1], + "903": [0, 1, 1], + "909": [0, 1, 1], + "910": [0, 2, 2], + "911": [0, 1, 1], + "912": [0, 1, 1], + "913": [0, 1, 1], + "914": [0, 1, 1], + "919": [1, 1, 1], + "920": [1, 1, 1], + "924": [1, 1, 1], + "925-four": [1, 1, 1], + "925-three": [1, 1, 1], + "932": [0, 1, 1], + "933": [0, 1, 1], + "934": [0, 1, 1], + "935": [2, 2, 2], + "936": [1, 1, 1], + "937": [1, 1, 1], + "940": [0, 1, 1], + "941": [0, 1, 1], + "944": [0, 1, 1], + "945": [0, 1, 1], + "948": [0, 1, 1], + "949": [0, 1, 1], + "951": [0, 1, 1], + "952": [0, 1, 1], + "953": [0, 1, 1], + "954": [0, 1, 1], + "957": [1, 1, 1], + "958": [1, 1, 1], + "959": [1, 1, 1], + "962": [1, 1, 1], + "967": [0, 1, 1], + "968": [0, 1, 1], + "969": [0, 1, 1], + "970": [0, 1, 1], + "973": [1, 1, 1], + "974": [0, 1, 1], + "975": [0, 1, 1], + "978-curly": [0, 2, 2], + "978-droopy": [0, 2, 2], + "978-stretchy": [0, 1, 1], + "979": [1, 1, 1], + "981": [0, 1, 1], + "982": [0, 1, 2], + "982-three-segment": [0, 1, 2], + "987": [1, 1, 1], + "988": [0, 1, 1], + "993": [0, 1, 1], + "994": [0, 1, 1], + "995": [0, 1, 1], + "996": [0, 1, 1], + "997": [0, 1, 1], + "998": [0, 1, 1], + "999": [1, 1, 1], + "1000": [1, 1, 1], + "1001": [0, 1, 1], + "1003": [0, 1, 1], + "1004": [0, 1, 1], + "1006": [0, 2, 1], + "1007-apex-build": [0, 2, 2], + "1008-ultimate-mode": [1, 1, 1], + "1010": [0, 1, 1], + "1012-counterfeit": [0, 1, 1], + "1013-unremarkable": [0, 1, 1], + "1018": [0, 1, 1], + "1022": [0, 2, 2], + "1023": [0, 1, 1], + "2026": [0, 1, 1], + "2027": [0, 1, 1], + "2028": [0, 1, 1], + "2052": [0, 1, 1], + "2053": [0, 1, 1], + "2103": [0, 1, 1], + "2670": [0, 1, 1], + "4052": [0, 1, 1], + "4077": [0, 1, 1], + "4078": [0, 1, 1], + "4079": [0, 1, 1], + "4080": [2, 1, 1], + "4144": [0, 1, 1], + "4145": [0, 1, 1], + "4146": [0, 1, 1], + "4199": [2, 1, 1], + "4222": [0, 1, 1], + "4263": [0, 1, 1], + "4264": [0, 1, 1], + "4562": [0, 1, 1], + "6100": [0, 1, 1], + "6101": [0, 1, 1], + "6215": [0, 1, 1], + "6503": [0, 1, 1], + "6549": [0, 1, 1], + "6570": [0, 1, 1], + "6571": [0, 1, 1], + "6705": [0, 1, 1], + "6706": [0, 1, 1], + "6713": [0, 1, 1], + "8901": [1, 1, 1], "female": { - "3": [ - 0, - 1, - 1 - ], - "19": [ - 0, - 1, - 1 - ], - "20": [ - 0, - 1, - 1 - ], - "41": [ - 0, - 1, - 1 - ], - "42": [ - 0, - 1, - 1 - ], - "44": [ - 0, - 1, - 1 - ], - "45": [ - 0, - 1, - 1 - ], - "84": [ - 1, - 1, - 1 - ], - "85": [ - 1, - 1, - 1 - ], - "111": [ - 0, - 1, - 1 - ], - "112": [ - 0, - 1, - 1 - ], - "118": [ - 0, - 1, - 1 - ], - "119": [ - 0, - 1, - 1 - ], - "123": [ - 1, - 1, - 1 - ], - "129": [ - 0, - 1, - 1 - ], - "130": [ - 0, - 1, - 1 - ], - "178": [ - 0, - 2, - 2 - ], - "185": [ - 0, - 1, - 1 - ], - "190": [ - 0, - 1, - 1 - ], - "203": [ - 0, - 1, - 1 - ], - "207": [ - 0, - 1, - 1 - ], - "215": [ - 0, - 1, - 1 - ], - "217": [ - 1, - 1, - 1 - ], - "229": [ - 0, - 1, - 1 - ], - "232": [ - 0, - 1, - 1 - ], - "255": [ - 0, - 1, - 1 - ], - "256": [ - 0, - 1, - 1 - ], - "257": [ - 0, - 1, - 1 - ], - "307": [ - 0, - 1, - 1 - ], - "308": [ - 0, - 1, - 1 - ], - "315": [ - 0, - 1, - 1 - ], - "369": [ - 0, - 1, - 1 - ], - "399": [ - 0, - 2, - 1 - ], - "400": [ - 0, - 1, - 1 - ], - "401": [ - 0, - 1, - 1 - ], - "402": [ - 0, - 1, - 1 - ], - "407": [ - 0, - 1, - 1 - ], - "418": [ - 0, - 2, - 2 - ], - "419": [ - 0, - 1, - 1 - ], - "424": [ - 0, - 1, - 1 - ], - "443": [ - 1, - 1, - 1 - ], - "444": [ - 1, - 1, - 1 - ], - "445": [ - 1, - 1, - 1 - ], - "453": [ - 0, - 1, - 1 - ], - "454": [ - 0, - 1, - 1 - ], - "456": [ - 0, - 1, - 1 - ], - "457": [ - 0, - 1, - 1 - ], - "461": [ - 0, - 1, - 1 - ], - "464": [ - 0, - 1, - 1 - ], - "465": [ - 0, - 1, - 1 - ], - "592": [ - 1, - 1, - 1 - ], - "593": [ - 1, - 1, - 1 - ], - "6215": [ - 0, - 1, - 1 - ] + "3": [0,1, 1], + "19": [0, 1, 1], + "20": [0, 1, 1], + "25": [0, 1, 1], + "25-beauty-cosplay": [0, 1, 1], + "25-cool-cosplay": [0, 1, 1], + "25-cosplay": [0, 1, 1], + "25-cute-cosplay": [0, 1, 1], + "25-partner": [0, 1, 1], + "25-smart-cosplay": [0, 1, 1], + "25-tough-cosplay": [0, 1, 1], + "26": [0, 1, 1], + "41": [0, 1, 1], + "42": [0, 1, 1], + "44": [0, 1, 1], + "45": [0, 1, 1], + "84": [1, 1, 1], + "85": [1, 1, 1], + "111": [0, 1, 1], + "112": [0, 1, 1], + "118": [0, 1, 1], + "119": [0, 1, 1], + "123": [1, 1, 1], + "129": [0, 1, 1], + "130": [0, 1, 1], + "154": [0, 1, 1], + "178": [0, 2, 2], + "185": [0, 1, 1], + "190": [0, 1, 1], + "194": [0, 1, 1], + "195": [0, 1, 1], + "198": [0, 1, 1], + "203": [0, 1, 1], + "207": [0, 1, 1], + "215": [0, 1, 1], + "217": [1, 1, 1], + "229": [0, 1, 1], + "232": [0, 1, 1], + "255": [0, 1, 1], + "256": [0, 1, 1], + "257": [0, 1, 1], + "307": [0, 1, 1], + "308": [0, 1, 1], + "315": [0, 1, 1], + "369": [0, 1, 1], + "399": [0, 2, 1], + "400": [0, 1, 1], + "401": [0, 1, 1], + "402": [0, 1, 1], + "407": [0, 1, 1], + "418": [0, 2, 2], + "419": [0, 1, 1], + "424": [0, 1, 1], + "443": [1, 1, 1], + "444": [1, 1, 1], + "445": [1, 1, 1], + "453": [0, 1, 1], + "454": [0, 1, 1], + "456": [0, 1, 1], + "457": [0, 1, 1], + "461": [0, 1, 1], + "464": [0, 1, 1], + "465": [0, 1, 1], + "592": [1, 1, 1], + "593": [1, 1, 1], + "6215": [0, 1, 1] } }, "exp": { - "3-mega": [ - 0, - 2, - 2 - ], - "6-mega-x": [ - 0, - 2, - 2 - ], - "6-mega-y": [ - 0, - 2, - 2 - ], - "80-mega": [ - 0, - 1, - 1 - ], - "94-mega": [ - 2, - 2, - 2 - ], - "127-mega": [ - 0, - 1, - 1 - ], - "130-mega": [ - 0, - 1, - 1 - ], - "142-mega": [ - 0, - 1, - 1 - ], - "150-mega-x": [ - 0, - 1, - 1 - ], - "150-mega-y": [ - 0, - 1, - 1 - ], - "181-mega": [ - 0, - 1, - 2 - ], - "212-mega": [ - 1, - 1, - 2 - ], - "229-mega": [ - 0, - 1, - 1 - ], - "248-mega": [ - 0, - 1, - 1 - ], - "257-mega": [ - 0, - 1, - 1 - ], - "282-mega": [ - 0, - 2, - 2 - ], - "302-mega": [ - 0, - 1, - 1 - ], - "303-mega": [ - 0, - 1, - 1 - ], - "306-mega": [ - 1, - 1, - 1 - ], - "308-mega": [ - 0, - 1, - 1 - ], - "310-mega": [ - 0, - 1, - 1 - ], - "334-mega": [ - 0, - 2, - 1 - ], - "354-mega": [ - 0, - 1, - 1 - ], - "362-mega": [ - 0, - 1, - 1 - ], - "373-mega": [ - 0, - 1, - 1 - ], - "376-mega": [ - 0, - 1, - 1 - ], - "380-mega": [ - 0, - 1, - 1 - ], - "381-mega": [ - 0, - 1, - 1 - ], - "382-primal": [ - 0, - 1, - 1 - ], - "383-primal": [ - 0, - 1, - 1 - ], - "384-mega": [ - 0, - 2, - 1 - ], - "428-mega": [ - 0, - 1, - 1 - ], - "445-mega": [ - 1, - 1, - 1 - ], - "448-mega": [ - 1, - 1, - 1 - ], - "475-mega": [ - 0, - 2, - 2 - ], - "531-mega": [ - 0, - 1, - 1 - ], - "653": [ - 0, - 1, - 1 - ], - "654": [ - 0, - 1, - 1 - ], - "655": [ - 0, - 1, - 1 - ], - "664": [ - 0, - 1, - 1 - ], - "665": [ - 0, - 1, - 1 - ], - "666-archipelago": [ - 0, - 1, - 1 - ], - "666-continental": [ - 0, - 1, - 1 - ], - "666-elegant": [ - 0, - 1, - 1 - ], - "666-fancy": [ - 0, - 2, - 2 - ], - "666-garden": [ - 0, - 1, - 1 - ], - "666-high-plains": [ - 0, - 1, - 1 - ], - "666-icy-snow": [ - 0, - 1, - 1 - ], - "666-jungle": [ - 0, - 1, - 1 - ], - "666-marine": [ - 0, - 1, - 1 - ], - "666-meadow": [ - 0, - 2, - 2 - ], - "666-modern": [ - 0, - 1, - 1 - ], - "666-monsoon": [ - 0, - 1, - 1 - ], - "666-ocean": [ - 0, - 1, - 1 - ], - "666-poke-ball": [ - 0, - 1, - 2 - ], - "666-polar": [ - 0, - 1, - 1 - ], - "666-river": [ - 0, - 2, - 1 - ], - "666-sandstorm": [ - 0, - 1, - 1 - ], - "666-savanna": [ - 0, - 1, - 1 - ], - "666-sun": [ - 0, - 1, - 1 - ], - "666-tundra": [ - 0, - 1, - 1 - ], - "669-red": [ - 0, - 2, - 2 - ], - "669-blue": [ - 0, - 1, - 1 - ], - "669-white": [ - 0, - 1, - 1 - ], - "669-yellow": [ - 0, - 1, - 1 - ], - "669-orange": [ - 0, - 2, - 2 - ], - "670-white": [ - 0, - 1, - 1 - ], - "670-blue": [ - 0, - 1, - 1 - ], - "670-orange": [ - 0, - 1, - 1 - ], - "670-red": [ - 0, - 1, - 1 - ], - "670-yellow": [ - 0, - 1, - 1 - ], - "671-red": [ - 0, - 1, - 2 - ], - "671-blue": [ - 0, - 1, - 2 - ], - "671-yellow": [ - 0, - 1, - 1 - ], - "671-white": [ - 0, - 1, - 2 - ], - "671-orange": [ - 0, - 1, - 2 - ], - "672": [ - 0, - 1, - 1 - ], - "673": [ - 0, - 1, - 1 - ], - "677": [ - 0, - 1, - 1 - ], - "678-female": [ - 0, - 1, - 1 - ], - "678": [ - 0, - 1, - 1 - ], - "690": [ - 0, - 1, - 1 - ], - "691": [ - 0, - 1, - 1 - ], - "696": [ - 0, - 1, - 1 - ], - "697": [ - 0, - 1, - 1 - ], - "698": [ - 0, - 1, - 1 - ], - "699": [ - 0, - 1, - 1 - ], - "700": [ - 0, - 1, - 1 - ], - "702": [ - 0, - 1, - 1 - ], - "703": [ - 0, - 1, - 1 - ], - "704": [ - 0, - 1, - 1 - ], - "705": [ - 0, - 2, - 2 - ], - "706": [ - 0, - 1, - 1 - ], - "708": [ - 0, - 1, - 1 - ], - "709": [ - 0, - 1, - 1 - ], - "710": [ - 0, - 1, - 1 - ], - "711": [ - 1, - 1, - 1 - ], - "712": [ - 0, - 1, - 1 - ], - "713": [ - 0, - 1, - 1 - ], - "714": [ - 0, - 1, - 1 - ], - "715": [ - 0, - 2, - 1 - ], - "716-active": [ - 0, - 1, - 1 - ], - "716-neutral": [ - 0, - 1, - 1 - ], - "717": [ - 0, - 2, - 2 - ], - "720-unbound": [ - 1, - 1, - 1 - ], - "720": [ - 1, - 1, - 1 - ], - "728": [ - 0, - 1, - 1 - ], - "729": [ - 0, - 2, - 2 - ], - "730": [ - 0, - 2, - 1 - ], - "734": [ - 0, - 1, - 1 - ], - "735": [ - 0, - 1, - 1 - ], - "742": [ - 0, - 2, - 2 - ], - "743": [ - 0, - 2, - 2 - ], - "747": [ - 0, - 2, - 2 - ], - "748": [ - 0, - 1, - 1 - ], - "751": [ - 0, - 1, - 1 - ], - "752": [ - 0, - 1, - 1 - ], - "753": [ - 0, - 1, - 1 - ], - "754": [ - 0, - 2, - 2 - ], - "755": [ - 0, - 1, - 1 - ], - "756": [ - 0, - 1, - 1 - ], - "761": [ - 0, - 1, - 1 - ], - "762": [ - 0, - 1, - 1 - ], - "763": [ - 0, - 1, - 1 - ], - "767": [ - 0, - 1, - 1 - ], - "768": [ - 0, - 1, - 1 - ], - "770": [ - 0, - 0, - 0 - ], - "771": [ - 0, - 2, - 2 - ], - "772": [ - 0, - 1, - 1 - ], - "773-fighting": [ - 0, - 1, - 1 - ], - "773-psychic": [ - 0, - 1, - 1 - ], - "773-poison": [ - 0, - 1, - 1 - ], - "773-ground": [ - 0, - 1, - 1 - ], - "773-ghost": [ - 0, - 1, - 1 - ], - "773-steel": [ - 0, - 1, - 1 - ], - "773-rock": [ - 0, - 1, - 1 - ], - "773-grass": [ - 0, - 1, - 1 - ], - "773-dragon": [ - 0, - 1, - 1 - ], - "773-bug": [ - 0, - 1, - 1 - ], - "773-ice": [ - 0, - 1, - 1 - ], - "773-dark": [ - 0, - 1, - 1 - ], - "773": [ - 0, - 1, - 1 - ], - "773-fairy": [ - 0, - 1, - 1 - ], - "773-water": [ - 0, - 1, - 1 - ], - "773-electric": [ - 0, - 1, - 1 - ], - "773-flying": [ - 0, - 1, - 1 - ], - "773-fire": [ - 0, - 1, - 1 - ], - "776": [ - 0, - 1, - 1 - ], - "777": [ - 0, - 1, - 1 - ], - "778-busted": [ - 0, - 1, - 1 - ], - "778-disguised": [ - 0, - 1, - 1 - ], - "779": [ - 0, - 1, - 1 - ], - "789": [ - 1, - 1, - 1 - ], - "790": [ - 0, - 1, - 1 - ], - "791": [ - 2, - 1, - 1 - ], - "792": [ - 0, - 1, - 1 - ], - "793": [ - 0, - 2, - 2 - ], - "797": [ - 0, - 1, - 1 - ], - "798": [ - 0, - 1, - 1 - ], - "800-dawn-wings": [ - 0, - 1, - 1 - ], - "800-dusk-mane": [ - 0, - 1, - 1 - ], - "800-ultra": [ - 0, - 1, - 1 - ], - "800": [ - 0, - 1, - 1 - ], - "802": [ - 1, - 1, - 1 - ], - "803": [ - 0, - 1, - 1 - ], - "804": [ - 0, - 1, - 1 - ], - "808": [ - 0, - 1, - 1 - ], - "809": [ - 0, - 1, - 1 - ], - "816": [ - 0, - 1, - 1 - ], - "817": [ - 0, - 1, - 1 - ], - "818": [ - 1, - 1, - 1 - ], - "821": [ - 0, - 2, - 2 - ], - "822": [ - 0, - 1, - 1 - ], - "823": [ - 0, - 1, - 1 - ], - "829": [ - 0, - 1, - 1 - ], - "830": [ - 0, - 1, - 1 - ], - "835": [ - 0, - 1, - 1 - ], - "836": [ - 0, - 2, - 2 - ], - "850": [ - 0, - 1, - 1 - ], - "851": [ - 0, - 1, - 1 - ], - "854": [ - 0, - 1, - 1 - ], - "855": [ - 0, - 1, - 1 - ], - "856": [ - 0, - 1, - 1 - ], - "857": [ - 0, - 2, - 2 - ], - "858": [ - 0, - 1, - 1 - ], - "859": [ - 0, - 1, - 1 - ], - "860": [ - 0, - 1, - 1 - ], - "861": [ - 0, - 1, - 1 - ], - "862": [ - 0, - 1, - 1 - ], - "863": [ - 0, - 1, - 1 - ], - "864": [ - 0, - 1, - 1 - ], - "867": [ - 0, - 1, - 1 - ], - "872": [ - 1, - 1, - 1 - ], - "873": [ - 1, - 1, - 1 - ], - "876-female": [ - 0, - 1, - 1 - ], - "876": [ - 0, - 1, - 1 - ], - "877-hangry": [ - 1, - 1, - 1 - ], - "877": [ - 1, - 1, - 1 - ], - "880": [ - 0, - 1, - 1 - ], - "881": [ - 0, - 1, - 1 - ], - "882": [ - 0, - 2, - 1 - ], - "883": [ - 0, - 1, - 1 - ], - "884": [ - 0, - 1, - 1 - ], - "885": [ - 1, - 1, - 1 - ], - "886": [ - 1, - 1, - 1 - ], - "887": [ - 1, - 1, - 1 - ], - "888": [ - 0, - 1, - 1 - ], - "888-crowned": [ - 0, - 1, - 1 - ], - "889": [ - 0, - 1, - 1 - ], - "889-crowned": [ - 0, - 1, - 1 - ], - "890": [ - 0, - 2, - 1 - ], - "890-eternamax": [ - 0, - 1, - 1 - ], - "891": [ - 1, - 1, - 1 - ], - "892-rapid-strike": [ - 1, - 1, - 1 - ], - "892": [ - 1, - 1, - 1 - ], - "896": [ - 1, - 1, - 1 - ], - "897": [ - 1, - 1, - 1 - ], - "898": [ - 1, - 1, - 1 - ], - "898-ice": [ - 1, - 1, - 1 - ], - "898-shadow": [ - 1, - 1, - 1 - ], - "900": [ - 0, - 1, - 1 - ], - "901": [ - 0, - 1, - 1 - ], - "903": [ - 0, - 1, - 1 - ], - "909": [ - 0, - 1, - 1 - ], - "910": [ - 0, - 2, - 2 - ], - "911": [ - 0, - 2, - 2 - ], - "912": [ - 0, - 1, - 2 - ], - "913": [ - 0, - 1, - 2 - ], - "914": [ - 0, - 2, - 1 - ], - "919": [ - 1, - 1, - 1 - ], - "920": [ - 1, - 1, - 1 - ], - "924": [ - 1, - 1, - 1 - ], - "925-four": [ - 1, - 2, - 2 - ], - "925-three": [ - 1, - 2, - 2 - ], - "932": [ - 0, - 2, - 2 - ], - "933": [ - 0, - 2, - 2 - ], - "934": [ - 0, - 1, - 1 - ], - "935": [ - 1, - 1, - 2 - ], - "936": [ - 2, - 2, - 2 - ], - "937": [ - 2, - 2, - 2 - ], - "940": [ - 0, - 1, - 1 - ], - "941": [ - 0, - 1, - 1 - ], - "948": [ - 0, - 1, - 1 - ], - "949": [ - 0, - 1, - 1 - ], - "951": [ - 0, - 1, - 1 - ], - "952": [ - 0, - 1, - 1 - ], - "953": [ - 0, - 1, - 1 - ], - "954": [ - 0, - 1, - 1 - ], - "957": [ - 2, - 2, - 2 - ], - "958": [ - 2, - 2, - 2 - ], - "959": [ - 2, - 2, - 2 - ], - "962": [ - 1, - 1, - 1 - ], - "967": [ - 0, - 1, - 1 - ], - "968": [ - 0, - 1, - 1 - ], - "969": [ - 0, - 1, - 1 - ], - "970": [ - 0, - 1, - 1 - ], - "973": [ - 1, - 1, - 1 - ], - "974": [ - 0, - 1, - 1 - ], - "975": [ - 0, - 1, - 1 - ], - "978-curly": [ - 0, - 2, - 2 - ], - "978-droopy": [ - 0, - 2, - 2 - ], - "978-stretchy": [ - 0, - 2, - 2 - ], - "979": [ - 2, - 2, - 2 - ], - "981": [ - 0, - 1, - 1 - ], - "982": [ - 0, - 1, - 1 - ], - "982-three-segment": [ - 0, - 1, - 1 - ], - "987": [ - 1, - 1, - 1 - ], - "988": [ - 0, - 1, - 2 - ], - "993": [ - 0, - 1, - 1 - ], - "994": [ - 0, - 1, - 2 - ], - "995": [ - 0, - 1, - 1 - ], - "996": [ - 0, - 1, - 1 - ], - "997": [ - 0, - 2, - 2 - ], - "998": [ - 0, - 2, - 2 - ], - "999": [ - 2, - 1, - 1 - ], - "1000": [ - 1, - 1, - 1 - ], - "1001": [ - 0, - 1, - 1 - ], - "1003": [ - 0, - 1, - 1 - ], - "1004": [ - 0, - 1, - 1 - ], - "1006": [ - 0, - 2, - 1 - ], - "1007-apex-build": [ - 0, - 2, - 2 - ], - "1008-ultimate-mode": [ - 1, - 1, - 1 - ], - "2027": [ - 0, - 1, - 1 - ], - "2028": [ - 0, - 1, - 1 - ], - "2052": [ - 0, - 1, - 1 - ], - "2053": [ - 0, - 1, - 0 - ], - "4052": [ - 0, - 1, - 1 - ], - "4077": [ - 0, - 1, - 1 - ], - "4078": [ - 0, - 1, - 1 - ], - "4079": [ - 0, - 1, - 1 - ], - "4080": [ - 2, - 1, - 1 - ], - "4144": [ - 0, - 1, - 1 - ], - "4145": [ - 0, - 1, - 1 - ], - "4146": [ - 0, - 1, - 1 - ], - "4199": [ - 2, - 1, - 1 - ], - "4222": [ - 0, - 1, - 1 - ], - "4263": [ - 0, - 1, - 1 - ], - "4264": [ - 0, - 1, - 1 - ], - "4562": [ - 0, - 1, - 1 - ], - "6100": [ - 0, - 1, - 1 - ], - "6101": [ - 0, - 1, - 1 - ], - "6215": [ - 0, - 1, - 1 - ], - "6549": [ - 0, - 1, - 1 - ], - "6570": [ - 0, - 1, - 1 - ], - "6571": [ - 0, - 1, - 1 - ], - "6705": [ - 0, - 1, - 1 - ], - "6706": [ - 0, - 2, - 2 - ], + "3-mega": [0, 2, 2], + "6-mega-x": [0, 2, 2], + "6-mega-y": [0, 2, 2], + "80-mega": [0, 1, 1], + "94-mega": [2, 2, 2], + "127-mega": [0, 1, 1], + "130-mega": [0, 1, 1], + "142-mega": [0, 1, 1], + "150-mega-x": [0, 1, 1], + "150-mega-y": [0, 1, 1], + "181-mega": [0, 1, 2], + "212-mega": [1, 1, 2], + "229-mega": [0, 1, 1], + "248-mega": [0, 1, 1], + "257-mega": [0, 1, 1], + "282-mega": [0, 2, 2], + "302-mega": [0, 1, 1], + "303-mega": [0, 1, 1], + "306-mega": [1, 1, 1], + "308-mega": [0, 1, 1], + "310-mega": [0, 1, 1], + "334-mega": [0, 2, 1], + "354-mega": [0, 1, 1], + "359-mega": [0, 1, 1], + "362-mega": [0, 1, 1], + "373-mega": [0, 1, 1], + "376-mega": [0, 1, 1], + "380-mega": [0, 1, 1], + "381-mega": [0, 1, 1], + "382-primal": [0, 1, 1], + "383-primal": [0, 1, 1], + "384-mega": [0, 2, 1], + "428-mega": [0, 1, 1], + "445-mega": [1, 1, 1], + "448-mega": [1, 1, 1], + "475-mega": [0, 2, 2], + "531-mega": [0, 1, 1], + "653": [0, 1, 1], + "654": [0, 1, 1], + "655": [0, 1, 1], + "656": [0, 1, 1], + "657": [0, 1, 1], + "658": [0, 1, 1], + "658-ash": [0, 1, 1], + "664": [0, 1, 1], + "665": [0, 1, 1], + "666-archipelago": [0, 1, 1], + "666-continental": [0, 1, 1], + "666-elegant": [0, 1, 1], + "666-fancy": [0, 2, 2], + "666-garden": [0, 1, 1], + "666-high-plains": [0, 1, 1], + "666-icy-snow": [0, 1, 1], + "666-jungle": [0, 1, 1], + "666-marine": [0, 1, 1], + "666-meadow": [0, 2, 2], + "666-modern": [0, 1, 1], + "666-monsoon": [0, 1, 1], + "666-ocean": [0, 1, 1], + "666-poke-ball": [0, 1, 2], + "666-polar": [0, 1, 1], + "666-river": [0, 2, 1], + "666-sandstorm": [0, 1, 1], + "666-savanna": [0, 1, 1], + "666-sun": [0, 1, 1], + "666-tundra": [0, 1, 1], + "669-red": [0, 2, 2], + "669-blue": [0, 1, 1], + "669-white": [0, 1, 1], + "669-yellow": [0, 1, 1], + "669-orange": [0, 2, 2], + "670-white": [0, 1, 1], + "670-blue": [0, 1, 1], + "670-orange": [0, 1, 1], + "670-red": [0, 1, 1], + "670-yellow": [0, 1, 1], + "671-red": [0, 1, 2], + "671-blue": [0, 1, 2], + "671-yellow": [0, 1, 1], + "671-white": [0, 1, 2], + "671-orange": [0, 1, 2], + "672": [0, 1, 1], + "673": [0, 1, 1], + "676": [0, 1, 1], + "677": [0, 1, 1], + "678-female": [0, 1, 1], + "678": [0, 1, 1], + "682": [0, 1, 1], + "683": [0, 1, 1], + "684": [0, 1, 1], + "685": [0, 1, 1], + "688": [0, 1, 1], + "689": [0, 1, 1], + "690": [0, 1, 1], + "691": [0, 1, 1], + "696": [0, 1, 1], + "697": [0, 1, 1], + "698": [0, 1, 1], + "699": [0, 1, 1], + "700": [0, 1, 1], + "702": [0, 1, 1], + "703": [0, 1, 1], + "704": [0, 1, 1], + "705": [0, 1, 1], + "706": [0, 1, 1], + "708": [0, 1, 1], + "709": [0, 1, 1], + "710": [0, 1, 1], + "711": [1, 1, 1], + "712": [0, 1, 1], + "713": [0, 1, 1], + "714": [0, 1, 1], + "715": [0, 2, 1], + "716-active": [0, 1, 1], + "716-neutral": [0, 1, 1], + "717": [0, 2, 2], + "720-unbound": [1, 1, 1], + "720": [1, 1, 1], + "728": [0, 1, 1], + "729": [0, 2, 2], + "730": [0, 2, 1], + "734": [0, 1, 1], + "735": [0, 1, 1], + "742": [0, 2, 2], + "743": [0, 2, 2], + "747": [0, 2, 2], + "748": [0, 1, 1], + "751": [0, 1, 1], + "752": [0, 1, 1], + "753": [0, 1, 1], + "754": [0, 2, 2], + "755": [0, 1, 1], + "756": [0, 1, 1], + "761": [0, 1, 1], + "762": [0, 1, 1], + "763": [0, 1, 1], + "767": [0, 1, 1], + "768": [0, 1, 1], + "770": [0, 0, 0], + "771": [0, 2, 2], + "772": [0, 1, 1], + "773-fighting": [0, 1, 1], + "773-psychic": [0, 1, 1], + "773-poison": [0, 1, 1], + "773-ground": [0, 1, 1], + "773-ghost": [0, 1, 1], + "773-steel": [0, 1, 1], + "773-rock": [0, 1, 1], + "773-grass": [0, 1, 1], + "773-dragon": [0, 1, 1], + "773-bug": [0, 1, 1], + "773-ice": [0, 1, 1], + "773-dark": [0, 1, 1], + "773": [0, 1, 1], + "773-fairy": [0, 1, 1], + "773-water": [0, 1, 1], + "773-electric": [0, 1, 1], + "773-flying": [0, 1, 1], + "773-fire": [0, 1, 1], + "776": [0, 1, 1], + "777": [0, 1, 1], + "778-busted": [0, 1, 1], + "778-disguised": [0, 1, 1], + "779": [0, 1, 1], + "789": [1, 1, 1], + "790": [0, 1, 1], + "791": [2, 1, 1], + "792": [0, 1, 1], + "793": [0, 2, 2], + "797": [0, 1, 1], + "798": [0, 1, 1], + "800-dawn-wings": [0, 1, 1], + "800-dusk-mane": [0, 1, 1], + "800-ultra": [0, 1, 1], + "800": [0, 1, 1], + "802": [1, 1, 1], + "803": [0, 1, 1], + "804": [0, 1, 1], + "807": [0, 1, 1], + "808": [0, 1, 1], + "809": [0, 1, 1], + "816": [0, 1, 1], + "817": [0, 1, 1], + "818": [1, 1, 1], + "821": [0, 2, 2], + "822": [0, 1, 1], + "823": [0, 1, 1], + "829": [0, 1, 1], + "830": [0, 1, 1], + "835": [0, 1, 1], + "836": [0, 2, 2], + "850": [0, 1, 1], + "851": [0, 1, 1], + "854": [0, 1, 1], + "855": [0, 1, 1], + "856": [0, 1, 1], + "857": [0, 2, 2], + "858": [0, 1, 1], + "859": [0, 1, 1], + "860": [0, 1, 1], + "861": [0, 1, 1], + "862": [0, 1, 1], + "863": [0, 1, 1], + "864": [0, 1, 1], + "867": [0, 1, 1], + "872": [1, 1, 1], + "873": [1, 1, 1], + "876-female": [0, 1, 1], + "876": [0, 1, 1], + "877-hangry": [1, 1, 1], + "877": [1, 1, 1], + "880": [0, 1, 1], + "881": [0, 1, 1], + "882": [0, 2, 1], + "883": [0, 1, 1], + "884": [0, 1, 1], + "885": [1, 1, 1], + "886": [1, 1, 1], + "887": [1, 1, 1], + "888": [0, 1, 1], + "888-crowned": [0, 1, 1], + "889": [0, 1, 1], + "889-crowned": [0, 1, 1], + "890": [0, 2, 1], + "890-eternamax": [0, 1, 1], + "891": [1, 1, 1], + "892-rapid-strike": [1, 1, 1], + "892": [1, 1, 1], + "894": [0, 1, 1], + "895": [0, 1, 1], + "896": [1, 1, 1], + "897": [1, 1, 1], + "898": [1, 1, 1], + "898-ice": [1, 1, 1], + "898-shadow": [1, 1, 1], + "900": [0, 1, 1], + "901": [0, 1, 1], + "903": [0, 1, 1], + "909": [0, 1, 1], + "910": [0, 2, 2], + "911": [0, 2, 2], + "912": [0, 1, 2], + "913": [0, 1, 2], + "914": [0, 2, 1], + "919": [1, 1, 1], + "920": [1, 1, 1], + "924": [1, 1, 1], + "925-four": [1, 2, 2], + "925-three": [1, 2, 2], + "932": [0, 2, 2], + "933": [0, 2, 2], + "934": [0, 1, 1], + "935": [1, 1, 2], + "936": [2, 2, 2], + "937": [2, 2, 2], + "940": [0, 1, 1], + "941": [0, 1, 1], + "944": [0, 1, 1], + "945": [0, 1, 1], + "948": [0, 1, 1], + "949": [0, 1, 1], + "951": [0, 1, 1], + "952": [0, 1, 1], + "953": [0, 1, 1], + "954": [0, 1, 1], + "957": [2, 2, 2], + "958": [2, 2, 2], + "959": [2, 2, 2], + "962": [1, 1, 1], + "967": [0, 1, 1], + "968": [0, 1, 1], + "969": [0, 1, 1], + "970": [0, 1, 1], + "973": [1, 1, 1], + "974": [0, 1, 1], + "975": [0, 1, 1], + "978-curly": [0, 2, 2], + "978-droopy": [0, 2, 2], + "978-stretchy": [0, 2, 2], + "979": [2, 2, 2], + "981": [0, 1, 1], + "982": [0, 1, 1], + "982-three-segment": [0, 1, 1], + "987": [1, 1, 1], + "988": [0, 1, 2], + "993": [0, 1, 1], + "994": [0, 1, 2], + "995": [0, 1, 1], + "996": [0, 1, 1], + "997": [0, 2, 2], + "998": [0, 2, 2], + "999": [2, 1, 1], + "1000": [1, 1, 1], + "1001": [0, 1, 1], + "1003": [0, 1, 1], + "1004": [0, 1, 1], + "1006": [0, 2, 1], + "1007-apex-build": [0, 2, 2], + "1008-ultimate-mode": [1, 1, 1], + "2026": [0, 1, 1], + "2027": [0, 1, 1], + "2028": [0, 1, 1], + "2052": [0, 1, 1], + "2053": [0, 1, 0], + "2103": [0, 1, 1], + "4052": [0, 1, 1], + "4077": [0, 1, 1], + "4078": [0, 1, 1], + "4079": [0, 1, 1], + "4080": [2, 1, 1], + "4144": [0, 1, 1], + "4145": [0, 1, 1], + "4146": [0, 1, 1], + "4199": [2, 1, 1], + "4222": [0, 1, 1], + "4263": [0, 1, 1], + "4264": [0, 1, 1], + "4562": [0, 1, 1], + "6100": [0, 1, 1], + "6101": [0, 1, 1], + "6215": [0, 1, 1], + "6503": [0, 1, 1], + "6549": [0, 1, 1], + "6570": [0, 1, 1], + "6571": [0, 1, 1], + "6705": [0, 1, 1], + "6706": [0, 1, 1], + "6713": [0, 1, 1], "female": {}, "back": { - "3-mega": [ - 0, - 2, - 2 - ], - "6-mega-x": [ - 0, - 2, - 2 - ], - "6-mega-y": [ - 0, - 1, - 2 - ], - "80-mega": [ - 0, - 1, - 1 - ], - "94-mega": [ - 1, - 1, - 1 - ], - "127-mega": [ - 0, - 1, - 1 - ], - "130-mega": [ - 0, - 1, - 1 - ], - "142-mega": [ - 0, - 1, - 1 - ], - "150-mega-x": [ - 0, - 1, - 1 - ], - "150-mega-y": [ - 0, - 1, - 1 - ], - "181-mega": [ - 0, - 1, - 2 - ], - "212-mega": [ - 1, - 2, - 2 - ], - "229-mega": [ - 0, - 1, - 1 - ], - "248-mega": [ - 0, - 2, - 1 - ], - "257-mega": [ - 0, - 1, - 1 - ], - "282-mega": [ - 0, - 1, - 1 - ], - "302-mega": [ - 0, - 1, - 1 - ], - "303-mega": [ - 0, - 1, - 1 - ], - "306-mega": [ - 1, - 1, - 1 - ], - "308-mega": [ - 0, - 1, - 1 - ], - "310-mega": [ - 0, - 1, - 1 - ], - "334-mega": [ - 0, - 1, - 1 - ], - "354-mega": [ - 0, - 1, - 1 - ], - "362-mega": [ - 0, - 1, - 1 - ], - "373-mega": [ - 0, - 1, - 1 - ], - "376-mega": [ - 0, - 1, - 1 - ], - "380-mega": [ - 0, - 1, - 1 - ], - "381-mega": [ - 0, - 1, - 1 - ], - "382-primal": [ - 0, - 1, - 1 - ], - "383-primal": [ - 0, - 1, - 1 - ], - "384-mega": [ - 0, - 1, - 1 - ], - "428-mega": [ - 0, - 1, - 1 - ], - "445-mega": [ - 1, - 1, - 1 - ], - "448-mega": [ - 1, - 1, - 1 - ], - "475-mega": [ - 0, - 2, - 2 - ], - "531-mega": [ - 0, - 1, - 1 - ], - "653": [ - 0, - 1, - 1 - ], - "654": [ - 0, - 1, - 1 - ], - "655": [ - 0, - 1, - 1 - ], - "664": [ - 0, - 1, - 1 - ], - "665": [ - 0, - 2, - 1 - ], - "666-archipelago": [ - 0, - 2, - 2 - ], - "666-continental": [ - 0, - 2, - 2 - ], - "666-elegant": [ - 0, - 2, - 2 - ], - "666-fancy": [ - 0, - 2, - 2 - ], - "666-garden": [ - 0, - 2, - 2 - ], - "666-high-plains": [ - 0, - 2, - 2 - ], - "666-icy-snow": [ - 0, - 2, - 2 - ], - "666-jungle": [ - 0, - 2, - 2 - ], - "666-marine": [ - 0, - 2, - 2 - ], - "666-meadow": [ - 0, - 2, - 2 - ], - "666-modern": [ - 0, - 2, - 2 - ], - "666-monsoon": [ - 0, - 2, - 2 - ], - "666-ocean": [ - 0, - 2, - 2 - ], - "666-poke-ball": [ - 0, - 2, - 2 - ], - "666-polar": [ - 0, - 2, - 2 - ], - "666-river": [ - 0, - 2, - 2 - ], - "666-sandstorm": [ - 0, - 2, - 2 - ], - "666-savanna": [ - 0, - 2, - 2 - ], - "666-sun": [ - 0, - 2, - 2 - ], - "666-tundra": [ - 0, - 2, - 2 - ], - "669-red": [ - 0, - 2, - 2 - ], - "669-blue": [ - 0, - 2, - 2 - ], - "669-white": [ - 0, - 2, - 2 - ], - "669-yellow": [ - 0, - 2, - 2 - ], - "669-orange": [ - 0, - 2, - 2 - ], - "670-white": [ - 0, - 1, - 1 - ], - "670-blue": [ - 0, - 2, - 2 - ], - "670-orange": [ - 0, - 1, - 1 - ], - "670-red": [ - 0, - 1, - 1 - ], - "670-yellow": [ - 0, - 1, - 1 - ], - "671-red": [ - 0, - 1, - 1 - ], - "671-blue": [ - 0, - 1, - 1 - ], - "671-yellow": [ - 0, - 1, - 1 - ], - "671-white": [ - 0, - 1, - 1 - ], - "671-orange": [ - 0, - 1, - 1 - ], - "672": [ - 0, - 1, - 1 - ], - "673": [ - 0, - 1, - 1 - ], - "677": [ - 0, - 1, - 1 - ], - "678-female": [ - 0, - 1, - 1 - ], - "678": [ - 0, - 1, - 1 - ], - "690": [ - 0, - 1, - 1 - ], - "691": [ - 0, - 1, - 1 - ], - "696": [ - 0, - 1, - 1 - ], - "697": [ - 0, - 1, - 1 - ], - "698": [ - 0, - 1, - 1 - ], - "699": [ - 0, - 2, - 2 - ], - "700": [ - 0, - 1, - 1 - ], - "702": [ - 0, - 1, - 1 - ], - "703": [ - 0, - 1, - 1 - ], - "704": [ - 0, - 1, - 1 - ], - "705": [ - 0, - 1, - 1 - ], - "706": [ - 0, - 1, - 1 - ], - "708": [ - 0, - 1, - 1 - ], - "709": [ - 0, - 1, - 1 - ], - "710": [ - 0, - 1, - 1 - ], - "711": [ - 1, - 1, - 1 - ], - "712": [ - 0, - 1, - 1 - ], - "713": [ - 0, - 1, - 1 - ], - "714": [ - 0, - 1, - 1 - ], - "715": [ - 0, - 1, - 1 - ], - "716-active": [ - 0, - 1, - 1 - ], - "716-neutral": [ - 0, - 1, - 1 - ], - "717": [ - 0, - 1, - 1 - ], - "720-unbound": [ - 1, - 1, - 1 - ], - "720": [ - 1, - 1, - 1 - ], - "728": [ - 0, - 1, - 1 - ], - "729": [ - 0, - 2, - 2 - ], - "730": [ - 0, - 2, - 1 - ], - "734": [ - 0, - 1, - 1 - ], - "735": [ - 0, - 1, - 1 - ], - "742": [ - 0, - 2, - 2 - ], - "743": [ - 0, - 2, - 2 - ], - "747": [ - 0, - 2, - 2 - ], - "748": [ - 0, - 1, - 1 - ], - "751": [ - 0, - 1, - 1 - ], - "752": [ - 0, - 1, - 1 - ], - "753": [ - 0, - 1, - 1 - ], - "754": [ - 0, - 2, - 2 - ], - "755": [ - 0, - 1, - 1 - ], - "756": [ - 0, - 1, - 1 - ], - "761": [ - 0, - 1, - 1 - ], - "762": [ - 0, - 1, - 1 - ], - "763": [ - 0, - 1, - 1 - ], - "767": [ - 0, - 1, - 1 - ], - "768": [ - 0, - 1, - 1 - ], - "771": [ - 0, - 1, - 1 - ], - "772": [ - 0, - 1, - 1 - ], - "773-fighting": [ - 0, - 1, - 1 - ], - "773-psychic": [ - 0, - 1, - 1 - ], - "773-poison": [ - 0, - 1, - 1 - ], - "773-ground": [ - 0, - 1, - 1 - ], - "773-ghost": [ - 0, - 1, - 1 - ], - "773-steel": [ - 0, - 1, - 1 - ], - "773-rock": [ - 0, - 1, - 1 - ], - "773-grass": [ - 0, - 1, - 1 - ], - "773-dragon": [ - 0, - 1, - 1 - ], - "773-bug": [ - 0, - 1, - 1 - ], - "773-ice": [ - 0, - 1, - 1 - ], - "773-dark": [ - 0, - 1, - 1 - ], - "773": [ - 0, - 1, - 1 - ], - "773-fairy": [ - 0, - 1, - 1 - ], - "773-water": [ - 0, - 1, - 1 - ], - "773-electric": [ - 0, - 1, - 1 - ], - "773-flying": [ - 0, - 1, - 1 - ], - "773-fire": [ - 0, - 1, - 1 - ], - "776": [ - 0, - 2, - 2 - ], - "777": [ - 0, - 1, - 1 - ], - "778-busted": [ - 0, - 1, - 1 - ], - "778-disguised": [ - 0, - 1, - 1 - ], - "779": [ - 0, - 1, - 1 - ], - "789": [ - 1, - 1, - 1 - ], - "790": [ - 0, - 1, - 1 - ], - "791": [ - 1, - 1, - 1 - ], - "792": [ - 0, - 1, - 1 - ], - "793": [ - 0, - 1, - 1 - ], - "797": [ - 0, - 1, - 1 - ], - "798": [ - 0, - 1, - 1 - ], - "800-dawn-wings": [ - 0, - 1, - 1 - ], - "800-dusk-mane": [ - 0, - 1, - 1 - ], - "800-ultra": [ - 0, - 1, - 1 - ], - "800": [ - 0, - 1, - 1 - ], - "802": [ - 1, - 1, - 1 - ], - "803": [ - 0, - 1, - 1 - ], - "804": [ - 0, - 1, - 1 - ], - "808": [ - 0, - 1, - 1 - ], - "809": [ - 0, - 1, - 1 - ], - "816": [ - 0, - 1, - 1 - ], - "817": [ - 0, - 1, - 1 - ], - "818": [ - 0, - 1, - 1 - ], - "821": [ - 0, - 1, - 1 - ], - "822": [ - 0, - 1, - 1 - ], - "823": [ - 0, - 1, - 1 - ], - "829": [ - 0, - 1, - 1 - ], - "830": [ - 0, - 1, - 1 - ], - "835": [ - 0, - 1, - 1 - ], - "836": [ - 0, - 1, - 1 - ], - "850": [ - 0, - 1, - 1 - ], - "851": [ - 0, - 1, - 1 - ], - "854": [ - 0, - 1, - 1 - ], - "855": [ - 0, - 1, - 1 - ], - "856": [ - 0, - 1, - 1 - ], - "857": [ - 0, - 2, - 2 - ], - "858": [ - 0, - 1, - 1 - ], - "859": [ - 0, - 1, - 1 - ], - "860": [ - 0, - 1, - 1 - ], - "861": [ - 0, - 1, - 1 - ], - "862": [ - 0, - 1, - 1 - ], - "863": [ - 0, - 1, - 1 - ], - "864": [ - 0, - 1, - 1 - ], - "867": [ - 0, - 1, - 1 - ], - "872": [ - 1, - 1, - 1 - ], - "873": [ - 1, - 1, - 1 - ], - "876-female": [ - 0, - 1, - 1 - ], - "876": [ - 0, - 1, - 1 - ], - "877-hangry": [ - 1, - 1, - 1 - ], - "877": [ - 1, - 1, - 1 - ], - "880": [ - 0, - 1, - 1 - ], - "881": [ - 0, - 1, - 1 - ], - "882": [ - 0, - 1, - 1 - ], - "883": [ - 0, - 1, - 1 - ], - "884": [ - 0, - 1, - 1 - ], - "885": [ - 1, - 1, - 1 - ], - "886": [ - 1, - 1, - 1 - ], - "887": [ - 1, - 1, - 1 - ], - "888": [ - 0, - 1, - 1 - ], - "888-crowned": [ - 0, - 1, - 1 - ], - "889": [ - 0, - 1, - 1 - ], - "889-crowned": [ - 0, - 1, - 1 - ], - "890": [ - 0, - 1, - 1 - ], - "891": [ - 1, - 1, - 1 - ], - "892-rapid-strike": [ - 1, - 1, - 1 - ], - "892": [ - 1, - 1, - 1 - ], - "896": [ - 1, - 1, - 1 - ], - "897": [ - 1, - 1, - 1 - ], - "898": [ - 1, - 1, - 1 - ], - "898-ice": [ - 1, - 1, - 1 - ], - "898-shadow": [ - 1, - 1, - 1 - ], - "900": [ - 0, - 1, - 1 - ], - "901": [ - 0, - 1, - 1 - ], - "903": [ - 0, - 1, - 1 - ], - "909": [ - 0, - 1, - 1 - ], - "910": [ - 0, - 2, - 2 - ], - "911": [ - 0, - 1, - 1 - ], - "912": [ - 0, - 1, - 1 - ], - "913": [ - 0, - 1, - 1 - ], - "914": [ - 0, - 2, - 2 - ], - "919": [ - 1, - 1, - 1 - ], - "920": [ - 1, - 1, - 1 - ], - "924": [ - 1, - 1, - 1 - ], - "925-four": [ - 1, - 2, - 2 - ], - "925-three": [ - 1, - 2, - 2 - ], - "932": [ - 0, - 1, - 1 - ], - "933": [ - 0, - 1, - 1 - ], - "934": [ - 0, - 1, - 1 - ], - "935": [ - 2, - 2, - 2 - ], - "936": [ - 2, - 2, - 2 - ], - "937": [ - 2, - 2, - 2 - ], - "940": [ - 0, - 1, - 1 - ], - "941": [ - 0, - 1, - 1 - ], - "948": [ - 0, - 1, - 1 - ], - "949": [ - 0, - 1, - 1 - ], - "951": [ - 0, - 1, - 1 - ], - "952": [ - 0, - 2, - 1 - ], - "953": [ - 0, - 1, - 1 - ], - "954": [ - 0, - 1, - 1 - ], - "957": [ - 1, - 1, - 1 - ], - "958": [ - 1, - 1, - 1 - ], - "959": [ - 1, - 1, - 1 - ], - "962": [ - 1, - 1, - 1 - ], - "967": [ - 0, - 1, - 1 - ], - "968": [ - 0, - 2, - 2 - ], - "969": [ - 0, - 1, - 1 - ], - "970": [ - 0, - 1, - 1 - ], - "973": [ - 1, - 1, - 1 - ], - "974": [ - 0, - 1, - 1 - ], - "975": [ - 0, - 1, - 1 - ], - "978-curly": [ - 0, - 2, - 2 - ], - "978-droopy": [ - 0, - 2, - 2 - ], - "978-stretchy": [ - 0, - 1, - 1 - ], - "979": [ - 1, - 1, - 1 - ], - "981": [ - 0, - 1, - 1 - ], - "982": [ - 0, - 1, - 1 - ], - "982-three-segment": [ - 0, - 1, - 1 - ], - "987": [ - 1, - 1, - 1 - ], - "988": [ - 0, - 1, - 1 - ], - "993": [ - 0, - 1, - 1 - ], - "994": [ - 0, - 1, - 1 - ], - "995": [ - 0, - 1, - 1 - ], - "996": [ - 0, - 1, - 1 - ], - "997": [ - 0, - 1, - 1 - ], - "998": [ - 0, - 1, - 1 - ], - "999": [ - 1, - 1, - 1 - ], - "1000": [ - 1, - 1, - 1 - ], - "1001": [ - 0, - 1, - 1 - ], - "1003": [ - 0, - 1, - 1 - ], - "1004": [ - 0, - 1, - 1 - ], - "1006": [ - 0, - 2, - 2 - ], - "1007-apex-build": [ - 0, - 2, - 2 - ], - "1008-ultimate-mode": [ - 1, - 1, - 1 - ], - "2027": [ - 0, - 1, - 1 - ], - "2028": [ - 0, - 1, - 1 - ], - "2052": [ - 0, - 1, - 1 - ], - "2053": [ - 0, - 1, - 1 - ], - "4052": [ - 0, - 1, - 1 - ], - "4077": [ - 0, - 1, - 1 - ], - "4078": [ - 0, - 1, - 1 - ], - "4079": [ - 0, - 1, - 1 - ], - "4080": [ - 2, - 2, - 2 - ], - "4144": [ - 0, - 1, - 1 - ], - "4145": [ - 0, - 1, - 1 - ], - "4146": [ - 0, - 1, - 1 - ], - "4199": [ - 2, - 1, - 1 - ], - "4222": [ - 0, - 1, - 1 - ], - "4263": [ - 0, - 1, - 1 - ], - "4264": [ - 0, - 1, - 1 - ], - "4562": [ - 0, - 1, - 1 - ], - "6100": [ - 0, - 1, - 1 - ], - "6101": [ - 0, - 1, - 1 - ], - "6215": [ - 0, - 1, - 1 - ], - "6549": [ - 0, - 1, - 1 - ], - "6570": [ - 0, - 1, - 1 - ], - "6571": [ - 0, - 1, - 1 - ], - "6705": [ - 0, - 1, - 1 - ], - "6706": [ - 0, - 2, - 2 - ], - "6713": [ - 0, - 1, - 1 - ] - }, - "6713": [ - 0, - 1, - 1 - ] + "3-mega": [0, 2, 2], + "6-mega-x": [0, 2, 2], + "6-mega-y": [0, 1, 2], + "80-mega": [0, 1, 1], + "94-mega": [1, 1, 1], + "127-mega": [0, 1, 1], + "130-mega": [0, 1, 1], + "142-mega": [0, 1, 1], + "150-mega-x": [0, 1, 1], + "150-mega-y": [0, 1, 1], + "181-mega": [0, 1, 2], + "212-mega": [1, 2, 2], + "229-mega": [0, 1, 1], + "248-mega": [0, 2, 1], + "257-mega": [0, 1, 1], + "282-mega": [0, 1, 1], + "302-mega": [0, 1, 1], + "303-mega": [0, 1, 1], + "306-mega": [1, 1, 1], + "308-mega": [0, 1, 1], + "310-mega": [0, 1, 1], + "334-mega": [0, 1, 1], + "354-mega": [0, 1, 1], + "359-mega": [0, 1, 1], + "362-mega": [0, 1, 1], + "373-mega": [0, 1, 1], + "376-mega": [0, 1, 1], + "380-mega": [0, 1, 1], + "381-mega": [0, 1, 1], + "382-primal": [0, 1, 1], + "383-primal": [0, 1, 1], + "384-mega": [0, 1, 1], + "428-mega": [0, 1, 1], + "445-mega": [1, 1, 1], + "448-mega": [1, 1, 1], + "475-mega": [0, 2, 2], + "531-mega": [0, 1, 1], + "653": [0, 1, 1], + "654": [0, 1, 1], + "655": [0, 1, 1], + "656": [0, 1, 1], + "657": [0, 1, 1], + "658": [0, 1, 1], + "658-ash": [0, 1, 1], + "664": [0, 1, 1], + "665": [0, 2, 1], + "666-archipelago": [0, 2, 2], + "666-continental": [0, 2, 2], + "666-elegant": [0, 2, 2], + "666-fancy": [0, 2, 2], + "666-garden": [0, 2, 2], + "666-high-plains": [0, 2, 2], + "666-icy-snow": [0, 2, 2], + "666-jungle": [0, 2, 2], + "666-marine": [0, 2, 2], + "666-meadow": [0, 2, 2], + "666-modern": [0, 2, 2], + "666-monsoon": [0, 2, 2], + "666-ocean": [0, 2, 2], + "666-poke-ball": [0, 2, 2], + "666-polar": [0, 2, 2], + "666-river": [0, 2, 2], + "666-sandstorm": [0, 2, 2], + "666-savanna": [0, 2, 2], + "666-sun": [0, 2, 2], + "666-tundra": [0, 2, 2], + "669-red": [0, 2, 2], + "669-blue": [0, 2, 2], + "669-white": [0, 2, 2], + "669-yellow": [0, 2, 2], + "669-orange": [0, 2, 2], + "670-white": [0, 1, 1], + "670-blue": [0, 2, 2], + "670-orange": [0, 1, 1], + "670-red": [0, 1, 1], + "670-yellow": [0, 1, 1], + "671-red": [0, 1, 1], + "671-blue": [0, 1, 1], + "671-yellow": [0, 1, 1], + "671-white": [0, 1, 1], + "671-orange": [0, 1, 1], + "672": [0, 1, 1], + "673": [0, 1, 1], + "676": [0, 1, 1], + "677": [0, 1, 1], + "678-female": [0, 1, 1], + "678": [0, 1, 1], + "682": [0, 1, 1], + "683": [0, 1, 1], + "684": [0, 1, 1], + "685": [0, 1, 1], + "688": [0, 1, 1], + "689": [0, 1, 1], + "690": [0, 1, 1], + "691": [0, 1, 1], + "696": [0, 1, 1], + "697": [0, 1, 1], + "698": [0, 1, 1], + "699": [0, 2, 2], + "700": [0, 1, 1], + "702": [0, 1, 1], + "703": [0, 1, 1], + "704": [0, 1, 1], + "705": [0, 1, 1], + "706": [0, 1, 1], + "708": [0, 1, 1], + "709": [0, 1, 1], + "710": [0, 1, 1], + "711": [1, 1, 1], + "712": [0, 1, 1], + "713": [0, 1, 1], + "714": [0, 1, 1], + "715": [0, 1, 1], + "716-active": [0, 1, 1], + "716-neutral": [0, 1, 1], + "717": [0, 1, 1], + "720-unbound": [1, 1, 1], + "720": [1, 1, 1], + "728": [0, 1, 1], + "729": [0, 2, 2], + "730": [0, 2, 1], + "734": [0, 1, 1], + "735": [0, 1, 1], + "742": [0, 2, 2], + "743": [0, 2, 2], + "747": [0, 2, 2], + "748": [0, 1, 1], + "751": [0, 1, 1], + "752": [0, 1, 1], + "753": [0, 1, 1], + "754": [0, 2, 2], + "755": [0, 1, 1], + "756": [0, 1, 1], + "761": [0, 1, 1], + "762": [0, 1, 1], + "763": [0, 1, 1], + "767": [0, 1, 1], + "768": [0, 1, 1], + "771": [0, 1, 1], + "772": [0, 1, 1], + "773-fighting": [0, 1, 1], + "773-psychic": [0, 1, 1], + "773-poison": [0, 1, 1], + "773-ground": [0, 1, 1], + "773-ghost": [0, 1, 1], + "773-steel": [0, 1, 1], + "773-rock": [0, 1, 1], + "773-grass": [0, 1, 1], + "773-dragon": [0, 1, 1], + "773-bug": [0, 1, 1], + "773-ice": [0, 1, 1], + "773-dark": [0, 1, 1], + "773": [0, 1, 1], + "773-fairy": [0, 1, 1], + "773-water": [0, 1, 1], + "773-electric": [0, 1, 1], + "773-flying": [0, 1, 1], + "773-fire": [0, 1, 1], + "776": [0, 2, 2], + "777": [0, 1, 1], + "778-busted": [0, 1, 1], + "778-disguised": [0, 1, 1], + "779": [0, 1, 1], + "789": [1, 1, 1], + "790": [0, 1, 1], + "791": [1, 1, 1], + "792": [0, 1, 1], + "793": [0, 1, 1], + "797": [0, 1, 1], + "798": [0, 1, 1], + "800-dawn-wings": [0, 1, 1], + "800-dusk-mane": [0, 1, 1], + "800-ultra": [0, 1, 1], + "800": [0, 1, 1], + "802": [1, 1, 1], + "803": [0, 1, 1], + "804": [0, 1, 1], + "807": [0, 1, 1], + "808": [0, 1, 1], + "809": [0, 1, 1], + "816": [0, 1, 1], + "817": [0, 1, 1], + "818": [0, 1, 1], + "821": [0, 1, 1], + "822": [0, 1, 1], + "823": [0, 1, 1], + "829": [0, 1, 1], + "830": [0, 1, 1], + "835": [0, 1, 1], + "836": [0, 1, 1], + "850": [0, 1, 1], + "851": [0, 1, 1], + "854": [0, 1, 1], + "855": [0, 1, 1], + "856": [0, 1, 1], + "857": [0, 2, 2], + "858": [0, 1, 1], + "859": [0, 1, 1], + "860": [0, 1, 1], + "861": [0, 1, 1], + "862": [0, 1, 1], + "863": [0, 1, 1], + "864": [0, 1, 1], + "867": [0, 1, 1], + "872": [1, 1, 1], + "873": [1, 1, 1], + "876-female": [0, 1, 1], + "876": [0, 1, 1], + "877-hangry": [1, 1, 1], + "877": [1, 1, 1], + "880": [0, 1, 1], + "881": [0, 1, 1], + "882": [0, 1, 1], + "883": [0, 1, 1], + "884": [0, 1, 1], + "885": [1, 1, 1], + "886": [1, 1, 1], + "887": [1, 1, 1], + "888": [0, 1, 1], + "888-crowned": [0, 1, 1], + "889": [0, 1, 1], + "889-crowned": [0, 1, 1], + "890": [0, 1, 1], + "891": [1, 1, 1], + "892-rapid-strike": [1, 1, 1], + "892": [1, 1, 1], + "894": [0, 1, 1], + "895": [0, 1, 1], + "896": [1, 1, 1], + "897": [1, 1, 1], + "898": [1, 1, 1], + "898-ice": [1, 1, 1], + "898-shadow": [1, 1, 1], + "900": [0, 1, 1], + "901": [0, 1, 1], + "903": [0, 1, 1], + "909": [0, 1, 1], + "910": [0, 2, 2], + "911": [0, 1, 1], + "912": [0, 1, 1], + "913": [0, 1, 1], + "914": [0, 2, 2], + "919": [1, 1, 1], + "920": [1, 1, 1], + "924": [1, 1, 1], + "925-four": [1, 2, 2], + "925-three": [1, 2, 2], + "932": [0, 1, 1], + "933": [0, 1, 1], + "934": [0, 1, 1], + "935": [2, 2, 2], + "936": [2, 2, 2], + "937": [2, 2, 2], + "940": [0, 1, 1], + "941": [0, 1, 1], + "944": [0, 1, 1], + "945": [0, 1, 1], + "948": [0, 1, 1], + "949": [0, 1, 1], + "951": [0, 1, 1], + "952": [0, 2, 1], + "953": [0, 1, 1], + "954": [0, 1, 1], + "957": [1, 1, 1], + "958": [1, 1, 1], + "959": [1, 1, 1], + "962": [1, 1, 1], + "967": [0, 1, 1], + "968": [0, 2, 2], + "969": [0, 1, 1], + "970": [0, 1, 1], + "973": [1, 1, 1], + "974": [0, 1, 1], + "975": [0, 1, 1], + "978-curly": [0, 2, 2], + "978-droopy": [0, 2, 2], + "978-stretchy": [0, 1, 1], + "979": [1, 1, 1], + "981": [0, 1, 1], + "982": [0, 1, 1], + "982-three-segment": [0, 1, 1], + "987": [1, 1, 1], + "988": [0, 1, 1], + "993": [0, 1, 1], + "994": [0, 1, 1], + "995": [0, 1, 1], + "996": [0, 1, 1], + "997": [0, 1, 1], + "998": [0, 1, 1], + "999": [1, 1, 1], + "1000": [1, 1, 1], + "1001": [0, 1, 1], + "1003": [0, 1, 1], + "1004": [0, 1, 1], + "1006": [0, 2, 2], + "1007-apex-build": [0, 2, 2], + "1008-ultimate-mode": [1, 1, 1], + "2026": [0, 1, 1], + "2027": [0, 1, 1], + "2028": [0, 1, 1], + "2052": [0, 1, 1], + "2053": [0, 1, 1], + "2103": [0, 1, 1], + "4052": [0, 1, 1], + "4077": [0, 1, 1], + "4078": [0, 1, 1], + "4079": [0, 1, 1], + "4080": [2, 2, 2], + "4144": [0, 1, 1], + "4145": [0, 1, 1], + "4146": [0, 1, 1], + "4199": [2, 1, 1], + "4222": [0, 1, 1], + "4263": [0, 1, 1], + "4264": [0, 1, 1], + "4562": [0, 1, 1], + "6100": [0, 1, 1], + "6101": [0, 1, 1], + "6215": [0, 1, 1], + "6503": [0, 1, 1], + "6549": [0, 1, 1], + "6570": [0, 1, 1], + "6571": [0, 1, 1], + "6705": [0, 1, 1], + "6706": [0, 1, 1], + "6713": [0, 1, 1] + } } } diff --git a/public/images/pokemon/variant/back/1012-counterfeit.json b/public/images/pokemon/variant/back/1012-counterfeit.json new file mode 100644 index 00000000000..10255311fe0 --- /dev/null +++ b/public/images/pokemon/variant/back/1012-counterfeit.json @@ -0,0 +1,34 @@ +{ + "1": { + "291e1e": "404ec8", + "87847e": "8a96c0", + "78c463": "f7dfc5", + "4c3a3a": "667fe9", + "5d9e4a": "dda08a", + "251b1b": "222078", + "a09750": "acbedf", + "e6e1db": "f5fdff", + "396725": "b0654a", + "ccc374": "e9f4f7", + "613f19": "7b86ad", + "544040": "626a96", + "c1b9ae": "c8ddf1", + "69441b": "3a44a4" + }, + "2": { + "291e1e": "37183f", + "87847e": "070722", + "78c463": "c3b4e0", + "4c3a3a": "563f5b", + "5d9e4a": "978dc7", + "251b1b": "1c0b1f", + "a09750": "1b2556", + "e6e1db": "212b5e", + "396725": "7a5aa7", + "ccc374": "293363", + "613f19": "0d1030", + "544040": "020109", + "c1b9ae": "111039", + "69441b": "44244b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/1013-unremarkable.json b/public/images/pokemon/variant/back/1013-unremarkable.json new file mode 100644 index 00000000000..2a6de98db5a --- /dev/null +++ b/public/images/pokemon/variant/back/1013-unremarkable.json @@ -0,0 +1,36 @@ +{ + "1": { + "5d9e4a": "dda08a", + "a09750": "c3d7eb", + "251b1b": "404ec8", + "7b6f6c": "acbedf", + "c1b9ae": "cbe1f5", + "69441b": "3a44a4", + "342405": "565e7a", + "78c463": "f7dfc5", + "9e8574": "b36171", + "988975": "939ec4", + "295217": "b0654a", + "e6e1db": "e6f9ff", + "6a5b20": "8a96c0", + "291a0d": "222078", + "453636": "667fe9" + }, + "2": { + "5d9e4a": "978dc7", + "a09750": "263665", + "251b1b": "37183f", + "7b6f6c": "0f102d", + "c1b9ae": "111039", + "69441b": "44244b", + "342405": "0b0c21", + "78c463": "c3b4e0", + "9e8574": "585d81", + "988975": "212e57", + "295217": "7a5aa7", + "e6e1db": "212b5e", + "6a5b20": "171542", + "291a0d": "170d26", + "453636": "563f5b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/102.json b/public/images/pokemon/variant/back/102.json new file mode 100644 index 00000000000..61035a495c9 --- /dev/null +++ b/public/images/pokemon/variant/back/102.json @@ -0,0 +1,20 @@ +{ + "1": { + "943131": "193662", + "e69c00": "a0694c", + "ffe6ce": "7ae49f", + "ffce4a": "cea573", + "ffb58c": "369b96", + "ef8463": "26647e", + "ffd6ad": "4fba94" + }, + "2": { + "943131": "414189", + "e69c00": "6d2341", + "ffe6ce": "ebb6f8", + "ffce4a": "92394b", + "ffb58c": "9475ce", + "ef8463": "6c5fb6", + "ffd6ad": "b98fe4" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/103.json b/public/images/pokemon/variant/back/103.json new file mode 100644 index 00000000000..492bc14b102 --- /dev/null +++ b/public/images/pokemon/variant/back/103.json @@ -0,0 +1,28 @@ +{ + "1": { + "ffde6b": "a3c4ed", + "e6ad5a": "869fdc", + "73ad31": "dea44c", + "8c7342": "283f5b", + "526329": "c8592a", + "9cd64a": "f4e774", + "a56b21": "6072ba", + "b59c4a": "426378", + "734210": "373e85", + "ffefa5": "d3efff", + "524210": "131d33" + }, + "2": { + "ffde6b": "eb748d", + "e6ad5a": "c84e7f", + "73ad31": "3d324b", + "8c7342": "d59cba", + "526329": "1f1a31", + "9cd64a": "6a5b73", + "a56b21": "83295f", + "b59c4a": "ffdbe7", + "734210": "4e1044", + "ffefa5": "ffa29d", + "524210": "925b81" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/128.json b/public/images/pokemon/variant/back/128.json new file mode 100644 index 00000000000..ef61b186930 --- /dev/null +++ b/public/images/pokemon/variant/back/128.json @@ -0,0 +1,30 @@ +{ + "1": { + "dea54a": "56b393", + "634a31": "173e0d", + "9c9cad": "997059", + "6b6b84": "75413b", + "b58431": "2e8a85", + "8c6b52": "355816", + "523a10": "102d4b", + "ad8c73": "5f722a", + "4a3a29": "072b05", + "8c6321": "215c72", + "cecede": "c2a082", + "3a3a4a": "4d2324" + }, + "2": { + "dea54a": "872b3b", + "634a31": "bc9681", + "9c9cad": "edda95", + "6b6b84": "cca45e", + "b58431": "5e172e", + "8c6b52": "d6c3aa", + "523a10": "2f0e21", + "ad8c73": "faf9ed", + "4a3a29": "966959", + "8c6321": "461029", + "cecede": "fffcc1", + "3a3a4a": "996537" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/152.json b/public/images/pokemon/variant/back/152.json new file mode 100644 index 00000000000..2460f5977d5 --- /dev/null +++ b/public/images/pokemon/variant/back/152.json @@ -0,0 +1,26 @@ +{ + "1": { + "849452": "7373b4", + "b5ce6b": "aca1d7", + "d6f78c": "ded2f1", + "84e631": "8074fa", + "ef7b7b": "9bd5c1", + "c52929": "77b3af", + "6bb529": "6f4be2", + "425a19": "505d8d", + "638c29": "6633bc", + "426319": "5d2398" + }, + "2": { + "849452": "a62775", + "b5ce6b": "c83c74", + "d6f78c": "e7617d", + "84e631": "feeeaf", + "ef7b7b": "71cf71", + "c52929": "4eac60", + "6bb529": "f0d187", + "425a19": "801a69", + "638c29": "d8a864", + "426319": "b4814b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/153.json b/public/images/pokemon/variant/back/153.json new file mode 100644 index 00000000000..8495177fbaa --- /dev/null +++ b/public/images/pokemon/variant/back/153.json @@ -0,0 +1,26 @@ +{ + "1": { + "a58419": "5961ce", + "ad3100": "47d0d1", + "295208": "232699", + "8cbd31": "8251dc", + "debd29": "7b8ce6", + "527b08": "4d36be", + "6b9c10": "6b41cc", + "f7e64a": "a2bbf8", + "6b5200": "493fa6", + "d68c52": "80f5e6" + }, + "2": { + "a58419": "a8244d", + "ad3100": "439227", + "295208": "c58c48", + "8cbd31": "fae084", + "debd29": "ca333d", + "527b08": "e8bc5e", + "6b9c10": "edc870", + "f7e64a": "ea704a", + "6b5200": "891b4f", + "d68c52": "8ec349" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/154.json b/public/images/pokemon/variant/back/154.json new file mode 100644 index 00000000000..a667f36b9c1 --- /dev/null +++ b/public/images/pokemon/variant/back/154.json @@ -0,0 +1,26 @@ +{ + "1": { + "634a00": "519aa7", + "ff3a5a": "3542a7", + "e6ad00": "7bcfc6", + "ce213a": "27217d", + "63bd42": "9d86d9", + "f7a59c": "72d1da", + "7b103a": "23124e", + "107b31": "8057b2", + "ffde21": "b1f2dc", + "9ce652": "b7afee" + }, + "2": { + "634a00": "488939", + "ff3a5a": "f9db74", + "e6ad00": "6bac4b", + "ce213a": "e5b650", + "63bd42": "a31f60", + "f7a59c": "fff6a9", + "7b103a": "b7873b", + "107b31": "761858", + "ffde21": "92c462", + "9ce652": "cd3b6b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/158.json b/public/images/pokemon/variant/back/158.json new file mode 100644 index 00000000000..a6c54577e98 --- /dev/null +++ b/public/images/pokemon/variant/back/158.json @@ -0,0 +1,29 @@ +{ + "1": { + "b54a52": "1d5d6c", + "6bb5e6": "dd8e59", + "94d6ff": "fdc17e", + "ffc552": "99d4d9", + "ad8429": "4798ab", + "ce4221": "772c52", + "3184c5": "ae5139", + "e67b7b": "749e9e", + "ef735a": "ad5778", + "7b1900": "4f0332", + "315a84": "73131e" + }, + "2": { + "000000": "ffffff", + "b54a52": "c48b27", + "6bb5e6": "97ac5b", + "94d6ff": "ccd198", + "ffc552": "2f5365", + "ad8429": "1c314f", + "ce4221": "ce8c20", + "3184c5": "4f854a", + "e67b7b": "e4b843", + "ef735a": "f3b649", + "7b1900": "a66b14", + "315a84": "2b4a30" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/159.json b/public/images/pokemon/variant/back/159.json new file mode 100644 index 00000000000..c1124bb8d42 --- /dev/null +++ b/public/images/pokemon/variant/back/159.json @@ -0,0 +1,29 @@ +{ + "1": { + "3a4a84": "973027", + "e64221": "749e9e", + "ce293a": "682c4e", + "5aade6": "e5a354", + "ffe68c": "a9e4e5", + "840008": "4f1037", + "3184c5": "cd6537", + "cebd63": "56b3bd", + "6b5200": "085d75", + "840009": "1d5d6c", + "f7525a": "774860" + }, + "2": { + "000000": "ffffff", + "3a4a84": "26472b", + "e64221": "e4b843", + "ce293a": "ce8c20", + "5aade6": "8fa54e", + "ffe68c": "2f5365", + "840008": "a66b14", + "3184c5": "468040", + "cebd63": "1c314f", + "6b5200": "112034", + "840009": "c48b27", + "f7525a": "f3b649" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/160.json b/public/images/pokemon/variant/back/160.json new file mode 100644 index 00000000000..ac9067df672 --- /dev/null +++ b/public/images/pokemon/variant/back/160.json @@ -0,0 +1,29 @@ +{ + "1": { + "8cd6ff": "ffcf72", + "6b5200": "085d75", + "ce293a": "682c4e", + "5ab5f7": "eda857", + "cebd63": "56b3bd", + "ffe68c": "a9e4e5", + "840008": "4f1037", + "294a8c": "973027", + "3a8cce": "d26738", + "ff8c84": "926877", + "f7525a": "774860" + }, + "2": { + "000000": "ffffff", + "8cd6ff": "d1d692", + "6b5200": "112034", + "ce293a": "ce8c20", + "5ab5f7": "9ab350", + "cebd63": "1c314f", + "ffe68c": "2f5365", + "840008": "a66b14", + "294a8c": "274c2d", + "3a8cce": "498a42", + "ff8c84": "fff284", + "f7525a": "f3b649" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/167.json b/public/images/pokemon/variant/back/167.json new file mode 100644 index 00000000000..65a2a2dedf9 --- /dev/null +++ b/public/images/pokemon/variant/back/167.json @@ -0,0 +1,24 @@ +{ + "1": { + "52b56b": "e5812a", + "000000": "ffffff", + "c5b519": "3f2e71", + "314a10": "641218", + "8ce631": "f2ba40", + "527b29": "d54f1a", + "846b29": "221b57", + "ffe64a": "624095" + }, + "2": { + "52b56b": "b54158", + "bdc5c5": "a1b7de", + "c5b519": "7d95b9", + "314a10": "481229", + "ffffff": "cde6fc", + "8ce631": "dd7081", + "527b29": "8c2848", + "846b29": "565e8d", + "ffe64a": "aac3d6", + "6b6b73": "62657d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/168.json b/public/images/pokemon/variant/back/168.json new file mode 100644 index 00000000000..7a4270ff9c0 --- /dev/null +++ b/public/images/pokemon/variant/back/168.json @@ -0,0 +1,29 @@ +{ + "1": { + "c54242": "62b943", + "6b5219": "043435", + "63319c": "e28220", + "bdbdbd": "b5d3dc", + "520000": "317945", + "ff5a4a": "a8d919", + "c5b54a": "15463c", + "ffde42": "186c45", + "ff8c73": "dce24b", + "bd84e6": "f1b940", + "6b6b6b": "5f7980" + }, + "2": { + "c54242": "7ca5c6", + "6b5219": "161437", + "63319c": "96304a", + "bdbdbd": "c09fa1", + "520000": "2d3d72", + "ff5a4a": "a3c8d1", + "c5b54a": "1f2150", + "ffffff": "fae8e7", + "ffde42": "313b60", + "ff8c73": "c4e8e7", + "bd84e6": "c8545d", + "6b6b6b": "605050" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/170.json b/public/images/pokemon/variant/back/170.json new file mode 100644 index 00000000000..6f6317314fb --- /dev/null +++ b/public/images/pokemon/variant/back/170.json @@ -0,0 +1,30 @@ +{ + "1": { + "08295a": "691f03", + "ffce52": "a1dbba", + "295294": "a14713", + "ffef84": "ccffd7", + "5a73c5": "dda13d", + "94cee6": "ffeabf", + "522919": "052b38", + "ffffde": "f2fff5", + "c59400": "84bda9", + "7bbde6": "ffe0a2", + "846352": "45757a", + "6ba5e6": "f6e37f" + }, + "2": { + "08295a": "1b072f", + "ffce52": "e25765", + "295294": "441e56", + "ffef84": "f97f7f", + "5a73c5": "693373", + "94cee6": "a15b8d", + "522919": "720b3a", + "ffffde": "ffc4be", + "c59400": "b62b51", + "7bbde6": "9f5a9b", + "846352": "931b3c", + "6ba5e6": "89498d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/171.json b/public/images/pokemon/variant/back/171.json new file mode 100644 index 00000000000..8a9cafe4265 --- /dev/null +++ b/public/images/pokemon/variant/back/171.json @@ -0,0 +1,30 @@ +{ + "1": { + "a5314a": "bf882c", + "4a7bce": "bc3c4c", + "423110": "05333a", + "ef635a": "efde5a", + "7badef": "f6907f", + "a5ceff": "fbcdb3", + "e6b552": "82ca4f", + "6394e6": "e86062", + "ffde63": "c3e875", + "ad9442": "2a8d3d", + "293173": "872341", + "7b634a": "0c5540" + }, + "2": { + "a5314a": "c3851d", + "4a7bce": "9781b3", + "423110": "040529", + "ef635a": "f0d050", + "7badef": "eecfed", + "a5ceff": "fbf5fa", + "e6b552": "3294b8", + "6394e6": "c5a5d0", + "ffde63": "4dd5d9", + "ad9442": "23689e", + "293173": "4b426c", + "7b634a": "0c1d4c" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/172-spiky.json b/public/images/pokemon/variant/back/172-spiky.json new file mode 100644 index 00000000000..f4c5e28b61a --- /dev/null +++ b/public/images/pokemon/variant/back/172-spiky.json @@ -0,0 +1,23 @@ +{ + "1": { + "c5ad10": "6cab9a", + "845a29": "45818a", + "a57b08": "5ca390", + "7d1c1c": "992424", + "e77b94": "bd4d5e", + "634a10": "30536b", + "f7e652": "a3d1a8" + }, + "2": { + "c5ad10": "4a6a90", + "845a29": "283567", + "171721": "9a4440", + "a57b08": "486a8e", + "212131": "d48d61", + "7d1c1c": "c38218", + "424252": "e7c17c", + "e77b94": "f5dd94", + "634a10": "2b2f54", + "f7e652": "7095ab" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/172-spiky_2.png b/public/images/pokemon/variant/back/172-spiky_2.png new file mode 100644 index 00000000000..9e9994d6b19 Binary files /dev/null and b/public/images/pokemon/variant/back/172-spiky_2.png differ diff --git a/public/images/pokemon/variant/back/172-spiky_3.png b/public/images/pokemon/variant/back/172-spiky_3.png new file mode 100644 index 00000000000..260de86af53 Binary files /dev/null and b/public/images/pokemon/variant/back/172-spiky_3.png differ diff --git a/public/images/pokemon/variant/back/172.json b/public/images/pokemon/variant/back/172.json new file mode 100644 index 00000000000..18c7f5bdee4 --- /dev/null +++ b/public/images/pokemon/variant/back/172.json @@ -0,0 +1,23 @@ +{ + "1": { + "c5ad10": "6cab9a", + "845a29": "45818a", + "a57b08": "5ca390", + "7d1c1c": "992424", + "e77b94": "bd4d5e", + "634a10": "30536b", + "f7e652": "a3d1a8" + }, + "2": { + "c5ad10": "4a6a90", + "845a29": "283567", + "171721": "9a4440", + "a57b08": "486a8e", + "212131": "d48d61", + "7d1c1c": "c38218", + "424252": "e7c17c", + "e77b94": "f5dd94", + "634a10": "2f335b", + "f7e652": "7095ab" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/172_2.png b/public/images/pokemon/variant/back/172_2.png new file mode 100644 index 00000000000..84a35b18ead Binary files /dev/null and b/public/images/pokemon/variant/back/172_2.png differ diff --git a/public/images/pokemon/variant/back/172_3.png b/public/images/pokemon/variant/back/172_3.png new file mode 100644 index 00000000000..b94789940f5 Binary files /dev/null and b/public/images/pokemon/variant/back/172_3.png differ diff --git a/public/images/pokemon/variant/back/174.json b/public/images/pokemon/variant/back/174.json new file mode 100644 index 00000000000..eaabbbc574d --- /dev/null +++ b/public/images/pokemon/variant/back/174.json @@ -0,0 +1,14 @@ +{ + "1": { + "9c1952": "3a6472", + "b55273": "43737d", + "e6849c": "81c2b8", + "ffadbd": "c5ebd5" + }, + "2": { + "9c1952": "9c5200", + "b55273": "a16b30", + "e6849c": "f5c45b", + "ffadbd": "f5e884" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/194.json b/public/images/pokemon/variant/back/194.json new file mode 100644 index 00000000000..83297ce4e5b --- /dev/null +++ b/public/images/pokemon/variant/back/194.json @@ -0,0 +1,20 @@ +{ + "1": { + "529ce6": "e8983d", + "9463a5": "65b1c2", + "633a6b": "204954", + "3a7bc5": "d5682e", + "73bdff": "ffc355", + "d65ad6": "81e2f7", + "104a84": "7a150a" + }, + "2": { + "529ce6": "564daa", + "9463a5": "cf933b", + "633a6b": "80301c", + "3a7bc5": "3f377e", + "73bdff": "5c66c4", + "d65ad6": "e9cb52", + "104a84": "180d42" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/195.json b/public/images/pokemon/variant/back/195.json new file mode 100644 index 00000000000..f79c398dc81 --- /dev/null +++ b/public/images/pokemon/variant/back/195.json @@ -0,0 +1,26 @@ +{ + "1": { + "ade6ff": "f6dfa8", + "84d6f7": "ed9e4f", + "637ba5": "936e66", + "639cbd": "dc6a4d", + "3194a5": "81e2f7", + "6b5a8c": "23768d", + "425284": "b03844", + "426b84": "af4237", + "195a6b": "54aec2", + "19423a": "204954" + }, + "2": { + "ade6ff": "9864c2", + "84d6f7": "724ba7", + "637ba5": "692d5d", + "639cbd": "493a8d", + "3194a5": "e9cb52", + "6b5a8c": "742f3d", + "425284": "240830", + "426b84": "3d237b", + "195a6b": "cf933b", + "19423a": "b96228" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/198.json b/public/images/pokemon/variant/back/198.json new file mode 100644 index 00000000000..eed8404265c --- /dev/null +++ b/public/images/pokemon/variant/back/198.json @@ -0,0 +1,26 @@ +{ + "1": { + "d94352": "8c1b23", + "314263": "462b20", + "efd684": "a6a6b3", + "d64252": "b3986b", + "42639c": "694c30", + "5a4a21": "25253b", + "292942": "2a1512", + "b59c21": "57566f", + "73293a": "755237", + "d6bd52": "838098" + }, + "2": { + "d94352": "8c1b23", + "314263": "0e4333", + "efd684": "c2723a", + "d64252": "bc4b84", + "42639c": "1d6e47", + "5a4a21": "4e1915", + "292942": "091e16", + "b59c21": "85412d", + "73293a": "7b2363", + "d6bd52": "9a5524" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/2026.json b/public/images/pokemon/variant/back/2026.json new file mode 100644 index 00000000000..4fb224dd489 --- /dev/null +++ b/public/images/pokemon/variant/back/2026.json @@ -0,0 +1,31 @@ +{ + "1": { + "b45f25": "2d5261", + "552720": "162f4b", + "f9ed9f": "eb999a", + "e9be14": "945c7b", + "e3882d": "3d7375", + "646124": "492652", + "ecd8b7": "b4c2a5", + "fffdfb": "d6d9ca", + "846b5b": "467f85", + "965821": "2f4e6b", + "dfc043": "d17577", + "602c24": "162f4b", + "fef443": "c48081", + "993c20": "1d3a57" + }, + "2": { + "b45f25": "bd8551", + "552720": "43617f", + "e9be14": "1a3551", + "e3882d": "d3b06f", + "646124": "122140", + "ecd8b7": "5a6f90", + "fffdfb": "6d8297", + "846b5b": "202746", + "965821": "9cb3ca", + "fef443": "3a5873", + "993c20": "965636" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/2103.json b/public/images/pokemon/variant/back/2103.json new file mode 100644 index 00000000000..2e97727835a --- /dev/null +++ b/public/images/pokemon/variant/back/2103.json @@ -0,0 +1,28 @@ +{ + "1": { + "2f9934": "dea44c", + "9f6b41": "426378", + "70442e": "283f5b", + "e6ac5a": "869fdc", + "522f16": "131d33", + "9cbd4a": "9977dd", + "fff68b": "a3c4ed", + "36cc36": "f4e774", + "2d5826": "c8592a", + "7b5210": "373e85", + "ffffcd": "d3efff" + }, + "2": { + "2f9934": "3d324b", + "9f6b41": "ffdbe7", + "70442e": "d59cba", + "e6ac5a": "c84e7f", + "522f16": "925b81", + "9cbd4a": "824a96", + "fff68b": "eb748d", + "36cc36": "6a5b73", + "2d5826": "1f1a31", + "7b5210": "4e1044", + "ffffcd": "ffa29d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/211.json b/public/images/pokemon/variant/back/211.json new file mode 100644 index 00000000000..01ae33500a4 --- /dev/null +++ b/public/images/pokemon/variant/back/211.json @@ -0,0 +1,22 @@ +{ + "1": { + "a5ad6b": "ad6643", + "194a52": "321128", + "dede94": "f1c17c", + "428494": "80294b", + "c5c57b": "dc9565", + "3a6363": "611a42", + "6b5231": "6d2c2c", + "73adb5": "a0415e" + }, + "2": { + "a5ad6b": "1e275b", + "194a52": "1c2f5b", + "dede94": "365492", + "428494": "60abdc", + "c5c57b": "2b3e7b", + "3a6363": "396796", + "6b5231": "181f46", + "73adb5": "8bd9ee" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25-beauty-cosplay.json b/public/images/pokemon/variant/back/25-beauty-cosplay.json new file mode 100644 index 00000000000..216262b149b --- /dev/null +++ b/public/images/pokemon/variant/back/25-beauty-cosplay.json @@ -0,0 +1,30 @@ +{ + "1": { + "5e5e6b": "6c6e60", + "f7e652": "a3d1a8", + "cecab9": "cfc8aa", + "f7e860": "eddc78", + "4d88c4": "7976c6", + "f7bd21": "79b5a5", + "2d276d": "2f2768", + "9c5200": "315c75", + "39509d": "47449c", + "fffdea": "f8ffe3", + "f7cc2f": "d5ac44" + }, + "2": { + "1e1526": "a45233", + "5e5e6b": "8a2554", + "f7e652": "577b98", + "cecab9": "b84084", + "f7e860": "eddc78", + "4d88c4": "e4f6f1", + "f7bd21": "486689", + "2d276d": "454a61", + "9c5200": "283361", + "39509d": "9ec4cd", + "fffdea": "ea82a6", + "4f454c": "f1b571", + "f7cc2f": "d5ac44" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25-cool-cosplay.json b/public/images/pokemon/variant/back/25-cool-cosplay.json new file mode 100644 index 00000000000..278feb070bd --- /dev/null +++ b/public/images/pokemon/variant/back/25-cool-cosplay.json @@ -0,0 +1,31 @@ +{ + "1": { + "171717": "2a1d36", + "c52119": "ad4e76", + "842222": "7b1f18", + "f7e652": "a3d1a8", + "fff7a5": "c4e3c3", + "f7bd21": "79b5a5", + "ba2b23": "b73850", + "9c5200": "1c4f75", + "d95b45": "cf6887", + "3b3b40": "4a3e46" + }, + "2": { + "171717": "a45233", + "656f86": "cf752b", + "a5b0b6": "f0b541", + "c52119": "ebc67c", + "842222": "1e1e43", + "f7e652": "577b98", + "fff7a5": "7b96aa", + "f7bd21": "445f8a", + "ba2b23": "2c2c47", + "55555e": "8f4b32", + "9c5200": "22325c", + "f4f7ab": "eadbb3", + "d95b45": "3a3f5e", + "3b3b40": "f1b571", + "272b2b": "7d3833" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25-cosplay.json b/public/images/pokemon/variant/back/25-cosplay.json new file mode 100644 index 00000000000..c574d63d743 --- /dev/null +++ b/public/images/pokemon/variant/back/25-cosplay.json @@ -0,0 +1,26 @@ +{ + "1": { + "f7e652": "a3d1a8", + "fff7a5": "c4e3c3", + "c52119": "ad4e76", + "f7bd21": "79b5a5", + "52525a": "4f454c", + "9c5200": "315c75", + "292929": "1e1526", + "633108": "09406b", + "e65a42": "cf6182", + "de9400": "338087" + }, + "2": { + "f7e652": "577b98", + "fff7a5": "7b96aa", + "c52119": "ebc67c", + "f7bd21": "445f8a", + "52525a": "f1b571", + "9c5200": "23345e", + "292929": "a45233", + "633108": "22244f", + "e65a42": "eedd9c", + "de9400": "324472" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25-cute-cosplay.json b/public/images/pokemon/variant/back/25-cute-cosplay.json new file mode 100644 index 00000000000..7b26b79d08f --- /dev/null +++ b/public/images/pokemon/variant/back/25-cute-cosplay.json @@ -0,0 +1,32 @@ +{ + "1": { + "752bd0": "5452b7", + "baa998": "bab699", + "fff7a5": "c4e3c3", + "f7e652": "a3d1a8", + "ea82a6": "e8848e", + "cf4770": "cf4a59", + "f3bace": "f2bbbb", + "853247": "85323c", + "f7ef97": "f0eaa8", + "52525a": "4f454c", + "292929": "30263b", + "f7bd21": "79b5a5", + "9c5200": "255e8a" + }, + "2": { + "752bd0": "7751c2", + "baa998": "d3ab5a", + "fff7a5": "7b96aa", + "f7e652": "577b98", + "ea82a6": "a4b95f", + "cf4770": "739b55", + "f3bace": "c5cc85", + "853247": "254b30", + "f7ef97": "ebe7b7", + "52525a": "f1b571", + "292929": "a45233", + "f7bd21": "445f8a", + "9c5200": "23345e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25-gigantamax.json b/public/images/pokemon/variant/back/25-gigantamax.json new file mode 100644 index 00000000000..1c47104e04d --- /dev/null +++ b/public/images/pokemon/variant/back/25-gigantamax.json @@ -0,0 +1,30 @@ +{ + "1": { + "623108": "09406b", + "c52018": "ad4e76", + "de9400": "338087", + "fefefe": "ffffff", + "f6bd20": "79b5a5", + "fff6a4": "c4e3c3", + "fff9c2": "b8ffd9", + "e65a41": "cf6182", + "9c5200": "315c75", + "f8fc4b": "5bc28b", + "f6e652": "a3d1a8" + }, + "2": { + "623108": "22244f", + "c52018": "ebc67c", + "de9400": "324472", + "fefefe": "ffffff", + "f6bd20": "445f8a", + "fff6a4": "7b96aa", + "fff9c2": "83b1d2", + "e65a41": "eedd9c", + "9c5200": "23345e", + "f8fc4b": "326a9f", + "695d65": "f1b571", + "f6e652": "577b98", + "323133": "d99362" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25-partner.json b/public/images/pokemon/variant/back/25-partner.json new file mode 100644 index 00000000000..c20fae48a34 --- /dev/null +++ b/public/images/pokemon/variant/back/25-partner.json @@ -0,0 +1,26 @@ +{ + "1": { + "45454a": "4f454c", + "9c5200": "315c75", + "de9400": "338087", + "171717": "1e1526", + "c52119": "ad4e76", + "633108": "09406b", + "e65a42": "cf6182", + "f7e652": "a3d1a8", + "fff7a5": "c4e3c3", + "f7bd21": "79b5a5" + }, + "2": { + "45454a": "f1b571", + "9c5200": "23345e", + "de9400": "324472", + "171717": "a45233", + "c52119": "ebc67c", + "633108": "22244f", + "e65a42": "eedd9c", + "f7e652": "577b98", + "fff7a5": "7b96aa", + "f7bd21": "445f8a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25-smart-cosplay.json b/public/images/pokemon/variant/back/25-smart-cosplay.json new file mode 100644 index 00000000000..50749b31d8b --- /dev/null +++ b/public/images/pokemon/variant/back/25-smart-cosplay.json @@ -0,0 +1,32 @@ +{ + "1": { + "fffdea": "f8ffe3", + "b7a599": "bab699", + "60b553": "76a848", + "f7e652": "a3d1a8", + "366635": "3e5b2f", + "95635b": "91685f", + "171717": "1e1526", + "5f3434": "573b38", + "54545c": "55555e", + "52525a": "4f454c", + "292929": "272b2b", + "f7bd21": "79b5a5", + "9c5200": "315c75" + }, + "2": { + "fffdea": "f2f0df", + "b7a599": "a7b6b9", + "60b553": "dfb053", + "f7e652": "577b98", + "366635": "ab5130", + "95635b": "a09ea3", + "171717": "a45233", + "5f3434": "666060", + "54545c": "45525c", + "52525a": "f1b571", + "292929": "202937", + "f7bd21": "445f8a", + "9c5200": "23345e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25-tough-cosplay.json b/public/images/pokemon/variant/back/25-tough-cosplay.json new file mode 100644 index 00000000000..49c50d17ad2 --- /dev/null +++ b/public/images/pokemon/variant/back/25-tough-cosplay.json @@ -0,0 +1,35 @@ +{ + "1": { + "e37511": "d1694f", + "bf2629": "cf6a59", + "8d2b1d": "bf3638", + "c52119": "ad4e76", + "46464d": "2b3340", + "292929": "1e1526", + "f7bd21": "79b5a5", + "fbab33": "de9764", + "e65a42": "cf6182", + "cecab9": "cfc8aa", + "52525a": "4f454c", + "f7e652": "a3d1a8", + "9c5200": "315c75" + }, + "2": { + "e37511": "60448d", + "bf2629": "826694", + "f8ffe3": "e8e3e4", + "8d2b1d": "3d3f7d", + "c52119": "ebc67c", + "46464d": "2b3340", + "292929": "a45233", + "f7bd21": "445f8a", + "fbab33": "845ea1", + "e65a42": "eedd9c", + "cecab9": "beb1b4", + "8e2525": "242866", + "52525a": "f1b571", + "f7e652": "577b98", + "272b2b": "162231", + "9c5200": "23345e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/25.json b/public/images/pokemon/variant/back/25.json new file mode 100644 index 00000000000..c20fae48a34 --- /dev/null +++ b/public/images/pokemon/variant/back/25.json @@ -0,0 +1,26 @@ +{ + "1": { + "45454a": "4f454c", + "9c5200": "315c75", + "de9400": "338087", + "171717": "1e1526", + "c52119": "ad4e76", + "633108": "09406b", + "e65a42": "cf6182", + "f7e652": "a3d1a8", + "fff7a5": "c4e3c3", + "f7bd21": "79b5a5" + }, + "2": { + "45454a": "f1b571", + "9c5200": "23345e", + "de9400": "324472", + "171717": "a45233", + "c52119": "ebc67c", + "633108": "22244f", + "e65a42": "eedd9c", + "f7e652": "577b98", + "fff7a5": "7b96aa", + "f7bd21": "445f8a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/26.json b/public/images/pokemon/variant/back/26.json new file mode 100644 index 00000000000..758faf12c97 --- /dev/null +++ b/public/images/pokemon/variant/back/26.json @@ -0,0 +1,34 @@ +{ + "1": { + "63636b": "4f454c", + "101011": "293059", + "944242": "395a80", + "bd5a31": "386d82", + "e6bd84": "a4bda7", + "ffbd00": "b3596b", + "5a2929": "293059", + "3a3a42": "30263b", + "8c6310": "8c3c4c", + "ffde5a": "cf7878", + "f7ad29": "76a68b", + "734231": "6e2f33", + "ffefd6": "c8d4ba", + "de7b31": "539190" + }, + "2": { + "542127": "905331", + "101011": "202a60", + "944242": "2d3b80", + "bd5a31": "375681", + "e6bd84": "a6b5ab", + "ffbd00": "f3cf91", + "5a2929": "202a60", + "8c6310": "c79b5a", + "ffde5a": "f2e4b6", + "f7ad29": "6385ab", + "734231": "bf8445", + "ffefd6": "cfc4b5", + "de7b31": "4d6f98", + "643034": "2e4685" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/276.json b/public/images/pokemon/variant/back/276.json new file mode 100644 index 00000000000..e0fb6b93467 --- /dev/null +++ b/public/images/pokemon/variant/back/276.json @@ -0,0 +1,32 @@ +{ + "1": { + "bdbdcc": "b5b5d5", + "bdbdce": "26523c", + "943a52": "ad8634", + "ffffff": "3c6a3d", + "a57331": "784524", + "212952": "12223d", + "3a3a31": "3e3e3e", + "5a6b9c": "2a596b", + "e69410": "bc7532", + "524a29": "4b210d", + "fffffd": "fffffe", + "314a7b": "1a385a", + "ce5273": "cebf49" + }, + "2": { + "bdbdcc": "b5b5d5", + "bdbdce": "453f63", + "943a52": "8ec08b", + "ffffff": "635d81", + "a57331": "4a323a", + "212952": "191222", + "3a3a31": "442c34", + "5a6b9c": "3c2f48", + "e69410": "63414f", + "524a29": "381f2c", + "fffffd": "fffffe", + "314a7b": "282037", + "ce5273": "bcd59d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/277.json b/public/images/pokemon/variant/back/277.json new file mode 100644 index 00000000000..5a3e049f5f5 --- /dev/null +++ b/public/images/pokemon/variant/back/277.json @@ -0,0 +1,36 @@ +{ + "1": { + "dea531": "bc7532", + "425a7b": "2a596b", + "ffffff": "3c6a3d", + "b5b5d6": "26523c", + "9c3152": "ad8634", + "945a10": "784524", + "5a5a5a": "b58251", + "63213a": "603c1d", + "c55a73": "cebf49", + "294263": "1a385a", + "292952": "12223d", + "fffffd": "fffffe", + "524221": "4b210d", + "b5b5d4": "b5b5d5", + "31313a": "89572a" + }, + "2": { + "dea531": "63414f", + "425a7b": "3c2f48", + "ffffff": "635d81", + "b5b5d6": "453f63", + "9c3152": "8ec08b", + "945a10": "4a323a", + "5a5a5a": "5d454d", + "63213a": "5d9469", + "c55a73": "bcd59d", + "294263": "282037", + "292952": "191222", + "fffffd": "fffffe", + "524221": "381f2c", + "b5b5d4": "b5b5d5", + "31313a": "442c34" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/359-mega.json b/public/images/pokemon/variant/back/359-mega.json new file mode 100644 index 00000000000..d81d313a1de --- /dev/null +++ b/public/images/pokemon/variant/back/359-mega.json @@ -0,0 +1,24 @@ +{ + "1": { + "ffffff": "61a8ab", + "414a6a": "421e4a", + "b4b4d5": "458196", + "293939": "27122b", + "8b8bac": "3b6987", + "525a7b": "59274e", + "d5deee": "589aa6", + "737bac": "874267", + "626283": "2a3163" + }, + "2": { + "ffffff": "9e363b", + "414a6a": "b39279", + "b4b4d5": "752f40", + "293939": "996e5f", + "8b8bac": "59213b", + "525a7b": "dfd1ae", + "d5deee": "8f2f41", + "737bac": "f5f1cb", + "626283": "42122d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/359.json b/public/images/pokemon/variant/back/359.json new file mode 100644 index 00000000000..4ccca6800b3 --- /dev/null +++ b/public/images/pokemon/variant/back/359.json @@ -0,0 +1,24 @@ +{ + "1": { + "424a6b": "421e4a", + "293a3a": "27122b", + "737bad": "874267", + "d6deef": "589aa6", + "525a7b": "612b54", + "8c8cad": "3b6987", + "636384": "2a3163", + "b5b5d6": "458196", + "ffffff": "61a8ab" + }, + "2": { + "424a6b": "b39279", + "293a3a": "996e5f", + "737bad": "f5f1cb", + "d6deef": "8f2f41", + "525a7b": "e0c79f", + "8c8cad": "59213b", + "636384": "42122d", + "b5b5d6": "752f40", + "ffffff": "9e363b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/377.json b/public/images/pokemon/variant/back/377.json new file mode 100644 index 00000000000..1ab9bce073f --- /dev/null +++ b/public/images/pokemon/variant/back/377.json @@ -0,0 +1,26 @@ +{ + "1": { + "b54200": "13512f", + "efad6b": "aac669", + "948c73": "2e4e7b", + "cec5ad": "4d8ba8", + "bd633a": "22773f", + "ef843a": "56963a", + "b5ad94": "3d6d8d", + "e6dead": "659db5", + "524a29": "182238", + "efe6de": "84c7ca" + }, + "2": { + "b54200": "3d0933", + "efad6b": "a54c5e", + "948c73": "262847", + "cec5ad": "303353", + "bd633a": "561934", + "ef843a": "722a41", + "b5ad94": "394170", + "e6dead": "383e6a", + "524a29": "161129", + "efe6de": "4d5784" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/378.json b/public/images/pokemon/variant/back/378.json new file mode 100644 index 00000000000..74ef70cbcec --- /dev/null +++ b/public/images/pokemon/variant/back/378.json @@ -0,0 +1,29 @@ +{ + "0": { + "ffffff": "d7b6f1", + "6bb5d6": "414184", + "293a7b": "101238", + "9cceff": "6f66a7", + "3a6b8c": "191d4c", + "bdefff": "9983c4", + "5a84ad": "282e64" + }, + "1": { + "6bb5d6": "bf344a", + "bdefff": "ffb88d", + "9cceff": "eb5d56", + "293a7b": "400b1c", + "ffffff": "fff7d3", + "3a6b8c": "64132c", + "5a84ad": "981d43" + }, + "2": { + "6bb5d6": "323232", + "bdefff": "5b5b5b", + "9cceff": "424242", + "293a7b": "100f17", + "ffffff": "8c8c8c", + "3a6b8c": "14131a", + "5a84ad": "212121" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/379.json b/public/images/pokemon/variant/back/379.json new file mode 100644 index 00000000000..e99b7d8c171 --- /dev/null +++ b/public/images/pokemon/variant/back/379.json @@ -0,0 +1,26 @@ +{ + "1": { + "4a5a5a": "34366f", + "3a4252": "292960", + "d6ced6": "cc9c65", + "848c84": "4c5c91", + "ffffff": "fff3aa", + "dedede": "f0d185", + "b5adad": "a66f52", + "4a4a4a": "533329", + "84847b": "80503b", + "3e4f4f": "542618" + }, + "2": { + "4a5a5a": "df8533", + "3a4252": "e29631", + "d6ced6": "cd5521", + "848c84": "ffcd49", + "ffffff": "ffb056", + "dedede": "e87537", + "b5adad": "ad2d1e", + "4a4a4a": "521328", + "84847b": "81222b", + "3e4f4f": "54051f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/39.json b/public/images/pokemon/variant/back/39.json new file mode 100644 index 00000000000..59d78f7958a --- /dev/null +++ b/public/images/pokemon/variant/back/39.json @@ -0,0 +1,16 @@ +{ + "1": { + "6b5263": "153427", + "ffada5": "c5ebd5", + "e67384": "81c2b8", + "a51021": "3a6472", + "ffcec5": "e5ffec" + }, + "2": { + "6b5263": "737454", + "ffada5": "f5e884", + "e67384": "f5c45b", + "a51021": "9c5200", + "ffcec5": "fff9bf" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/390.json b/public/images/pokemon/variant/back/390.json new file mode 100644 index 00000000000..94bfe837547 --- /dev/null +++ b/public/images/pokemon/variant/back/390.json @@ -0,0 +1,32 @@ +{ + "1": { + "7a410f": "994943", + "e63131": "1db978", + "b56b29": "64464d", + "9c3131": "2d8766", + "947308": "a86256", + "7b4210": "382029", + "ef6b6b": "81dc3f", + "f06e6e": "76c96d", + "ffd631": "eafe67", + "ffe6ad": "edc6a4", + "e63a42": "5db95b", + "de8400": "876766", + "deb552": "cc9176" + }, + "2": { + "7a410f": "626678", + "e63131": "b5b0f3", + "b56b29": "293b69", + "9c3131": "422e6f", + "947308": "818596", + "7b4210": "171f46", + "ef6b6b": "cbcfff", + "f06e6e": "cb96e5", + "ffd631": "f3f8fe", + "ffe6ad": "d3d5e0", + "e63a42": "8457b0", + "de8400": "3e5f8a", + "deb552": "a5a9b8" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/391.json b/public/images/pokemon/variant/back/391.json new file mode 100644 index 00000000000..6c21033ceba --- /dev/null +++ b/public/images/pokemon/variant/back/391.json @@ -0,0 +1,36 @@ +{ + "1": { + "8c7342": "a86256", + "cf451b": "2d8766", + "c59463": "cc9176", + "dee6e6": "dac99d", + "9c5219": "64464d", + "ffffff": "faf7d4", + "735a10": "6b2b28", + "efce94": "edc6a4", + "ffce42": "eafe67", + "ffcd45": "f69044", + "1052b5": "ba2342", + "6b3a08": "382029", + "d68c29": "876766", + "ce4219": "1db978", + "efa542": "cd5528" + }, + "2": { + "8c7342": "818596", + "cf451b": "8457b0", + "c59463": "a5a9b8", + "dee6e6": "dca15d", + "9c5219": "293b69", + "ffffff": "ffe175", + "735a10": "626678", + "efce94": "d3d5e0", + "ffce42": "f3f8fe", + "ffcd45": "e8fdff", + "1052b5": "e09f2f", + "6b3a08": "171f46", + "d68c29": "3e5f8a", + "ce4219": "b5b0f3", + "efa542": "b0cbd4" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/392.json b/public/images/pokemon/variant/back/392.json new file mode 100644 index 00000000000..44c2930f77d --- /dev/null +++ b/public/images/pokemon/variant/back/392.json @@ -0,0 +1,42 @@ +{ + "1": { + "e68c5a": "876766", + "6b3a10": "382029", + "e63740": "2d8766", + "bdc5de": "dac99d", + "a56342": "64464d", + "845a08": "9b2719", + "737384": "9f8876", + "ffdf4f": "eafe67", + "e63a42": "1db978", + "c59c21": "cd5528", + "ffde52": "f69044", + "ffdd47": "e8a82a", + "c79e22": "cf8021", + "ffffff": "faf7d4", + "19427b": "581225", + "f78c4a": "81dc3f", + "3a73a5": "972733", + "842931": "174c48" + }, + "2": { + "e68c5a": "3e5f8a", + "6b3a10": "171f46", + "e63740": "8457b0", + "bdc5de": "dca15d", + "a56342": "293b69", + "845a08": "617995", + "737384": "a15a34", + "ffdf4f": "f3f8fe", + "e63a42": "b5b0f3", + "c59c21": "a0c0cd", + "ffde52": "e8fdff", + "ffdd47": "fff8e5", + "c79e22": "ccbdab", + "ffffff": "ffe175", + "19427b": "4d5196", + "f78c4a": "cbcfff", + "3a73a5": "9c96e2", + "842931": "422e6f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/40.json b/public/images/pokemon/variant/back/40.json new file mode 100644 index 00000000000..21e5ef69cd1 --- /dev/null +++ b/public/images/pokemon/variant/back/40.json @@ -0,0 +1,17 @@ +{ + "1": { + "f77b94": "81c2b8", + "ce6b63": "82b8a9", + "8c4242": "3a6472", + "ffadbd": "c5ebd5" + }, + "2": { + "737373": "3b1f24", + "f77b94": "f5c45b", + "ffffff": "d07439", + "ce6b63": "e6a54c", + "e6dee6": "bc4e24", + "8c4242": "9c5200", + "ffadbd": "f5e884" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/430.json b/public/images/pokemon/variant/back/430.json new file mode 100644 index 00000000000..2edd26708c9 --- /dev/null +++ b/public/images/pokemon/variant/back/430.json @@ -0,0 +1,34 @@ +{ + "1": { + "31313a": "280113", + "8c313a": "b3986b", + "5a5a3a": "1e1e2c", + "545454": "3c3b4d", + "a3a3b5": "7a1e21", + "3a5a9c": "694c30", + "525151": "380514", + "a7a7b8": "60606c", + "efeff8": "b9382d", + "4a2121": "755237", + "ad943a": "3f3e50", + "f7de3a": "61616d", + "3a3a5a": "422e26", + "29213a": "271b1a" + }, + "2": { + "31313a": "080735", + "8c313a": "bc4b84", + "5a5a3a": "4e1915", + "545454": "85412d", + "a3a3b5": "4f358e", + "3a5a9c": "1d6e47", + "525151": "1c1754", + "a7a7b8": "c27238", + "efeff8": "975bc2", + "4a2121": "7b2363", + "ad943a": "85402c", + "f7de3a": "c2723a", + "3a3a5a": "0e4333", + "29213a": "091e16" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/455.json b/public/images/pokemon/variant/back/455.json new file mode 100644 index 00000000000..d10a2ff0741 --- /dev/null +++ b/public/images/pokemon/variant/back/455.json @@ -0,0 +1,34 @@ +{ + "1": { + "f7ce31": "7c5d53", + "9c214a": "451e14", + "2b453d": "523b3c", + "3a5a3a": "b34a82", + "5a6342": "826660", + "8c9452": "b89d8c", + "846b31": "301e20", + "bdc57b": "efd9ba", + "e62919": "775331", + "63843a": "e880ab", + "8f9653": "e2b0bc", + "29423a": "7e3b67", + "c59c31": "4d3432" + }, + "2": { + "f7ce31": "518078", + "ffffff": "affffe", + "9c214a": "1e4340", + "2b453d": "151926", + "3a5a3a": "37818a", + "5a6342": "2d304e", + "8c9452": "424d6e", + "846b31": "122e2f", + "bdc57b": "6679a1", + "e62919": "406b64", + "63843a": "74ddcd", + "422919": "0d2626", + "8f9653": "3d909b", + "29423a": "123247", + "c59c31": "244a45" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/486.json b/public/images/pokemon/variant/back/486.json new file mode 100644 index 00000000000..36a343a2966 --- /dev/null +++ b/public/images/pokemon/variant/back/486.json @@ -0,0 +1,32 @@ +{ + "1": { + "fafafa": "ffc245", + "adadc5": "ca7426", + "8c94ad": "13081a", + "374859": "6b76a4", + "d6ced6": "e89b34", + "f7d65a": "ce5129", + "5f6d7d": "7b2a19", + "ffffff": "eb8746", + "21846b": "90a7cd", + "3a4a5a": "5e1e33", + "c59c52": "a12612", + "7b6321": "3d021b", + "4aa563": "e2f2ff" + }, + "2": { + "fafafa": "88b06f", + "adadc5": "4f673a", + "8c94ad": "494922", + "374859": "2f1a18", + "d6ced6": "6e884b", + "f7d65a": "8f9b9e", + "5f6d7d": "374427", + "ffffff": "a8afaf", + "21846b": "492f29", + "3a4a5a": "3b1930", + "c59c52": "5d717a", + "7b6321": "384751", + "4aa563": "755648" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/501.json b/public/images/pokemon/variant/back/501.json new file mode 100644 index 00000000000..3476b2710b1 --- /dev/null +++ b/public/images/pokemon/variant/back/501.json @@ -0,0 +1,24 @@ +{ + "1": { + "215a63": "1e1a35", + "c5c5ce": "e3c2ca", + "4a6bad": "9660d1", + "294252": "241e44", + "21949c": "373049", + "29bdc5": "5d4a70", + "31426b": "4b349e", + "212142": "241e44" + }, + "2": { + "8c8c9c": "8f7491", + "4a4a4a": "715b72", + "215a63": "000000", + "c5c5ce": "ba9bc1", + "4a6bad": "589787", + "21949c": "321e1e", + "29bdc5": "5e3e38", + "31426b": "3c706b", + "ffffff": "f5e9f4", + "212142": "104432" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/502.json b/public/images/pokemon/variant/back/502.json new file mode 100644 index 00000000000..26772013df7 --- /dev/null +++ b/public/images/pokemon/variant/back/502.json @@ -0,0 +1,28 @@ +{ + "1": { + "4a4a4a": "20193d", + "31528c": "9d5bc9", + "293a6b": "503e8e", + "7b5a10": "d877cd", + "52bdbd": "624060", + "c59429": "ff9ef3", + "efd68c": "f2d5ee", + "313131": "120f33", + "315a73": "1e1624", + "218c94": "39273d", + "fffdfd": "ebb9c4" + }, + "2": { + "4a4a4a": "2c3940", + "31528c": "5e3e38", + "293a6b": "321e1e", + "7b5a10": "0d5656", + "52bdbd": "8b7566", + "c59429": "488383", + "efd68c": "63c7bd", + "313131": "1f2b36", + "315a73": "483026", + "218c94": "684f44", + "fffdfd": "ffffc2" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/503.json b/public/images/pokemon/variant/back/503.json new file mode 100644 index 00000000000..9eb2168dd5b --- /dev/null +++ b/public/images/pokemon/variant/back/503.json @@ -0,0 +1,33 @@ +{ + "1": { + "84a5a5": "563785", + "4a4a4a": "5e283e", + "215a9c": "4d244b", + "8aa3a3": "a05982", + "d65263": "b73891", + "ad945a": "db87d1", + "7b6342": "975fad", + "474a46": "2b1838", + "fffeff": "ebb9c4", + "213a63": "28142c", + "4a4a4c": "6b3e51", + "d6c57b": "f2d5ee", + "5a7373": "332a59", + "8da8a8": "a58b90" + }, + "2": { + "4a4a4a": "c2700d", + "215a9c": "5e3e38", + "8aa3a3": "efa838", + "d65263": "41857b", + "ad945a": "488383", + "7b6342": "0d5656", + "474a46": "462d27", + "fffeff": "f9df58", + "213a63": "321e1e", + "4a4a4c": "c2700d", + "d6c57b": "63c7bd", + "5a7373": "2a5c57", + "8da8a8": "84a5a5" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/527.json b/public/images/pokemon/variant/back/527.json new file mode 100644 index 00000000000..67767eefcb3 --- /dev/null +++ b/public/images/pokemon/variant/back/527.json @@ -0,0 +1,20 @@ +{ + "1": { + "424a5a": "866ca1", + "6b94ad": "6e315e", + "73adc5": "853e66", + "292931": "55457a", + "addef7": "914a6e", + "4a6b7b": "562259", + "27272f": "361538" + }, + "2": { + "424a5a": "bf3f75", + "6b94ad": "db843d", + "73adc5": "e8b04f", + "292931": "8c2961", + "addef7": "f7e05c", + "4a6b7b": "994d22", + "27272f": "7c3622" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/528.json b/public/images/pokemon/variant/back/528.json new file mode 100644 index 00000000000..fb91d0318a5 --- /dev/null +++ b/public/images/pokemon/variant/back/528.json @@ -0,0 +1,30 @@ +{ + "1": { + "317b94": "6e315e", + "4c4c54": "582253", + "313131": "55457a", + "de8c84": "6bc7e8", + "6b7b84": "439ca1", + "ceefff": "a6ffd7", + "bdbdce": "76debd", + "19a5ce": "914a6e", + "944a4a": "4874b8", + "313132": "451b41", + "4a4a52": "866ca1", + "47474f": "2e6f7a" + }, + "2": { + "317b94": "e0b49a", + "4c4c54": "a6705e", + "313131": "701c4c", + "de8c84": "7b5ebf", + "6b7b84": "994d22", + "ceefff": "f7e05c", + "bdbdce": "db843d", + "19a5ce": "f9fae3", + "944a4a": "393582", + "313132": "a87354", + "4a4a52": "bf3f75", + "47474f": "6b2314" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/587.json b/public/images/pokemon/variant/back/587.json new file mode 100644 index 00000000000..85c4c20f4f0 --- /dev/null +++ b/public/images/pokemon/variant/back/587.json @@ -0,0 +1,28 @@ +{ + "1": { + "212121": "1d352a", + "d6a531": "a84223", + "b58c08": "681c0e", + "bda573": "5a9fbf", + "6b5a31": "16223d", + "cec5ad": "8bd5dc", + "7f6b0d": "3b1c1b", + "846e07": "35708c", + "ffd600": "d55b19", + "9c9c73": "406da4", + "313131": "2b5d3f" + }, + "2": { + "212121": "372a5b", + "d6a531": "6597cd", + "b58c08": "4879af", + "bda573": "9b4072", + "6b5a31": "321832", + "cec5ad": "c4658e", + "7f6b0d": "355c90", + "846e07": "723158", + "ffd600": "8bcaee", + "9c9c73": "7b3760", + "313131": "5e3a86" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/588.json b/public/images/pokemon/variant/back/588.json new file mode 100644 index 00000000000..c00f1886940 --- /dev/null +++ b/public/images/pokemon/variant/back/588.json @@ -0,0 +1,20 @@ +{ + "1": { + "213a5a": "2f185b", + "316bff": "8150a7", + "4a4a4a": "64242d", + "313131": "38131d", + "000000": "ffffff", + "528cff": "c682d6", + "3a5284": "492c72" + }, + "2": { + "213a5a": "44446f", + "316bff": "d2cdeb", + "4a4a4a": "28334f", + "313131": "182138", + "000000": "ffffff", + "528cff": "f9f3ff", + "3a5284": "7777a7" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/589.json b/public/images/pokemon/variant/back/589.json new file mode 100644 index 00000000000..b499504daa3 --- /dev/null +++ b/public/images/pokemon/variant/back/589.json @@ -0,0 +1,30 @@ +{ + "1": { + "c5c5c5": "f9c347", + "ef2952": "eb8343", + "bd2152": "c44126", + "840808": "931119", + "bd9c19": "b8c5e5", + "e65a10": "614593", + "6b6b6b": "b34516", + "294a84": "7436a4", + "195abd": "9448bf", + "94949c": "dc862d", + "000000": "ffffff", + "3a424a": "69130d" + }, + "2": { + "c5c5c5": "6e8e99", + "ef2952": "f7efff", + "bd2152": "beb7df", + "840808": "72709e", + "bd9c19": "a42641", + "e65a10": "ffe8c3", + "6b6b6b": "293a52", + "294a84": "4f3d33", + "195abd": "785442", + "94949c": "3f6372", + "000000": "ffffff", + "3a424a": "1b253d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/590.json b/public/images/pokemon/variant/back/590.json new file mode 100644 index 00000000000..7d19153ec2c --- /dev/null +++ b/public/images/pokemon/variant/back/590.json @@ -0,0 +1,30 @@ +{ + "1": { + "684c30": "0d9999", + "9c3a3a": "71de8c", + "846b63": "0fad9a", + "9c3a7b": "88af70", + "6b4a31": "0d9999", + "422929": "0a5870", + "7b3131": "49ad77", + "de5a52": "e6ffc1", + "d6639c": "f4ebba", + "7a3730": "49aa87", + "c5b59c": "47d1b5", + "fff7e6": "afecc6" + }, + "2": { + "684c30": "2b5caf", + "9c3a3a": "e098cd", + "846b63": "64a3bc", + "9c3a7b": "b1c4dd", + "6b4a31": "f2f7f9", + "422929": "b9d9e5", + "7b3131": "ad629a", + "de5a52": "ffbfcb", + "d6639c": "f2f7f9", + "7a3730": "404f6b", + "c5b59c": "498cd3", + "fff7e6": "6ac2e2" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/591.json b/public/images/pokemon/variant/back/591.json new file mode 100644 index 00000000000..0d369a42c02 --- /dev/null +++ b/public/images/pokemon/variant/back/591.json @@ -0,0 +1,28 @@ +{ + "1": { + "cec5c5": "afecc6", + "291919": "094164", + "de528c": "e6ffc1", + "634c42": "348999", + "423331": "094164", + "9c9484": "47d1b5", + "634d42": "0c7588", + "634a42": "0d9999", + "423131": "0a5870", + "6b314a": "49ad77", + "ad3163": "71de8c" + }, + "2": { + "cec5c5": "6ac2e2", + "291919": "5e718e", + "de528c": "ffbfcb", + "634c42": "3f7dc7", + "423331": "223656", + "9c9484": "56a1e2", + "634d42": "2b5caf", + "634a42": "f2f7f9", + "423131": "9bb6c1", + "6b314a": "ad629a", + "ad3163": "e098cd" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/616.json b/public/images/pokemon/variant/back/616.json new file mode 100644 index 00000000000..a883b42edc8 --- /dev/null +++ b/public/images/pokemon/variant/back/616.json @@ -0,0 +1,26 @@ +{ + "1": { + "3a8442": "4e3671", + "5a5a7b": "b34516", + "9494ad": "dc862d", + "630021": "204b4f", + "b5214a": "346c65", + "ff4a7b": "6ba779", + "de3163": "4a8474", + "29315a": "69130d", + "c5c5d6": "f9c347", + "000000": "ffffff" + }, + "2": { + "3a8442": "d6aa53", + "5a5a7b": "293a52", + "9494ad": "3f6372", + "630021": "2e3469", + "b5214a": "4f62a4", + "ff4a7b": "8cb0d6", + "de3163": "6b8bbf", + "29315a": "1b253d", + "c5c5d6": "6e8e99", + "000000": "ffffff" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/617.json b/public/images/pokemon/variant/back/617.json new file mode 100644 index 00000000000..93310065d35 --- /dev/null +++ b/public/images/pokemon/variant/back/617.json @@ -0,0 +1,30 @@ +{ + "1": { + "ffffff": "fff47e", + "a5846b": "5a6675", + "42b55a": "4e3671", + "c53a6b": "427b6b", + "636363": "c46d31", + "bdbdce": "df9847", + "527b42": "362658", + "732931": "214c49", + "ff4a7b": "6ba779", + "6b84c5": "eef5ff", + "293a6b": "69719e", + "000000": "ffffff", + "3a2919": "192638", + "5a6384": "b8c5e5" + }, + "2": { + "a5846b": "637974", + "42b55a": "415c69", + "c53a6b": "dcaa47", + "527b42": "2d3d52", + "ff4a7b": "ffee72", + "6b84c5": "b43d40", + "293a6b": "461b2e", + "000000": "ffffff", + "3a2919": "2a2235", + "5a6384": "7b2c3d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/621.json b/public/images/pokemon/variant/back/621.json new file mode 100644 index 00000000000..cf80562d31f --- /dev/null +++ b/public/images/pokemon/variant/back/621.json @@ -0,0 +1,26 @@ +{ + "1": { + "8c7b5a": "73654b", + "940042": "1a2248", + "104a8c": "7e231b", + "635231": "605127", + "efc500": "5c7886", + "103163": "601111", + "521031": "0f1330", + "d60042": "26335d", + "316bad": "a13b2c", + "d65273": "be5b5e" + }, + "2": { + "8c7b5a": "da8921", + "940042": "177297", + "104a8c": "c9bb9a", + "635231": "be6e18", + "efc500": "ffd437", + "103163": "a0896b", + "521031": "0f4973", + "d60042": "24aec0", + "316bad": "e3ddbd", + "d65273": "c583a5" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/6503.json b/public/images/pokemon/variant/back/6503.json new file mode 100644 index 00000000000..455b06a69d6 --- /dev/null +++ b/public/images/pokemon/variant/back/6503.json @@ -0,0 +1,38 @@ +{ + "1": { + "282f62": "f7d9de", + "84a5a5": "563785", + "a82c47": "d45b9e", + "8aa3a3": "d3a0bb", + "faf9f9": "f6f4f4", + "494a48": "3d2439", + "1d3962": "28142c", + "474a46": "2b1838", + "d75063": "b73891", + "fbfcfa": "fafcf9", + "324149": "363442", + "1e224e": "dc95ae", + "6b1c34": "8f3396", + "181531": "a26579", + "5a7373": "332a59", + "8da8a8": "a58b90", + "1e5b9b": "4d244b" + }, + "2": { + "282f62": "efdfee", + "84a5a5": "41857b", + "a82c47": "8abfb1", + "8aa3a3": "232d2e", + "faf9f9": "2c3940", + "494a48": "181f20", + "1d3962": "321e1e", + "474a46": "181f20", + "d75063": "8f65d8", + "fbfcfa": "fcfdfc", + "1e224e": "ba9bc1", + "6b1c34": "6d9d9a", + "181531": "715b72", + "5a7373": "2a5c57", + "1e5b9b": "5e3e38" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/656.json b/public/images/pokemon/variant/back/656.json new file mode 100644 index 00000000000..34b11bfab78 --- /dev/null +++ b/public/images/pokemon/variant/back/656.json @@ -0,0 +1,24 @@ +{ + "1": { + "838394": "4d7dc5", + "7bcdff": "9c75c2", + "62ace6": "8363af", + "ffffff": "b1e5ff", + "396a83": "362864", + "9c9cc5": "5385c7", + "cdcde6": "7eb7e8", + "174592": "198158", + "5a94cd": "7054a4" + }, + "2": { + "838394": "cc6845", + "7bcdff": "dd6155", + "62ace6": "c44848", + "ffffff": "fff4bd", + "396a83": "5c0d33", + "9c9cc5": "c96a48", + "cdcde6": "f7b785", + "174592": "198158", + "5a94cd": "a92f3f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/657.json b/public/images/pokemon/variant/back/657.json new file mode 100644 index 00000000000..083a9dba0a6 --- /dev/null +++ b/public/images/pokemon/variant/back/657.json @@ -0,0 +1,24 @@ +{ + "1": { + "f8f8f8": "8dcfff", + "737373": "0f3f82", + "0b566a": "281f52", + "002c58": "1c0726", + "bfbfbf": "4386df", + "006ba6": "4e1852", + "0b4a7a": "340f3d", + "41ccf5": "7755a7", + "2896b5": "4b3578" + }, + "2": { + "f8f8f8": "fff6c7", + "737373": "df6a50", + "0b566a": "7e1628", + "002c58": "0c3b54", + "bfbfbf": "ffc996", + "006ba6": "239c91", + "0b4a7a": "156f78", + "41ccf5": "dd7355", + "2896b5": "a92f3a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/658-ash.json b/public/images/pokemon/variant/back/658-ash.json new file mode 100644 index 00000000000..370d5df8081 --- /dev/null +++ b/public/images/pokemon/variant/back/658-ash.json @@ -0,0 +1,38 @@ +{ + "1": { + "265595": "432b6c", + "de3431": "3fca9f", + "f8f8f8": "a1e9f0", + "7b282e": "0e3e81", + "6b1d1d": "206d74", + "134e52": "062e3c", + "bfb169": "165e78", + "ffb2bf": "b7e9ff", + "bf4c60": "4386df", + "282c35": "271f4c", + "f2798d": "8dcfff", + "268794": "1c3e58", + "3e7acc": "6b4592", + "7ddeff": "7ddcd6", + "4ebdd9": "41a7b0", + "18335c": "170738" + }, + "2": { + "265595": "cc7251", + "de3431": "9ceec6", + "f8f8f8": "89d2b8", + "7b282e": "152a5c", + "6b1d1d": "356e8d", + "134e52": "0d1e3e", + "bfb169": "4d2637", + "ffb2bf": "86d6b6", + "bf4c60": "32738b", + "282c35": "4d2637", + "f2798d": "5eb4a9", + "268794": "1c3e58", + "3e7acc": "ecbb7a", + "7ddeff": "46988d", + "4ebdd9": "2f6e74", + "18335c": "9f2727" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/658.json b/public/images/pokemon/variant/back/658.json new file mode 100644 index 00000000000..c1bb4222ce4 --- /dev/null +++ b/public/images/pokemon/variant/back/658.json @@ -0,0 +1,26 @@ +{ + "1": { + "ffb2bf": "b7e9ff", + "bf4c60": "4386df", + "3d61cc": "6b4592", + "fff0a6": "208698", + "2e4999": "432b6c", + "f2798d": "8dcfff", + "803340": "0e3e81", + "1b2a59": "170738", + "66d9ff": "7ddcd6", + "bfb169": "165e78" + }, + "2": { + "ffb2bf": "86d6b6", + "bf4c60": "32738b", + "3d61cc": "ecbb7a", + "fff0a6": "652240", + "2e4999": "cc7251", + "f2798d": "5eb4a9", + "803340": "152a5c", + "1b2a59": "9f2727", + "66d9ff": "48968c", + "bfb169": "431022" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/6706.json b/public/images/pokemon/variant/back/6706.json new file mode 100644 index 00000000000..2de5352e936 --- /dev/null +++ b/public/images/pokemon/variant/back/6706.json @@ -0,0 +1,38 @@ +{ + "1": { + "566678": "197497", + "8e96aa": "3b235c", + "929aad": "3aa8c4", + "625287": "4e4094", + "536273": "301848", + "988b98": "b24c86", + "36404c": "0c5474", + "c4cce1": "513981", + "e6d3e9": "f1a4c5", + "bfacc1": "d074a0", + "546475": "0e6296", + "c5cee3": "63cee1", + "80737f": "8a2166", + "4b454f": "6f1357", + "9170b9": "8b69c3", + "b791f2": "c7a1e5" + }, + "2": { + "566678": "a34205", + "8e96aa": "073338", + "929aad": "d27e26", + "625287": "0e3f47", + "536273": "042329", + "988b98": "2b736f", + "36404c": "842401", + "c4cce1": "0d484a", + "e6d3e9": "9cead8", + "bfacc1": "5db6a9", + "546475": "8e480b", + "c5cee3": "f7af58", + "80737f": "194f51", + "4b454f": "274159", + "9170b9": "2f667c", + "b791f2": "4a9699" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/6706_3.json b/public/images/pokemon/variant/back/6706_3.json deleted file mode 100644 index 9a97ce27059..00000000000 --- a/public/images/pokemon/variant/back/6706_3.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "textures": [ - { - "image": "6706_3.png", - "format": "RGBA8888", - "size": { - "w": 79, - "h": 79 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 79, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 73 - }, - "frame": { - "x": 0, - "y": 0, - "w": 79, - "h": 73 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:64f7e6dfa489012922487e45ba53d557:4d24652b372939abe499497c4b6647b0:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-dandy.json b/public/images/pokemon/variant/back/676-dandy.json new file mode 100644 index 00000000000..f73bd90f690 --- /dev/null +++ b/public/images/pokemon/variant/back/676-dandy.json @@ -0,0 +1,28 @@ +{ + "1": { + "594d46": "788087", + "376277": "4f8fe3", + "9c9f94": "42090e", + "30552b": "423839", + "b8bcaf": "5e0f16", + "508a3c": "aa9999", + "f1f2ee": "8a1d1d", + "816e64": "a6afb3", + "6eb92b": "eddddd", + "4b4b46": "2b040f" + }, + "2": { + "594d46": "9c7aca", + "376277": "314173", + "fe3c31": "8362b4", + "9c9f94": "ad76bc", + "30552b": "6a102e", + "b8bcaf": "ce9ede", + "508a3c": "ac254b", + "f1f2ee": "e6c3f8", + "a83c31": "473085", + "816e64": "ae95dc", + "6eb92b": "e44a62", + "4b4b46": "6b3f77" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-debutante.json b/public/images/pokemon/variant/back/676-debutante.json new file mode 100644 index 00000000000..cad1f7792f0 --- /dev/null +++ b/public/images/pokemon/variant/back/676-debutante.json @@ -0,0 +1,28 @@ +{ + "1": { + "594d46": "788087", + "376277": "4f8fe3", + "9c9f94": "42090e", + "dfb76a": "aa9999", + "4b4b46": "2b040f", + "bcc0b3": "5e0f16", + "816e64": "a6afb3", + "ac6d40": "423839", + "f8f9f7": "8a1d1d", + "fbf588": "eddddd" + }, + "2": { + "594d46": "48a7d0", + "376277": "717171", + "fe3c31": "762ea8", + "9c9f94": "0b374f", + "dfb76a": "c6a65c", + "4b4b46": "021a2f", + "bcc0b3": "0b4b68", + "a83c31": "521073", + "816e64": "74ccec", + "ac6d40": "684d24", + "f8f9f7": "0e728e", + "fbf588": "ffe998" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-diamond.json b/public/images/pokemon/variant/back/676-diamond.json new file mode 100644 index 00000000000..35876619287 --- /dev/null +++ b/public/images/pokemon/variant/back/676-diamond.json @@ -0,0 +1,30 @@ +{ + "1": { + "594d46": "788087", + "aa3e2b": "423839", + "b8bcaf": "5e0f16", + "f1f2ee": "8a1d1d", + "376277": "4f8fe3", + "645e55": "2b040f", + "d95b37": "aa9999", + "e68a4d": "eddddd", + "453434": "313439", + "816e64": "a6afb3", + "9c9f94": "42090e" + }, + "2": { + "594d46": "bd9462", + "aa3e2b": "642c0a", + "b8bcaf": "319c6a", + "f1f2ee": "6abd81", + "376277": "c56e34", + "fe3c31": "b37e47", + "645e55": "10573c", + "d95b37": "935927", + "e68a4d": "b37e47", + "453434": "6c4b2d", + "a83c31": "642c0a", + "816e64": "eed59c", + "9c9f94": "288c66" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-heart.json b/public/images/pokemon/variant/back/676-heart.json new file mode 100644 index 00000000000..abb8ed1a9b3 --- /dev/null +++ b/public/images/pokemon/variant/back/676-heart.json @@ -0,0 +1,30 @@ +{ + "1": { + "594d46": "788087", + "f18598": "48474c", + "b8bcaf": "5e0f16", + "f1f2ee": "8a1d1d", + "e0546c": "2a2a2f", + "376277": "4f8fe3", + "645e55": "2b040f", + "453434": "313439", + "816e64": "a6afb3", + "a73f4f": "19181f", + "9c9f94": "42090e" + }, + "2": { + "594d46": "aca49c", + "f18598": "5f5953", + "b8bcaf": "bfc7e8", + "f1f2ee": "e4eafc", + "e0546c": "4c413c", + "376277": "1b1c21", + "fe3c31": "9475de", + "645e55": "7a81b7", + "453434": "837373", + "a83c31": "7249b7", + "816e64": "dadace", + "a73f4f": "2c2320", + "9c9f94": "9fa7c8" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-kabuki.json b/public/images/pokemon/variant/back/676-kabuki.json new file mode 100644 index 00000000000..54e87ca19b2 --- /dev/null +++ b/public/images/pokemon/variant/back/676-kabuki.json @@ -0,0 +1,36 @@ +{ + "1": { + "811d1d": "240b12", + "8f2121": "19181f", + "b01a1a": "17161c", + "d02f2e": "2a2a2f", + "594d46": "a6afb3", + "f66559": "fe3c31", + "f44b3d": "313439", + "376277": "436ca1", + "8a7d79": "788087", + "68675c": "2b040f", + "9c9f94": "42090e", + "534343": "360513", + "bcc0b3": "5e0f16", + "f1f2ee": "8a1d1d", + "b32524": "a83c31" + }, + "2": { + "811d1d": "181a38", + "8f2121": "191b38", + "b01a1a": "48578e", + "d02f2e": "305d9e", + "594d46": "3e5368", + "f66559": "9890ec", + "f44b3d": "4c89d9", + "376277": "436ca1", + "8a7d79": "233342", + "68675c": "1b1d39", + "9c9f94": "468197", + "534343": "192b42", + "bcc0b3": "549ab8", + "f1f2ee": "6bcfd9", + "b32524": "8067c6" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-la-reine.json b/public/images/pokemon/variant/back/676-la-reine.json new file mode 100644 index 00000000000..a464639a025 --- /dev/null +++ b/public/images/pokemon/variant/back/676-la-reine.json @@ -0,0 +1,28 @@ +{ + "1": { + "8a7d79": "788087", + "376277": "4f8fe3", + "31a7bb": "aa9999", + "594d46": "a6afb3", + "4b4b46": "2b040f", + "9c9f94": "42090e", + "56d1d8": "eddddd", + "bcc0b3": "5e0f16", + "2f7387": "423839", + "f1f2ee": "8a1d1d" + }, + "2": { + "a83c31": "3041b7", + "8a7d79": "a11e24", + "376277": "221755", + "31a7bb": "e3b876", + "594d46": "973721", + "4b4b46": "550b0c", + "9c9f94": "c63b31", + "56d1d8": "ffec9b", + "bcc0b3": "d9533c", + "2f7387": "8e673e", + "f1f2ee": "ee724b", + "fe3c31": "4b77e1" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-matron.json b/public/images/pokemon/variant/back/676-matron.json new file mode 100644 index 00000000000..70a32e09a19 --- /dev/null +++ b/public/images/pokemon/variant/back/676-matron.json @@ -0,0 +1,29 @@ +{ + "1": { + "873a5b": "19181f", + "376277": "4f8fe3", + "9c9f94": "42090e", + "594d46": "788087", + "b8bcaf": "5e0f16", + "5f5951": "2b040f", + "121212": "101010", + "b95b83": "2a2a2f", + "816e64": "a6afb3", + "f8f9f7": "8a1d1d", + "d07da9": "313439" + }, + "2": { + "873a5b": "1b447b", + "376277": "2246aa", + "fe3c31": "64edf3", + "9c9f94": "bd4d6a", + "594d46": "d0b5b5", + "b8bcaf": "d95e7e", + "5f5951": "8a2843", + "b95b83": "528fcc", + "816e64": "e3d6d6", + "a83c31": "45a6d0", + "f8f9f7": "fa8c9f", + "d07da9": "64c8f3" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-pharaoh.json b/public/images/pokemon/variant/back/676-pharaoh.json new file mode 100644 index 00000000000..fa9c60533b6 --- /dev/null +++ b/public/images/pokemon/variant/back/676-pharaoh.json @@ -0,0 +1,30 @@ +{ + "1": { + "594d46": "788087", + "376277": "4f8fe3", + "9c9f94": "42090e", + "bcc0b3": "5e0f16", + "25559c": "2a2a2f", + "484640": "2b040f", + "217fc4": "313439", + "68675c": "2b040f", + "816e64": "42090e", + "243a6f": "19181f", + "f1f2ee": "8a1d1d" + }, + "2": { + "594d46": "22172f", + "376277": "5e0808", + "fe3c31": "ec4d3e", + "9c9f94": "332b42", + "bcc0b3": "3b3955", + "25559c": "d0902d", + "484640": "17122f", + "217fc4": "eed552", + "68675c": "17122f", + "a83c31": "a11717", + "816e64": "332b42", + "243a6f": "a15317", + "f1f2ee": "5a5a71" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676-star.json b/public/images/pokemon/variant/back/676-star.json new file mode 100644 index 00000000000..f6bdec0ca9e --- /dev/null +++ b/public/images/pokemon/variant/back/676-star.json @@ -0,0 +1,30 @@ +{ + "1": { + "594d46": "788087", + "b8bcaf": "5e0f16", + "f1f2ee": "8a1d1d", + "3a5078": "19181f", + "376277": "4f8fe3", + "645e55": "2b040f", + "3e8ebf": "2a2a2f", + "9c9f94": "42090e", + "453434": "48474c", + "816e64": "a6afb3", + "7dc2e8": "313439" + }, + "2": { + "594d46": "d7bc4d", + "b8bcaf": "d6dec2", + "f1f2ee": "fcfef5", + "3a5078": "613d11", + "376277": "647bb1", + "fe3c31": "b5e0f3", + "645e55": "848e75", + "3e8ebf": "ac802f", + "9c9f94": "c3cdab", + "453434": "836329", + "a83c31": "6192aa", + "816e64": "f7e784", + "7dc2e8": "cdac4a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/676.json b/public/images/pokemon/variant/back/676.json new file mode 100644 index 00000000000..9a8ab0f7aa3 --- /dev/null +++ b/public/images/pokemon/variant/back/676.json @@ -0,0 +1,23 @@ +{ + "1": { + "bcbca8": "5e0f16", + "606056": "2b040f", + "8e8e7b": "42090e", + "f2f2da": "8a1d1d", + "3f6273": "2b040f", + "736b67": "a6afb3", + "494340": "788087", + "3f6274": "4f8fe3" + }, + "2": { + "bcbca8": "a4624a", + "cc2929": "3a240e", + "606056": "4a281b", + "8e8e7b": "805145", + "f2f2da": "c18960", + "3f6273": "4a281b", + "736b67": "ffe6ac", + "494340": "e6c594", + "3f6274": "4a2e23" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/682.json b/public/images/pokemon/variant/back/682.json new file mode 100644 index 00000000000..5b3a6821f1f --- /dev/null +++ b/public/images/pokemon/variant/back/682.json @@ -0,0 +1,20 @@ +{ + "1": { + "6b3962": "30185d", + "cc7087": "318759", + "993d80": "4f297e", + "ff99b3": "48ab61", + "7f4d59": "20644e" + }, + "2": { + "6b3962": "b89477", + "cc7087": "c3561a", + "993d80": "d2bfa1", + "ff99b3": "da7e29", + "7f4d59": "a23812", + "a6a6a6": "503851", + "737373": "422f46", + "4d4d4d": "332539", + "e5e5e5": "6b4767" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/683.json b/public/images/pokemon/variant/back/683.json new file mode 100644 index 00000000000..9d7f4682b9a --- /dev/null +++ b/public/images/pokemon/variant/back/683.json @@ -0,0 +1,20 @@ +{ + "1": { + "6b3962": "30185d", + "cc7087": "318759", + "993d80": "4f297e", + "ff99b3": "48ab61", + "404040": "2c283b", + "7f4d59": "20644e", + "bf5f9f": "7c48a1" + }, + "2": { + "6b3962": "b89477", + "cc7087": "c3561a", + "993d80": "d2bfa1", + "ff99b3": "da7e29", + "404040": "2a2234", + "7f4d59": "a23812", + "bf5f9f": "f0ebdd" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/684.json b/public/images/pokemon/variant/back/684.json new file mode 100644 index 00000000000..18afd91b4a2 --- /dev/null +++ b/public/images/pokemon/variant/back/684.json @@ -0,0 +1,18 @@ +{ + "1": { + "805963": "3c195b", + "7b5760": "8f1d15", + "cc99a6": "814db1", + "ffccd9": "8961c6", + "fff2f2": "f39f62", + "ccadad": "e6774a" + }, + "2": { + "805963": "679baa", + "7b5760": "3c2f51", + "cc99a6": "93d6ce", + "ffccd9": "cbf6da", + "fff2f2": "746998", + "ccadad": "4b4876" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/685.json b/public/images/pokemon/variant/back/685.json new file mode 100644 index 00000000000..87b0bad9422 --- /dev/null +++ b/public/images/pokemon/variant/back/685.json @@ -0,0 +1,28 @@ +{ + "1": { + "f8f8f8": "caff90", + "661a2d": "13391c", + "805963": "2d0c42", + "7b5760": "b13924", + "ffccd9": "8961c6", + "ff8ca9": "8dbe6d", + "cc99a6": "613b84", + "e53964": "689b52", + "fff2f2": "f39f62", + "ccadad": "df6b40", + "a62949": "26592b" + }, + "2": { + "f8f8f8": "e4819d", + "661a2d": "26061b", + "805963": "679baa", + "7b5760": "3c2f51", + "ffccd9": "cbf6da", + "ff8ca9": "8c4264", + "cc99a6": "93d6ce", + "e53964": "612747", + "fff2f2": "746998", + "ccadad": "4b4876", + "a62949": "441838" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/688.json b/public/images/pokemon/variant/back/688.json new file mode 100644 index 00000000000..ac388cd384e --- /dev/null +++ b/public/images/pokemon/variant/back/688.json @@ -0,0 +1,30 @@ +{ + "1": { + "b7653f": "459aac", + "385860": "70240f", + "6b503b": "373295", + "372e27": "220a56", + "c0e0e8": "e8d37b", + "8a6d45": "4557b5", + "808080": "7c582e", + "5890b0": "a9582e", + "fcffff": "e8e5c6", + "d0d0d0": "d3bc8c", + "88c0c8": "cd8a50", + "ef8955": "70cccf" + }, + "2": { + "b7653f": "332149", + "385860": "2c052a", + "6b503b": "ba9fba", + "372e27": "1e1324", + "c0e0e8": "a74083", + "8a6d45": "f6eefc", + "808080": "4d6a09", + "5890b0": "4b0038", + "fcffff": "d1ec8c", + "d0d0d0": "94c268", + "88c0c8": "731f5c", + "ef8955": "4a376e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/689.json b/public/images/pokemon/variant/back/689.json new file mode 100644 index 00000000000..6c47b57f35b --- /dev/null +++ b/public/images/pokemon/variant/back/689.json @@ -0,0 +1,31 @@ +{ + "1": { + "cc7f70": "459aac", + "f2f2f2": "e8e5c6", + "5b8da6": "8d5030", + "595959": "7c582e", + "403410": "220a56", + "3f6273": "672e1e", + "b3b3b3": "d3bc8c", + "bfeaff": "e8d37b", + "85b4cc": "cd8a50", + "ff9f8c": "70cccf", + "66541f": "373295", + "997e2e": "4557b5" + }, + "2": { + "cc7f70": "332149", + "f2f2f2": "caea77", + "5b8da6": "4b0038", + "595959": "2a5524", + "403410": "3f2a4b", + "3f6273": "3e073b", + "b3b3b3": "7eac4e", + "bfeaff": "a74083", + "85b4cc": "731f5c", + "f8f8f8": "dbaf67", + "ff9f8c": "4a376e", + "66541f": "ccb6cc", + "997e2e": "f6eefc" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/807.json b/public/images/pokemon/variant/back/807.json new file mode 100644 index 00000000000..4471a1b5b50 --- /dev/null +++ b/public/images/pokemon/variant/back/807.json @@ -0,0 +1,28 @@ +{ + "1": { + "484f57": "243058", + "5bd0f2": "ebceff", + "2759a5": "736599", + "727678": "3f5277", + "daa936": "5c96b4", + "ef8a4e": "517bb5", + "f9e455": "80c7d7", + "9d682d": "3d648c", + "000000": "ffffff", + "2394d8": "b298d8", + "31343e": "14193f" + }, + "2": { + "484f57": "cba3ca", + "5bd0f2": "df7298", + "2759a5": "a3378a", + "727678": "e7c9e2", + "daa936": "351d53", + "ef8a4e": "844c94", + "f9e455": "58326f", + "9d682d": "1f1144", + "000000": "ffffff", + "2394d8": "be5293", + "31343e": "a880b0" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/894.json b/public/images/pokemon/variant/back/894.json new file mode 100644 index 00000000000..d213b87dcf4 --- /dev/null +++ b/public/images/pokemon/variant/back/894.json @@ -0,0 +1,24 @@ +{ + "1": { + "e5ee1a": "6ad7f3", + "7d542a": "2769aa", + "bc8b2f": "124b78", + "fefac7": "dffff6", + "2e3967": "357b84", + "8eacdd": "caffd1", + "375395": "5fcaad", + "4e7cc9": "9bf1c4", + "d7ad0d": "45a3d6" + }, + "2": { + "e5ee1a": "d4ffd0", + "7d542a": "429877", + "bc8b2f": "2a6f5d", + "fefac7": "ffffff", + "2e3967": "514199", + "8eacdd": "c693d8", + "375395": "815bad", + "4e7cc9": "b67cd6", + "d7ad0d": "7cd395" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/895.json b/public/images/pokemon/variant/back/895.json new file mode 100644 index 00000000000..d9a7f49ae44 --- /dev/null +++ b/public/images/pokemon/variant/back/895.json @@ -0,0 +1,26 @@ +{ + "1": { + "641e2c": "722123", + "b63650": "bc623e", + "608d99": "fae5bf", + "2b3d40": "754f47", + "4b6f78": "f1d4b6", + "e05276": "ef8429", + "f27a99": "efb55a", + "3f545f": "ad8473", + "872c3c": "93372d", + "242e35": "512c25" + }, + "2": { + "641e2c": "15553b", + "b63650": "3bb349", + "608d99": "9b7ebc", + "2b3d40": "241951", + "4b6f78": "5a4382", + "e05276": "8aea41", + "f27a99": "dfff75", + "3f545f": "3a2a67", + "872c3c": "227843", + "242e35": "0f0c1e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/944.json b/public/images/pokemon/variant/back/944.json new file mode 100644 index 00000000000..6f41f91c4d6 --- /dev/null +++ b/public/images/pokemon/variant/back/944.json @@ -0,0 +1,44 @@ +{ + "1": { + "b5eab2": "75a0d0", + "d4eac7": "8bcfe5", + "bdb2bd": "53a164", + "ceceb7": "3ec295", + "726766": "4f985c", + "4a4860": "372869", + "8ce1b2": "6383c4", + "564a49": "286943", + "000000": "ffffff", + "4ca391": "3a4a8a", + "97859b": "3f8d59", + "a571e6": "ffe269", + "774d9b": "d09139", + "efeee1": "88eeab", + "afc6d8": "8056a7", + "c9e1f4": "b782cd", + "918772": "1c9b8d", + "869fad": "5e4090", + "3a2b2f": "18493f" + }, + "2": { + "b5eab2": "a9c6dc", + "d4eac7": "e2f8ff", + "bdb2bd": "78b0c2", + "ceceb7": "abc1df", + "726766": "5386b9", + "4a4860": "4f133f", + "8ce1b2": "8397c4", + "564a49": "2c4f8a", + "000000": "ffffff", + "4ca391": "6974ad", + "97859b": "5582a4", + "a571e6": "4c5372", + "774d9b": "2c2c46", + "efeee1": "e2f3ff", + "afc6d8": "c23f4f", + "c9e1f4": "f98381", + "918772": "6777aa", + "869fad": "902a4b", + "3a2b2f": "1e3072" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/945.json b/public/images/pokemon/variant/back/945.json new file mode 100644 index 00000000000..500e68e3812 --- /dev/null +++ b/public/images/pokemon/variant/back/945.json @@ -0,0 +1,38 @@ +{ + "1": { + "403f4f": "357747", + "1f2635": "1c193d", + "dcdcc3": "5ddcb2", + "d6d3ca": "499833", + "e0ebf1": "7ddfee", + "e6e2e1": "fffbf3", + "8d2151": "4676aa", + "4f483f": "1b727b", + "323d4a": "2e2452", + "000000": "ffffff", + "d73875": "68adca", + "aebec7": "62b0d0", + "38bdda": "494e64", + "282434": "14463f", + "aca699": "2db3a4", + "a4988b": "16613d", + "4b616b": "473869" + }, + "2": { + "403f4f": "3b6b9e", + "1f2635": "3b091c", + "dcdcc3": "edf0f1", + "e6e2e1": "ebf4f9", + "8d2151": "4676aa", + "4f483f": "5d7487", + "323d4a": "580f1d", + "000000": "ffffff", + "a599a8": "bf888f", + "d73875": "68adca", + "7c6a84": "965b6f", + "38bdda": "494e64", + "282434": "2d427e", + "aca699": "acbfc7", + "4b616b": "8a2029" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/154.json b/public/images/pokemon/variant/back/female/154.json new file mode 100644 index 00000000000..d7463ebee9d --- /dev/null +++ b/public/images/pokemon/variant/back/female/154.json @@ -0,0 +1,26 @@ +{ + "1": { + "634a00": "6da0df", + "ff3a5a": "234d81", + "e6ad00": "90c6f8", + "ce213a": "192e5e", + "63bd42": "9d86d9", + "f7a59c": "78d38b", + "7b103a": "111c44", + "107b31": "8057b2", + "ffde21": "b9e2ff", + "9ce652": "b7afee" + }, + "2": { + "634a00": "144627", + "ff3a5a": "9ed662", + "e6ad00": "1e632b", + "ce213a": "81c65c", + "63bd42": "a31f60", + "f7a59c": "ddf2b5", + "7b103a": "59ac45", + "107b31": "761858", + "ffde21": "288028", + "9ce652": "cd3b6b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/194.json b/public/images/pokemon/variant/back/female/194.json new file mode 100644 index 00000000000..db649381d14 --- /dev/null +++ b/public/images/pokemon/variant/back/female/194.json @@ -0,0 +1,20 @@ +{ + "1": { + "529ce6": "e8983d", + "9463a5": "2ea380", + "633a6b": "09484f", + "3a7bc5": "d5682e", + "73bdff": "ffc355", + "d65ad6": "44d77f", + "104a84": "7a150a" + }, + "2": { + "529ce6": "564daa", + "9463a5": "aeccdf", + "633a6b": "444c7e", + "3a7bc5": "3f377e", + "73bdff": "5c66c4", + "d65ad6": "e8faff", + "104a84": "180d42" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/195.json b/public/images/pokemon/variant/back/female/195.json new file mode 100644 index 00000000000..a097ea3eac4 --- /dev/null +++ b/public/images/pokemon/variant/back/female/195.json @@ -0,0 +1,24 @@ +{ + "1": { + "ade6ff": "f6dfa8", + "84d6f7": "ed9e4f", + "637ba5": "816251", + "639cbd": "dc6a4d", + "3194a5": "44d77f", + "6b5a8c": "1b5a55", + "425284": "b03844", + "426b84": "b8453b", + "195a6b": "2ea380" + }, + "2": { + "ade6ff": "9864c2", + "84d6f7": "724ba7", + "637ba5": "504a8a", + "639cbd": "493a8d", + "3194a5": "ebf5ff", + "6b5a8c": "5e649b", + "425284": "240830", + "195a6b": "aebbdf", + "19423a": "747aae" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/198.json b/public/images/pokemon/variant/back/female/198.json new file mode 100644 index 00000000000..eed8404265c --- /dev/null +++ b/public/images/pokemon/variant/back/female/198.json @@ -0,0 +1,26 @@ +{ + "1": { + "d94352": "8c1b23", + "314263": "462b20", + "efd684": "a6a6b3", + "d64252": "b3986b", + "42639c": "694c30", + "5a4a21": "25253b", + "292942": "2a1512", + "b59c21": "57566f", + "73293a": "755237", + "d6bd52": "838098" + }, + "2": { + "d94352": "8c1b23", + "314263": "0e4333", + "efd684": "c2723a", + "d64252": "bc4b84", + "42639c": "1d6e47", + "5a4a21": "4e1915", + "292942": "091e16", + "b59c21": "85412d", + "73293a": "7b2363", + "d6bd52": "9a5524" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/25-beauty-cosplay.json b/public/images/pokemon/variant/back/female/25-beauty-cosplay.json new file mode 100644 index 00000000000..34a087f71cd --- /dev/null +++ b/public/images/pokemon/variant/back/female/25-beauty-cosplay.json @@ -0,0 +1,32 @@ +{ + "1": { + "f7cc2f": "d5ac44", + "9c5200": "315c75", + "f7e860": "eddc78", + "cecab9": "b84084", + "2d276d": "454a61", + "4d88c4": "e4f6f1", + "39509d": "9ec4cd", + "fffdea": "ea82a6", + "f7e652": "a3d1a8", + "f7bd21": "79b5a5", + "5e5e6b": "8a2554" + }, + "2": { + "4f454c": "f1b571", + "f7cc2f": "d5ac44", + "fffabf": "f5efd1", + "9c5200": "283361", + "f7e860": "eddc78", + "965b0e": "96500e", + "cecab9": "b84084", + "2d276d": "454a61", + "4d88c4": "e4f6f1", + "39509d": "9ec4cd", + "fffdea": "ea82a6", + "1e1526": "a45233", + "f7e652": "577b98", + "f7bd21": "486689", + "5e5e6b": "8a2554" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/25-cool-cosplay.json b/public/images/pokemon/variant/back/female/25-cool-cosplay.json new file mode 100644 index 00000000000..278feb070bd --- /dev/null +++ b/public/images/pokemon/variant/back/female/25-cool-cosplay.json @@ -0,0 +1,31 @@ +{ + "1": { + "171717": "2a1d36", + "c52119": "ad4e76", + "842222": "7b1f18", + "f7e652": "a3d1a8", + "fff7a5": "c4e3c3", + "f7bd21": "79b5a5", + "ba2b23": "b73850", + "9c5200": "1c4f75", + "d95b45": "cf6887", + "3b3b40": "4a3e46" + }, + "2": { + "171717": "a45233", + "656f86": "cf752b", + "a5b0b6": "f0b541", + "c52119": "ebc67c", + "842222": "1e1e43", + "f7e652": "577b98", + "fff7a5": "7b96aa", + "f7bd21": "445f8a", + "ba2b23": "2c2c47", + "55555e": "8f4b32", + "9c5200": "22325c", + "f4f7ab": "eadbb3", + "d95b45": "3a3f5e", + "3b3b40": "f1b571", + "272b2b": "7d3833" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/25-cosplay.json b/public/images/pokemon/variant/back/female/25-cosplay.json new file mode 100644 index 00000000000..c574d63d743 --- /dev/null +++ b/public/images/pokemon/variant/back/female/25-cosplay.json @@ -0,0 +1,26 @@ +{ + "1": { + "f7e652": "a3d1a8", + "fff7a5": "c4e3c3", + "c52119": "ad4e76", + "f7bd21": "79b5a5", + "52525a": "4f454c", + "9c5200": "315c75", + "292929": "1e1526", + "633108": "09406b", + "e65a42": "cf6182", + "de9400": "338087" + }, + "2": { + "f7e652": "577b98", + "fff7a5": "7b96aa", + "c52119": "ebc67c", + "f7bd21": "445f8a", + "52525a": "f1b571", + "9c5200": "23345e", + "292929": "a45233", + "633108": "22244f", + "e65a42": "eedd9c", + "de9400": "324472" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/25-cute-cosplay.json b/public/images/pokemon/variant/back/female/25-cute-cosplay.json new file mode 100644 index 00000000000..7b26b79d08f --- /dev/null +++ b/public/images/pokemon/variant/back/female/25-cute-cosplay.json @@ -0,0 +1,32 @@ +{ + "1": { + "752bd0": "5452b7", + "baa998": "bab699", + "fff7a5": "c4e3c3", + "f7e652": "a3d1a8", + "ea82a6": "e8848e", + "cf4770": "cf4a59", + "f3bace": "f2bbbb", + "853247": "85323c", + "f7ef97": "f0eaa8", + "52525a": "4f454c", + "292929": "30263b", + "f7bd21": "79b5a5", + "9c5200": "255e8a" + }, + "2": { + "752bd0": "7751c2", + "baa998": "d3ab5a", + "fff7a5": "7b96aa", + "f7e652": "577b98", + "ea82a6": "a4b95f", + "cf4770": "739b55", + "f3bace": "c5cc85", + "853247": "254b30", + "f7ef97": "ebe7b7", + "52525a": "f1b571", + "292929": "a45233", + "f7bd21": "445f8a", + "9c5200": "23345e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/25-partner.json b/public/images/pokemon/variant/back/female/25-partner.json new file mode 100644 index 00000000000..affebee3c8b --- /dev/null +++ b/public/images/pokemon/variant/back/female/25-partner.json @@ -0,0 +1,26 @@ +{ + "1": { + "9c5200": "315c75", + "171717": "1e1526", + "fff7a5": "c4e3c3", + "f7bd21": "79b5a5", + "f7e652": "a3d1a8", + "c52119": "ad4e76", + "e65a42": "cf6182", + "633108": "09406b", + "45454a": "4f454c", + "de9400": "338087" + }, + "2": { + "9c5200": "23345e", + "171717": "a45233", + "fff7a5": "7b96aa", + "f7bd21": "445f8a", + "f7e652": "577b98", + "c52119": "ebc67c", + "e65a42": "eedd9c", + "633108": "22244f", + "45454a": "f1b571", + "de9400": "324472" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/25-smart-cosplay.json b/public/images/pokemon/variant/back/female/25-smart-cosplay.json new file mode 100644 index 00000000000..50749b31d8b --- /dev/null +++ b/public/images/pokemon/variant/back/female/25-smart-cosplay.json @@ -0,0 +1,32 @@ +{ + "1": { + "fffdea": "f8ffe3", + "b7a599": "bab699", + "60b553": "76a848", + "f7e652": "a3d1a8", + "366635": "3e5b2f", + "95635b": "91685f", + "171717": "1e1526", + "5f3434": "573b38", + "54545c": "55555e", + "52525a": "4f454c", + "292929": "272b2b", + "f7bd21": "79b5a5", + "9c5200": "315c75" + }, + "2": { + "fffdea": "f2f0df", + "b7a599": "a7b6b9", + "60b553": "dfb053", + "f7e652": "577b98", + "366635": "ab5130", + "95635b": "a09ea3", + "171717": "a45233", + "5f3434": "666060", + "54545c": "45525c", + "52525a": "f1b571", + "292929": "202937", + "f7bd21": "445f8a", + "9c5200": "23345e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/25-tough-cosplay.json b/public/images/pokemon/variant/back/female/25-tough-cosplay.json new file mode 100644 index 00000000000..49c50d17ad2 --- /dev/null +++ b/public/images/pokemon/variant/back/female/25-tough-cosplay.json @@ -0,0 +1,35 @@ +{ + "1": { + "e37511": "d1694f", + "bf2629": "cf6a59", + "8d2b1d": "bf3638", + "c52119": "ad4e76", + "46464d": "2b3340", + "292929": "1e1526", + "f7bd21": "79b5a5", + "fbab33": "de9764", + "e65a42": "cf6182", + "cecab9": "cfc8aa", + "52525a": "4f454c", + "f7e652": "a3d1a8", + "9c5200": "315c75" + }, + "2": { + "e37511": "60448d", + "bf2629": "826694", + "f8ffe3": "e8e3e4", + "8d2b1d": "3d3f7d", + "c52119": "ebc67c", + "46464d": "2b3340", + "292929": "a45233", + "f7bd21": "445f8a", + "fbab33": "845ea1", + "e65a42": "eedd9c", + "cecab9": "beb1b4", + "8e2525": "242866", + "52525a": "f1b571", + "f7e652": "577b98", + "272b2b": "162231", + "9c5200": "23345e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/25.json b/public/images/pokemon/variant/back/female/25.json new file mode 100644 index 00000000000..affebee3c8b --- /dev/null +++ b/public/images/pokemon/variant/back/female/25.json @@ -0,0 +1,26 @@ +{ + "1": { + "9c5200": "315c75", + "171717": "1e1526", + "fff7a5": "c4e3c3", + "f7bd21": "79b5a5", + "f7e652": "a3d1a8", + "c52119": "ad4e76", + "e65a42": "cf6182", + "633108": "09406b", + "45454a": "4f454c", + "de9400": "338087" + }, + "2": { + "9c5200": "23345e", + "171717": "a45233", + "fff7a5": "7b96aa", + "f7bd21": "445f8a", + "f7e652": "577b98", + "c52119": "ebc67c", + "e65a42": "eedd9c", + "633108": "22244f", + "45454a": "f1b571", + "de9400": "324472" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/female/26.json b/public/images/pokemon/variant/back/female/26.json new file mode 100644 index 00000000000..6a29870fc8b --- /dev/null +++ b/public/images/pokemon/variant/back/female/26.json @@ -0,0 +1,33 @@ +{ + "1": { + "63636b": "4f454c", + "944242": "395a80", + "bd5a31": "386d82", + "e6bd84": "a4bda7", + "ffbd00": "b3596b", + "5a2929": "293059", + "3a3a42": "30263b", + "8c6310": "8c3c4c", + "ffde5a": "cf7878", + "f7ad29": "76a68b", + "734231": "6e2f33", + "ffefd6": "c8d4ba", + "de7b31": "539190" + }, + "2": { + "101010": "000000", + "542127": "905331", + "944242": "2d3b80", + "bd5a31": "375681", + "e6bd84": "a6b5ab", + "ffbd00": "f3cf91", + "5a2929": "202a60", + "8c6310": "c79b5a", + "ffde5a": "f2e4b6", + "f7ad29": "6385ab", + "734231": "bf8445", + "ffefd6": "cfc4b5", + "de7b31": "4d6f98", + "643034": "2e4685" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/2026.json b/public/images/pokemon/variant/exp/2026.json new file mode 100644 index 00000000000..287b16fb52b --- /dev/null +++ b/public/images/pokemon/variant/exp/2026.json @@ -0,0 +1,34 @@ +{ + "1": { + "ecd8b7": "b4c2a5", + "646124": "492652", + "602c24": "162f4b", + "fef652": "eb999a", + "846b5b": "467f85", + "1a73cc": "b85346", + "9c5430": "1d3a57", + "174680": "2b1307", + "fef443": "c48081", + "b45f25": "2d5261", + "fffdfb": "d6d9ca", + "e9be14": "945c7b", + "e3882d": "3d7375", + "965821": "2f4e6b", + "552720": "142c48" + }, + "2": { + "ecd8b7": "5a6f90", + "646124": "122140", + "fef652": "faee9e", + "846b5b": "202746", + "1a73cc": "c26400", + "174680": "2b0606", + "fef443": "3a5873", + "b45f25": "bd8551", + "fffdfb": "6d8297", + "e9be14": "1a3551", + "e3882d": "d3b06f", + "965821": "9cb3ca", + "552720": "43617f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/2103.json b/public/images/pokemon/variant/exp/2103.json new file mode 100644 index 00000000000..2e97727835a --- /dev/null +++ b/public/images/pokemon/variant/exp/2103.json @@ -0,0 +1,28 @@ +{ + "1": { + "2f9934": "dea44c", + "9f6b41": "426378", + "70442e": "283f5b", + "e6ac5a": "869fdc", + "522f16": "131d33", + "9cbd4a": "9977dd", + "fff68b": "a3c4ed", + "36cc36": "f4e774", + "2d5826": "c8592a", + "7b5210": "373e85", + "ffffcd": "d3efff" + }, + "2": { + "2f9934": "3d324b", + "9f6b41": "ffdbe7", + "70442e": "d59cba", + "e6ac5a": "c84e7f", + "522f16": "925b81", + "9cbd4a": "824a96", + "fff68b": "eb748d", + "36cc36": "6a5b73", + "2d5826": "1f1a31", + "7b5210": "4e1044", + "ffffcd": "ffa29d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/359-mega.json b/public/images/pokemon/variant/exp/359-mega.json new file mode 100644 index 00000000000..084ba24477b --- /dev/null +++ b/public/images/pokemon/variant/exp/359-mega.json @@ -0,0 +1,34 @@ +{ + "1": { + "ffffff": "61a8ab", + "253334": "27122b", + "253333": "2b3266", + "273636": "101f30", + "7b2931": "c9824b", + "414a6a": "421e4a", + "b4b4d5": "458196", + "cd2920": "f7c26d", + "293939": "27122b", + "525a7b": "59274e", + "d5deee": "589aa6", + "737bac": "874267", + "8b8bac": "3b6987", + "626283": "2a3163" + }, + "2": { + "ffffff": "9e363b", + "253334": "996e5f", + "253333": "420b26", + "273636": "420918", + "7b2931": "0f4391", + "414a6a": "b39279", + "b4b4d5": "752f40", + "cd2920": "2a96ce", + "293939": "996e5f", + "525a7b": "e0c79f", + "d5deee": "8f2f41", + "737bac": "f5f1cb", + "8b8bac": "59213b", + "626283": "42122d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/6503.json b/public/images/pokemon/variant/exp/6503.json new file mode 100644 index 00000000000..62c6cb628b2 --- /dev/null +++ b/public/images/pokemon/variant/exp/6503.json @@ -0,0 +1,37 @@ +{ + "1": { + "282f62": "f7d9de", + "c4c5cf": "e3c2ca", + "84a4a7": "563785", + "a82c47": "d45b9e", + "8aa3a3": "6b415b", + "8da8a8": "a58b90", + "1d3962": "28142c", + "d75063": "b73891", + "d9cacd": "f7d9de", + "808280": "020501", + "1e224e": "dc95ae", + "1e5b9b": "4d244b", + "181531": "a26579", + "6b1c34": "8f3396", + "597471": "332a59", + "494a48": "3d2439" + }, + "2": { + "282f62": "efdfee", + "c4c5cf": "232d2e", + "84a4a7": "41857b", + "a82c47": "8abfb1", + "8aa3a3": "181f20", + "faf9f9": "2c3940", + "8da8a8": "bdbdbd", + "1d3962": "321e1e", + "d75063": "8f65d8", + "1e224e": "ba9bc1", + "1e5b9b": "5e3e38", + "181531": "715b72", + "6b1c34": "6d9d9a", + "597471": "2a5c57", + "494a48": "0b0f18" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/656.json b/public/images/pokemon/variant/exp/656.json new file mode 100644 index 00000000000..68743a4c9f1 --- /dev/null +++ b/public/images/pokemon/variant/exp/656.json @@ -0,0 +1,32 @@ +{ + "1": { + "838394": "4d7dc5", + "62ace6": "8363af", + "7bcdff": "9c75c2", + "ffec8c": "ddfff9", + "a1a1c4": "7ab7ec", + "c9b241": "97d6e2", + "dfcf77": "bae7e8", + "174592": "37408c", + "fdfdfd": "b1e5ff", + "9c9cc5": "5385c7", + "cdcde6": "7eb7e8", + "396a83": "362864", + "5a94cd": "7054a4" + }, + "2": { + "838394": "cc6845", + "62ace6": "c44848", + "7bcdff": "dd6155", + "ffec8c": "ddfff9", + "a1a1c4": "f7c685", + "c9b241": "97d6e2", + "dfcf77": "bae7e8", + "174592": "198158", + "fdfdfd": "fff4bd", + "9c9cc5": "c96a48", + "cdcde6": "f7b785", + "396a83": "5c0d33", + "5a94cd": "a92f3f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/657.json b/public/images/pokemon/variant/exp/657.json new file mode 100644 index 00000000000..773b4d2efc1 --- /dev/null +++ b/public/images/pokemon/variant/exp/657.json @@ -0,0 +1,32 @@ +{ + "1": { + "f8f8f8": "8dcfff", + "efc653": "abd7db", + "737373": "0f3f82", + "0b566a": "281f52", + "ffec72": "c9fff5", + "002c58": "1c0726", + "bfbfbf": "4386df", + "006ba6": "4e1852", + "009dd5": "61255e", + "0b4a7a": "340f3d", + "e1a03a": "78c7c7", + "41ccf5": "7755a7", + "2896b5": "4b3578" + }, + "2": { + "f8f8f8": "fff6c7", + "efc653": "abd7db", + "737373": "df6a50", + "0b566a": "7e1628", + "ffec72": "ddfff9", + "002c58": "0c3b54", + "bfbfbf": "ffc996", + "006ba6": "239c91", + "009dd5": "37b8ac", + "0b4a7a": "156f78", + "e1a03a": "86abbb", + "41ccf5": "dd7355", + "2896b5": "a92f3a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/658-ash.json b/public/images/pokemon/variant/exp/658-ash.json new file mode 100644 index 00000000000..96b60b02adf --- /dev/null +++ b/public/images/pokemon/variant/exp/658-ash.json @@ -0,0 +1,44 @@ +{ + "1": { + "265595": "432b6c", + "3f4447": "466698", + "de3431": "3fca9f", + "f8f8f8": "a1e9f0", + "7b282e": "0e3e81", + "6b1d1d": "206d74", + "4ebdd9": "41a7b0", + "bfb169": "165e78", + "bfbfbf": "8cc7d4", + "ffb2bf": "b7e9ff", + "bf4c60": "4386df", + "fff0a6": "208698", + "3e7acc": "6b4592", + "18335c": "170738", + "f2798d": "8dcfff", + "f01818": "39b88f", + "7ddeff": "7ddcd6", + "268794": "1c3e58", + "282c35": "271f4c" + }, + "2": { + "265595": "cc7251", + "3f4447": "466698", + "de3431": "9ceec6", + "f8f8f8": "89d2b8", + "7b282e": "152a5c", + "6b1d1d": "356e8d", + "4ebdd9": "2f6e74", + "bfb169": "431022", + "bfbfbf": "8cc7d4", + "ffb2bf": "86d6b6", + "bf4c60": "32738b", + "fff0a6": "472333", + "3e7acc": "ecbb7a", + "18335c": "9f2727", + "f2798d": "5eb4a9", + "f01818": "ffe88d", + "7ddeff": "46988d", + "268794": "1c3e58", + "282c35": "4d2637" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/658.json b/public/images/pokemon/variant/exp/658.json new file mode 100644 index 00000000000..826e31b4e21 --- /dev/null +++ b/public/images/pokemon/variant/exp/658.json @@ -0,0 +1,34 @@ +{ + "1": { + "ffb2bf": "b7e9ff", + "bf4c60": "4386df", + "66d9ff": "7ddcd6", + "3d61cc": "6b4592", + "fff0a6": "208698", + "c92e2e": "73c5ff", + "937f69": "406695", + "c2c1bc": "89b0d7", + "f2798d": "8dcfff", + "f7f7f7": "d8ffff", + "bfb169": "165e78", + "1b2a59": "170738", + "803340": "0e3e81", + "2e4999": "432b6c" + }, + "2": { + "ffb2bf": "86d6b6", + "bf4c60": "32738b", + "66d9ff": "48968c", + "3d61cc": "ecbb7a", + "fff0a6": "652240", + "c92e2e": "63bf9b", + "937f69": "466698", + "c2c1bc": "8cc7d4", + "f2798d": "5eb4a9", + "f7f7f7": "d7eff4", + "bfb169": "431022", + "1b2a59": "9f2727", + "803340": "152a5c", + "2e4999": "cc7251" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/6706.json b/public/images/pokemon/variant/exp/6706.json new file mode 100644 index 00000000000..2a5f8e112ee --- /dev/null +++ b/public/images/pokemon/variant/exp/6706.json @@ -0,0 +1,40 @@ +{ + "1": { + "566678": "0e6296", + "e0e4f4": "513981", + "625287": "4e4094", + "536273": "1f1233", + "988b98": "b24c86", + "36404c": "0c5474", + "c4cce1": "3b235c", + "e6d3e9": "f1a4c5", + "bfacc1": "da75a5", + "515f70": "197497", + "c5cee3": "63cee1", + "b791f2": "c7a1e5", + "8b93a6": "3aa8c4", + "80737f": "8a2166", + "4b454f": "6f1357", + "9170b9": "8b69c3", + "8e96aa": "301848" + }, + "2": { + "566678": "8e480b", + "e0e4f4": "176463", + "625287": "274159", + "536273": "02262c", + "988b98": "2a6563", + "36404c": "842401", + "c4cce1": "0d484a", + "e6d3e9": "9cead8", + "bfacc1": "5db6a9", + "515f70": "a34205", + "c5cee3": "f7af58", + "b791f2": "4a9699", + "8b93a6": "d27e26", + "80737f": "2b736f", + "4b454f": "194f51", + "9170b9": "2f667c", + "8e96aa": "073338" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/6706_2.json b/public/images/pokemon/variant/exp/6706_2.json deleted file mode 100644 index cb2ddfb1a12..00000000000 --- a/public/images/pokemon/variant/exp/6706_2.json +++ /dev/null @@ -1,2015 +0,0 @@ -{ - "textures": [ - { - "image": "6706_2.png", - "format": "RGBA8888", - "size": { - "w": 508, - "h": 508 - }, - "scale": 1, - "frames": [ - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 26, - "w": 59, - "h": 61 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 61 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 26, - "y": 25, - "w": 56, - "h": 63 - }, - "frame": { - "x": 59, - "y": 0, - "w": 56, - "h": 63 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 26, - "y": 25, - "w": 56, - "h": 63 - }, - "frame": { - "x": 59, - "y": 0, - "w": 56, - "h": 63 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 115, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 115, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 29, - "y": 21, - "w": 54, - "h": 65 - }, - "frame": { - "x": 168, - "y": 0, - "w": 54, - "h": 65 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 29, - "y": 21, - "w": 54, - "h": 65 - }, - "frame": { - "x": 168, - "y": 0, - "w": 54, - "h": 65 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 222, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 222, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 55, - "h": 66 - }, - "frame": { - "x": 275, - "y": 0, - "w": 55, - "h": 66 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 55, - "h": 66 - }, - "frame": { - "x": 275, - "y": 0, - "w": 55, - "h": 66 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 23, - "w": 54, - "h": 66 - }, - "frame": { - "x": 330, - "y": 0, - "w": 54, - "h": 66 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 23, - "w": 54, - "h": 66 - }, - "frame": { - "x": 330, - "y": 0, - "w": 54, - "h": 66 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 54, - "h": 67 - }, - "frame": { - "x": 384, - "y": 0, - "w": 54, - "h": 67 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 54, - "h": 67 - }, - "frame": { - "x": 384, - "y": 0, - "w": 54, - "h": 67 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 21, - "w": 52, - "h": 68 - }, - "frame": { - "x": 438, - "y": 0, - "w": 52, - "h": 68 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 21, - "w": 52, - "h": 68 - }, - "frame": { - "x": 438, - "y": 0, - "w": 52, - "h": 68 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 68 - }, - "frame": { - "x": 0, - "y": 61, - "w": 53, - "h": 68 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 68 - }, - "frame": { - "x": 0, - "y": 61, - "w": 53, - "h": 68 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 18, - "y": 22, - "w": 52, - "h": 68 - }, - "frame": { - "x": 53, - "y": 63, - "w": 52, - "h": 68 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 18, - "y": 22, - "w": 52, - "h": 68 - }, - "frame": { - "x": 53, - "y": 63, - "w": 52, - "h": 68 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 19, - "y": 21, - "w": 55, - "h": 69 - }, - "frame": { - "x": 105, - "y": 65, - "w": 55, - "h": 69 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 19, - "y": 21, - "w": 55, - "h": 69 - }, - "frame": { - "x": 105, - "y": 65, - "w": 55, - "h": 69 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 160, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 160, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 16, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 213, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 16, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 213, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 15, - "y": 21, - "w": 52, - "h": 70 - }, - "frame": { - "x": 266, - "y": 66, - "w": 52, - "h": 70 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 15, - "y": 21, - "w": 52, - "h": 70 - }, - "frame": { - "x": 266, - "y": 66, - "w": 52, - "h": 70 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 18, - "w": 87, - "h": 71 - }, - "frame": { - "x": 405, - "y": 68, - "w": 87, - "h": 71 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 19, - "w": 86, - "h": 72 - }, - "frame": { - "x": 0, - "y": 131, - "w": 86, - "h": 72 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 74, - "h": 80 - }, - "frame": { - "x": 434, - "y": 139, - "w": 74, - "h": 80 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 74, - "h": 80 - }, - "frame": { - "x": 434, - "y": 139, - "w": 74, - "h": 80 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 72 - }, - "frame": { - "x": 0, - "y": 203, - "w": 85, - "h": 72 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 13, - "w": 83, - "h": 72 - }, - "frame": { - "x": 85, - "y": 206, - "w": 83, - "h": 72 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 18, - "w": 84, - "h": 73 - }, - "frame": { - "x": 168, - "y": 206, - "w": 84, - "h": 73 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 252, - "y": 210, - "w": 85, - "h": 73 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 423, - "y": 219, - "w": 85, - "h": 73 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 423, - "y": 219, - "w": 85, - "h": 73 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 81, - "h": 74 - }, - "frame": { - "x": 171, - "y": 279, - "w": 81, - "h": 74 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 81, - "h": 74 - }, - "frame": { - "x": 171, - "y": 279, - "w": 81, - "h": 74 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 84, - "h": 74 - }, - "frame": { - "x": 252, - "y": 283, - "w": 84, - "h": 74 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 84, - "h": 74 - }, - "frame": { - "x": 252, - "y": 283, - "w": 84, - "h": 74 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 336, - "y": 284, - "w": 86, - "h": 73 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 336, - "y": 284, - "w": 86, - "h": 73 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 422, - "y": 292, - "w": 80, - "h": 74 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 422, - "y": 292, - "w": 80, - "h": 74 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 349, - "w": 79, - "h": 74 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 349, - "w": 79, - "h": 74 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 79, - "y": 352, - "w": 80, - "h": 74 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 79, - "y": 352, - "w": 80, - "h": 74 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 75 - }, - "frame": { - "x": 0, - "y": 423, - "w": 79, - "h": 75 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 75 - }, - "frame": { - "x": 0, - "y": 423, - "w": 79, - "h": 75 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 78, - "h": 75 - }, - "frame": { - "x": 79, - "y": 426, - "w": 78, - "h": 75 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 78, - "h": 75 - }, - "frame": { - "x": 79, - "y": 426, - "w": 78, - "h": 75 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 85, - "h": 75 - }, - "frame": { - "x": 157, - "y": 428, - "w": 85, - "h": 75 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:62a4a665074efb5def1545546995dc5b:de2788ebeab6b42f331926f332da5125:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/6706_2.png b/public/images/pokemon/variant/exp/6706_2.png deleted file mode 100644 index 7e7dfa8e05a..00000000000 Binary files a/public/images/pokemon/variant/exp/6706_2.png and /dev/null differ diff --git a/public/images/pokemon/variant/exp/6706_3.json b/public/images/pokemon/variant/exp/6706_3.json deleted file mode 100644 index 8c9b16b80ab..00000000000 --- a/public/images/pokemon/variant/exp/6706_3.json +++ /dev/null @@ -1,2015 +0,0 @@ -{ - "textures": [ - { - "image": "6706_3.png", - "format": "RGBA8888", - "size": { - "w": 508, - "h": 508 - }, - "scale": 1, - "frames": [ - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 26, - "w": 59, - "h": 61 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 61 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 26, - "y": 25, - "w": 56, - "h": 63 - }, - "frame": { - "x": 59, - "y": 0, - "w": 56, - "h": 63 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 26, - "y": 25, - "w": 56, - "h": 63 - }, - "frame": { - "x": 59, - "y": 0, - "w": 56, - "h": 63 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 115, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 115, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 29, - "y": 21, - "w": 54, - "h": 65 - }, - "frame": { - "x": 168, - "y": 0, - "w": 54, - "h": 65 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 29, - "y": 21, - "w": 54, - "h": 65 - }, - "frame": { - "x": 168, - "y": 0, - "w": 54, - "h": 65 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 222, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 222, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 55, - "h": 66 - }, - "frame": { - "x": 275, - "y": 0, - "w": 55, - "h": 66 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 55, - "h": 66 - }, - "frame": { - "x": 275, - "y": 0, - "w": 55, - "h": 66 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 23, - "w": 54, - "h": 66 - }, - "frame": { - "x": 330, - "y": 0, - "w": 54, - "h": 66 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 23, - "w": 54, - "h": 66 - }, - "frame": { - "x": 330, - "y": 0, - "w": 54, - "h": 66 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 54, - "h": 67 - }, - "frame": { - "x": 384, - "y": 0, - "w": 54, - "h": 67 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 54, - "h": 67 - }, - "frame": { - "x": 384, - "y": 0, - "w": 54, - "h": 67 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 21, - "w": 52, - "h": 68 - }, - "frame": { - "x": 438, - "y": 0, - "w": 52, - "h": 68 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 21, - "w": 52, - "h": 68 - }, - "frame": { - "x": 438, - "y": 0, - "w": 52, - "h": 68 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 68 - }, - "frame": { - "x": 0, - "y": 61, - "w": 53, - "h": 68 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 68 - }, - "frame": { - "x": 0, - "y": 61, - "w": 53, - "h": 68 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 18, - "y": 22, - "w": 52, - "h": 68 - }, - "frame": { - "x": 53, - "y": 63, - "w": 52, - "h": 68 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 18, - "y": 22, - "w": 52, - "h": 68 - }, - "frame": { - "x": 53, - "y": 63, - "w": 52, - "h": 68 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 19, - "y": 21, - "w": 55, - "h": 69 - }, - "frame": { - "x": 105, - "y": 65, - "w": 55, - "h": 69 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 19, - "y": 21, - "w": 55, - "h": 69 - }, - "frame": { - "x": 105, - "y": 65, - "w": 55, - "h": 69 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 160, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 160, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 16, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 213, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 16, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 213, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 15, - "y": 21, - "w": 52, - "h": 70 - }, - "frame": { - "x": 266, - "y": 66, - "w": 52, - "h": 70 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 15, - "y": 21, - "w": 52, - "h": 70 - }, - "frame": { - "x": 266, - "y": 66, - "w": 52, - "h": 70 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 18, - "w": 87, - "h": 71 - }, - "frame": { - "x": 405, - "y": 68, - "w": 87, - "h": 71 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 19, - "w": 86, - "h": 72 - }, - "frame": { - "x": 0, - "y": 131, - "w": 86, - "h": 72 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 74, - "h": 80 - }, - "frame": { - "x": 434, - "y": 139, - "w": 74, - "h": 80 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 74, - "h": 80 - }, - "frame": { - "x": 434, - "y": 139, - "w": 74, - "h": 80 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 72 - }, - "frame": { - "x": 0, - "y": 203, - "w": 85, - "h": 72 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 13, - "w": 83, - "h": 72 - }, - "frame": { - "x": 85, - "y": 206, - "w": 83, - "h": 72 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 18, - "w": 84, - "h": 73 - }, - "frame": { - "x": 168, - "y": 206, - "w": 84, - "h": 73 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 252, - "y": 210, - "w": 85, - "h": 73 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 423, - "y": 219, - "w": 85, - "h": 73 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 423, - "y": 219, - "w": 85, - "h": 73 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 81, - "h": 74 - }, - "frame": { - "x": 171, - "y": 279, - "w": 81, - "h": 74 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 81, - "h": 74 - }, - "frame": { - "x": 171, - "y": 279, - "w": 81, - "h": 74 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 84, - "h": 74 - }, - "frame": { - "x": 252, - "y": 283, - "w": 84, - "h": 74 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 84, - "h": 74 - }, - "frame": { - "x": 252, - "y": 283, - "w": 84, - "h": 74 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 336, - "y": 284, - "w": 86, - "h": 73 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 336, - "y": 284, - "w": 86, - "h": 73 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 422, - "y": 292, - "w": 80, - "h": 74 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 422, - "y": 292, - "w": 80, - "h": 74 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 349, - "w": 79, - "h": 74 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 349, - "w": 79, - "h": 74 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 79, - "y": 352, - "w": 80, - "h": 74 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 79, - "y": 352, - "w": 80, - "h": 74 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 75 - }, - "frame": { - "x": 0, - "y": 423, - "w": 79, - "h": 75 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 75 - }, - "frame": { - "x": 0, - "y": 423, - "w": 79, - "h": 75 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 78, - "h": 75 - }, - "frame": { - "x": 79, - "y": 426, - "w": 78, - "h": 75 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 78, - "h": 75 - }, - "frame": { - "x": 79, - "y": 426, - "w": 78, - "h": 75 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 85, - "h": 75 - }, - "frame": { - "x": 157, - "y": 428, - "w": 85, - "h": 75 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:62a4a665074efb5def1545546995dc5b:de2788ebeab6b42f331926f332da5125:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/6706_3.png b/public/images/pokemon/variant/exp/6706_3.png deleted file mode 100644 index 3ad44f4bbf5..00000000000 Binary files a/public/images/pokemon/variant/exp/6706_3.png and /dev/null differ diff --git a/public/images/pokemon/variant/exp/676.json b/public/images/pokemon/variant/exp/676.json new file mode 100644 index 00000000000..d5ec3013e8e --- /dev/null +++ b/public/images/pokemon/variant/exp/676.json @@ -0,0 +1,22 @@ +{ + "1": { + "a8a592": "42090e", + "376277": "2b040f", + "ccc8b1": "5e0f16", + "59463c": "aaaec1", + "97362c": "a83c31", + "68675c": "2b040f", + "fc362c": "cc2929", + "efeeda": "8a1d1d" + }, + "2": { + "a8a592": "805145", + "376277": "4a281b", + "ccc8b1": "a4624a", + "59463c": "ffe6ac", + "97362c": "3a240e", + "68675c": "4a281b", + "fc362c": "50351b", + "efeeda": "c18960" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/682.json b/public/images/pokemon/variant/exp/682.json new file mode 100644 index 00000000000..a8a7caf46b1 --- /dev/null +++ b/public/images/pokemon/variant/exp/682.json @@ -0,0 +1,28 @@ +{ + "1": { + "661f1f": "cd6132", + "bf5f9f": "7c48a1", + "ff99b3": "48ab61", + "f24949": "ffa24f", + "6b3962": "30185d", + "993d80": "4f297e", + "ffb6c2": "62c45f", + "7f4d59": "20644e", + "cc7087": "318759" + }, + "2": { + "661f1f": "daa235", + "bf5f9f": "f0ebdd", + "ff99b3": "da7e29", + "a6a6a6": "503851", + "737373": "422f46", + "f24949": "ffe664", + "6b3962": "b89477", + "993d80": "d2bfa1", + "ffb6c2": "ed9f3a", + "e5e5e5": "6b4767", + "7f4d59": "a23812", + "4d4d4d": "332539", + "cc7087": "c3561a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/683.json b/public/images/pokemon/variant/exp/683.json new file mode 100644 index 00000000000..f9485702936 --- /dev/null +++ b/public/images/pokemon/variant/exp/683.json @@ -0,0 +1,32 @@ +{ + "1": { + "661f1f": "b64d29", + "cc7087": "318759", + "ff99b3": "48ab61", + "fff0a6": "fec04b", + "f24949": "ffa24f", + "6b3962": "30185d", + "e5c37e": "d6872c", + "993d80": "4f297e", + "7f4d59": "20644e", + "404040": "2c283b", + "b33636": "f4863f", + "bf5f9f": "7c48a1" + }, + "2": { + "661f1f": "c78925", + "cc7087": "c3561a", + "ff99b3": "da7e29", + "fff0a6": "6d8719", + "e5e5e5": "6b4767", + "f24949": "ffe664", + "6b3962": "b89477", + "e5c37e": "376d11", + "993d80": "d2bfa1", + "7f4d59": "a23812", + "a6a6a6": "503851", + "404040": "2a2234", + "b33636": "f0c150", + "bf5f9f": "f0ebdd" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/684.json b/public/images/pokemon/variant/exp/684.json new file mode 100644 index 00000000000..fb88bb28c70 --- /dev/null +++ b/public/images/pokemon/variant/exp/684.json @@ -0,0 +1,30 @@ +{ + "1": { + "805963": "2d0c42", + "553a41": "8f1d15", + "661a2d": "13391c", + "e53964": "8dbe6d", + "ffccd9": "8961c6", + "5e4048": "260b37", + "cc99a6": "613b84", + "f8f8f8": "caff90", + "fff2f2": "f39f62", + "a62949": "689b52", + "7b5760": "b13924", + "ccadad": "df6b40" + }, + "2": { + "805963": "6796aa", + "553a41": "1d1426", + "661a2d": "26061b", + "e53964": "8c4264", + "ffccd9": "cbf6da", + "5e4048": "52718e", + "cc99a6": "93d6ce", + "f8f8f8": "ffe5ec", + "fff2f2": "746998", + "a62949": "612747", + "7b5760": "3c2f51", + "ccadad": "4b4876" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/685.json b/public/images/pokemon/variant/exp/685.json new file mode 100644 index 00000000000..24ead59428a --- /dev/null +++ b/public/images/pokemon/variant/exp/685.json @@ -0,0 +1,28 @@ +{ + "1": { + "f8f8f8": "caff90", + "661a2d": "13391c", + "7b5760": "b13924", + "ffccd9": "8961c6", + "ff8ca9": "8dbe6d", + "cc99a6": "613b84", + "e53964": "689b52", + "fff2f2": "f39f62", + "a62949": "26592b", + "ccadad": "df6b40", + "805963": "2d0c42" + }, + "2": { + "f8f8f8": "e4819d", + "661a2d": "26061b", + "7b5760": "3c2f51", + "ffccd9": "cbf6da", + "ff8ca9": "8c4264", + "cc99a6": "93d6ce", + "e53964": "612747", + "fff2f2": "746998", + "a62949": "441838", + "ccadad": "4b4876", + "805963": "52718e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/688.json b/public/images/pokemon/variant/exp/688.json new file mode 100644 index 00000000000..e5749f6bb3f --- /dev/null +++ b/public/images/pokemon/variant/exp/688.json @@ -0,0 +1,33 @@ +{ + "1": { + "5890b0": "a9582e", + "385860": "70240f", + "372e27": "220a56", + "6b503b": "373295", + "d0d0d0": "d3bc8c", + "c0e0e8": "e8d37b", + "8a6d45": "4557b5", + "101010": "37160a", + "b7653f": "459aac", + "fcffff": "e8e5c6", + "808080": "7c582e", + "88c0c8": "cd8a50", + "ef8955": "70cccf" + }, + "2": { + "5890b0": "4b0038", + "385860": "2c052a", + "372e27": "1e1324", + "6b503b": "ba9fba", + "d0d0d0": "7eac4e", + "c0e0e8": "a74083", + "8a6d45": "f6eefc", + "101010": "0a391b", + "b7653f": "332149", + "fcffff": "caea77", + "f8f8f8": "ffffff", + "808080": "2a5524", + "88c0c8": "731f5c", + "ef8955": "4a376e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/689.json b/public/images/pokemon/variant/exp/689.json new file mode 100644 index 00000000000..cd6db09c8d2 --- /dev/null +++ b/public/images/pokemon/variant/exp/689.json @@ -0,0 +1,31 @@ +{ + "1": { + "bfeaff": "e8d37b", + "f2f2f2": "e8e5c6", + "5b8da6": "8d5030", + "595959": "7c582e", + "403410": "220a56", + "3f6273": "672e1e", + "b3b3b3": "d3bc8c", + "cc7f70": "459aac", + "85b4cc": "cd8a50", + "ff9f8c": "70cccf", + "66541f": "373295", + "997e2e": "4557b5" + }, + "2": { + "bfeaff": "a74083", + "f2f2f2": "caea77", + "5b8da6": "4b0038", + "595959": "2a5524", + "403410": "3f2a4b", + "3f6273": "3e073b", + "b3b3b3": "7eac4e", + "cc7f70": "332149", + "85b4cc": "731f5c", + "f8f8f8": "dbaf67", + "ff9f8c": "4a376e", + "66541f": "ccb6cc", + "997e2e": "f6eefc" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/705.json b/public/images/pokemon/variant/exp/705.json new file mode 100644 index 00000000000..a29b8f124dc --- /dev/null +++ b/public/images/pokemon/variant/exp/705.json @@ -0,0 +1,33 @@ +{ + "1": { + "101010":"101010", + "4d454d":"8a2166", + "807380":"b93f84", + "bfacbf":"e56ca6", + "f2daf2":"fbb3d2", + "665980":"4e4094", + "8f7db3":"8b69c3", + "b8a1e5":"c7a1e5", + "4d993d":"aa6a00", + "66cc52":"ffd047", + "4e9c3e":"0c5474", + "67cf53":"3aa8c4", + "b6f2aa":"63cee1" + }, + "2": { + "101010":"101010", + "4d454d":"194f51", + "807380":"2b736f", + "bfacbf":"5db6a9", + "f2daf2":"9cead8", + "665980":"274159", + "8f7db3":"2f667c", + "b8a1e5":"4a9699", + "4d993d":"007d61", + "66cc52":"49ffbf", + "4e9c3e":"842401", + "67cf53":"a34205", + "b6f2aa":"d27e26" + } +} + diff --git a/public/images/pokemon/variant/exp/705_2.json b/public/images/pokemon/variant/exp/705_2.json deleted file mode 100644 index bf9fd104c5d..00000000000 --- a/public/images/pokemon/variant/exp/705_2.json +++ /dev/null @@ -1,272 +0,0 @@ -{ - "textures": [ - { - "image": "705_2.png", - "format": "RGBA8888", - "size": { - "w": 154, - "h": 154 - }, - "scale": 1, - "frames": [ - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 46, - "h": 58 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 58 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 46, - "h": 58 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 58 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 46, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 46, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 91, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 42, - "h": 58 - }, - "frame": { - "x": 0, - "y": 58, - "w": 42, - "h": 58 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 42, - "h": 58 - }, - "frame": { - "x": 0, - "y": 58, - "w": 42, - "h": 58 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 58 - }, - "frame": { - "x": 42, - "y": 58, - "w": 41, - "h": 58 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 58 - }, - "frame": { - "x": 42, - "y": 58, - "w": 41, - "h": 58 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 36, - "h": 58 - }, - "frame": { - "x": 83, - "y": 58, - "w": 36, - "h": 58 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 36, - "h": 58 - }, - "frame": { - "x": 83, - "y": 58, - "w": 36, - "h": 58 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 58 - }, - "frame": { - "x": 119, - "y": 58, - "w": 35, - "h": 58 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4bf155254b23c88780e7eee282256589:82bb727988054c3064e203b6908ff464:6b57e983626c7fc9144ab67f30c66814$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/705_2.png b/public/images/pokemon/variant/exp/705_2.png deleted file mode 100644 index 8256ebc7fdb..00000000000 Binary files a/public/images/pokemon/variant/exp/705_2.png and /dev/null differ diff --git a/public/images/pokemon/variant/exp/705_3.json b/public/images/pokemon/variant/exp/705_3.json deleted file mode 100644 index 199d7bc9c3e..00000000000 --- a/public/images/pokemon/variant/exp/705_3.json +++ /dev/null @@ -1,272 +0,0 @@ -{ - "textures": [ - { - "image": "705_3.png", - "format": "RGBA8888", - "size": { - "w": 154, - "h": 154 - }, - "scale": 1, - "frames": [ - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 46, - "h": 58 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 58 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 46, - "h": 58 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 58 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 46, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 46, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 91, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 42, - "h": 58 - }, - "frame": { - "x": 0, - "y": 58, - "w": 42, - "h": 58 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 42, - "h": 58 - }, - "frame": { - "x": 0, - "y": 58, - "w": 42, - "h": 58 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 58 - }, - "frame": { - "x": 42, - "y": 58, - "w": 41, - "h": 58 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 58 - }, - "frame": { - "x": 42, - "y": 58, - "w": 41, - "h": 58 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 36, - "h": 58 - }, - "frame": { - "x": 83, - "y": 58, - "w": 36, - "h": 58 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 36, - "h": 58 - }, - "frame": { - "x": 83, - "y": 58, - "w": 36, - "h": 58 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 58 - }, - "frame": { - "x": 119, - "y": 58, - "w": 35, - "h": 58 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4bf155254b23c88780e7eee282256589:82bb727988054c3064e203b6908ff464:6b57e983626c7fc9144ab67f30c66814$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/705_3.png b/public/images/pokemon/variant/exp/705_3.png deleted file mode 100644 index 66b43956bdf..00000000000 Binary files a/public/images/pokemon/variant/exp/705_3.png and /dev/null differ diff --git a/public/images/pokemon/variant/exp/807.json b/public/images/pokemon/variant/exp/807.json new file mode 100644 index 00000000000..8344e88090b --- /dev/null +++ b/public/images/pokemon/variant/exp/807.json @@ -0,0 +1,36 @@ +{ + "1": { + "53e4f9": "d7a7de", + "ef8a4e": "4f7bb6", + "2759a5": "736599", + "14bdea": "c987e3", + "2394d8": "b298d8", + "31343e": "14193f", + "1f73b4": "995fc0", + "4cf4fe": "f4a7ff", + "484f57": "243058", + "000000": "ffffff", + "727678": "3e5277", + "9d682d": "3c648d", + "f9e455": "7fc7d9", + "daa936": "5a96b6", + "5bd0f2": "ebceff" + }, + "2": { + "53e4f9": "d967a2", + "ef8a4e": "834b95", + "2759a5": "a4378a", + "14bdea": "c02f8d", + "2394d8": "c05192", + "31343e": "a981b1", + "1f73b4": "9a1d82", + "4cf4fe": "e3418f", + "484f57": "cda4cb", + "000000": "ffffff", + "727678": "e8cae3", + "9d682d": "1d1044", + "f9e455": "56306f", + "daa936": "331b53", + "5bd0f2": "e17197" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/894.json b/public/images/pokemon/variant/exp/894.json new file mode 100644 index 00000000000..dd270f3bc0e --- /dev/null +++ b/public/images/pokemon/variant/exp/894.json @@ -0,0 +1,27 @@ +{ + "1": { + "e5ee1a": "6ad7f3", + "ff9dc2": "2c3072", + "7d542a": "2769aa", + "8eacdd": "caffd1", + "bc8b2f": "124b78", + "fffbfb": "dffff6", + "2e3967": "357b84", + "fefac7": "dffff6", + "375395": "5fcaad", + "4e7cc9": "9bf1c4", + "d7ad0d": "45a3d6" + }, + "2": { + "e5ee1a": "d4ffd0", + "ff9dc2": "382875", + "7d542a": "429877", + "8eacdd": "c693d8", + "bc8b2f": "2a6f5d", + "2e3967": "514199", + "fefac7": "ffffff", + "375395": "815bad", + "4e7cc9": "b67cd6", + "d7ad0d": "7cd395" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/895.json b/public/images/pokemon/variant/exp/895.json new file mode 100644 index 00000000000..7c37283fee7 --- /dev/null +++ b/public/images/pokemon/variant/exp/895.json @@ -0,0 +1,34 @@ +{ + "1": { + "2261ca": "561a5b", + "641e2c": "722123", + "ff92ae": "edca71", + "242e35": "512c25", + "608d99": "fae5bf", + "2b3d40": "754f47", + "76dff5": "ffe8f7", + "4b6f78": "f1d4b6", + "e05276": "ef8429", + "b63650": "bc623e", + "f27a99": "efb55a", + "872c3c": "93372d", + "3f545f": "ad8473", + "139ee1": "9b407f" + }, + "2": { + "2261ca": "640e0b", + "641e2c": "15553b", + "ff92ae": "f1ff8d", + "242e35": "0f0c1e", + "608d99": "9b7ebc", + "2b3d40": "241951", + "76dff5": "fffcdf", + "4b6f78": "5a4382", + "e05276": "8aea41", + "b63650": "3bb349", + "f27a99": "dfff75", + "872c3c": "227843", + "3f545f": "3a2a67", + "139ee1": "98301c" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/944.json b/public/images/pokemon/variant/exp/944.json new file mode 100644 index 00000000000..4f1707ae85c --- /dev/null +++ b/public/images/pokemon/variant/exp/944.json @@ -0,0 +1,42 @@ +{ + "1": { + "b5eab2": "75a0d0", + "d4eac7": "8bcfe5", + "bdb2bd": "53a164", + "ceceb7": "3ec295", + "726766": "4f985c", + "4a4860": "372869", + "8ce1b2": "6383c4", + "564a49": "286943", + "000000": "ffffff", + "4ca391": "3a4a8a", + "a571e6": "ffe269", + "774d9b": "d09139", + "97859b": "3f8d59", + "afc6d8": "8056a7", + "efeee1": "88eeab", + "869fad": "5e4090", + "918772": "1c9b8d", + "3a2b2f": "18493f" + }, + "2": { + "b5eab2": "a9c6dc", + "d4eac7": "e2f8ff", + "bdb2bd": "78b0c2", + "ceceb7": "abc1df", + "726766": "5386b9", + "4a4860": "4f133f", + "8ce1b2": "8397c4", + "564a49": "2c4f8a", + "000000": "ffffff", + "4ca391": "3a4a8a", + "a571e6": "4c5372", + "774d9b": "2c2c46", + "97859b": "5582a4", + "afc6d8": "c23f4f", + "efeee1": "e2f3ff", + "869fad": "902a4b", + "918772": "6777aa", + "3a2b2f": "1e3072" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/945.json b/public/images/pokemon/variant/exp/945.json new file mode 100644 index 00000000000..e22743030f9 --- /dev/null +++ b/public/images/pokemon/variant/exp/945.json @@ -0,0 +1,53 @@ +{ + "1": { + "403f4f": "357747", + "1f2635": "1c193d", + "dcdcc3": "5ddcb2", + "282434": "14463f", + "ebe4e2": "ade273", + "a491a4": "499833", + "e6e2e1": "fffbf3", + "671544": "0f4e67", + "584698": "18153d", + "134175": "a74d2a", + "4f483f": "1b727b", + "323d4a": "2e2452", + "000000": "ffffff", + "8ac2a2": "1a355d", + "d73875": "29ad89", + "e0ebf1": "7ddfee", + "2481b0": "d09139", + "4b616b": "473869", + "38bdda": "ffe269", + "695575": "16613d", + "aca699": "2db3a4", + "8d2151": "157375", + "cedaaa": "2f5b7b" + }, + "2": { + "403f4f": "3b6b9e", + "1f2635": "3b091c", + "dcdcc3": "edf0f1", + "282434": "2d427e", + "ebe4e2": "c23f4f", + "a491a4": "902a4b", + "e6e2e1": "ebf4f9", + "671544": "223969", + "584698": "1f1e43", + "134175": "1c182f", + "4f483f": "5d7487", + "323d4a": "580f1d", + "000000": "ffffff", + "a599a8": "bf888f", + "8ac2a2": "8397c4", + "7c6a84": "965b6f", + "d73875": "68adca", + "2481b0": "2c2c46", + "4b616b": "8a2029", + "38bdda": "494e64", + "695575": "4f133f", + "aca699": "acbfc7", + "8d2151": "4676aa", + "cedaaa": "bad4e8" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/2026.json b/public/images/pokemon/variant/exp/back/2026.json new file mode 100644 index 00000000000..5758dcc8c6c --- /dev/null +++ b/public/images/pokemon/variant/exp/back/2026.json @@ -0,0 +1,31 @@ +{ + "1": { + "552720": "162f4b", + "ecd8b7": "b4c2a5", + "dfc043": "d17577", + "fffdfb": "d6d9ca", + "993c20": "1d3a57", + "b45f25": "2d5261", + "965821": "2f4e6b", + "e9be14": "945c7b", + "846b5b": "467f85", + "602c24": "162f4b", + "f9ed9f": "eb999a", + "e3882d": "3d7375", + "646124": "492652", + "fef443": "c48081" + }, + "2": { + "552720": "43617f", + "ecd8b7": "5a6f90", + "fffdfb": "6d8297", + "993c20": "965636", + "b45f25": "bd8551", + "965821": "9cb3ca", + "e9be14": "1a3551", + "846b5b": "202746", + "e3882d": "d3b06f", + "646124": "122140", + "fef443": "3a5873" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/2103.json b/public/images/pokemon/variant/exp/back/2103.json new file mode 100644 index 00000000000..2e97727835a --- /dev/null +++ b/public/images/pokemon/variant/exp/back/2103.json @@ -0,0 +1,28 @@ +{ + "1": { + "2f9934": "dea44c", + "9f6b41": "426378", + "70442e": "283f5b", + "e6ac5a": "869fdc", + "522f16": "131d33", + "9cbd4a": "9977dd", + "fff68b": "a3c4ed", + "36cc36": "f4e774", + "2d5826": "c8592a", + "7b5210": "373e85", + "ffffcd": "d3efff" + }, + "2": { + "2f9934": "3d324b", + "9f6b41": "ffdbe7", + "70442e": "d59cba", + "e6ac5a": "c84e7f", + "522f16": "925b81", + "9cbd4a": "824a96", + "fff68b": "eb748d", + "36cc36": "6a5b73", + "2d5826": "1f1a31", + "7b5210": "4e1044", + "ffffcd": "ffa29d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/359-mega.json b/public/images/pokemon/variant/exp/back/359-mega.json new file mode 100644 index 00000000000..5ae5a7477e7 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/359-mega.json @@ -0,0 +1,24 @@ +{ + "1": { + "ffffff": "61a8ab", + "414a6a": "421e4a", + "b4b4d5": "458196", + "293939": "27122b", + "525a7b": "59274e", + "d5deee": "589aa6", + "737bac": "874267", + "626283": "2a3163", + "8b8bac": "3b6987" + }, + "2": { + "ffffff": "9e363b", + "414a6a": "b39279", + "b4b4d5": "752f40", + "293939": "996e5f", + "525a7b": "e0c79f", + "d5deee": "8f2f41", + "737bac": "f5f1cb", + "626283": "42122d", + "8b8bac": "59213b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/6503.json b/public/images/pokemon/variant/exp/back/6503.json new file mode 100644 index 00000000000..a977e095e71 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/6503.json @@ -0,0 +1,35 @@ +{ + "1": { + "181531": "a26579", + "fafcf9": "f6f4f4", + "84a4a7": "563785", + "a82c47": "d45b9e", + "8aa3a3": "d3a0bb", + "494a48": "3d2439", + "1d3962": "28142c", + "474a46": "2b1838", + "d75063": "b73891", + "6b1c34": "8f3396", + "1e224e": "dc95ae", + "1e5b9b": "4d244b", + "8da8a8": "a58b90", + "597471": "332a59", + "282f62": "f7d9de" + }, + "2": { + "181531": "715b72", + "fafcf9": "2c3940", + "84a4a7": "41857b", + "a82c47": "8abfb1", + "8aa3a3": "232d2e", + "494a48": "181f20", + "1d3962": "321e1e", + "474a46": "181f20", + "d75063": "8f65d8", + "6b1c34": "6d9d9a", + "1e224e": "ba9bc1", + "1e5b9b": "5e3e38", + "597471": "2a5c57", + "282f62": "efdfee" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/656.json b/public/images/pokemon/variant/exp/back/656.json new file mode 100644 index 00000000000..34b11bfab78 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/656.json @@ -0,0 +1,24 @@ +{ + "1": { + "838394": "4d7dc5", + "7bcdff": "9c75c2", + "62ace6": "8363af", + "ffffff": "b1e5ff", + "396a83": "362864", + "9c9cc5": "5385c7", + "cdcde6": "7eb7e8", + "174592": "198158", + "5a94cd": "7054a4" + }, + "2": { + "838394": "cc6845", + "7bcdff": "dd6155", + "62ace6": "c44848", + "ffffff": "fff4bd", + "396a83": "5c0d33", + "9c9cc5": "c96a48", + "cdcde6": "f7b785", + "174592": "198158", + "5a94cd": "a92f3f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/657.json b/public/images/pokemon/variant/exp/back/657.json new file mode 100644 index 00000000000..083a9dba0a6 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/657.json @@ -0,0 +1,24 @@ +{ + "1": { + "f8f8f8": "8dcfff", + "737373": "0f3f82", + "0b566a": "281f52", + "002c58": "1c0726", + "bfbfbf": "4386df", + "006ba6": "4e1852", + "0b4a7a": "340f3d", + "41ccf5": "7755a7", + "2896b5": "4b3578" + }, + "2": { + "f8f8f8": "fff6c7", + "737373": "df6a50", + "0b566a": "7e1628", + "002c58": "0c3b54", + "bfbfbf": "ffc996", + "006ba6": "239c91", + "0b4a7a": "156f78", + "41ccf5": "dd7355", + "2896b5": "a92f3a" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/658-ash.json b/public/images/pokemon/variant/exp/back/658-ash.json new file mode 100644 index 00000000000..370d5df8081 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/658-ash.json @@ -0,0 +1,38 @@ +{ + "1": { + "265595": "432b6c", + "de3431": "3fca9f", + "f8f8f8": "a1e9f0", + "7b282e": "0e3e81", + "6b1d1d": "206d74", + "134e52": "062e3c", + "bfb169": "165e78", + "ffb2bf": "b7e9ff", + "bf4c60": "4386df", + "282c35": "271f4c", + "f2798d": "8dcfff", + "268794": "1c3e58", + "3e7acc": "6b4592", + "7ddeff": "7ddcd6", + "4ebdd9": "41a7b0", + "18335c": "170738" + }, + "2": { + "265595": "cc7251", + "de3431": "9ceec6", + "f8f8f8": "89d2b8", + "7b282e": "152a5c", + "6b1d1d": "356e8d", + "134e52": "0d1e3e", + "bfb169": "4d2637", + "ffb2bf": "86d6b6", + "bf4c60": "32738b", + "282c35": "4d2637", + "f2798d": "5eb4a9", + "268794": "1c3e58", + "3e7acc": "ecbb7a", + "7ddeff": "46988d", + "4ebdd9": "2f6e74", + "18335c": "9f2727" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/658.json b/public/images/pokemon/variant/exp/back/658.json new file mode 100644 index 00000000000..c1bb4222ce4 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/658.json @@ -0,0 +1,26 @@ +{ + "1": { + "ffb2bf": "b7e9ff", + "bf4c60": "4386df", + "3d61cc": "6b4592", + "fff0a6": "208698", + "2e4999": "432b6c", + "f2798d": "8dcfff", + "803340": "0e3e81", + "1b2a59": "170738", + "66d9ff": "7ddcd6", + "bfb169": "165e78" + }, + "2": { + "ffb2bf": "86d6b6", + "bf4c60": "32738b", + "3d61cc": "ecbb7a", + "fff0a6": "652240", + "2e4999": "cc7251", + "f2798d": "5eb4a9", + "803340": "152a5c", + "1b2a59": "9f2727", + "66d9ff": "48968c", + "bfb169": "431022" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/6706.json b/public/images/pokemon/variant/exp/back/6706.json new file mode 100644 index 00000000000..2de5352e936 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/6706.json @@ -0,0 +1,38 @@ +{ + "1": { + "566678": "197497", + "8e96aa": "3b235c", + "929aad": "3aa8c4", + "625287": "4e4094", + "536273": "301848", + "988b98": "b24c86", + "36404c": "0c5474", + "c4cce1": "513981", + "e6d3e9": "f1a4c5", + "bfacc1": "d074a0", + "546475": "0e6296", + "c5cee3": "63cee1", + "80737f": "8a2166", + "4b454f": "6f1357", + "9170b9": "8b69c3", + "b791f2": "c7a1e5" + }, + "2": { + "566678": "a34205", + "8e96aa": "073338", + "929aad": "d27e26", + "625287": "0e3f47", + "536273": "042329", + "988b98": "2b736f", + "36404c": "842401", + "c4cce1": "0d484a", + "e6d3e9": "9cead8", + "bfacc1": "5db6a9", + "546475": "8e480b", + "c5cee3": "f7af58", + "80737f": "194f51", + "4b454f": "274159", + "9170b9": "2f667c", + "b791f2": "4a9699" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/6706_2.json b/public/images/pokemon/variant/exp/back/6706_2.json deleted file mode 100644 index 5c916aeb664..00000000000 --- a/public/images/pokemon/variant/exp/back/6706_2.json +++ /dev/null @@ -1,776 +0,0 @@ -{ - "textures": [ - { - "image": "6706_2.png", - "format": "RGBA8888", - "size": { - "w": 358, - "h": 358 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 84, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 84, - "h": 69 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 84, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 84, - "h": 69 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 84, - "y": 0, - "w": 83, - "h": 72 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 84, - "y": 0, - "w": 83, - "h": 72 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 0, - "y": 69, - "w": 83, - "h": 72 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 167, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 167, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 250, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 250, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 167, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 167, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 83, - "y": 72, - "w": 82, - "h": 73 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 83, - "y": 72, - "w": 82, - "h": 73 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 249, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 249, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 0, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 0, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 0, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 0, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 81, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 81, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 81, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 81, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 165, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 165, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 247, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 247, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 162, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 162, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 81, - "h": 70 - }, - "frame": { - "x": 162, - "y": 288, - "w": 81, - "h": 70 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 81, - "h": 70 - }, - "frame": { - "x": 162, - "y": 288, - "w": 81, - "h": 70 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 242, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 242, - "y": 215, - "w": 80, - "h": 73 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:5d65e2c5a6a97b7c7014a175ce3592af:3255e87f637a475d82734fc7d93baf71:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/6706_2.png b/public/images/pokemon/variant/exp/back/6706_2.png deleted file mode 100644 index cb793478420..00000000000 Binary files a/public/images/pokemon/variant/exp/back/6706_2.png and /dev/null differ diff --git a/public/images/pokemon/variant/exp/back/6706_3.json b/public/images/pokemon/variant/exp/back/6706_3.json deleted file mode 100644 index 3bb1dc426b2..00000000000 --- a/public/images/pokemon/variant/exp/back/6706_3.json +++ /dev/null @@ -1,776 +0,0 @@ -{ - "textures": [ - { - "image": "6706_3.png", - "format": "RGBA8888", - "size": { - "w": 358, - "h": 358 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 84, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 84, - "h": 69 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 84, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 84, - "h": 69 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 84, - "y": 0, - "w": 83, - "h": 72 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 84, - "y": 0, - "w": 83, - "h": 72 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 0, - "y": 69, - "w": 83, - "h": 72 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 167, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 167, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 250, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 250, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 167, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 167, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 83, - "y": 72, - "w": 82, - "h": 73 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 83, - "y": 72, - "w": 82, - "h": 73 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 249, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 249, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 0, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 0, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 0, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 0, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 81, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 81, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 81, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 81, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 165, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 165, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 247, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 247, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 162, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 162, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 81, - "h": 70 - }, - "frame": { - "x": 162, - "y": 288, - "w": 81, - "h": 70 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 81, - "h": 70 - }, - "frame": { - "x": 162, - "y": 288, - "w": 81, - "h": 70 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 242, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 242, - "y": 215, - "w": 80, - "h": 73 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:5d65e2c5a6a97b7c7014a175ce3592af:3255e87f637a475d82734fc7d93baf71:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/6706_3.png b/public/images/pokemon/variant/exp/back/6706_3.png deleted file mode 100644 index 6390c20799f..00000000000 Binary files a/public/images/pokemon/variant/exp/back/6706_3.png and /dev/null differ diff --git a/public/images/pokemon/variant/exp/back/676.json b/public/images/pokemon/variant/exp/back/676.json new file mode 100644 index 00000000000..7e64f6b0f61 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/676.json @@ -0,0 +1,21 @@ +{ + "1": { + "f2f2da": "8a1d1d", + "3f6273": "2b040f", + "595350": "788087", + "736b67": "a6afb3", + "ccccb8": "5e0f16", + "66665c": "2b040f", + "a6a695": "42090e" + }, + "2": { + "cc2929": "3a240e", + "f2f2da": "c18960", + "3f6273": "4a281b", + "595350": "e6c594", + "736b67": "ffe6ac", + "ccccb8": "a4624a", + "66665c": "4a281b", + "a6a695": "805145" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/682.json b/public/images/pokemon/variant/exp/back/682.json new file mode 100644 index 00000000000..bc2111153cf --- /dev/null +++ b/public/images/pokemon/variant/exp/back/682.json @@ -0,0 +1,21 @@ +{ + "1": { + "6b3962": "30185d", + "cc7087": "318759", + "993d80": "4f297e", + "ff99b3": "48ab61", + "7f4d59": "20644e", + "4d4d4d": "a6a6a6" + }, + "2": { + "4f4c4f": "332539", + "6b3962": "b89477", + "cc7087": "c3561a", + "993d80": "d2bfa1", + "ff99b3": "da7e29", + "7f4d59": "a23812", + "e5e5e5": "6b4767", + "4d4d4d": "503851", + "737373": "422f46" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/683.json b/public/images/pokemon/variant/exp/back/683.json new file mode 100644 index 00000000000..9d7f4682b9a --- /dev/null +++ b/public/images/pokemon/variant/exp/back/683.json @@ -0,0 +1,20 @@ +{ + "1": { + "6b3962": "30185d", + "cc7087": "318759", + "993d80": "4f297e", + "ff99b3": "48ab61", + "404040": "2c283b", + "7f4d59": "20644e", + "bf5f9f": "7c48a1" + }, + "2": { + "6b3962": "b89477", + "cc7087": "c3561a", + "993d80": "d2bfa1", + "ff99b3": "da7e29", + "404040": "2a2234", + "7f4d59": "a23812", + "bf5f9f": "f0ebdd" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/684.json b/public/images/pokemon/variant/exp/back/684.json new file mode 100644 index 00000000000..25de3aa838f --- /dev/null +++ b/public/images/pokemon/variant/exp/back/684.json @@ -0,0 +1,22 @@ +{ + "1": { + "805963": "2d0c42", + "553a41": "8f1d15", + "ffccd9": "8961c6", + "cc99a6": "613b84", + "fff2f2": "f39f62", + "5e4048": "260b37", + "ccadad": "df6b40", + "7b5760": "b13924" + }, + "2": { + "805963": "6796aa", + "553a41": "1d1426", + "ffccd9": "cbf6da", + "cc99a6": "93d6ce", + "fff2f2": "746998", + "5e4048": "52718e", + "ccadad": "4b4876", + "7b5760": "3c2f51" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/685.json b/public/images/pokemon/variant/exp/back/685.json new file mode 100644 index 00000000000..a144e0d45ff --- /dev/null +++ b/public/images/pokemon/variant/exp/back/685.json @@ -0,0 +1,26 @@ +{ + "1": { + "f8f8f8": "caff90", + "661a2d": "13391c", + "805963": "2d0c42", + "ffccd9": "8961c6", + "ff8ca9": "8dbe6d", + "cc99a6": "613b84", + "e53964": "689b52", + "fff2f2": "f39f62", + "ccadad": "df6b40", + "a62949": "26592b" + }, + "2": { + "f8f8f8": "e4819d", + "661a2d": "26061b", + "805963": "679baa", + "ffccd9": "cbf6da", + "ff8ca9": "8c4264", + "cc99a6": "93d6ce", + "e53964": "612747", + "fff2f2": "746998", + "ccadad": "4b4876", + "a62949": "441838" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/688.json b/public/images/pokemon/variant/exp/back/688.json new file mode 100644 index 00000000000..e3d15e60fed --- /dev/null +++ b/public/images/pokemon/variant/exp/back/688.json @@ -0,0 +1,30 @@ +{ + "1": { + "bfeaff": "e8d37b", + "f2f2f2": "e8e5c6", + "5b8da6": "a9582e", + "595959": "7c582e", + "403410": "220a56", + "3f6273": "70240f", + "b3b3b3": "d3bc8c", + "ffac59": "70cccf", + "85b4cc": "cd8a50", + "997e2e": "4557b5", + "cc8a47": "459aac", + "66541f": "373295" + }, + "2": { + "bfeaff": "a74083", + "f2f2f2": "d1ec8c", + "5b8da6": "4b0038", + "595959": "4d6a09", + "403410": "1e1324", + "3f6273": "2c052a", + "b3b3b3": "94c268", + "ffac59": "4a376e", + "85b4cc": "731f5c", + "997e2e": "f6eefc", + "cc8a47": "332149", + "66541f": "ba9fba" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/689.json b/public/images/pokemon/variant/exp/back/689.json new file mode 100644 index 00000000000..6c47b57f35b --- /dev/null +++ b/public/images/pokemon/variant/exp/back/689.json @@ -0,0 +1,31 @@ +{ + "1": { + "cc7f70": "459aac", + "f2f2f2": "e8e5c6", + "5b8da6": "8d5030", + "595959": "7c582e", + "403410": "220a56", + "3f6273": "672e1e", + "b3b3b3": "d3bc8c", + "bfeaff": "e8d37b", + "85b4cc": "cd8a50", + "ff9f8c": "70cccf", + "66541f": "373295", + "997e2e": "4557b5" + }, + "2": { + "cc7f70": "332149", + "f2f2f2": "caea77", + "5b8da6": "4b0038", + "595959": "2a5524", + "403410": "3f2a4b", + "3f6273": "3e073b", + "b3b3b3": "7eac4e", + "bfeaff": "a74083", + "85b4cc": "731f5c", + "f8f8f8": "dbaf67", + "ff9f8c": "4a376e", + "66541f": "ccb6cc", + "997e2e": "f6eefc" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/807.json b/public/images/pokemon/variant/exp/back/807.json new file mode 100644 index 00000000000..aff6a52c9b2 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/807.json @@ -0,0 +1,38 @@ +{ + "1": { + "53e4f9": "eac1eb", + "ef8a4e": "4f7bb6", + "2759a5": "736599", + "5bd0f2": "ebceff", + "2394d8": "b298d8", + "31343e": "14193f", + "1f73b4": "995fc0", + "4cf4fe": "f4a7ff", + "484f57": "243058", + "daa936": "5c96b4", + "727678": "3e5277", + "30cff1": "d7a7de", + "f9e455": "80c7d7", + "000000": "ffffff", + "9d682d": "3d648c", + "14bdea": "c987e3" + }, + "2": { + "53e4f9": "e688af", + "ef8a4e": "844c94", + "2759a5": "a3378a", + "5bd0f2": "df7298", + "2394d8": "be5293", + "31343e": "a880b0", + "1f73b4": "9a1d82", + "4cf4fe": "e3418f", + "484f57": "cba3ca", + "daa936": "351d53", + "727678": "e7c9e2", + "30cff1": "d967a2", + "f9e455": "58326f", + "000000": "ffffff", + "9d682d": "1f1144", + "14bdea": "c02f8d" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/894.json b/public/images/pokemon/variant/exp/back/894.json new file mode 100644 index 00000000000..276133a842a --- /dev/null +++ b/public/images/pokemon/variant/exp/back/894.json @@ -0,0 +1,24 @@ +{ + "1": { + "e5ee1a": "6ad7f3", + "7d542a": "2769aa", + "bc8b2f": "124b78", + "8eacdd": "caffd1", + "2e3967": "357b84", + "fefac7": "dffff6", + "375395": "5fcaad", + "4e7cc9": "9bf1c4", + "d7ad0d": "45a3d6" + }, + "2": { + "e5ee1a": "d4ffd0", + "7d542a": "429877", + "bc8b2f": "2a6f5d", + "8eacdd": "c693d8", + "2e3967": "514199", + "fefac7": "ffffff", + "375395": "815bad", + "4e7cc9": "b67cd6", + "d7ad0d": "7cd395" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/895.json b/public/images/pokemon/variant/exp/back/895.json new file mode 100644 index 00000000000..d6859edafb3 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/895.json @@ -0,0 +1,28 @@ +{ + "1": { + "641e2c": "722123", + "b63650": "bc623e", + "608d99": "fae5bf", + "2b3d40": "754f47", + "4b6f78": "f1d4b6", + "e05276": "ef8429", + "f27a99": "efb55a", + "ff92ae": "edca71", + "3f545f": "ad8473", + "872c3c": "93372d", + "242e35": "512c25" + }, + "2": { + "641e2c": "15553b", + "b63650": "3bb349", + "608d99": "9b7ebc", + "2b3d40": "241951", + "4b6f78": "5a4382", + "e05276": "8aea41", + "f27a99": "dfff75", + "ff92ae": "f1ff8d", + "3f545f": "3a2a67", + "872c3c": "227843", + "242e35": "0f0c1e" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/944.json b/public/images/pokemon/variant/exp/back/944.json new file mode 100644 index 00000000000..6de6bc5e833 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/944.json @@ -0,0 +1,34 @@ +{ + "1": { + "403f4f": "33784a", + "dcdcc3": "88eeab", + "484441": "286943", + "282434": "16402d", + "2f2826": "18493f", + "774d9b": "d09139", + "8095a8": "5e4090", + "e6e2e1": "53a164", + "a599a8": "3f8d59", + "211e28": "103833", + "bbd2e3": "8056a7", + "aca699": "3ec295", + "000000": "ffffff", + "6c5c4d": "1c9b8d" + }, + "2": { + "403f4f": "395d87", + "dcdcc3": "e2f3ff", + "484441": "2c4f8a", + "282434": "1d2f5b", + "2f2826": "1e3072", + "774d9b": "4c5372", + "8095a8": "902a4b", + "e6e2e1": "78b0c2", + "a599a8": "5582a4", + "211e28": "17255b", + "bbd2e3": "c23f4f", + "aca699": "abc1df", + "000000": "ffffff", + "6c5c4d": "6777aa" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/945.json b/public/images/pokemon/variant/exp/back/945.json new file mode 100644 index 00000000000..6590d0b67ed --- /dev/null +++ b/public/images/pokemon/variant/exp/back/945.json @@ -0,0 +1,43 @@ +{ + "1": { + "403f4f": "357747", + "1f2635": "1c193d", + "dcdcc3": "5ddcb2", + "282434": "14463f", + "a491a4": "499833", + "e6e2e1": "fffbf3", + "671544": "0f4e67", + "134175": "a74d2a", + "4f483f": "1b727b", + "323d4a": "2e2452", + "000000": "ffffff", + "4b616b": "473869", + "d73875": "29ad89", + "2481b0": "d09139", + "38bdda": "ffe269", + "695575": "16613d", + "aca699": "2db3a4", + "8d2151": "157375" + }, + "2": { + "403f4f": "3b6b9e", + "1f2635": "3b091c", + "dcdcc3": "edf0f1", + "282434": "2d427e", + "a491a4": "902a4b", + "e6e2e1": "ebf4f9", + "671544": "223969", + "134175": "1c182f", + "4f483f": "5d7487", + "323d4a": "580f1d", + "000000": "ffffff", + "4b616b": "8a2029", + "a599a8": "bf888f", + "d73875": "68adca", + "2481b0": "2c2c46", + "38bdda": "494e64", + "695575": "4f133f", + "aca699": "acbfc7", + "8d2151": "4676aa" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/154.json b/public/images/pokemon/variant/female/154.json new file mode 100644 index 00000000000..c02d214d834 --- /dev/null +++ b/public/images/pokemon/variant/female/154.json @@ -0,0 +1,30 @@ +{ + "1": { + "634a00": "6da0df", + "f7a59c": "3c88ac", + "e6ad00": "90c6f8", + "ff3a5a": "234d81", + "ffde21": "b9e2ff", + "ce213a": "192e5e", + "63bd42": "9d86d9", + "bdff7b": "dadffe", + "7b103a": "111c44", + "107b31": "8057b2", + "fefefe": "a6f5af", + "9ce652": "b7afee" + }, + "2": { + "634a00": "144627", + "f7a59c": "ddf2b5", + "e6ad00": "1e632b", + "ff3a5a": "9ed662", + "ffde21": "288028", + "ce213a": "81c65c", + "63bd42": "a31f60", + "bdff7b": "f57382", + "7b103a": "59ac45", + "107b31": "761858", + "fefefe": "f6ffdf", + "9ce652": "cd3b6b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/194.json b/public/images/pokemon/variant/female/194.json new file mode 100644 index 00000000000..5824dec5029 --- /dev/null +++ b/public/images/pokemon/variant/female/194.json @@ -0,0 +1,24 @@ +{ + "1": { + "104a84": "7a150a", + "b54242": "1a6a62", + "ff6b73": "4db983", + "633a6b": "09484f", + "3a7bc5": "d5682e", + "ef73e6": "44d77f", + "73bdff": "ffc355", + "529ce6": "e8983d", + "d65ad6": "2ea380" + }, + "2": { + "104a84": "180d42", + "b54242": "8a9fc2", + "ff6b73": "e8faff", + "633a6b": "444c7e", + "3a7bc5": "3f377e", + "ef73e6": "e8faff", + "73bdff": "5c66c4", + "529ce6": "564daa", + "d65ad6": "aeccdf" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/195.json b/public/images/pokemon/variant/female/195.json new file mode 100644 index 00000000000..ff25261d120 --- /dev/null +++ b/public/images/pokemon/variant/female/195.json @@ -0,0 +1,25 @@ +{ + "1": { + "ade6ff": "f6dfa8", + "84d6f7": "ed9e4f", + "f7f7f7": "fffbea", + "637ba5": "816251", + "639cbd": "dc6a4d", + "3194a5": "44d77f", + "425284": "b03844", + "195a6b": "2ea380", + "6b5a8c": "1b5a55" + }, + "2": { + "ade6ff": "9864c2", + "84d6f7": "724ba7", + "f7f7f7": "e8b6ff", + "637ba5": "504a8a", + "639cbd": "493a8d", + "3194a5": "ebf5ff", + "19423a": "747aae", + "425284": "240830", + "195a6b": "aebbdf", + "6b5a8c": "5e649b" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/198.json b/public/images/pokemon/variant/female/198.json new file mode 100644 index 00000000000..b0386502899 --- /dev/null +++ b/public/images/pokemon/variant/female/198.json @@ -0,0 +1,34 @@ +{ + "1": { + "d94352": "b3986b", + "314263": "462b20", + "d64252": "7a101c", + "73293a": "4d0419", + "ffad8c": "ad2e24", + "73283a": "630c17", + "d6404f": "8c1b23", + "efd684": "a6a6b3", + "42639c": "694c30", + "5a4a21": "25253b", + "292942": "2a1512", + "b59c21": "57566f", + "752a3c": "755237", + "d6bd52": "838098" + }, + "2": { + "d94352": "bc4b84", + "314263": "0e4333", + "d64252": "5939a9", + "73293a": "1e1764", + "ffad8c": "b164e6", + "73283a": "630c17", + "d6404f": "8c1b23", + "efd684": "c2723a", + "42639c": "1d6e47", + "5a4a21": "4e1915", + "292942": "091e16", + "b59c21": "85412d", + "752a3c": "7b2363", + "d6bd52": "9a5524" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/25-beauty-cosplay.json b/public/images/pokemon/variant/female/25-beauty-cosplay.json new file mode 100644 index 00000000000..0e5a6a1bad2 --- /dev/null +++ b/public/images/pokemon/variant/female/25-beauty-cosplay.json @@ -0,0 +1,49 @@ +{ + "1": { + "c52119": "ad4e76", + "5e5e6b": "6c6e60", + "f7e652": "a3d1a8", + "52525a": "4f454c", + "cecab9": "cfc8aa", + "e65137": "c95578", + "fffabf": "f4f7ab", + "b52821": "ad4469", + "292929": "1e1526", + "39509d": "47449c", + "f7e860": "f2ea50", + "e65a42": "cf6182", + "4d88c4": "7976c6", + "f7bd21": "79b5a5", + "2d276d": "2f2768", + "242323": "282030", + "585861": "443e6c", + "fff7a5": "c4e3c3", + "9c5200": "315c75", + "f7cc2f": "f7bd21", + "fffdea": "f8ffe3" + }, + "2": { + "c52119": "ebc67c", + "5e5e6b": "8a2554", + "f7e652": "577b98", + "52525a": "f1b571", + "cecab9": "b84084", + "e65137": "b95b6e", + "fffabf": "f5efd1", + "b52821": "6a253f", + "292929": "a45233", + "39509d": "9ec4cd", + "f7e860": "eddc78", + "e65a42": "eedd9c", + "4d88c4": "e4f6f1", + "f7bd21": "486689", + "2d276d": "454a61", + "242323": "282030", + "585861": "3f4246", + "fff7a5": "7b96aa", + "9c5200": "283361", + "965b0e": "96500e", + "f7cc2f": "d5ac44", + "fffdea": "ea82a6" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/25-cool-cosplay.json b/public/images/pokemon/variant/female/25-cool-cosplay.json new file mode 100644 index 00000000000..de4a138b690 --- /dev/null +++ b/public/images/pokemon/variant/female/25-cool-cosplay.json @@ -0,0 +1,49 @@ +{ + "1": { + "171717": "2a1d36", + "e8b127": "f5ca2f", + "52525a": "55555e", + "c52119": "ad4e76", + "842222": "7b1f18", + "f7e652": "a3d1a8", + "fff7a5": "c4e3c3", + "2baf23": "76a848", + "f7bd21": "79b5a5", + "e65a42": "cf6182", + "ba2b23": "b73850", + "f5e193": "f4f7ab", + "e66953": "b95b6e", + "6f6c8e": "656f86", + "a6adb6": "a5b0b6", + "8c4e22": "965b0e", + "9c5200": "1c4f75", + "c43129": "6a253f", + "d95b45": "cf6887", + "45484d": "443e6c", + "3b3b40": "4a3e46", + "292929": "272b2b" + }, + "2": { + "171717": "a45233", + "e8b127": "e7b432", + "52525a": "8f4b32", + "c52119": "ebc67c", + "842222": "1e1e43", + "f7e652": "577b98", + "fff7a5": "7b96aa", + "2baf23": "572626", + "f7bd21": "445f8a", + "e65a42": "eedd9c", + "ba2b23": "2c2c47", + "f5e193": "eadbb3", + "e66953": "b95b6e", + "6f6c8e": "cf752b", + "a6adb6": "f0b541", + "8c4e22": "b1632b", + "9c5200": "22325c", + "c43129": "6a253f", + "d95b45": "3a3f5e", + "3b3b40": "f1b571", + "292929": "7d3833" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/25-cosplay.json b/public/images/pokemon/variant/female/25-cosplay.json new file mode 100644 index 00000000000..e324c094019 --- /dev/null +++ b/public/images/pokemon/variant/female/25-cosplay.json @@ -0,0 +1,36 @@ +{ + "1": { + "f7e652": "a3d1a8", + "212121": "30263b", + "c43129": "6a253f", + "171717": "1e1526", + "292929": "282030", + "e65a42": "cf6182", + "c52119": "ad4e76", + "42424a": "443e6c", + "fff7a5": "c4e3c3", + "f7bd21": "79b5a5", + "45454a": "4f454c", + "9c5200": "315c75", + "633108": "09406b", + "e66953": "b95b6e", + "de9400": "338087" + }, + "2": { + "f7e652": "577b98", + "212121": "d8805b", + "c43129": "6a253f", + "171717": "a45233", + "292929": "282030", + "e65a42": "eedd9c", + "c52119": "ebc67c", + "42424a": "3f4246", + "fff7a5": "7b96aa", + "f7bd21": "445f8a", + "45454a": "f1b571", + "9c5200": "23345e", + "633108": "22244f", + "e66953": "b95b6e", + "de9400": "324472" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/25-cute-cosplay.json b/public/images/pokemon/variant/female/25-cute-cosplay.json new file mode 100644 index 00000000000..26bebb4143d --- /dev/null +++ b/public/images/pokemon/variant/female/25-cute-cosplay.json @@ -0,0 +1,43 @@ +{ + "1": { + "212121": "30263b", + "e65a42": "cf6182", + "fff7a5": "c4e3c3", + "45454a": "4f454c", + "c52119": "ad4e76", + "9c5200": "255e8a", + "752bd0": "5452b7", + "f3bace": "f2bbbb", + "f7e652": "a3d1a8", + "ea82a6": "e8848e", + "e66953": "b95b6e", + "853247": "85323c", + "c43129": "6a253f", + "baa998": "bab699", + "42424a": "443e6c", + "fff9ba": "f0eaa8", + "f7bd21": "79b5a5", + "cf4770": "cf4a59" + }, + "2": { + "212121": "d8805b", + "e65a42": "eedd9c", + "fff7a5": "7b96aa", + "45454a": "f1b571", + "c52119": "ebc67c", + "9c5200": "1e2d52", + "752bd0": "7751c2", + "f3bace": "c5cc85", + "f7e652": "577b98", + "ea82a6": "a4b95f", + "e66953": "b95b6e", + "171717": "a45233", + "853247": "254b30", + "c43129": "6a253f", + "baa998": "d3ab5a", + "42424a": "373d45", + "fff9ba": "ebe7b7", + "f7bd21": "445f8a", + "cf4770": "739b55" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/25-partner.json b/public/images/pokemon/variant/female/25-partner.json new file mode 100644 index 00000000000..0542587ba6d --- /dev/null +++ b/public/images/pokemon/variant/female/25-partner.json @@ -0,0 +1,36 @@ +{ + "1": { + "42424a": "443e6c", + "fff7a5": "c4e3c3", + "c52119": "ad4e76", + "de9400": "338087", + "e65a42": "cf6182", + "f7e652": "a3d1a8", + "e66953": "b95b6e", + "45454a": "4f454c", + "292929": "282030", + "c43129": "6a253f", + "212121": "30263b", + "171717": "1e1526", + "f7bd21": "79b5a5", + "9c5200": "315c75", + "633108": "09406b" + }, + "2": { + "42424a": "3f4246", + "fff7a5": "7b96aa", + "c52119": "ebc67c", + "de9400": "324472", + "e65a42": "eedd9c", + "f7e652": "577b98", + "e66953": "b95b6e", + "45454a": "f1b571", + "292929": "282030", + "c43129": "6a253f", + "212121": "d8805b", + "171717": "a45233", + "f7bd21": "445f8a", + "9c5200": "23345e", + "633108": "22244f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/25-smart-cosplay.json b/public/images/pokemon/variant/female/25-smart-cosplay.json new file mode 100644 index 00000000000..4ba98883f16 --- /dev/null +++ b/public/images/pokemon/variant/female/25-smart-cosplay.json @@ -0,0 +1,42 @@ +{ + "1": { + "212121": "30263b", + "b7a599": "bab699", + "60b553": "76a848", + "366635": "3e5b2f", + "e35252": "d16b9a", + "c52119": "ad4e76", + "292929": "272b2b", + "9c5200": "315c75", + "f7e652": "a3d1a8", + "95635b": "91685f", + "171717": "1e1526", + "ba2525": "993f70", + "e65a42": "cf6182", + "54545c": "55555e", + "52525a": "4f454c", + "fffdea": "f8ffe3", + "f7bd21": "79b5a5", + "5f3434": "573b38" + }, + "2": { + "212121": "d8805b", + "b7a599": "a7b6b9", + "60b553": "dfb053", + "366635": "ab5130", + "e35252": "3a3f5e", + "c52119": "ebc67c", + "292929": "202937", + "9c5200": "23345e", + "f7e652": "577b98", + "95635b": "a09ea3", + "171717": "a45233", + "ba2525": "2b2b45", + "e65a42": "eedd9c", + "54545c": "45525c", + "52525a": "f1b571", + "fffdea": "f2f0df", + "f7bd21": "445f8a", + "5f3434": "666060" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/25-tough-cosplay.json b/public/images/pokemon/variant/female/25-tough-cosplay.json new file mode 100644 index 00000000000..620ac882643 --- /dev/null +++ b/public/images/pokemon/variant/female/25-tough-cosplay.json @@ -0,0 +1,43 @@ +{ + "1": { + "e37511": "d1694f", + "bf2629": "bf3638", + "303030": "30263b", + "b8282b": "753652", + "8d2b1d": "8e2525", + "424242": "443e6c", + "c52119": "ad4e76", + "292929": "1e1526", + "f7bd21": "79b5a5", + "fbab33": "de9764", + "db4a37": "ad4c60", + "e65a42": "cf6182", + "9c5200": "315c75", + "db5b42": "cf6a59", + "52525a": "4f454c", + "cecab9": "cfc8aa", + "f7e652": "a3d1a8" + }, + "2": { + "e37511": "644794", + "bf2629": "8e6fa1", + "f8ffe3": "e8e3e4", + "303030": "d8805b", + "b8282b": "6a253f", + "8d2b1d": "242866", + "424242": "3f4246", + "c52119": "e8be68", + "292929": "a45233", + "f7bd21": "445f8a", + "fbab33": "845ea1", + "db4a37": "b95b6e", + "e65a42": "edda8c", + "9c5200": "23345e", + "db5b42": "624780", + "52525a": "f1b571", + "4d4d4d": "2b3340", + "272b2b": "162231", + "cecab9": "cfc0c3", + "f7e652": "577b98" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/25.json b/public/images/pokemon/variant/female/25.json new file mode 100644 index 00000000000..0542587ba6d --- /dev/null +++ b/public/images/pokemon/variant/female/25.json @@ -0,0 +1,36 @@ +{ + "1": { + "42424a": "443e6c", + "fff7a5": "c4e3c3", + "c52119": "ad4e76", + "de9400": "338087", + "e65a42": "cf6182", + "f7e652": "a3d1a8", + "e66953": "b95b6e", + "45454a": "4f454c", + "292929": "282030", + "c43129": "6a253f", + "212121": "30263b", + "171717": "1e1526", + "f7bd21": "79b5a5", + "9c5200": "315c75", + "633108": "09406b" + }, + "2": { + "42424a": "3f4246", + "fff7a5": "7b96aa", + "c52119": "ebc67c", + "de9400": "324472", + "e65a42": "eedd9c", + "f7e652": "577b98", + "e66953": "b95b6e", + "45454a": "f1b571", + "292929": "282030", + "c43129": "6a253f", + "212121": "d8805b", + "171717": "a45233", + "f7bd21": "445f8a", + "9c5200": "23345e", + "633108": "22244f" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/26.json b/public/images/pokemon/variant/female/26.json new file mode 100644 index 00000000000..40921512c4b --- /dev/null +++ b/public/images/pokemon/variant/female/26.json @@ -0,0 +1,39 @@ +{ + "1": { + "101010": "000000", + "ffefd6": "c8d4ba", + "bd1908": "ad4e76", + "944242": "643034", + "bd5a31": "386d82", + "e6bd84": "a4bda7", + "ffbd00": "b3596b", + "5a2929": "293059", + "3a3a42": "30263b", + "8c6310": "8c3c4c", + "ffde5a": "cf7878", + "8d5911": "983e50", + "734231": "6e2f33", + "63636b": "4f454c", + "de7b31": "539190", + "f7ad29": "76a68b", + "643034": "395a80" + }, + "2": { + "101010": "000000", + "ffefd6": "cfc4b5", + "542127": "905331", + "bd1908": "a44c5d", + "944242": "2e4685", + "bd5a31": "375681", + "e6bd84": "a6b5ab", + "ffbd00": "f3cf91", + "5a2929": "202a60", + "8c6310": "c79b5a", + "ffde5a": "f2e4b6", + "8d5911": "dea96e", + "734231": "bd8447", + "de7b31": "4d6f98", + "f7ad29": "6385ab", + "643034": "2d3b80" + } +} \ No newline at end of file diff --git a/public/images/pokemon_icons_1v.json b/public/images/pokemon_icons_1v.json index 4400b9d0213..de66db65eb7 100644 --- a/public/images/pokemon_icons_1v.json +++ b/public/images/pokemon_icons_1v.json @@ -1,1740 +1,2299 @@ -{ "frames": { - "100_2": { - "frame": { "x": 390, "y": 53, "w": 14, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 14, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "100_3": { - "frame": { "x": 328, "y": 30, "w": 14, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 14, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "101_2": { - "frame": { "x": 287, "y": 172, "w": 16, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 16, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "101_3": { - "frame": { "x": 263, "y": 156, "w": 16, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 16, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "111_2": { - "frame": { "x": 211, "y": 226, "w": 24, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 24, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "111_3": { - "frame": { "x": 265, "y": 233, "w": 24, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 24, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "112_2": { - "frame": { "x": 347, "y": 125, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "112_3": { - "frame": { "x": 322, "y": 125, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "113_1": { - "frame": { "x": 421, "y": 158, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "113_2": { - "frame": { "x": 299, "y": 277, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "113_3": { - "frame": { "x": 280, "y": 276, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "114_2": { - "frame": { "x": 212, "y": 297, "w": 19, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "114_3": { - "frame": { "x": 336, "y": 298, "w": 19, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "116_2": { - "frame": { "x": 142, "y": 303, "w": 18, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 18, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "116_3": { - "frame": { "x": 17, "y": 303, "w": 18, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 18, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "117_2": { - "frame": { "x": 92, "y": 226, "w": 24, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 24, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "117_3": { - "frame": { "x": 376, "y": 223, "w": 24, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 24, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "118_1": { - "frame": { "x": 400, "y": 241, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "118_2": { - "frame": { "x": 20, "y": 242, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "118_3": { - "frame": { "x": 372, "y": 243, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "119_1": { - "frame": { "x": 400, "y": 200, "w": 25, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 25, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "119_2": { - "frame": { "x": 196, "y": 199, "w": 25, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 25, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "119_3": { - "frame": { "x": 0, "y": 199, "w": 25, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 25, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "120_2": { - "frame": { "x": 77, "y": 306, "w": 17, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 17, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "120_3": { - "frame": { "x": 94, "y": 311, "w": 17, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 17, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "121_2": { - "frame": { "x": 355, "y": 300, "w": 19, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "121_3": { - "frame": { "x": 58, "y": 296, "w": 19, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "123_1": { - "frame": { "x": 148, "y": 284, "w": 19, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 19, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "123_2": { - "frame": { "x": 0, "y": 284, "w": 19, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 19, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "123_3": { - "frame": { "x": 173, "y": 283, "w": 19, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 19, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "125_1": { - "frame": { "x": 69, "y": 235, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "125_2": { - "frame": { "x": 311, "y": 235, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "125_3": { - "frame": { "x": 235, "y": 234, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "126_2": { - "frame": { "x": 287, "y": 188, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "126_3": { - "frame": { "x": 378, "y": 178, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "127-mega_2": { - "frame": { "x": 0, "y": 54, "w": 31, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 4, "w": 31, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "127-mega_3": { - "frame": { "x": 359, "y": 53, "w": 31, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 4, "w": 31, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "127_2": { - "frame": { "x": 0, "y": 219, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "127_3": { - "frame": { "x": 46, "y": 223, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "129_2": { - "frame": { "x": 213, "y": 175, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "129_3": { - "frame": { "x": 418, "y": 0, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "130-mega_2": { - "frame": { "x": 30, "y": 25, "w": 30, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 30, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "130-mega_3": { - "frame": { "x": 0, "y": 25, "w": 30, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 30, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "130_2": { - "frame": { "x": 210, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "130_3": { - "frame": { "x": 239, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "131-gigantamax_2": { - "frame": { "x": 373, "y": 25, "w": 31, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 31, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "131-gigantamax_3": { - "frame": { "x": 342, "y": 25, "w": 31, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 31, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "131_2": { - "frame": { "x": 172, "y": 198, "w": 24, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 24, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "131_3": { - "frame": { "x": 354, "y": 194, "w": 24, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 24, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "132_2": { - "frame": { "x": 231, "y": 311, "w": 16, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 15, "w": 16, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "132_3": { - "frame": { "x": 247, "y": 312, "w": 16, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 15, "w": 16, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "133_2": { - "frame": { "x": 0, "y": 303, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "133_3": { - "frame": { "x": 35, "y": 305, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "134_2": { - "frame": { "x": 165, "y": 219, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "134_3": { - "frame": { "x": 69, "y": 214, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "135_1": { - "frame": { "x": 20, "y": 261, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "135_2": { - "frame": { "x": 153, "y": 263, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "135_3": { - "frame": { "x": 396, "y": 260, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "136_1": { - "frame": { "x": 23, "y": 221, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "136_2": { - "frame": { "x": 400, "y": 220, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "136_3": { - "frame": { "x": 142, "y": 217, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "137_2": { - "frame": { "x": 280, "y": 296, "w": 19, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "137_3": { - "frame": { "x": 299, "y": 297, "w": 19, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "138_2": { - "frame": { "x": 415, "y": 301, "w": 18, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 18, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "138_3": { - "frame": { "x": 167, "y": 302, "w": 18, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 18, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "139_2": { - "frame": { "x": 47, "y": 201, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "139_3": { - "frame": { "x": 243, "y": 212, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "140_2": { - "frame": { "x": 263, "y": 312, "w": 16, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 15, "w": 16, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "140_3": { - "frame": { "x": 424, "y": 239, "w": 16, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 15, "w": 16, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "141_2": { - "frame": { "x": 261, "y": 276, "w": 19, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 19, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "141_3": { - "frame": { "x": 214, "y": 276, "w": 19, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 19, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "142-mega_2": { - "frame": { "x": 268, "y": 56, "w": 32, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 5, "w": 32, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "142-mega_3": { - "frame": { "x": 62, "y": 57, "w": 32, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 5, "w": 32, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "142_2": { - "frame": { "x": 322, "y": 103, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "142_3": { - "frame": { "x": 351, "y": 103, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "144_1": { - "frame": { "x": 304, "y": 168, "w": 27, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 27, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "144_2": { - "frame": { "x": 49, "y": 158, "w": 27, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 27, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "144_3": { - "frame": { "x": 394, "y": 158, "w": 27, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 27, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "145_1": { - "frame": { "x": 77, "y": 155, "w": 29, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 7, "w": 29, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "145_2": { - "frame": { "x": 130, "y": 153, "w": 29, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 7, "w": 29, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "145_3": { - "frame": { "x": 159, "y": 153, "w": 29, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 7, "w": 29, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "146_1": { - "frame": { "x": 70, "y": 196, "w": 28, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 28, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "146_2": { - "frame": { "x": 122, "y": 195, "w": 28, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 28, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "146_3": { - "frame": { "x": 258, "y": 194, "w": 28, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 28, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "147_2": { - "frame": { "x": 192, "y": 287, "w": 20, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 20, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "147_3": { - "frame": { "x": 38, "y": 287, "w": 20, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 20, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "148_2": { - "frame": { "x": 98, "y": 204, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "148_3": { - "frame": { "x": 378, "y": 201, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "149_2": { - "frame": { "x": 188, "y": 155, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "149_3": { - "frame": { "x": 24, "y": 156, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "150-mega-x_2": { - "frame": { "x": 106, "y": 155, "w": 21, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 21, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "150-mega-x_3": { - "frame": { "x": 242, "y": 156, "w": 21, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 21, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "150-mega-y_2": { - "frame": { "x": 175, "y": 107, "w": 20, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 0, "w": 20, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "150-mega-y_3": { - "frame": { "x": 407, "y": 108, "w": 20, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 0, "w": 20, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "150_2": { - "frame": { "x": 352, "y": 236, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "150_3": { - "frame": { "x": 332, "y": 235, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "151_2": { - "frame": { "x": 195, "y": 130, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "151_3": { - "frame": { "x": 231, "y": 127, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "19_2": { - "frame": { "x": 321, "y": 258, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "19_3": { - "frame": { "x": 0, "y": 263, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1_2": { - "frame": { "x": 338, "y": 279, "w": 20, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 20, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1_3": { - "frame": { "x": 318, "y": 279, "w": 20, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 20, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "20_2": { - "frame": { "x": 174, "y": 177, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "20_3": { - "frame": { "x": 23, "y": 178, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "23_2": { - "frame": { "x": 416, "y": 280, "w": 18, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 18, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "23_3": { - "frame": { "x": 20, "y": 282, "w": 18, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 18, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "24_2": { - "frame": { "x": 138, "y": 238, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "24_3": { - "frame": { "x": 0, "y": 240, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "29_1": { - "frame": { "x": 130, "y": 133, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "29_2": { - "frame": { "x": 397, "y": 299, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "29_3": { - "frame": { "x": 379, "y": 299, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2_2": { - "frame": { "x": 362, "y": 262, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2_3": { - "frame": { "x": 173, "y": 263, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "3-gigantamax_2": { - "frame": { "x": 214, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "3-gigantamax_3": { - "frame": { "x": 246, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "3-mega_2": { - "frame": { "x": 181, "y": 58, "w": 29, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 29, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "3-mega_3": { - "frame": { "x": 152, "y": 57, "w": 29, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 29, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "30_2": { - "frame": { "x": 87, "y": 267, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "30_3": { - "frame": { "x": 40, "y": 265, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "31_1": { - "frame": { "x": 331, "y": 168, "w": 23, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 23, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "31_2": { - "frame": { "x": 0, "y": 172, "w": 23, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 23, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "31_3": { - "frame": { "x": 127, "y": 172, "w": 23, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 23, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "35_2": { - "frame": { "x": 318, "y": 298, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "35_3": { - "frame": { "x": 124, "y": 299, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "36_2": { - "frame": { "x": 178, "y": 240, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "36_3": { - "frame": { "x": 158, "y": 240, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "37_2": { - "frame": { "x": 194, "y": 267, "w": 20, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 20, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "37_3": { - "frame": { "x": 241, "y": 274, "w": 20, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 20, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "38_2": { - "frame": { "x": 370, "y": 149, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "38_3": { - "frame": { "x": 218, "y": 152, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "3_2": { - "frame": { "x": 0, "y": 79, "w": 30, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 4, "w": 30, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "3_3": { - "frame": { "x": 240, "y": 80, "w": 30, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 4, "w": 30, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "41_1": { - "frame": { "x": 341, "y": 259, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "41_2": { - "frame": { "x": 416, "y": 260, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "41_3": { - "frame": { "x": 132, "y": 261, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "42_1": { - "frame": { "x": 104, "y": 133, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "42_2": { - "frame": { "x": 25, "y": 134, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "42_3": { - "frame": { "x": 51, "y": 136, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "43_2": { - "frame": { "x": 423, "y": 220, "w": 17, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 17, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "43_3": { - "frame": { "x": 423, "y": 178, "w": 17, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 17, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "44_2": { - "frame": { "x": 116, "y": 235, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "44_3": { - "frame": { "x": 289, "y": 235, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "45_2": { - "frame": { "x": 100, "y": 181, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "45_3": { - "frame": { "x": 48, "y": 178, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "46_1": { - "frame": { "x": 65, "y": 257, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "46_2": { - "frame": { "x": 299, "y": 257, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "46_3": { - "frame": { "x": 78, "y": 113, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "47_1": { - "frame": { "x": 25, "y": 199, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "47_2": { - "frame": { "x": 308, "y": 213, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "47_3": { - "frame": { "x": 120, "y": 213, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4_2": { - "frame": { "x": 59, "y": 277, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4_3": { - "frame": { "x": 106, "y": 277, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "50_2": { - "frame": { "x": 425, "y": 138, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "50_3": { - "frame": { "x": 425, "y": 197, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "51_2": { - "frame": { "x": 286, "y": 211, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "51_3": { - "frame": { "x": 221, "y": 204, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "52-gigantamax_1": { - "frame": { "x": 77, "y": 83, "w": 23, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 23, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "52-gigantamax_2": { - "frame": { "x": 54, "y": 81, "w": 23, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 23, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "52-gigantamax_3": { - "frame": { "x": 417, "y": 78, "w": 23, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 23, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "52_1": { - "frame": { "x": 44, "y": 244, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "52_2": { - "frame": { "x": 90, "y": 246, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "52_3": { - "frame": { "x": 198, "y": 246, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "53_1": { - "frame": { "x": 235, "y": 182, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "53_2": { - "frame": { "x": 400, "y": 178, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "53_3": { - "frame": { "x": 309, "y": 191, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "56_1": { - "frame": { "x": 342, "y": 148, "w": 28, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 28, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "56_2": { - "frame": { "x": 314, "y": 148, "w": 28, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 28, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "56_3": { - "frame": { "x": 397, "y": 138, "w": 28, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 28, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "57_1": { - "frame": { "x": 150, "y": 83, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "57_2": { - "frame": { "x": 294, "y": 103, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "57_3": { - "frame": { "x": 0, "y": 103, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "5_2": { - "frame": { "x": 332, "y": 191, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "5_3": { - "frame": { "x": 150, "y": 194, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6-gigantamax_2": { - "frame": { "x": 270, "y": 80, "w": 24, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 24, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6-gigantamax_3": { - "frame": { "x": 30, "y": 81, "w": 24, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 24, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6-mega-x_2": { - "frame": { "x": 40, "y": 0, "w": 40, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 2, "w": 40, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6-mega-x_3": { - "frame": { "x": 0, "y": 0, "w": 40, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 2, "w": 40, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6-mega-y_2": { - "frame": { "x": 380, "y": 0, "w": 38, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 2, "w": 38, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6-mega-y_3": { - "frame": { "x": 342, "y": 0, "w": 38, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 2, "w": 38, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "69_2": { - "frame": { "x": 173, "y": 137, "w": 20, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 13, "w": 20, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "69_3": { - "frame": { "x": 185, "y": 305, "w": 20, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 13, "w": 20, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6_2": { - "frame": { "x": 60, "y": 29, "w": 32, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 32, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6_3": { - "frame": { "x": 404, "y": 25, "w": 32, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 32, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "70_2": { - "frame": { "x": 277, "y": 256, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "70_3": { - "frame": { "x": 219, "y": 256, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "71_2": { - "frame": { "x": 178, "y": 84, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "71_3": { - "frame": { "x": 210, "y": 83, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "77_2": { - "frame": { "x": 280, "y": 149, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "77_3": { - "frame": { "x": 0, "y": 149, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "78_2": { - "frame": { "x": 123, "y": 57, "w": 29, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 29, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "78_3": { - "frame": { "x": 94, "y": 57, "w": 29, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 29, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "79_1": { - "frame": { "x": 265, "y": 212, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "79_2": { - "frame": { "x": 256, "y": 253, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "79_3": { - "frame": { "x": 111, "y": 256, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "7_2": { - "frame": { "x": 233, "y": 294, "w": 21, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 21, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "7_3": { - "frame": { "x": 80, "y": 289, "w": 21, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 21, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "80-mega_2": { - "frame": { "x": 125, "y": 83, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "80-mega_3": { - "frame": { "x": 100, "y": 83, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "80_2": { - "frame": { "x": 238, "y": 104, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "80_3": { - "frame": { "x": 380, "y": 103, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "81_2": { - "frame": { "x": 101, "y": 296, "w": 23, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 23, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "81_3": { - "frame": { "x": 254, "y": 297, "w": 23, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 23, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "82_2": { - "frame": { "x": 354, "y": 172, "w": 24, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 24, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "82_3": { - "frame": { "x": 76, "y": 174, "w": 24, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 24, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "83_2": { - "frame": { "x": 78, "y": 133, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "83_3": { - "frame": { "x": 254, "y": 134, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "84_1": { - "frame": { "x": 358, "y": 282, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "84_2": { - "frame": { "x": 383, "y": 281, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "84_3": { - "frame": { "x": 127, "y": 281, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "85_1": { - "frame": { "x": 388, "y": 78, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "85_2": { - "frame": { "x": 359, "y": 78, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "85_3": { - "frame": { "x": 330, "y": 78, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "86_1": { - "frame": { "x": 53, "y": 113, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "86_2": { - "frame": { "x": 28, "y": 111, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "86_3": { - "frame": { "x": 148, "y": 130, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "87_1": { - "frame": { "x": 372, "y": 126, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "87_2": { - "frame": { "x": 0, "y": 126, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "87_3": { - "frame": { "x": 289, "y": 126, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "8_2": { - "frame": { "x": 150, "y": 172, "w": 24, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 24, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "8_3": { - "frame": { "x": 263, "y": 172, "w": 24, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 24, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "9-gigantamax_2": { - "frame": { "x": 181, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "9-gigantamax_3": { - "frame": { "x": 152, "y": 29, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "9-mega_2": { - "frame": { "x": 122, "y": 29, "w": 30, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 30, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "9-mega_3": { - "frame": { "x": 92, "y": 29, "w": 30, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 30, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "92_1": { - "frame": { "x": 188, "y": 219, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "92_2": { - "frame": { "x": 330, "y": 214, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "92_3": { - "frame": { "x": 353, "y": 215, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "93_1": { - "frame": { "x": 404, "y": 52, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "93_2": { - "frame": { "x": 268, "y": 30, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "93_3": { - "frame": { "x": 298, "y": 30, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 2, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94-gigantamax_1": { - "frame": { "x": 182, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94-gigantamax_2": { - "frame": { "x": 310, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94-gigantamax_3": { - "frame": { "x": 278, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94-mega_1": { - "frame": { "x": 148, "y": 0, "w": 34, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 34, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94-mega_2": { - "frame": { "x": 114, "y": 0, "w": 34, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 34, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94-mega_3": { - "frame": { "x": 80, "y": 0, "w": 34, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 34, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94_1": { - "frame": { "x": 265, "y": 110, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94_2": { - "frame": { "x": 124, "y": 109, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "94_3": { - "frame": { "x": 100, "y": 109, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "98_2": { - "frame": { "x": 240, "y": 58, "w": 28, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 28, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "98_3": { - "frame": { "x": 300, "y": 56, "w": 28, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 28, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "99-gigantamax_2": { - "frame": { "x": 328, "y": 53, "w": 31, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 31, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "99-gigantamax_3": { - "frame": { "x": 31, "y": 56, "w": 31, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 31, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "99_2": { - "frame": { "x": 300, "y": 78, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "99_3": { - "frame": { "x": 210, "y": 58, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "9_2": { - "frame": { "x": 150, "y": 106, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "9_3": { - "frame": { "x": 206, "y": 106, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_1v.png", - "format": "RGBA8888", - "size": { "w": 440, "h": 328 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_1v.png", + "format": "RGBA8888", + "size": { + "w": 600, + "h": 600 + }, + "scale": 1, + "frames": [ + { + "filename": "1_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "1_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "2_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "2_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "3-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "3-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "3-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "3-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "3_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "3_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "4_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "4_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "5_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "5_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "6-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 0, "w": 40, "h": 30} + }, + { + "filename": "6-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "6-mega-x_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "6-mega-x_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "6-mega-y_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "6-mega-y_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "6_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "6_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "7_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "7_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "8_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "8_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "9-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "9-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "9-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "9-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 30, "w": 40, "h": 30} + }, + { + "filename": "9_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "9_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "19_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "19_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "20_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "20_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "23_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "23_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "24_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "24_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "25-beauty-cosplay_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "25-beauty-cosplay_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "25-cool-cosplay_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "25-cool-cosplay_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "25-cosplay_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 60, "w": 40, "h": 30} + }, + { + "filename": "25-cosplay_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-cute-cosplay_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-cute-cosplay_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-partner_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-partner_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-smart-cosplay_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-smart-cosplay_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-tough-cosplay_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25-tough-cosplay_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "25_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "26_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "26_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 90, "w": 40, "h": 30} + }, + { + "filename": "29_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "29_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "29_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "30_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "30_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "31_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "31_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "31_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "35_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "35_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "36_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "36_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "37_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "37_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "38_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 120, "w": 40, "h": 30} + }, + { + "filename": "38_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "39_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "39_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "40_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "40_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "41_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "41_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "41_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "42_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "42_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "42_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "43_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "43_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "44_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "44_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 150, "w": 40, "h": 30} + }, + { + "filename": "45_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "45_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "46_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "46_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "46_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "47_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "47_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "47_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "50_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "50_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "51_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "51_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "52-gigantamax_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "52-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "52-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 180, "w": 40, "h": 30} + }, + { + "filename": "52_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "52_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "52_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "53_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "53_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "53_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "56_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "56_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "56_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "57_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "57_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "57_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "69_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "69_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "70_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 210, "w": 40, "h": 30} + }, + { + "filename": "70_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "71_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "71_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "77_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "77_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "78_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "78_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "79_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "79_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "79_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "80-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "80-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "80_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "80_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "81_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 240, "w": 40, "h": 30} + }, + { + "filename": "81_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "82_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "82_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "83_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "83_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "84-f_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "84-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "84-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "84_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "84_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "84_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "85-f_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "85-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "85-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "85_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 270, "w": 40, "h": 30} + }, + { + "filename": "85_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "85_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "86_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "86_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "86_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "87_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "87_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "87_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "92_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "92_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "92_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "93_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "93_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "93_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "94-gigantamax_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 300, "w": 40, "h": 30} + }, + { + "filename": "94-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "94-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "94-mega_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "94-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "94-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "94_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "94_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "94_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "98_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "98_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "99-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "99-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "99_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "99_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "100_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 330, "w": 40, "h": 30} + }, + { + "filename": "100_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "101_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "101_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "102_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "102_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "103_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "103_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "111_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "111_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "112_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "112_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "113_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "113_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "113_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "114_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 360, "w": 40, "h": 30} + }, + { + "filename": "114_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "116_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "116_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "117_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "117_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "118_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "118_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "118_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "119_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "119_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "119_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "120_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "120_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "121_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "121_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 390, "w": 40, "h": 30} + }, + { + "filename": "123_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "123_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "123_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "125_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "125_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "125_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "126_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "126_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "127-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "127-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "127_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "127_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "128_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "128_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "129_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 420, "w": 40, "h": 30} + }, + { + "filename": "129_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "130-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "130-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "130_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "130_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "131-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "131-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "131_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "131_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "132_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "132_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "133-partner_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "133-partner_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "133_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "133_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 450, "w": 40, "h": 30} + }, + { + "filename": "134_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "134_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "135_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "135_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "135_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "136_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "136_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "136_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "137_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "137_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "138_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "138_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "139_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "139_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "140_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 480, "w": 40, "h": 30} + }, + { + "filename": "140_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "141_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "141_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "142-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "142-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "142_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "142_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "144_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "144_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "144_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "145_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "145_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "145_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "146_1", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "146_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 510, "w": 40, "h": 30} + }, + { + "filename": "146_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 0, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "147_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 40, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "147_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 80, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "148_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 120, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "148_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 160, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "149_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 200, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "149_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 240, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "150-mega-x_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 280, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "150-mega-x_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 320, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "150-mega-y_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 360, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "150-mega-y_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 400, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "150_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 440, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "150_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 480, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "151_2", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 520, "y": 540, "w": 40, "h": 30} + }, + { + "filename": "151_3", + "rotated": false, + "trimmed": false, + "sourceSize": {"w": 40, "h": 30}, + "spriteSourceSize": {"x": 0, "y": 0, "w": 40, "h": 30}, + "frame": {"x": 560, "y": 540, "w": 40, "h": 30} + } + ] + } + ], + "meta": { + "app": "texturepacker", + "version": "3.0" + } } diff --git a/public/images/pokemon_icons_1v.png b/public/images/pokemon_icons_1v.png index 2aa0433b3f6..d6b1bc0cf7e 100644 Binary files a/public/images/pokemon_icons_1v.png and b/public/images/pokemon_icons_1v.png differ diff --git a/public/images/pokemon_icons_2v.json b/public/images/pokemon_icons_2v.json index ac38ebbcf6b..23eec483b42 100644 --- a/public/images/pokemon_icons_2v.json +++ b/public/images/pokemon_icons_2v.json @@ -1,1271 +1,4640 @@ -{ "frames": { - "161_2": { - "frame": { "x": 225, "y": 163, "w": 15, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 4, "w": 15, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "161_3": { - "frame": { "x": 82, "y": 162, "w": 15, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 4, "w": 15, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "162_2": { - "frame": { "x": 22, "y": 102, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "162_3": { - "frame": { "x": 45, "y": 103, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "163_2": { - "frame": { "x": 0, "y": 184, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "163_3": { - "frame": { "x": 240, "y": 183, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "164_2": { - "frame": { "x": 64, "y": 145, "w": 18, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 18, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "164_3": { - "frame": { "x": 186, "y": 145, "w": 18, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 18, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "169_1": { - "frame": { "x": 148, "y": 29, "w": 30, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 30, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "169_2": { - "frame": { "x": 55, "y": 30, "w": 30, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 30, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "169_3": { - "frame": { "x": 85, "y": 30, "w": 30, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 30, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "173_3": { - "frame": { "x": 64, "y": 223, "w": 16, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 16, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "175_1": { - "frame": { "x": 185, "y": 206, "w": 16, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 16, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "175_2": { - "frame": { "x": 31, "y": 207, "w": 16, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 16, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "175_3": { - "frame": { "x": 169, "y": 207, "w": 16, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 16, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "176_1": { - "frame": { "x": 54, "y": 168, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "176_2": { - "frame": { "x": 37, "y": 166, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "176_3": { - "frame": { "x": 261, "y": 99, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "177_2": { - "frame": { "x": 135, "y": 196, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "177_3": { - "frame": { "x": 152, "y": 196, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "178_2": { - "frame": { "x": 276, "y": 164, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "178_3": { - "frame": { "x": 293, "y": 164, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "179_2": { - "frame": { "x": 226, "y": 143, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "179_3": { - "frame": { "x": 88, "y": 142, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "180_2": { - "frame": { "x": 116, "y": 122, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "180_3": { - "frame": { "x": 239, "y": 121, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "181-mega_2": { - "frame": { "x": 262, "y": 0, "w": 29, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 29, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "181-mega_3": { - "frame": { "x": 291, "y": 0, "w": 29, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 29, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "181_2": { - "frame": { "x": 200, "y": 96, "w": 20, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 3, "w": 20, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "181_3": { - "frame": { "x": 124, "y": 97, "w": 20, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 3, "w": 20, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "182_2": { - "frame": { "x": 97, "y": 184, "w": 16, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 16, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "182_3": { - "frame": { "x": 17, "y": 184, "w": 16, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 16, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "183_2": { - "frame": { "x": 154, "y": 160, "w": 23, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 11, "w": 23, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "183_3": { - "frame": { "x": 131, "y": 156, "w": 23, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 11, "w": 23, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "184_2": { - "frame": { "x": 25, "y": 56, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "184_3": { - "frame": { "x": 202, "y": 53, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "185_2": { - "frame": { "x": 22, "y": 123, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "185_3": { - "frame": { "x": 0, "y": 123, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "190_2": { - "frame": { "x": 284, "y": 124, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 9, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "190_3": { - "frame": { "x": 260, "y": 124, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 9, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "193_2": { - "frame": { "x": 137, "y": 140, "w": 28, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 12, "w": 28, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "193_3": { - "frame": { "x": 88, "y": 126, "w": 28, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 12, "w": 28, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "196_1": { - "frame": { "x": 251, "y": 78, "w": 27, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 27, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "196_2": { - "frame": { "x": 0, "y": 80, "w": 27, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 27, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "196_3": { - "frame": { "x": 289, "y": 77, "w": 27, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 27, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "197_2": { - "frame": { "x": 289, "y": 143, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "197_3": { - "frame": { "x": 269, "y": 143, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "199_1": { - "frame": { "x": 220, "y": 97, "w": 19, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 2, "w": 19, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "199_2": { - "frame": { "x": 297, "y": 98, "w": 19, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 2, "w": 19, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "199_3": { - "frame": { "x": 278, "y": 98, "w": 19, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 2, "w": 19, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "200_1": { - "frame": { "x": 69, "y": 204, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "200_2": { - "frame": { "x": 257, "y": 202, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "200_3": { - "frame": { "x": 211, "y": 203, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-a_2": { - "frame": { "x": 148, "y": 233, "w": 10, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 7, "w": 10, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-a_3": { - "frame": { "x": 128, "y": 230, "w": 10, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 7, "w": 10, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-b_2": { - "frame": { "x": 13, "y": 225, "w": 12, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 7, "w": 12, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-b_3": { - "frame": { "x": 271, "y": 224, "w": 12, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 7, "w": 12, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-c_2": { - "frame": { "x": 85, "y": 205, "w": 15, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-c_3": { - "frame": { "x": 304, "y": 205, "w": 15, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-d_2": { - "frame": { "x": 201, "y": 222, "w": 14, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 9, "w": 14, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-d_3": { - "frame": { "x": 215, "y": 222, "w": 14, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 9, "w": 14, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-exclamation_2": { - "frame": { "x": 227, "y": 53, "w": 10, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 8, "w": 10, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-exclamation_3": { - "frame": { "x": 103, "y": 241, "w": 10, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 8, "w": 10, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-e_2": { - "frame": { "x": 257, "y": 221, "w": 14, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 14, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-e_3": { - "frame": { "x": 243, "y": 203, "w": 14, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 14, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-f_2": { - "frame": { "x": 152, "y": 214, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-f_3": { - "frame": { "x": 212, "y": 77, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-g_2": { - "frame": { "x": 310, "y": 145, "w": 10, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 7, "w": 10, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-g_3": { - "frame": { "x": 138, "y": 230, "w": 10, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 7, "w": 10, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-h_2": { - "frame": { "x": 177, "y": 168, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-h_3": { - "frame": { "x": 115, "y": 173, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-i_2": { - "frame": { "x": 113, "y": 241, "w": 10, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 8, "w": 10, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-i_3": { - "frame": { "x": 199, "y": 241, "w": 10, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 8, "w": 10, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-j_2": { - "frame": { "x": 62, "y": 239, "w": 11, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 9, "w": 11, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-j_3": { - "frame": { "x": 92, "y": 241, "w": 11, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 9, "w": 11, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-k_2": { - "frame": { "x": 229, "y": 222, "w": 13, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 13, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-k_3": { - "frame": { "x": 226, "y": 123, "w": 13, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 13, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-l_2": { - "frame": { "x": 291, "y": 208, "w": 13, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 13, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-l_3": { - "frame": { "x": 0, "y": 223, "w": 13, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 13, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-m_2": { - "frame": { "x": 97, "y": 164, "w": 18, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 18, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-m_3": { - "frame": { "x": 19, "y": 164, "w": 18, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 18, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-n_2": { - "frame": { "x": 211, "y": 189, "w": 22, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 13, "w": 22, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-n_3": { - "frame": { "x": 113, "y": 192, "w": 22, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 13, "w": 22, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-o_2": { - "frame": { "x": 151, "y": 177, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-o_3": { - "frame": { "x": 133, "y": 173, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-p_2": { - "frame": { "x": 71, "y": 168, "w": 11, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 8, "w": 11, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-p_3": { - "frame": { "x": 278, "y": 78, "w": 11, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 8, "w": 11, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-question_2": { - "frame": { "x": 309, "y": 124, "w": 11, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 7, "w": 11, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-question_3": { - "frame": { "x": 51, "y": 225, "w": 11, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 7, "w": 11, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-q_2": { - "frame": { "x": 304, "y": 225, "w": 14, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 14, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-q_3": { - "frame": { "x": 283, "y": 228, "w": 14, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 14, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-r_2": { - "frame": { "x": 255, "y": 241, "w": 10, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 10, "w": 10, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-r_3": { - "frame": { "x": 297, "y": 241, "w": 10, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 16, "y": 10, "w": 10, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-s_2": { - "frame": { "x": 290, "y": 185, "w": 14, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 14, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-s_3": { - "frame": { "x": 276, "y": 185, "w": 14, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 14, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-t_2": { - "frame": { "x": 167, "y": 225, "w": 12, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 12, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-t_3": { - "frame": { "x": 80, "y": 225, "w": 12, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 12, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-u_2": { - "frame": { "x": 273, "y": 208, "w": 18, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 12, "w": 18, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-u_3": { - "frame": { "x": 134, "y": 214, "w": 18, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 12, "w": 18, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-v_2": { - "frame": { "x": 100, "y": 223, "w": 14, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 14, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-v_3": { - "frame": { "x": 185, "y": 224, "w": 14, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 14, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-w_2": { - "frame": { "x": 100, "y": 206, "w": 17, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 17, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-w_3": { - "frame": { "x": 117, "y": 206, "w": 17, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 17, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-x_2": { - "frame": { "x": 242, "y": 241, "w": 13, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 14, "w": 13, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-x_3": { - "frame": { "x": 209, "y": 241, "w": 13, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 14, "w": 13, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-y_2": { - "frame": { "x": 25, "y": 225, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-y_3": { - "frame": { "x": 38, "y": 225, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-z_2": { - "frame": { "x": 310, "y": 166, "w": 10, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 9, "w": 10, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "201-z_3": { - "frame": { "x": 185, "y": 187, "w": 10, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 9, "w": 10, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "203_2": { - "frame": { "x": 102, "y": 80, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "203_3": { - "frame": { "x": 51, "y": 80, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "206_2": { - "frame": { "x": 204, "y": 146, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "206_3": { - "frame": { "x": 42, "y": 147, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "207_2": { - "frame": { "x": 227, "y": 73, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "207_3": { - "frame": { "x": 103, "y": 56, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "212-mega_1": { - "frame": { "x": 234, "y": 0, "w": 28, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 28, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "212-mega_2": { - "frame": { "x": 206, "y": 0, "w": 28, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 28, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "212-mega_3": { - "frame": { "x": 178, "y": 0, "w": 28, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 28, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "212_1": { - "frame": { "x": 122, "y": 29, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "212_2": { - "frame": { "x": 292, "y": 26, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "212_3": { - "frame": { "x": 29, "y": 29, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "213_2": { - "frame": { "x": 27, "y": 80, "w": 24, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 24, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "213_3": { - "frame": { "x": 78, "y": 77, "w": 24, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 24, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "215_2": { - "frame": { "x": 259, "y": 164, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "215_3": { - "frame": { "x": 204, "y": 165, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "216_2": { - "frame": { "x": 304, "y": 185, "w": 16, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 16, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "216_3": { - "frame": { "x": 169, "y": 187, "w": 16, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 16, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "217_1": { - "frame": { "x": 95, "y": 103, "w": 21, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 21, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "217_2": { - "frame": { "x": 144, "y": 117, "w": 21, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 21, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "217_3": { - "frame": { "x": 165, "y": 117, "w": 21, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 21, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "222_2": { - "frame": { "x": 248, "y": 143, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "222_3": { - "frame": { "x": 110, "y": 144, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "226_2": { - "frame": { "x": 182, "y": 77, "w": 30, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 9, "w": 30, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "226_3": { - "frame": { "x": 152, "y": 77, "w": 30, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 9, "w": 30, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "227_2": { - "frame": { "x": 127, "y": 74, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "227_3": { - "frame": { "x": 237, "y": 28, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "228_2": { - "frame": { "x": 0, "y": 164, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "228_3": { - "frame": { "x": 240, "y": 163, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "229-mega_2": { - "frame": { "x": 266, "y": 51, "w": 23, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 23, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "229-mega_3": { - "frame": { "x": 55, "y": 53, "w": 23, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 23, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "229_2": { - "frame": { "x": 44, "y": 124, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "229_3": { - "frame": { "x": 206, "y": 123, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "230_2": { - "frame": { "x": 68, "y": 121, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "230_3": { - "frame": { "x": 186, "y": 121, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "231_2": { - "frame": { "x": 49, "y": 189, "w": 20, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "231_3": { - "frame": { "x": 71, "y": 188, "w": 20, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "232_2": { - "frame": { "x": 237, "y": 51, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "232_3": { - "frame": { "x": 148, "y": 52, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "233_2": { - "frame": { "x": 257, "y": 185, "w": 19, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 19, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "233_3": { - "frame": { "x": 127, "y": 56, "w": 19, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 19, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "235_2": { - "frame": { "x": 176, "y": 96, "w": 24, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 7, "w": 24, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "235_3": { - "frame": { "x": 152, "y": 96, "w": 24, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 7, "w": 24, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "239_1": { - "frame": { "x": 0, "y": 144, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "239_2": { - "frame": { "x": 21, "y": 144, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "239_3": { - "frame": { "x": 165, "y": 140, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "240_2": { - "frame": { "x": 33, "y": 187, "w": 16, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 16, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "240_3": { - "frame": { "x": 195, "y": 186, "w": 16, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 16, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "242_1": { - "frame": { "x": 239, "y": 99, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "242_2": { - "frame": { "x": 0, "y": 101, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "242_3": { - "frame": { "x": 73, "y": 99, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "243_2": { - "frame": { "x": 262, "y": 26, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "243_3": { - "frame": { "x": 178, "y": 28, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "244_2": { - "frame": { "x": 289, "y": 53, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "244_3": { - "frame": { "x": 0, "y": 54, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "245_2": { - "frame": { "x": 208, "y": 28, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "245_3": { - "frame": { "x": 0, "y": 29, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "246_2": { - "frame": { "x": 49, "y": 205, "w": 15, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 15, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "246_3": { - "frame": { "x": 16, "y": 205, "w": 15, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 15, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "247_2": { - "frame": { "x": 0, "y": 204, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "247_3": { - "frame": { "x": 227, "y": 203, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "248-mega_2": { - "frame": { "x": 122, "y": 0, "w": 28, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 28, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "248-mega_3": { - "frame": { "x": 150, "y": 0, "w": 28, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 28, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "248_2": { - "frame": { "x": 177, "y": 53, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "248_3": { - "frame": { "x": 78, "y": 53, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "249_2": { - "frame": { "x": 0, "y": 0, "w": 32, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "249_3": { - "frame": { "x": 32, "y": 0, "w": 32, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "250_2": { - "frame": { "x": 93, "y": 0, "w": 29, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 29, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "250_3": { - "frame": { "x": 64, "y": 0, "w": 29, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 29, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "251_2": { - "frame": { "x": 114, "y": 223, "w": 14, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 14, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "251_3": { - "frame": { "x": 242, "y": 223, "w": 14, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 14, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_2v.png", - "format": "RGBA8888", - "size": { "w": 320, "h": 261 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_2v.png", + "format": "RGBA8888", + "size": { + "w": 520, + "h": 520 + }, + "scale": 1, + "frames": [ + { + "filename": "152_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "152_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "153_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "153_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "154-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "154-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "154_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "154_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "158_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "158_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "159_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "159_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "160_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "160_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "161_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "161_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "162_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "162_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "163_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "163_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "164_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "164_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "167_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "167_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "168_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "168_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "169_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "169_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "169_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "170_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "170_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "171_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "171_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "172-spiky_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "172-spiky_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "172_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "172_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "173_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "173_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "174_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "174_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "175_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "175_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "175_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "176_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "176_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "176_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "177_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "177_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "178_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "178_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "179_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "179_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "180_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "180_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "181-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "181-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "181_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "181_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "182_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "182_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "183_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "183_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "184_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "184_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "185_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "185_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "190_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "190_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "193_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "193_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "194_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "194_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "195_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "195_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "196_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "196_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "196_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "197_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "197_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "198-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "198_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "198-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "198_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "199_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "199_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "199_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "200_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "200_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "200_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-a_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-a_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-b_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-b_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-c_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-c_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-d_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-d_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-e_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-e_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-exclamation_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-exclamation_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-g_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-g_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-h_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-h_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-i_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-i_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-j_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-j_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-k_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-k_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-l_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-l_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-m_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-m_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-n_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-n_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-o_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-o_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-p_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-p_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-q_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-q_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-question_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-question_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-r_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-r_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-s_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-s_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-t_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-t_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-u_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-u_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-v_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-v_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-w_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-w_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-x_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-x_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-y_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-y_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-z_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "201-z_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "203_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "203_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "206_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "206_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "207_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "207_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "211_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "211_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "212-mega_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "212-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "212-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "212_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "212_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "212_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "213_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "213_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "215_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "215_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "216_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "216_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "216_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "217_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "217_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "217_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "222_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "222_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "226_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "226_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "227_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "227_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "228_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "228_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "229-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "229-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "229_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "229_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "230_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "230_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "231_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "231_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "232_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "232_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "233_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "233_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "235_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "235_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "239_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "239_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "239_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "240_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "240_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "242_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "242_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "242_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "243_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "243_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "244_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "244_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "245_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "245_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "246_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "246_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "247_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "247_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "248-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "248-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "248_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "248_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "249_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "249_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "250_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "250_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "251_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "251_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 480, + "w": 40, + "h": 30 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:cb87bf48266ab3d893dbbd24a52f875f:d37e73561b49b4fe831e3fcaee67b851:63b368599cdc6e139499267117e91cd5$" + } } diff --git a/public/images/pokemon_icons_2v.png b/public/images/pokemon_icons_2v.png index 443d14b176d..e74840b647b 100644 Binary files a/public/images/pokemon_icons_2v.png and b/public/images/pokemon_icons_2v.png differ diff --git a/public/images/pokemon_icons_3v.json b/public/images/pokemon_icons_3v.json index 2cd15286a81..2500eebbff8 100644 --- a/public/images/pokemon_icons_3v.json +++ b/public/images/pokemon_icons_3v.json @@ -1,1411 +1,4661 @@ -{ "frames": { - "255_2": { - "frame": { "x": 167, "y": 275, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "255_3": { - "frame": { "x": 367, "y": 186, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "256_2": { - "frame": { "x": 106, "y": 124, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "256_3": { - "frame": { "x": 51, "y": 124, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "257-mega_2": { - "frame": { "x": 146, "y": 0, "w": 32, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 32, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "257-mega_3": { - "frame": { "x": 178, "y": 0, "w": 32, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 32, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "257_2": { - "frame": { "x": 0, "y": 81, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "257_3": { - "frame": { "x": 150, "y": 78, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "261_2": { - "frame": { "x": 17, "y": 232, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "261_3": { - "frame": { "x": 38, "y": 232, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "262_2": { - "frame": { "x": 48, "y": 149, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "262_3": { - "frame": { "x": 96, "y": 149, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "263_2": { - "frame": { "x": 123, "y": 243, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "263_3": { - "frame": { "x": 252, "y": 243, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "264_2": { - "frame": { "x": 115, "y": 193, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "264_3": { - "frame": { "x": 66, "y": 192, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "278_1": { - "frame": { "x": 275, "y": 78, "w": 26, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 14, "w": 26, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "278_2": { - "frame": { "x": 151, "y": 232, "w": 26, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 14, "w": 26, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "278_3": { - "frame": { "x": 97, "y": 233, "w": 26, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 14, "w": 26, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "279_1": { - "frame": { "x": 178, "y": 165, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "279_2": { - "frame": { "x": 144, "y": 166, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "279_3": { - "frame": { "x": 254, "y": 161, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "280_2": { - "frame": { "x": 122, "y": 275, "w": 14, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 14, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "280_3": { - "frame": { "x": 108, "y": 275, "w": 14, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 14, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "281_2": { - "frame": { "x": 159, "y": 209, "w": 18, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 18, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "281_3": { - "frame": { "x": 177, "y": 210, "w": 18, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 18, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "282-mega_2": { - "frame": { "x": 227, "y": 99, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "282-mega_3": { - "frame": { "x": 352, "y": 0, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "282_2": { - "frame": { "x": 201, "y": 98, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "282_3": { - "frame": { "x": 175, "y": 98, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "285_2": { - "frame": { "x": 15, "y": 271, "w": 18, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 13, "w": 18, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "285_3": { - "frame": { "x": 307, "y": 269, "w": 18, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 13, "w": 18, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "286_2": { - "frame": { "x": 220, "y": 123, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "286_3": { - "frame": { "x": 0, "y": 107, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "290_1": { - "frame": { "x": 291, "y": 249, "w": 23, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 14, "w": 23, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "290_2": { - "frame": { "x": 353, "y": 248, "w": 23, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 14, "w": 23, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "290_3": { - "frame": { "x": 97, "y": 247, "w": 23, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 14, "w": 23, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "291_1": { - "frame": { "x": 277, "y": 180, "w": 23, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 23, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "291_2": { - "frame": { "x": 245, "y": 182, "w": 23, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 23, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "291_3": { - "frame": { "x": 222, "y": 180, "w": 23, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 23, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "292_1": { - "frame": { "x": 357, "y": 229, "w": 20, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 20, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "292_2": { - "frame": { "x": 77, "y": 231, "w": 20, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 20, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "292_3": { - "frame": { "x": 296, "y": 230, "w": 20, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 20, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "298_2": { - "frame": { "x": 139, "y": 263, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "298_3": { - "frame": { "x": 277, "y": 263, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "300_1": { - "frame": { "x": 108, "y": 213, "w": 20, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 20, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "300_2": { - "frame": { "x": 17, "y": 212, "w": 20, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 20, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "300_3": { - "frame": { "x": 88, "y": 211, "w": 20, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 20, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "301_1": { - "frame": { "x": 115, "y": 172, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "301_2": { - "frame": { "x": 0, "y": 178, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "301_3": { - "frame": { "x": 93, "y": 170, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "302-mega_2": { - "frame": { "x": 274, "y": 51, "w": 28, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 28, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "302-mega_3": { - "frame": { "x": 150, "y": 51, "w": 28, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 28, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "302_2": { - "frame": { "x": 338, "y": 166, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "302_3": { - "frame": { "x": 315, "y": 166, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "303-mega_1": { - "frame": { "x": 26, "y": 51, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "303-mega_2": { - "frame": { "x": 56, "y": 51, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "303-mega_3": { - "frame": { "x": 342, "y": 50, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "303_1": { - "frame": { "x": 315, "y": 145, "w": 26, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 26, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "303_2": { - "frame": { "x": 341, "y": 145, "w": 26, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 26, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "303_3": { - "frame": { "x": 178, "y": 144, "w": 26, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 26, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "304_1": { - "frame": { "x": 196, "y": 275, "w": 16, "h": 12 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 16, "w": 16, "h": 12 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "304_2": { - "frame": { "x": 180, "y": 275, "w": 16, "h": 12 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 16, "w": 16, "h": 12 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "304_3": { - "frame": { "x": 252, "y": 202, "w": 16, "h": 12 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 16, "w": 16, "h": 12 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "305_1": { - "frame": { "x": 334, "y": 227, "w": 23, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 11, "w": 23, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "305_2": { - "frame": { "x": 128, "y": 226, "w": 23, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 11, "w": 23, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "305_3": { - "frame": { "x": 273, "y": 226, "w": 23, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 11, "w": 23, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "306-mega_1": { - "frame": { "x": 62, "y": 25, "w": 31, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 31, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "306-mega_2": { - "frame": { "x": 93, "y": 25, "w": 31, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 31, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "306-mega_3": { - "frame": { "x": 342, "y": 24, "w": 31, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 31, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "306_1": { - "frame": { "x": 55, "y": 77, "w": 29, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 4, "w": 29, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "306_2": { - "frame": { "x": 338, "y": 76, "w": 29, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 4, "w": 29, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "306_3": { - "frame": { "x": 26, "y": 77, "w": 29, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 4, "w": 29, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "307_2": { - "frame": { "x": 215, "y": 241, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "307_3": { - "frame": { "x": 274, "y": 243, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "308-mega_2": { - "frame": { "x": 190, "y": 48, "w": 29, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 29, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "308-mega_3": { - "frame": { "x": 219, "y": 48, "w": 29, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 29, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "308_2": { - "frame": { "x": 0, "y": 199, "w": 17, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 3, "w": 17, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "308_3": { - "frame": { "x": 235, "y": 202, "w": 17, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 3, "w": 17, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "309_2": { - "frame": { "x": 45, "y": 268, "w": 19, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 13, "w": 19, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "309_3": { - "frame": { "x": 253, "y": 99, "w": 19, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 13, "w": 19, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "310-mega_2": { - "frame": { "x": 25, "y": 101, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "310-mega_3": { - "frame": { "x": 338, "y": 100, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "310_2": { - "frame": { "x": 323, "y": 187, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "310_3": { - "frame": { "x": 167, "y": 186, "w": 20, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 20, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "311_1": { - "frame": { "x": 164, "y": 256, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "311_2": { - "frame": { "x": 77, "y": 250, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "311_3": { - "frame": { "x": 314, "y": 250, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "312_2": { - "frame": { "x": 196, "y": 256, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "312_3": { - "frame": { "x": 180, "y": 256, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "315_2": { - "frame": { "x": 153, "y": 144, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "315_3": { - "frame": { "x": 290, "y": 138, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "320_2": { - "frame": { "x": 211, "y": 200, "w": 24, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 10, "w": 24, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "320_3": { - "frame": { "x": 268, "y": 200, "w": 24, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 10, "w": 24, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "321_2": { - "frame": { "x": 84, "y": 98, "w": 30, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 30, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "321_3": { - "frame": { "x": 308, "y": 93, "w": 30, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 30, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "327_2": { - "frame": { "x": 364, "y": 100, "w": 15, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 15, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "327_3": { - "frame": { "x": 0, "y": 247, "w": 15, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 15, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "328_2": { - "frame": { "x": 177, "y": 237, "w": 19, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 19, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "328_3": { - "frame": { "x": 196, "y": 237, "w": 19, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 19, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "329_2": { - "frame": { "x": 229, "y": 160, "w": 25, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 25, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "329_3": { - "frame": { "x": 290, "y": 160, "w": 25, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 25, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "330_2": { - "frame": { "x": 51, "y": 101, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "330_3": { - "frame": { "x": 139, "y": 104, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "333_2": { - "frame": { "x": 45, "y": 252, "w": 19, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 19, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "333_3": { - "frame": { "x": 120, "y": 259, "w": 19, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 19, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "334-mega_2": { - "frame": { "x": 280, "y": 114, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "334-mega_3": { - "frame": { "x": 253, "y": 114, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "334_2": { - "frame": { "x": 73, "y": 168, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "334_3": { - "frame": { "x": 23, "y": 167, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "335_2": { - "frame": { "x": 0, "y": 156, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "335_3": { - "frame": { "x": 121, "y": 150, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "336_2": { - "frame": { "x": 137, "y": 187, "w": 23, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 23, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "336_3": { - "frame": { "x": 300, "y": 187, "w": 23, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 8, "w": 23, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "337_2": { - "frame": { "x": 277, "y": 161, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "337_3": { - "frame": { "x": 154, "y": 275, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "338_2": { - "frame": { "x": 43, "y": 170, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "338_3": { - "frame": { "x": 201, "y": 169, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "339_2": { - "frame": { "x": 226, "y": 268, "w": 21, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 14, "w": 21, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "339_3": { - "frame": { "x": 64, "y": 269, "w": 21, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 14, "w": 21, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "340_2": { - "frame": { "x": 187, "y": 191, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "340_3": { - "frame": { "x": 343, "y": 187, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "341_2": { - "frame": { "x": 252, "y": 218, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "341_3": { - "frame": { "x": 195, "y": 218, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "342_2": { - "frame": { "x": 129, "y": 127, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "342_3": { - "frame": { "x": 243, "y": 137, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-rainy_1": { - "frame": { "x": 330, "y": 261, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-rainy_2": { - "frame": { "x": 344, "y": 262, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-rainy_3": { - "frame": { "x": 212, "y": 261, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-snowy_1": { - "frame": { "x": 216, "y": 218, "w": 17, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 17, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-snowy_2": { - "frame": { "x": 363, "y": 206, "w": 17, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 17, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-snowy_3": { - "frame": { "x": 0, "y": 224, "w": 17, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 17, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-sunny_1": { - "frame": { "x": 59, "y": 232, "w": 18, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 18, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-sunny_2": { - "frame": { "x": 316, "y": 230, "w": 18, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 18, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351-sunny_3": { - "frame": { "x": 362, "y": 124, "w": 18, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 18, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351_2": { - "frame": { "x": 367, "y": 76, "w": 13, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 13, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "351_3": { - "frame": { "x": 367, "y": 144, "w": 13, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 13, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "352_1": { - "frame": { "x": 37, "y": 212, "w": 20, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 20, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "352_2": { - "frame": { "x": 57, "y": 212, "w": 20, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 20, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "352_3": { - "frame": { "x": 314, "y": 210, "w": 20, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 20, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "353_2": { - "frame": { "x": 262, "y": 263, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "353_3": { - "frame": { "x": 292, "y": 263, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "354-mega_2": { - "frame": { "x": 0, "y": 51, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "354-mega_3": { - "frame": { "x": 248, "y": 48, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "354_2": { - "frame": { "x": 137, "y": 207, "w": 22, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 22, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "354_3": { - "frame": { "x": 292, "y": 207, "w": 22, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 22, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "357_2": { - "frame": { "x": 31, "y": 25, "w": 31, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 31, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "357_3": { - "frame": { "x": 0, "y": 25, "w": 31, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 31, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "358_1": { - "frame": { "x": 232, "y": 247, "w": 15, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "358_2": { - "frame": { "x": 15, "y": 250, "w": 15, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "358_3": { - "frame": { "x": 30, "y": 250, "w": 15, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "361_2": { - "frame": { "x": 0, "y": 268, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "361_3": { - "frame": { "x": 358, "y": 262, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "362-mega_2": { - "frame": { "x": 0, "y": 132, "w": 23, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 23, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "362-mega_3": { - "frame": { "x": 267, "y": 137, "w": 23, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 23, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "362_2": { - "frame": { "x": 233, "y": 227, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "362_3": { - "frame": { "x": 361, "y": 166, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "369_2": { - "frame": { "x": 204, "y": 148, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "369_3": { - "frame": { "x": 23, "y": 146, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "371_2": { - "frame": { "x": 247, "y": 259, "w": 15, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "371_3": { - "frame": { "x": 93, "y": 261, "w": 15, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 15, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "372_2": { - "frame": { "x": 343, "y": 206, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "372_3": { - "frame": { "x": 190, "y": 27, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "373-mega_2": { - "frame": { "x": 111, "y": 0, "w": 35, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 3, "w": 35, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "373-mega_3": { - "frame": { "x": 76, "y": 0, "w": 35, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 2, "y": 3, "w": 35, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "373_2": { - "frame": { "x": 86, "y": 75, "w": 32, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 5, "w": 32, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "373_3": { - "frame": { "x": 118, "y": 75, "w": 32, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 5, "w": 32, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "374_2": { - "frame": { "x": 145, "y": 246, "w": 19, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "374_3": { - "frame": { "x": 334, "y": 244, "w": 19, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "375_2": { - "frame": { "x": 166, "y": 122, "w": 27, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 27, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "375_3": { - "frame": { "x": 193, "y": 122, "w": 27, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 27, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "376-mega_2": { - "frame": { "x": 118, "y": 51, "w": 32, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 5, "w": 32, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "376-mega_3": { - "frame": { "x": 86, "y": 51, "w": 32, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 5, "w": 32, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "376_2": { - "frame": { "x": 178, "y": 75, "w": 32, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 7, "w": 32, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "376_3": { - "frame": { "x": 210, "y": 75, "w": 32, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 7, "w": 32, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "380-mega_2": { - "frame": { "x": 282, "y": 0, "w": 35, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 35, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "380-mega_3": { - "frame": { "x": 317, "y": 0, "w": 35, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 35, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "380_2": { - "frame": { "x": 23, "y": 125, "w": 27, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "380_3": { - "frame": { "x": 335, "y": 124, "w": 27, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "381-mega_2": { - "frame": { "x": 210, "y": 24, "w": 35, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 35, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "381-mega_3": { - "frame": { "x": 245, "y": 24, "w": 35, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 35, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "381_2": { - "frame": { "x": 78, "y": 121, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "381_3": { - "frame": { "x": 307, "y": 116, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "382-primal_2": { - "frame": { "x": 302, "y": 72, "w": 36, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 8, "w": 36, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "382-primal_3": { - "frame": { "x": 302, "y": 51, "w": 36, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 8, "w": 36, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "382_2": { - "frame": { "x": 275, "y": 93, "w": 33, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 8, "w": 33, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "382_3": { - "frame": { "x": 242, "y": 78, "w": 33, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 8, "w": 33, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "383-primal_2": { - "frame": { "x": 246, "y": 0, "w": 36, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 36, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "383-primal_3": { - "frame": { "x": 210, "y": 0, "w": 36, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 4, "w": 36, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "383_2": { - "frame": { "x": 157, "y": 27, "w": 33, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 33, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "383_3": { - "frame": { "x": 124, "y": 27, "w": 33, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 4, "w": 33, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "384-mega_2": { - "frame": { "x": 38, "y": 0, "w": 38, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 3, "w": 38, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "384-mega_3": { - "frame": { "x": 0, "y": 0, "w": 38, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 3, "w": 38, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "384_2": { - "frame": { "x": 311, "y": 24, "w": 31, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 2, "w": 31, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "384_3": { - "frame": { "x": 280, "y": 24, "w": 31, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 2, "w": 31, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "385_1": { - "frame": { "x": 22, "y": 192, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "385_2": { - "frame": { "x": 93, "y": 191, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "385_3": { - "frame": { "x": 44, "y": 192, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "475-mega_3": { - "frame": { "x": 114, "y": 98, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "475_3": { - "frame": { "x": 74, "y": 143, "w": 22, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 22, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_3v.png", - "format": "RGBA8888", - "size": { "w": 380, "h": 294 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_3v.png", + "format": "RGBA8888", + "size": { + "w": 520, + "h": 520 + }, + "scale": 1, + "frames": [ + { + "filename": "255-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "255-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "255_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "255_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "256-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "256-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "256_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "256_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "257-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "257-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "257-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "257-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "257_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "257_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "261_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "261_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "262_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "262_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "263_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "263_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "264_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "264_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "276_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "276_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "277_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "277_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "278_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "278_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "278_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "279_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "279_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "279_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "280_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "280_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "281_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "281_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "282-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "282-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "282_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "282_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "285_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "285_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "286_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "286_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "290_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "290_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "290_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "291_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "291_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "291_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "292_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "292_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "292_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "298_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "298_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "300_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "300_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "300_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "301_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "301_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "301_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "302-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "302-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "302_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "302_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "303-mega_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "303-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "303-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "303_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "303_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "303_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "304_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "304_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "304_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "305_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "305_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "305_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "306-mega_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "306-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "306-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "306_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "306_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "306_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "307_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "307_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "308-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "308-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "308_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "308_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "309_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "309_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "310-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "310-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "310_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "310_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "311_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "311_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "311_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "312_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "312_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "315_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "315_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "320_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "320_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "321_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "321_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "327_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "327_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "328_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "328_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "329_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "329_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "330_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "330_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "333_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "333_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "334-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "334-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "334_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "334_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "335_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "335_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "336_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "336_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "337_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "337_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "338_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "338_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "339_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "339_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "340_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "340_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "341_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "341_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "342_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "342_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-rainy_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-rainy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-rainy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-snowy_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-snowy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-snowy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-sunny_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-sunny_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "351-sunny_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "351_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "351_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "352_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "352_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "352_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "353_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "353_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "354-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "354-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "354_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "354_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "357_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "357_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "358_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "358_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "358_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "359-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "359-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "359_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "359_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "361_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "361_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "362-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "362-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "362_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "362_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "369_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "369_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "370_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "370_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "371_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "371_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "372_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "372_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "373-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "373-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "373_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "373_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "374_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "374_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "375_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "375_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "376-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "376-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "376_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "376_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "377_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "377_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "378_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "378_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "378_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "379_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "379_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "380-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "380-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "380_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "380_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "381-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "381-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "381_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "381_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "382-primal_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "382-primal_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "382_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "382_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "383-primal_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "383-primal_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "383_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "383_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "384-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "384-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "384_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "384_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "385_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "385_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "385_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 480, + "w": 40, + "h": 30 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:673055e796ec5f9913fd1dd04284765c:1804ddee68059c3372bf99289c91dd89:039b026190bf1878996b3e03190bcdf3$" + } } diff --git a/public/images/pokemon_icons_3v.png b/public/images/pokemon_icons_3v.png index 51a1707ea35..6b699b3bfa9 100644 Binary files a/public/images/pokemon_icons_3v.png and b/public/images/pokemon_icons_3v.png differ diff --git a/public/images/pokemon_icons_4v.json b/public/images/pokemon_icons_4v.json index 9113fe89dc8..2f171915e01 100644 --- a/public/images/pokemon_icons_4v.json +++ b/public/images/pokemon_icons_4v.json @@ -1,1390 +1,4409 @@ -{ "frames": { - "387_2": { - "frame": { "x": 39, "y": 225, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "387_3": { - "frame": { "x": 148, "y": 225, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "388_2": { - "frame": { "x": 261, "y": 187, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "388_3": { - "frame": { "x": 64, "y": 190, "w": 22, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "389_2": { - "frame": { "x": 272, "y": 47, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "389_3": { - "frame": { "x": 244, "y": 47, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "393_2": { - "frame": { "x": 69, "y": 275, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "393_3": { - "frame": { "x": 285, "y": 275, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "394_2": { - "frame": { "x": 321, "y": 232, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "394_3": { - "frame": { "x": 0, "y": 244, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "395_2": { - "frame": { "x": 340, "y": 95, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "395_3": { - "frame": { "x": 24, "y": 98, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "399_2": { - "frame": { "x": 24, "y": 123, "w": 20, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "399_3": { - "frame": { "x": 108, "y": 267, "w": 20, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "400_2": { - "frame": { "x": 217, "y": 180, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "400_3": { - "frame": { "x": 239, "y": 180, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "401_2": { - "frame": { "x": 279, "y": 243, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "401_3": { - "frame": { "x": 201, "y": 243, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "402_2": { - "frame": { "x": 97, "y": 186, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "402_3": { - "frame": { "x": 289, "y": 182, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "406_2": { - "frame": { "x": 298, "y": 275, "w": 12, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 12, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "406_3": { - "frame": { "x": 184, "y": 225, "w": 12, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 12, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "407_2": { - "frame": { "x": 177, "y": 203, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "407_3": { - "frame": { "x": 86, "y": 210, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-plant_1": { - "frame": { "x": 338, "y": 232, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-plant_2": { - "frame": { "x": 184, "y": 243, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-plant_3": { - "frame": { "x": 99, "y": 242, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-sandy_1": { - "frame": { "x": 164, "y": 247, "w": 15, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 15, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-sandy_2": { - "frame": { "x": 76, "y": 252, "w": 15, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 15, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-sandy_3": { - "frame": { "x": 296, "y": 252, "w": 15, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 15, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-trash_1": { - "frame": { "x": 218, "y": 245, "w": 16, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 16, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-trash_2": { - "frame": { "x": 132, "y": 244, "w": 16, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 16, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "412-trash_3": { - "frame": { "x": 116, "y": 244, "w": 16, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 16, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-plant_1": { - "frame": { "x": 333, "y": 168, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-plant_2": { - "frame": { "x": 311, "y": 168, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-plant_3": { - "frame": { "x": 75, "y": 167, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-sandy_1": { - "frame": { "x": 0, "y": 117, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-sandy_2": { - "frame": { "x": 292, "y": 117, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-sandy_3": { - "frame": { "x": 316, "y": 117, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-trash_1": { - "frame": { "x": 125, "y": 157, "w": 23, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 23, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-trash_2": { - "frame": { "x": 319, "y": 145, "w": 23, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 23, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "413-trash_3": { - "frame": { "x": 266, "y": 142, "w": 23, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 23, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "414_2": { - "frame": { "x": 120, "y": 180, "w": 25, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 25, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "414_3": { - "frame": { "x": 145, "y": 180, "w": 25, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 25, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "418_2": { - "frame": { "x": 127, "y": 224, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "418_3": { - "frame": { "x": 0, "y": 224, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "419_2": { - "frame": { "x": 221, "y": 159, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "419_3": { - "frame": { "x": 50, "y": 158, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "422-east_1": { - "frame": { "x": 197, "y": 203, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "422-east_2": { - "frame": { "x": 302, "y": 232, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "422-east_3": { - "frame": { "x": 80, "y": 232, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "422-west_1": { - "frame": { "x": 36, "y": 265, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "422-west_2": { - "frame": { "x": 91, "y": 264, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "422-west_3": { - "frame": { "x": 253, "y": 264, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "423-east_1": { - "frame": { "x": 148, "y": 157, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "423-east_2": { - "frame": { "x": 266, "y": 165, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "423-east_3": { - "frame": { "x": 41, "y": 179, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "423-west_1": { - "frame": { "x": 97, "y": 164, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "423-west_2": { - "frame": { "x": 194, "y": 160, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "423-west_3": { - "frame": { "x": 171, "y": 160, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "424_2": { - "frame": { "x": 303, "y": 0, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "424_3": { - "frame": { "x": 274, "y": 0, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "425_2": { - "frame": { "x": 270, "y": 265, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "425_3": { - "frame": { "x": 234, "y": 265, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "426_2": { - "frame": { "x": 110, "y": 96, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "426_3": { - "frame": { "x": 268, "y": 96, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "427_2": { - "frame": { "x": 21, "y": 225, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "427_3": { - "frame": { "x": 166, "y": 225, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "428-mega_2": { - "frame": { "x": 95, "y": 0, "w": 33, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 5, "w": 33, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "428-mega_3": { - "frame": { "x": 62, "y": 0, "w": 33, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 5, "w": 33, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "428_2": { - "frame": { "x": 47, "y": 117, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "428_3": { - "frame": { "x": 73, "y": 117, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "429_1": { - "frame": { "x": 247, "y": 138, "w": 19, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 19, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "429_2": { - "frame": { "x": 0, "y": 140, "w": 19, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 19, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "429_3": { - "frame": { "x": 78, "y": 139, "w": 19, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 19, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "433_1": { - "frame": { "x": 328, "y": 213, "w": 23, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 23, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "433_2": { - "frame": { "x": 305, "y": 213, "w": 23, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 23, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "433_3": { - "frame": { "x": 61, "y": 211, "w": 23, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 23, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "436_2": { - "frame": { "x": 0, "y": 284, "w": 13, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 13, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "436_3": { - "frame": { "x": 108, "y": 283, "w": 13, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 13, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "437_2": { - "frame": { "x": 239, "y": 117, "w": 27, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "437_3": { - "frame": { "x": 212, "y": 117, "w": 27, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "438_2": { - "frame": { "x": 351, "y": 211, "w": 12, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 8, "w": 12, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "438_3": { - "frame": { "x": 351, "y": 191, "w": 12, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 8, "w": 12, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "440_1": { - "frame": { "x": 163, "y": 270, "w": 14, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 14, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "440_2": { - "frame": { "x": 343, "y": 271, "w": 14, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 14, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "440_3": { - "frame": { "x": 329, "y": 271, "w": 14, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 14, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "441_2": { - "frame": { "x": 157, "y": 203, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "441_3": { - "frame": { "x": 237, "y": 202, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "442_2": { - "frame": { "x": 106, "y": 222, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "442_3": { - "frame": { "x": 197, "y": 223, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "443_1": { - "frame": { "x": 256, "y": 245, "w": 19, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 19, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "443_2": { - "frame": { "x": 17, "y": 247, "w": 19, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 19, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "443_3": { - "frame": { "x": 234, "y": 246, "w": 19, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 19, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "444_1": { - "frame": { "x": 170, "y": 182, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "444_2": { - "frame": { "x": 0, "y": 183, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "444_3": { - "frame": { "x": 193, "y": 182, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "445-mega_1": { - "frame": { "x": 214, "y": 0, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "445-mega_2": { - "frame": { "x": 184, "y": 0, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "445-mega_3": { - "frame": { "x": 244, "y": 0, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "445_1": { - "frame": { "x": 207, "y": 48, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "445_2": { - "frame": { "x": 87, "y": 49, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "445_3": { - "frame": { "x": 331, "y": 49, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "447_1": { - "frame": { "x": 23, "y": 183, "w": 18, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 18, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "447_2": { - "frame": { "x": 0, "y": 266, "w": 18, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 18, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "447_3": { - "frame": { "x": 18, "y": 266, "w": 18, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 18, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "448-mega_1": { - "frame": { "x": 138, "y": 200, "w": 19, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 4, "w": 19, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "448-mega_2": { - "frame": { "x": 42, "y": 201, "w": 19, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 4, "w": 19, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "448-mega_3": { - "frame": { "x": 23, "y": 201, "w": 19, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 4, "w": 19, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "448_1": { - "frame": { "x": 195, "y": 265, "w": 16, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 16, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "448_2": { - "frame": { "x": 179, "y": 265, "w": 16, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 16, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "448_3": { - "frame": { "x": 53, "y": 265, "w": 16, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 16, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "453_2": { - "frame": { "x": 128, "y": 267, "w": 17, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 17, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "453_3": { - "frame": { "x": 211, "y": 268, "w": 17, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 17, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "454_2": { - "frame": { "x": 330, "y": 191, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "454_3": { - "frame": { "x": 342, "y": 145, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "456_2": { - "frame": { "x": 56, "y": 247, "w": 20, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 20, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "456_3": { - "frame": { "x": 36, "y": 247, "w": 20, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 20, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "457_2": { - "frame": { "x": 19, "y": 160, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "457_3": { - "frame": { "x": 289, "y": 159, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "458_2": { - "frame": { "x": 311, "y": 254, "w": 20, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 20, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "458_3": { - "frame": { "x": 331, "y": 254, "w": 20, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 20, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "461_2": { - "frame": { "x": 218, "y": 223, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "461_3": { - "frame": { "x": 237, "y": 224, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "462_2": { - "frame": { "x": 58, "y": 70, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "462_3": { - "frame": { "x": 329, "y": 71, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "464_2": { - "frame": { "x": 83, "y": 95, "w": 27, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "464_3": { - "frame": { "x": 313, "y": 95, "w": 27, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "465_2": { - "frame": { "x": 145, "y": 53, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "465_3": { - "frame": { "x": 300, "y": 51, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "466_1": { - "frame": { "x": 216, "y": 94, "w": 26, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 26, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "466_2": { - "frame": { "x": 242, "y": 94, "w": 26, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 26, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "466_3": { - "frame": { "x": 57, "y": 94, "w": 26, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 26, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "467_2": { - "frame": { "x": 171, "y": 138, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "467_3": { - "frame": { "x": 121, "y": 120, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "468_1": { - "frame": { "x": 97, "y": 145, "w": 28, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 28, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "468_2": { - "frame": { "x": 291, "y": 140, "w": 28, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 28, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "468_3": { - "frame": { "x": 50, "y": 139, "w": 28, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 28, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "469_2": { - "frame": { "x": 204, "y": 70, "w": 30, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 30, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "469_3": { - "frame": { "x": 174, "y": 70, "w": 30, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 30, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "470_1": { - "frame": { "x": 266, "y": 120, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "470_2": { - "frame": { "x": 146, "y": 135, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "470_3": { - "frame": { "x": 196, "y": 138, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "471_1": { - "frame": { "x": 110, "y": 73, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "471_2": { - "frame": { "x": 286, "y": 73, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "471_3": { - "frame": { "x": 137, "y": 75, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "472_2": { - "frame": { "x": 275, "y": 25, "w": 31, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 6, "w": 31, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "472_3": { - "frame": { "x": 244, "y": 25, "w": 31, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 6, "w": 31, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "474_2": { - "frame": { "x": 292, "y": 96, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "474_3": { - "frame": { "x": 216, "y": 202, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "475-mega_2": { - "frame": { "x": 120, "y": 47, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "475-mega_3": { - "frame": { "x": 33, "y": 28, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "475_2": { - "frame": { "x": 99, "y": 120, "w": 22, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 22, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "475_3": { - "frame": { "x": 340, "y": 120, "w": 22, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 22, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "478_2": { - "frame": { "x": 148, "y": 247, "w": 16, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 16, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "478_3": { - "frame": { "x": 313, "y": 73, "w": 16, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 16, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-fan_2": { - "frame": { "x": 221, "y": 138, "w": 26, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 26, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-fan_3": { - "frame": { "x": 24, "y": 139, "w": 26, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 26, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-frost_2": { - "frame": { "x": 214, "y": 25, "w": 30, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 30, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-frost_3": { - "frame": { "x": 184, "y": 25, "w": 30, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 30, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-heat_2": { - "frame": { "x": 58, "y": 48, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-heat_3": { - "frame": { "x": 0, "y": 70, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-mow_2": { - "frame": { "x": 192, "y": 91, "w": 24, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-mow_3": { - "frame": { "x": 0, "y": 92, "w": 24, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-wash_2": { - "frame": { "x": 164, "y": 91, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479-wash_3": { - "frame": { "x": 29, "y": 76, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479_2": { - "frame": { "x": 156, "y": 0, "w": 28, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 28, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "479_3": { - "frame": { "x": 128, "y": 0, "w": 28, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 28, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "480_1": { - "frame": { "x": 186, "y": 116, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "480_2": { - "frame": { "x": 160, "y": 113, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "480_3": { - "frame": { "x": 134, "y": 98, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "481_1": { - "frame": { "x": 178, "y": 48, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "481_2": { - "frame": { "x": 0, "y": 48, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "481_3": { - "frame": { "x": 29, "y": 54, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "482_1": { - "frame": { "x": 84, "y": 71, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "482_2": { - "frame": { "x": 260, "y": 70, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "482_3": { - "frame": { "x": 234, "y": 70, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "485_2": { - "frame": { "x": 0, "y": 28, "w": 33, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 8, "w": 33, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "485_3": { - "frame": { "x": 120, "y": 27, "w": 33, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 8, "w": 33, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "487-altered_2": { - "frame": { "x": 332, "y": 0, "w": 30, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 4, "w": 30, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "487-altered_3": { - "frame": { "x": 62, "y": 24, "w": 30, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 4, "w": 30, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "487-origin_2": { - "frame": { "x": 92, "y": 24, "w": 28, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 28, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "487-origin_3": { - "frame": { "x": 332, "y": 24, "w": 28, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 28, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "488_2": { - "frame": { "x": 153, "y": 27, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "488_3": { - "frame": { "x": 306, "y": 25, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "489_1": { - "frame": { "x": 57, "y": 230, "w": 23, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 11, "w": 23, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "489_2": { - "frame": { "x": 279, "y": 226, "w": 23, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 11, "w": 23, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "489_3": { - "frame": { "x": 256, "y": 228, "w": 23, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 11, "w": 23, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "490_1": { - "frame": { "x": 257, "y": 208, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "490_2": { - "frame": { "x": 283, "y": 206, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "490_3": { - "frame": { "x": 0, "y": 204, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "491_2": { - "frame": { "x": 0, "y": 0, "w": 31, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 31, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "491_3": { - "frame": { "x": 31, "y": 0, "w": 31, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 31, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "492-land_2": { - "frame": { "x": 145, "y": 269, "w": 18, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 18, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "492-land_3": { - "frame": { "x": 311, "y": 271, "w": 18, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 18, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "492-sky_2": { - "frame": { "x": 117, "y": 200, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "492-sky_3": { - "frame": { "x": 309, "y": 191, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_4v.png", - "format": "RGBA8888", - "size": { "w": 363, "h": 300 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_4v.png", + "format": "RGBA8888", + "size": { + "w": 520, + "h": 520 + }, + "scale": 1, + "frames": [ + { + "filename": "387_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "387_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "388_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "388_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "389_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "389_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "390_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "390_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "391_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "391_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "392_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "392_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "393_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "393_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "394_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "394_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "395_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "395_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "399_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "399_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "400_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "400_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "401_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "401_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "402_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "402_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "406_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "406_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "407_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "407_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-plant_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-plant_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-plant_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-sandy_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-sandy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-sandy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-trash_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-trash_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "412-trash_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-plant_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-plant_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-plant_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-sandy_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-sandy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-sandy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-trash_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-trash_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "413-trash_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "414_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "414_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "418_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "418_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "419_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "419_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "422-east_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "422-east_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "422-east_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "422-west_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "422-west_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "422-west_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "423-east_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "423-east_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "423-east_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "423-west_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "423-west_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "423-west_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "424_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "424_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "425_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "425_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "426_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "426_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "427_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "427_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "428-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "428-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "428_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "428_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "429_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "429_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "429_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "430_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "430_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "433_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "433_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "433_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "436_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "436_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "437_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "437_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "438_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "438_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "440_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "440_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "440_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "441_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "441_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "442_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "442_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "443_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "443_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "443_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "444_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "444_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "444_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "445-mega_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "445-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "445-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "445_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "445_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "445_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "447_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "447_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "447_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "448-mega_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "448-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "448-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "448_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "448_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "448_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "453_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "453_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "454_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "454_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "455_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "455_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "456_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "456_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "457_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "457_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "458_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "458_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "461_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "461_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "462_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "462_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "464_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "464_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "465_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "465_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "466_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "466_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "466_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "467_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "467_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "468_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "468_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "468_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "469_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "469_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "470_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "470_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "470_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "471_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "471_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "471_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "472_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "472_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "474_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "474_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "475-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "475-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "475_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "475_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "478_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "478_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-fan_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-fan_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-frost_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-frost_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-heat_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-heat_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-mow_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-mow_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-wash_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "479-wash_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "479_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "479_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "480_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "480_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "480_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "481_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "481_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "481_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "482_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "482_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "482_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "485_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "485_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "486_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "486_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "487-altered_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "487-altered_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "487-origin_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "487-origin_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "488_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "488_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "489_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "489_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "489_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "490_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "490_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "490_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "491_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "491_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "492-land_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "492-land_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "492-sky_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "492-sky_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 480, + "w": 40, + "h": 30 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:2288ca6bd49f36a5ca5b49f1bcaab17a:e83f40529aad7883718910695eafd075:ebc3f8ec5b2480b298192d752b6e57dc$" + } } diff --git a/public/images/pokemon_icons_4v.png b/public/images/pokemon_icons_4v.png index 4dbf5cc6918..7cfab80312a 100644 Binary files a/public/images/pokemon_icons_4v.png and b/public/images/pokemon_icons_4v.png differ diff --git a/public/images/pokemon_icons_5v.json b/public/images/pokemon_icons_5v.json index ef3ce80e8ef..7da5a765c0c 100644 --- a/public/images/pokemon_icons_5v.json +++ b/public/images/pokemon_icons_5v.json @@ -1,1341 +1,4640 @@ -{ "frames": { - "494_2": { - "frame": { "x": 251, "y": 190, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "494_3": { - "frame": { "x": 212, "y": 186, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "495_2": { - "frame": { "x": 192, "y": 225, "w": 20, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 20, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "495_3": { - "frame": { "x": 103, "y": 224, "w": 20, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 20, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "496_2": { - "frame": { "x": 138, "y": 180, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "496_3": { - "frame": { "x": 95, "y": 183, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "497_2": { - "frame": { "x": 28, "y": 94, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "497_3": { - "frame": { "x": 242, "y": 74, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "517_2": { - "frame": { "x": 92, "y": 260, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "517_3": { - "frame": { "x": 62, "y": 260, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "518_2": { - "frame": { "x": 288, "y": 149, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "518_3": { - "frame": { "x": 0, "y": 164, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "524_2": { - "frame": { "x": 88, "y": 140, "w": 11, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 11, "w": 11, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "524_3": { - "frame": { "x": 99, "y": 118, "w": 11, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 15, "y": 11, "w": 11, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "525_2": { - "frame": { "x": 47, "y": 164, "w": 24, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 24, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "525_3": { - "frame": { "x": 23, "y": 164, "w": 24, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 24, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "526_2": { - "frame": { "x": 95, "y": 26, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "526_3": { - "frame": { "x": 157, "y": 26, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "529_2": { - "frame": { "x": 202, "y": 208, "w": 21, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 11, "w": 21, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "529_3": { - "frame": { "x": 269, "y": 209, "w": 21, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 11, "w": 21, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "530_2": { - "frame": { "x": 183, "y": 71, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "530_3": { - "frame": { "x": 0, "y": 51, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "531-mega_2": { - "frame": { "x": 292, "y": 97, "w": 22, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 22, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "531-mega_3": { - "frame": { "x": 270, "y": 74, "w": 22, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 22, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "531_2": { - "frame": { "x": 311, "y": 169, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "531_3": { - "frame": { "x": 263, "y": 168, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "532_2": { - "frame": { "x": 71, "y": 179, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 9, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "532_3": { - "frame": { "x": 60, "y": 75, "w": 24, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 9, "w": 24, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "533_2": { - "frame": { "x": 242, "y": 50, "w": 27, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 27, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "533_3": { - "frame": { "x": 269, "y": 50, "w": 27, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 27, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "534_2": { - "frame": { "x": 249, "y": 0, "w": 31, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 5, "w": 31, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "534_3": { - "frame": { "x": 218, "y": 0, "w": 31, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 5, "w": 31, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "538_2": { - "frame": { "x": 166, "y": 115, "w": 28, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 8, "w": 28, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "538_3": { - "frame": { "x": 0, "y": 116, "w": 28, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 8, "w": 28, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "539_2": { - "frame": { "x": 169, "y": 165, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "539_3": { - "frame": { "x": 208, "y": 164, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "540_2": { - "frame": { "x": 16, "y": 248, "w": 15, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 11, "w": 15, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "540_3": { - "frame": { "x": 297, "y": 245, "w": 15, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 11, "w": 15, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "541_2": { - "frame": { "x": 288, "y": 229, "w": 20, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "541_3": { - "frame": { "x": 57, "y": 230, "w": 20, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "542_2": { - "frame": { "x": 195, "y": 242, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "542_3": { - "frame": { "x": 181, "y": 242, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "543_2": { - "frame": { "x": 312, "y": 249, "w": 18, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 14, "w": 18, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "543_3": { - "frame": { "x": 241, "y": 249, "w": 18, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 14, "w": 18, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "544_2": { - "frame": { "x": 223, "y": 213, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "544_3": { - "frame": { "x": 245, "y": 213, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "545_2": { - "frame": { "x": 154, "y": 51, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "545_3": { - "frame": { "x": 115, "y": 71, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "546_2": { - "frame": { "x": 160, "y": 242, "w": 21, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 14, "w": 21, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "546_3": { - "frame": { "x": 139, "y": 242, "w": 21, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 14, "w": 21, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "547_2": { - "frame": { "x": 230, "y": 171, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "547_3": { - "frame": { "x": 285, "y": 171, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "548_1": { - "frame": { "x": 251, "y": 171, "w": 12, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 12, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "548_2": { - "frame": { "x": 340, "y": 97, "w": 12, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 12, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "548_3": { - "frame": { "x": 228, "y": 97, "w": 12, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 12, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "549_2": { - "frame": { "x": 191, "y": 165, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "549_3": { - "frame": { "x": 335, "y": 119, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "551_2": { - "frame": { "x": 324, "y": 211, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 13, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "551_3": { - "frame": { "x": 62, "y": 214, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 13, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "552_2": { - "frame": { "x": 88, "y": 158, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "552_3": { - "frame": { "x": 144, "y": 159, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "553_2": { - "frame": { "x": 324, "y": 50, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "553_3": { - "frame": { "x": 296, "y": 50, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "556_2": { - "frame": { "x": 99, "y": 135, "w": 23, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 23, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "556_3": { - "frame": { "x": 253, "y": 124, "w": 23, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 23, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "559_1": { - "frame": { "x": 166, "y": 256, "w": 15, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 15, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "559_2": { - "frame": { "x": 136, "y": 256, "w": 15, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 15, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "559_3": { - "frame": { "x": 151, "y": 256, "w": 15, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 12, "w": 15, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "560_1": { - "frame": { "x": 144, "y": 138, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "560_2": { - "frame": { "x": 117, "y": 183, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "560_3": { - "frame": { "x": 23, "y": 185, "w": 20, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 20, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "562_2": { - "frame": { "x": 127, "y": 220, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "562_3": { - "frame": { "x": 290, "y": 213, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "563_2": { - "frame": { "x": 218, "y": 25, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "563_3": { - "frame": { "x": 307, "y": 0, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 3, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "568_2": { - "frame": { "x": 181, "y": 205, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "568_3": { - "frame": { "x": 0, "y": 205, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "569-gigantamax_2": { - "frame": { "x": 32, "y": 0, "w": 32, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "569-gigantamax_3": { - "frame": { "x": 0, "y": 0, "w": 32, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "569_2": { - "frame": { "x": 277, "y": 28, "w": 30, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 30, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "569_3": { - "frame": { "x": 0, "y": 29, "w": 30, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 30, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "570_2": { - "frame": { "x": 209, "y": 247, "w": 16, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 16, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "570_3": { - "frame": { "x": 225, "y": 247, "w": 16, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 16, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "571_2": { - "frame": { "x": 86, "y": 51, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "571_3": { - "frame": { "x": 29, "y": 51, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "572_2": { - "frame": { "x": 43, "y": 185, "w": 22, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 22, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "572_3": { - "frame": { "x": 0, "y": 186, "w": 22, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 22, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "577_1": { - "frame": { "x": 47, "y": 260, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "577_2": { - "frame": { "x": 71, "y": 164, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "577_3": { - "frame": { "x": 77, "y": 260, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "578_1": { - "frame": { "x": 0, "y": 241, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "578_2": { - "frame": { "x": 93, "y": 241, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "578_3": { - "frame": { "x": 77, "y": 241, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "579_1": { - "frame": { "x": 0, "y": 73, "w": 30, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 7, "w": 30, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "579_2": { - "frame": { "x": 30, "y": 73, "w": 30, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 7, "w": 30, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "579_3": { - "frame": { "x": 144, "y": 73, "w": 30, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 7, "w": 30, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "585-autumn_1": { - "frame": { "x": 333, "y": 145, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "585-spring_1": { - "frame": { "x": 333, "y": 167, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "585-summer_1": { - "frame": { "x": 333, "y": 189, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "585-winter_1": { - "frame": { "x": 306, "y": 191, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "586-autumn_1": { - "frame": { "x": 86, "y": 73, "w": 25, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 25, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "586-spring_1": { - "frame": { "x": 51, "y": 116, "w": 23, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 23, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "586-summer_1": { - "frame": { "x": 28, "y": 116, "w": 23, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 23, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "586-winter_1": { - "frame": { "x": 267, "y": 100, "w": 23, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 23, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "592-f_1": { - "frame": { "x": 89, "y": 203, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "592-f_2": { - "frame": { "x": 43, "y": 204, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "592-f_3": { - "frame": { "x": 108, "y": 204, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "592_2": { - "frame": { "x": 137, "y": 200, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "592_3": { - "frame": { "x": 230, "y": 193, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "593-f_1": { - "frame": { "x": 56, "y": 94, "w": 27, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "593-f_2": { - "frame": { "x": 139, "y": 94, "w": 27, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "593-f_3": { - "frame": { "x": 240, "y": 96, "w": 27, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 27, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "593_2": { - "frame": { "x": 0, "y": 94, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "593_3": { - "frame": { "x": 212, "y": 75, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "594_2": { - "frame": { "x": 264, "y": 242, "w": 13, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 6, "w": 13, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "594_3": { - "frame": { "x": 34, "y": 243, "w": 13, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 6, "w": 13, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "595_2": { - "frame": { "x": 149, "y": 226, "w": 21, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 21, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "595_3": { - "frame": { "x": 267, "y": 226, "w": 21, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 21, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "596_2": { - "frame": { "x": 174, "y": 93, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "596_3": { - "frame": { "x": 111, "y": 93, "w": 28, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 28, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "602_2": { - "frame": { "x": 107, "y": 262, "w": 14, "h": 11 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 17, "w": 14, "h": 11 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "602_3": { - "frame": { "x": 290, "y": 262, "w": 14, "h": 11 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 17, "w": 14, "h": 11 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "603_2": { - "frame": { "x": 191, "y": 186, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "603_3": { - "frame": { "x": 160, "y": 187, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "604_2": { - "frame": { "x": 186, "y": 49, "w": 30, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 7, "w": 30, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "604_3": { - "frame": { "x": 124, "y": 49, "w": 30, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 7, "w": 30, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "605_1": { - "frame": { "x": 123, "y": 256, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "605_2": { - "frame": { "x": 330, "y": 249, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "605_3": { - "frame": { "x": 293, "y": 193, "w": 13, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 13, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "606_1": { - "frame": { "x": 19, "y": 226, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "606_2": { - "frame": { "x": 312, "y": 227, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "606_3": { - "frame": { "x": 327, "y": 227, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "607_2": { - "frame": { "x": 0, "y": 260, "w": 13, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 13, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "607_3": { - "frame": { "x": 277, "y": 259, "w": 13, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 10, "w": 13, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "608_2": { - "frame": { "x": 0, "y": 223, "w": 19, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "608_3": { - "frame": { "x": 84, "y": 223, "w": 19, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 19, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "609_2": { - "frame": { "x": 64, "y": 27, "w": 29, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 29, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "609_3": { - "frame": { "x": 186, "y": 26, "w": 29, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 29, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "610_2": { - "frame": { "x": 21, "y": 206, "w": 18, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 18, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "610_3": { - "frame": { "x": 156, "y": 206, "w": 18, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 18, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "611_2": { - "frame": { "x": 113, "y": 162, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "611_3": { - "frame": { "x": 263, "y": 147, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "612_2": { - "frame": { "x": 322, "y": 73, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "612_3": { - "frame": { "x": 296, "y": 73, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "618_2": { - "frame": { "x": 277, "y": 245, "w": 20, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 14, "w": 20, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "618_3": { - "frame": { "x": 47, "y": 246, "w": 20, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 14, "w": 20, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "619_2": { - "frame": { "x": 39, "y": 224, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "619_3": { - "frame": { "x": 174, "y": 223, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "620_2": { - "frame": { "x": 228, "y": 118, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "620_3": { - "frame": { "x": 74, "y": 118, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "622_2": { - "frame": { "x": 212, "y": 229, "w": 18, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 18, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "622_3": { - "frame": { "x": 230, "y": 229, "w": 18, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 18, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "623_2": { - "frame": { "x": 60, "y": 50, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "623_3": { - "frame": { "x": 216, "y": 50, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "631_2": { - "frame": { "x": 83, "y": 98, "w": 28, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 8, "w": 28, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "631_3": { - "frame": { "x": 111, "y": 115, "w": 28, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 8, "w": 28, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "632_2": { - "frame": { "x": 65, "y": 198, "w": 24, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 12, "w": 24, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "632_3": { - "frame": { "x": 269, "y": 193, "w": 24, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 12, "w": 24, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "633_2": { - "frame": { "x": 248, "y": 229, "w": 16, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 16, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "633_3": { - "frame": { "x": 123, "y": 236, "w": 16, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 16, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "634_2": { - "frame": { "x": 202, "y": 97, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "634_3": { - "frame": { "x": 314, "y": 97, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "635_2": { - "frame": { "x": 307, "y": 25, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "635_3": { - "frame": { "x": 248, "y": 25, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "640_2": { - "frame": { "x": 290, "y": 123, "w": 21, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 21, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "640_3": { - "frame": { "x": 314, "y": 119, "w": 21, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 21, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "641-incarnate_1": { - "frame": { "x": 188, "y": 0, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 2, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "641-therian_1": { - "frame": { "x": 127, "y": 0, "w": 30, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 1, "w": 30, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "642-incarnate_1": { - "frame": { "x": 64, "y": 0, "w": 31, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "642-therian_1": { - "frame": { "x": 95, "y": 0, "w": 32, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 3, "w": 32, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "645-incarnate_1": { - "frame": { "x": 157, "y": 0, "w": 31, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 2, "w": 31, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "645-therian_1": { - "frame": { "x": 280, "y": 0, "w": 27, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 27, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "647-ordinary_2": { - "frame": { "x": 194, "y": 119, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "647-ordinary_3": { - "frame": { "x": 139, "y": 116, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "647-resolute_2": { - "frame": { "x": 124, "y": 27, "w": 30, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 30, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "647-resolute_3": { - "frame": { "x": 30, "y": 29, "w": 30, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 30, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "648-aria_2": { - "frame": { "x": 109, "y": 241, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "648-aria_3": { - "frame": { "x": 276, "y": 124, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "648-pirouette_2": { - "frame": { "x": 337, "y": 23, "w": 15, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 15, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "648-pirouette_3": { - "frame": { "x": 337, "y": 0, "w": 15, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 15, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649-burn_2": { - "frame": { "x": 22, "y": 140, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649-burn_3": { - "frame": { "x": 122, "y": 138, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649-chill_2": { - "frame": { "x": 0, "y": 136, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649-chill_3": { - "frame": { "x": 164, "y": 135, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649-douse_2": { - "frame": { "x": 241, "y": 147, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649-douse_3": { - "frame": { "x": 311, "y": 145, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649-shock_2": { - "frame": { "x": 186, "y": 141, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649-shock_3": { - "frame": { "x": 219, "y": 140, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649_2": { - "frame": { "x": 66, "y": 140, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "649_3": { - "frame": { "x": 44, "y": 140, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_5v.png", - "format": "RGBA8888", - "size": { "w": 352, "h": 278 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_5v.png", + "format": "RGBA8888", + "size": { + "w": 520, + "h": 520 + }, + "scale": 1, + "frames": [ + { + "filename": "494_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "494_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "495_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "495_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "496_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "496_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "497_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "497_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "501_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "501_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "502_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "502_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "503_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "503_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "517_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "517_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "518_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "518_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "524_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "524_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "525_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "525_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "526_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "526_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "527_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "527_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "528_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "528_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "529_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "529_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "530_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "530_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "531-mega_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "531-mega_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "531_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "531_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "532_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "532_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "533_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "533_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "534_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "534_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "538_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "538_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "539_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "539_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "540_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "540_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "541_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "541_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "542_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "542_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "543_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "543_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "544_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "544_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "545_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "545_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "546_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "546_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "547_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "547_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "548_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "548_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "548_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "549_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "549_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "551_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "551_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "552_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "552_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "553_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "553_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "556_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "556_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "559_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "559_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "559_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "560_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "560_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "560_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "562_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "562_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "563_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "563_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "568_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "568_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "569-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "569-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "569_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "569_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "570_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "570_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "571_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "571_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "572_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "572_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "577_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "577_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "577_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "578_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "578_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "578_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "579_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "579_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "579_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "585-autumn_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "585-spring_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "585-summer_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "585-winter_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "586-autumn_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "586-spring_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "586-summer_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "586-winter_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "587_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "587_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "588_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "588_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "589_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "589_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "590_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "590_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "591_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "591_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "592-f_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "592-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "592-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "592_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "592_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "593-f_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "593-f_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "593-f_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "593_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "593_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "594_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "594_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "595_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "595_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "596_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "596_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "602_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "602_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "603_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "603_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "604_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "604_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "605_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "605_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "605_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "606_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "606_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "606_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "607_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "607_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "608_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "608_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "609_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "609_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "610_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "610_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "611_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "611_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "612_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "612_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "616_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "616_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "617_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "617_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "618_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "618_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "619_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "619_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "620_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "620_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "621_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "621_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "622_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "622_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "623_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "623_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "631_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "631_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "632_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "632_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "633_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "633_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "634_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "634_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "635_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "635_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "636_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "636_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "637_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "637_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "640_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "640_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "641-incarnate_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "641-therian_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "642-incarnate_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "642-therian_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "645-incarnate_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "645-therian_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "647-ordinary_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "647-ordinary_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "647-resolute_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "647-resolute_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "648-aria_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "648-aria_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "648-pirouette_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "648-pirouette_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649-burn_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649-burn_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649-chill_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649-chill_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649-douse_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649-douse_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649-shock_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649-shock_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "649_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 480, + "w": 40, + "h": 30 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:b615ea9a62bec26b97d0171030d11a55:35fd8571f91311ef2e9944578f979466:f1931bc28ee7f32dba7543723757cf2a$" + } } diff --git a/public/images/pokemon_icons_5v.png b/public/images/pokemon_icons_5v.png index 917e0621263..9dd1b278ac1 100644 Binary files a/public/images/pokemon_icons_5v.png and b/public/images/pokemon_icons_5v.png differ diff --git a/public/images/pokemon_icons_6v.json b/public/images/pokemon_icons_6v.json index 600624ca730..8061ed9152b 100644 --- a/public/images/pokemon_icons_6v.json +++ b/public/images/pokemon_icons_6v.json @@ -1,1026 +1,3905 @@ -{ "frames": { - "2670_2": { - "frame": { "x": 119, "y": 159, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2670_3": { - "frame": { "x": 175, "y": 157, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "653_2": { - "frame": { "x": 142, "y": 204, "w": 17, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 17, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "653_3": { - "frame": { "x": 304, "y": 210, "w": 17, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 17, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "654_2": { - "frame": { "x": 322, "y": 22, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "654_3": { - "frame": { "x": 322, "y": 0, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "655_2": { - "frame": { "x": 287, "y": 145, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "655_3": { - "frame": { "x": 260, "y": 145, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "664_2": { - "frame": { "x": 38, "y": 214, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "664_3": { - "frame": { "x": 159, "y": 204, "w": 14, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 14, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "665_2": { - "frame": { "x": 173, "y": 217, "w": 16, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 16, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "665_3": { - "frame": { "x": 52, "y": 218, "w": 16, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 16, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-archipelago_2": { - "frame": { "x": 78, "y": 105, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-archipelago_3": { - "frame": { "x": 130, "y": 107, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-continental_2": { - "frame": { "x": 156, "y": 107, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-continental_3": { - "frame": { "x": 182, "y": 107, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-elegant_2": { - "frame": { "x": 260, "y": 120, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-elegant_3": { - "frame": { "x": 286, "y": 120, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-fancy_2": { - "frame": { "x": 52, "y": 105, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-fancy_3": { - "frame": { "x": 208, "y": 126, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-garden_2": { - "frame": { "x": 156, "y": 82, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-garden_3": { - "frame": { "x": 234, "y": 126, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-high-plains_2": { - "frame": { "x": 0, "y": 130, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-high-plains_3": { - "frame": { "x": 26, "y": 130, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-icy-snow_2": { - "frame": { "x": 0, "y": 55, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-icy-snow_3": { - "frame": { "x": 26, "y": 55, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-jungle_2": { - "frame": { "x": 52, "y": 55, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-jungle_3": { - "frame": { "x": 78, "y": 55, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-marine_2": { - "frame": { "x": 104, "y": 57, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-marine_3": { - "frame": { "x": 130, "y": 57, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-meadow_2": { - "frame": { "x": 156, "y": 57, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-meadow_3": { - "frame": { "x": 182, "y": 57, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-modern_2": { - "frame": { "x": 268, "y": 70, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-modern_3": { - "frame": { "x": 294, "y": 70, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-monsoon_2": { - "frame": { "x": 208, "y": 76, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-monsoon_3": { - "frame": { "x": 234, "y": 76, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-ocean_2": { - "frame": { "x": 312, "y": 120, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-ocean_3": { - "frame": { "x": 0, "y": 80, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-poke-ball_2": { - "frame": { "x": 26, "y": 80, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-poke-ball_3": { - "frame": { "x": 52, "y": 80, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-polar_2": { - "frame": { "x": 78, "y": 80, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-polar_3": { - "frame": { "x": 104, "y": 82, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-river_2": { - "frame": { "x": 130, "y": 82, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-river_3": { - "frame": { "x": 104, "y": 107, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-sandstorm_2": { - "frame": { "x": 182, "y": 82, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-sandstorm_3": { - "frame": { "x": 260, "y": 95, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-savanna_2": { - "frame": { "x": 286, "y": 95, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-savanna_3": { - "frame": { "x": 312, "y": 95, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-sun_2": { - "frame": { "x": 208, "y": 101, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-sun_3": { - "frame": { "x": 234, "y": 101, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-tundra_2": { - "frame": { "x": 0, "y": 105, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "666-tundra_3": { - "frame": { "x": 26, "y": 105, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-blue_2": { - "frame": { "x": 0, "y": 220, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-blue_3": { - "frame": { "x": 142, "y": 223, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-orange_2": { - "frame": { "x": 83, "y": 223, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-orange_3": { - "frame": { "x": 113, "y": 224, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-red_2": { - "frame": { "x": 157, "y": 225, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-red_3": { - "frame": { "x": 229, "y": 229, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-white_2": { - "frame": { "x": 296, "y": 229, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-white_3": { - "frame": { "x": 189, "y": 218, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-yellow_2": { - "frame": { "x": 98, "y": 219, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "669-yellow_3": { - "frame": { "x": 68, "y": 223, "w": 15, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 10, "w": 15, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-blue_2": { - "frame": { "x": 175, "y": 178, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-blue_3": { - "frame": { "x": 138, "y": 180, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-orage_2": { - "frame": { "x": 86, "y": 182, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-orage_3": { - "frame": { "x": 268, "y": 190, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-red_2": { - "frame": { "x": 67, "y": 179, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-red_3": { - "frame": { "x": 119, "y": 180, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-white_2": { - "frame": { "x": 249, "y": 190, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-white_3": { - "frame": { "x": 198, "y": 175, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-yellow_2": { - "frame": { "x": 0, "y": 177, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "670-yellow_3": { - "frame": { "x": 19, "y": 177, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-blue_2": { - "frame": { "x": 230, "y": 27, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-blue_3": { - "frame": { "x": 182, "y": 30, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-orange_2": { - "frame": { "x": 156, "y": 30, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-orange_3": { - "frame": { "x": 256, "y": 27, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-red_2": { - "frame": { "x": 0, "y": 28, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-red_3": { - "frame": { "x": 26, "y": 28, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-white_2": { - "frame": { "x": 52, "y": 28, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-white_3": { - "frame": { "x": 130, "y": 30, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-yellow_2": { - "frame": { "x": 78, "y": 28, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "671-yellow_3": { - "frame": { "x": 104, "y": 30, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "672_2": { - "frame": { "x": 263, "y": 212, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "672_3": { - "frame": { "x": 321, "y": 213, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "673_2": { - "frame": { "x": 23, "y": 155, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "673_3": { - "frame": { "x": 0, "y": 155, "w": 23, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 23, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "677_2": { - "frame": { "x": 280, "y": 215, "w": 16, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 16, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "677_3": { - "frame": { "x": 18, "y": 216, "w": 16, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 10, "w": 16, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "678-female_2": { - "frame": { "x": 316, "y": 169, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "678-female_3": { - "frame": { "x": 253, "y": 168, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "678_2": { - "frame": { "x": 295, "y": 169, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "678_3": { - "frame": { "x": 274, "y": 168, "w": 21, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 21, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "690_2": { - "frame": { "x": 194, "y": 197, "w": 18, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 18, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "690_3": { - "frame": { "x": 0, "y": 199, "w": 18, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 18, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "691_2": { - "frame": { "x": 290, "y": 0, "w": 32, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 32, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "691_3": { - "frame": { "x": 290, "y": 23, "w": 32, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 32, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "696_2": { - "frame": { "x": 174, "y": 200, "w": 20, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "696_3": { - "frame": { "x": 18, "y": 199, "w": 20, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "697_2": { - "frame": { "x": 208, "y": 54, "w": 30, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 30, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "697_3": { - "frame": { "x": 238, "y": 54, "w": 30, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 30, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "698_2": { - "frame": { "x": 157, "y": 180, "w": 17, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 17, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "698_3": { - "frame": { "x": 287, "y": 191, "w": 17, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 17, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "699_2": { - "frame": { "x": 130, "y": 132, "w": 24, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 1, "w": 24, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "699_3": { - "frame": { "x": 106, "y": 132, "w": 24, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 1, "w": 24, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "700_2": { - "frame": { "x": 320, "y": 70, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "700_3": { - "frame": { "x": 208, "y": 30, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "702_2": { - "frame": { "x": 105, "y": 202, "w": 22, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 11, "w": 22, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "702_3": { - "frame": { "x": 59, "y": 201, "w": 22, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 11, "w": 22, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "703_2": { - "frame": { "x": 105, "y": 182, "w": 14, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 15, "w": 14, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "703_3": { - "frame": { "x": 268, "y": 54, "w": 14, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 15, "w": 14, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "704_2": { - "frame": { "x": 142, "y": 159, "w": 12, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 14, "w": 12, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "704_3": { - "frame": { "x": 128, "y": 224, "w": 12, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 14, "w": 12, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "705_2": { - "frame": { "x": 325, "y": 191, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 6, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "705_3": { - "frame": { "x": 127, "y": 202, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 6, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "706_2": { - "frame": { "x": 204, "y": 151, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "706_3": { - "frame": { "x": 314, "y": 145, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "708_2": { - "frame": { "x": 228, "y": 151, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "708_3": { - "frame": { "x": 52, "y": 154, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "709_2": { - "frame": { "x": 154, "y": 132, "w": 25, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 25, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "709_3": { - "frame": { "x": 179, "y": 132, "w": 25, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 25, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "710_2": { - "frame": { "x": 81, "y": 204, "w": 17, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 17, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "710_3": { - "frame": { "x": 212, "y": 211, "w": 17, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 9, "w": 17, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "711_1": { - "frame": { "x": 77, "y": 156, "w": 21, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 21, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "711_2": { - "frame": { "x": 154, "y": 157, "w": 21, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 21, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "711_3": { - "frame": { "x": 98, "y": 159, "w": 21, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 5, "w": 21, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "712_2": { - "frame": { "x": 229, "y": 211, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "712_3": { - "frame": { "x": 246, "y": 212, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 10, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "713_2": { - "frame": { "x": 52, "y": 130, "w": 27, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 27, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "713_3": { - "frame": { "x": 79, "y": 132, "w": 27, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 27, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "714_2": { - "frame": { "x": 46, "y": 175, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "714_3": { - "frame": { "x": 228, "y": 172, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 6, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "715_2": { - "frame": { "x": 310, "y": 46, "w": 28, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 4, "w": 28, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "715_3": { - "frame": { "x": 282, "y": 46, "w": 28, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 4, "w": 28, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "716-active_2": { - "frame": { "x": 114, "y": 0, "w": 29, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 29, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "716-active_3": { - "frame": { "x": 143, "y": 0, "w": 29, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 29, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "716-neutral_2": { - "frame": { "x": 172, "y": 0, "w": 29, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 29, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "716-neutral_3": { - "frame": { "x": 201, "y": 0, "w": 29, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 29, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "717_2": { - "frame": { "x": 230, "y": 0, "w": 30, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 30, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "717_3": { - "frame": { "x": 260, "y": 0, "w": 30, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 30, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "720-unbound_1": { - "frame": { "x": 38, "y": 0, "w": 38, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 2, "w": 38, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "720-unbound_2": { - "frame": { "x": 76, "y": 0, "w": 38, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 2, "w": 38, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "720-unbound_3": { - "frame": { "x": 0, "y": 0, "w": 38, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 2, "w": 38, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "720_1": { - "frame": { "x": 217, "y": 192, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "720_2": { - "frame": { "x": 38, "y": 195, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "720_3": { - "frame": { "x": 304, "y": 191, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_6v.png", - "format": "RGBA8888", - "size": { "w": 342, "h": 247 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_6v.png", + "format": "RGBA8888", + "size": { + "w": 480, + "h": 480 + }, + "scale": 1, + "frames": [ + { + "filename": "653_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "653_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "654_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "654_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "655_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "655_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "656_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "656_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "657_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "657_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "658-ash_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "658-ash_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "658_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "658_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "664_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "664_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "665_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "665_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-archipelago_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-archipelago_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-continental_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-continental_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-elegant_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-elegant_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-fancy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-fancy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-garden_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-garden_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-high-plains_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-high-plains_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-icy-snow_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-icy-snow_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-jungle_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-jungle_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-marine_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-marine_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-meadow_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-meadow_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-modern_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-modern_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-monsoon_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-monsoon_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-ocean_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-ocean_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-poke-ball_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-poke-ball_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-polar_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-polar_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-river_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-river_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-sandstorm_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-sandstorm_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-savanna_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-savanna_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-sun_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-sun_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-tundra_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "666-tundra_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-blue_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-blue_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-orange_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-orange_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-red_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-red_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-white_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-white_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-yellow_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "669-yellow_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-blue_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-blue_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-orange_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-orange_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-red_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-red_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-white_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-white_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-yellow_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "670-yellow_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-blue_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-blue_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-orange_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-orange_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-red_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-red_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-white_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-white_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-yellow_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "671-yellow_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "672_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "672_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "673_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "673_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-dandy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-dandy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-debutante_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-debutante_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-diamond_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-diamond_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-heart_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-heart_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-kabuki_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-kabuki_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-la-reine_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-la-reine_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-matron_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-matron_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-pharaoh_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-pharaoh_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-star_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "676-star_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "676_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "676_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "677_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "677_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "678-female_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "678-female_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "678_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "678_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "682_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "682_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "683_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "683_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "684_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "684_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "685_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "685_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "688_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "688_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "689_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "689_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "690_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "690_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "691_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "691_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "696_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "696_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "697_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "697_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "698_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "698_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "699_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "699_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "700_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "700_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "702_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "702_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "703_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "703_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "704_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "704_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "705_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "705_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "706_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "706_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "708_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "708_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "709_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "709_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "710_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "710_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "711_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "711_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "711_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "712_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "712_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "713_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "713_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "714_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "714_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "715_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "715_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "716-active_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "716-active_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "716-neutral_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "716-neutral_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "717_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "717_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "720-unbound_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "720-unbound_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "720-unbound_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "720_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "720_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "720_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "2670_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "2670_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 450, + "w": 40, + "h": 30 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:41960148e7a74c451d8ed1c46adc4e09:5dc2b45aa8a432e966da6c4070905be6:8a74f769af240f74b0e67390bbb36c14$" + } } diff --git a/public/images/pokemon_icons_6v.png b/public/images/pokemon_icons_6v.png index 83e29e28738..29d00876b50 100644 Binary files a/public/images/pokemon_icons_6v.png and b/public/images/pokemon_icons_6v.png differ diff --git a/public/images/pokemon_icons_7v.json b/public/images/pokemon_icons_7v.json index a7f828a0fe1..30e12ce3bb4 100644 --- a/public/images/pokemon_icons_7v.json +++ b/public/images/pokemon_icons_7v.json @@ -1,956 +1,2981 @@ -{ "frames": { - "2027_2": { - "frame": { "x": 160, "y": 218, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2027_3": { - "frame": { "x": 91, "y": 218, "w": 21, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 10, "w": 21, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2028_2": { - "frame": { "x": 26, "y": 148, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2028_3": { - "frame": { "x": 104, "y": 148, "w": 25, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 25, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2052_2": { - "frame": { "x": 144, "y": 195, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2052_3": { - "frame": { "x": 331, "y": 195, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2053_2": { - "frame": { "x": 121, "y": 172, "w": 24, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 24, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "2053_3": { - "frame": { "x": 312, "y": 172, "w": 24, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 24, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "728_2": { - "frame": { "x": 62, "y": 219, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "728_3": { - "frame": { "x": 45, "y": 219, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "729_2": { - "frame": { "x": 158, "y": 171, "w": 23, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 23, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "729_3": { - "frame": { "x": 98, "y": 172, "w": 23, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 23, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "730_2": { - "frame": { "x": 130, "y": 145, "w": 28, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 28, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "730_3": { - "frame": { "x": 234, "y": 147, "w": 28, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 28, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "734_2": { - "frame": { "x": 306, "y": 214, "w": 25, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 25, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "734_3": { - "frame": { "x": 20, "y": 215, "w": 25, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 25, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "735_2": { - "frame": { "x": 268, "y": 175, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "735_3": { - "frame": { "x": 288, "y": 175, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "742_2": { - "frame": { "x": 187, "y": 217, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "742_3": { - "frame": { "x": 283, "y": 217, "w": 19, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 19, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "743_2": { - "frame": { "x": 0, "y": 197, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "743_3": { - "frame": { "x": 96, "y": 196, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "747_2": { - "frame": { "x": 165, "y": 198, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "747_3": { - "frame": { "x": 202, "y": 197, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "748_2": { - "frame": { "x": 0, "y": 148, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "748_3": { - "frame": { "x": 312, "y": 147, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "751_2": { - "frame": { "x": 104, "y": 60, "w": 14, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 14, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "751_3": { - "frame": { "x": 130, "y": 88, "w": 14, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 14, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "752_2": { - "frame": { "x": 283, "y": 199, "w": 23, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 23, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "752_3": { - "frame": { "x": 116, "y": 214, "w": 23, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 8, "w": 23, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "753_2": { - "frame": { "x": 187, "y": 198, "w": 14, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 8, "w": 14, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "753_3": { - "frame": { "x": 234, "y": 118, "w": 14, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 8, "w": 14, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "754_2": { - "frame": { "x": 71, "y": 197, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "754_3": { - "frame": { "x": 224, "y": 198, "w": 20, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 20, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "755_2": { - "frame": { "x": 346, "y": 52, "w": 13, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 4, "w": 13, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "755_3": { - "frame": { "x": 268, "y": 30, "w": 13, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 14, "y": 4, "w": 13, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "756_2": { - "frame": { "x": 338, "y": 171, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "756_3": { - "frame": { "x": 0, "y": 173, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "761_2": { - "frame": { "x": 323, "y": 235, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "761_3": { - "frame": { "x": 129, "y": 235, "w": 16, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 16, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "762_2": { - "frame": { "x": 342, "y": 29, "w": 18, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 4, "w": 18, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "762_3": { - "frame": { "x": 265, "y": 199, "w": 18, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 4, "w": 18, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "763_2": { - "frame": { "x": 50, "y": 175, "w": 21, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 21, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "763_3": { - "frame": { "x": 181, "y": 174, "w": 21, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 21, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "767_2": { - "frame": { "x": 223, "y": 220, "w": 24, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 24, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "767_3": { - "frame": { "x": 17, "y": 231, "w": 24, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 11, "w": 24, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "768_2": { - "frame": { "x": 26, "y": 172, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "768_3": { - "frame": { "x": 74, "y": 150, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "771_2": { - "frame": { "x": 163, "y": 236, "w": 18, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 11, "w": 18, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "771_3": { - "frame": { "x": 145, "y": 236, "w": 18, "h": 13 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 11, "w": 18, "h": 13 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "772_2": { - "frame": { "x": 262, "y": 147, "w": 25, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 25, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "772_3": { - "frame": { "x": 287, "y": 147, "w": 25, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 25, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-bug_2": { - "frame": { "x": 0, "y": 118, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-bug_3": { - "frame": { "x": 26, "y": 118, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-dark_2": { - "frame": { "x": 104, "y": 118, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-dark_3": { - "frame": { "x": 182, "y": 118, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-dragon_2": { - "frame": { "x": 208, "y": 118, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-dragon_3": { - "frame": { "x": 52, "y": 120, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-electric_2": { - "frame": { "x": 78, "y": 120, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-electric_3": { - "frame": { "x": 268, "y": 57, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-fairy_2": { - "frame": { "x": 294, "y": 57, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-fairy_3": { - "frame": { "x": 320, "y": 57, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-fighting_2": { - "frame": { "x": 0, "y": 58, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-fighting_3": { - "frame": { "x": 26, "y": 58, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-fire_2": { - "frame": { "x": 118, "y": 58, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-fire_3": { - "frame": { "x": 203, "y": 58, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-flying_2": { - "frame": { "x": 229, "y": 58, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-flying_3": { - "frame": { "x": 326, "y": 117, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-ghost_2": { - "frame": { "x": 78, "y": 60, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-ghost_3": { - "frame": { "x": 144, "y": 85, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-grass_2": { - "frame": { "x": 170, "y": 85, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-grass_3": { - "frame": { "x": 255, "y": 87, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-ground_2": { - "frame": { "x": 281, "y": 87, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-ground_3": { - "frame": { "x": 307, "y": 87, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-ice_2": { - "frame": { "x": 333, "y": 87, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-ice_3": { - "frame": { "x": 0, "y": 88, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-poison_2": { - "frame": { "x": 26, "y": 88, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-poison_3": { - "frame": { "x": 104, "y": 88, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-psychic_2": { - "frame": { "x": 196, "y": 88, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-psychic_3": { - "frame": { "x": 222, "y": 88, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-rock_2": { - "frame": { "x": 52, "y": 90, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-rock_3": { - "frame": { "x": 78, "y": 90, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-steel_2": { - "frame": { "x": 130, "y": 115, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-steel_3": { - "frame": { "x": 52, "y": 60, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-water_2": { - "frame": { "x": 156, "y": 115, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773-water_3": { - "frame": { "x": 248, "y": 117, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773_2": { - "frame": { "x": 274, "y": 117, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "773_3": { - "frame": { "x": 300, "y": 117, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "776_2": { - "frame": { "x": 181, "y": 148, "w": 23, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 23, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "776_3": { - "frame": { "x": 158, "y": 145, "w": 23, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 23, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "777_2": { - "frame": { "x": 223, "y": 234, "w": 17, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 17, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "777_3": { - "frame": { "x": 112, "y": 232, "w": 17, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 8, "w": 17, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "778-busted_2": { - "frame": { "x": 302, "y": 230, "w": 21, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 21, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "778-busted_3": { - "frame": { "x": 247, "y": 222, "w": 21, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 12, "w": 21, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "778-disguised_2": { - "frame": { "x": 206, "y": 217, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "778-disguised_3": { - "frame": { "x": 0, "y": 219, "w": 17, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 5, "w": 17, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "779_2": { - "frame": { "x": 244, "y": 199, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "779_3": { - "frame": { "x": 45, "y": 199, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "789_1": { - "frame": { "x": 308, "y": 194, "w": 23, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 23, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "789_2": { - "frame": { "x": 22, "y": 195, "w": 23, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 23, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "789_3": { - "frame": { "x": 121, "y": 194, "w": 23, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 6, "w": 23, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "790_2": { - "frame": { "x": 331, "y": 216, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "790_3": { - "frame": { "x": 139, "y": 216, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "791_1": { - "frame": { "x": 239, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "791_2": { - "frame": { "x": 210, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "791_3": { - "frame": { "x": 118, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "792_2": { - "frame": { "x": 175, "y": 57, "w": 28, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 28, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "792_3": { - "frame": { "x": 147, "y": 57, "w": 28, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 1, "w": 28, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "793_2": { - "frame": { "x": 247, "y": 175, "w": 21, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 21, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "793_3": { - "frame": { "x": 226, "y": 174, "w": 21, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 21, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "797_2": { - "frame": { "x": 250, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "797_3": { - "frame": { "x": 218, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "798_2": { - "frame": { "x": 179, "y": 28, "w": 31, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "798_3": { - "frame": { "x": 148, "y": 28, "w": 31, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "800-dawn-wings_2": { - "frame": { "x": 31, "y": 28, "w": 31, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 31, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "800-dawn-wings_3": { - "frame": { "x": 0, "y": 28, "w": 31, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 31, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "800-dusk-mane_2": { - "frame": { "x": 114, "y": 0, "w": 34, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 34, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "800-dusk-mane_3": { - "frame": { "x": 80, "y": 0, "w": 34, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 0, "w": 34, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "800-ultra_2": { - "frame": { "x": 183, "y": 0, "w": 35, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 35, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "800-ultra_3": { - "frame": { "x": 148, "y": 0, "w": 35, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 35, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "800_2": { - "frame": { "x": 90, "y": 30, "w": 28, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 28, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "800_3": { - "frame": { "x": 62, "y": 30, "w": 28, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 28, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "802_1": { - "frame": { "x": 74, "y": 173, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 4, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "802_2": { - "frame": { "x": 204, "y": 173, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 4, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "802_3": { - "frame": { "x": 338, "y": 147, "w": 22, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 4, "w": 22, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "803_2": { - "frame": { "x": 51, "y": 150, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 3, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "803_3": { - "frame": { "x": 204, "y": 148, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 3, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "804_2": { - "frame": { "x": 315, "y": 0, "w": 33, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 33, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "804_3": { - "frame": { "x": 282, "y": 0, "w": 33, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 33, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "808_2": { - "frame": { "x": 339, "y": 235, "w": 17, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 17, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "808_3": { - "frame": { "x": 79, "y": 236, "w": 17, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 17, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "809-gigantamax_2": { - "frame": { "x": 312, "y": 29, "w": 30, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "809-gigantamax_3": { - "frame": { "x": 282, "y": 29, "w": 30, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "809_2": { - "frame": { "x": 40, "y": 0, "w": 40, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 40, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "809_3": { - "frame": { "x": 0, "y": 0, "w": 40, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 0, "y": 1, "w": 40, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_6v.png", - "format": "RGBA8888", - "size": { "w": 360, "h": 254 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_7v.png", + "format": "RGBA8888", + "size": { + "w": 440, + "h": 440 + }, + "scale": 1, + "frames": [ + { + "filename": "728_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "728_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "729_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "729_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "730_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "730_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "734_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "734_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "735_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "735_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "742_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "742_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "743_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "743_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "747_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "747_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "748_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "748_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "751_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "751_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "752_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "752_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "753_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "753_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "754_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "754_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "755_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "755_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "756_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "756_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "761_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "761_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "762_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "762_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "763_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "763_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "767_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "767_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "768_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "768_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "771_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "771_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "772_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "772_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-bug_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-bug_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-dark_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-dark_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-dragon_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-dragon_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-electric_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-electric_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-fairy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-fairy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-fighting_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-fighting_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-fire_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-fire_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-flying_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-flying_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-ghost_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-ghost_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-grass_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-grass_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-ground_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-ground_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-ice_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-ice_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-poison_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-poison_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-psychic_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-psychic_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-rock_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-rock_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-steel_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-steel_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-water_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "773-water_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "773_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "773_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "776_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "776_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "777_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "777_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "778-busted_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "778-busted_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "778-disguised_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "778-disguised_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "779_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "779_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "789_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "789_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "789_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "790_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "790_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "791_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "791_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "791_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "792_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "792_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "793_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "793_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "797_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "797_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "798_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "798_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "800-dawn-wings_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "800-dawn-wings_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "800-dusk-mane_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "800-dusk-mane_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "800-ultra_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "800-ultra_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "800_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "800_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "802_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "802_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "802_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "803_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "803_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "804_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "804_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "807_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "807_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "808_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "808_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "809-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "809-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "809_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "809_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "2026_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "2026_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "2027_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "2027_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "2028_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "2028_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "2052_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "2052_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "2053_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "2053_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "2103_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "2103_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 360, + "w": 40, + "h": 30 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:914c9869d6dab145bbbe443bdc3f932c:80b9ecf9647b68af17c07b88e1a1856e:d5975df27e1e94206a68aa1fd3c2c8d0$" + } } diff --git a/public/images/pokemon_icons_7v.png b/public/images/pokemon_icons_7v.png index 50fee6de396..1f7d6e5f826 100644 Binary files a/public/images/pokemon_icons_7v.png and b/public/images/pokemon_icons_7v.png differ diff --git a/public/images/pokemon_icons_8v.json b/public/images/pokemon_icons_8v.json index 002957bba0c..a33f88e9d9b 100644 --- a/public/images/pokemon_icons_8v.json +++ b/public/images/pokemon_icons_8v.json @@ -1,1306 +1,4115 @@ -{ "frames": { - "4052_2": { - "frame": { "x": 85, "y": 209, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4052_3": { - "frame": { "x": 106, "y": 210, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4077_2": { - "frame": { "x": 203, "y": 112, "w": 24, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 24, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4077_3": { - "frame": { "x": 48, "y": 112, "w": 24, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 24, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4078_2": { - "frame": { "x": 230, "y": 133, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4078_3": { - "frame": { "x": 203, "y": 133, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4079_2": { - "frame": { "x": 79, "y": 250, "w": 26, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 26, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4079_3": { - "frame": { "x": 351, "y": 250, "w": 26, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 8, "w": 26, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4080_1": { - "frame": { "x": 352, "y": 161, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4080_2": { - "frame": { "x": 23, "y": 161, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4080_3": { - "frame": { "x": 328, "y": 160, "w": 24, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4144_2": { - "frame": { "x": 146, "y": 230, "w": 22, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4144_3": { - "frame": { "x": 85, "y": 231, "w": 22, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4145_2": { - "frame": { "x": 228, "y": 110, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4145_3": { - "frame": { "x": 97, "y": 89, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4146_2": { - "frame": { "x": 240, "y": 200, "w": 28, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 28, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4146_3": { - "frame": { "x": 212, "y": 200, "w": 28, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 6, "w": 28, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4199_1": { - "frame": { "x": 360, "y": 30, "w": 20, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 20, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4199_2": { - "frame": { "x": 96, "y": 182, "w": 20, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 20, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4199_3": { - "frame": { "x": 192, "y": 179, "w": 20, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 20, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4222_2": { - "frame": { "x": 309, "y": 228, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4222_3": { - "frame": { "x": 330, "y": 228, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4263_2": { - "frame": { "x": 216, "y": 258, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4263_3": { - "frame": { "x": 304, "y": 265, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4264_2": { - "frame": { "x": 287, "y": 210, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4264_3": { - "frame": { "x": 160, "y": 210, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4562_2": { - "frame": { "x": 76, "y": 264, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "4562_3": { - "frame": { "x": 351, "y": 264, "w": 22, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 22, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6100_2": { - "frame": { "x": 168, "y": 230, "w": 14, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 14, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6100_3": { - "frame": { "x": 49, "y": 277, "w": 14, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 14, "w": 14, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6101_2": { - "frame": { "x": 312, "y": 187, "w": 16, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 16, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6101_3": { - "frame": { "x": 266, "y": 271, "w": 16, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 16, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6215_2": { - "frame": { "x": 182, "y": 251, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6215_3": { - "frame": { "x": 126, "y": 250, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6549_2": { - "frame": { "x": 288, "y": 249, "w": 16, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 16, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6549_3": { - "frame": { "x": 286, "y": 58, "w": 16, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 5, "w": 16, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6570_2": { - "frame": { "x": 146, "y": 249, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6570_3": { - "frame": { "x": 333, "y": 248, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 6, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6571_2": { - "frame": { "x": 193, "y": 156, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6571_3": { - "frame": { "x": 23, "y": 138, "w": 25, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 25, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6705_2": { - "frame": { "x": 125, "y": 89, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 6, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6705_3": { - "frame": { "x": 34, "y": 271, "w": 15, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 6, "w": 15, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6706_2": { - "frame": { "x": 234, "y": 85, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6706_3": { - "frame": { "x": 260, "y": 85, "w": 26, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 26, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6713_2": { - "frame": { "x": 257, "y": 133, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "6713_3": { - "frame": { "x": 48, "y": 134, "w": 27, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 5, "w": 27, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "816_2": { - "frame": { "x": 0, "y": 188, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "816_3": { - "frame": { "x": 290, "y": 187, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "817_2": { - "frame": { "x": 308, "y": 136, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "817_3": { - "frame": { "x": 332, "y": 136, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "818-gigantamax_2": { - "frame": { "x": 214, "y": 28, "w": 30, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "818-gigantamax_3": { - "frame": { "x": 348, "y": 0, "w": 30, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "818_2": { - "frame": { "x": 75, "y": 134, "w": 22, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 1, "w": 22, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "818_3": { - "frame": { "x": 123, "y": 135, "w": 22, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 1, "w": 22, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "821_2": { - "frame": { "x": 139, "y": 271, "w": 19, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 19, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "821_3": { - "frame": { "x": 158, "y": 271, "w": 19, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 7, "w": 19, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "822_2": { - "frame": { "x": 0, "y": 231, "w": 22, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "822_3": { - "frame": { "x": 287, "y": 230, "w": 22, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "823-gigantamax_2": { - "frame": { "x": 302, "y": 28, "w": 32, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 32, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "823-gigantamax_3": { - "frame": { "x": 0, "y": 30, "w": 32, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 32, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "823_2": { - "frame": { "x": 140, "y": 87, "w": 27, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 27, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "823_3": { - "frame": { "x": 201, "y": 88, "w": 27, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 27, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "829_2": { - "frame": { "x": 270, "y": 231, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "829_3": { - "frame": { "x": 122, "y": 271, "w": 17, "h": 18 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 6, "w": 17, "h": 18 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "830_2": { - "frame": { "x": 42, "y": 226, "w": 19, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "830_3": { - "frame": { "x": 233, "y": 218, "w": 19, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "835_2": { - "frame": { "x": 211, "y": 218, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "835_3": { - "frame": { "x": 0, "y": 211, "w": 22, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "836_2": { - "frame": { "x": 189, "y": 206, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "836_3": { - "frame": { "x": 138, "y": 205, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "850_2": { - "frame": { "x": 194, "y": 276, "w": 21, "h": 10 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 21, "h": 10 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "850_3": { - "frame": { "x": 233, "y": 275, "w": 21, "h": 10 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 10, "w": 21, "h": 10 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "851_2": { - "frame": { "x": 113, "y": 0, "w": 37, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 0, "w": 37, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "851_3": { - "frame": { "x": 76, "y": 0, "w": 37, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 0, "w": 37, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "854_2": { - "frame": { "x": 98, "y": 274, "w": 17, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "854_3": { - "frame": { "x": 177, "y": 272, "w": 17, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "855_2": { - "frame": { "x": 116, "y": 187, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "855_3": { - "frame": { "x": 167, "y": 187, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "856_2": { - "frame": { "x": 127, "y": 227, "w": 19, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "856_3": { - "frame": { "x": 182, "y": 228, "w": 19, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "857_2": { - "frame": { "x": 312, "y": 206, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "857_3": { - "frame": { "x": 44, "y": 204, "w": 22, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 4, "w": 22, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "858-gigantamax_2": { - "frame": { "x": 273, "y": 28, "w": 29, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 29, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "858-gigantamax_3": { - "frame": { "x": 244, "y": 28, "w": 29, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 29, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "858_2": { - "frame": { "x": 47, "y": 179, "w": 22, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 22, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "858_3": { - "frame": { "x": 74, "y": 161, "w": 22, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 22, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "859_2": { - "frame": { "x": 326, "y": 270, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "859_3": { - "frame": { "x": 0, "y": 271, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "860_2": { - "frame": { "x": 22, "y": 184, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "860_3": { - "frame": { "x": 69, "y": 186, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "861-gigantamax_2": { - "frame": { "x": 0, "y": 57, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "861-gigantamax_3": { - "frame": { "x": 302, "y": 55, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "861_2": { - "frame": { "x": 286, "y": 85, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "861_3": { - "frame": { "x": 72, "y": 83, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "863_2": { - "frame": { "x": 22, "y": 207, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "863_3": { - "frame": { "x": 360, "y": 112, "w": 20, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 20, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "864_2": { - "frame": { "x": 94, "y": 30, "w": 30, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 1, "w": 30, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "864_3": { - "frame": { "x": 151, "y": 30, "w": 30, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 1, "w": 30, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "867_2": { - "frame": { "x": 32, "y": 30, "w": 31, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "867_3": { - "frame": { "x": 63, "y": 30, "w": 31, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 1, "w": 31, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "872_1": { - "frame": { "x": 282, "y": 272, "w": 17, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "872_2": { - "frame": { "x": 216, "y": 274, "w": 17, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "872_3": { - "frame": { "x": 17, "y": 274, "w": 17, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "873_1": { - "frame": { "x": 243, "y": 178, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "873_2": { - "frame": { "x": 218, "y": 178, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "873_3": { - "frame": { "x": 270, "y": 162, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "876-female_2": { - "frame": { "x": 350, "y": 184, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "876-female_3": { - "frame": { "x": 268, "y": 184, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "876_2": { - "frame": { "x": 268, "y": 207, "w": 19, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "876_3": { - "frame": { "x": 66, "y": 209, "w": 19, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "877-hangry_1": { - "frame": { "x": 105, "y": 253, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "877-hangry_2": { - "frame": { "x": 249, "y": 254, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "877-hangry_3": { - "frame": { "x": 199, "y": 255, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "877_1": { - "frame": { "x": 59, "y": 256, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "877_2": { - "frame": { "x": 0, "y": 250, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "877_3": { - "frame": { "x": 17, "y": 253, "w": 17, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 17, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "880_2": { - "frame": { "x": 244, "y": 156, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "880_3": { - "frame": { "x": 218, "y": 156, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "881_2": { - "frame": { "x": 252, "y": 231, "w": 18, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 3, "w": 18, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "881_3": { - "frame": { "x": 61, "y": 233, "w": 18, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 3, "w": 18, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "882_2": { - "frame": { "x": 328, "y": 183, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "882_3": { - "frame": { "x": 145, "y": 182, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 3, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "883_2": { - "frame": { "x": 357, "y": 207, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "883_3": { - "frame": { "x": 334, "y": 207, "w": 23, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 4, "w": 23, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "884-gigantamax_2": { - "frame": { "x": 124, "y": 30, "w": 27, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 27, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "884-gigantamax_3": { - "frame": { "x": 181, "y": 30, "w": 27, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 27, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "884_2": { - "frame": { "x": 123, "y": 162, "w": 22, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 22, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "884_3": { - "frame": { "x": 0, "y": 163, "w": 22, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 22, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "885_1": { - "frame": { "x": 201, "y": 238, "w": 24, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 24, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "885_2": { - "frame": { "x": 225, "y": 241, "w": 24, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 24, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "885_3": { - "frame": { "x": 309, "y": 248, "w": 24, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 6, "w": 24, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "886_1": { - "frame": { "x": 308, "y": 112, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "886_2": { - "frame": { "x": 125, "y": 111, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "886_3": { - "frame": { "x": 177, "y": 112, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "887_1": { - "frame": { "x": 86, "y": 57, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 2, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "887_2": { - "frame": { "x": 56, "y": 57, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 2, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "887_3": { - "frame": { "x": 26, "y": 57, "w": 30, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 2, "w": 30, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "888-crowned_2": { - "frame": { "x": 182, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "888-crowned_3": { - "frame": { "x": 150, "y": 0, "w": 32, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "888_2": { - "frame": { "x": 167, "y": 89, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "888_3": { - "frame": { "x": 311, "y": 89, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "889-crowned_2": { - "frame": { "x": 214, "y": 0, "w": 34, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 34, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "889-crowned_3": { - "frame": { "x": 248, "y": 0, "w": 34, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 34, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "889_2": { - "frame": { "x": 260, "y": 58, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "889_3": { - "frame": { "x": 234, "y": 58, "w": 26, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 1, "w": 26, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "890-eternamax_2": { - "frame": { "x": 0, "y": 0, "w": 38, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 0, "w": 38, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "890-eternamax_3": { - "frame": { "x": 38, "y": 0, "w": 38, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 1, "y": 0, "w": 38, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "890_2": { - "frame": { "x": 282, "y": 0, "w": 33, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 33, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "890_3": { - "frame": { "x": 315, "y": 0, "w": 33, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 3, "y": 1, "w": 33, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "891_1": { - "frame": { "x": 164, "y": 249, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "891_2": { - "frame": { "x": 270, "y": 249, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "891_3": { - "frame": { "x": 41, "y": 249, "w": 18, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 4, "w": 18, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-gigantamax-rapid_1": { - "frame": { "x": 284, "y": 111, "w": 24, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 24, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-gigantamax-rapid_2": { - "frame": { "x": 0, "y": 112, "w": 24, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 24, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-gigantamax-rapid_3": { - "frame": { "x": 24, "y": 112, "w": 24, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 24, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-gigantamax-single_1": { - "frame": { "x": 26, "y": 83, "w": 23, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 23, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-gigantamax-single_2": { - "frame": { "x": 49, "y": 83, "w": 23, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 23, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-gigantamax-single_3": { - "frame": { "x": 352, "y": 60, "w": 23, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 23, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-rapid-strike_1": { - "frame": { "x": 48, "y": 157, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-rapid-strike_2": { - "frame": { "x": 97, "y": 160, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892-rapid-strike_3": { - "frame": { "x": 145, "y": 160, "w": 26, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 4, "w": 26, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892_1": { - "frame": { "x": 356, "y": 136, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892_2": { - "frame": { "x": 284, "y": 137, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "892_3": { - "frame": { "x": 0, "y": 138, "w": 23, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 2, "w": 23, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "896_1": { - "frame": { "x": 97, "y": 136, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "896_2": { - "frame": { "x": 145, "y": 136, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "896_3": { - "frame": { "x": 169, "y": 136, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "897_1": { - "frame": { "x": 151, "y": 112, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "897_2": { - "frame": { "x": 97, "y": 112, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "897_3": { - "frame": { "x": 334, "y": 112, "w": 26, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 26, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898-ice_1": { - "frame": { "x": 328, "y": 60, "w": 24, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 24, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898-ice_2": { - "frame": { "x": 116, "y": 60, "w": 24, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 24, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898-ice_3": { - "frame": { "x": 177, "y": 60, "w": 24, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 24, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898-shadow_1": { - "frame": { "x": 151, "y": 57, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898-shadow_2": { - "frame": { "x": 208, "y": 58, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898-shadow_3": { - "frame": { "x": 334, "y": 30, "w": 26, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 0, "w": 26, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898_1": { - "frame": { "x": 351, "y": 228, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898_2": { - "frame": { "x": 22, "y": 231, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "898_3": { - "frame": { "x": 107, "y": 231, "w": 19, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 19, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "900_2": { - "frame": { "x": 0, "y": 87, "w": 25, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 25, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "900_3": { - "frame": { "x": 72, "y": 109, "w": 25, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 3, "w": 25, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "901_2": { - "frame": { "x": 256, "y": 110, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "901_3": { - "frame": { "x": 339, "y": 89, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 5, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "903_2": { - "frame": { "x": 307, "y": 160, "w": 21, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 21, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "903_3": { - "frame": { "x": 171, "y": 160, "w": 21, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 21, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_8v.png", - "format": "RGBA8888", - "size": { "w": 380, "h": 293 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_8v.png", + "format": "RGBA8888", + "size": { + "w": 510, + "h": 510 + }, + "scale": 1, + "frames": [ + { + "filename": "816_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "816_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "817_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "817_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "818-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "818-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "818_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "818_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "821_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "821_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "822_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "822_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "823-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "823-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "823_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "823_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "829_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "829_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "830_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "830_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "835_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "835_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "836_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "836_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "850_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "850_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "851-gigantamax", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "851-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "851-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "851_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "851_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "851s-gigantamax", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "854_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "854_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "855_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "855_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "856_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "856_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "857_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "857_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "858-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "858-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "858_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "858_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "859_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "859_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "860_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "860_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "861-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "861-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "861_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "861_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "863_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "863_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "864_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "864_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "867_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "867_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "872_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "872_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "872_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "873_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "873_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "873_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "876-female_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "876-female_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "876_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "876_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "877-hangry_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "877-hangry_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "877-hangry_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "877_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "877_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "877_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "880_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "880_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "881_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "881_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "882_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "882_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "883_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "883_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "884-gigantamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "884-gigantamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "884_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "884_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "885_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "885_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "885_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "886_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "886_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "886_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "887_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "887_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "887_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "888-crowned_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "888-crowned_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "888_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "888_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "889-crowned_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "889-crowned_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "889_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "889_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "890-eternamax_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "890-eternamax_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "890_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "890_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "891_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "891_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "891_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-gigantamax-rapid_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-gigantamax-rapid_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-gigantamax-rapid_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-gigantamax-single_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-gigantamax-single_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-gigantamax-single_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-rapid-strike_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-rapid-strike_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892-rapid-strike_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "892_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "892_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "894_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "894_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "895_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "895_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "896_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "896_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "896_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "897_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "897_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "897_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "898-ice_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "898-ice_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "898-ice_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "898-shadow_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "898-shadow_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "898-shadow_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "898_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "898_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "898_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "900_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "900_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "901_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "901_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "903_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "903_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4052_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4052_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4077_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4077_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4078_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4078_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4079_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4079_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4080_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "4080_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4080_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4144_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4144_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4145_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4145_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4146_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4146_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4199_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4199_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4199_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4222_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "4222_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "4263_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "4263_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "4264_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "4264_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "4562_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "4562_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "6100_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "6100_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "6101_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "6101_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "6215_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "6215_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6503_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6503_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6549_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6549_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6570_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6570_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6571_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6571_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6705_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6705_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6706_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 450, + "w": 40, + "h": 30 + } + }, + { + "filename": "6706_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "6713_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 480, + "w": 40, + "h": 30 + } + }, + { + "filename": "6713_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 480, + "w": 40, + "h": 30 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:c6192164d1b1971f54a6c5864e11748d:46b3adcf2a25bfb824db3d24cd1c96a9:ec5f05e7f30cd98f74db0c2326109fd3$" + } } diff --git a/public/images/pokemon_icons_8v.png b/public/images/pokemon_icons_8v.png index 1968bfe6214..2af86ac656f 100644 Binary files a/public/images/pokemon_icons_8v.png and b/public/images/pokemon_icons_8v.png differ diff --git a/public/images/pokemon_icons_9v.json b/public/images/pokemon_icons_9v.json index 83a47f101fa..6c8b93208e3 100644 --- a/public/images/pokemon_icons_9v.json +++ b/public/images/pokemon_icons_9v.json @@ -1,1047 +1,3296 @@ -{ "frames": { - "1000_1": { - "frame": { "x": 93, "y": 139, "w": 22, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 1, "w": 22, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1000_2": { - "frame": { "x": 170, "y": 135, "w": 22, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 1, "w": 22, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1000_3": { - "frame": { "x": 192, "y": 135, "w": 22, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 1, "w": 22, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1001_2": { - "frame": { "x": 249, "y": 0, "w": 30, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1001_3": { - "frame": { "x": 279, "y": 0, "w": 30, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1003_2": { - "frame": { "x": 27, "y": 58, "w": 28, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 28, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1003_3": { - "frame": { "x": 55, "y": 58, "w": 28, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 28, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1004_2": { - "frame": { "x": 249, "y": 207, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1004_3": { - "frame": { "x": 204, "y": 206, "w": 21, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 8, "w": 21, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1006_2": { - "frame": { "x": 44, "y": 140, "w": 22, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 22, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1006_3": { - "frame": { "x": 22, "y": 139, "w": 22, "h": 27 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 22, "h": 27 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1007-apex-build_2": { - "frame": { "x": 155, "y": 0, "w": 32, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1007-apex-build_3": { - "frame": { "x": 187, "y": 0, "w": 32, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 32, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1008-ultimate-mode_1": { - "frame": { "x": 185, "y": 29, "w": 30, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1008-ultimate-mode_2": { - "frame": { "x": 155, "y": 29, "w": 30, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1008-ultimate-mode_3": { - "frame": { "x": 219, "y": 0, "w": 30, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 30, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1010_2": { - "frame": { "x": 271, "y": 179, "w": 21, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 21, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1010_3": { - "frame": { "x": 162, "y": 182, "w": 21, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 2, "w": 21, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1018_2": { - "frame": { "x": 0, "y": 0, "w": 31, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 31, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1018_3": { - "frame": { "x": 31, "y": 0, "w": 31, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 31, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1022_2": { - "frame": { "x": 27, "y": 86, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1022_3": { - "frame": { "x": 163, "y": 84, "w": 29, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 29, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1023_2": { - "frame": { "x": 300, "y": 30, "w": 20, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 20, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "1023_3": { - "frame": { "x": 46, "y": 167, "w": 20, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 1, "w": 20, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "8901_1": { - "frame": { "x": 30, "y": 30, "w": 30, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 1, "w": 30, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "8901_2": { - "frame": { "x": 60, "y": 30, "w": 30, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 1, "w": 30, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "8901_3": { - "frame": { "x": 0, "y": 30, "w": 30, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 1, "w": 30, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "909_2": { - "frame": { "x": 42, "y": 195, "w": 21, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 21, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "909_3": { - "frame": { "x": 63, "y": 196, "w": 21, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 5, "w": 21, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "910_2": { - "frame": { "x": 271, "y": 205, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "910_3": { - "frame": { "x": 292, "y": 204, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "911_2": { - "frame": { "x": 131, "y": 112, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "911_3": { - "frame": { "x": 188, "y": 112, "w": 28, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 3, "w": 28, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "912_2": { - "frame": { "x": 36, "y": 244, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "912_3": { - "frame": { "x": 178, "y": 244, "w": 15, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 9, "w": 15, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "913_2": { - "frame": { "x": 84, "y": 217, "w": 17, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 17, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "913_3": { - "frame": { "x": 197, "y": 59, "w": 17, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 5, "w": 17, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "914_2": { - "frame": { "x": 122, "y": 135, "w": 24, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "914_3": { - "frame": { "x": 146, "y": 135, "w": 24, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 3, "w": 24, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "919_1": { - "frame": { "x": 0, "y": 253, "w": 16, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 13, "w": 16, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "919_2": { - "frame": { "x": 51, "y": 250, "w": 16, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 13, "w": 16, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "919_3": { - "frame": { "x": 95, "y": 247, "w": 16, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 13, "w": 16, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "920_1": { - "frame": { "x": 0, "y": 190, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "920_2": { - "frame": { "x": 208, "y": 183, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "920_3": { - "frame": { "x": 0, "y": 143, "w": 22, "h": 23 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 5, "w": 22, "h": 23 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "924_1": { - "frame": { "x": 237, "y": 152, "w": 29, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 8, "w": 29, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "924_2": { - "frame": { "x": 144, "y": 162, "w": 29, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 8, "w": 29, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "924_3": { - "frame": { "x": 266, "y": 159, "w": 29, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 8, "w": 29, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "925-four_1": { - "frame": { "x": 93, "y": 117, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "925-four_2": { - "frame": { "x": 245, "y": 130, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "925-four_3": { - "frame": { "x": 216, "y": 112, "w": 29, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 6, "w": 29, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "925-three_1": { - "frame": { "x": 115, "y": 160, "w": 29, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 8, "w": 29, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "925-three_2": { - "frame": { "x": 202, "y": 163, "w": 29, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 8, "w": 29, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "925-three_3": { - "frame": { "x": 173, "y": 162, "w": 29, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 8, "w": 29, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "932_2": { - "frame": { "x": 202, "y": 226, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "932_3": { - "frame": { "x": 292, "y": 225, "w": 18, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 9, "w": 18, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "933_2": { - "frame": { "x": 183, "y": 183, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "933_3": { - "frame": { "x": 292, "y": 183, "w": 25, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 7, "w": 25, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "934_2": { - "frame": { "x": 273, "y": 30, "w": 27, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 27, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "934_3": { - "frame": { "x": 0, "y": 58, "w": 27, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 0, "w": 27, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "935_1": { - "frame": { "x": 300, "y": 244, "w": 13, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 13, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "935_2": { - "frame": { "x": 287, "y": 244, "w": 13, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 13, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "935_3": { - "frame": { "x": 236, "y": 241, "w": 13, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 13, "y": 7, "w": 13, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "936_1": { - "frame": { "x": 251, "y": 179, "w": 20, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 0, "w": 20, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "936_2": { - "frame": { "x": 66, "y": 168, "w": 20, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 0, "w": 20, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "936_3": { - "frame": { "x": 231, "y": 172, "w": 20, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 0, "w": 20, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "937_1": { - "frame": { "x": 215, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "937_2": { - "frame": { "x": 244, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "937_3": { - "frame": { "x": 90, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "937_9": { - "frame": { "x": 119, "y": 30, "w": 29, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 5, "y": 0, "w": 29, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "940_2": { - "frame": { "x": 245, "y": 116, "w": 17, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 14, "w": 17, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "940_3": { - "frame": { "x": 153, "y": 254, "w": 17, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 14, "w": 17, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "941_2": { - "frame": { "x": 183, "y": 204, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "941_3": { - "frame": { "x": 125, "y": 204, "w": 21, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 7, "w": 21, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "948_2": { - "frame": { "x": 249, "y": 227, "w": 16, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 16, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "948_3": { - "frame": { "x": 0, "y": 232, "w": 16, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 7, "w": 16, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "949_2": { - "frame": { "x": 22, "y": 193, "w": 20, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 20, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "949_3": { - "frame": { "x": 86, "y": 192, "w": 20, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 20, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "951_2": { - "frame": { "x": 220, "y": 241, "w": 16, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 16, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "951_3": { - "frame": { "x": 162, "y": 234, "w": 16, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 8, "w": 16, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "952_2": { - "frame": { "x": 112, "y": 180, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "952_3": { - "frame": { "x": 137, "y": 182, "w": 25, "h": 22 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 6, "w": 25, "h": 22 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "953_2": { - "frame": { "x": 51, "y": 219, "w": 24, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 12, "w": 24, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "953_3": { - "frame": { "x": 225, "y": 225, "w": 24, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 12, "w": 24, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "954_2": { - "frame": { "x": 296, "y": 130, "w": 21, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 0, "w": 21, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "954_3": { - "frame": { "x": 216, "y": 134, "w": 21, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 0, "w": 21, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "957_1": { - "frame": { "x": 193, "y": 245, "w": 16, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 16, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "957_2": { - "frame": { "x": 301, "y": 113, "w": 16, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 16, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "957_3": { - "frame": { "x": 265, "y": 246, "w": 16, "h": 17 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 11, "w": 16, "h": 17 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "958_1": { - "frame": { "x": 270, "y": 226, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "958_2": { - "frame": { "x": 145, "y": 227, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "958_3": { - "frame": { "x": 101, "y": 227, "w": 17, "h": 20 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 8, "w": 17, "h": 20 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "959_1": { - "frame": { "x": 62, "y": 0, "w": 31, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 31, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "959_2": { - "frame": { "x": 93, "y": 0, "w": 31, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 31, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "959_3": { - "frame": { "x": 124, "y": 0, "w": 31, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 0, "w": 31, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "962_1": { - "frame": { "x": 301, "y": 88, "w": 19, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "962_2": { - "frame": { "x": 230, "y": 200, "w": 19, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "962_3": { - "frame": { "x": 106, "y": 202, "w": 19, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 3, "w": 19, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "967_2": { - "frame": { "x": 182, "y": 225, "w": 20, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 20, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "967_3": { - "frame": { "x": 125, "y": 225, "w": 20, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 9, "w": 20, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "968_2": { - "frame": { "x": 48, "y": 112, "w": 23, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 23, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "968_3": { - "frame": { "x": 25, "y": 111, "w": 23, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 23, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "969_2": { - "frame": { "x": 16, "y": 260, "w": 18, "h": 12 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 16, "w": 18, "h": 12 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "969_3": { - "frame": { "x": 67, "y": 255, "w": 18, "h": 12 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 11, "y": 16, "w": 18, "h": 12 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "970_2": { - "frame": { "x": 118, "y": 244, "w": 20, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "970_3": { - "frame": { "x": 16, "y": 244, "w": 20, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 12, "w": 20, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "973_1": { - "frame": { "x": 167, "y": 208, "w": 15, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 2, "w": 15, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "973_2": { - "frame": { "x": 21, "y": 218, "w": 15, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 2, "w": 15, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "973_3": { - "frame": { "x": 36, "y": 218, "w": 15, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 2, "w": 15, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "974_2": { - "frame": { "x": 73, "y": 240, "w": 22, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 13, "w": 22, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "974_3": { - "frame": { "x": 51, "y": 235, "w": 22, "h": 15 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 13, "w": 22, "h": 15 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "975_2": { - "frame": { "x": 269, "y": 109, "w": 32, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 7, "w": 32, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "975_3": { - "frame": { "x": 269, "y": 88, "w": 32, "h": 21 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 4, "y": 7, "w": 32, "h": 21 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "978-curly_2": { - "frame": { "x": 111, "y": 260, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "978-curly_3": { - "frame": { "x": 209, "y": 261, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "978-droopy_2": { - "frame": { "x": 85, "y": 262, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "978-droopy_3": { - "frame": { "x": 193, "y": 262, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "978-stretchy_2": { - "frame": { "x": 224, "y": 262, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "978-stretchy_3": { - "frame": { "x": 34, "y": 263, "w": 15, "h": 14 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 14, "w": 15, "h": 14 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "979_1": { - "frame": { "x": 56, "y": 86, "w": 27, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 27, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "979_2": { - "frame": { "x": 192, "y": 86, "w": 27, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 27, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "979_3": { - "frame": { "x": 219, "y": 86, "w": 27, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 27, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "981_2.png": { - "frame": { "x": 108, "y": 87, "w": 23, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 0, "w": 23, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "981_3.png": { - "frame": { "x": 246, "y": 86, "w": 23, "h": 30 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 0, "w": 23, "h": 30 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "982-three-segment_2": { - "frame": { "x": 83, "y": 87, "w": 25, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 1, "w": 25, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "982-three-segment_3": { - "frame": { "x": 295, "y": 60, "w": 25, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 1, "w": 25, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "982_2": { - "frame": { "x": 24, "y": 167, "w": 22, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 22, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "982_3": { - "frame": { "x": 90, "y": 166, "w": 22, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 2, "w": 22, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "987_1": { - "frame": { "x": 66, "y": 144, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "987_2": { - "frame": { "x": 295, "y": 159, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "987_3": { - "frame": { "x": 0, "y": 166, "w": 24, "h": 24 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 10, "y": 4, "w": 24, "h": 24 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "988_2": { - "frame": { "x": 137, "y": 84, "w": 26, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 1, "w": 26, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "988_3": { - "frame": { "x": 269, "y": 60, "w": 26, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 1, "w": 26, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "993_2": { - "frame": { "x": 167, "y": 59, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "993_3": { - "frame": { "x": 137, "y": 59, "w": 30, "h": 25 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 6, "y": 2, "w": 30, "h": 25 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "994_2": { - "frame": { "x": 242, "y": 58, "w": 27, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 1, "w": 27, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "994_3": { - "frame": { "x": 215, "y": 58, "w": 27, "h": 28 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 1, "w": 27, "h": 28 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "995_2": { - "frame": { "x": 110, "y": 58, "w": 27, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 27, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "995_3": { - "frame": { "x": 83, "y": 58, "w": 27, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 8, "y": 0, "w": 27, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "996_2": { - "frame": { "x": 138, "y": 247, "w": 15, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 15, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "996_3": { - "frame": { "x": 249, "y": 248, "w": 15, "h": 16 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 12, "y": 12, "w": 15, "h": 16 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "997_2": { - "frame": { "x": 146, "y": 208, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "997_3": { - "frame": { "x": 0, "y": 213, "w": 21, "h": 19 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 9, "w": 21, "h": 19 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "998_2": { - "frame": { "x": 163, "y": 109, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "998_3": { - "frame": { "x": 0, "y": 88, "w": 25, "h": 26 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 7, "y": 2, "w": 25, "h": 26 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "999_1": { - "frame": { "x": 274, "y": 130, "w": 22, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 0, "w": 22, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "999_2": { - "frame": { "x": 71, "y": 115, "w": 22, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 0, "w": 22, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - }, - "999_3": { - "frame": { "x": 0, "y": 114, "w": 22, "h": 29 }, - "rotated": false, - "trimmed": true, - "spriteSourceSize": { "x": 9, "y": 0, "w": 22, "h": 29 }, - "sourceSize": { "w": 40, "h": 30 } - } - }, - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.7-dev", - "image": "pokemon_icons_9v.png", - "format": "RGBA8888", - "size": { "w": 320, "h": 277 }, - "scale": "1" - } +{ + "textures": [ + { + "image": "pokemon_icons_9v.png", + "format": "RGBA8888", + "size": { + "w": 450, + "h": 450 + }, + "scale": 1, + "frames": [ + { + "filename": "909_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "909_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "910_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "910_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "911_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "911_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "912_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "912_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "913_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "913_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "914_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 30 + } + }, + { + "filename": "914_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "919_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "919_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "919_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "920_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "920_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "920_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "924_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "924_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "924_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "925-four_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 30, + "w": 40, + "h": 30 + } + }, + { + "filename": "925-four_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "925-four_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "925-three_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "925-three_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "925-three_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "932_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "932_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "933_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "933_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "934_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "934_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 60, + "w": 40, + "h": 30 + } + }, + { + "filename": "935_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "935_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "935_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "936_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "936_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "936_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "937_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "937_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "937_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "937_9", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "940_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 90, + "w": 40, + "h": 30 + } + }, + { + "filename": "940_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "941_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "941_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "944_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "944_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "945_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "945_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "948_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "948_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "949_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "949_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "951_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "951_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "952_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "952_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "953_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "953_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "954_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "954_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "957_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "957_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "957_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 150, + "w": 40, + "h": 30 + } + }, + { + "filename": "958_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "958_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "958_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "959_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "959_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "959_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "962_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "962_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "962_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "967_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "967_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 180, + "w": 40, + "h": 30 + } + }, + { + "filename": "968_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "968_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "969_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "969_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "970_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "970_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "973_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "973_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "973_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "974_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "974_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 210, + "w": 40, + "h": 30 + } + }, + { + "filename": "975_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "975_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "978-curly_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "978-curly_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "978-droopy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "978-droopy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "978-stretchy_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "978-stretchy_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "979_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "979_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "979_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 240, + "w": 40, + "h": 30 + } + }, + { + "filename": "981_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "981_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "982-three-segment_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "982-three-segment_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "982_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "982_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "987_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "987_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "987_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "988_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "988_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 270, + "w": 40, + "h": 30 + } + }, + { + "filename": "993_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "993_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "994_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "994_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "995_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "995_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "996_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "996_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "997_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "997_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "998_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 300, + "w": 40, + "h": 30 + } + }, + { + "filename": "998_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "999_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "999_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "999_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "1000_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "1000_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "1000_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "1001_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "1001_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "1003_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "1003_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 330, + "w": 40, + "h": 30 + } + }, + { + "filename": "1004_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1004_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1006_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1006_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1007-apex-build_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1007-apex-build_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1008-ultimate-mode_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1008-ultimate-mode_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1008-ultimate-mode_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1010_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1010_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 360, + "w": 40, + "h": 30 + } + }, + { + "filename": "1012-counterfeit_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1012-counterfeit_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1013-unremarkable_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1013-unremarkable_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1018_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1018_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1022_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 240, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1022_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 280, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1023_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 320, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "1023_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 360, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "8901_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 390, + "w": 40, + "h": 30 + } + }, + { + "filename": "8901_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 0, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "8901_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 40, + "y": 420, + "w": 40, + "h": 30 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:c13ec323095f727665fa953e64e98300:e7531bea9b5e1bef44def5b357c81630:3ec5c0bc286c296cfb7fa30a8b06f3da$" + } } diff --git a/public/images/pokemon_icons_9v.png b/public/images/pokemon_icons_9v.png index 5d0908d0590..f71b6c5ada5 100644 Binary files a/public/images/pokemon_icons_9v.png and b/public/images/pokemon_icons_9v.png differ diff --git a/public/images/statuses_it.png b/public/images/statuses_it.png index d372b989be9..af3107018f8 100644 Binary files a/public/images/statuses_it.png and b/public/images/statuses_it.png differ diff --git a/public/images/pokemon/variant/6706_2.json b/public/images/trainer/future_self_f.json similarity index 54% rename from public/images/pokemon/variant/6706_2.json rename to public/images/trainer/future_self_f.json index f6bbf20116e..0831828c2bc 100644 --- a/public/images/pokemon/variant/6706_2.json +++ b/public/images/trainer/future_self_f.json @@ -1,33 +1,33 @@ { "textures": [ { - "image": "6706_2.png", + "image": "future_self_f.png", "format": "RGBA8888", "size": { - "w": 82, - "h": 82 + "w": 29, + "h": 69 }, "scale": 1, "frames": [ { "filename": "0001.png", "rotated": false, - "trimmed": false, + "trimmed": true, "sourceSize": { - "w": 82, - "h": 72 + "w": 69, + "h": 69 }, "spriteSourceSize": { - "x": 0, + "x": 21, "y": 0, - "w": 82, - "h": 72 + "w": 29, + "h": 69 }, "frame": { "x": 0, "y": 0, - "w": 82, - "h": 72 + "w": 29, + "h": 69 } } ] @@ -36,6 +36,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:02eb46aa66ac70df612e129b7801a85c:a77cca14b23f4f3aece64d1a82449a0f:d60cc2e5ae2bd18de8ee3ab0649593ee$" + "smartupdate": "$TexturePacker:SmartUpdate:4eb16332c2e77886e4e621b62269f05e:26f1bc53c853efdbe228d67604b95b54:d25525a5db42bd57d2afe4b6e3081ee1$" } -} \ No newline at end of file +} diff --git a/public/images/trainer/future_self_f.png b/public/images/trainer/future_self_f.png new file mode 100644 index 00000000000..e75c5e5e65b Binary files /dev/null and b/public/images/trainer/future_self_f.png differ diff --git a/public/images/pokemon/variant/back/6706_2.json b/public/images/trainer/future_self_m.json similarity index 59% rename from public/images/pokemon/variant/back/6706_2.json rename to public/images/trainer/future_self_m.json index dccfbce60c5..f5d60ff5add 100644 --- a/public/images/pokemon/variant/back/6706_2.json +++ b/public/images/trainer/future_self_m.json @@ -1,32 +1,32 @@ { "textures": [ { - "image": "6706_2.png", + "image": "future_self_m.png", "format": "RGBA8888", "size": { - "w": 79, - "h": 79 + "w": 36, + "h": 73 }, "scale": 1, "frames": [ { "filename": "0001.png", "rotated": false, - "trimmed": false, + "trimmed": true, "sourceSize": { - "w": 79, + "w": 73, "h": 73 }, "spriteSourceSize": { - "x": 0, + "x": 18, "y": 0, - "w": 79, + "w": 36, "h": 73 }, "frame": { "x": 0, "y": 0, - "w": 79, + "w": 36, "h": 73 } } @@ -36,6 +36,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:64f7e6dfa489012922487e45ba53d557:4d24652b372939abe499497c4b6647b0:d60cc2e5ae2bd18de8ee3ab0649593ee$" + "smartupdate": "$TexturePacker:SmartUpdate:0d8d68d06ae75bc93d72b54183a9df02:d3d509801da9ff5c0bd4793a05ece391:83c4b8c2ed25ea7d9795bec5c40c8602$" } -} \ No newline at end of file +} diff --git a/public/images/trainer/future_self_m.png b/public/images/trainer/future_self_m.png new file mode 100644 index 00000000000..edd15cb6ea3 Binary files /dev/null and b/public/images/trainer/future_self_m.png differ diff --git a/public/images/types_it.png b/public/images/types_it.png index 8b644f1041c..3be03aeea68 100644 Binary files a/public/images/types_it.png and b/public/images/types_it.png differ diff --git a/public/images/ui/friendship.png b/public/images/ui/friendship.png new file mode 100644 index 00000000000..073adcadc76 Binary files /dev/null and b/public/images/ui/friendship.png differ diff --git a/public/images/ui/friendship_overlay.png b/public/images/ui/friendship_overlay.png new file mode 100644 index 00000000000..4a4724fbdc9 Binary files /dev/null and b/public/images/ui/friendship_overlay.png differ diff --git a/public/images/ui/legacy/friendship.png b/public/images/ui/legacy/friendship.png new file mode 100644 index 00000000000..073adcadc76 Binary files /dev/null and b/public/images/ui/legacy/friendship.png differ diff --git a/public/images/ui/legacy/friendship_overlay.png b/public/images/ui/legacy/friendship_overlay.png new file mode 100644 index 00000000000..4a4724fbdc9 Binary files /dev/null and b/public/images/ui/legacy/friendship_overlay.png differ diff --git a/public/images/ui/legacy/link_icon.png b/public/images/ui/legacy/link_icon.png new file mode 100644 index 00000000000..56081261b9c Binary files /dev/null and b/public/images/ui/legacy/link_icon.png differ diff --git a/public/images/ui/legacy/unlink_icon.png b/public/images/ui/legacy/unlink_icon.png new file mode 100644 index 00000000000..f0da5f8e3ed Binary files /dev/null and b/public/images/ui/legacy/unlink_icon.png differ diff --git a/public/images/ui/link_icon.png b/public/images/ui/link_icon.png new file mode 100644 index 00000000000..56081261b9c Binary files /dev/null and b/public/images/ui/link_icon.png differ diff --git a/public/images/ui/unlink_icon.png b/public/images/ui/unlink_icon.png new file mode 100644 index 00000000000..f0da5f8e3ed Binary files /dev/null and b/public/images/ui/unlink_icon.png differ diff --git a/public/locales b/public/locales index 3ccef8472dd..71390cba88f 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 3ccef8472dd7cc7c362538489954cb8fdad27e5f +Subproject commit 71390cba88f4103d0d2273d59a6dd8340a4fa54f diff --git a/src/account.ts b/src/account.ts index c6d2f85489a..692ff2b0d81 100644 --- a/src/account.ts +++ b/src/account.ts @@ -20,7 +20,7 @@ export function initLoggedInUser(): void { export function updateUserInfo(): Promise<[boolean, integer]> { return new Promise<[boolean, integer]>(resolve => { if (bypassLogin) { - loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "", hasAdminRole: false}; + loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "", hasAdminRole: false }; let lastSessionSlot = -1; for (let s = 0; s < 5; s++) { if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) { diff --git a/src/battle-scene.ts b/src/battle-scene.ts index df852126bc2..3cbf4d7b422 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1,57 +1,57 @@ import Phaser from "phaser"; -import UI from "./ui/ui"; -import Pokemon, { EnemyPokemon, PlayerPokemon } from "./field/pokemon"; -import PokemonSpecies, { allSpecies, getPokemonSpecies, PokemonSpeciesFilter } from "./data/pokemon-species"; +import UI from "#app/ui/ui"; +import Pokemon, { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; +import PokemonSpecies, { allSpecies, getPokemonSpecies, PokemonSpeciesFilter } from "#app/data/pokemon-species"; import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils"; -import * as Utils from "./utils"; -import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, Modifier, ModifierBar, ModifierPredicate, MultipleParticipantExpBonusModifier, overrideHeldItems, overrideModifiers, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, TerastallizeModifier, TurnHeldItemTransferModifier } from "./modifier/modifier"; -import { PokeballType } from "./data/pokeball"; -import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims"; -import { Phase } from "./phase"; -import { initGameSpeed } from "./system/game-speed"; -import { Arena, ArenaBase } from "./field/arena"; -import { GameData } from "./system/game-data"; -import { addTextObject, getTextColor, TextStyle } from "./ui/text"; -import { allMoves } from "./data/move"; -import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, ModifierPoolType, modifierTypes, PokemonHeldItemModifierType } from "./modifier/modifier-type"; -import AbilityBar from "./ui/ability-bar"; -import { allAbilities, applyAbAttrs, applyPostBattleInitAbAttrs, BlockItemTheftAbAttr, ChangeMovePriorityAbAttr, DoubleBattleChanceAbAttr, PostBattleInitAbAttr } from "./data/ability"; -import Battle, { BattleType, FixedBattleConfig } from "./battle"; -import { GameMode, GameModes, getGameMode } from "./game-mode"; -import FieldSpritePipeline from "./pipelines/field-sprite"; -import SpritePipeline from "./pipelines/sprite"; -import PartyExpBar from "./ui/party-exp-bar"; -import { trainerConfigs, TrainerSlot } from "./data/trainer-config"; -import Trainer, { TrainerVariant } from "./field/trainer"; -import TrainerData from "./system/trainer-data"; +import * as Utils from "#app/utils"; +import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, Modifier, ModifierBar, ModifierPredicate, MultipleParticipantExpBonusModifier, overrideHeldItems, overrideModifiers, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, RememberMoveModifier, TerastallizeModifier, TurnHeldItemTransferModifier } from "./modifier/modifier"; +import { PokeballType } from "#app/data/pokeball"; +import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "#app/data/battle-anims"; +import { Phase } from "#app/phase"; +import { initGameSpeed } from "#app/system/game-speed"; +import { Arena, ArenaBase } from "#app/field/arena"; +import { GameData } from "#app/system/game-data"; +import { addTextObject, getTextColor, TextStyle } from "#app/ui/text"; +import { allMoves } from "#app/data/move"; +import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, ModifierPoolType, modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; +import AbilityBar from "#app/ui/ability-bar"; +import { allAbilities, applyAbAttrs, applyPostBattleInitAbAttrs, BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, PostBattleInitAbAttr } from "#app/data/ability"; +import Battle, { BattleType, FixedBattleConfig } from "#app/battle"; +import { GameMode, GameModes, getGameMode } from "#app/game-mode"; +import FieldSpritePipeline from "#app/pipelines/field-sprite"; +import SpritePipeline from "#app/pipelines/sprite"; +import PartyExpBar from "#app/ui/party-exp-bar"; +import { trainerConfigs, TrainerSlot } from "#app/data/trainer-config"; +import Trainer, { TrainerVariant } from "#app/field/trainer"; +import TrainerData from "#app/system/trainer-data"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; -import { pokemonPrevolutions } from "./data/balance/pokemon-evolutions"; -import PokeballTray from "./ui/pokeball-tray"; -import InvertPostFX from "./pipelines/invert"; -import { Achv, achvs, ModifierAchv, MoneyAchv } from "./system/achv"; -import { Voucher, vouchers } from "./system/voucher"; -import { Gender } from "./data/gender"; +import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; +import PokeballTray from "#app/ui/pokeball-tray"; +import InvertPostFX from "#app/pipelines/invert"; +import { Achv, achvs, ModifierAchv, MoneyAchv } from "#app/system/achv"; +import { Voucher, vouchers } from "#app/system/voucher"; +import { Gender } from "#app/data/gender"; import UIPlugin from "phaser3-rex-plugins/templates/ui/ui-plugin"; -import { addUiThemeOverrides } from "./ui/ui-theme"; -import PokemonData from "./system/pokemon-data"; -import { Nature } from "./data/nature"; -import { FormChangeItem, pokemonFormChanges, SpeciesFormChange, SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger } from "./data/pokemon-forms"; -import { FormChangePhase } from "./phases/form-change-phase"; -import { getTypeRgb } from "./data/type"; -import PokemonSpriteSparkleHandler from "./field/pokemon-sprite-sparkle-handler"; -import CharSprite from "./ui/char-sprite"; -import DamageNumberHandler from "./field/damage-number-handler"; -import PokemonInfoContainer from "./ui/pokemon-info-container"; -import { biomeDepths, getBiomeName } from "./data/balance/biomes"; -import { SceneBase } from "./scene-base"; -import CandyBar from "./ui/candy-bar"; -import { Variant, variantData } from "./data/variant"; +import { addUiThemeOverrides } from "#app/ui/ui-theme"; +import PokemonData from "#app/system/pokemon-data"; +import { Nature } from "#app/data/nature"; +import { FormChangeItem, pokemonFormChanges, SpeciesFormChange, SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger } from "#app/data/pokemon-forms"; +import { FormChangePhase } from "#app/phases/form-change-phase"; +import { getTypeRgb } from "#app/data/type"; +import PokemonSpriteSparkleHandler from "#app/field/pokemon-sprite-sparkle-handler"; +import CharSprite from "#app/ui/char-sprite"; +import DamageNumberHandler from "#app/field/damage-number-handler"; +import PokemonInfoContainer from "#app/ui/pokemon-info-container"; +import { biomeDepths, getBiomeName } from "#app/data/balance/biomes"; +import { SceneBase } from "#app/scene-base"; +import CandyBar from "#app/ui/candy-bar"; +import { Variant, variantData } from "#app/data/variant"; import { Localizable } from "#app/interfaces/locales"; import Overrides from "#app/overrides"; -import { InputsController } from "./inputs-controller"; -import { UiInputs } from "./ui-inputs"; -import { NewArenaEvent } from "./events/battle-scene"; -import { ArenaFlyout } from "./ui/arena-flyout"; +import { InputsController } from "#app/inputs-controller"; +import { UiInputs } from "#app/ui-inputs"; +import { NewArenaEvent } from "#app/events/battle-scene"; +import { ArenaFlyout } from "#app/ui/arena-flyout"; import { EaseType } from "#enums/ease-type"; import { BattleSpec } from "#enums/battle-spec"; import { BattleStyle } from "#enums/battle-style"; @@ -66,27 +66,27 @@ import { TimedEventManager } from "#app/timed-event-manager"; import { PokemonAnimType } from "#enums/pokemon-anim-type"; import i18next from "i18next"; import { TrainerType } from "#enums/trainer-type"; -import { battleSpecDialogue } from "./data/dialogue"; -import { LoadingScene } from "./loading-scene"; -import { LevelCapPhase } from "./phases/level-cap-phase"; -import { LoginPhase } from "./phases/login-phase"; -import { MessagePhase } from "./phases/message-phase"; -import { MovePhase } from "./phases/move-phase"; -import { NewBiomeEncounterPhase } from "./phases/new-biome-encounter-phase"; -import { NextEncounterPhase } from "./phases/next-encounter-phase"; -import { PokemonAnimPhase } from "./phases/pokemon-anim-phase"; -import { QuietFormChangePhase } from "./phases/quiet-form-change-phase"; -import { ReturnPhase } from "./phases/return-phase"; -import { SelectBiomePhase } from "./phases/select-biome-phase"; -import { ShowTrainerPhase } from "./phases/show-trainer-phase"; -import { SummonPhase } from "./phases/summon-phase"; -import { SwitchPhase } from "./phases/switch-phase"; -import { TitlePhase } from "./phases/title-phase"; -import { ToggleDoublePositionPhase } from "./phases/toggle-double-position-phase"; -import { TurnInitPhase } from "./phases/turn-init-phase"; -import { ShopCursorTarget } from "./enums/shop-cursor-target"; -import MysteryEncounter from "./data/mystery-encounters/mystery-encounter"; -import { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters"; +import { battleSpecDialogue } from "#app/data/dialogue"; +import { LoadingScene } from "#app/loading-scene"; +import { LevelCapPhase } from "#app/phases/level-cap-phase"; +import { LoginPhase } from "#app/phases/login-phase"; +import { MessagePhase } from "#app/phases/message-phase"; +import { MovePhase } from "#app/phases/move-phase"; +import { NewBiomeEncounterPhase } from "#app/phases/new-biome-encounter-phase"; +import { NextEncounterPhase } from "#app/phases/next-encounter-phase"; +import { PokemonAnimPhase } from "#app/phases/pokemon-anim-phase"; +import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; +import { ReturnPhase } from "#app/phases/return-phase"; +import { SelectBiomePhase } from "#app/phases/select-biome-phase"; +import { ShowTrainerPhase } from "#app/phases/show-trainer-phase"; +import { SummonPhase } from "#app/phases/summon-phase"; +import { SwitchPhase } from "#app/phases/switch-phase"; +import { TitlePhase } from "#app/phases/title-phase"; +import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase"; +import { TurnInitPhase } from "#app/phases/turn-init-phase"; +import { ShopCursorTarget } from "#app/enums/shop-cursor-target"; +import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; +import { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, mysteryEncountersByBiome } from "#app/data/mystery-encounters/mystery-encounters"; import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; @@ -94,7 +94,8 @@ import HeldModifierConfig from "#app/interfaces/held-modifier-config"; import { ExpPhase } from "#app/phases/exp-phase"; import { ShowPartyExpBarPhase } from "#app/phases/show-party-exp-bar-phase"; import { MysteryEncounterMode } from "#enums/mystery-encounter-mode"; -import { ExpGainsSpeed } from "./enums/exp-gains-speed"; +import { ExpGainsSpeed } from "#enums/exp-gains-speed"; +import { FRIENDSHIP_GAIN_FROM_BATTLE } from "#app/data/balance/starters"; export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1"; @@ -789,7 +790,7 @@ export default class BattleScene extends SceneBase { } getEnemyParty(): EnemyPokemon[] { - return this.currentBattle?.enemyParty || []; + return this.currentBattle?.enemyParty ?? []; } getEnemyPokemon(): EnemyPokemon | undefined { @@ -889,6 +890,9 @@ export default class BattleScene extends SceneBase { } const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource); + if (Overrides.OPP_FUSION_OVERRIDE) { + pokemon.generateFusionSpecies(); + } overrideModifiers(this, false); overrideHeldItems(this, pokemon, false); @@ -1187,10 +1191,7 @@ export default class BattleScene extends SceneBase { if (trainerConfigs[trainerType].doubleOnly) { doubleTrainer = true; } else if (trainerConfigs[trainerType].hasDouble) { - const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); - this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); - playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, false, doubleChance)); - doubleTrainer = !Utils.randSeedInt(doubleChance.value); + doubleTrainer = !Utils.randSeedInt(this.getDoubleBattleChance(newWaveIndex, playerField)); // Add a check that special trainers can't be double except for tate and liza - they should use the normal double chance if (trainerConfigs[trainerType].trainerTypeDouble && ![ TrainerType.TATE, TrainerType.LIZA ].includes(trainerType)) { doubleTrainer = false; @@ -1203,12 +1204,10 @@ export default class BattleScene extends SceneBase { // Check for mystery encounter // Can only occur in place of a standard (non-boss) wild battle, waves 10-180 - if (this.isWaveMysteryEncounter(newBattleType, newWaveIndex, mysteryEncounterType) || newBattleType === BattleType.MYSTERY_ENCOUNTER) { + if (this.isWaveMysteryEncounter(newBattleType, newWaveIndex) || newBattleType === BattleType.MYSTERY_ENCOUNTER) { newBattleType = BattleType.MYSTERY_ENCOUNTER; - // Reset base spawn weight + // Reset to base spawn weight this.mysteryEncounterSaveData.encounterSpawnChance = BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT; - } else if (newBattleType === BattleType.WILD) { - this.mysteryEncounterSaveData.encounterSpawnChance += WEIGHT_INCREMENT_ON_SPAWN_MISS; } } @@ -1261,7 +1260,7 @@ export default class BattleScene extends SceneBase { const isEndlessFifthWave = this.gameMode.hasShortBiomes && (lastBattle.waveIndex % 5) === 0; const isWaveIndexMultipleOfFiftyMinusOne = (lastBattle.waveIndex % 50) === 49; const isNewBiome = isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne); - const resetArenaState = isNewBiome || [BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.currentBattle.battleType) || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS; + const resetArenaState = isNewBiome || [ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.currentBattle.battleType) || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS; this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy()); this.trySpreadPokerus(); if (!isNewBiome && (newWaveIndex % 10) === 5) { @@ -1355,69 +1354,69 @@ export default class BattleScene extends SceneBase { } switch (species.speciesId) { - case Species.UNOWN: - case Species.SHELLOS: - case Species.GASTRODON: - case Species.BASCULIN: - case Species.DEERLING: - case Species.SAWSBUCK: - case Species.FROAKIE: - case Species.FROGADIER: - case Species.SCATTERBUG: - case Species.SPEWPA: - case Species.VIVILLON: - case Species.FLABEBE: - case Species.FLOETTE: - case Species.FLORGES: - case Species.FURFROU: - case Species.PUMPKABOO: - case Species.GOURGEIST: - case Species.ORICORIO: - case Species.MAGEARNA: - case Species.ZARUDE: - case Species.SQUAWKABILLY: - case Species.TATSUGIRI: - case Species.PALDEA_TAUROS: - return Utils.randSeedInt(species.forms.length); - case Species.PIKACHU: - return Utils.randSeedInt(8); - case Species.EEVEE: - return Utils.randSeedInt(2); - case Species.GRENINJA: - return Utils.randSeedInt(2); - case Species.ZYGARDE: - return Utils.randSeedInt(3); - case Species.MINIOR: - return Utils.randSeedInt(6); - case Species.ALCREMIE: - return Utils.randSeedInt(9); - case Species.MEOWSTIC: - case Species.INDEEDEE: - case Species.BASCULEGION: - case Species.OINKOLOGNE: - return gender === Gender.FEMALE ? 1 : 0; - case Species.TOXTRICITY: - const lowkeyNatures = [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ]; - if (nature !== undefined && lowkeyNatures.indexOf(nature) > -1) { - return 1; - } - return 0; - case Species.GIMMIGHOUL: - // Chest form can only be found in Mysterious Chest Encounter, if this is a game mode with MEs - if (this.gameMode.hasMysteryEncounters) { - return 1; // Wandering form - } else { + case Species.UNOWN: + case Species.SHELLOS: + case Species.GASTRODON: + case Species.BASCULIN: + case Species.DEERLING: + case Species.SAWSBUCK: + case Species.FROAKIE: + case Species.FROGADIER: + case Species.SCATTERBUG: + case Species.SPEWPA: + case Species.VIVILLON: + case Species.FLABEBE: + case Species.FLOETTE: + case Species.FLORGES: + case Species.FURFROU: + case Species.PUMPKABOO: + case Species.GOURGEIST: + case Species.ORICORIO: + case Species.MAGEARNA: + case Species.ZARUDE: + case Species.SQUAWKABILLY: + case Species.TATSUGIRI: + case Species.PALDEA_TAUROS: return Utils.randSeedInt(species.forms.length); - } + case Species.PIKACHU: + return Utils.randSeedInt(8); + case Species.EEVEE: + return Utils.randSeedInt(2); + case Species.GRENINJA: + return Utils.randSeedInt(2); + case Species.ZYGARDE: + return Utils.randSeedInt(4); + case Species.MINIOR: + return Utils.randSeedInt(7); + case Species.ALCREMIE: + return Utils.randSeedInt(9); + case Species.MEOWSTIC: + case Species.INDEEDEE: + case Species.BASCULEGION: + case Species.OINKOLOGNE: + return gender === Gender.FEMALE ? 1 : 0; + case Species.TOXTRICITY: + const lowkeyNatures = [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ]; + if (nature !== undefined && lowkeyNatures.indexOf(nature) > -1) { + return 1; + } + return 0; + case Species.GIMMIGHOUL: + // Chest form can only be found in Mysterious Chest Encounter, if this is a game mode with MEs + if (this.gameMode.hasMysteryEncounters) { + return 1; // Wandering form + } else { + return Utils.randSeedInt(species.forms.length); + } } if (ignoreArena) { switch (species.speciesId) { - case Species.BURMY: - case Species.WORMADAM: - case Species.ROTOM: - case Species.LYCANROC: - return Utils.randSeedInt(species.forms.length); + case Species.BURMY: + case Species.WORMADAM: + case Species.ROTOM: + case Species.LYCANROC: + return Utils.randSeedInt(species.forms.length); } return 0; } @@ -1758,14 +1757,14 @@ export default class BattleScene extends SceneBase { if (fromArenaPool) { return this.arena.randomSpecies(waveIndex, level, undefined, getPartyLuckValue(this.party)); } - const filteredSpecies = speciesFilter ? [...new Set(allSpecies.filter(s => s.isCatchable()).filter(speciesFilter).map(s => { + const filteredSpecies = speciesFilter ? [ ...new Set(allSpecies.filter(s => s.isCatchable()).filter(speciesFilter).map(s => { if (!filterAllEvolutions) { while (pokemonPrevolutions.hasOwnProperty(s.speciesId)) { s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]); } } return s; - }))] : allSpecies.filter(s => s.isCatchable()); + })) ] : allSpecies.filter(s => s.isCatchable()); return filteredSpecies[Utils.randSeedInt(filteredSpecies.length)]; } @@ -1882,17 +1881,17 @@ export default class BattleScene extends SceneBase { const soundDetails = sound.key.split("/"); switch (soundDetails[0]) { - case "battle_anims": - case "cry": - if (soundDetails[1].startsWith("PRSFX- ")) { - sound.setVolume(this.masterVolume*this.fieldVolume*0.5); - } else { - sound.setVolume(this.masterVolume*this.fieldVolume); - } - break; - case "se": - case "ui": - sound.setVolume(this.masterVolume*this.seVolume); + case "battle_anims": + case "cry": + if (soundDetails[1].startsWith("PRSFX- ")) { + sound.setVolume(this.masterVolume * this.fieldVolume * 0.5); + } else { + sound.setVolume(this.masterVolume * this.fieldVolume); + } + break; + case "se": + case "ui": + sound.setVolume(this.masterVolume * this.seVolume); } } } @@ -1932,31 +1931,31 @@ export default class BattleScene extends SceneBase { const keyDetails = key.split("/"); config["volume"] = config["volume"] ?? 1; switch (keyDetails[0]) { - case "level_up_fanfare": - case "item_fanfare": - case "minor_fanfare": - case "heal": - case "evolution": - case "evolution_fanfare": + case "level_up_fanfare": + case "item_fanfare": + case "minor_fanfare": + case "heal": + case "evolution": + case "evolution_fanfare": // These sounds are loaded in as BGM, but played as sound effects // When these sounds are updated in updateVolume(), they are treated as BGM however because they are placed in the BGM Cache through being called by playSoundWithoutBGM() - config["volume"] *= (this.masterVolume * this.bgmVolume); - break; - case "battle_anims": - case "cry": - config["volume"] *= (this.masterVolume * this.fieldVolume); - //PRSFX sound files are unusually loud - if (keyDetails[1].startsWith("PRSFX- ")) { - config["volume"] *= 0.5; - } - break; - case "ui": + config["volume"] *= (this.masterVolume * this.bgmVolume); + break; + case "battle_anims": + case "cry": + config["volume"] *= (this.masterVolume * this.fieldVolume); + //PRSFX sound files are unusually loud + if (keyDetails[1].startsWith("PRSFX- ")) { + config["volume"] *= 0.5; + } + break; + case "ui": //As of, right now this applies to the "select", "menu_open", "error" sound effects - config["volume"] *= (this.masterVolume * this.uiVolume); - break; - case "se": - config["volume"] *= (this.masterVolume * this.seVolume); - break; + config["volume"] *= (this.masterVolume * this.uiVolume); + break; + case "se": + config["volume"] *= (this.masterVolume * this.seVolume); + break; } this.sound.play(key, config); return this.sound.get(key) as AnySound; @@ -1985,208 +1984,208 @@ export default class BattleScene extends SceneBase { getBgmLoopPoint(bgmName: string): number { switch (bgmName) { - case "battle_kanto_champion": //B2W2 Kanto Champion Battle - return 13.950; - case "battle_johto_champion": //B2W2 Johto Champion Battle - return 23.498; - case "battle_hoenn_champion_g5": //B2W2 Hoenn Champion Battle - return 11.328; - case "battle_hoenn_champion_g6": //ORAS Hoenn Champion Battle - return 11.762; - case "battle_sinnoh_champion": //B2W2 Sinnoh Champion Battle - return 12.235; - case "battle_champion_alder": //BW Unova Champion Battle - return 27.653; - case "battle_champion_iris": //B2W2 Unova Champion Battle - return 10.145; - case "battle_kalos_champion": //XY Kalos Champion Battle - return 10.380; - case "battle_alola_champion": //USUM Alola Champion Battle - return 13.025; - case "battle_galar_champion": //SWSH Galar Champion Battle - return 61.635; - case "battle_champion_geeta": //SV Champion Geeta Battle - return 37.447; - case "battle_champion_nemona": //SV Champion Nemona Battle - return 14.914; - case "battle_champion_kieran": //SV Champion Kieran Battle - return 7.206; - case "battle_hoenn_elite": //ORAS Elite Four Battle - return 11.350; - case "battle_unova_elite": //BW Elite Four Battle - return 17.730; - case "battle_kalos_elite": //XY Elite Four Battle - return 12.340; - case "battle_alola_elite": //SM Elite Four Battle - return 19.212; - case "battle_galar_elite": //SWSH League Tournament Battle - return 164.069; - case "battle_paldea_elite": //SV Elite Four Battle - return 12.770; - case "battle_bb_elite": //SV BB League Elite Four Battle - return 19.434; - case "battle_final_encounter": //PMD RTDX Rayquaza's Domain - return 19.159; - case "battle_final": //BW Ghetsis Battle - return 16.453; - case "battle_kanto_gym": //B2W2 Kanto Gym Battle - return 13.857; - case "battle_johto_gym": //B2W2 Johto Gym Battle - return 12.911; - case "battle_hoenn_gym": //B2W2 Hoenn Gym Battle - return 12.379; - case "battle_sinnoh_gym": //B2W2 Sinnoh Gym Battle - return 13.122; - case "battle_unova_gym": //BW Unova Gym Battle - return 19.145; - case "battle_kalos_gym": //XY Kalos Gym Battle - return 44.810; - case "battle_galar_gym": //SWSH Galar Gym Battle - return 171.262; - case "battle_paldea_gym": //SV Paldea Gym Battle - return 127.489; - case "battle_legendary_kanto": //XY Kanto Legendary Battle - return 32.966; - case "battle_legendary_raikou": //HGSS Raikou Battle - return 12.632; - case "battle_legendary_entei": //HGSS Entei Battle - return 2.905; - case "battle_legendary_suicune": //HGSS Suicune Battle - return 12.636; - case "battle_legendary_lugia": //HGSS Lugia Battle - return 19.770; - case "battle_legendary_ho_oh": //HGSS Ho-oh Battle - return 17.668; - case "battle_legendary_regis_g5": //B2W2 Legendary Titan Battle - return 49.500; - case "battle_legendary_regis_g6": //ORAS Legendary Titan Battle - return 21.130; - case "battle_legendary_gro_kyo": //ORAS Groudon & Kyogre Battle - return 10.547; - case "battle_legendary_rayquaza": //ORAS Rayquaza Battle - return 10.495; - case "battle_legendary_deoxys": //ORAS Deoxys Battle - return 13.333; - case "battle_legendary_lake_trio": //ORAS Lake Guardians Battle - return 16.887; - case "battle_legendary_sinnoh": //ORAS Sinnoh Legendary Battle - return 22.770; - case "battle_legendary_dia_pal": //ORAS Dialga & Palkia Battle - return 16.009; - case "battle_legendary_origin_forme": //LA Origin Dialga & Palkia Battle - return 18.961; - case "battle_legendary_giratina": //ORAS Giratina Battle - return 10.451; - case "battle_legendary_arceus": //HGSS Arceus Battle - return 9.595; - case "battle_legendary_unova": //BW Unova Legendary Battle - return 13.855; - case "battle_legendary_kyurem": //BW Kyurem Battle - return 18.314; - case "battle_legendary_res_zek": //BW Reshiram & Zekrom Battle - return 18.329; - case "battle_legendary_xern_yvel": //XY Xerneas & Yveltal Battle - return 26.468; - case "battle_legendary_tapu": //SM Tapu Battle - return 0.000; - case "battle_legendary_sol_lun": //SM Solgaleo & Lunala Battle - return 6.525; - case "battle_legendary_ub": //SM Ultra Beast Battle - return 9.818; - case "battle_legendary_dusk_dawn": //USUM Dusk Mane & Dawn Wings Necrozma Battle - return 5.211; - case "battle_legendary_ultra_nec": //USUM Ultra Necrozma Battle - return 10.344; - case "battle_legendary_zac_zam": //SWSH Zacian & Zamazenta Battle - return 11.424; - case "battle_legendary_glas_spec": //SWSH Glastrier & Spectrier Battle - return 12.503; - case "battle_legendary_calyrex": //SWSH Calyrex Battle - return 50.641; - case "battle_legendary_riders": //SWSH Ice & Shadow Rider Calyrex Battle - return 18.155; - case "battle_legendary_birds_galar": //SWSH Galarian Legendary Birds Battle - return 0.175; - case "battle_legendary_ruinous": //SV Treasures of Ruin Battle - return 6.333; - case "battle_legendary_kor_mir": //SV Depths of Area Zero Battle - return 6.442; - case "battle_legendary_loyal_three": //SV Loyal Three Battle - return 6.500; - case "battle_legendary_ogerpon": //SV Ogerpon Battle - return 14.335; - case "battle_legendary_terapagos": //SV Terapagos Battle - return 24.377; - case "battle_legendary_pecharunt": //SV Pecharunt Battle - return 6.508; - case "battle_rival": //BW Rival Battle - return 14.110; - case "battle_rival_2": //BW N Battle - return 17.714; - case "battle_rival_3": //BW Final N Battle - return 17.586; - case "battle_trainer": //BW Trainer Battle - return 13.686; - case "battle_wild": //BW Wild Battle - return 12.703; - case "battle_wild_strong": //BW Strong Wild Battle - return 13.940; - case "end_summit": //PMD RTDX Sky Tower Summit - return 30.025; - case "battle_rocket_grunt": //HGSS Team Rocket Battle - return 12.707; - case "battle_aqua_magma_grunt": //ORAS Team Aqua & Magma Battle - return 12.062; - case "battle_galactic_grunt": //BDSP Team Galactic Battle - return 13.043; - case "battle_plasma_grunt": //BW Team Plasma Battle - return 12.974; - case "battle_flare_grunt": //XY Team Flare Battle - return 4.228; - case "battle_aether_grunt": // SM Aether Foundation Battle - return 16.00; - case "battle_skull_grunt": // SM Team Skull Battle - return 20.87; - case "battle_macro_grunt": // SWSH Trainer Battle - return 11.56; - case "battle_star_grunt": //SV Team Star Battle - return 133.362; - case "battle_galactic_admin": //BDSP Team Galactic Admin Battle - return 11.997; - case "battle_skull_admin": //SM Team Skull Admin Battle - return 15.463; - case "battle_oleana": //SWSH Oleana Battle - return 14.110; - case "battle_star_admin": //SV Team Star Boss Battle - return 9.493; - case "battle_rocket_boss": //USUM Giovanni Battle - return 9.115; - case "battle_aqua_magma_boss": //ORAS Archie & Maxie Battle - return 14.847; - case "battle_galactic_boss": //BDSP Cyrus Battle - return 106.962; - case "battle_plasma_boss": //B2W2 Ghetsis Battle - return 25.624; - case "battle_flare_boss": //XY Lysandre Battle - return 8.085; - case "battle_aether_boss": //SM Lusamine Battle - return 11.33; - case "battle_skull_boss": //SM Guzma Battle - return 13.13; - case "battle_macro_boss": //SWSH Rose Battle - return 11.42; - case "battle_star_boss": //SV Cassiopeia Battle - return 25.764; - case "mystery_encounter_gen_5_gts": // BW GTS - return 8.52; - case "mystery_encounter_gen_6_gts": // XY GTS - return 9.24; - case "mystery_encounter_fun_and_games": // EoS Guildmaster Wigglytuff - return 4.78; - case "mystery_encounter_weird_dream": // EoS Temporal Spire - return 41.42; - case "mystery_encounter_delibirdy": // Firel Delibirdy - return 82.28; + case "battle_kanto_champion": //B2W2 Kanto Champion Battle + return 13.950; + case "battle_johto_champion": //B2W2 Johto Champion Battle + return 23.498; + case "battle_hoenn_champion_g5": //B2W2 Hoenn Champion Battle + return 11.328; + case "battle_hoenn_champion_g6": //ORAS Hoenn Champion Battle + return 11.762; + case "battle_sinnoh_champion": //B2W2 Sinnoh Champion Battle + return 12.235; + case "battle_champion_alder": //BW Unova Champion Battle + return 27.653; + case "battle_champion_iris": //B2W2 Unova Champion Battle + return 10.145; + case "battle_kalos_champion": //XY Kalos Champion Battle + return 10.380; + case "battle_alola_champion": //USUM Alola Champion Battle + return 13.025; + case "battle_galar_champion": //SWSH Galar Champion Battle + return 61.635; + case "battle_champion_geeta": //SV Champion Geeta Battle + return 37.447; + case "battle_champion_nemona": //SV Champion Nemona Battle + return 14.914; + case "battle_champion_kieran": //SV Champion Kieran Battle + return 7.206; + case "battle_hoenn_elite": //ORAS Elite Four Battle + return 11.350; + case "battle_unova_elite": //BW Elite Four Battle + return 17.730; + case "battle_kalos_elite": //XY Elite Four Battle + return 12.340; + case "battle_alola_elite": //SM Elite Four Battle + return 19.212; + case "battle_galar_elite": //SWSH League Tournament Battle + return 164.069; + case "battle_paldea_elite": //SV Elite Four Battle + return 12.770; + case "battle_bb_elite": //SV BB League Elite Four Battle + return 19.434; + case "battle_final_encounter": //PMD RTDX Rayquaza's Domain + return 19.159; + case "battle_final": //BW Ghetsis Battle + return 16.453; + case "battle_kanto_gym": //B2W2 Kanto Gym Battle + return 13.857; + case "battle_johto_gym": //B2W2 Johto Gym Battle + return 12.911; + case "battle_hoenn_gym": //B2W2 Hoenn Gym Battle + return 12.379; + case "battle_sinnoh_gym": //B2W2 Sinnoh Gym Battle + return 13.122; + case "battle_unova_gym": //BW Unova Gym Battle + return 19.145; + case "battle_kalos_gym": //XY Kalos Gym Battle + return 44.810; + case "battle_galar_gym": //SWSH Galar Gym Battle + return 171.262; + case "battle_paldea_gym": //SV Paldea Gym Battle + return 127.489; + case "battle_legendary_kanto": //XY Kanto Legendary Battle + return 32.966; + case "battle_legendary_raikou": //HGSS Raikou Battle + return 12.632; + case "battle_legendary_entei": //HGSS Entei Battle + return 2.905; + case "battle_legendary_suicune": //HGSS Suicune Battle + return 12.636; + case "battle_legendary_lugia": //HGSS Lugia Battle + return 19.770; + case "battle_legendary_ho_oh": //HGSS Ho-oh Battle + return 17.668; + case "battle_legendary_regis_g5": //B2W2 Legendary Titan Battle + return 49.500; + case "battle_legendary_regis_g6": //ORAS Legendary Titan Battle + return 21.130; + case "battle_legendary_gro_kyo": //ORAS Groudon & Kyogre Battle + return 10.547; + case "battle_legendary_rayquaza": //ORAS Rayquaza Battle + return 10.495; + case "battle_legendary_deoxys": //ORAS Deoxys Battle + return 13.333; + case "battle_legendary_lake_trio": //ORAS Lake Guardians Battle + return 16.887; + case "battle_legendary_sinnoh": //ORAS Sinnoh Legendary Battle + return 22.770; + case "battle_legendary_dia_pal": //ORAS Dialga & Palkia Battle + return 16.009; + case "battle_legendary_origin_forme": //LA Origin Dialga & Palkia Battle + return 18.961; + case "battle_legendary_giratina": //ORAS Giratina Battle + return 10.451; + case "battle_legendary_arceus": //HGSS Arceus Battle + return 9.595; + case "battle_legendary_unova": //BW Unova Legendary Battle + return 13.855; + case "battle_legendary_kyurem": //BW Kyurem Battle + return 18.314; + case "battle_legendary_res_zek": //BW Reshiram & Zekrom Battle + return 18.329; + case "battle_legendary_xern_yvel": //XY Xerneas & Yveltal Battle + return 26.468; + case "battle_legendary_tapu": //SM Tapu Battle + return 0.000; + case "battle_legendary_sol_lun": //SM Solgaleo & Lunala Battle + return 6.525; + case "battle_legendary_ub": //SM Ultra Beast Battle + return 9.818; + case "battle_legendary_dusk_dawn": //USUM Dusk Mane & Dawn Wings Necrozma Battle + return 5.211; + case "battle_legendary_ultra_nec": //USUM Ultra Necrozma Battle + return 10.344; + case "battle_legendary_zac_zam": //SWSH Zacian & Zamazenta Battle + return 11.424; + case "battle_legendary_glas_spec": //SWSH Glastrier & Spectrier Battle + return 12.503; + case "battle_legendary_calyrex": //SWSH Calyrex Battle + return 50.641; + case "battle_legendary_riders": //SWSH Ice & Shadow Rider Calyrex Battle + return 18.155; + case "battle_legendary_birds_galar": //SWSH Galarian Legendary Birds Battle + return 0.175; + case "battle_legendary_ruinous": //SV Treasures of Ruin Battle + return 6.333; + case "battle_legendary_kor_mir": //SV Depths of Area Zero Battle + return 6.442; + case "battle_legendary_loyal_three": //SV Loyal Three Battle + return 6.500; + case "battle_legendary_ogerpon": //SV Ogerpon Battle + return 14.335; + case "battle_legendary_terapagos": //SV Terapagos Battle + return 24.377; + case "battle_legendary_pecharunt": //SV Pecharunt Battle + return 6.508; + case "battle_rival": //BW Rival Battle + return 14.110; + case "battle_rival_2": //BW N Battle + return 17.714; + case "battle_rival_3": //BW Final N Battle + return 17.586; + case "battle_trainer": //BW Trainer Battle + return 13.686; + case "battle_wild": //BW Wild Battle + return 12.703; + case "battle_wild_strong": //BW Strong Wild Battle + return 13.940; + case "end_summit": //PMD RTDX Sky Tower Summit + return 30.025; + case "battle_rocket_grunt": //HGSS Team Rocket Battle + return 12.707; + case "battle_aqua_magma_grunt": //ORAS Team Aqua & Magma Battle + return 12.062; + case "battle_galactic_grunt": //BDSP Team Galactic Battle + return 13.043; + case "battle_plasma_grunt": //BW Team Plasma Battle + return 12.974; + case "battle_flare_grunt": //XY Team Flare Battle + return 4.228; + case "battle_aether_grunt": // SM Aether Foundation Battle + return 16.00; + case "battle_skull_grunt": // SM Team Skull Battle + return 20.87; + case "battle_macro_grunt": // SWSH Trainer Battle + return 11.56; + case "battle_star_grunt": //SV Team Star Battle + return 133.362; + case "battle_galactic_admin": //BDSP Team Galactic Admin Battle + return 11.997; + case "battle_skull_admin": //SM Team Skull Admin Battle + return 15.463; + case "battle_oleana": //SWSH Oleana Battle + return 14.110; + case "battle_star_admin": //SV Team Star Boss Battle + return 9.493; + case "battle_rocket_boss": //USUM Giovanni Battle + return 9.115; + case "battle_aqua_magma_boss": //ORAS Archie & Maxie Battle + return 14.847; + case "battle_galactic_boss": //BDSP Cyrus Battle + return 106.962; + case "battle_plasma_boss": //B2W2 Ghetsis Battle + return 25.624; + case "battle_flare_boss": //XY Lysandre Battle + return 8.085; + case "battle_aether_boss": //SM Lusamine Battle + return 11.33; + case "battle_skull_boss": //SM Guzma Battle + return 13.13; + case "battle_macro_boss": //SWSH Rose Battle + return 11.42; + case "battle_star_boss": //SV Cassiopeia Battle + return 25.764; + case "mystery_encounter_gen_5_gts": // BW GTS + return 8.52; + case "mystery_encounter_gen_6_gts": // XY GTS + return 9.24; + case "mystery_encounter_fun_and_games": // EoS Guildmaster Wigglytuff + return 4.78; + case "mystery_encounter_weird_dream": // EoS Temporal Spire + return 41.42; + case "mystery_encounter_delibirdy": // Firel Delibirdy + return 82.28; } return 0; @@ -2221,7 +2220,7 @@ export default class BattleScene extends SceneBase { * */ pushConditionalPhase(phase: Phase, condition: () => boolean): void { - this.conditionalQueue.push([condition, phase]); + this.conditionalQueue.push([ condition, phase ]); } /** @@ -2313,7 +2312,10 @@ export default class BattleScene extends SceneBase { } } - this.currentPhase?.start(); + if (this.currentPhase) { + console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;"); + this.currentPhase.start(); + } } overridePhase(phase: Phase): boolean { @@ -2323,6 +2325,7 @@ export default class BattleScene extends SceneBase { this.standbyPhase = this.currentPhase; this.currentPhase = phase; + console.log(`%cStart Phase ${phase.constructor.name}`, "color:green;"); phase.start(); return true; @@ -2356,15 +2359,17 @@ export default class BattleScene extends SceneBase { return false; } - pushMovePhase(movePhase: MovePhase, priorityOverride?: integer): void { - const movePriority = new Utils.IntegerHolder(priorityOverride !== undefined ? priorityOverride : movePhase.move.getMove().priority); - applyAbAttrs(ChangeMovePriorityAbAttr, movePhase.pokemon, null, false, movePhase.move.getMove(), movePriority); - const lowerPriorityPhase = this.phaseQueue.find(p => p instanceof MovePhase && p.move.getMove().priority < movePriority.value); - if (lowerPriorityPhase) { - this.phaseQueue.splice(this.phaseQueue.indexOf(lowerPriorityPhase), 0, movePhase); - } else { - this.pushPhase(movePhase); + /** + * Will search for a specific phase in {@linkcode phaseQueuePrepend} via filter, and remove the first result if a match is found. + * @param phaseFilter filter function + */ + tryRemoveUnshiftedPhase(phaseFilter: (phase: Phase) => boolean): boolean { + const phaseIndex = this.phaseQueuePrepend.findIndex(phaseFilter); + if (phaseIndex > -1) { + this.phaseQueuePrepend.splice(phaseIndex, 1); + return true; } + return false; } /** @@ -2429,7 +2434,7 @@ export default class BattleScene extends SceneBase { return Math.floor(moneyValue / 10) * 10; } - addModifier(modifier: Modifier | null, ignoreUpdate?: boolean, playSound?: boolean, virtual?: boolean, instant?: boolean): Promise { + addModifier(modifier: Modifier | null, ignoreUpdate?: boolean, playSound?: boolean, virtual?: boolean, instant?: boolean, cost?: number): Promise { if (!modifier) { return Promise.resolve(false); } @@ -2445,7 +2450,10 @@ export default class BattleScene extends SceneBase { } if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) { if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) { - success = modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]); + const pokemon = this.getPokemonById(modifier.pokemonId); + if (pokemon) { + success = modifier.apply(pokemon, true); + } } if (playSound && !this.sound.get(soundName)) { this.playSound(soundName); @@ -2472,7 +2480,7 @@ export default class BattleScene extends SceneBase { for (const p in this.party) { const pokemon = this.party[p]; - const args: any[] = [ pokemon ]; + const args: unknown[] = []; if (modifier instanceof PokemonHpRestoreModifier) { if (!(modifier as PokemonHpRestoreModifier).fainted) { const hpRestoreMultiplier = new Utils.IntegerHolder(1); @@ -2483,10 +2491,12 @@ export default class BattleScene extends SceneBase { } } else if (modifier instanceof FusePokemonModifier) { args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon); + } else if (modifier instanceof RememberMoveModifier && !Utils.isNullOrUndefined(cost)) { + args.push(cost); } - if (modifier.shouldApply(args)) { - const result = modifier.apply(args); + if (modifier.shouldApply(pokemon, ...args)) { + const result = modifier.apply(pokemon, ...args); if (result instanceof Promise) { modifierPromises.push(result.then(s => success ||= s)); } else { @@ -2495,11 +2505,11 @@ export default class BattleScene extends SceneBase { } } - return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success)); + return Promise.allSettled([ this.party.map(p => p.updateInfo(instant)), ...modifierPromises ]).then(() => resolve(success)); } else { const args = [ this ]; - if (modifier.shouldApply(args)) { - const result = modifier.apply(args); + if (modifier.shouldApply(...args)) { + const result = modifier.apply(...args); if (result instanceof Promise) { return result.then(success => resolve(success)); } else { @@ -2521,7 +2531,10 @@ export default class BattleScene extends SceneBase { } if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) { if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) { - modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]); + const pokemon = this.getPokemonById(modifier.pokemonId); + if (pokemon) { + modifier.apply(pokemon, true); + } } for (const rm of modifiersToRemove) { this.removeModifier(rm, true); @@ -2678,7 +2691,7 @@ export default class BattleScene extends SceneBase { } /** - * Removes all modifiers from enemy of PersistentModifier type + * Removes all modifiers from enemy pokemon of {@linkcode PersistentModifier} type */ clearEnemyModifiers(): void { const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PersistentModifier); @@ -2689,10 +2702,11 @@ export default class BattleScene extends SceneBase { } /** - * Removes all modifiers from enemy of PokemonHeldItemModifier type + * Removes all modifiers from enemy pokemon of {@linkcode PokemonHeldItemModifier} type + * @param pokemon - If specified, only removes held items from that {@linkcode Pokemon} */ - clearEnemyHeldItemModifiers(): void { - const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PokemonHeldItemModifier); + clearEnemyHeldItemModifiers(pokemon?: Pokemon): void { + const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PokemonHeldItemModifier && (!pokemon || m.getPokemon(this) === pokemon)); for (const m of modifiersToRemove) { this.enemyModifiers.splice(this.enemyModifiers.indexOf(m), 1); } @@ -2755,7 +2769,10 @@ export default class BattleScene extends SceneBase { if (modifierIndex > -1) { modifiers.splice(modifierIndex, 1); if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) { - modifier.apply([ this.getPokemonById(modifier.pokemonId), false ]); + const pokemon = this.getPokemonById(modifier.pokemonId); + if (pokemon) { + modifier.apply(pokemon, false); + } } return true; } @@ -2773,38 +2790,66 @@ export default class BattleScene extends SceneBase { return (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType); } - findModifiers(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier[] { - return (player ? this.modifiers : this.enemyModifiers).filter(m => (modifierFilter as ModifierPredicate)(m)); + /** + * Get all of the modifiers that pass the `modifierFilter` function + * @param modifierFilter The function used to filter a target's modifiers + * @param isPlayer Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` + * @returns the list of all modifiers that passed the `modifierFilter` function + */ + findModifiers(modifierFilter: ModifierPredicate, isPlayer: boolean = true): PersistentModifier[] { + return (isPlayer ? this.modifiers : this.enemyModifiers).filter(modifierFilter); } + /** + * Find the first modifier that pass the `modifierFilter` function + * @param modifierFilter The function used to filter a target's modifiers + * @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` + * @returns the first modifier that passed the `modifierFilter` function; `undefined` if none passed + */ findModifier(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier | undefined { - return (player ? this.modifiers : this.enemyModifiers).find(m => (modifierFilter as ModifierPredicate)(m)); + return (player ? this.modifiers : this.enemyModifiers).find(modifierFilter); } - applyShuffledModifiers(scene: BattleScene, modifierType: Constructor, player: boolean = true, ...args: any[]): PersistentModifier[] { - let modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args)); + /** + * Apply all modifiers that match `modifierType` in a random order + * @param scene {@linkcode BattleScene} used to randomize the order of modifiers + * @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier} + * @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` + * @param ...args The list of arguments needed to invoke `modifierType.apply` + * @returns the list of all modifiers that matched `modifierType` and were applied. + */ + applyShuffledModifiers(scene: BattleScene, modifierType: Constructor, player: boolean = true, ...args: Parameters): T[] { + let modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args)); scene.executeWithSeedOffset(() => { const shuffleModifiers = mods => { if (mods.length < 1) { return mods; } const rand = Utils.randSeedInt(mods.length); - return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))]; + return [ mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand)) ]; }; modifiers = shuffleModifiers(modifiers); }, scene.currentBattle.turn << 4, scene.waveSeed); return this.applyModifiersInternal(modifiers, player, args); } - applyModifiers(modifierType: Constructor, player: boolean = true, ...args: any[]): PersistentModifier[] { - const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args)); + /** + * Apply all modifiers that match `modifierType` + * @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier} + * @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` + * @param ...args The list of arguments needed to invoke `modifierType.apply` + * @returns the list of all modifiers that matched `modifierType` and were applied. + */ + applyModifiers(modifierType: Constructor, player: boolean = true, ...args: Parameters): T[] { + const modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args)); return this.applyModifiersInternal(modifiers, player, args); } - applyModifiersInternal(modifiers: PersistentModifier[], player: boolean, args: any[]): PersistentModifier[] { - const appliedModifiers: PersistentModifier[] = []; + /** Helper function to apply all passed modifiers */ + applyModifiersInternal(modifiers: T[], player: boolean, args: Parameters): T[] { + const appliedModifiers: T[] = []; for (const modifier of modifiers) { - if (modifier.apply(args)) { + if (modifier.apply(...args)) { console.log("Applied", modifier.type.name, !player ? "(enemy)" : ""); appliedModifiers.push(modifier); } @@ -2813,10 +2858,17 @@ export default class BattleScene extends SceneBase { return appliedModifiers; } - applyModifier(modifierType: Constructor, player: boolean = true, ...args: any[]): PersistentModifier | null { - const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args)); + /** + * Apply the first modifier that matches `modifierType` + * @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier} + * @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` + * @param ...args The list of arguments needed to invoke `modifierType.apply` + * @returns the first modifier that matches `modifierType` and was applied; return `null` if none matched + */ + applyModifier(modifierType: Constructor, player: boolean = true, ...args: Parameters): T | null { + const modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args)); for (const modifier of modifiers) { - if (modifier.apply(args)) { + if (modifier.apply(...args)) { console.log("Applied", modifier.type.name, !player ? "(enemy)" : ""); return modifier; } @@ -2882,7 +2934,7 @@ export default class BattleScene extends SceneBase { } } - validateAchv(achv: Achv, args?: any[]): boolean { + validateAchv(achv: Achv, args?: unknown[]): boolean { if (!this.gameData.achvUnlocks.hasOwnProperty(achv.id) && achv.validate(this, args)) { this.gameData.achvUnlocks[achv.id] = new Date().getTime(); this.ui.achvBar.showAchv(achv); @@ -2895,7 +2947,7 @@ export default class BattleScene extends SceneBase { return false; } - validateVoucher(voucher: Voucher, args?: any[]): boolean { + validateVoucher(voucher: Voucher, args?: unknown[]): boolean { if (!this.gameData.voucherUnlocks.hasOwnProperty(voucher.id) && voucher.validate(this, args)) { this.gameData.voucherUnlocks[voucher.id] = new Date().getTime(); this.ui.achvBar.showAchv(voucher); @@ -2934,7 +2986,7 @@ export default class BattleScene extends SceneBase { keys.push(p.getBattleSpriteKey(true, true)); keys.push("cry/" + p.species.getCryKey(p.formIndex)); if (p.fusionSpecies) { - keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex)); + keys.push("cry/" + p.fusionSpecies.getCryKey(p.fusionFormIndex)); } }); // enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon @@ -2943,7 +2995,7 @@ export default class BattleScene extends SceneBase { keys.push(p.getSpriteKey(true)); keys.push("cry/" + p.species.getCryKey(p.formIndex)); if (p.fusionSpecies) { - keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex)); + keys.push("cry/" + p.fusionSpecies.getCryKey(p.fusionFormIndex)); } }); return keys; @@ -3011,7 +3063,7 @@ export default class BattleScene extends SceneBase { const pId = partyMember.id; const participated = participantIds.has(pId); if (participated && pokemonDefeated) { - partyMember.addFriendship(2); + partyMember.addFriendship(FRIENDSHIP_GAIN_FROM_BATTLE); const machoBraceModifier = partyMember.getHeldItems().find(m => m instanceof PokemonIncrementingStatModifier); if (machoBraceModifier && machoBraceModifier.stackCount < machoBraceModifier.getMaxStackCount(this)) { machoBraceModifier.stackCount++; @@ -3081,18 +3133,26 @@ export default class BattleScene extends SceneBase { } } + /** + * Returns if a wave COULD spawn a {@linkcode MysteryEncounter}. + * Even if returns `true`, does not guarantee that a wave will actually be a ME. + * That check is made in {@linkcode BattleScene.isWaveMysteryEncounter} instead. + */ + isMysteryEncounterValidForWave(battleType: BattleType, waveIndex: number): boolean { + const [ lowestMysteryEncounterWave, highestMysteryEncounterWave ] = this.gameMode.getMysteryEncounterLegalWaves(); + return this.gameMode.hasMysteryEncounters && battleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave; + } + /** * Determines whether a wave should randomly generate a {@linkcode MysteryEncounter}. * Currently, the only modes that MEs are allowed in are Classic and Challenge. * Additionally, MEs cannot spawn outside of waves 10-180 in those modes - * * @param newBattleType * @param waveIndex - * @param sessionDataEncounterType */ - private isWaveMysteryEncounter(newBattleType: BattleType, waveIndex: number, sessionDataEncounterType?: MysteryEncounterType): boolean { - const [lowestMysteryEncounterWave, highestMysteryEncounterWave] = this.gameMode.getMysteryEncounterLegalWaves(); - if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave) { + private isWaveMysteryEncounter(newBattleType: BattleType, waveIndex: number): boolean { + const [ lowestMysteryEncounterWave, highestMysteryEncounterWave ] = this.gameMode.getMysteryEncounterLegalWaves(); + if (this.isMysteryEncounterValidForWave(newBattleType, waveIndex)) { // Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance; const encounteredEvents = this.mysteryEncounterSaveData.encounteredEvents; @@ -3125,13 +3185,20 @@ export default class BattleScene extends SceneBase { /** * Loads or generates a mystery encounter * @param encounterType used to load session encounter when restarting game, etc. + * @param canBypass optional boolean to indicate that the request is coming from a function that needs to access a Mystery Encounter outside of gameplay requirements * @returns */ - getMysteryEncounter(encounterType?: MysteryEncounterType): MysteryEncounter { + getMysteryEncounter(encounterType?: MysteryEncounterType, canBypass?: boolean): MysteryEncounter { // Loading override or session encounter let encounter: MysteryEncounter | null; if (!isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_OVERRIDE) && allMysteryEncounters.hasOwnProperty(Overrides.MYSTERY_ENCOUNTER_OVERRIDE)) { encounter = allMysteryEncounters[Overrides.MYSTERY_ENCOUNTER_OVERRIDE]; + if (canBypass) { + return encounter; + } + } else if (canBypass) { + encounter = allMysteryEncounters[encounterType ?? -1]; + return encounter; } else { encounter = !isNullOrUndefined(encounterType) ? allMysteryEncounters[encounterType] : null; } @@ -3157,7 +3224,7 @@ export default class BattleScene extends SceneBase { } // See Enum values for base tier weights - const tierWeights = [MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE]; + const tierWeights = [ MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE ]; // Adjust tier weights by previously encountered events to lower odds of only Common/Great in run this.mysteryEncounterSaveData.encounteredEvents.forEach(seenEncounterData => { diff --git a/src/battle.ts b/src/battle.ts index 412fd1b5184..6086c2ceb4e 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -497,7 +497,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand } /* 1/3 chance for evil team grunts to be double battles */ - const evilTeamGrunts = [TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT]; + const evilTeamGrunts = [ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ]; const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]); if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) { @@ -527,34 +527,34 @@ export const classicFixedBattles: FixedBattleConfigs = { .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), [25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) - .setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }), + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }), [35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)), [55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) - .setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }), + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }), [62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)), [64]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)), [66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) - .setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ] ], true)), + .setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true)), [95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) - .setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }), + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }), [112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)), [114]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) - .setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ] ], true, 1)), + .setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true, 1)), [ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE, TrainerType.PENNY ])) - .setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }), + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }), [145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) - .setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }), + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }), [ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2, TrainerType.PENNY_2 ])) - .setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }), + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }), [182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])), [184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) @@ -567,5 +567,5 @@ export const classicFixedBattles: FixedBattleConfigs = { .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])), [195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) - .setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }) + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }) }; diff --git a/src/configs/inputs/cfg_keyboard_qwerty.ts b/src/configs/inputs/cfg_keyboard_qwerty.ts index 09a02f02836..5ddc12e8784 100644 --- a/src/configs/inputs/cfg_keyboard_qwerty.ts +++ b/src/configs/inputs/cfg_keyboard_qwerty.ts @@ -1,5 +1,5 @@ -import {Button} from "#enums/buttons"; -import {SettingKeyboard} from "#app/system/settings/settings-keyboard"; +import { Button } from "#enums/buttons"; +import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; const cfg_keyboard_qwerty = { padID: "default", diff --git a/src/configs/inputs/configHandler.ts b/src/configs/inputs/configHandler.ts index 45fb033e9fa..50be692cbc3 100644 --- a/src/configs/inputs/configHandler.ts +++ b/src/configs/inputs/configHandler.ts @@ -1,4 +1,4 @@ -import {Device} from "#enums/devices"; +import { Device } from "#enums/devices"; /** * Retrieves the key associated with the specified keycode from the mapping. diff --git a/src/configs/inputs/pad_dualshock.ts b/src/configs/inputs/pad_dualshock.ts index 742040958b4..2fbdd0ddfaa 100644 --- a/src/configs/inputs/pad_dualshock.ts +++ b/src/configs/inputs/pad_dualshock.ts @@ -1,5 +1,5 @@ -import {SettingGamepad} from "../../system/settings/settings-gamepad"; -import {Button} from "#enums/buttons"; +import { SettingGamepad } from "../../system/settings/settings-gamepad"; +import { Button } from "#enums/buttons"; /** * Dualshock mapping diff --git a/src/configs/inputs/pad_generic.ts b/src/configs/inputs/pad_generic.ts index 88ff66e231c..256af8f0fe3 100644 --- a/src/configs/inputs/pad_generic.ts +++ b/src/configs/inputs/pad_generic.ts @@ -1,5 +1,5 @@ -import {SettingGamepad} from "../../system/settings/settings-gamepad"; -import {Button} from "#enums/buttons"; +import { SettingGamepad } from "../../system/settings/settings-gamepad"; +import { Button } from "#enums/buttons"; /** * Generic pad mapping diff --git a/src/configs/inputs/pad_procon.ts b/src/configs/inputs/pad_procon.ts index be751cc3acc..98d17c4ef57 100644 --- a/src/configs/inputs/pad_procon.ts +++ b/src/configs/inputs/pad_procon.ts @@ -1,5 +1,5 @@ -import {SettingGamepad} from "#app/system/settings/settings-gamepad"; -import {Button} from "#enums/buttons"; +import { SettingGamepad } from "#app/system/settings/settings-gamepad"; +import { Button } from "#enums/buttons"; /** * Nintendo Pro Controller mapping diff --git a/src/configs/inputs/pad_unlicensedSNES.ts b/src/configs/inputs/pad_unlicensedSNES.ts index 8a7f3e78f98..77e68e6a644 100644 --- a/src/configs/inputs/pad_unlicensedSNES.ts +++ b/src/configs/inputs/pad_unlicensedSNES.ts @@ -1,5 +1,5 @@ -import {SettingGamepad} from "../../system/settings/settings-gamepad"; -import {Button} from "#enums/buttons"; +import { SettingGamepad } from "../../system/settings/settings-gamepad"; +import { Button } from "#enums/buttons"; /** * 081f-e401 - UnlicensedSNES diff --git a/src/configs/inputs/pad_xbox360.ts b/src/configs/inputs/pad_xbox360.ts index e003ccc8e87..6afc452f50b 100644 --- a/src/configs/inputs/pad_xbox360.ts +++ b/src/configs/inputs/pad_xbox360.ts @@ -1,5 +1,5 @@ -import {SettingGamepad} from "../../system/settings/settings-gamepad"; -import {Button} from "#enums/buttons"; +import { SettingGamepad } from "../../system/settings/settings-gamepad"; +import { Button } from "#enums/buttons"; /** * Generic pad mapping diff --git a/src/data/ability.ts b/src/data/ability.ts index 8a7365b2c28..3c73bb47c47 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -7,7 +7,7 @@ import { Weather, WeatherType } from "./weather"; import { BattlerTag, GroundedTag } from "./battler-tags"; import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { Gender } from "./gender"; -import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, ChargeAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move"; +import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { BerryModifier, PokemonHeldItemModifier } from "../modifier/modifier"; import { TerrainType } from "./terrain"; @@ -118,6 +118,14 @@ export class Ability implements Localizable { this.nameAppend += " (N)"; return this; } + + /** + * Internal flag used for developers to document edge cases. When using this, please be sure to document the edge case. + * @returns the ability + */ + edgeCase(): this { + return this; + } } type AbAttrApplyFunc = (attr: TAttr, passive: boolean) => boolean | Promise; @@ -162,7 +170,7 @@ export class BlockRecoilDamageAttr extends AbAttr { } getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) { - return i18next.t("abilityTriggers:blockRecoilDamage", {pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName}); + return i18next.t("abilityTriggers:blockRecoilDamage", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName }); } } @@ -322,6 +330,30 @@ export class ReceivedMoveDamageMultiplierAbAttr extends PreDefendAbAttr { } } +/** + * Reduces the damage dealt to an allied Pokemon. Used by Friend Guard. + * @see {@linkcode applyPreDefend} + */ +export class AlliedFieldDamageReductionAbAttr extends PreDefendAbAttr { + private damageMultiplier: number; + + constructor(damageMultiplier: number) { + super(); + this.damageMultiplier = damageMultiplier; + } + + /** + * Handles the damage reduction + * @param args + * - `[0]` {@linkcode Utils.NumberHolder} - The damage being dealt + */ + override applyPreDefend(_pokemon: Pokemon, _passive: boolean, _simulated: boolean, _attacker: Pokemon, _move: Move, _cancelled: Utils.BooleanHolder, args: any[]): boolean { + const damage = args[0] as Utils.NumberHolder; + damage.value = Utils.toDmgValue(damage.value * this.damageMultiplier); + return true; + } +} + export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultiplierAbAttr { constructor(moveType: Type, damageMultiplier: number) { super((target, user, move) => user.getMoveType(move) === moveType, damageMultiplier); @@ -634,15 +666,15 @@ export class ReverseDrainAbAttr extends PostDefendAbAttr { * Examples include: Absorb, Draining Kiss, Bitter Blade, etc. * Also displays a message to show this ability was activated. * @param pokemon {@linkcode Pokemon} with this ability - * @param passive N/A + * @param _passive N/A * @param attacker {@linkcode Pokemon} that is attacking this Pokemon * @param move {@linkcode PokemonMove} that is being used - * @param hitResult N/A - * @args N/A + * @param _hitResult N/A + * @param _args N/A * @returns true if healing should be reversed on a healing move, false otherwise. */ - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.hasAttr(HitHealAttr)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.hasAttr(HitHealAttr) && !move.hitsSubstitute(attacker, pokemon)) { if (!simulated) { pokemon.scene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) })); } @@ -669,8 +701,8 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr { this.allOthers = allOthers; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (this.condition(pokemon, attacker, move)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) { if (simulated) { return true; } @@ -707,13 +739,13 @@ export class PostDefendHpGatedStatStageChangeAbAttr extends PostDefendAbAttr { this.selfTarget = selfTarget; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate); + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + const hpGateFlat: number = Math.ceil(pokemon.getMaxHp() * this.hpGate); const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1]; const damageReceived = lastAttackReceived?.damage || 0; - if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat)) { - if (!simulated ) { + if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat) && !move.hitsSubstitute(attacker, pokemon)) { + if (!simulated) { pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages)); } return true; @@ -734,8 +766,8 @@ export class PostDefendApplyArenaTrapTagAbAttr extends PostDefendAbAttr { this.tagType = tagType; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (this.condition(pokemon, attacker, move)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) { const tag = pokemon.scene.arena.getTag(this.tagType) as ArenaTrapTag; if (!pokemon.scene.arena.getTag(this.tagType) || tag.layers < tag.maxLayers) { if (!simulated) { @@ -758,8 +790,8 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr { this.tagType = tagType; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (this.condition(pokemon, attacker, move)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) { if (!pokemon.getTag(this.tagType) && !simulated) { pokemon.addTag(this.tagType, undefined, undefined, pokemon.id); pokemon.scene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name })); @@ -771,8 +803,8 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr { } export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr { - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (hitResult < HitResult.NO_EFFECT) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean { + if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) { if (simulated) { return true; } @@ -787,7 +819,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:postDefendTypeChange", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName, @@ -805,8 +837,8 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr { this.terrainType = terrainType; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (hitResult < HitResult.NO_EFFECT) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean { + if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) { if (simulated) { return pokemon.scene.arena.terrain?.terrainType !== (this.terrainType || undefined); } else { @@ -829,8 +861,9 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr { this.effects = effects; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status + && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !move.hitsSubstitute(attacker, pokemon)) { const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; if (simulated) { return attacker.canSetStatus(effect, true, false, pokemon); @@ -869,8 +902,8 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr { this.turnCount = turnCount; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance && !move.hitsSubstitute(attacker, pokemon)) { if (simulated) { return attacker.canAddTag(this.tagType); } else { @@ -893,7 +926,11 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr { this.stages = stages; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.hitsSubstitute(attacker, pokemon)) { + return false; + } + if (!simulated) { pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.stages)); } @@ -901,7 +938,7 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr { return true; } - getCondition(): AbAttrCondition { + override getCondition(): AbAttrCondition { return (pokemon: Pokemon) => pokemon.turnData.attacksReceived.length !== 0 && pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1].critical; } } @@ -915,8 +952,9 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr { this.damageRatio = damageRatio; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) + && !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !move.hitsSubstitute(attacker, pokemon)) { attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)); return true; @@ -925,7 +963,7 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:postDefendContactDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName @@ -948,8 +986,8 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr { this.turns = turns; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !move.hitsSubstitute(attacker, pokemon)) { if (pokemon.getTag(BattlerTagType.PERISH_SONG) || attacker.getTag(BattlerTagType.PERISH_SONG)) { return false; } else { @@ -963,24 +1001,24 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { - return i18next.t("abilityTriggers:perishBody", {pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName}); + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { + return i18next.t("abilityTriggers:perishBody", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName }); } } export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr { private weatherType: WeatherType; - protected condition: PokemonDefendCondition | null; + protected condition?: PokemonDefendCondition; constructor(weatherType: WeatherType, condition?: PokemonDefendCondition) { super(); this.weatherType = weatherType; - this.condition = condition ?? null; + this.condition = condition; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (this.condition !== null && !this.condition(pokemon, attacker, move)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (this.condition && !this.condition(pokemon, attacker, move) || move.hitsSubstitute(attacker, pokemon)) { return false; } if (!pokemon.scene.arena.weather?.isImmutable()) { @@ -999,8 +1037,9 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr { super(); } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) + && !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr) && !move.hitsSubstitute(attacker, pokemon)) { if (!simulated) { const tempAbilityId = attacker.getAbility().id; attacker.summonData.ability = pokemon.getAbility().id; @@ -1012,7 +1051,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, _abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:postDefendAbilitySwap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } } @@ -1025,8 +1064,9 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr { this.ability = ability; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) + && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr) && !move.hitsSubstitute(attacker, pokemon)) { if (!simulated) { attacker.summonData.ability = this.ability; } @@ -1037,7 +1077,7 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:postDefendAbilityGive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName @@ -1056,8 +1096,8 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr { this.chance = chance; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (attacker.getTag(BattlerTagType.DISABLED) === null) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (attacker.getTag(BattlerTagType.DISABLED) === null && !move.hitsSubstitute(attacker, pokemon)) { if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) { if (simulated) { return true; @@ -1123,7 +1163,9 @@ export class MoveEffectChanceMultiplierAbAttr extends AbAttr { apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { // Disable showAbility during getTargetBenefitScore this.showAbility = args[4]; - if ((args[0] as Utils.NumberHolder).value <= 0 || (args[1] as Move).id === Moves.ORDER_UP) { + + const exceptMoves = [ Moves.ORDER_UP, Moves.ELECTRO_SHOT ]; + if ((args[0] as Utils.NumberHolder).value <= 0 || exceptMoves.includes((args[1] as Move).id)) { return false; } @@ -1268,7 +1310,7 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr { if (pokemon.getTypes().some((t) => t !== moveType)) { if (!simulated) { this.moveType = moveType; - pokemon.summonData.types = [moveType]; + pokemon.summonData.types = [ moveType ]; pokemon.updateInfo(); } @@ -1313,7 +1355,6 @@ export class AddSecondStrikeAbAttr extends PreAttackAbAttr { */ const exceptAttrs: Constructor[] = [ MultiHitAttr, - ChargeAttr, SacrificialAttr, SacrificialAttrOnHit ]; @@ -1329,6 +1370,7 @@ export class AddSecondStrikeAbAttr extends PreAttackAbAttr { /** Also check if this move is an Attack move and if it's only targeting one Pokemon */ return numTargets === 1 + && !move.isChargingMove() && !exceptAttrs.some(attr => move.hasAttr(attr)) && !exceptMoves.some(id => move.id === id) && move.category !== MoveCategory.STATUS; @@ -1724,17 +1766,17 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr { } export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr { - private condition: PokemonDefendCondition | null; + private condition?: PokemonDefendCondition; constructor(condition?: PokemonDefendCondition) { super(); - this.condition = condition ?? null; + this.condition = condition; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): Promise { return new Promise(resolve => { - if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) { + if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move)) && !move.hitsSubstitute(attacker, pokemon)) { const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable); if (heldItems.length) { const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; @@ -2404,11 +2446,12 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { super(true); } - applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { + async applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): Promise { const targets = pokemon.getOpponents(); if (simulated || !targets.length) { return simulated; } + const promises: Promise[] = []; let target: Pokemon; if (targets.length > 1) { @@ -2417,7 +2460,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { target = targets[0]; } - target = target!; // compiler doesn't know its guranteed to be defined + target = target!; pokemon.summonData.speciesForm = target.getSpeciesForm(); pokemon.summonData.fusionSpeciesForm = target.getFusionSpeciesForm(); pokemon.summonData.ability = target.getAbility().id; @@ -2434,18 +2477,26 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { pokemon.setStatStage(s, target.getStatStage(s)); } - pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m?.moveId ?? Moves.NONE, m?.ppUsed, m?.ppUp)); - pokemon.summonData.types = target.getTypes(); - - - pokemon.scene.playSound("battle_anims/PRSFX- Transform"); - - pokemon.loadAssets(false).then(() => { - pokemon.playAnim(); - pokemon.updateInfo(); + pokemon.summonData.moveset = target.getMoveset().map((m) => { + if (m) { + // If PP value is less than 5, do nothing. If greater, we need to reduce the value to 5. + return new PokemonMove(m.moveId, 0, 0, false, Math.min(m.getMove().pp, 5)); + } else { + console.warn(`Imposter: somehow iterating over a ${m} value when copying moveset!`); + return new PokemonMove(Moves.NONE); + } }); + pokemon.summonData.types = target.getTypes(); + promises.push(pokemon.updateInfo()); pokemon.scene.queueMessage(i18next.t("abilityTriggers:postSummonTransform", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), targetName: target.name, })); + pokemon.scene.playSound("battle_anims/PRSFX- Transform"); + promises.push(pokemon.loadAssets(false).then(() => { + pokemon.playAnim(); + pokemon.updateInfo(); + })); + + await Promise.all(promises); return true; } @@ -2563,24 +2614,24 @@ export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr { // Clear weather only if user's ability matches the weather and no other pokemon has the ability. switch (weatherType) { - case (WeatherType.HARSH_SUN): - if (pokemon.hasAbility(Abilities.DESOLATE_LAND) + case (WeatherType.HARSH_SUN): + if (pokemon.hasAbility(Abilities.DESOLATE_LAND) && pokemon.scene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) { - turnOffWeather = true; - } - break; - case (WeatherType.HEAVY_RAIN): - if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA) + turnOffWeather = true; + } + break; + case (WeatherType.HEAVY_RAIN): + if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA) && pokemon.scene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) { - turnOffWeather = true; - } - break; - case (WeatherType.STRONG_WINDS): - if (pokemon.hasAbility(Abilities.DELTA_STREAM) + turnOffWeather = true; + } + break; + case (WeatherType.STRONG_WINDS): + if (pokemon.hasAbility(Abilities.DELTA_STREAM) && pokemon.scene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) { - turnOffWeather = true; - } - break; + turnOffWeather = true; + } + break; } if (simulated) { @@ -2814,7 +2865,7 @@ export class PreApplyBattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr { constructor(immuneTagTypes: BattlerTagType | BattlerTagType[]) { super(); - this.immuneTagTypes = Array.isArray(immuneTagTypes) ? immuneTagTypes : [immuneTagTypes]; + this.immuneTagTypes = Array.isArray(immuneTagTypes) ? immuneTagTypes : [ immuneTagTypes ]; } applyPreApplyBattlerTag(pokemon: Pokemon, passive: boolean, simulated: boolean, tag: BattlerTag, cancelled: Utils.BooleanHolder, args: any[]): boolean { @@ -3099,17 +3150,17 @@ function getAnticipationCondition(): AbAttrCondition { // edge case for hidden power, type is computed if (move.getMove().id === Moves.HIDDEN_POWER) { const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1) - +(opponent.ivs[Stat.ATK] & 1) * 2 - +(opponent.ivs[Stat.DEF] & 1) * 4 - +(opponent.ivs[Stat.SPD] & 1) * 8 - +(opponent.ivs[Stat.SPATK] & 1) * 16 - +(opponent.ivs[Stat.SPDEF] & 1) * 32) * 15/63); + + (opponent.ivs[Stat.ATK] & 1) * 2 + + (opponent.ivs[Stat.DEF] & 1) * 4 + + (opponent.ivs[Stat.SPD] & 1) * 8 + + (opponent.ivs[Stat.SPATK] & 1) * 16 + + (opponent.ivs[Stat.SPDEF] & 1) * 32) * 15 / 63); const type = [ Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND, Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL, Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC, - Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK][iv_val]; + Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK ][iv_val]; if (pokemon.getAttackTypeEffectiveness(type, opponent) >= 2) { return true; @@ -3563,22 +3614,19 @@ export class MoodyAbAttr extends PostTurnAbAttr { } } -export class PostTurnStatStageChangeAbAttr extends PostTurnAbAttr { - private stats: BattleStat[]; - private stages: number; +export class SpeedBoostAbAttr extends PostTurnAbAttr { - constructor(stats: BattleStat[], stages: number) { + constructor() { super(true); - - this.stats = Array.isArray(stats) - ? stats - : [ stats ]; - this.stages = stages; } applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { if (!simulated) { - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.stages)); + if (!pokemon.turnData.switchedInThisTurn && !pokemon.turnData.failedRunAway) { + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.SPD ], 1)); + } else { + return false; + } } return true; } @@ -3644,7 +3692,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr { if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { if (!simulated) { opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER); - pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: getPokemonNameWithAffix(opp)})); + pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) })); } hadEffect = true; } @@ -3755,8 +3803,8 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr { */ applyPostMoveUsed(dancer: Pokemon, move: PokemonMove, source: Pokemon, targets: BattlerIndex[], simulated: boolean, args: any[]): boolean | Promise { // List of tags that prevent the Dancer from replicating the move - const forbiddenTags = [BattlerTagType.FLYING, BattlerTagType.UNDERWATER, - BattlerTagType.UNDERGROUND, BattlerTagType.HIDDEN]; + const forbiddenTags = [ BattlerTagType.FLYING, BattlerTagType.UNDERWATER, + BattlerTagType.UNDERGROUND, BattlerTagType.HIDDEN ]; // The move to replicate cannot come from the Dancer if (source.getBattlerIndex() !== dancer.getBattlerIndex() && !dancer.summonData.tags.some(tag => forbiddenTags.includes(tag.tagType))) { @@ -3767,7 +3815,7 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr { dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, target, move, true, true)); } else if (move.getMove() instanceof SelfStatusMove) { // If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself - dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, [dancer.getBattlerIndex()], move, true, true)); + dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, [ dancer.getBattlerIndex() ], move, true, true)); } } return true; @@ -3784,9 +3832,9 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr { */ getTarget(dancer: Pokemon, source: Pokemon, targets: BattlerIndex[]) : BattlerIndex[] { if (dancer.isPlayer()) { - return source.isPlayer() ? targets : [source.getBattlerIndex()]; + return source.isPlayer() ? targets : [ source.getBattlerIndex() ]; } - return source.isPlayer() ? [source.getBattlerIndex()] : targets; + return source.isPlayer() ? [ source.getBattlerIndex() ] : targets; } } @@ -4063,24 +4111,24 @@ export class PostFaintClearWeatherAbAttr extends PostFaintAbAttr { // Clear weather only if user's ability matches the weather and no other pokemon has the ability. switch (weatherType) { - case (WeatherType.HARSH_SUN): - if (pokemon.hasAbility(Abilities.DESOLATE_LAND) + case (WeatherType.HARSH_SUN): + if (pokemon.hasAbility(Abilities.DESOLATE_LAND) && pokemon.scene.getField(true).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) { - turnOffWeather = true; - } - break; - case (WeatherType.HEAVY_RAIN): - if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA) + turnOffWeather = true; + } + break; + case (WeatherType.HEAVY_RAIN): + if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA) && pokemon.scene.getField(true).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) { - turnOffWeather = true; - } - break; - case (WeatherType.STRONG_WINDS): - if (pokemon.hasAbility(Abilities.DELTA_STREAM) + turnOffWeather = true; + } + break; + case (WeatherType.STRONG_WINDS): + if (pokemon.hasAbility(Abilities.DELTA_STREAM) && pokemon.scene.getField(true).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) { - turnOffWeather = true; - } - break; + turnOffWeather = true; + } + break; } if (simulated) { @@ -4184,6 +4232,11 @@ export class RedirectTypeMoveAbAttr extends RedirectMoveAbAttr { export class BlockRedirectAbAttr extends AbAttr { } +/** + * Used by Early Bird, makes the pokemon wake up faster + * @param statusEffect - The {@linkcode StatusEffect} to check for + * @see {@linkcode apply} + */ export class ReduceStatusEffectDurationAbAttr extends AbAttr { private statusEffect: StatusEffect; @@ -4193,9 +4246,19 @@ export class ReduceStatusEffectDurationAbAttr extends AbAttr { this.statusEffect = statusEffect; } - apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { + /** + * Reduces the number of sleep turns remaining by an extra 1 when applied + * @param args - The args passed to the `AbAttr`: + * - `[0]` - The {@linkcode StatusEffect} of the Pokemon + * - `[1]` - The number of turns remaining until the status is healed + * @returns `true` if the ability was applied + */ + apply(_pokemon: Pokemon, _passive: boolean, _simulated: boolean, _cancelled: Utils.BooleanHolder, args: any[]): boolean { + if (!(args[1] instanceof Utils.NumberHolder)) { + return false; + } if (args[0] === this.statusEffect) { - (args[1] as Utils.IntegerHolder).value = Utils.toDmgValue((args[1] as Utils.IntegerHolder).value / 2); + args[1].value -= 1; return true; } @@ -4326,6 +4389,30 @@ export class AlwaysHitAbAttr extends AbAttr { } /** Attribute for abilities that allow moves that make contact to ignore protection (i.e. Unseen Fist) */ export class IgnoreProtectOnContactAbAttr extends AbAttr { } +/** + * Attribute implementing the effects of {@link https://bulbapedia.bulbagarden.net/wiki/Infiltrator_(Ability) | Infiltrator}. + * Allows the source's moves to bypass the effects of opposing Light Screen, Reflect, Aurora Veil, Safeguard, Mist, and Substitute. + */ +export class InfiltratorAbAttr extends AbAttr { + /** + * Sets a flag to bypass screens, Substitute, Safeguard, and Mist + * @param pokemon n/a + * @param passive n/a + * @param simulated n/a + * @param cancelled n/a + * @param args `[0]` a {@linkcode Utils.BooleanHolder | BooleanHolder} containing the flag + * @returns `true` if the bypass flag was successfully set; `false` otherwise. + */ + override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: null, args: any[]): boolean { + const bypassed = args[0]; + if (args[0] instanceof Utils.BooleanHolder) { + bypassed.value = true; + return true; + } + return false; + } +} + export class UncopiableAbilityAbAttr extends AbAttr { constructor() { super(false); @@ -4476,7 +4563,7 @@ export class PostSummonStatStageChangeOnArenaAbAttr extends PostSummonStatStageC export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr { private multiplier: number; private tagType: BattlerTagType; - private recoilDamageFunc: ((pokemon: Pokemon) => number) | undefined; + private recoilDamageFunc?: ((pokemon: Pokemon) => number); private triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string; constructor(condition: PokemonDefendCondition, multiplier: number, tagType: BattlerTagType, triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string, recoilDamageFunc?: (pokemon: Pokemon) => number) { @@ -4492,16 +4579,16 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr { * Applies the pre-defense ability to the Pokémon. * Removes the appropriate `BattlerTagType` when hit by an attack and is in its defense form. * - * @param {Pokemon} pokemon The Pokémon with the ability. - * @param {boolean} passive n/a - * @param {Pokemon} attacker The attacking Pokémon. - * @param {PokemonMove} move The move being used. - * @param {Utils.BooleanHolder} cancelled n/a - * @param {any[]} args Additional arguments. - * @returns {boolean} Whether the immunity was applied. + * @param pokemon The Pokémon with the ability. + * @param _passive n/a + * @param attacker The attacking Pokémon. + * @param move The move being used. + * @param _cancelled n/a + * @param args Additional arguments. + * @returns `true` if the immunity was applied. */ - applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { - if (this.condition(pokemon, attacker, move)) { + override applyPreDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _cancelled: Utils.BooleanHolder, args: any[]): boolean { + if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) { if (!simulated) { (args[0] as Utils.NumberHolder).value = this.multiplier; pokemon.removeTag(this.tagType); @@ -4517,12 +4604,12 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr { /** * Gets the message triggered when the Pokémon avoids damage using the form-changing ability. - * @param {Pokemon} pokemon The Pokémon with the ability. - * @param {string} abilityName The name of the ability. - * @param {...any} args n/a - * @returns {string} The trigger message. + * @param pokemon The Pokémon with the ability. + * @param abilityName The name of the ability. + * @param _args n/a + * @returns The trigger message. */ - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return this.triggerMessageFunc(pokemon, abilityName); } } @@ -4561,7 +4648,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr { const turnCommand = pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()]; const isCommandFight = turnCommand?.command === Command.FIGHT; - const move = turnCommand?.move?.move ?allMoves[turnCommand.move.move] : null; + const move = turnCommand?.move?.move ? allMoves[turnCommand.move.move] : null; const isDamageMove = move?.category === MoveCategory.PHYSICAL || move?.category === MoveCategory.SPECIAL; if (isCommandFight && isDamageMove) { @@ -4574,7 +4661,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr { } getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { - return i18next.t("abilityTriggers:quickDraw", {pokemonName: getPokemonNameWithAffix(pokemon)}); + return i18next.t("abilityTriggers:quickDraw", { pokemonName: getPokemonNameWithAffix(pokemon) }); } } @@ -4613,6 +4700,84 @@ export class PreventBypassSpeedChanceAbAttr extends AbAttr { } } +/** + * This applies a terrain-based type change to the Pokemon. + * Used by Mimicry. + */ +export class TerrainEventTypeChangeAbAttr extends PostSummonAbAttr { + constructor() { + super(true); + } + + override apply(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _cancelled: Utils.BooleanHolder, _args: any[]): boolean { + if (pokemon.isTerastallized()) { + return false; + } + const currentTerrain = pokemon.scene.arena.getTerrainType(); + const typeChange: Type[] = this.determineTypeChange(pokemon, currentTerrain); + if (typeChange.length !== 0) { + if (pokemon.summonData.addedType && typeChange.includes(pokemon.summonData.addedType)) { + pokemon.summonData.addedType = null; + } + pokemon.summonData.types = typeChange; + pokemon.updateInfo(); + } + return true; + } + + /** + * Retrieves the type(s) the Pokemon should change to in response to a terrain + * @param pokemon + * @param currentTerrain {@linkcode TerrainType} + * @returns a list of type(s) + */ + private determineTypeChange(pokemon: Pokemon, currentTerrain: TerrainType): Type[] { + const typeChange: Type[] = []; + switch (currentTerrain) { + case TerrainType.ELECTRIC: + typeChange.push(Type.ELECTRIC); + break; + case TerrainType.MISTY: + typeChange.push(Type.FAIRY); + break; + case TerrainType.GRASSY: + typeChange.push(Type.GRASS); + break; + case TerrainType.PSYCHIC: + typeChange.push(Type.PSYCHIC); + break; + default: + pokemon.getTypes(false, false, true).forEach(t => { + typeChange.push(t); + }); + break; + } + return typeChange; + } + + /** + * Checks if the Pokemon should change types if summoned into an active terrain + * @returns `true` if there is an active terrain requiring a type change | `false` if not + */ + override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise { + if (pokemon.scene.arena.getTerrainType() !== TerrainType.NONE) { + return this.apply(pokemon, passive, simulated, new Utils.BooleanHolder(false), []); + } + return false; + } + + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) { + const currentTerrain = pokemon.scene.arena.getTerrainType(); + const pokemonNameWithAffix = getPokemonNameWithAffix(pokemon); + if (currentTerrain === TerrainType.NONE) { + return i18next.t("abilityTriggers:pokemonTypeChangeRevert", { pokemonNameWithAffix }); + } else { + const moveType = i18next.t(`pokemonInfo:Type.${Type[this.determineTypeChange(pokemon, currentTerrain)[0]]}`); + return i18next.t("abilityTriggers:pokemonTypeChange", { pokemonNameWithAffix, moveType }); + } + } +} + async function applyAbAttrsInternal( attrType: Constructor, pokemon: Pokemon | null, @@ -4622,8 +4787,8 @@ async function applyAbAttrsInternal( simulated: boolean = false, messages: string[] = [], ) { - for (const passive of [false, true]) { - if (!pokemon?.canApplyAbility(passive)) { + for (const passive of [ false, true ]) { + if (!pokemon?.canApplyAbility(passive) || (passive && pokemon.getPassiveAbility().id === pokemon.getAbility().id)) { continue; } @@ -4843,7 +5008,7 @@ export function initAbilities() { .attr(PostSummonWeatherChangeAbAttr, WeatherType.RAIN) .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.RAIN), new Ability(Abilities.SPEED_BOOST, 3) - .attr(PostTurnStatStageChangeAbAttr, [ Stat.SPD ], 1), + .attr(SpeedBoostAbAttr), new Ability(Abilities.BATTLE_ARMOR, 3) .attr(BlockCritAbAttr) .ignorable(), @@ -4872,7 +5037,7 @@ export function initAbilities() { .attr(TypeImmunityHealAbAttr, Type.WATER) .ignorable(), new Ability(Abilities.OBLIVIOUS, 3) - .attr(BattlerTagImmunityAbAttr, [BattlerTagType.INFATUATED, BattlerTagType.TAUNT]) + .attr(BattlerTagImmunityAbAttr, [ BattlerTagType.INFATUATED, BattlerTagType.TAUNT ]) .attr(IntimidateImmunityAbAttr) .ignorable(), new Ability(Abilities.CLOUD_NINE, 3) @@ -4897,8 +5062,7 @@ export function initAbilities() { .attr(TypeImmunityAddBattlerTagAbAttr, Type.FIRE, BattlerTagType.FIRE_BOOST, 1) .ignorable(), new Ability(Abilities.SHIELD_DUST, 3) - .attr(IgnoreMoveEffectsAbAttr) - .partial(), + .attr(IgnoreMoveEffectsAbAttr), new Ability(Abilities.OWN_TEMPO, 3) .attr(BattlerTagImmunityAbAttr, BattlerTagType.CONFUSED) .attr(IntimidateImmunityAbAttr) @@ -4942,8 +5106,7 @@ export function initAbilities() { .attr(TypeImmunityStatStageChangeAbAttr, Type.ELECTRIC, Stat.SPATK, 1) .ignorable(), new Ability(Abilities.SERENE_GRACE, 3) - .attr(MoveEffectChanceMultiplierAbAttr, 2) - .partial(), + .attr(MoveEffectChanceMultiplierAbAttr, 2), new Ability(Abilities.SWIFT_SWIM, 3) .attr(StatMultiplierAbAttr, Stat.SPD, 2) .condition(getWeatherCondition(WeatherType.RAIN, WeatherType.HEAVY_RAIN)), @@ -5017,10 +5180,10 @@ export function initAbilities() { new Ability(Abilities.CUTE_CHARM, 3) .attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED), new Ability(Abilities.PLUS, 3) - .conditionalAttr(p => p.scene.currentBattle.double && [Abilities.PLUS, Abilities.MINUS].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5) + .conditionalAttr(p => p.scene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5) .ignorable(), new Ability(Abilities.MINUS, 3) - .conditionalAttr(p => p.scene.currentBattle.double && [Abilities.PLUS, Abilities.MINUS].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5) + .conditionalAttr(p => p.scene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5) .ignorable(), new Ability(Abilities.FORECAST, 3) .attr(UncopiableAbilityAbAttr) @@ -5138,7 +5301,7 @@ export function initAbilities() { .conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), StatMultiplierAbAttr, Stat.SPD, 1.5), new Ability(Abilities.NORMALIZE, 4) .attr(MoveTypeChangeAbAttr, Type.NORMAL, 1.2, (user, target, move) => { - return ![Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST].includes(move.id); + return ![ Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST ].includes(move.id); }), new Ability(Abilities.SNIPER, 4) .attr(MultCritAbAttr, 1.5), @@ -5184,7 +5347,7 @@ export function initAbilities() { new Ability(Abilities.SLOW_START, 4) .attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5), new Ability(Abilities.SCRAPPY, 4) - .attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING]) + .attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ]) .attr(IntimidateImmunityAbAttr), new Ability(Abilities.STORM_DRAIN, 4) .attr(RedirectTypeMoveAbAttr, Type.WATER) @@ -5225,16 +5388,17 @@ export function initAbilities() { .attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT)) .condition(getSheerForceHitDisableAbCondition()), new Ability(Abilities.SHEER_FORCE, 5) - .attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461/4096) + .attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461 / 4096) .attr(MoveEffectChanceMultiplierAbAttr, 0) - .partial(), + .edgeCase() // Should disable shell bell and Meloetta's relic song transformation + .edgeCase(), // Should disable life orb, eject button, red card, kee/maranga berry if they get implemented new Ability(Abilities.CONTRARY, 5) .attr(StatStageChangeMultiplierAbAttr, -1) .ignorable(), new Ability(Abilities.UNNERVE, 5) .attr(PreventBerryUseAbAttr), new Ability(Abilities.DEFIANT, 5) - .attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [Stat.ATK], 2), + .attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [ Stat.ATK ], 2), new Ability(Abilities.DEFEATIST, 5) .attr(StatMultiplierAbAttr, Stat.ATK, 0.5) .attr(StatMultiplierAbAttr, Stat.SPATK, 0.5) @@ -5245,8 +5409,8 @@ export function initAbilities() { new Ability(Abilities.HEALER, 5) .conditionalAttr(pokemon => pokemon.getAlly() && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true), new Ability(Abilities.FRIEND_GUARD, 5) - .ignorable() - .unimplemented(), + .attr(AlliedFieldDamageReductionAbAttr, 0.75) + .ignorable(), new Ability(Abilities.WEAK_ARMOR, 5) .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL, Stat.DEF, -1) .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL, Stat.SPD, 2), @@ -5270,7 +5434,7 @@ export function initAbilities() { /** Rate is doubled when under sun {@link https://dex.pokemonshowdown.com/abilities/harvest} */ (pokemon) => 0.5 * (getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)(pokemon) ? 2 : 1) ) - .partial(), + .edgeCase(), // Cannot recover berries used up by fling or natural gift (unimplemented) new Ability(Abilities.TELEPATHY, 5) .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon.getAlly() === attacker && move instanceof AttackMove) .ignorable(), @@ -5306,7 +5470,8 @@ export function initAbilities() { .attr(PostSummonTransformAbAttr) .attr(UncopiableAbilityAbAttr), new Ability(Abilities.INFILTRATOR, 5) - .unimplemented(), + .attr(InfiltratorAbAttr) + .partial(), // does not bypass Mist new Ability(Abilities.MUMMY, 5) .attr(PostDefendAbilityGiveAbAttr, Abilities.MUMMY) .bypassFaint(), @@ -5320,7 +5485,7 @@ export function initAbilities() { return move.category !== MoveCategory.STATUS && (moveType === Type.DARK || moveType === Type.BUG || moveType === Type.GHOST); }, Stat.SPD, 1) - .attr(PostIntimidateStatStageChangeAbAttr, [Stat.SPD], 1), + .attr(PostIntimidateStatStageChangeAbAttr, [ Stat.SPD ], 1), new Ability(Abilities.MAGIC_BOUNCE, 5) .ignorable() .unimplemented(), @@ -5349,7 +5514,7 @@ export function initAbilities() { .bypassFaint(), new Ability(Abilities.VICTORY_STAR, 5) .attr(StatMultiplierAbAttr, Stat.ACC, 1.1) - .partial(), + .partial(), // Does not boost ally's accuracy new Ability(Abilities.TURBOBLAZE, 5) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTurboblaze", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })) .attr(MoveAbilityBypassAbAttr), @@ -5357,12 +5522,12 @@ export function initAbilities() { .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTeravolt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })) .attr(MoveAbilityBypassAbAttr), new Ability(Abilities.AROMA_VEIL, 6) - .attr(UserFieldBattlerTagImmunityAbAttr, [BattlerTagType.INFATUATED, BattlerTagType.TAUNT, BattlerTagType.DISABLED, BattlerTagType.TORMENT, BattlerTagType.HEAL_BLOCK]), + .attr(UserFieldBattlerTagImmunityAbAttr, [ BattlerTagType.INFATUATED, BattlerTagType.TAUNT, BattlerTagType.DISABLED, BattlerTagType.TORMENT, BattlerTagType.HEAL_BLOCK ]), new Ability(Abilities.FLOWER_VEIL, 6) .ignorable() .unimplemented(), new Ability(Abilities.CHEEK_POUCH, 6) - .attr(HealFromBerryUseAbAttr, 1/3), + .attr(HealFromBerryUseAbAttr, 1 / 3), new Ability(Abilities.PROTEAN, 6) .attr(PokemonTypeChangeAbAttr), //.condition((p) => !p.summonData?.abilitiesApplied.includes(Abilities.PROTEAN)), //Gen 9 Implementation @@ -5375,7 +5540,7 @@ export function initAbilities() { .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.hasFlag(MoveFlags.BALLBOMB_MOVE)) .ignorable(), new Ability(Abilities.COMPETITIVE, 6) - .attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [Stat.SPATK], 2), + .attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [ Stat.SPATK ], 2), new Ability(Abilities.STRONG_JAW, 6) .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.BITING_MOVE), 1.5), new Ability(Abilities.REFRIGERATE, 6) @@ -5460,7 +5625,7 @@ export function initAbilities() { .attr(UnsuppressableAbilityAbAttr) .attr(NoFusionAbilityAbAttr) .bypassFaint() - .partial(), + .partial(), // Meteor form should protect against status effects and yawn new Ability(Abilities.STAKEOUT, 7) .attr(MovePowerBoostAbAttr, (user, target, move) => user?.scene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command === Command.POKEMON, 2), new Ability(Abilities.WATER_BUBBLE, 7) @@ -5471,7 +5636,7 @@ export function initAbilities() { new Ability(Abilities.STEELWORKER, 7) .attr(MoveTypePowerBoostAbAttr, Type.STEEL), new Ability(Abilities.BERSERK, 7) - .attr(PostDefendHpGatedStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, 0.5, [Stat.SPATK], 1) + .attr(PostDefendHpGatedStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, 0.5, [ Stat.SPATK ], 1) .condition(getSheerForceHitDisableAbCondition()), new Ability(Abilities.SLUSH_RUSH, 7) .attr(StatMultiplierAbAttr, Stat.SPD, 2) @@ -5503,7 +5668,8 @@ export function initAbilities() { .attr(NoFusionAbilityAbAttr) // Add BattlerTagType.DISGUISE if the pokemon is in its disguised form .conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.DISGUISE, 0, false) - .attr(FormBlockDamageAbAttr, (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getMoveEffectiveness(user, move) > 0, 0, BattlerTagType.DISGUISE, + .attr(FormBlockDamageAbAttr, + (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getMoveEffectiveness(user, move) > 0, 0, BattlerTagType.DISGUISE, (pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }), (pokemon) => Utils.toDmgValue(pokemon.getMaxHp() / 8)) .attr(PostBattleInitFormChangeAbAttr, () => 0) @@ -5517,19 +5683,21 @@ export function initAbilities() { .attr(UnsuppressableAbilityAbAttr) .attr(NoFusionAbilityAbAttr) .bypassFaint(), - new Ability(Abilities.POWER_CONSTRUCT, 7) // TODO: 10% Power Construct Zygarde isn't accounted for yet. If changed, update Zygarde's getSpeciesFormIndex entry accordingly - .attr(PostBattleInitFormChangeAbAttr, () => 2) - .attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2) - .attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2) + new Ability(Abilities.POWER_CONSTRUCT, 7) + .conditionalAttr(pokemon => pokemon.formIndex === 2 || pokemon.formIndex === 4, PostBattleInitFormChangeAbAttr, () => 2) + .conditionalAttr(pokemon => pokemon.formIndex === 3 || pokemon.formIndex === 5, PostBattleInitFormChangeAbAttr, () => 3) + .conditionalAttr(pokemon => pokemon.formIndex === 2 || pokemon.formIndex === 4, PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2) + .conditionalAttr(pokemon => pokemon.formIndex === 2 || pokemon.formIndex === 4, PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2) + .conditionalAttr(pokemon => pokemon.formIndex === 3 || pokemon.formIndex === 5, PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "10-complete" ? 5 : 3) + .conditionalAttr(pokemon => pokemon.formIndex === 3 || pokemon.formIndex === 5, PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "10-complete" ? 5 : 3) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr) .attr(NoFusionAbilityAbAttr) - .bypassFaint() - .partial(), - new Ability(Abilities.CORROSION, 7) // TODO: Test Corrosion against Magic Bounce once it is implemented - .attr(IgnoreTypeStatusEffectImmunityAbAttr, [StatusEffect.POISON, StatusEffect.TOXIC], [Type.STEEL, Type.POISON]) - .partial(), + .bypassFaint(), + new Ability(Abilities.CORROSION, 7) + .attr(IgnoreTypeStatusEffectImmunityAbAttr, [ StatusEffect.POISON, StatusEffect.TOXIC ], [ Type.STEEL, Type.POISON ]) + .edgeCase(), // Should interact correctly with magic coat/bounce (not yet implemented), fling with toxic orb (not implemented yet), and synchronize (not fully implemented yet) new Ability(Abilities.COMATOSE, 7) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) @@ -5545,7 +5713,7 @@ export function initAbilities() { new Ability(Abilities.DANCER, 7) .attr(PostDancingMoveAbAttr), new Ability(Abilities.BATTERY, 7) - .attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL], 1.3), + .attr(AllyMoveCategoryPowerBoostAbAttr, [ MoveCategory.SPECIAL ], 1.3), new Ability(Abilities.FLUFFY, 7) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 0.5) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE, 2) @@ -5665,17 +5833,18 @@ export function initAbilities() { .conditionalAttr(getWeatherCondition(WeatherType.HAIL, WeatherType.SNOW), PostSummonAddBattlerTagAbAttr, BattlerTagType.ICE_FACE, 0) // When weather changes to HAIL or SNOW while pokemon is fielded, add BattlerTagType.ICE_FACE .attr(PostWeatherChangeAddBattlerTagAttr, BattlerTagType.ICE_FACE, 0, WeatherType.HAIL, WeatherType.SNOW) - .attr(FormBlockDamageAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0, BattlerTagType.ICE_FACE, + .attr(FormBlockDamageAbAttr, + (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0, BattlerTagType.ICE_FACE, (pokemon, abilityName) => i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName })) .attr(PostBattleInitFormChangeAbAttr, () => 0) .bypassFaint() .ignorable(), new Ability(Abilities.POWER_SPOT, 8) - .attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL], 1.3), + .attr(AllyMoveCategoryPowerBoostAbAttr, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ], 1.3), new Ability(Abilities.MIMICRY, 8) - .unimplemented(), + .attr(TerrainEventTypeChangeAbAttr), new Ability(Abilities.SCREEN_CLEANER, 8) - .attr(PostSummonRemoveArenaTagAbAttr, [ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.REFLECT]), + .attr(PostSummonRemoveArenaTagAbAttr, [ ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.REFLECT ]), new Ability(Abilities.STEELY_SPIRIT, 8) .attr(UserFieldMoveTypePowerBoostAbAttr, Type.STEEL), new Ability(Abilities.PERISH_BODY, 8) @@ -5683,7 +5852,7 @@ export function initAbilities() { new Ability(Abilities.WANDERING_SPIRIT, 8) .attr(PostDefendAbilitySwapAbAttr) .bypassFaint() - .partial(), + .edgeCase(), // interacts incorrectly with rock head. It's meant to switch abilities before recoil would apply so that a pokemon with rock head would lose rock head first and still take the recoil new Ability(Abilities.GORILLA_TACTICS, 8) .attr(GorillaTacticsAbAttr), new Ability(Abilities.NEUTRALIZING_GAS, 8) @@ -5692,7 +5861,7 @@ export function initAbilities() { .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonNeutralizingGas", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })) - .partial(), + .partial(), // A bunch of weird interactions with other abilities being suppressed then unsuppressed new Ability(Abilities.PASTEL_VEIL, 8) .attr(PostSummonUserFieldRemoveStatusEffectAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) .attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) @@ -5758,7 +5927,7 @@ export function initAbilities() { .attr(PostSummonStatStageChangeOnArenaAbAttr, ArenaTagType.TAILWIND) .ignorable(), new Ability(Abilities.GUARD_DOG, 9) - .attr(PostIntimidateStatStageChangeAbAttr, [Stat.ATK], 1, true) + .attr(PostIntimidateStatStageChangeAbAttr, [ Stat.ATK ], 1, true) .attr(ForceSwitchOutImmunityAbAttr) .ignorable(), new Ability(Abilities.ROCKY_PAYLOAD, 9) @@ -5797,7 +5966,7 @@ export function initAbilities() { new Ability(Abilities.GOOD_AS_GOLD, 9) .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.category === MoveCategory.STATUS) .ignorable() - .partial(), + .partial(), // Lots of weird interactions with moves and abilities such as negating status moves that target the field new Ability(Abilities.VESSEL_OF_RUIN, 9) .attr(FieldMultiplyStatAbAttr, Stat.SPATK, 0.75) .attr(PostSummonMessageAbAttr, (user) => i18next.t("abilityTriggers:postSummonVesselOfRuin", { pokemonNameWithAffix: getPokemonNameWithAffix(user), statName: i18next.t(getStatKey(Stat.SPATK)) })) @@ -5830,7 +5999,7 @@ export function initAbilities() { .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SLICING_MOVE), 1.5), new Ability(Abilities.SUPREME_OVERLORD, 9) .attr(VariableMovePowerBoostAbAttr, (user, target, move) => 1 + 0.1 * Math.min(user.isPlayer() ? user.scene.currentBattle.playerFaints : user.scene.currentBattle.enemyFaints, 5)) - .partial(), + .partial(), // Counter resets every wave instead of on arena reset new Ability(Abilities.COSTAR, 9) .attr(PostSummonCopyAllyStatsAbAttr), new Ability(Abilities.TOXIC_DEBRIS, 9) @@ -5847,7 +6016,7 @@ export function initAbilities() { .attr(PreventBypassSpeedChanceAbAttr, (pokemon, move) => move.category === MoveCategory.STATUS) .attr(MoveAbilityBypassAbAttr, (pokemon, move: Move) => move.category === MoveCategory.STATUS), new Ability(Abilities.MINDS_EYE, 9) - .attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING]) + .attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ]) .attr(ProtectStatAbAttr, Stat.ACC) .attr(IgnoreOpponentStatStagesAbAttr, [ Stat.EVA ]) .ignorable(), @@ -5863,25 +6032,25 @@ export function initAbilities() { .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) - .partial(), + .partial(), // Ogerpon tera interactions new Ability(Abilities.EMBODY_ASPECT_WELLSPRING, 9) .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.SPDEF ], 1, true) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) - .partial(), + .partial(), // Ogerpon tera interactions new Ability(Abilities.EMBODY_ASPECT_HEARTHFLAME, 9) .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.ATK ], 1, true) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) - .partial(), + .partial(), // Ogerpon tera interactions new Ability(Abilities.EMBODY_ASPECT_CORNERSTONE, 9) .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.DEF ], 1, true) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) - .partial(), + .partial(), // Ogerpon tera interactions new Ability(Abilities.TERA_SHIFT, 9) .attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1) .attr(UncopiableAbilityAbAttr) diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 9e121b81fea..43de6e02dcb 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -1,13 +1,13 @@ import { Arena } from "#app/field/arena"; import BattleScene from "#app/battle-scene"; import { Type } from "#app/data/type"; -import * as Utils from "#app/utils"; +import { BooleanHolder, NumberHolder, toDmgValue } from "#app/utils"; import { MoveCategory, allMoves, MoveTarget, IncrementMovePriorityAttr, applyMoveAttrs } from "#app/data/move"; import { getPokemonNameWithAffix } from "#app/messages"; -import Pokemon, { HitResult, PlayerPokemon, PokemonMove, EnemyPokemon } from "#app/field/pokemon"; +import Pokemon, { HitResult, PokemonMove } from "#app/field/pokemon"; import { StatusEffect } from "#app/data/status-effect"; import { BattlerIndex } from "#app/battle"; -import { BlockNonDirectDamageAbAttr, ChangeMovePriorityAbAttr, ProtectStatAbAttr, applyAbAttrs } from "#app/data/ability"; +import { BlockNonDirectDamageAbAttr, ChangeMovePriorityAbAttr, InfiltratorAbAttr, ProtectStatAbAttr, applyAbAttrs } from "#app/data/ability"; import { Stat } from "#enums/stat"; import { CommonAnim, CommonBattleAnim } from "#app/data/battle-anims"; import i18next from "i18next"; @@ -19,6 +19,7 @@ import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase"; import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; +import { CommonAnimPhase } from "#app/phases/common-anim-phase"; export enum ArenaTagSide { BOTH, @@ -27,22 +28,15 @@ export enum ArenaTagSide { } export abstract class ArenaTag { - public tagType: ArenaTagType; - public turnCount: integer; - public sourceMove?: Moves; - public sourceId?: integer; - public side: ArenaTagSide; + constructor( + public tagType: ArenaTagType, + public turnCount: number, + public sourceMove?: Moves, + public sourceId?: number, + public side: ArenaTagSide = ArenaTagSide.BOTH + ) {} - - constructor(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId?: integer, side: ArenaTagSide = ArenaTagSide.BOTH) { - this.tagType = tagType; - this.turnCount = turnCount; - this.sourceMove = sourceMove; - this.sourceId = sourceId; - this.side = side; - } - - apply(arena: Arena, args: any[]): boolean { + apply(arena: Arena, simulated: boolean, ...args: unknown[]): boolean { return true; } @@ -65,6 +59,44 @@ export abstract class ArenaTag { ? allMoves[this.sourceMove].name : null; } + + /** + * When given a arena tag or json representing one, load the data for it. + * This is meant to be inherited from by any arena tag with custom attributes + * @param {ArenaTag | any} source An arena tag + */ + loadTag(source : ArenaTag | any) : void { + this.turnCount = source.turnCount; + this.sourceMove = source.sourceMove; + this.sourceId = source.sourceId; + this.side = source.side; + } + + /** + * Helper function that retrieves the source Pokemon + * @param scene medium to retrieve the source Pokemon + * @returns The source {@linkcode Pokemon} or `null` if none is found + */ + public getSourcePokemon(scene: BattleScene): Pokemon | null { + return this.sourceId ? scene.getPokemonById(this.sourceId) : null; + } + + /** + * Helper function that retrieves the Pokemon affected + * @param scene - medium to retrieve the involved Pokemon + * @returns list of PlayerPokemon or EnemyPokemon on the field + */ + public getAffectedPokemon(scene: BattleScene): Pokemon[] { + switch (this.side) { + case ArenaTagSide.PLAYER: + return scene.getPlayerField() ?? []; + case ArenaTagSide.ENEMY: + return scene.getEnemyField() ?? []; + case ArenaTagSide.BOTH: + default: + return scene.getField(true) ?? []; + } + } } /** @@ -72,7 +104,7 @@ export abstract class ArenaTag { * Prevents Pokémon on the opposing side from lowering the stats of the Pokémon in the Mist. */ export class MistTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.MIST, turnCount, Moves.MIST, sourceId, side); } @@ -90,10 +122,32 @@ export class MistTag extends ArenaTag { } } - apply(arena: Arena, args: any[]): boolean { - (args[0] as Utils.BooleanHolder).value = true; + /** + * Cancels the lowering of stats + * @param arena the {@linkcode Arena} containing this effect + * @param simulated `true` if the effect should be applied quietly + * @param attacker the {@linkcode Pokemon} using a move into this effect. + * @param cancelled a {@linkcode BooleanHolder} whose value is set to `true` + * to flag the stat reduction as cancelled + * @returns `true` if a stat reduction was cancelled; `false` otherwise + */ + override apply(arena: Arena, simulated: boolean, attacker: Pokemon, cancelled: BooleanHolder): boolean { + // `StatStageChangePhase` currently doesn't have a reference to the source of stat drops, + // so this code currently has no effect on gameplay. + if (attacker) { + const bypassed = new BooleanHolder(false); + // TODO: Allow this to be simulated + applyAbAttrs(InfiltratorAbAttr, attacker, null, false, bypassed); + if (bypassed.value) { + return false; + } + } - arena.scene.queueMessage(i18next.t("arenaTag:mistApply")); + cancelled.value = true; + + if (!simulated) { + arena.scene.queueMessage(i18next.t("arenaTag:mistApply")); + } return true; } @@ -116,7 +170,7 @@ export class WeakenMoveScreenTag extends ArenaTag { * @param side - The side (player or enemy) the tag affects. * @param weakenedCategories - The categories of moves that are weakened by this tag. */ - constructor(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, weakenedCategories: MoveCategory[]) { + constructor(tagType: ArenaTagType, turnCount: number, sourceMove: Moves, sourceId: number, side: ArenaTagSide, weakenedCategories: MoveCategory[]) { super(tagType, turnCount, sourceMove, sourceId, side); this.weakenedCategories = weakenedCategories; @@ -125,17 +179,21 @@ export class WeakenMoveScreenTag extends ArenaTag { /** * Applies the weakening effect to the move. * - * @param arena - The arena where the move is applied. - * @param args - The arguments for the move application. - * @param args[0] - The category of the move. - * @param args[1] - A boolean indicating whether it is a double battle. - * @param args[2] - An object of type `Utils.NumberHolder` that holds the damage multiplier - * - * @returns True if the move was weakened, otherwise false. + * @param arena the {@linkcode Arena} where the move is applied. + * @param simulated n/a + * @param attacker the attacking {@linkcode Pokemon} + * @param moveCategory the attacking move's {@linkcode MoveCategory}. + * @param damageMultiplier A {@linkcode NumberHolder} containing the damage multiplier + * @returns `true` if the attacking move was weakened; `false` otherwise. */ - apply(arena: Arena, args: any[]): boolean { - if (this.weakenedCategories.includes((args[0] as MoveCategory))) { - (args[2] as Utils.NumberHolder).value = (args[1] as boolean) ? 2732/4096 : 0.5; + override apply(arena: Arena, simulated: boolean, attacker: Pokemon, moveCategory: MoveCategory, damageMultiplier: NumberHolder): boolean { + if (this.weakenedCategories.includes(moveCategory)) { + const bypassed = new BooleanHolder(false); + applyAbAttrs(InfiltratorAbAttr, attacker, null, false, bypassed); + if (bypassed.value) { + return false; + } + damageMultiplier.value = arena.scene.currentBattle.double ? 2732 / 4096 : 0.5; return true; } return false; @@ -147,8 +205,8 @@ export class WeakenMoveScreenTag extends ArenaTag { * Used by {@linkcode Moves.REFLECT} */ class ReflectTag extends WeakenMoveScreenTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { - super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [MoveCategory.PHYSICAL]); + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { + super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [ MoveCategory.PHYSICAL ]); } onAdd(arena: Arena, quiet: boolean = false): void { @@ -163,8 +221,8 @@ class ReflectTag extends WeakenMoveScreenTag { * Used by {@linkcode Moves.LIGHT_SCREEN} */ class LightScreenTag extends WeakenMoveScreenTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { - super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [MoveCategory.SPECIAL]); + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { + super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [ MoveCategory.SPECIAL ]); } onAdd(arena: Arena, quiet: boolean = false): void { @@ -179,8 +237,8 @@ class LightScreenTag extends WeakenMoveScreenTag { * Used by {@linkcode Moves.AURORA_VEIL} */ class AuroraVeilTag extends WeakenMoveScreenTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { - super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL]); + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { + super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ]); } onAdd(arena: Arena, quiet: boolean = false): void { @@ -202,7 +260,7 @@ export class ConditionalProtectTag extends ArenaTag { /** Does this apply to all moves, including those that ignore other forms of protection? */ protected ignoresBypass: boolean; - constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, condition: ProtectConditionFunc, ignoresBypass: boolean = false) { + constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: number, side: ArenaTagSide, condition: ProtectConditionFunc, ignoresBypass: boolean = false) { super(tagType, 1, sourceMove, sourceId, side); this.protectConditionFunc = condition; @@ -217,38 +275,34 @@ export class ConditionalProtectTag extends ArenaTag { onRemove(arena: Arena): void { } /** - * apply(): Checks incoming moves against the condition function + * Checks incoming moves against the condition function * and protects the target if conditions are met - * @param arena The arena containing this tag - * @param args\[0\] (Utils.BooleanHolder) Signals if the move is cancelled - * @param args\[1\] (Pokemon) The Pokemon using the move - * @param args\[2\] (Pokemon) The intended target of the move - * @param args\[3\] (Moves) The parameters to the condition function - * @param args\[4\] (Utils.BooleanHolder) Signals if the applied protection supercedes protection-ignoring effects - * @returns + * @param arena the {@linkcode Arena} containing this tag + * @param simulated `true` if the tag is applied quietly; `false` otherwise. + * @param isProtected a {@linkcode BooleanHolder} used to flag if the move is protected against + * @param attacker the attacking {@linkcode Pokemon} + * @param defender the defending {@linkcode Pokemon} + * @param moveId the {@linkcode Moves | identifier} for the move being used + * @param ignoresProtectBypass a {@linkcode BooleanHolder} used to flag if a protection effect supercedes effects that ignore protection + * @returns `true` if this tag protected against the attack; `false` otherwise */ - apply(arena: Arena, args: any[]): boolean { - const [ cancelled, user, target, moveId, ignoresBypass ] = args; + override apply(arena: Arena, simulated: boolean, isProtected: BooleanHolder, attacker: Pokemon, defender: Pokemon, + moveId: Moves, ignoresProtectBypass: BooleanHolder): boolean { - if (cancelled instanceof Utils.BooleanHolder - && user instanceof Pokemon - && target instanceof Pokemon - && typeof moveId === "number" - && ignoresBypass instanceof Utils.BooleanHolder) { + if ((this.side === ArenaTagSide.PLAYER) === defender.isPlayer() + && this.protectConditionFunc(arena, moveId)) { + if (!isProtected.value) { + isProtected.value = true; + if (!simulated) { + attacker.stopMultiHit(defender); - if ((this.side === ArenaTagSide.PLAYER) === target.isPlayer() - && this.protectConditionFunc(arena, moveId)) { - if (!cancelled.value) { - cancelled.value = true; - user.stopMultiHit(target); - - new CommonBattleAnim(CommonAnim.PROTECT, target).play(arena.scene); - arena.scene.queueMessage(i18next.t("arenaTag:conditionalProtectApply", { moveName: super.getMoveName(), pokemonNameWithAffix: getPokemonNameWithAffix(target) })); + new CommonBattleAnim(CommonAnim.PROTECT, defender).play(arena.scene); + arena.scene.queueMessage(i18next.t("arenaTag:conditionalProtectApply", { moveName: super.getMoveName(), pokemonNameWithAffix: getPokemonNameWithAffix(defender) })); } - - ignoresBypass.value = ignoresBypass.value || this.ignoresBypass; - return true; } + + ignoresProtectBypass.value = ignoresProtectBypass.value || this.ignoresBypass; + return true; } return false; } @@ -264,7 +318,7 @@ export class ConditionalProtectTag extends ArenaTag { */ const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => { const move = allMoves[moveId]; - const priority = new Utils.IntegerHolder(move.priority); + const priority = new NumberHolder(move.priority); const effectPhase = arena.scene.getCurrentPhase(); if (effectPhase instanceof MoveEffectPhase) { @@ -280,7 +334,7 @@ const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => { * Condition: The incoming move has increased priority. */ class QuickGuardTag extends ConditionalProtectTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.QUICK_GUARD, Moves.QUICK_GUARD, sourceId, side, QuickGuardConditionFunc); } } @@ -296,11 +350,11 @@ const WideGuardConditionFunc: ProtectConditionFunc = (arena, moveId) : boolean = const move = allMoves[moveId]; switch (move.moveTarget) { - case MoveTarget.ALL_ENEMIES: - case MoveTarget.ALL_NEAR_ENEMIES: - case MoveTarget.ALL_OTHERS: - case MoveTarget.ALL_NEAR_OTHERS: - return true; + case MoveTarget.ALL_ENEMIES: + case MoveTarget.ALL_NEAR_ENEMIES: + case MoveTarget.ALL_OTHERS: + case MoveTarget.ALL_NEAR_OTHERS: + return true; } return false; }; @@ -311,7 +365,7 @@ const WideGuardConditionFunc: ProtectConditionFunc = (arena, moveId) : boolean = * can be an ally or enemy. */ class WideGuardTag extends ConditionalProtectTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.WIDE_GUARD, Moves.WIDE_GUARD, sourceId, side, WideGuardConditionFunc); } } @@ -333,7 +387,7 @@ const MatBlockConditionFunc: ProtectConditionFunc = (arena, moveId) : boolean => * Condition: The incoming move is a Physical or Special attack move. */ class MatBlockTag extends ConditionalProtectTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.MAT_BLOCK, Moves.MAT_BLOCK, sourceId, side, MatBlockConditionFunc); } @@ -371,7 +425,7 @@ const CraftyShieldConditionFunc: ProtectConditionFunc = (arena, moveId) => { * not target all Pokemon or sides of the field. */ class CraftyShieldTag extends ConditionalProtectTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.CRAFTY_SHIELD, Moves.CRAFTY_SHIELD, sourceId, side, CraftyShieldConditionFunc, true); } } @@ -383,12 +437,12 @@ class CraftyShieldTag extends ConditionalProtectTag { export class NoCritTag extends ArenaTag { /** * Constructor method for the NoCritTag class - * @param turnCount `integer` the number of turns this effect lasts + * @param turnCount `number` the number of turns this effect lasts * @param sourceMove {@linkcode Moves} the move that created this effect - * @param sourceId `integer` the ID of the {@linkcode Pokemon} that created this effect + * @param sourceId `number` the ID of the {@linkcode Pokemon} that created this effect * @param side {@linkcode ArenaTagSide} the side to which this effect belongs */ - constructor(turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceMove: Moves, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.NO_CRIT, turnCount, sourceMove, sourceId, side); } @@ -418,7 +472,7 @@ class WishTag extends ArenaTag { private triggerMessage: string; private healHp: number; - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.WISH, turnCount, Moves.WISH, sourceId, side); } @@ -428,7 +482,7 @@ class WishTag extends ArenaTag { if (user) { this.battlerIndex = user.getBattlerIndex(); this.triggerMessage = i18next.t("arenaTag:wishTagOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(user) }); - this.healHp = Utils.toDmgValue(user.getMaxHp() / 2); + this.healHp = toDmgValue(user.getMaxHp() / 2); } else { console.warn("Failed to get source for WishTag onAdd"); } @@ -459,18 +513,25 @@ export class WeakenMoveTypeTag extends ArenaTag { * @param sourceMove - The move that created the tag. * @param sourceId - The ID of the source of the tag. */ - constructor(tagType: ArenaTagType, turnCount: integer, type: Type, sourceMove: Moves, sourceId: integer) { + constructor(tagType: ArenaTagType, turnCount: number, type: Type, sourceMove: Moves, sourceId: number) { super(tagType, turnCount, sourceMove, sourceId); this.weakenedType = type; } - apply(arena: Arena, args: any[]): boolean { - if ((args[0] as Type) === this.weakenedType) { - (args[1] as Utils.NumberHolder).value *= 0.33; + /** + * Reduces an attack's power by 0.33x if it matches this tag's weakened type. + * @param arena n/a + * @param simulated n/a + * @param type the attack's {@linkcode Type} + * @param power a {@linkcode NumberHolder} containing the attack's power + * @returns `true` if the attack's power was reduced; `false` otherwise. + */ + override apply(arena: Arena, simulated: boolean, type: Type, power: NumberHolder): boolean { + if (type === this.weakenedType) { + power.value *= 0.33; return true; } - return false; } } @@ -480,7 +541,7 @@ export class WeakenMoveTypeTag extends ArenaTag { * Weakens Electric type moves for a set amount of turns, usually 5. */ class MudSportTag extends WeakenMoveTypeTag { - constructor(turnCount: integer, sourceId: integer) { + constructor(turnCount: number, sourceId: number) { super(ArenaTagType.MUD_SPORT, turnCount, Type.ELECTRIC, Moves.MUD_SPORT, sourceId); } @@ -498,7 +559,7 @@ class MudSportTag extends WeakenMoveTypeTag { * Weakens Fire type moves for a set amount of turns, usually 5. */ class WaterSportTag extends WeakenMoveTypeTag { - constructor(turnCount: integer, sourceId: integer) { + constructor(turnCount: number, sourceId: number) { super(ArenaTagType.WATER_SPORT, turnCount, Type.FIRE, Moves.WATER_SPORT, sourceId); } @@ -512,15 +573,16 @@ class WaterSportTag extends WeakenMoveTypeTag { } /** - * Arena Tag class for the secondary effect of {@link https://bulbapedia.bulbagarden.net/wiki/Plasma_Fists_(move) | Plasma Fists}. + * Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Ion_Deluge_(move) | Ion Deluge} + * and the secondary effect of {@link https://bulbapedia.bulbagarden.net/wiki/Plasma_Fists_(move) | Plasma Fists}. * Converts Normal-type moves to Electric type for the rest of the turn. */ -export class PlasmaFistsTag extends ArenaTag { - constructor() { - super(ArenaTagType.PLASMA_FISTS, 1, Moves.PLASMA_FISTS); +export class IonDelugeTag extends ArenaTag { + constructor(sourceMove?: Moves) { + super(ArenaTagType.ION_DELUGE, 1, sourceMove); } - /** Queues Plasma Fists' on-add message */ + /** Queues an on-add message */ onAdd(arena: Arena): void { arena.scene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd")); } @@ -530,13 +592,12 @@ export class PlasmaFistsTag extends ArenaTag { /** * Converts Normal-type moves to Electric type * @param arena n/a - * @param args - * - `[0]` {@linkcode Utils.NumberHolder} A container with a move's {@linkcode Type} + * @param simulated n/a + * @param moveType a {@linkcode NumberHolder} containing a move's {@linkcode Type} * @returns `true` if the given move type changed; `false` otherwise. */ - apply(arena: Arena, args: any[]): boolean { - const moveType = args[0]; - if (moveType instanceof Utils.NumberHolder && moveType.value === Type.NORMAL) { + override apply(arena: Arena, simulated: boolean, moveType: NumberHolder): boolean { + if (moveType.value === Type.NORMAL) { moveType.value = Type.ELECTRIC; return true; } @@ -548,8 +609,8 @@ export class PlasmaFistsTag extends ArenaTag { * Abstract class to implement arena traps. */ export class ArenaTrapTag extends ArenaTag { - public layers: integer; - public maxLayers: integer; + public layers: number; + public maxLayers: number; /** * Creates a new instance of the ArenaTrapTag class. @@ -560,7 +621,7 @@ export class ArenaTrapTag extends ArenaTag { * @param side - The side (player or enemy) the tag affects. * @param maxLayers - The maximum amount of layers this tag can have. */ - constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, maxLayers: integer) { + constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: number, side: ArenaTagSide, maxLayers: number) { super(tagType, 0, sourceMove, sourceId, side); this.layers = 1; @@ -575,22 +636,34 @@ export class ArenaTrapTag extends ArenaTag { } } - apply(arena: Arena, args: any[]): boolean { - const pokemon = args[0] as Pokemon; - if (this.sourceId === pokemon.id || (this.side === ArenaTagSide.PLAYER) !== pokemon.isPlayer()) { + /** + * Activates the hazard effect onto a Pokemon when it enters the field + * @param arena the {@linkcode Arena} containing this tag + * @param simulated if `true`, only checks if the hazard would activate. + * @param pokemon the {@linkcode Pokemon} triggering this hazard + * @returns `true` if this hazard affects the given Pokemon; `false` otherwise. + */ + override apply(arena: Arena, simulated: boolean, pokemon: Pokemon): boolean { + if ((this.side === ArenaTagSide.PLAYER) !== pokemon.isPlayer()) { return false; } - return this.activateTrap(pokemon); + return this.activateTrap(pokemon, simulated); } - activateTrap(pokemon: Pokemon): boolean { + activateTrap(pokemon: Pokemon, simulated: boolean): boolean { return false; } getMatchupScoreMultiplier(pokemon: Pokemon): number { return pokemon.isGrounded() ? 1 : Phaser.Math.Linear(0, 1 / Math.pow(2, this.layers), Math.min(pokemon.getHpRatio(), 0.5) * 2); } + + loadTag(source: any): void { + super.loadTag(source); + this.layers = source.layers; + this.maxLayers = source.maxLayers; + } } /** @@ -599,7 +672,7 @@ export class ArenaTrapTag extends ArenaTag { * in damage for 1, 2, or 3 layers of Spikes respectively if they are summoned into this trap. */ class SpikesTag extends ArenaTrapTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.SPIKES, Moves.SPIKES, sourceId, side, 3); } @@ -612,14 +685,18 @@ class SpikesTag extends ArenaTrapTag { } } - activateTrap(pokemon: Pokemon): boolean { + override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { if (pokemon.isGrounded()) { - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); + if (simulated) { + return !cancelled.value; + } + if (!cancelled.value) { const damageHpRatio = 1 / (10 - 2 * this.layers); - const damage = Utils.toDmgValue(pokemon.getMaxHp() * damageHpRatio); + const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); pokemon.scene.queueMessage(i18next.t("arenaTag:spikesActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.damageAndUpdate(damage, HitResult.OTHER); @@ -643,7 +720,7 @@ class SpikesTag extends ArenaTrapTag { class ToxicSpikesTag extends ArenaTrapTag { private neutralized: boolean; - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.TOXIC_SPIKES, Moves.TOXIC_SPIKES, sourceId, side, 2); this.neutralized = false; } @@ -663,8 +740,11 @@ class ToxicSpikesTag extends ArenaTrapTag { } } - activateTrap(pokemon: Pokemon): boolean { + override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { if (pokemon.isGrounded()) { + if (simulated) { + return true; + } if (pokemon.isOfType(Type.POISON)) { this.neutralized = true; if (pokemon.scene.arena.removeTag(this.tagType)) { @@ -701,7 +781,7 @@ class ToxicSpikesTag extends ArenaTrapTag { class DelayedAttackTag extends ArenaTag { public targetIndex: BattlerIndex; - constructor(tagType: ArenaTagType, sourceMove: Moves | undefined, sourceId: integer, targetIndex: BattlerIndex) { + constructor(tagType: ArenaTagType, sourceMove: Moves | undefined, sourceId: number, targetIndex: BattlerIndex) { super(tagType, 3, sourceMove, sourceId); this.targetIndex = targetIndex; @@ -726,7 +806,7 @@ class DelayedAttackTag extends ArenaTag { * who is summoned into the trap, based on the Rock type's type effectiveness. */ class StealthRockTag extends ArenaTrapTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.STEALTH_ROCK, Moves.STEALTH_ROCK, sourceId, side, 1); } @@ -745,31 +825,31 @@ class StealthRockTag extends ArenaTrapTag { let damageHpRatio: number = 0; switch (effectiveness) { - case 0: - damageHpRatio = 0; - break; - case 0.25: - damageHpRatio = 0.03125; - break; - case 0.5: - damageHpRatio = 0.0625; - break; - case 1: - damageHpRatio = 0.125; - break; - case 2: - damageHpRatio = 0.25; - break; - case 4: - damageHpRatio = 0.5; - break; + case 0: + damageHpRatio = 0; + break; + case 0.25: + damageHpRatio = 0.03125; + break; + case 0.5: + damageHpRatio = 0.0625; + break; + case 1: + damageHpRatio = 0.125; + break; + case 2: + damageHpRatio = 0.25; + break; + case 4: + damageHpRatio = 0.5; + break; } return damageHpRatio; } - activateTrap(pokemon: Pokemon): boolean { - const cancelled = new Utils.BooleanHolder(false); + override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (cancelled.value) { @@ -779,12 +859,16 @@ class StealthRockTag extends ArenaTrapTag { const damageHpRatio = this.getDamageHpRatio(pokemon); if (damageHpRatio) { - const damage = Utils.toDmgValue(pokemon.getMaxHp() * damageHpRatio); + if (simulated) { + return true; + } + const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); pokemon.scene.queueMessage(i18next.t("arenaTag:stealthRockActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.damageAndUpdate(damage, HitResult.OTHER); if (pokemon.turnData) { pokemon.turnData.damageTaken += damage; } + return true; } return false; @@ -802,7 +886,7 @@ class StealthRockTag extends ArenaTrapTag { * to any Pokémon who is summoned into this trap. */ class StickyWebTag extends ArenaTrapTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.STICKY_WEB, Moves.STICKY_WEB, sourceId, side, 1); } @@ -814,14 +898,20 @@ class StickyWebTag extends ArenaTrapTag { } } - activateTrap(pokemon: Pokemon): boolean { + override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { if (pokemon.isGrounded()) { - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(ProtectStatAbAttr, pokemon, cancelled); + + if (simulated) { + return !cancelled.value; + } + if (!cancelled.value) { pokemon.scene.queueMessage(i18next.t("arenaTag:stickyWebActivateTrap", { pokemonName: pokemon.getNameToRender() })); - const stages = new Utils.NumberHolder(-1); + const stages = new NumberHolder(-1); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [ Stat.SPD ], stages.value)); + return true; } } @@ -836,12 +926,19 @@ class StickyWebTag extends ArenaTrapTag { * also reversing the turn order for all Pokémon on the field as well. */ export class TrickRoomTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer) { + constructor(turnCount: number, sourceId: number) { super(ArenaTagType.TRICK_ROOM, turnCount, Moves.TRICK_ROOM, sourceId); } - apply(arena: Arena, args: any[]): boolean { - const speedReversed = args[0] as Utils.BooleanHolder; + /** + * Reverses Speed-based turn order for all Pokemon on the field + * @param arena n/a + * @param simulated n/a + * @param speedReversed a {@linkcode BooleanHolder} used to flag if Speed-based + * turn order should be reversed. + * @returns `true` if turn order is successfully reversed; `false` otherwise + */ + override apply(arena: Arena, simulated: boolean, speedReversed: BooleanHolder): boolean { speedReversed.value = !speedReversed.value; return true; } @@ -864,7 +961,7 @@ export class TrickRoomTag extends ArenaTag { * {@linkcode Abilities.LEVITATE} for the duration of the arena tag, usually 5 turns. */ export class GravityTag extends ArenaTag { - constructor(turnCount: integer) { + constructor(turnCount: number) { super(ArenaTagType.GRAVITY, turnCount, Moves.GRAVITY); } @@ -872,7 +969,11 @@ export class GravityTag extends ArenaTag { arena.scene.queueMessage(i18next.t("arenaTag:gravityOnAdd")); arena.scene.getField(true).forEach((pokemon) => { if (pokemon !== null) { - pokemon.removeTag(BattlerTagType.MAGNET_RISEN); + pokemon.removeTag(BattlerTagType.FLOATING); + pokemon.removeTag(BattlerTagType.TELEKINESIS); + if (pokemon.getTag(BattlerTagType.FLYING)) { + pokemon.addTag(BattlerTagType.INTERRUPTED); + } } }); } @@ -888,7 +989,7 @@ export class GravityTag extends ArenaTag { * Applies this arena tag for 4 turns (including the turn the move was used). */ class TailwindTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side); } @@ -926,7 +1027,7 @@ class TailwindTag extends ArenaTag { * Doubles the prize money from trainers and money moves like {@linkcode Moves.PAY_DAY} and {@linkcode Moves.MAKE_IT_RAIN}. */ class HappyHourTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.HAPPY_HOUR, turnCount, Moves.HAPPY_HOUR, sourceId, side); } @@ -940,7 +1041,7 @@ class HappyHourTag extends ArenaTag { } class SafeguardTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.SAFEGUARD, turnCount, Moves.SAFEGUARD, sourceId, side); } @@ -953,42 +1054,35 @@ class SafeguardTag extends ArenaTag { } } +class NoneTag extends ArenaTag { + constructor() { + super(ArenaTagType.NONE, 0); + } +} /** * This arena tag facilitates the application of the move Imprison * Imprison remains in effect as long as the source Pokemon is active and present on the field. * Imprison will apply to any opposing Pokemon that switch onto the field as well. */ class ImprisonTag extends ArenaTrapTag { - private source: Pokemon; - constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.IMPRISON, Moves.IMPRISON, sourceId, side, 1); } - /** - * Helper function that retrieves the Pokemon affected - * @param {BattleScene} scene medium to retrieve the involved Pokemon - * @returns list of PlayerPokemon or EnemyPokemon on the field - */ - private retrieveField(scene: BattleScene): PlayerPokemon[] | EnemyPokemon[] { - if (!this.source.isPlayer()) { - return scene.getPlayerField() ?? []; - } - return scene.getEnemyField() ?? []; - } - /** * This function applies the effects of Imprison to the opposing Pokemon already present on the field. * @param arena */ override onAdd({ scene }: Arena) { - this.source = scene.getPokemonById(this.sourceId!)!; - if (this.source) { - const party = this.retrieveField(scene); - party?.forEach((p: PlayerPokemon | EnemyPokemon ) => { - p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); + const source = this.getSourcePokemon(scene); + if (source) { + const party = this.getAffectedPokemon(scene); + party?.forEach((p: Pokemon ) => { + if (p.isAllowedInBattle()) { + p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); + } }); - scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", {pokemonNameWithAffix: getPokemonNameWithAffix(this.source)})); + scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) })); } } @@ -997,8 +1091,9 @@ class ImprisonTag extends ArenaTrapTag { * @param _arena * @returns `true` if the source of the tag is still active on the field | `false` if not */ - override lapse(_arena: Arena): boolean { - return this.source.isActive(true); + override lapse({ scene }: Arena): boolean { + const source = this.getSourcePokemon(scene); + return source ? source.isActive(true) : false; } /** @@ -1007,7 +1102,8 @@ class ImprisonTag extends ArenaTrapTag { * @returns `true` */ override activateTrap(pokemon: Pokemon): boolean { - if (this.source.isActive(true)) { + const source = this.getSourcePokemon(pokemon.scene); + if (source && source.isActive(true) && pokemon.isAllowedInBattle()) { pokemon.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); } return true; @@ -1018,65 +1114,167 @@ class ImprisonTag extends ArenaTrapTag { * @param arena */ override onRemove({ scene }: Arena): void { - const party = this.retrieveField(scene); - party?.forEach((p: PlayerPokemon | EnemyPokemon) => { + const party = this.getAffectedPokemon(scene); + party?.forEach((p: Pokemon) => { p.removeTag(BattlerTagType.IMPRISON); }); } } -export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null { - switch (tagType) { - case ArenaTagType.MIST: - return new MistTag(turnCount, sourceId, side); - case ArenaTagType.QUICK_GUARD: - return new QuickGuardTag(sourceId, side); - case ArenaTagType.WIDE_GUARD: - return new WideGuardTag(sourceId, side); - case ArenaTagType.MAT_BLOCK: - return new MatBlockTag(sourceId, side); - case ArenaTagType.CRAFTY_SHIELD: - return new CraftyShieldTag(sourceId, side); - case ArenaTagType.NO_CRIT: - return new NoCritTag(turnCount, sourceMove!, sourceId, side); // TODO: is this bang correct? - case ArenaTagType.MUD_SPORT: - return new MudSportTag(turnCount, sourceId); - case ArenaTagType.WATER_SPORT: - return new WaterSportTag(turnCount, sourceId); - case ArenaTagType.PLASMA_FISTS: - return new PlasmaFistsTag(); - case ArenaTagType.SPIKES: - return new SpikesTag(sourceId, side); - case ArenaTagType.TOXIC_SPIKES: - return new ToxicSpikesTag(sourceId, side); - case ArenaTagType.FUTURE_SIGHT: - case ArenaTagType.DOOM_DESIRE: - return new DelayedAttackTag(tagType, sourceMove, sourceId, targetIndex!); // TODO:questionable bang - case ArenaTagType.WISH: - return new WishTag(turnCount, sourceId, side); - case ArenaTagType.STEALTH_ROCK: - return new StealthRockTag(sourceId, side); - case ArenaTagType.STICKY_WEB: - return new StickyWebTag(sourceId, side); - case ArenaTagType.TRICK_ROOM: - return new TrickRoomTag(turnCount, sourceId); - case ArenaTagType.GRAVITY: - return new GravityTag(turnCount); - case ArenaTagType.REFLECT: - return new ReflectTag(turnCount, sourceId, side); - case ArenaTagType.LIGHT_SCREEN: - return new LightScreenTag(turnCount, sourceId, side); - case ArenaTagType.AURORA_VEIL: - return new AuroraVeilTag(turnCount, sourceId, side); - case ArenaTagType.TAILWIND: - return new TailwindTag(turnCount, sourceId, side); - case ArenaTagType.HAPPY_HOUR: - return new HappyHourTag(turnCount, sourceId, side); - case ArenaTagType.SAFEGUARD: - return new SafeguardTag(turnCount, sourceId, side); - case ArenaTagType.IMPRISON: - return new ImprisonTag(sourceId, side); - default: - return null; +/** + * Arena Tag implementing the "sea of fire" effect from the combination + * of {@link https://bulbapedia.bulbagarden.net/wiki/Fire_Pledge_(move) | Fire Pledge} + * and {@link https://bulbapedia.bulbagarden.net/wiki/Grass_Pledge_(move) | Grass Pledge}. + * Damages all non-Fire-type Pokemon on the given side of the field at the end + * of each turn for 4 turns. + */ +class FireGrassPledgeTag extends ArenaTag { + constructor(sourceId: number, side: ArenaTagSide) { + super(ArenaTagType.FIRE_GRASS_PLEDGE, 4, Moves.FIRE_PLEDGE, sourceId, side); + } + + override onAdd(arena: Arena): void { + // "A sea of fire enveloped your/the opposing team!" + arena.scene.queueMessage(i18next.t(`arenaTag:fireGrassPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); + } + + override lapse(arena: Arena): boolean { + const field: Pokemon[] = (this.side === ArenaTagSide.PLAYER) + ? arena.scene.getPlayerField() + : arena.scene.getEnemyField(); + + field.filter(pokemon => !pokemon.isOfType(Type.FIRE)).forEach(pokemon => { + // "{pokemonNameWithAffix} was hurt by the sea of fire!" + pokemon.scene.queueMessage(i18next.t("arenaTag:fireGrassPledgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + // TODO: Replace this with a proper animation + pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.MAGMA_STORM)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8)); + }); + + return super.lapse(arena); } } + +/** + * Arena Tag implementing the "rainbow" effect from the combination + * of {@link https://bulbapedia.bulbagarden.net/wiki/Water_Pledge_(move) | Water Pledge} + * and {@link https://bulbapedia.bulbagarden.net/wiki/Fire_Pledge_(move) | Fire Pledge}. + * Doubles the secondary effect chance of moves from Pokemon on the + * given side of the field for 4 turns. + */ +class WaterFirePledgeTag extends ArenaTag { + constructor(sourceId: number, side: ArenaTagSide) { + super(ArenaTagType.WATER_FIRE_PLEDGE, 4, Moves.WATER_PLEDGE, sourceId, side); + } + + override onAdd(arena: Arena): void { + // "A rainbow appeared in the sky on your/the opposing team's side!" + arena.scene.queueMessage(i18next.t(`arenaTag:waterFirePledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); + } + + /** + * Doubles the chance for the given move's secondary effect(s) to trigger + * @param arena the {@linkcode Arena} containing this tag + * @param simulated n/a + * @param moveChance a {@linkcode NumberHolder} containing + * the move's current effect chance + * @returns `true` if the move's effect chance was doubled (currently always `true`) + */ + override apply(arena: Arena, simulated: boolean, moveChance: NumberHolder): boolean { + moveChance.value *= 2; + return true; + } +} + +/** + * Arena Tag implementing the "swamp" effect from the combination + * of {@link https://bulbapedia.bulbagarden.net/wiki/Grass_Pledge_(move) | Grass Pledge} + * and {@link https://bulbapedia.bulbagarden.net/wiki/Water_Pledge_(move) | Water Pledge}. + * Quarters the Speed of Pokemon on the given side of the field for 4 turns. + */ +class GrassWaterPledgeTag extends ArenaTag { + constructor(sourceId: number, side: ArenaTagSide) { + super(ArenaTagType.GRASS_WATER_PLEDGE, 4, Moves.GRASS_PLEDGE, sourceId, side); + } + + override onAdd(arena: Arena): void { + // "A swamp enveloped your/the opposing team!" + arena.scene.queueMessage(i18next.t(`arenaTag:grassWaterPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); + } +} + +// TODO: swap `sourceMove` and `sourceId` and make `sourceMove` an optional parameter +export function getArenaTag(tagType: ArenaTagType, turnCount: number, sourceMove: Moves | undefined, sourceId: number, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null { + switch (tagType) { + case ArenaTagType.MIST: + return new MistTag(turnCount, sourceId, side); + case ArenaTagType.QUICK_GUARD: + return new QuickGuardTag(sourceId, side); + case ArenaTagType.WIDE_GUARD: + return new WideGuardTag(sourceId, side); + case ArenaTagType.MAT_BLOCK: + return new MatBlockTag(sourceId, side); + case ArenaTagType.CRAFTY_SHIELD: + return new CraftyShieldTag(sourceId, side); + case ArenaTagType.NO_CRIT: + return new NoCritTag(turnCount, sourceMove!, sourceId, side); // TODO: is this bang correct? + case ArenaTagType.MUD_SPORT: + return new MudSportTag(turnCount, sourceId); + case ArenaTagType.WATER_SPORT: + return new WaterSportTag(turnCount, sourceId); + case ArenaTagType.ION_DELUGE: + return new IonDelugeTag(sourceMove); + case ArenaTagType.SPIKES: + return new SpikesTag(sourceId, side); + case ArenaTagType.TOXIC_SPIKES: + return new ToxicSpikesTag(sourceId, side); + case ArenaTagType.FUTURE_SIGHT: + case ArenaTagType.DOOM_DESIRE: + return new DelayedAttackTag(tagType, sourceMove, sourceId, targetIndex!); // TODO:questionable bang + case ArenaTagType.WISH: + return new WishTag(turnCount, sourceId, side); + case ArenaTagType.STEALTH_ROCK: + return new StealthRockTag(sourceId, side); + case ArenaTagType.STICKY_WEB: + return new StickyWebTag(sourceId, side); + case ArenaTagType.TRICK_ROOM: + return new TrickRoomTag(turnCount, sourceId); + case ArenaTagType.GRAVITY: + return new GravityTag(turnCount); + case ArenaTagType.REFLECT: + return new ReflectTag(turnCount, sourceId, side); + case ArenaTagType.LIGHT_SCREEN: + return new LightScreenTag(turnCount, sourceId, side); + case ArenaTagType.AURORA_VEIL: + return new AuroraVeilTag(turnCount, sourceId, side); + case ArenaTagType.TAILWIND: + return new TailwindTag(turnCount, sourceId, side); + case ArenaTagType.HAPPY_HOUR: + return new HappyHourTag(turnCount, sourceId, side); + case ArenaTagType.SAFEGUARD: + return new SafeguardTag(turnCount, sourceId, side); + case ArenaTagType.IMPRISON: + return new ImprisonTag(sourceId, side); + case ArenaTagType.FIRE_GRASS_PLEDGE: + return new FireGrassPledgeTag(sourceId, side); + case ArenaTagType.WATER_FIRE_PLEDGE: + return new WaterFirePledgeTag(sourceId, side); + case ArenaTagType.GRASS_WATER_PLEDGE: + return new GrassWaterPledgeTag(sourceId, side); + default: + return null; + } +} + +/** + * When given a battler tag or json representing one, creates an actual ArenaTag object with the same data. + * @param {ArenaTag | any} source An arena tag + * @return {ArenaTag} The valid arena tag + */ +export function loadArenaTag(source: ArenaTag | any): ArenaTag { + const tag = getArenaTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId, source.targetIndex, source.side) + ?? new NoneTag(); + tag.loadTag(source); + return tag; +} + diff --git a/src/data/balance/biomes.ts b/src/data/balance/biomes.ts index 82413b1c009..dc811e645c8 100644 --- a/src/data/balance/biomes.ts +++ b/src/data/balance/biomes.ts @@ -13,14 +13,14 @@ export function getBiomeName(biome: Biome | -1) { return i18next.t("biome:unknownLocation"); } switch (biome) { - case Biome.GRASS: - return i18next.t("biome:GRASS"); - case Biome.RUINS: - return i18next.t("biome:RUINS"); - case Biome.END: - return i18next.t("biome:END"); - default: - return i18next.t(`biome:${Biome[biome].toUpperCase()}`); + case Biome.GRASS: + return i18next.t("biome:GRASS"); + case Biome.RUINS: + return i18next.t("biome:RUINS"); + case Biome.END: + return i18next.t("biome:END"); + default: + return i18next.t(`biome:${Biome[biome].toUpperCase()}`); } } @@ -37,34 +37,34 @@ export const biomeLinks: BiomeLinks = { [Biome.PLAINS]: [ Biome.GRASS, Biome.METROPOLIS, Biome.LAKE ], [Biome.GRASS]: Biome.TALL_GRASS, [Biome.TALL_GRASS]: [ Biome.FOREST, Biome.CAVE ], - [Biome.SLUM]: [ Biome.CONSTRUCTION_SITE, [ Biome.SWAMP, 2 ] ], + [Biome.SLUM]: [ Biome.CONSTRUCTION_SITE, [ Biome.SWAMP, 2 ]], [Biome.FOREST]: [ Biome.JUNGLE, Biome.MEADOW ], [Biome.SEA]: [ Biome.SEABED, Biome.ICE_CAVE ], [Biome.SWAMP]: [ Biome.GRAVEYARD, Biome.TALL_GRASS ], - [Biome.BEACH]: [ Biome.SEA, [ Biome.ISLAND, 2 ] ], + [Biome.BEACH]: [ Biome.SEA, [ Biome.ISLAND, 2 ]], [Biome.LAKE]: [ Biome.BEACH, Biome.SWAMP, Biome.CONSTRUCTION_SITE ], - [Biome.SEABED]: [ Biome.CAVE, [ Biome.VOLCANO, 3 ] ], - [Biome.MOUNTAIN]: [ Biome.VOLCANO, [ Biome.WASTELAND, 2 ], [ Biome.SPACE, 3 ] ], + [Biome.SEABED]: [ Biome.CAVE, [ Biome.VOLCANO, 3 ]], + [Biome.MOUNTAIN]: [ Biome.VOLCANO, [ Biome.WASTELAND, 2 ], [ Biome.SPACE, 3 ]], [Biome.BADLANDS]: [ Biome.DESERT, Biome.MOUNTAIN ], - [Biome.CAVE]: [ Biome.BADLANDS, Biome.LAKE, [ Biome.LABORATORY, 2 ] ], - [Biome.DESERT]: [ Biome.RUINS, [ Biome.CONSTRUCTION_SITE, 2 ] ], + [Biome.CAVE]: [ Biome.BADLANDS, Biome.LAKE, [ Biome.LABORATORY, 2 ]], + [Biome.DESERT]: [ Biome.RUINS, [ Biome.CONSTRUCTION_SITE, 2 ]], [Biome.ICE_CAVE]: Biome.SNOWY_FOREST, [Biome.MEADOW]: [ Biome.PLAINS, Biome.FAIRY_CAVE ], [Biome.POWER_PLANT]: Biome.FACTORY, - [Biome.VOLCANO]: [ Biome.BEACH, [ Biome.ICE_CAVE, 3 ] ], + [Biome.VOLCANO]: [ Biome.BEACH, [ Biome.ICE_CAVE, 3 ]], [Biome.GRAVEYARD]: Biome.ABYSS, - [Biome.DOJO]: [ Biome.PLAINS, [ Biome.JUNGLE, 2], [ Biome.TEMPLE, 2 ] ], - [Biome.FACTORY]: [ Biome.PLAINS, [ Biome.LABORATORY, 2 ] ], - [Biome.RUINS]: [ Biome.MOUNTAIN, [ Biome.FOREST, 2 ] ], + [Biome.DOJO]: [ Biome.PLAINS, [ Biome.JUNGLE, 2 ], [ Biome.TEMPLE, 2 ]], + [Biome.FACTORY]: [ Biome.PLAINS, [ Biome.LABORATORY, 2 ]], + [Biome.RUINS]: [ Biome.MOUNTAIN, [ Biome.FOREST, 2 ]], [Biome.WASTELAND]: Biome.BADLANDS, - [Biome.ABYSS]: [ Biome.CAVE, [ Biome.SPACE, 2 ], [ Biome.WASTELAND, 2 ] ], + [Biome.ABYSS]: [ Biome.CAVE, [ Biome.SPACE, 2 ], [ Biome.WASTELAND, 2 ]], [Biome.SPACE]: Biome.RUINS, - [Biome.CONSTRUCTION_SITE]: [ Biome.POWER_PLANT, [ Biome.DOJO, 2 ] ], + [Biome.CONSTRUCTION_SITE]: [ Biome.POWER_PLANT, [ Biome.DOJO, 2 ]], [Biome.JUNGLE]: [ Biome.TEMPLE ], - [Biome.FAIRY_CAVE]: [ Biome.ICE_CAVE, [ Biome.SPACE, 2 ] ], - [Biome.TEMPLE]: [ Biome.DESERT, [ Biome.SWAMP, 2 ], [ Biome.RUINS, 2 ] ], + [Biome.FAIRY_CAVE]: [ Biome.ICE_CAVE, [ Biome.SPACE, 2 ]], + [Biome.TEMPLE]: [ Biome.DESERT, [ Biome.SWAMP, 2 ], [ Biome.RUINS, 2 ]], [Biome.METROPOLIS]: Biome.SLUM, - [Biome.SNOWY_FOREST]: [ Biome.FOREST, [ Biome.MOUNTAIN, 2 ], [ Biome.LAKE, 2 ] ], + [Biome.SNOWY_FOREST]: [ Biome.FOREST, [ Biome.MOUNTAIN, 2 ], [ Biome.LAKE, 2 ]], [Biome.ISLAND]: Biome.SEA, [Biome.LABORATORY]: Biome.CONSTRUCTION_SITE }; @@ -113,7 +113,7 @@ export const biomePokemonPools: BiomePokemonPools = { [Biome.TOWN]: { [BiomePoolTier.COMMON]: { [TimeOfDay.DAWN]: [ - { 1: [ Species.CATERPIE ], 7: [ Species.METAPOD ] }, + { 1: [ Species.CATERPIE ], 7: [ Species.METAPOD ]}, Species.SENTRET, Species.LEDYBA, Species.HOPPIP, @@ -121,12 +121,12 @@ export const biomePokemonPools: BiomePokemonPools = { Species.STARLY, Species.PIDOVE, Species.COTTONEE, - { 1: [ Species.SCATTERBUG ], 9: [ Species.SPEWPA ] }, + { 1: [ Species.SCATTERBUG ], 9: [ Species.SPEWPA ]}, Species.YUNGOOS, Species.SKWOVET ], [TimeOfDay.DAY]: [ - { 1: [ Species.CATERPIE ], 7: [ Species.METAPOD ] }, + { 1: [ Species.CATERPIE ], 7: [ Species.METAPOD ]}, Species.SENTRET, Species.HOPPIP, Species.SUNKERN, @@ -134,12 +134,12 @@ export const biomePokemonPools: BiomePokemonPools = { Species.STARLY, Species.PIDOVE, Species.COTTONEE, - { 1: [ Species.SCATTERBUG ], 9: [ Species.SPEWPA ] }, + { 1: [ Species.SCATTERBUG ], 9: [ Species.SPEWPA ]}, Species.YUNGOOS, Species.SKWOVET ], - [TimeOfDay.DUSK]: [ { 1: [ Species.WEEDLE ], 7: [ Species.KAKUNA ] }, Species.POOCHYENA, Species.PATRAT, Species.PURRLOIN, Species.BLIPBUG ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.WEEDLE ], 7: [ Species.KAKUNA ] }, Species.HOOTHOOT, Species.SPINARAK, Species.POOCHYENA, Species.CASCOON, Species.PATRAT, Species.PURRLOIN, Species.BLIPBUG ], + [TimeOfDay.DUSK]: [{ 1: [ Species.WEEDLE ], 7: [ Species.KAKUNA ]}, Species.POOCHYENA, Species.PATRAT, Species.PURRLOIN, Species.BLIPBUG ], + [TimeOfDay.NIGHT]: [{ 1: [ Species.WEEDLE ], 7: [ Species.KAKUNA ]}, Species.HOOTHOOT, Species.SPINARAK, Species.POOCHYENA, Species.CASCOON, Species.PATRAT, Species.PURRLOIN, Species.BLIPBUG ], [TimeOfDay.ALL]: [ Species.PIDGEY, Species.RATTATA, Species.SPEAROW, Species.ZIGZAGOON, Species.WURMPLE, Species.TAILLOW, Species.BIDOOF, Species.LILLIPUP, Species.FLETCHLING, Species.WOOLOO, Species.LECHONK ] }, [BiomePoolTier.UNCOMMON]: { @@ -149,56 +149,56 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.EKANS, Species.ODDISH, Species.PARAS, Species.VENONAT, Species.MEOWTH, Species.SEEDOT, Species.SHROOMISH, Species.KRICKETOT, Species.VENIPEDE ], [TimeOfDay.ALL]: [ Species.NINCADA, Species.WHISMUR, Species.FIDOUGH ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [ Species.TANDEMAUS ], [TimeOfDay.DAY]: [ Species.TANDEMAUS ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ABRA, Species.SURSKIT, Species.ROOKIDEE ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.EEVEE, Species.RALTS ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [ Species.TANDEMAUS ], [TimeOfDay.DAY]: [ Species.TANDEMAUS ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ABRA, Species.SURSKIT, Species.ROOKIDEE ]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.EEVEE, Species.RALTS ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.PLAINS]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.SENTRET ], 15: [ Species.FURRET ] }, { 1: [ Species.YUNGOOS ], 30: [ Species.GUMSHOOS ] }, { 1: [ Species.SKWOVET ], 24: [ Species.GREEDENT ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.SENTRET ], 15: [ Species.FURRET ] }, { 1: [ Species.YUNGOOS ], 30: [ Species.GUMSHOOS ] }, { 1: [ Species.SKWOVET ], 24: [ Species.GREEDENT ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.MEOWTH ], 28: [ Species.PERSIAN ] }, { 1: [ Species.POOCHYENA ], 18: [ Species.MIGHTYENA ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.ZUBAT ], 22: [ Species.GOLBAT ] }, { 1: [ Species.MEOWTH ], 28: [ Species.PERSIAN ] }, { 1: [ Species.POOCHYENA ], 18: [ Species.MIGHTYENA ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.ZIGZAGOON ], 20: [ Species.LINOONE ] }, { 1: [ Species.BIDOOF ], 15: [ Species.BIBAREL ] }, { 1: [ Species.LECHONK ], 18: [ Species.OINKOLOGNE ] } ] + [TimeOfDay.DAWN]: [{ 1: [ Species.SENTRET ], 15: [ Species.FURRET ]}, { 1: [ Species.YUNGOOS ], 30: [ Species.GUMSHOOS ]}, { 1: [ Species.SKWOVET ], 24: [ Species.GREEDENT ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.SENTRET ], 15: [ Species.FURRET ]}, { 1: [ Species.YUNGOOS ], 30: [ Species.GUMSHOOS ]}, { 1: [ Species.SKWOVET ], 24: [ Species.GREEDENT ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.MEOWTH ], 28: [ Species.PERSIAN ]}, { 1: [ Species.POOCHYENA ], 18: [ Species.MIGHTYENA ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.ZUBAT ], 22: [ Species.GOLBAT ]}, { 1: [ Species.MEOWTH ], 28: [ Species.PERSIAN ]}, { 1: [ Species.POOCHYENA ], 18: [ Species.MIGHTYENA ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.ZIGZAGOON ], 20: [ Species.LINOONE ]}, { 1: [ Species.BIDOOF ], 15: [ Species.BIBAREL ]}, { 1: [ Species.LECHONK ], 18: [ Species.OINKOLOGNE ]}] }, [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [ - { 1: [ Species.DODUO ], 31: [ Species.DODRIO ] }, - { 1: [ Species.POOCHYENA ], 18: [ Species.MIGHTYENA ] }, - { 1: [ Species.STARLY ], 14: [ Species.STARAVIA ], 34: [ Species.STARAPTOR ] }, - { 1: [ Species.PIDOVE ], 21: [ Species.TRANQUILL ], 32: [ Species.UNFEZANT ] }, - { 1: [ Species.PAWMI ], 18: [ Species.PAWMO ], 32: [ Species.PAWMOT ] } + { 1: [ Species.DODUO ], 31: [ Species.DODRIO ]}, + { 1: [ Species.POOCHYENA ], 18: [ Species.MIGHTYENA ]}, + { 1: [ Species.STARLY ], 14: [ Species.STARAVIA ], 34: [ Species.STARAPTOR ]}, + { 1: [ Species.PIDOVE ], 21: [ Species.TRANQUILL ], 32: [ Species.UNFEZANT ]}, + { 1: [ Species.PAWMI ], 18: [ Species.PAWMO ], 32: [ Species.PAWMOT ]} ], [TimeOfDay.DAY]: [ - { 1: [ Species.DODUO ], 31: [ Species.DODRIO ] }, - { 1: [ Species.POOCHYENA ], 18: [ Species.MIGHTYENA ] }, - { 1: [ Species.STARLY ], 14: [ Species.STARAVIA ], 34: [ Species.STARAPTOR ] }, - { 1: [ Species.PIDOVE ], 21: [ Species.TRANQUILL ], 32: [ Species.UNFEZANT ] }, - { 1: [ Species.ROCKRUFF ], 25: [ Species.LYCANROC ] }, - { 1: [ Species.PAWMI ], 18: [ Species.PAWMO ], 32: [ Species.PAWMOT ] } + { 1: [ Species.DODUO ], 31: [ Species.DODRIO ]}, + { 1: [ Species.POOCHYENA ], 18: [ Species.MIGHTYENA ]}, + { 1: [ Species.STARLY ], 14: [ Species.STARAVIA ], 34: [ Species.STARAPTOR ]}, + { 1: [ Species.PIDOVE ], 21: [ Species.TRANQUILL ], 32: [ Species.UNFEZANT ]}, + { 1: [ Species.ROCKRUFF ], 25: [ Species.LYCANROC ]}, + { 1: [ Species.PAWMI ], 18: [ Species.PAWMO ], 32: [ Species.PAWMOT ]} ], - [TimeOfDay.DUSK]: [ { 1: [ Species.MANKEY ], 28: [ Species.PRIMEAPE ], 75: [ Species.ANNIHILAPE ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.MANKEY ], 28: [ Species.PRIMEAPE ], 75: [ Species.ANNIHILAPE ] } ], + [TimeOfDay.DUSK]: [{ 1: [ Species.MANKEY ], 28: [ Species.PRIMEAPE ], 75: [ Species.ANNIHILAPE ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.MANKEY ], 28: [ Species.PRIMEAPE ], 75: [ Species.ANNIHILAPE ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.PIDGEY ], 18: [ Species.PIDGEOTTO ], 36: [ Species.PIDGEOT ] }, - { 1: [ Species.SPEAROW ], 20: [ Species.FEAROW ] }, + { 1: [ Species.PIDGEY ], 18: [ Species.PIDGEOTTO ], 36: [ Species.PIDGEOT ]}, + { 1: [ Species.SPEAROW ], 20: [ Species.FEAROW ]}, Species.PIKACHU, - { 1: [ Species.FLETCHLING ], 17: [ Species.FLETCHINDER ], 35: [ Species.TALONFLAME ] } + { 1: [ Species.FLETCHLING ], 17: [ Species.FLETCHINDER ], 35: [ Species.TALONFLAME ]} ] }, [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [ Species.PALDEA_TAUROS ], [TimeOfDay.DAY]: [ Species.PALDEA_TAUROS ], - [TimeOfDay.DUSK]: [ { 1: [ Species.SHINX ], 15: [ Species.LUXIO ], 30: [ Species.LUXRAY ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.SHINX ], 15: [ Species.LUXIO ], 30: [ Species.LUXRAY ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.ABRA ], 16: [ Species.KADABRA ] }, { 1: [ Species.BUNEARY ], 20: [ Species.LOPUNNY ] }, { 1: [ Species.ROOKIDEE ], 18: [ Species.CORVISQUIRE ], 38: [ Species.CORVIKNIGHT ] } ] + [TimeOfDay.DUSK]: [{ 1: [ Species.SHINX ], 15: [ Species.LUXIO ], 30: [ Species.LUXRAY ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.SHINX ], 15: [ Species.LUXIO ], 30: [ Species.LUXRAY ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.ABRA ], 16: [ Species.KADABRA ]}, { 1: [ Species.BUNEARY ], 20: [ Species.LOPUNNY ]}, { 1: [ Species.ROOKIDEE ], 18: [ Species.CORVISQUIRE ], 38: [ Species.CORVIKNIGHT ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.FARFETCHD, Species.LICKITUNG, Species.CHANSEY, Species.EEVEE, Species.SNORLAX, { 1: [ Species.DUNSPARCE ], 62: [ Species.DUDUNSPARCE ] } ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO, Species.LATIAS, Species.LATIOS ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.FARFETCHD, Species.LICKITUNG, Species.CHANSEY, Species.EEVEE, Species.SNORLAX, { 1: [ Species.DUNSPARCE ], 62: [ Species.DUDUNSPARCE ]}]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO, Species.LATIAS, Species.LATIOS ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.DODRIO, Species.FURRET, Species.GUMSHOOS, Species.GREEDENT ], [TimeOfDay.DAY]: [ Species.DODRIO, Species.FURRET, Species.GUMSHOOS, Species.GREEDENT ], @@ -213,22 +213,22 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.FARFETCHD, Species.SNORLAX, Species.LICKILICKY, Species.DUDUNSPARCE ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.LATIAS, Species.LATIOS ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.LATIAS, Species.LATIOS ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.GRASS]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.HOPPIP ], 18: [ Species.SKIPLOOM ] }, Species.SUNKERN, Species.COTTONEE, Species.PETILIL ], - [TimeOfDay.DAY]: [ { 1: [ Species.HOPPIP ], 18: [ Species.SKIPLOOM ] }, Species.SUNKERN, Species.COTTONEE, Species.PETILIL ], - [TimeOfDay.DUSK]: [ { 1: [ Species.SEEDOT ], 14: [ Species.NUZLEAF ] }, { 1: [ Species.SHROOMISH ], 23: [ Species.BRELOOM ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.SEEDOT ], 14: [ Species.NUZLEAF ] }, { 1: [ Species.SHROOMISH ], 23: [ Species.BRELOOM ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.HOPPIP ], 18: [ Species.SKIPLOOM ]}, Species.SUNKERN, Species.COTTONEE, Species.PETILIL ], + [TimeOfDay.DAY]: [{ 1: [ Species.HOPPIP ], 18: [ Species.SKIPLOOM ]}, Species.SUNKERN, Species.COTTONEE, Species.PETILIL ], + [TimeOfDay.DUSK]: [{ 1: [ Species.SEEDOT ], 14: [ Species.NUZLEAF ]}, { 1: [ Species.SHROOMISH ], 23: [ Species.BRELOOM ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.SEEDOT ], 14: [ Species.NUZLEAF ]}, { 1: [ Species.SHROOMISH ], 23: [ Species.BRELOOM ]}], [TimeOfDay.ALL]: [] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.COMBEE ], 21: [ Species.VESPIQUEN ] }, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.COMBEE ], 21: [ Species.VESPIQUEN ] }, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.COMBEE ], 21: [ Species.VESPIQUEN ]}, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.COMBEE ], 21: [ Species.VESPIQUEN ]}, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ]}], [TimeOfDay.ALL]: [] }, [BiomePoolTier.RARE]: { @@ -236,28 +236,28 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.BULBASAUR ], 16: [ Species.IVYSAUR ], 32: [ Species.VENUSAUR ] }, Species.GROWLITHE, { 1: [ Species.TURTWIG ], 18: [ Species.GROTLE ], 32: [ Species.TORTERRA ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.BULBASAUR ], 16: [ Species.IVYSAUR ], 32: [ Species.VENUSAUR ]}, Species.GROWLITHE, { 1: [ Species.TURTWIG ], 18: [ Species.GROTLE ], 32: [ Species.TORTERRA ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SUDOWOODO ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.VIRIZION ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.JUMPLUFF, Species.SUNFLORA, Species.WHIMSICOTT ], [TimeOfDay.DAY]: [ Species.JUMPLUFF, Species.SUNFLORA, Species.WHIMSICOTT ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.VENUSAUR, Species.SUDOWOODO, Species.TORTERRA ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.VIRIZION ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SUDOWOODO ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.VIRIZION ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.JUMPLUFF, Species.SUNFLORA, Species.WHIMSICOTT ], [TimeOfDay.DAY]: [ Species.JUMPLUFF, Species.SUNFLORA, Species.WHIMSICOTT ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.VENUSAUR, Species.SUDOWOODO, Species.TORTERRA ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.VIRIZION ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.TALL_GRASS]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.BOUNSWEET ], 18: [ Species.STEENEE ], 58: [ Species.TSAREENA ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.NIDORAN_F ], 16: [ Species.NIDORINA ] }, { 1: [ Species.NIDORAN_M ], 16: [ Species.NIDORINO ] }, { 1: [ Species.BOUNSWEET ], 18: [ Species.STEENEE ], 58: [ Species.TSAREENA ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.ODDISH ], 21: [ Species.GLOOM ] }, { 1: [ Species.KRICKETOT ], 10: [ Species.KRICKETUNE ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.ODDISH ], 21: [ Species.GLOOM ] }, { 1: [ Species.KRICKETOT ], 10: [ Species.KRICKETUNE ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.NINCADA ], 20: [ Species.NINJASK ] }, { 1: [ Species.FOMANTIS ], 44: [ Species.LURANTIS ] }, { 1: [ Species.NYMBLE ], 24: [ Species.LOKIX ] } ] + [TimeOfDay.DAWN]: [{ 1: [ Species.BOUNSWEET ], 18: [ Species.STEENEE ], 58: [ Species.TSAREENA ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.NIDORAN_F ], 16: [ Species.NIDORINA ]}, { 1: [ Species.NIDORAN_M ], 16: [ Species.NIDORINO ]}, { 1: [ Species.BOUNSWEET ], 18: [ Species.STEENEE ], 58: [ Species.TSAREENA ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.ODDISH ], 21: [ Species.GLOOM ]}, { 1: [ Species.KRICKETOT ], 10: [ Species.KRICKETUNE ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.ODDISH ], 21: [ Species.GLOOM ]}, { 1: [ Species.KRICKETOT ], 10: [ Species.KRICKETUNE ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.NINCADA ], 20: [ Species.NINJASK ]}, { 1: [ Species.FOMANTIS ], 44: [ Species.LURANTIS ]}, { 1: [ Species.NYMBLE ], 24: [ Species.LOKIX ]}] }, [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], - [TimeOfDay.NIGHT]: [ { 1: [ Species.PARAS ], 24: [ Species.PARASECT ] }, { 1: [ Species.VENONAT ], 31: [ Species.VENOMOTH ] }, { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ] } ], + [TimeOfDay.NIGHT]: [{ 1: [ Species.PARAS ], 24: [ Species.PARASECT ]}, { 1: [ Species.VENONAT ], 31: [ Species.VENOMOTH ]}, { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ]}], [TimeOfDay.ALL]: [ Species.VULPIX ] }, [BiomePoolTier.RARE]: { @@ -265,10 +265,10 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ Species.PINSIR, { 1: [ Species.CHIKORITA ], 16: [ Species.BAYLEEF ], 32: [ Species.MEGANIUM ] }, { 1: [ Species.GIRAFARIG ], 62: [ Species.FARIGIRAF ] }, Species.ZANGOOSE, Species.KECLEON, Species.TROPIUS ] + [TimeOfDay.ALL]: [ Species.PINSIR, { 1: [ Species.CHIKORITA ], 16: [ Species.BAYLEEF ], 32: [ Species.MEGANIUM ]}, { 1: [ Species.GIRAFARIG ], 62: [ Species.FARIGIRAF ]}, Species.ZANGOOSE, Species.KECLEON, Species.TROPIUS ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SCYTHER, Species.SHEDINJA, Species.ROTOM ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SCYTHER, Species.SHEDINJA, Species.ROTOM ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.TSAREENA ], [TimeOfDay.DAY]: [ Species.NIDOQUEEN, Species.NIDOKING, Species.TSAREENA ], @@ -276,87 +276,87 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.VILEPLUME, Species.KRICKETUNE ], [TimeOfDay.ALL]: [ Species.NINJASK, Species.ZANGOOSE, Species.KECLEON, Species.LURANTIS, Species.LOKIX ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.BELLOSSOM ], [TimeOfDay.DAY]: [ Species.BELLOSSOM ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.PINSIR, Species.MEGANIUM, Species.FARIGIRAF ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.BELLOSSOM ], [TimeOfDay.DAY]: [ Species.BELLOSSOM ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.PINSIR, Species.MEGANIUM, Species.FARIGIRAF ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.METROPOLIS]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.YAMPER ], 25: [ Species.BOLTUND ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.YAMPER ], 25: [ Species.BOLTUND ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.HOUNDOUR ], 24: [ Species.HOUNDOOM ] }, { 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.RATTATA ], 20: [ Species.RATICATE ] }, { 1: [ Species.ZIGZAGOON ], 20: [ Species.LINOONE ] }, { 1: [ Species.LILLIPUP ], 16: [ Species.HERDIER ], 32: [ Species.STOUTLAND ] } ] + [TimeOfDay.DAWN]: [{ 1: [ Species.YAMPER ], 25: [ Species.BOLTUND ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.YAMPER ], 25: [ Species.BOLTUND ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.HOUNDOUR ], 24: [ Species.HOUNDOOM ]}, { 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.RATTATA ], 20: [ Species.RATICATE ]}, { 1: [ Species.ZIGZAGOON ], 20: [ Species.LINOONE ]}, { 1: [ Species.LILLIPUP ], 16: [ Species.HERDIER ], 32: [ Species.STOUTLAND ]}] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ] }, Species.INDEEDEE ], - [TimeOfDay.DAY]: [ { 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ] }, Species.INDEEDEE ], - [TimeOfDay.DUSK]: [ { 1: [ Species.ESPURR ], 25: [ Species.MEOWSTIC ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.ESPURR ], 25: [ Species.MEOWSTIC ] } ], - [TimeOfDay.ALL]: [ Species.PIKACHU, { 1: [ Species.GLAMEOW ], 38: [ Species.PURUGLY ] }, Species.FURFROU, { 1: [ Species.FIDOUGH ], 26: [ Species.DACHSBUN ] }, Species.SQUAWKABILLY ] + [TimeOfDay.DAWN]: [{ 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ]}, Species.INDEEDEE ], + [TimeOfDay.DAY]: [{ 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ]}, Species.INDEEDEE ], + [TimeOfDay.DUSK]: [{ 1: [ Species.ESPURR ], 25: [ Species.MEOWSTIC ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.ESPURR ], 25: [ Species.MEOWSTIC ]}], + [TimeOfDay.ALL]: [ Species.PIKACHU, { 1: [ Species.GLAMEOW ], 38: [ Species.PURUGLY ]}, Species.FURFROU, { 1: [ Species.FIDOUGH ], 26: [ Species.DACHSBUN ]}, Species.SQUAWKABILLY ] }, [BiomePoolTier.RARE]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.TANDEMAUS ], 25: [ Species.MAUSHOLD ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.TANDEMAUS ], 25: [ Species.MAUSHOLD ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.TANDEMAUS ], 25: [ Species.MAUSHOLD ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.TANDEMAUS ], 25: [ Species.MAUSHOLD ]}], [TimeOfDay.DUSK]: [ Species.MORPEKO ], [TimeOfDay.NIGHT]: [ Species.MORPEKO ], - [TimeOfDay.ALL]: [ { 1: [ Species.VAROOM ], 40: [ Species.REVAVROOM ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.VAROOM ], 40: [ Species.REVAVROOM ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO, Species.EEVEE, Species.SMEARGLE ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CASTFORM ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.BOLTUND ], [TimeOfDay.DAY]: [ Species.BOLTUND ], [TimeOfDay.DUSK]: [ Species.MEOWSTIC ], [TimeOfDay.NIGHT]: [ Species.MEOWSTIC ], [TimeOfDay.ALL]: [ Species.STOUTLAND, Species.FURFROU, Species.DACHSBUN ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.MAUSHOLD ], [TimeOfDay.DAY]: [ Species.MAUSHOLD ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CASTFORM, Species.REVAVROOM ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO, Species.EEVEE, Species.SMEARGLE ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CASTFORM ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.BOLTUND ], [TimeOfDay.DAY]: [ Species.BOLTUND ], [TimeOfDay.DUSK]: [ Species.MEOWSTIC ], [TimeOfDay.NIGHT]: [ Species.MEOWSTIC ], [TimeOfDay.ALL]: [ Species.STOUTLAND, Species.FURFROU, Species.DACHSBUN ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.MAUSHOLD ], [TimeOfDay.DAY]: [ Species.MAUSHOLD ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CASTFORM, Species.REVAVROOM ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.FOREST]: { [BiomePoolTier.COMMON]: { [TimeOfDay.DAWN]: [ Species.BUTTERFREE, - { 1: [ Species.BELLSPROUT ], 21: [ Species.WEEPINBELL ] }, - { 1: [ Species.COMBEE ], 21: [ Species.VESPIQUEN ] }, + { 1: [ Species.BELLSPROUT ], 21: [ Species.WEEPINBELL ]}, + { 1: [ Species.COMBEE ], 21: [ Species.VESPIQUEN ]}, Species.PETILIL, - { 1: [ Species.DEERLING ], 34: [ Species.SAWSBUCK ] }, + { 1: [ Species.DEERLING ], 34: [ Species.SAWSBUCK ]}, Species.VIVILLON ], [TimeOfDay.DAY]: [ Species.BUTTERFREE, - { 1: [ Species.BELLSPROUT ], 21: [ Species.WEEPINBELL ] }, + { 1: [ Species.BELLSPROUT ], 21: [ Species.WEEPINBELL ]}, Species.BEAUTIFLY, - { 1: [ Species.COMBEE ], 21: [ Species.VESPIQUEN ] }, + { 1: [ Species.COMBEE ], 21: [ Species.VESPIQUEN ]}, Species.PETILIL, - { 1: [ Species.DEERLING ], 34: [ Species.SAWSBUCK ] }, + { 1: [ Species.DEERLING ], 34: [ Species.SAWSBUCK ]}, Species.VIVILLON ], [TimeOfDay.DUSK]: [ Species.BEEDRILL, - { 1: [ Species.PINECO ], 31: [ Species.FORRETRESS ] }, - { 1: [ Species.SEEDOT ], 14: [ Species.NUZLEAF ] }, - { 1: [ Species.SHROOMISH ], 23: [ Species.BRELOOM ] }, - { 1: [ Species.VENIPEDE ], 22: [ Species.WHIRLIPEDE ], 30: [ Species.SCOLIPEDE ] } + { 1: [ Species.PINECO ], 31: [ Species.FORRETRESS ]}, + { 1: [ Species.SEEDOT ], 14: [ Species.NUZLEAF ]}, + { 1: [ Species.SHROOMISH ], 23: [ Species.BRELOOM ]}, + { 1: [ Species.VENIPEDE ], 22: [ Species.WHIRLIPEDE ], 30: [ Species.SCOLIPEDE ]} ], [TimeOfDay.NIGHT]: [ Species.BEEDRILL, - { 1: [ Species.VENONAT ], 31: [ Species.VENOMOTH ] }, - { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ] }, - { 1: [ Species.PINECO ], 31: [ Species.FORRETRESS ] }, + { 1: [ Species.VENONAT ], 31: [ Species.VENOMOTH ]}, + { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ]}, + { 1: [ Species.PINECO ], 31: [ Species.FORRETRESS ]}, Species.DUSTOX, - { 1: [ Species.SEEDOT ], 14: [ Species.NUZLEAF ] }, - { 1: [ Species.SHROOMISH ], 23: [ Species.BRELOOM ] }, - { 1: [ Species.VENIPEDE ], 22: [ Species.WHIRLIPEDE ], 30: [ Species.SCOLIPEDE ] } + { 1: [ Species.SEEDOT ], 14: [ Species.NUZLEAF ]}, + { 1: [ Species.SHROOMISH ], 23: [ Species.BRELOOM ]}, + { 1: [ Species.VENIPEDE ], 22: [ Species.WHIRLIPEDE ], 30: [ Species.SCOLIPEDE ]} ], - [TimeOfDay.ALL]: [ { 1: [ Species.TAROUNTULA ], 15: [ Species.SPIDOPS ] }, { 1: [ Species.NYMBLE ], 24: [ Species.LOKIX ] }, { 1: [ Species.SHROODLE ], 28: [ Species.GRAFAIAI ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.TAROUNTULA ], 15: [ Species.SPIDOPS ]}, { 1: [ Species.NYMBLE ], 24: [ Species.LOKIX ]}, { 1: [ Species.SHROODLE ], 28: [ Species.GRAFAIAI ]}] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ Species.ROSELIA, Species.MOTHIM, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ] } ], - [TimeOfDay.DAY]: [ Species.ROSELIA, Species.MOTHIM, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ] }, { 1: [ Species.DOTTLER ], 30: [ Species.ORBEETLE ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.HOOTHOOT ], 20: [ Species.NOCTOWL ] }, { 1: [ Species.ROCKRUFF ], 25: [ Species.LYCANROC ] }, { 1: [ Species.DOTTLER ], 30: [ Species.ORBEETLE ] } ], + [TimeOfDay.DAWN]: [ Species.ROSELIA, Species.MOTHIM, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ]}], + [TimeOfDay.DAY]: [ Species.ROSELIA, Species.MOTHIM, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ]}, { 1: [ Species.DOTTLER ], 30: [ Species.ORBEETLE ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.HOOTHOOT ], 20: [ Species.NOCTOWL ]}, { 1: [ Species.ROCKRUFF ], 25: [ Species.LYCANROC ]}, { 1: [ Species.DOTTLER ], 30: [ Species.ORBEETLE ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.EKANS ], 22: [ Species.ARBOK ] }, - { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ] }, - { 1: [ Species.BURMY ], 20: [ Species.WORMADAM ] }, - { 1: [ Species.PANSAGE ], 30: [ Species.SIMISAGE ] } + { 1: [ Species.EKANS ], 22: [ Species.ARBOK ]}, + { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ]}, + { 1: [ Species.BURMY ], 20: [ Species.WORMADAM ]}, + { 1: [ Species.PANSAGE ], 30: [ Species.SIMISAGE ]} ] }, [BiomePoolTier.RARE]: { @@ -366,18 +366,18 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.SCYTHER ], [TimeOfDay.ALL]: [ Species.HERACROSS, - { 1: [ Species.TREECKO ], 16: [ Species.GROVYLE ], 36: [ Species.SCEPTILE ] }, + { 1: [ Species.TREECKO ], 16: [ Species.GROVYLE ], 36: [ Species.SCEPTILE ]}, Species.TROPIUS, Species.KARRABLAST, Species.SHELMET, - { 1: [ Species.CHESPIN ], 16: [ Species.QUILLADIN ], 36: [ Species.CHESNAUGHT ] }, - { 1: [ Species.ROWLET ], 17: [ Species.DARTRIX ], 34: [ Species.DECIDUEYE ] }, + { 1: [ Species.CHESPIN ], 16: [ Species.QUILLADIN ], 36: [ Species.CHESNAUGHT ]}, + { 1: [ Species.ROWLET ], 17: [ Species.DARTRIX ], 34: [ Species.DECIDUEYE ]}, Species.SQUAWKABILLY, - { 1: [ Species.TOEDSCOOL ], 30: [ Species.TOEDSCRUEL ] } + { 1: [ Species.TOEDSCOOL ], 30: [ Species.TOEDSCRUEL ]} ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.BLOODMOON_URSALUNA ], [TimeOfDay.ALL]: [ Species.DURANT ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KARTANA, Species.WO_CHIEN ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.BLOODMOON_URSALUNA ], [TimeOfDay.ALL]: [ Species.DURANT ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KARTANA, Species.WO_CHIEN ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.VICTREEBEL, Species.MOTHIM, Species.VESPIQUEN, Species.LILLIGANT, Species.SAWSBUCK ], [TimeOfDay.DAY]: [ Species.VICTREEBEL, Species.BEAUTIFLY, Species.MOTHIM, Species.VESPIQUEN, Species.LILLIGANT, Species.SAWSBUCK ], @@ -392,29 +392,29 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.LYCANROC, Species.BLOODMOON_URSALUNA ], [TimeOfDay.ALL]: [ Species.HERACROSS, Species.SCEPTILE, Species.ESCAVALIER, Species.ACCELGOR, Species.DURANT, Species.CHESNAUGHT, Species.DECIDUEYE, Species.TOEDSCRUEL ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KARTANA, Species.WO_CHIEN ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CALYREX ] } + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KARTANA, Species.WO_CHIEN ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CALYREX ]} }, [Biome.SEA]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ] }, { 1: [ Species.WINGULL ], 25: [ Species.PELIPPER ] }, Species.CRAMORANT, { 1: [ Species.FINIZEN ], 38: [ Species.PALAFIN ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ] }, { 1: [ Species.WINGULL ], 25: [ Species.PELIPPER ] }, Species.CRAMORANT, { 1: [ Species.FINIZEN ], 38: [ Species.PALAFIN ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.INKAY ], 30: [ Species.MALAMAR ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.FINNEON ], 31: [ Species.LUMINEON ] }, { 1: [ Species.INKAY ], 30: [ Species.MALAMAR ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.TENTACOOL ], 30: [ Species.TENTACRUEL ] }, { 1: [ Species.MAGIKARP ], 20: [ Species.GYARADOS ] }, { 1: [ Species.BUIZEL ], 26: [ Species.FLOATZEL ] } ] + [TimeOfDay.DAWN]: [{ 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ]}, { 1: [ Species.WINGULL ], 25: [ Species.PELIPPER ]}, Species.CRAMORANT, { 1: [ Species.FINIZEN ], 38: [ Species.PALAFIN ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ]}, { 1: [ Species.WINGULL ], 25: [ Species.PELIPPER ]}, Species.CRAMORANT, { 1: [ Species.FINIZEN ], 38: [ Species.PALAFIN ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.INKAY ], 30: [ Species.MALAMAR ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.FINNEON ], 31: [ Species.LUMINEON ]}, { 1: [ Species.INKAY ], 30: [ Species.MALAMAR ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.TENTACOOL ], 30: [ Species.TENTACRUEL ]}, { 1: [ Species.MAGIKARP ], 20: [ Species.GYARADOS ]}, { 1: [ Species.BUIZEL ], 26: [ Species.FLOATZEL ]}] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.STARYU ], 30: [ Species.STARMIE ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.STARYU ], 30: [ Species.STARMIE ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ] }, Species.SHELLDER, { 1: [ Species.CARVANHA ], 30: [ Species.SHARPEDO ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ] }, Species.SHELLDER, { 1: [ Species.CHINCHOU ], 27: [ Species.LANTURN ] }, { 1: [ Species.CARVANHA ], 30: [ Species.SHARPEDO ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.STARYU ], 30: [ Species.STARMIE ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.STARYU ], 30: [ Species.STARMIE ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ]}, Species.SHELLDER, { 1: [ Species.CARVANHA ], 30: [ Species.SHARPEDO ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ]}, Species.SHELLDER, { 1: [ Species.CHINCHOU ], 27: [ Species.LANTURN ]}, { 1: [ Species.CARVANHA ], 30: [ Species.SHARPEDO ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.POLIWAG ], 25: [ Species.POLIWHIRL ] }, - { 1: [ Species.HORSEA ], 32: [ Species.SEADRA ] }, - { 1: [ Species.GOLDEEN ], 33: [ Species.SEAKING ] }, - { 1: [ Species.WAILMER ], 40: [ Species.WAILORD ] }, - { 1: [ Species.PANPOUR ], 30: [ Species.SIMIPOUR ] }, - { 1: [ Species.WATTREL ], 25: [ Species.KILOWATTREL ] } + { 1: [ Species.POLIWAG ], 25: [ Species.POLIWHIRL ]}, + { 1: [ Species.HORSEA ], 32: [ Species.SEADRA ]}, + { 1: [ Species.GOLDEEN ], 33: [ Species.SEAKING ]}, + { 1: [ Species.WAILMER ], 40: [ Species.WAILORD ]}, + { 1: [ Species.PANPOUR ], 30: [ Species.SIMIPOUR ]}, + { 1: [ Species.WATTREL ], 25: [ Species.KILOWATTREL ]} ] }, [BiomePoolTier.RARE]: { @@ -422,10 +422,10 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ Species.LAPRAS, { 1: [ Species.PIPLUP ], 16: [ Species.PRINPLUP ], 36: [ Species.EMPOLEON ] }, { 1: [ Species.POPPLIO ], 17: [ Species.BRIONNE ], 34: [ Species.PRIMARINA ] } ] + [TimeOfDay.ALL]: [ Species.LAPRAS, { 1: [ Species.PIPLUP ], 16: [ Species.PRINPLUP ], 36: [ Species.EMPOLEON ]}, { 1: [ Species.POPPLIO ], 17: [ Species.BRIONNE ], 34: [ Species.PRIMARINA ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KINGDRA, Species.ROTOM, { 1: [ Species.TIRTOUGA ], 37: [ Species.CARRACOSTA ] } ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KINGDRA, Species.ROTOM, { 1: [ Species.TIRTOUGA ], 37: [ Species.CARRACOSTA ]}]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.PELIPPER, Species.CRAMORANT, Species.PALAFIN ], [TimeOfDay.DAY]: [ Species.PELIPPER, Species.CRAMORANT, Species.PALAFIN ], @@ -433,34 +433,34 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.SHARPEDO, Species.LUMINEON, Species.MALAMAR ], [TimeOfDay.ALL]: [ Species.TENTACRUEL, Species.FLOATZEL, Species.SIMIPOUR, Species.KILOWATTREL ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KINGDRA, Species.EMPOLEON, Species.PRIMARINA ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.LUGIA ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KINGDRA, Species.EMPOLEON, Species.PRIMARINA ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.LUGIA ]} }, [Biome.SWAMP]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.WOOPER ], 20: [ Species.QUAGSIRE ] }, { 1: [ Species.LOTAD ], 14: [ Species.LOMBRE ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.WOOPER ], 20: [ Species.QUAGSIRE ] }, { 1: [ Species.LOTAD ], 14: [ Species.LOMBRE ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.EKANS ], 22: [ Species.ARBOK ] }, { 1: [ Species.PALDEA_WOOPER ], 20: [ Species.CLODSIRE ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.EKANS ], 22: [ Species.ARBOK ] }, { 1: [ Species.PALDEA_WOOPER ], 20: [ Species.CLODSIRE ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.WOOPER ], 20: [ Species.QUAGSIRE ]}, { 1: [ Species.LOTAD ], 14: [ Species.LOMBRE ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.WOOPER ], 20: [ Species.QUAGSIRE ]}, { 1: [ Species.LOTAD ], 14: [ Species.LOMBRE ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.EKANS ], 22: [ Species.ARBOK ]}, { 1: [ Species.PALDEA_WOOPER ], 20: [ Species.CLODSIRE ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.EKANS ], 22: [ Species.ARBOK ]}, { 1: [ Species.PALDEA_WOOPER ], 20: [ Species.CLODSIRE ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.POLIWAG ], 25: [ Species.POLIWHIRL ] }, - { 1: [ Species.GULPIN ], 26: [ Species.SWALOT ] }, - { 1: [ Species.SHELLOS ], 30: [ Species.GASTRODON ] }, - { 1: [ Species.TYMPOLE ], 25: [ Species.PALPITOAD ], 36: [ Species.SEISMITOAD ] } + { 1: [ Species.POLIWAG ], 25: [ Species.POLIWHIRL ]}, + { 1: [ Species.GULPIN ], 26: [ Species.SWALOT ]}, + { 1: [ Species.SHELLOS ], 30: [ Species.GASTRODON ]}, + { 1: [ Species.TYMPOLE ], 25: [ Species.PALPITOAD ], 36: [ Species.SEISMITOAD ]} ] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.EKANS ], 22: [ Species.ARBOK ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.EKANS ], 22: [ Species.ARBOK ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.CROAGUNK ], 37: [ Species.TOXICROAK ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.CROAGUNK ], 37: [ Species.TOXICROAK ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.EKANS ], 22: [ Species.ARBOK ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.EKANS ], 22: [ Species.ARBOK ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.CROAGUNK ], 37: [ Species.TOXICROAK ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.CROAGUNK ], 37: [ Species.TOXICROAK ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.PSYDUCK ], 33: [ Species.GOLDUCK ] }, - { 1: [ Species.BARBOACH ], 30: [ Species.WHISCASH ] }, - { 1: [ Species.SKORUPI ], 40: [ Species.DRAPION ] }, + { 1: [ Species.PSYDUCK ], 33: [ Species.GOLDUCK ]}, + { 1: [ Species.BARBOACH ], 30: [ Species.WHISCASH ]}, + { 1: [ Species.SKORUPI ], 40: [ Species.DRAPION ]}, Species.STUNFISK, - { 1: [ Species.MAREANIE ], 38: [ Species.TOXAPEX ] } + { 1: [ Species.MAREANIE ], 38: [ Species.TOXAPEX ]} ] }, [BiomePoolTier.RARE]: { @@ -468,16 +468,16 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.TOTODILE ], 18: [ Species.CROCONAW ], 30: [ Species.FERALIGATR ] }, { 1: [ Species.MUDKIP ], 16: [ Species.MARSHTOMP ], 36: [ Species.SWAMPERT ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.TOTODILE ], 18: [ Species.CROCONAW ], 30: [ Species.FERALIGATR ]}, { 1: [ Species.MUDKIP ], 16: [ Species.MARSHTOMP ], 36: [ Species.SWAMPERT ]}] }, [BiomePoolTier.SUPER_RARE]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.GALAR_SLOWPOKE ], 40: [ Species.GALAR_SLOWBRO ] }, { 1: [ Species.HISUI_SLIGGOO ], 80: [ Species.HISUI_GOODRA ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.GALAR_SLOWPOKE ], 40: [ Species.GALAR_SLOWBRO ] }, { 1: [ Species.HISUI_SLIGGOO ], 80: [ Species.HISUI_GOODRA ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.GALAR_SLOWPOKE ], 40: [ Species.GALAR_SLOWBRO ]}, { 1: [ Species.HISUI_SLIGGOO ], 80: [ Species.HISUI_GOODRA ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.GALAR_SLOWPOKE ], 40: [ Species.GALAR_SLOWBRO ]}, { 1: [ Species.HISUI_SLIGGOO ], 80: [ Species.HISUI_GOODRA ]}], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.POLITOED, Species.GALAR_STUNFISK ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AZELF, Species.POIPOLE ] }, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AZELF, Species.POIPOLE ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.QUAGSIRE, Species.LUDICOLO ], [TimeOfDay.DAY]: [ Species.QUAGSIRE, Species.LUDICOLO ], @@ -492,22 +492,22 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.FERALIGATR, Species.POLITOED, Species.SWAMPERT, Species.GALAR_STUNFISK ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AZELF, Species.NAGANADEL ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AZELF, Species.NAGANADEL ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.BEACH]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.STARYU ], 30: [ Species.STARMIE ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.STARYU ], 30: [ Species.STARMIE ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.STARYU ], 30: [ Species.STARMIE ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.STARYU ], 30: [ Species.STARMIE ]}], [TimeOfDay.DUSK]: [ Species.SHELLDER ], [TimeOfDay.NIGHT]: [ Species.SHELLDER ], [TimeOfDay.ALL]: [ - { 1: [ Species.KRABBY ], 28: [ Species.KINGLER ] }, - { 1: [ Species.CORPHISH ], 30: [ Species.CRAWDAUNT ] }, - { 1: [ Species.DWEBBLE ], 34: [ Species.CRUSTLE ] }, - { 1: [ Species.BINACLE ], 39: [ Species.BARBARACLE ] }, - { 1: [ Species.MAREANIE ], 38: [ Species.TOXAPEX ] }, - { 1: [ Species.WIGLETT ], 26: [ Species.WUGTRIO ] } + { 1: [ Species.KRABBY ], 28: [ Species.KINGLER ]}, + { 1: [ Species.CORPHISH ], 30: [ Species.CRAWDAUNT ]}, + { 1: [ Species.DWEBBLE ], 34: [ Species.CRUSTLE ]}, + { 1: [ Species.BINACLE ], 39: [ Species.BARBARACLE ]}, + { 1: [ Species.MAREANIE ], 38: [ Species.TOXAPEX ]}, + { 1: [ Species.WIGLETT ], 26: [ Species.WUGTRIO ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -515,11 +515,11 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.BURMY ], 20: [ Species.WORMADAM ] }, { 1: [ Species.CLAUNCHER ], 37: [ Species.CLAWITZER ] }, { 1: [ Species.SANDYGAST ], 42: [ Species.PALOSSAND ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.BURMY ], 20: [ Species.WORMADAM ]}, { 1: [ Species.CLAUNCHER ], 37: [ Species.CLAWITZER ]}, { 1: [ Species.SANDYGAST ], 42: [ Species.PALOSSAND ]}] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.QUAXLY ], 16: [ Species.QUAXWELL ], 36: [ Species.QUAQUAVAL ] }, Species.TATSUGIRI ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.TIRTOUGA ], 37: [ Species.CARRACOSTA ] } ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CRESSELIA, Species.KELDEO, Species.TAPU_FINI ] }, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.QUAXLY ], 16: [ Species.QUAXWELL ], 36: [ Species.QUAQUAVAL ]}, Species.TATSUGIRI ]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.TIRTOUGA ], 37: [ Species.CARRACOSTA ]}]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CRESSELIA, Species.KELDEO, Species.TAPU_FINI ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.STARMIE ], [TimeOfDay.DAY]: [ Species.STARMIE ], @@ -527,29 +527,29 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.CLOYSTER ], [TimeOfDay.ALL]: [ Species.KINGLER, Species.CRAWDAUNT, Species.WORMADAM, Species.CRUSTLE, Species.BARBARACLE, Species.CLAWITZER, Species.TOXAPEX, Species.PALOSSAND ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CARRACOSTA, Species.QUAQUAVAL ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CRESSELIA, Species.KELDEO, Species.TAPU_FINI ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CARRACOSTA, Species.QUAQUAVAL ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CRESSELIA, Species.KELDEO, Species.TAPU_FINI ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.LAKE]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.LOTAD ], 14: [ Species.LOMBRE ] }, { 1: [ Species.DUCKLETT ], 35: [ Species.SWANNA ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.LOTAD ], 14: [ Species.LOMBRE ] }, { 1: [ Species.DUCKLETT ], 35: [ Species.SWANNA ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.MARILL ], 18: [ Species.AZUMARILL ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.MARILL ], 18: [ Species.AZUMARILL ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.LOTAD ], 14: [ Species.LOMBRE ]}, { 1: [ Species.DUCKLETT ], 35: [ Species.SWANNA ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.LOTAD ], 14: [ Species.LOMBRE ]}, { 1: [ Species.DUCKLETT ], 35: [ Species.SWANNA ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.MARILL ], 18: [ Species.AZUMARILL ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.MARILL ], 18: [ Species.AZUMARILL ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.PSYDUCK ], 33: [ Species.GOLDUCK ] }, - { 1: [ Species.GOLDEEN ], 33: [ Species.SEAKING ] }, - { 1: [ Species.MAGIKARP ], 20: [ Species.GYARADOS ] }, - { 1: [ Species.CHEWTLE ], 22: [ Species.DREDNAW ] } + { 1: [ Species.PSYDUCK ], 33: [ Species.GOLDUCK ]}, + { 1: [ Species.GOLDEEN ], 33: [ Species.SEAKING ]}, + { 1: [ Species.MAGIKARP ], 20: [ Species.GYARADOS ]}, + { 1: [ Species.CHEWTLE ], 22: [ Species.DREDNAW ]} ] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.DEWPIDER ], 22: [ Species.ARAQUANID ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.DEWPIDER ], 22: [ Species.ARAQUANID ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.DEWPIDER ], 22: [ Species.ARAQUANID ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.DEWPIDER ], 22: [ Species.ARAQUANID ]}], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ] }, { 1: [ Species.WOOPER ], 20: [ Species.QUAGSIRE ] }, { 1: [ Species.SURSKIT ], 22: [ Species.MASQUERAIN ] }, Species.WISHIWASHI, Species.FLAMIGO ] + [TimeOfDay.ALL]: [{ 1: [ Species.SLOWPOKE ], 37: [ Species.SLOWBRO ]}, { 1: [ Species.WOOPER ], 20: [ Species.QUAGSIRE ]}, { 1: [ Species.SURSKIT ], 22: [ Species.MASQUERAIN ]}, Species.WISHIWASHI, Species.FLAMIGO ] }, [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], @@ -557,14 +557,14 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.SQUIRTLE ], 16: [ Species.WARTORTLE ], 36: [ Species.BLASTOISE ] }, - { 1: [ Species.OSHAWOTT ], 17: [ Species.DEWOTT ], 36: [ Species.SAMUROTT ] }, - { 1: [ Species.FROAKIE ], 16: [ Species.FROGADIER ], 36: [ Species.GRENINJA ] }, - { 1: [ Species.SOBBLE ], 16: [ Species.DRIZZILE ], 35: [ Species.INTELEON ] } + { 1: [ Species.SQUIRTLE ], 16: [ Species.WARTORTLE ], 36: [ Species.BLASTOISE ]}, + { 1: [ Species.OSHAWOTT ], 17: [ Species.DEWOTT ], 36: [ Species.SAMUROTT ]}, + { 1: [ Species.FROAKIE ], 16: [ Species.FROGADIER ], 36: [ Species.GRENINJA ]}, + { 1: [ Species.SOBBLE ], 16: [ Species.DRIZZILE ], 35: [ Species.INTELEON ]} ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.VAPOREON, Species.SLOWKING ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SUICUNE, Species.MESPRIT ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.VAPOREON, Species.SLOWKING ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SUICUNE, Species.MESPRIT ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.SWANNA, Species.ARAQUANID ], [TimeOfDay.DAY]: [ Species.SWANNA, Species.ARAQUANID ], @@ -572,9 +572,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.AZUMARILL ], [TimeOfDay.ALL]: [ Species.GOLDUCK, Species.SLOWBRO, Species.SEAKING, Species.GYARADOS, Species.MASQUERAIN, Species.WISHIWASHI, Species.DREDNAW ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLASTOISE, Species.VAPOREON, Species.SLOWKING, Species.SAMUROTT, Species.GRENINJA, Species.INTELEON ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SUICUNE, Species.MESPRIT ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLASTOISE, Species.VAPOREON, Species.SLOWKING, Species.SAMUROTT, Species.GRENINJA, Species.INTELEON ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SUICUNE, Species.MESPRIT ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.SEABED]: { [BiomePoolTier.COMMON]: { @@ -583,12 +583,12 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.CHINCHOU ], 27: [ Species.LANTURN ] }, + { 1: [ Species.CHINCHOU ], 27: [ Species.LANTURN ]}, Species.REMORAID, Species.CLAMPERL, Species.BASCULIN, - { 1: [ Species.FRILLISH ], 40: [ Species.JELLICENT ] }, - { 1: [ Species.ARROKUDA ], 26: [ Species.BARRASKEWDA ] }, + { 1: [ Species.FRILLISH ], 40: [ Species.JELLICENT ]}, + { 1: [ Species.ARROKUDA ], 26: [ Species.BARRASKEWDA ]}, Species.VELUZA ] }, @@ -598,12 +598,12 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.TENTACOOL ], 30: [ Species.TENTACRUEL ] }, + { 1: [ Species.TENTACOOL ], 30: [ Species.TENTACRUEL ]}, Species.SHELLDER, - { 1: [ Species.WAILMER ], 40: [ Species.WAILORD ] }, + { 1: [ Species.WAILMER ], 40: [ Species.WAILORD ]}, Species.LUVDISC, - { 1: [ Species.SHELLOS ], 30: [ Species.GASTRODON ] }, - { 1: [ Species.SKRELP ], 48: [ Species.DRAGALGE ] }, + { 1: [ Species.SHELLOS ], 30: [ Species.GASTRODON ]}, + { 1: [ Species.SKRELP ], 48: [ Species.DRAGALGE ]}, Species.PINCURCHIN, Species.DONDOZO ] @@ -613,7 +613,7 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ Species.QWILFISH, Species.CORSOLA, Species.OCTILLERY, { 1: [ Species.MANTYKE ], 52: [ Species.MANTINE ] }, Species.ALOMOMOLA, { 1: [ Species.TYNAMO ], 39: [ Species.EELEKTRIK ] }, Species.DHELMISE ] + [TimeOfDay.ALL]: [ Species.QWILFISH, Species.CORSOLA, Species.OCTILLERY, { 1: [ Species.MANTYKE ], 52: [ Species.MANTINE ]}, Species.ALOMOMOLA, { 1: [ Species.TYNAMO ], 39: [ Species.EELEKTRIK ]}, Species.DHELMISE ] }, [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], @@ -621,16 +621,16 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.OMANYTE ], 40: [ Species.OMASTAR ] }, - { 1: [ Species.KABUTO ], 40: [ Species.KABUTOPS ] }, + { 1: [ Species.OMANYTE ], 40: [ Species.OMASTAR ]}, + { 1: [ Species.KABUTO ], 40: [ Species.KABUTOPS ]}, Species.RELICANTH, Species.PYUKUMUKU, - { 1: [ Species.GALAR_CORSOLA ], 38: [ Species.CURSOLA ] }, + { 1: [ Species.GALAR_CORSOLA ], 38: [ Species.CURSOLA ]}, Species.ARCTOVISH, Species.HISUI_QWILFISH ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.FEEBAS, Species.NIHILEGO ] }, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.FEEBAS, Species.NIHILEGO ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], @@ -645,56 +645,56 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.OMASTAR, Species.KABUTOPS, Species.RELICANTH, Species.EELEKTROSS, Species.PYUKUMUKU, Species.DHELMISE, Species.CURSOLA, Species.ARCTOVISH, Species.BASCULEGION, Species.OVERQWIL ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MILOTIC, Species.NIHILEGO ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KYOGRE ] } + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MILOTIC, Species.NIHILEGO ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KYOGRE ]} }, [Biome.MOUNTAIN]: { [BiomePoolTier.COMMON]: { [TimeOfDay.DAWN]: [ - { 1: [ Species.TAILLOW ], 22: [ Species.SWELLOW ] }, - { 1: [ Species.SWABLU ], 35: [ Species.ALTARIA ] }, - { 1: [ Species.STARLY ], 14: [ Species.STARAVIA ], 34: [ Species.STARAPTOR ] }, - { 1: [ Species.PIDOVE ], 21: [ Species.TRANQUILL ], 32: [ Species.UNFEZANT ] }, - { 1: [ Species.FLETCHLING ], 17: [ Species.FLETCHINDER ], 35: [ Species.TALONFLAME ] } + { 1: [ Species.TAILLOW ], 22: [ Species.SWELLOW ]}, + { 1: [ Species.SWABLU ], 35: [ Species.ALTARIA ]}, + { 1: [ Species.STARLY ], 14: [ Species.STARAVIA ], 34: [ Species.STARAPTOR ]}, + { 1: [ Species.PIDOVE ], 21: [ Species.TRANQUILL ], 32: [ Species.UNFEZANT ]}, + { 1: [ Species.FLETCHLING ], 17: [ Species.FLETCHINDER ], 35: [ Species.TALONFLAME ]} ], [TimeOfDay.DAY]: [ - { 1: [ Species.TAILLOW ], 22: [ Species.SWELLOW ] }, - { 1: [ Species.SWABLU ], 35: [ Species.ALTARIA ] }, - { 1: [ Species.STARLY ], 14: [ Species.STARAVIA ], 34: [ Species.STARAPTOR ] }, - { 1: [ Species.PIDOVE ], 21: [ Species.TRANQUILL ], 32: [ Species.UNFEZANT ] }, - { 1: [ Species.FLETCHLING ], 17: [ Species.FLETCHINDER ], 35: [ Species.TALONFLAME ] } + { 1: [ Species.TAILLOW ], 22: [ Species.SWELLOW ]}, + { 1: [ Species.SWABLU ], 35: [ Species.ALTARIA ]}, + { 1: [ Species.STARLY ], 14: [ Species.STARAVIA ], 34: [ Species.STARAPTOR ]}, + { 1: [ Species.PIDOVE ], 21: [ Species.TRANQUILL ], 32: [ Species.UNFEZANT ]}, + { 1: [ Species.FLETCHLING ], 17: [ Species.FLETCHINDER ], 35: [ Species.TALONFLAME ]} ], - [TimeOfDay.DUSK]: [ { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ] }, { 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ] }, { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ] }, { 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ] }, { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.PIDGEY ], 18: [ Species.PIDGEOTTO ], 36: [ Species.PIDGEOT ] }, { 1: [ Species.SPEAROW ], 20: [ Species.FEAROW ] }, { 1: [ Species.SKIDDO ], 32: [ Species.GOGOAT ] } ] + [TimeOfDay.DUSK]: [{ 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ]}, { 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ]}, { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ]}, { 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ]}, { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.PIDGEY ], 18: [ Species.PIDGEOTTO ], 36: [ Species.PIDGEOT ]}, { 1: [ Species.SPEAROW ], 20: [ Species.FEAROW ]}, { 1: [ Species.SKIDDO ], 32: [ Species.GOGOAT ]}] }, [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [ - { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ] }, - { 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ] }, - { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ] }, - { 1: [ Species.RUFFLET ], 54: [ Species.BRAVIARY ] }, - { 1: [ Species.ROOKIDEE ], 18: [ Species.CORVISQUIRE ], 38: [ Species.CORVIKNIGHT ] }, - { 1: [ Species.FLITTLE ], 35: [ Species.ESPATHRA ] }, + { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ]}, + { 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ]}, + { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ]}, + { 1: [ Species.RUFFLET ], 54: [ Species.BRAVIARY ]}, + { 1: [ Species.ROOKIDEE ], 18: [ Species.CORVISQUIRE ], 38: [ Species.CORVIKNIGHT ]}, + { 1: [ Species.FLITTLE ], 35: [ Species.ESPATHRA ]}, Species.BOMBIRDIER ], [TimeOfDay.DAY]: [ - { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ] }, - { 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ] }, - { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ] }, - { 1: [ Species.RUFFLET ], 54: [ Species.BRAVIARY ] }, - { 1: [ Species.ROOKIDEE ], 18: [ Species.CORVISQUIRE ], 38: [ Species.CORVIKNIGHT ] }, - { 1: [ Species.FLITTLE ], 35: [ Species.ESPATHRA ] }, + { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ]}, + { 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ]}, + { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ]}, + { 1: [ Species.RUFFLET ], 54: [ Species.BRAVIARY ]}, + { 1: [ Species.ROOKIDEE ], 18: [ Species.CORVISQUIRE ], 38: [ Species.CORVIKNIGHT ]}, + { 1: [ Species.FLITTLE ], 35: [ Species.ESPATHRA ]}, Species.BOMBIRDIER ], - [TimeOfDay.DUSK]: [ { 1: [ Species.VULLABY ], 54: [ Species.MANDIBUZZ ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.VULLABY ], 54: [ Species.MANDIBUZZ ] } ], + [TimeOfDay.DUSK]: [{ 1: [ Species.VULLABY ], 54: [ Species.MANDIBUZZ ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.VULLABY ], 54: [ Species.MANDIBUZZ ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.MACHOP ], 28: [ Species.MACHOKE ] }, - { 1: [ Species.GEODUDE ], 25: [ Species.GRAVELER ] }, - { 1: [ Species.NATU ], 25: [ Species.XATU ] }, - { 1: [ Species.SLUGMA ], 38: [ Species.MAGCARGO ] }, - { 1: [ Species.NACLI ], 24: [ Species.NACLSTACK ], 38: [ Species.GARGANACL ] } + { 1: [ Species.MACHOP ], 28: [ Species.MACHOKE ]}, + { 1: [ Species.GEODUDE ], 25: [ Species.GRAVELER ]}, + { 1: [ Species.NATU ], 25: [ Species.XATU ]}, + { 1: [ Species.SLUGMA ], 38: [ Species.MAGCARGO ]}, + { 1: [ Species.NACLI ], 24: [ Species.NACLSTACK ], 38: [ Species.GARGANACL ]} ] }, [BiomePoolTier.RARE]: { @@ -702,7 +702,7 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.MURKROW ], - [TimeOfDay.ALL]: [ Species.SKARMORY, { 1: [ Species.TORCHIC ], 16: [ Species.COMBUSKEN ], 36: [ Species.BLAZIKEN ] }, { 1: [ Species.SPOINK ], 32: [ Species.GRUMPIG ] }, Species.HAWLUCHA, Species.KLAWF ] + [TimeOfDay.ALL]: [ Species.SKARMORY, { 1: [ Species.TORCHIC ], 16: [ Species.COMBUSKEN ], 36: [ Species.BLAZIKEN ]}, { 1: [ Species.SPOINK ], 32: [ Species.GRUMPIG ]}, Species.HAWLUCHA, Species.KLAWF ] }, [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], @@ -710,16 +710,16 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.LARVITAR ], 30: [ Species.PUPITAR ] }, - { 1: [ Species.CRANIDOS ], 30: [ Species.RAMPARDOS ] }, - { 1: [ Species.SHIELDON ], 30: [ Species.BASTIODON ] }, - { 1: [ Species.GIBLE ], 24: [ Species.GABITE ], 48: [ Species.GARCHOMP ] }, + { 1: [ Species.LARVITAR ], 30: [ Species.PUPITAR ]}, + { 1: [ Species.CRANIDOS ], 30: [ Species.RAMPARDOS ]}, + { 1: [ Species.SHIELDON ], 30: [ Species.BASTIODON ]}, + { 1: [ Species.GIBLE ], 24: [ Species.GABITE ], 48: [ Species.GARCHOMP ]}, Species.ROTOM, Species.ARCHEOPS, - { 1: [ Species.AXEW ], 38: [ Species.FRAXURE ] } + { 1: [ Species.AXEW ], 38: [ Species.FRAXURE ]} ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TORNADUS, Species.TING_LU, Species.OGERPON ] }, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TORNADUS, Species.TING_LU, Species.OGERPON ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.SWELLOW, Species.ALTARIA, Species.STARAPTOR, Species.UNFEZANT, Species.BRAVIARY, Species.TALONFLAME, Species.CORVIKNIGHT, Species.ESPATHRA ], [TimeOfDay.DAY]: [ Species.SWELLOW, Species.ALTARIA, Species.STARAPTOR, Species.UNFEZANT, Species.BRAVIARY, Species.TALONFLAME, Species.CORVIKNIGHT, Species.ESPATHRA ], @@ -727,39 +727,39 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.MANDIBUZZ ], [TimeOfDay.ALL]: [ Species.PIDGEOT, Species.FEAROW, Species.SKARMORY, Species.AGGRON, Species.GOGOAT, Species.GARGANACL ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.HISUI_BRAVIARY ], [TimeOfDay.DAY]: [ Species.HISUI_BRAVIARY ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLAZIKEN, Species.RAMPARDOS, Species.BASTIODON, Species.HAWLUCHA ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM, Species.TORNADUS, Species.TING_LU, Species.OGERPON ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HO_OH ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.HISUI_BRAVIARY ], [TimeOfDay.DAY]: [ Species.HISUI_BRAVIARY ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLAZIKEN, Species.RAMPARDOS, Species.BASTIODON, Species.HAWLUCHA ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM, Species.TORNADUS, Species.TING_LU, Species.OGERPON ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HO_OH ]} }, [Biome.BADLANDS]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.PHANPY ], 25: [ Species.DONPHAN ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.PHANPY ], 25: [ Species.DONPHAN ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.PHANPY ], 25: [ Species.DONPHAN ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.PHANPY ], 25: [ Species.DONPHAN ]}], [TimeOfDay.DUSK]: [], - [TimeOfDay.NIGHT]: [ { 1: [ Species.CUBONE ], 28: [ Species.MAROWAK ] } ], + [TimeOfDay.NIGHT]: [{ 1: [ Species.CUBONE ], 28: [ Species.MAROWAK ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.DIGLETT ], 26: [ Species.DUGTRIO ] }, - { 1: [ Species.GEODUDE ], 25: [ Species.GRAVELER ] }, - { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ] }, - { 1: [ Species.DRILBUR ], 31: [ Species.EXCADRILL ] }, - { 1: [ Species.MUDBRAY ], 30: [ Species.MUDSDALE ] } + { 1: [ Species.DIGLETT ], 26: [ Species.DUGTRIO ]}, + { 1: [ Species.GEODUDE ], 25: [ Species.GRAVELER ]}, + { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ]}, + { 1: [ Species.DRILBUR ], 31: [ Species.EXCADRILL ]}, + { 1: [ Species.MUDBRAY ], 30: [ Species.MUDSDALE ]} ] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.SIZZLIPEDE ], 28: [ Species.CENTISKORCH ] }, { 1: [ Species.CAPSAKID ], 30: [ Species.SCOVILLAIN ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.SIZZLIPEDE ], 28: [ Species.CENTISKORCH ] }, { 1: [ Species.CAPSAKID ], 30: [ Species.SCOVILLAIN ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.SIZZLIPEDE ], 28: [ Species.CENTISKORCH ]}, { 1: [ Species.CAPSAKID ], 30: [ Species.SCOVILLAIN ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.SIZZLIPEDE ], 28: [ Species.CENTISKORCH ]}, { 1: [ Species.CAPSAKID ], 30: [ Species.SCOVILLAIN ]}], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.SANDSHREW ], 22: [ Species.SANDSLASH ] }, - { 1: [ Species.NUMEL ], 33: [ Species.CAMERUPT ] }, - { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ] }, - { 1: [ Species.CUFANT ], 34: [ Species.COPPERAJAH ] } + { 1: [ Species.SANDSHREW ], 22: [ Species.SANDSLASH ]}, + { 1: [ Species.NUMEL ], 33: [ Species.CAMERUPT ]}, + { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ]}, + { 1: [ Species.CUFANT ], 34: [ Species.COPPERAJAH ]} ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ONIX, Species.GLIGAR, { 1: [ Species.POLTCHAGEIST ], 30: [ Species.SINISTCHA ] } ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.LANDORUS, Species.OKIDOGI ] }, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ONIX, Species.GLIGAR, { 1: [ Species.POLTCHAGEIST ], 30: [ Species.SINISTCHA ]}]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.LANDORUS, Species.OKIDOGI ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.DONPHAN, Species.CENTISKORCH, Species.SCOVILLAIN ], [TimeOfDay.DAY]: [ Species.DONPHAN, Species.CENTISKORCH, Species.SCOVILLAIN ], @@ -767,9 +767,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.MAROWAK ], [TimeOfDay.ALL]: [ Species.DUGTRIO, Species.GOLEM, Species.RHYPERIOR, Species.GLISCOR, Species.EXCADRILL, Species.MUDSDALE, Species.COPPERAJAH ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.STEELIX, Species.SINISTCHA ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.LANDORUS, Species.OKIDOGI ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GROUDON ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.STEELIX, Species.SINISTCHA ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.LANDORUS, Species.OKIDOGI ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GROUDON ]} }, [Biome.CAVE]: { [BiomePoolTier.COMMON]: { @@ -778,27 +778,27 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.ZUBAT ], 22: [ Species.GOLBAT ] }, - { 1: [ Species.PARAS ], 24: [ Species.PARASECT ] }, - { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ] }, - { 1: [ Species.WHISMUR ], 20: [ Species.LOUDRED ], 40: [ Species.EXPLOUD ] }, - { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ] }, - { 1: [ Species.WOOBAT ], 20: [ Species.SWOOBAT ] }, - { 1: [ Species.BUNNELBY ], 20: [ Species.DIGGERSBY ] }, - { 1: [ Species.NACLI ], 24: [ Species.NACLSTACK ], 38: [ Species.GARGANACL ] } + { 1: [ Species.ZUBAT ], 22: [ Species.GOLBAT ]}, + { 1: [ Species.PARAS ], 24: [ Species.PARASECT ]}, + { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ]}, + { 1: [ Species.WHISMUR ], 20: [ Species.LOUDRED ], 40: [ Species.EXPLOUD ]}, + { 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ]}, + { 1: [ Species.WOOBAT ], 20: [ Species.SWOOBAT ]}, + { 1: [ Species.BUNNELBY ], 20: [ Species.DIGGERSBY ]}, + { 1: [ Species.NACLI ], 24: [ Species.NACLSTACK ], 38: [ Species.GARGANACL ]} ] }, [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], - [TimeOfDay.DUSK]: [ { 1: [ Species.ROCKRUFF ], 25: [ Species.LYCANROC ] } ], + [TimeOfDay.DUSK]: [{ 1: [ Species.ROCKRUFF ], 25: [ Species.LYCANROC ]}], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.GEODUDE ], 25: [ Species.GRAVELER ] }, - { 1: [ Species.MAKUHITA ], 24: [ Species.HARIYAMA ] }, + { 1: [ Species.GEODUDE ], 25: [ Species.GRAVELER ]}, + { 1: [ Species.MAKUHITA ], 24: [ Species.HARIYAMA ]}, Species.NOSEPASS, - { 1: [ Species.NOIBAT ], 48: [ Species.NOIVERN ] }, - { 1: [ Species.WIMPOD ], 30: [ Species.GOLISOPOD ] } + { 1: [ Species.NOIBAT ], 48: [ Species.NOIVERN ]}, + { 1: [ Species.WIMPOD ], 30: [ Species.GOLISOPOD ]} ] }, [BiomePoolTier.RARE]: { @@ -806,10 +806,10 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ Species.ONIX, { 1: [ Species.FERROSEED ], 40: [ Species.FERROTHORN ] }, Species.CARBINK, { 1: [ Species.GLIMMET ], 35: [ Species.GLIMMORA ] } ] + [TimeOfDay.ALL]: [ Species.ONIX, { 1: [ Species.FERROSEED ], 40: [ Species.FERROTHORN ]}, Species.CARBINK, { 1: [ Species.GLIMMET ], 35: [ Species.GLIMMORA ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SHUCKLE ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.UXIE ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SHUCKLE ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.UXIE ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], @@ -817,34 +817,34 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.PARASECT, Species.ONIX, Species.CROBAT, Species.URSARING, Species.EXPLOUD, Species.PROBOPASS, Species.GIGALITH, Species.SWOOBAT, Species.DIGGERSBY, Species.NOIVERN, Species.GOLISOPOD, Species.GARGANACL ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ Species.LYCANROC ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SHUCKLE, Species.FERROTHORN, Species.GLIMMORA ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.UXIE ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TERAPAGOS ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ Species.LYCANROC ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SHUCKLE, Species.FERROTHORN, Species.GLIMMORA ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.UXIE ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TERAPAGOS ]} }, [Biome.DESERT]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ Species.TRAPINCH, { 1: [ Species.HIPPOPOTAS ], 34: [ Species.HIPPOWDON ] }, { 1: [ Species.RELLOR ], 29: [ Species.RABSCA ] } ], - [TimeOfDay.DAY]: [ Species.TRAPINCH, { 1: [ Species.HIPPOPOTAS ], 34: [ Species.HIPPOWDON ] }, { 1: [ Species.RELLOR ], 29: [ Species.RABSCA ] } ], - [TimeOfDay.DUSK]: [ { 1: [ Species.CACNEA ], 32: [ Species.CACTURNE ] }, { 1: [ Species.SANDILE ], 29: [ Species.KROKOROK ], 40: [ Species.KROOKODILE ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.CACNEA ], 32: [ Species.CACTURNE ] }, { 1: [ Species.SANDILE ], 29: [ Species.KROKOROK ], 40: [ Species.KROOKODILE ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.SANDSHREW ], 22: [ Species.SANDSLASH ] }, { 1: [ Species.SKORUPI ], 40: [ Species.DRAPION ] }, { 1: [ Species.SILICOBRA ], 36: [ Species.SANDACONDA ] } ] + [TimeOfDay.DAWN]: [ Species.TRAPINCH, { 1: [ Species.HIPPOPOTAS ], 34: [ Species.HIPPOWDON ]}, { 1: [ Species.RELLOR ], 29: [ Species.RABSCA ]}], + [TimeOfDay.DAY]: [ Species.TRAPINCH, { 1: [ Species.HIPPOPOTAS ], 34: [ Species.HIPPOWDON ]}, { 1: [ Species.RELLOR ], 29: [ Species.RABSCA ]}], + [TimeOfDay.DUSK]: [{ 1: [ Species.CACNEA ], 32: [ Species.CACTURNE ]}, { 1: [ Species.SANDILE ], 29: [ Species.KROKOROK ], 40: [ Species.KROOKODILE ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.CACNEA ], 32: [ Species.CACTURNE ]}, { 1: [ Species.SANDILE ], 29: [ Species.KROKOROK ], 40: [ Species.KROOKODILE ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.SANDSHREW ], 22: [ Species.SANDSLASH ]}, { 1: [ Species.SKORUPI ], 40: [ Species.DRAPION ]}, { 1: [ Species.SILICOBRA ], 36: [ Species.SANDACONDA ]}] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.SANDILE ], 29: [ Species.KROKOROK ], 40: [ Species.KROOKODILE ] }, Species.HELIOPTILE ], - [TimeOfDay.DAY]: [ { 1: [ Species.SANDILE ], 29: [ Species.KROKOROK ], 40: [ Species.KROOKODILE ] }, Species.HELIOPTILE ], + [TimeOfDay.DAWN]: [{ 1: [ Species.SANDILE ], 29: [ Species.KROKOROK ], 40: [ Species.KROOKODILE ]}, Species.HELIOPTILE ], + [TimeOfDay.DAY]: [{ 1: [ Species.SANDILE ], 29: [ Species.KROKOROK ], 40: [ Species.KROOKODILE ]}, Species.HELIOPTILE ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ Species.MARACTUS, { 1: [ Species.BRAMBLIN ], 30: [ Species.BRAMBLEGHAST ] }, Species.ORTHWORM ] + [TimeOfDay.ALL]: [ Species.MARACTUS, { 1: [ Species.BRAMBLIN ], 30: [ Species.BRAMBLEGHAST ]}, Species.ORTHWORM ] }, [BiomePoolTier.RARE]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.VIBRAVA ], 45: [ Species.FLYGON ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.VIBRAVA ], 45: [ Species.FLYGON ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.VIBRAVA ], 45: [ Species.FLYGON ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.VIBRAVA ], 45: [ Species.FLYGON ]}], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.DARUMAKA ], 35: [ Species.DARMANITAN ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.DARUMAKA ], 35: [ Species.DARMANITAN ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.LILEEP ], 40: [ Species.CRADILY ] }, { 1: [ Species.ANORITH ], 40: [ Species.ARMALDO ] } ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIROCK, Species.TAPU_BULU, Species.PHEROMOSA ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.LILEEP ], 40: [ Species.CRADILY ]}, { 1: [ Species.ANORITH ], 40: [ Species.ARMALDO ]}]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIROCK, Species.TAPU_BULU, Species.PHEROMOSA ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.HIPPOWDON, Species.HELIOLISK, Species.RABSCA ], [TimeOfDay.DAY]: [ Species.HIPPOWDON, Species.HELIOLISK, Species.RABSCA ], @@ -852,9 +852,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.CACTURNE, Species.KROOKODILE ], [TimeOfDay.ALL]: [ Species.SANDSLASH, Species.DRAPION, Species.DARMANITAN, Species.MARACTUS, Species.SANDACONDA, Species.BRAMBLEGHAST ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CRADILY, Species.ARMALDO ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIROCK, Species.TAPU_BULU, Species.PHEROMOSA ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CRADILY, Species.ARMALDO ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIROCK, Species.TAPU_BULU, Species.PHEROMOSA ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.ICE_CAVE]: { [BiomePoolTier.COMMON]: { @@ -863,14 +863,14 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.SEEL ], 34: [ Species.DEWGONG ] }, - { 1: [ Species.SWINUB ], 33: [ Species.PILOSWINE ] }, - { 1: [ Species.SNOVER ], 40: [ Species.ABOMASNOW ] }, - { 1: [ Species.VANILLITE ], 35: [ Species.VANILLISH ], 47: [ Species.VANILLUXE ] }, - { 1: [ Species.CUBCHOO ], 37: [ Species.BEARTIC ] }, - { 1: [ Species.BERGMITE ], 37: [ Species.AVALUGG ] }, + { 1: [ Species.SEEL ], 34: [ Species.DEWGONG ]}, + { 1: [ Species.SWINUB ], 33: [ Species.PILOSWINE ]}, + { 1: [ Species.SNOVER ], 40: [ Species.ABOMASNOW ]}, + { 1: [ Species.VANILLITE ], 35: [ Species.VANILLISH ], 47: [ Species.VANILLUXE ]}, + { 1: [ Species.CUBCHOO ], 37: [ Species.BEARTIC ]}, + { 1: [ Species.BERGMITE ], 37: [ Species.AVALUGG ]}, Species.CRABRAWLER, - { 1: [ Species.SNOM ], 20: [ Species.FROSMOTH ] } + { 1: [ Species.SNOM ], 20: [ Species.FROSMOTH ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -880,15 +880,15 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SNEASEL, - { 1: [ Species.SNORUNT ], 42: [ Species.GLALIE ] }, - { 1: [ Species.SPHEAL ], 32: [ Species.SEALEO ], 44: [ Species.WALREIN ] }, + { 1: [ Species.SNORUNT ], 42: [ Species.GLALIE ]}, + { 1: [ Species.SPHEAL ], 32: [ Species.SEALEO ], 44: [ Species.WALREIN ]}, Species.EISCUE, - { 1: [ Species.CETODDLE ], 30: [ Species.CETITAN ] } + { 1: [ Species.CETODDLE ], 30: [ Species.CETITAN ]} ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.JYNX, Species.LAPRAS, Species.FROSLASS, Species.CRYOGONAL ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DELIBIRD, Species.ROTOM, { 1: [ Species.AMAURA ], 59: [ Species.AURORUS ] } ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ARTICUNO, Species.REGICE ] }, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.JYNX, Species.LAPRAS, Species.FROSLASS, Species.CRYOGONAL ]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DELIBIRD, Species.ROTOM, { 1: [ Species.AMAURA ], 59: [ Species.AURORUS ]}]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ARTICUNO, Species.REGICE ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], @@ -896,46 +896,46 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DEWGONG, Species.GLALIE, Species.WALREIN, Species.WEAVILE, Species.MAMOSWINE, Species.FROSLASS, Species.VANILLUXE, Species.BEARTIC, Species.CRYOGONAL, Species.AVALUGG, Species.CRABOMINABLE, Species.CETITAN ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.JYNX, Species.LAPRAS, Species.GLACEON, Species.AURORUS ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ARTICUNO, Species.REGICE, Species.ROTOM ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KYUREM ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.JYNX, Species.LAPRAS, Species.GLACEON, Species.AURORUS ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ARTICUNO, Species.REGICE, Species.ROTOM ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KYUREM ]} }, [Biome.MEADOW]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.LEDYBA ], 18: [ Species.LEDIAN ] }, Species.ROSELIA, Species.COTTONEE, Species.MINCCINO ], + [TimeOfDay.DAWN]: [{ 1: [ Species.LEDYBA ], 18: [ Species.LEDIAN ]}, Species.ROSELIA, Species.COTTONEE, Species.MINCCINO ], [TimeOfDay.DAY]: [ Species.ROSELIA, Species.COTTONEE, Species.MINCCINO ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.BLITZLE ], 27: [ Species.ZEBSTRIKA ] }, - { 1: [ Species.FLABEBE ], 19: [ Species.FLOETTE ] }, - { 1: [ Species.CUTIEFLY ], 25: [ Species.RIBOMBEE ] }, - { 1: [ Species.GOSSIFLEUR ], 20: [ Species.ELDEGOSS ] }, - { 1: [ Species.WOOLOO ], 24: [ Species.DUBWOOL ] } + { 1: [ Species.BLITZLE ], 27: [ Species.ZEBSTRIKA ]}, + { 1: [ Species.FLABEBE ], 19: [ Species.FLOETTE ]}, + { 1: [ Species.CUTIEFLY ], 25: [ Species.RIBOMBEE ]}, + { 1: [ Species.GOSSIFLEUR ], 20: [ Species.ELDEGOSS ]}, + { 1: [ Species.WOOLOO ], 24: [ Species.DUBWOOL ]} ] }, [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [ - { 1: [ Species.PONYTA ], 40: [ Species.RAPIDASH ] }, - { 1: [ Species.SNUBBULL ], 23: [ Species.GRANBULL ] }, - { 1: [ Species.SKITTY ], 30: [ Species.DELCATTY ] }, + { 1: [ Species.PONYTA ], 40: [ Species.RAPIDASH ]}, + { 1: [ Species.SNUBBULL ], 23: [ Species.GRANBULL ]}, + { 1: [ Species.SKITTY ], 30: [ Species.DELCATTY ]}, Species.BOUFFALANT, - { 1: [ Species.SMOLIV ], 25: [ Species.DOLLIV ], 35: [ Species.ARBOLIVA ] } + { 1: [ Species.SMOLIV ], 25: [ Species.DOLLIV ], 35: [ Species.ARBOLIVA ]} ], [TimeOfDay.DAY]: [ - { 1: [ Species.PONYTA ], 40: [ Species.RAPIDASH ] }, - { 1: [ Species.SNUBBULL ], 23: [ Species.GRANBULL ] }, - { 1: [ Species.SKITTY ], 30: [ Species.DELCATTY ] }, + { 1: [ Species.PONYTA ], 40: [ Species.RAPIDASH ]}, + { 1: [ Species.SNUBBULL ], 23: [ Species.GRANBULL ]}, + { 1: [ Species.SKITTY ], 30: [ Species.DELCATTY ]}, Species.BOUFFALANT, - { 1: [ Species.SMOLIV ], 25: [ Species.DOLLIV ], 35: [ Species.ARBOLIVA ] } + { 1: [ Species.SMOLIV ], 25: [ Species.DOLLIV ], 35: [ Species.ARBOLIVA ]} ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.JIGGLYPUFF ], 30: [ Species.WIGGLYTUFF ] }, - { 1: [ Species.MAREEP ], 15: [ Species.FLAAFFY ], 30: [ Species.AMPHAROS ] }, - { 1: [ Species.RALTS ], 20: [ Species.KIRLIA ], 30: [ Species.GARDEVOIR ] }, - { 1: [ Species.GLAMEOW ], 38: [ Species.PURUGLY ] }, + { 1: [ Species.JIGGLYPUFF ], 30: [ Species.WIGGLYTUFF ]}, + { 1: [ Species.MAREEP ], 15: [ Species.FLAAFFY ], 30: [ Species.AMPHAROS ]}, + { 1: [ Species.RALTS ], 20: [ Species.KIRLIA ], 30: [ Species.GARDEVOIR ]}, + { 1: [ Species.GLAMEOW ], 38: [ Species.PURUGLY ]}, Species.ORICORIO ] }, @@ -944,10 +944,10 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.VOLBEAT, Species.ILLUMISE ], - [TimeOfDay.ALL]: [ Species.TAUROS, Species.EEVEE, Species.MILTANK, Species.SPINDA, { 1: [ Species.APPLIN ], 30: [ Species.DIPPLIN ] }, { 1: [ Species.SPRIGATITO ], 16: [ Species.FLORAGATO ], 36: [ Species.MEOWSCARADA ] } ] + [TimeOfDay.ALL]: [ Species.TAUROS, Species.EEVEE, Species.MILTANK, Species.SPINDA, { 1: [ Species.APPLIN ], 30: [ Species.DIPPLIN ]}, { 1: [ Species.SPRIGATITO ], 16: [ Species.FLORAGATO ], 36: [ Species.MEOWSCARADA ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CHANSEY, Species.SYLVEON ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MELOETTA ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CHANSEY, Species.SYLVEON ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MELOETTA ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.LEDIAN, Species.GRANBULL, Species.DELCATTY, Species.ROSERADE, Species.CINCCINO, Species.BOUFFALANT, Species.ARBOLIVA ], [TimeOfDay.DAY]: [ Species.GRANBULL, Species.DELCATTY, Species.ROSERADE, Species.CINCCINO, Species.BOUFFALANT, Species.ARBOLIVA ], @@ -955,9 +955,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TAUROS, Species.MILTANK, Species.GARDEVOIR, Species.PURUGLY, Species.ZEBSTRIKA, Species.FLORGES, Species.RIBOMBEE, Species.DUBWOOL ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.HISUI_LILLIGANT ], [TimeOfDay.DAY]: [ Species.HISUI_LILLIGANT ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLISSEY, Species.SYLVEON, Species.FLAPPLE, Species.APPLETUN, Species.MEOWSCARADA, Species.HYDRAPPLE ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MELOETTA ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SHAYMIN ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.HISUI_LILLIGANT ], [TimeOfDay.DAY]: [ Species.HISUI_LILLIGANT ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLISSEY, Species.SYLVEON, Species.FLAPPLE, Species.APPLETUN, Species.MEOWSCARADA, Species.HYDRAPPLE ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MELOETTA ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SHAYMIN ]} }, [Biome.POWER_PLANT]: { [BiomePoolTier.COMMON]: { @@ -967,20 +967,20 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.PIKACHU, - { 1: [ Species.MAGNEMITE ], 30: [ Species.MAGNETON ] }, - { 1: [ Species.VOLTORB ], 30: [ Species.ELECTRODE ] }, - { 1: [ Species.ELECTRIKE ], 26: [ Species.MANECTRIC ] }, - { 1: [ Species.SHINX ], 15: [ Species.LUXIO ], 30: [ Species.LUXRAY ] }, + { 1: [ Species.MAGNEMITE ], 30: [ Species.MAGNETON ]}, + { 1: [ Species.VOLTORB ], 30: [ Species.ELECTRODE ]}, + { 1: [ Species.ELECTRIKE ], 26: [ Species.MANECTRIC ]}, + { 1: [ Species.SHINX ], 15: [ Species.LUXIO ], 30: [ Species.LUXRAY ]}, Species.DEDENNE, - { 1: [ Species.GRUBBIN ], 20: [ Species.CHARJABUG ] }, - { 1: [ Species.PAWMI ], 18: [ Species.PAWMO ], 32: [ Species.PAWMOT ] }, - { 1: [ Species.TADBULB ], 30: [ Species.BELLIBOLT ] } + { 1: [ Species.GRUBBIN ], 20: [ Species.CHARJABUG ]}, + { 1: [ Species.PAWMI ], 18: [ Species.PAWMO ], 32: [ Species.PAWMOT ]}, + { 1: [ Species.TADBULB ], 30: [ Species.BELLIBOLT ]} ] }, - [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ELECTABUZZ, Species.PLUSLE, Species.MINUN, Species.PACHIRISU, Species.EMOLGA, Species.TOGEDEMARU ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.MAREEP ], 15: [ Species.FLAAFFY ] } ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.JOLTEON, Species.HISUI_VOLTORB ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.RAIKOU, Species.THUNDURUS, Species.XURKITREE, Species.ZERAORA, Species.REGIELEKI ] }, + [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ELECTABUZZ, Species.PLUSLE, Species.MINUN, Species.PACHIRISU, Species.EMOLGA, Species.TOGEDEMARU ]}, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.MAREEP ], 15: [ Species.FLAAFFY ]}]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.JOLTEON, Species.HISUI_VOLTORB ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.RAIKOU, Species.THUNDURUS, Species.XURKITREE, Species.ZERAORA, Species.REGIELEKI ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], @@ -988,9 +988,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.RAICHU, Species.MANECTRIC, Species.LUXRAY, Species.MAGNEZONE, Species.ELECTIVIRE, Species.DEDENNE, Species.VIKAVOLT, Species.TOGEDEMARU, Species.PAWMOT, Species.BELLIBOLT ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.JOLTEON, Species.AMPHAROS, Species.HISUI_ELECTRODE ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ZAPDOS, Species.RAIKOU, Species.THUNDURUS, Species.XURKITREE, Species.ZERAORA, Species.REGIELEKI ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ZEKROM ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.JOLTEON, Species.AMPHAROS, Species.HISUI_ELECTRODE ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ZAPDOS, Species.RAIKOU, Species.THUNDURUS, Species.XURKITREE, Species.ZERAORA, Species.REGIELEKI ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ZEKROM ]} }, [Biome.VOLCANO]: { [BiomePoolTier.COMMON]: { @@ -1001,32 +1001,32 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.ALL]: [ Species.VULPIX, Species.GROWLITHE, - { 1: [ Species.PONYTA ], 40: [ Species.RAPIDASH ] }, - { 1: [ Species.SLUGMA ], 38: [ Species.MAGCARGO ] }, - { 1: [ Species.NUMEL ], 33: [ Species.CAMERUPT ] }, - { 1: [ Species.SALANDIT ], 33: [ Species.SALAZZLE ] }, - { 1: [ Species.ROLYCOLY ], 18: [ Species.CARKOL ], 34: [ Species.COALOSSAL ] } + { 1: [ Species.PONYTA ], 40: [ Species.RAPIDASH ]}, + { 1: [ Species.SLUGMA ], 38: [ Species.MAGCARGO ]}, + { 1: [ Species.NUMEL ], 33: [ Species.CAMERUPT ]}, + { 1: [ Species.SALANDIT ], 33: [ Species.SALAZZLE ]}, + { 1: [ Species.ROLYCOLY ], 18: [ Species.CARKOL ], 34: [ Species.COALOSSAL ]} ] }, - [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MAGMAR, Species.TORKOAL, { 1: [ Species.PANSEAR ], 30: [ Species.SIMISEAR ] }, Species.HEATMOR, Species.TURTONATOR ] }, + [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MAGMAR, Species.TORKOAL, { 1: [ Species.PANSEAR ], 30: [ Species.SIMISEAR ]}, Species.HEATMOR, Species.TURTONATOR ]}, [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.CHARMANDER ], 16: [ Species.CHARMELEON ], 36: [ Species.CHARIZARD ] }, - { 1: [ Species.CYNDAQUIL ], 14: [ Species.QUILAVA ], 36: [ Species.TYPHLOSION ] }, - { 1: [ Species.CHIMCHAR ], 14: [ Species.MONFERNO ], 36: [ Species.INFERNAPE ] }, - { 1: [ Species.TEPIG ], 17: [ Species.PIGNITE ], 36: [ Species.EMBOAR ] }, - { 1: [ Species.FENNEKIN ], 16: [ Species.BRAIXEN ], 36: [ Species.DELPHOX ] }, - { 1: [ Species.LITTEN ], 17: [ Species.TORRACAT ], 34: [ Species.INCINEROAR ] }, - { 1: [ Species.SCORBUNNY ], 16: [ Species.RABOOT ], 35: [ Species.CINDERACE ] }, - { 1: [ Species.CHARCADET ], 30: [ Species.ARMAROUGE ] } + { 1: [ Species.CHARMANDER ], 16: [ Species.CHARMELEON ], 36: [ Species.CHARIZARD ]}, + { 1: [ Species.CYNDAQUIL ], 14: [ Species.QUILAVA ], 36: [ Species.TYPHLOSION ]}, + { 1: [ Species.CHIMCHAR ], 14: [ Species.MONFERNO ], 36: [ Species.INFERNAPE ]}, + { 1: [ Species.TEPIG ], 17: [ Species.PIGNITE ], 36: [ Species.EMBOAR ]}, + { 1: [ Species.FENNEKIN ], 16: [ Species.BRAIXEN ], 36: [ Species.DELPHOX ]}, + { 1: [ Species.LITTEN ], 17: [ Species.TORRACAT ], 34: [ Species.INCINEROAR ]}, + { 1: [ Species.SCORBUNNY ], 16: [ Species.RABOOT ], 35: [ Species.CINDERACE ]}, + { 1: [ Species.CHARCADET ], 30: [ Species.ARMAROUGE ]} ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.FLAREON, Species.ROTOM, { 1: [ Species.LARVESTA ], 59: [ Species.VOLCARONA ] }, Species.HISUI_GROWLITHE ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ENTEI, Species.HEATRAN, Species.VOLCANION, Species.CHI_YU ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.FLAREON, Species.ROTOM, { 1: [ Species.LARVESTA ], 59: [ Species.VOLCARONA ]}, Species.HISUI_GROWLITHE ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ENTEI, Species.HEATRAN, Species.VOLCANION, Species.CHI_YU ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], @@ -1041,8 +1041,8 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CHARIZARD, Species.FLAREON, Species.TYPHLOSION, Species.INFERNAPE, Species.EMBOAR, Species.VOLCARONA, Species.DELPHOX, Species.INCINEROAR, Species.CINDERACE, Species.ARMAROUGE, Species.HISUI_ARCANINE ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MOLTRES, Species.ENTEI, Species.ROTOM, Species.HEATRAN, Species.VOLCANION, Species.CHI_YU ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.RESHIRAM ] } + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MOLTRES, Species.ENTEI, Species.ROTOM, Species.HEATRAN, Species.VOLCANION, Species.CHI_YU ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.RESHIRAM ]} }, [Biome.GRAVEYARD]: { [BiomePoolTier.COMMON]: { @@ -1051,14 +1051,14 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.GASTLY ], 25: [ Species.HAUNTER ] }, - { 1: [ Species.SHUPPET ], 37: [ Species.BANETTE ] }, - { 1: [ Species.DUSKULL ], 37: [ Species.DUSCLOPS ] }, - { 1: [ Species.DRIFLOON ], 28: [ Species.DRIFBLIM ] }, - { 1: [ Species.LITWICK ], 41: [ Species.LAMPENT ] }, + { 1: [ Species.GASTLY ], 25: [ Species.HAUNTER ]}, + { 1: [ Species.SHUPPET ], 37: [ Species.BANETTE ]}, + { 1: [ Species.DUSKULL ], 37: [ Species.DUSCLOPS ]}, + { 1: [ Species.DRIFLOON ], 28: [ Species.DRIFBLIM ]}, + { 1: [ Species.LITWICK ], 41: [ Species.LAMPENT ]}, Species.PHANTUMP, Species.PUMPKABOO, - { 1: [ Species.GREAVARD ], 60: [ Species.HOUNDSTONE ] } + { 1: [ Species.GREAVARD ], 60: [ Species.HOUNDSTONE ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -1066,11 +1066,11 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.CUBONE ], 28: [ Species.MAROWAK ] }, { 1: [ Species.YAMASK ], 34: [ Species.COFAGRIGUS ] }, { 1: [ Species.SINISTEA ], 30: [ Species.POLTEAGEIST ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.CUBONE ], 28: [ Species.MAROWAK ]}, { 1: [ Species.YAMASK ], 34: [ Species.COFAGRIGUS ]}, { 1: [ Species.SINISTEA ], 30: [ Species.POLTEAGEIST ]}] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MISDREAVUS, Species.MIMIKYU, { 1: [ Species.FUECOCO ], 16: [ Species.CROCALOR ], 36: [ Species.SKELEDIRGE ] }, Species.CERULEDGE ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SPIRITOMB ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MARSHADOW, Species.SPECTRIER ] }, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MISDREAVUS, Species.MIMIKYU, { 1: [ Species.FUECOCO ], 16: [ Species.CROCALOR ], 36: [ Species.SKELEDIRGE ]}, Species.CERULEDGE ]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SPIRITOMB ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MARSHADOW, Species.SPECTRIER ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.MAROWAK ], [TimeOfDay.DAY]: [ Species.MAROWAK ], @@ -1078,9 +1078,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GENGAR, Species.BANETTE, Species.DRIFBLIM, Species.MISMAGIUS, Species.DUSKNOIR, Species.CHANDELURE, Species.TREVENANT, Species.GOURGEIST, Species.MIMIKYU, Species.POLTEAGEIST, Species.HOUNDSTONE ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SKELEDIRGE, Species.CERULEDGE, Species.HISUI_TYPHLOSION ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MARSHADOW, Species.SPECTRIER ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GIRATINA ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.SKELEDIRGE, Species.CERULEDGE, Species.HISUI_TYPHLOSION ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MARSHADOW, Species.SPECTRIER ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GIRATINA ]} }, [Biome.DOJO]: { [BiomePoolTier.COMMON]: { @@ -1089,11 +1089,11 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.MANKEY ], 28: [ Species.PRIMEAPE ], 75: [ Species.ANNIHILAPE ] }, - { 1: [ Species.MAKUHITA ], 24: [ Species.HARIYAMA ] }, - { 1: [ Species.MEDITITE ], 37: [ Species.MEDICHAM ] }, - { 1: [ Species.STUFFUL ], 27: [ Species.BEWEAR ] }, - { 1: [ Species.CLOBBOPUS ], 55: [ Species.GRAPPLOCT ] } + { 1: [ Species.MANKEY ], 28: [ Species.PRIMEAPE ], 75: [ Species.ANNIHILAPE ]}, + { 1: [ Species.MAKUHITA ], 24: [ Species.HARIYAMA ]}, + { 1: [ Species.MEDITITE ], 37: [ Species.MEDICHAM ]}, + { 1: [ Species.STUFFUL ], 27: [ Species.BEWEAR ]}, + { 1: [ Species.CLOBBOPUS ], 55: [ Species.GRAPPLOCT ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -1101,11 +1101,11 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.CROAGUNK ], 37: [ Species.TOXICROAK ] }, { 1: [ Species.SCRAGGY ], 39: [ Species.SCRAFTY ] }, { 1: [ Species.MIENFOO ], 50: [ Species.MIENSHAO ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.CROAGUNK ], 37: [ Species.TOXICROAK ]}, { 1: [ Species.SCRAGGY ], 39: [ Species.SCRAFTY ]}, { 1: [ Species.MIENFOO ], 50: [ Species.MIENSHAO ]}] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HITMONLEE, Species.HITMONCHAN, Species.LUCARIO, Species.THROH, Species.SAWK, { 1: [ Species.PANCHAM ], 52: [ Species.PANGORO ] } ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HITMONTOP, Species.GALLADE, Species.GALAR_FARFETCHD ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TERRAKION, Species.KUBFU, Species.GALAR_ZAPDOS ] }, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HITMONLEE, Species.HITMONCHAN, Species.LUCARIO, Species.THROH, Species.SAWK, { 1: [ Species.PANCHAM ], 52: [ Species.PANGORO ]}]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HITMONTOP, Species.GALLADE, Species.GALAR_FARFETCHD ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TERRAKION, Species.KUBFU, Species.GALAR_ZAPDOS ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], @@ -1113,9 +1113,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HITMONLEE, Species.HITMONCHAN, Species.HARIYAMA, Species.MEDICHAM, Species.LUCARIO, Species.TOXICROAK, Species.THROH, Species.SAWK, Species.SCRAFTY, Species.MIENSHAO, Species.BEWEAR, Species.GRAPPLOCT, Species.ANNIHILAPE ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HITMONTOP, Species.GALLADE, Species.PANGORO, Species.SIRFETCHD, Species.HISUI_DECIDUEYE ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TERRAKION, Species.URSHIFU ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ZAMAZENTA, Species.GALAR_ZAPDOS ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HITMONTOP, Species.GALLADE, Species.PANGORO, Species.SIRFETCHD, Species.HISUI_DECIDUEYE ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TERRAKION, Species.URSHIFU ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ZAMAZENTA, Species.GALAR_ZAPDOS ]} }, [Biome.FACTORY]: { [BiomePoolTier.COMMON]: { @@ -1124,21 +1124,21 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.MACHOP ], 28: [ Species.MACHOKE ] }, - { 1: [ Species.MAGNEMITE ], 30: [ Species.MAGNETON ] }, - { 1: [ Species.VOLTORB ], 30: [ Species.ELECTRODE ] }, - { 1: [ Species.TIMBURR ], 25: [ Species.GURDURR ] }, - { 1: [ Species.KLINK ], 38: [ Species.KLANG ], 49: [ Species.KLINKLANG ] } + { 1: [ Species.MACHOP ], 28: [ Species.MACHOKE ]}, + { 1: [ Species.MAGNEMITE ], 30: [ Species.MAGNETON ]}, + { 1: [ Species.VOLTORB ], 30: [ Species.ELECTRODE ]}, + { 1: [ Species.TIMBURR ], 25: [ Species.GURDURR ]}, + { 1: [ Species.KLINK ], 38: [ Species.KLANG ], 49: [ Species.KLINKLANG ]} ] }, - [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.BRONZOR ], 33: [ Species.BRONZONG ] }, Species.KLEFKI ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.PORYGON ], 30: [ Species.PORYGON2 ] } ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.BELDUM ], 20: [ Species.METANG ], 45: [ Species.METAGROSS ] } ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GENESECT, Species.MAGEARNA ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KLINKLANG, Species.KLEFKI ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GENESECT, Species.MAGEARNA ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.BRONZOR ], 33: [ Species.BRONZONG ]}, Species.KLEFKI ]}, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.PORYGON ], 30: [ Species.PORYGON2 ]}]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.BELDUM ], 20: [ Species.METANG ], 45: [ Species.METAGROSS ]}]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GENESECT, Species.MAGEARNA ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KLINKLANG, Species.KLEFKI ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GENESECT, Species.MAGEARNA ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.RUINS]: { [BiomePoolTier.COMMON]: { @@ -1147,12 +1147,12 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.DROWZEE ], 26: [ Species.HYPNO ] }, - { 1: [ Species.NATU ], 25: [ Species.XATU ] }, + { 1: [ Species.DROWZEE ], 26: [ Species.HYPNO ]}, + { 1: [ Species.NATU ], 25: [ Species.XATU ]}, Species.UNOWN, - { 1: [ Species.SPOINK ], 32: [ Species.GRUMPIG ] }, - { 1: [ Species.BALTOY ], 36: [ Species.CLAYDOL ] }, - { 1: [ Species.ELGYEM ], 42: [ Species.BEHEEYEM ] } + { 1: [ Species.SPOINK ], 32: [ Species.GRUMPIG ]}, + { 1: [ Species.BALTOY ], 36: [ Species.CLAYDOL ]}, + { 1: [ Species.ELGYEM ], 42: [ Species.BEHEEYEM ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -1160,58 +1160,58 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.ABRA ], 16: [ Species.KADABRA ] }, Species.SIGILYPH, { 1: [ Species.TINKATINK ], 24: [ Species.TINKATUFF ], 38: [ Species.TINKATON ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.ABRA ], 16: [ Species.KADABRA ]}, Species.SIGILYPH, { 1: [ Species.TINKATINK ], 24: [ Species.TINKATUFF ], 38: [ Species.TINKATON ]}] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MR_MIME, Species.WOBBUFFET, { 1: [ Species.GOTHITA ], 32: [ Species.GOTHORITA ], 41: [ Species.GOTHITELLE ] }, Species.STONJOURNER ] }, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MR_MIME, Species.WOBBUFFET, { 1: [ Species.GOTHITA ], 32: [ Species.GOTHORITA ], 41: [ Species.GOTHITELLE ]}, Species.STONJOURNER ]}, [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ Species.ESPEON ], - [TimeOfDay.DUSK]: [ { 1: [ Species.GALAR_YAMASK ], 34: [ Species.RUNERIGUS ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.GALAR_YAMASK ], 34: [ Species.RUNERIGUS ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.ARCHEN ], 37: [ Species.ARCHEOPS ] } ] + [TimeOfDay.DUSK]: [{ 1: [ Species.GALAR_YAMASK ], 34: [ Species.RUNERIGUS ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.GALAR_YAMASK ], 34: [ Species.RUNERIGUS ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.ARCHEN ], 37: [ Species.ARCHEOPS ]}] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGISTEEL, Species.FEZANDIPITI ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ALAKAZAM, Species.HYPNO, Species.XATU, Species.GRUMPIG, Species.CLAYDOL, Species.SIGILYPH, Species.GOTHITELLE, Species.BEHEEYEM, Species.TINKATON ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ Species.ESPEON ], [TimeOfDay.DUSK]: [ Species.RUNERIGUS ], [TimeOfDay.NIGHT]: [ Species.RUNERIGUS ], [TimeOfDay.ALL]: [ Species.MR_MIME, Species.WOBBUFFET, Species.ARCHEOPS ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGISTEEL, Species.FEZANDIPITI ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KORAIDON ] } + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGISTEEL, Species.FEZANDIPITI ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ALAKAZAM, Species.HYPNO, Species.XATU, Species.GRUMPIG, Species.CLAYDOL, Species.SIGILYPH, Species.GOTHITELLE, Species.BEHEEYEM, Species.TINKATON ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ Species.ESPEON ], [TimeOfDay.DUSK]: [ Species.RUNERIGUS ], [TimeOfDay.NIGHT]: [ Species.RUNERIGUS ], [TimeOfDay.ALL]: [ Species.MR_MIME, Species.WOBBUFFET, Species.ARCHEOPS ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGISTEEL, Species.FEZANDIPITI ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KORAIDON ]} }, [Biome.WASTELAND]: { [BiomePoolTier.COMMON]: { [TimeOfDay.DAWN]: [ - { 1: [ Species.BAGON ], 30: [ Species.SHELGON ], 50: [ Species.SALAMENCE ] }, - { 1: [ Species.GOOMY ], 40: [ Species.SLIGGOO ], 80: [ Species.GOODRA ] }, - { 1: [ Species.JANGMO_O ], 35: [ Species.HAKAMO_O ], 45: [ Species.KOMMO_O ] } + { 1: [ Species.BAGON ], 30: [ Species.SHELGON ], 50: [ Species.SALAMENCE ]}, + { 1: [ Species.GOOMY ], 40: [ Species.SLIGGOO ], 80: [ Species.GOODRA ]}, + { 1: [ Species.JANGMO_O ], 35: [ Species.HAKAMO_O ], 45: [ Species.KOMMO_O ]} ], [TimeOfDay.DAY]: [ - { 1: [ Species.BAGON ], 30: [ Species.SHELGON ], 50: [ Species.SALAMENCE ] }, - { 1: [ Species.GOOMY ], 40: [ Species.SLIGGOO ], 80: [ Species.GOODRA ] }, - { 1: [ Species.JANGMO_O ], 35: [ Species.HAKAMO_O ], 45: [ Species.KOMMO_O ] } + { 1: [ Species.BAGON ], 30: [ Species.SHELGON ], 50: [ Species.SALAMENCE ]}, + { 1: [ Species.GOOMY ], 40: [ Species.SLIGGOO ], 80: [ Species.GOODRA ]}, + { 1: [ Species.JANGMO_O ], 35: [ Species.HAKAMO_O ], 45: [ Species.KOMMO_O ]} ], - [TimeOfDay.DUSK]: [ { 1: [ Species.LARVITAR ], 30: [ Species.PUPITAR ], 55: [ Species.TYRANITAR ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.LARVITAR ], 30: [ Species.PUPITAR ], 55: [ Species.TYRANITAR ] } ], + [TimeOfDay.DUSK]: [{ 1: [ Species.LARVITAR ], 30: [ Species.PUPITAR ], 55: [ Species.TYRANITAR ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.LARVITAR ], 30: [ Species.PUPITAR ], 55: [ Species.TYRANITAR ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.VIBRAVA ], 45: [ Species.FLYGON ] }, - { 1: [ Species.GIBLE ], 24: [ Species.GABITE ], 48: [ Species.GARCHOMP ] }, - { 1: [ Species.AXEW ], 38: [ Species.FRAXURE ], 48: [ Species.HAXORUS ] } + { 1: [ Species.VIBRAVA ], 45: [ Species.FLYGON ]}, + { 1: [ Species.GIBLE ], 24: [ Species.GABITE ], 48: [ Species.GARCHOMP ]}, + { 1: [ Species.AXEW ], 38: [ Species.FRAXURE ], 48: [ Species.HAXORUS ]} ] }, [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], - [TimeOfDay.DUSK]: [ { 1: [ Species.DEINO ], 50: [ Species.ZWEILOUS ], 64: [ Species.HYDREIGON ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.DEINO ], 50: [ Species.ZWEILOUS ], 64: [ Species.HYDREIGON ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.SWABLU ], 35: [ Species.ALTARIA ] }, Species.DRAMPA, Species.CYCLIZAR ] + [TimeOfDay.DUSK]: [{ 1: [ Species.DEINO ], 50: [ Species.ZWEILOUS ], 64: [ Species.HYDREIGON ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.DEINO ], 50: [ Species.ZWEILOUS ], 64: [ Species.HYDREIGON ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.SWABLU ], 35: [ Species.ALTARIA ]}, Species.DRAMPA, Species.CYCLIZAR ] }, [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], - [TimeOfDay.DUSK]: [ { 1: [ Species.DREEPY ], 50: [ Species.DRAKLOAK ], 60: [ Species.DRAGAPULT ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.DREEPY ], 50: [ Species.DRAKLOAK ], 60: [ Species.DRAGAPULT ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.DRATINI ], 30: [ Species.DRAGONAIR ], 55: [ Species.DRAGONITE ] }, { 1: [ Species.FRIGIBAX ], 35: [ Species.ARCTIBAX ], 54: [ Species.BAXCALIBUR ] } ] + [TimeOfDay.DUSK]: [{ 1: [ Species.DREEPY ], 50: [ Species.DRAKLOAK ], 60: [ Species.DRAGAPULT ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.DREEPY ], 50: [ Species.DRAKLOAK ], 60: [ Species.DRAGAPULT ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.DRATINI ], 30: [ Species.DRAGONAIR ], 55: [ Species.DRAGONITE ]}, { 1: [ Species.FRIGIBAX ], 35: [ Species.ARCTIBAX ], 54: [ Species.BAXCALIBUR ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AERODACTYL, Species.DRUDDIGON, { 1: [ Species.TYRUNT ], 59: [ Species.TYRANTRUM ] }, Species.DRACOZOLT, Species.DRACOVISH ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIDRAGO ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AERODACTYL, Species.DRUDDIGON, { 1: [ Species.TYRUNT ], 59: [ Species.TYRANTRUM ]}, Species.DRACOZOLT, Species.DRACOVISH ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIDRAGO ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.SALAMENCE, Species.GOODRA, Species.KOMMO_O ], [TimeOfDay.DAY]: [ Species.SALAMENCE, Species.GOODRA, Species.KOMMO_O ], @@ -1219,9 +1219,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.TYRANITAR, Species.DRAGAPULT ], [TimeOfDay.ALL]: [ Species.DRAGONITE, Species.FLYGON, Species.GARCHOMP, Species.HAXORUS, Species.DRAMPA, Species.BAXCALIBUR ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AERODACTYL, Species.DRUDDIGON, Species.TYRANTRUM, Species.DRACOZOLT, Species.DRACOVISH ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIDRAGO ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DIALGA ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AERODACTYL, Species.DRUDDIGON, Species.TYRANTRUM, Species.DRACOZOLT, Species.DRACOVISH ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIDRAGO ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DIALGA ]} }, [Biome.ABYSS]: { [BiomePoolTier.COMMON]: { @@ -1231,25 +1231,25 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MURKROW, - { 1: [ Species.HOUNDOUR ], 24: [ Species.HOUNDOOM ] }, + { 1: [ Species.HOUNDOUR ], 24: [ Species.HOUNDOOM ]}, Species.SABLEYE, - { 1: [ Species.PURRLOIN ], 20: [ Species.LIEPARD ] }, - { 1: [ Species.PAWNIARD ], 52: [ Species.BISHARP ], 64: [ Species.KINGAMBIT ] }, - { 1: [ Species.NICKIT ], 18: [ Species.THIEVUL ] }, - { 1: [ Species.IMPIDIMP ], 32: [ Species.MORGREM ], 42: [ Species.GRIMMSNARL ] }, - { 1: [ Species.MASCHIFF ], 30: [ Species.MABOSSTIFF ] } + { 1: [ Species.PURRLOIN ], 20: [ Species.LIEPARD ]}, + { 1: [ Species.PAWNIARD ], 52: [ Species.BISHARP ], 64: [ Species.KINGAMBIT ]}, + { 1: [ Species.NICKIT ], 18: [ Species.THIEVUL ]}, + { 1: [ Species.IMPIDIMP ], 32: [ Species.MORGREM ], 42: [ Species.GRIMMSNARL ]}, + { 1: [ Species.MASCHIFF ], 30: [ Species.MABOSSTIFF ]} ] }, - [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, + [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ Species.ABSOL, Species.SPIRITOMB, { 1: [ Species.ZORUA ], 30: [ Species.ZOROARK ] }, { 1: [ Species.DEINO ], 50: [ Species.ZWEILOUS ], 64: [ Species.HYDREIGON ] } ] + [TimeOfDay.ALL]: [ Species.ABSOL, Species.SPIRITOMB, { 1: [ Species.ZORUA ], 30: [ Species.ZOROARK ]}, { 1: [ Species.DEINO ], 50: [ Species.ZWEILOUS ], 64: [ Species.HYDREIGON ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.UMBREON ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DARKRAI, Species.GALAR_MOLTRES ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.UMBREON ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DARKRAI, Species.GALAR_MOLTRES ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], @@ -1257,9 +1257,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HOUNDOOM, Species.SABLEYE, Species.ABSOL, Species.HONCHKROW, Species.SPIRITOMB, Species.LIEPARD, Species.ZOROARK, Species.HYDREIGON, Species.THIEVUL, Species.GRIMMSNARL, Species.MABOSSTIFF, Species.KINGAMBIT ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.UMBREON, Species.HISUI_SAMUROTT ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DARKRAI ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.PALKIA, Species.YVELTAL, Species.GALAR_MOLTRES ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.UMBREON, Species.HISUI_SAMUROTT ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DARKRAI ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.PALKIA, Species.YVELTAL, Species.GALAR_MOLTRES ]} }, [Biome.SPACE]: { [BiomePoolTier.COMMON]: { @@ -1267,22 +1267,22 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DAY]: [ Species.SOLROCK ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.LUNATONE ], - [TimeOfDay.ALL]: [ Species.CLEFAIRY, { 1: [ Species.BRONZOR ], 33: [ Species.BRONZONG ] }, { 1: [ Species.MUNNA ], 30: [ Species.MUSHARNA ] }, Species.MINIOR ] + [TimeOfDay.ALL]: [ Species.CLEFAIRY, { 1: [ Species.BRONZOR ], 33: [ Species.BRONZONG ]}, { 1: [ Species.MUNNA ], 30: [ Species.MUSHARNA ]}, Species.MINIOR ] }, - [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.BALTOY ], 36: [ Species.CLAYDOL ] }, { 1: [ Species.ELGYEM ], 42: [ Species.BEHEEYEM ] } ] }, + [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.BALTOY ], 36: [ Species.CLAYDOL ]}, { 1: [ Species.ELGYEM ], 42: [ Species.BEHEEYEM ]}]}, [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ { 1: [ Species.BELDUM ], 20: [ Species.METANG ], 45: [ Species.METAGROSS ] }, Species.SIGILYPH, { 1: [ Species.SOLOSIS ], 32: [ Species.DUOSION ], 41: [ Species.REUNICLUS ] } ] + [TimeOfDay.ALL]: [{ 1: [ Species.BELDUM ], 20: [ Species.METANG ], 45: [ Species.METAGROSS ]}, Species.SIGILYPH, { 1: [ Species.SOLOSIS ], 32: [ Species.DUOSION ], 41: [ Species.REUNICLUS ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.PORYGON ], 30: [ Species.PORYGON2 ] } ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.COSMOG ], 43: [ Species.COSMOEM ] }, Species.CELESTEELA ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ Species.SOLROCK ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.LUNATONE ], [TimeOfDay.ALL]: [ Species.CLEFABLE, Species.BRONZONG, Species.MUSHARNA, Species.REUNICLUS, Species.MINIOR ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.METAGROSS, Species.PORYGON_Z ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CELESTEELA ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ Species.SOLGALEO ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.LUNALA ], [TimeOfDay.ALL]: [ Species.RAYQUAZA, Species.NECROZMA ] } + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.PORYGON ], 30: [ Species.PORYGON2 ]}]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.COSMOG ], 43: [ Species.COSMOEM ]}, Species.CELESTEELA ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ Species.SOLROCK ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.LUNATONE ], [TimeOfDay.ALL]: [ Species.CLEFABLE, Species.BRONZONG, Species.MUSHARNA, Species.REUNICLUS, Species.MINIOR ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.METAGROSS, Species.PORYGON_Z ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CELESTEELA ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ Species.SOLGALEO ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ Species.LUNALA ], [TimeOfDay.ALL]: [ Species.RAYQUAZA, Species.NECROZMA ]} }, [Biome.CONSTRUCTION_SITE]: { [BiomePoolTier.COMMON]: { @@ -1291,10 +1291,10 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.MACHOP ], 28: [ Species.MACHOKE ] }, - { 1: [ Species.MAGNEMITE ], 30: [ Species.MAGNETON ] }, - { 1: [ Species.DRILBUR ], 31: [ Species.EXCADRILL ] }, - { 1: [ Species.TIMBURR ], 25: [ Species.GURDURR ] } + { 1: [ Species.MACHOP ], 28: [ Species.MACHOKE ]}, + { 1: [ Species.MAGNEMITE ], 30: [ Species.MAGNETON ]}, + { 1: [ Species.DRILBUR ], 31: [ Species.EXCADRILL ]}, + { 1: [ Species.TIMBURR ], 25: [ Species.GURDURR ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -1303,60 +1303,60 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.GRIMER ], 38: [ Species.MUK ] }, - { 1: [ Species.KOFFING ], 35: [ Species.WEEZING ] }, - { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ] }, - { 1: [ Species.SCRAGGY ], 39: [ Species.SCRAFTY ] } + { 1: [ Species.GRIMER ], 38: [ Species.MUK ]}, + { 1: [ Species.KOFFING ], 35: [ Species.WEEZING ]}, + { 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ]}, + { 1: [ Species.SCRAGGY ], 39: [ Species.SCRAFTY ]} ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ { 1: [ Species.GALAR_MEOWTH ], 28: [ Species.PERRSERKER ] } ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ONIX, Species.HITMONLEE, Species.HITMONCHAN, Species.DURALUDON ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO, Species.HITMONTOP ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.COBALION, Species.STAKATAKA ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MACHAMP, Species.CONKELDURR ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ Species.PERRSERKER ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ARCHALUDON ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.COBALION, Species.STAKATAKA ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [{ 1: [ Species.GALAR_MEOWTH ], 28: [ Species.PERRSERKER ]}], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ONIX, Species.HITMONLEE, Species.HITMONCHAN, Species.DURALUDON ]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO, Species.HITMONTOP ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.COBALION, Species.STAKATAKA ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MACHAMP, Species.CONKELDURR ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ Species.PERRSERKER ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ARCHALUDON ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.COBALION, Species.STAKATAKA ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.JUNGLE]: { [BiomePoolTier.COMMON]: { - [TimeOfDay.DAWN]: [ Species.VESPIQUEN, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ] }, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ] } ], - [TimeOfDay.DAY]: [ Species.VESPIQUEN, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ] }, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ] } ], - [TimeOfDay.DUSK]: [ Species.SHROOMISH, { 1: [ Species.PURRLOIN ], 20: [ Species.LIEPARD ] }, { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ] }, Species.SHROOMISH, { 1: [ Species.PURRLOIN ], 20: [ Species.LIEPARD ] }, { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ] } ], - [TimeOfDay.ALL]: [ Species.AIPOM, { 1: [ Species.BLITZLE ], 27: [ Species.ZEBSTRIKA ] }, { 1: [ Species.PIKIPEK ], 14: [ Species.TRUMBEAK ], 28: [ Species.TOUCANNON ] } ] + [TimeOfDay.DAWN]: [ Species.VESPIQUEN, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ]}, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ]}], + [TimeOfDay.DAY]: [ Species.VESPIQUEN, { 1: [ Species.CHERUBI ], 25: [ Species.CHERRIM ]}, { 1: [ Species.SEWADDLE ], 20: [ Species.SWADLOON ], 30: [ Species.LEAVANNY ]}], + [TimeOfDay.DUSK]: [ Species.SHROOMISH, { 1: [ Species.PURRLOIN ], 20: [ Species.LIEPARD ]}, { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ]}, Species.SHROOMISH, { 1: [ Species.PURRLOIN ], 20: [ Species.LIEPARD ]}, { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ]}], + [TimeOfDay.ALL]: [ Species.AIPOM, { 1: [ Species.BLITZLE ], 27: [ Species.ZEBSTRIKA ]}, { 1: [ Species.PIKIPEK ], 14: [ Species.TRUMBEAK ], 28: [ Species.TOUCANNON ]}] }, [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [ Species.EXEGGCUTE, Species.TROPIUS, Species.COMBEE, Species.KOMALA ], [TimeOfDay.DAY]: [ Species.EXEGGCUTE, Species.TROPIUS, Species.COMBEE, Species.KOMALA ], - [TimeOfDay.DUSK]: [ Species.TANGELA, { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ] }, { 1: [ Species.PANCHAM ], 52: [ Species.PANGORO ] } ], - [TimeOfDay.NIGHT]: [ Species.TANGELA, { 1: [ Species.PANCHAM ], 52: [ Species.PANGORO ] } ], + [TimeOfDay.DUSK]: [ Species.TANGELA, { 1: [ Species.SPINARAK ], 22: [ Species.ARIADOS ]}, { 1: [ Species.PANCHAM ], 52: [ Species.PANGORO ]}], + [TimeOfDay.NIGHT]: [ Species.TANGELA, { 1: [ Species.PANCHAM ], 52: [ Species.PANGORO ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.PANSAGE ], 30: [ Species.SIMISAGE ] }, - { 1: [ Species.PANSEAR ], 30: [ Species.SIMISEAR ] }, - { 1: [ Species.PANPOUR ], 30: [ Species.SIMIPOUR ] }, - { 1: [ Species.JOLTIK ], 36: [ Species.GALVANTULA ] }, - { 1: [ Species.LITLEO ], 35: [ Species.PYROAR ] }, - { 1: [ Species.FOMANTIS ], 44: [ Species.LURANTIS ] }, + { 1: [ Species.PANSAGE ], 30: [ Species.SIMISAGE ]}, + { 1: [ Species.PANSEAR ], 30: [ Species.SIMISEAR ]}, + { 1: [ Species.PANPOUR ], 30: [ Species.SIMIPOUR ]}, + { 1: [ Species.JOLTIK ], 36: [ Species.GALVANTULA ]}, + { 1: [ Species.LITLEO ], 35: [ Species.PYROAR ]}, + { 1: [ Species.FOMANTIS ], 44: [ Species.LURANTIS ]}, Species.FALINKS ] }, [BiomePoolTier.RARE]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ] }, Species.PASSIMIAN, { 1: [ Species.GALAR_PONYTA ], 40: [ Species.GALAR_RAPIDASH ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ] }, Species.PASSIMIAN ], + [TimeOfDay.DAWN]: [{ 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ]}, Species.PASSIMIAN, { 1: [ Species.GALAR_PONYTA ], 40: [ Species.GALAR_RAPIDASH ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.FOONGUS ], 39: [ Species.AMOONGUSS ]}, Species.PASSIMIAN ], [TimeOfDay.DUSK]: [ Species.ORANGURU ], [TimeOfDay.NIGHT]: [ Species.ORANGURU ], [TimeOfDay.ALL]: [ Species.SCYTHER, Species.YANMA, - { 1: [ Species.SLAKOTH ], 18: [ Species.VIGOROTH ], 36: [ Species.SLAKING ] }, + { 1: [ Species.SLAKOTH ], 18: [ Species.VIGOROTH ], 36: [ Species.SLAKING ]}, Species.SEVIPER, Species.CARNIVINE, - { 1: [ Species.SNIVY ], 17: [ Species.SERVINE ], 36: [ Species.SERPERIOR ] }, - { 1: [ Species.GROOKEY ], 16: [ Species.THWACKEY ], 35: [ Species.RILLABOOM ] } + { 1: [ Species.SNIVY ], 17: [ Species.SERVINE ], 36: [ Species.SERPERIOR ]}, + { 1: [ Species.GROOKEY ], 16: [ Species.THWACKEY ], 35: [ Species.RILLABOOM ]} ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KANGASKHAN, Species.CHATOT, Species.KLEAVOR ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TAPU_LELE, Species.BUZZWOLE, Species.ZARUDE, Species.MUNKIDORI ] }, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KANGASKHAN, Species.CHATOT, Species.KLEAVOR ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TAPU_LELE, Species.BUZZWOLE, Species.ZARUDE, Species.MUNKIDORI ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.EXEGGUTOR, Species.TROPIUS, Species.CHERRIM, Species.LEAVANNY, Species.KOMALA ], [TimeOfDay.DAY]: [ Species.EXEGGUTOR, Species.TROPIUS, Species.CHERRIM, Species.LEAVANNY, Species.KOMALA ], @@ -1371,8 +1371,8 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KANGASKHAN, Species.SCIZOR, Species.SLAKING, Species.LEAFEON, Species.SERPERIOR, Species.RILLABOOM ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TAPU_LELE, Species.BUZZWOLE, Species.ZARUDE, Species.MUNKIDORI ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KLEAVOR ] } + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TAPU_LELE, Species.BUZZWOLE, Species.ZARUDE, Species.MUNKIDORI ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.KLEAVOR ]} }, [Biome.FAIRY_CAVE]: { [BiomePoolTier.COMMON]: { @@ -1381,14 +1381,14 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.JIGGLYPUFF ], 30: [ Species.WIGGLYTUFF ] }, - { 1: [ Species.MARILL ], 18: [ Species.AZUMARILL ] }, + { 1: [ Species.JIGGLYPUFF ], 30: [ Species.WIGGLYTUFF ]}, + { 1: [ Species.MARILL ], 18: [ Species.AZUMARILL ]}, Species.MAWILE, - { 1: [ Species.SPRITZEE ], 40: [ Species.AROMATISSE ] }, - { 1: [ Species.SWIRLIX ], 40: [ Species.SLURPUFF ] }, - { 1: [ Species.CUTIEFLY ], 25: [ Species.RIBOMBEE ] }, - { 1: [ Species.MORELULL ], 24: [ Species.SHIINOTIC ] }, - { 1: [ Species.MILCERY ], 30: [ Species.ALCREMIE ] } + { 1: [ Species.SPRITZEE ], 40: [ Species.AROMATISSE ]}, + { 1: [ Species.SWIRLIX ], 40: [ Species.SLURPUFF ]}, + { 1: [ Species.CUTIEFLY ], 25: [ Species.RIBOMBEE ]}, + { 1: [ Species.MORELULL ], 24: [ Species.SHIINOTIC ]}, + { 1: [ Species.MILCERY ], 30: [ Species.ALCREMIE ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -1399,15 +1399,15 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.ALL]: [ Species.CLEFAIRY, Species.TOGETIC, - { 1: [ Species.RALTS ], 20: [ Species.KIRLIA ], 30: [ Species.GARDEVOIR ] }, + { 1: [ Species.RALTS ], 20: [ Species.KIRLIA ], 30: [ Species.GARDEVOIR ]}, Species.CARBINK, Species.COMFEY, - { 1: [ Species.HATENNA ], 32: [ Species.HATTREM ], 42: [ Species.HATTERENE ] } + { 1: [ Species.HATENNA ], 32: [ Species.HATTREM ], 42: [ Species.HATTERENE ]} ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AUDINO, Species.ETERNAL_FLOETTE ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DIANCIE, Species.ENAMORUS ] }, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.AUDINO, Species.ETERNAL_FLOETTE ]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DIANCIE, Species.ENAMORUS ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], @@ -1415,9 +1415,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.WIGGLYTUFF, Species.MAWILE, Species.TOGEKISS, Species.AUDINO, Species.AROMATISSE, Species.SLURPUFF, Species.CARBINK, Species.RIBOMBEE, Species.SHIINOTIC, Species.COMFEY, Species.HATTERENE, Species.ALCREMIE ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ETERNAL_FLOETTE ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DIANCIE, Species.ENAMORUS ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.XERNEAS ] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ETERNAL_FLOETTE ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DIANCIE, Species.ENAMORUS ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.XERNEAS ]} }, [Biome.TEMPLE]: { [BiomePoolTier.COMMON]: { @@ -1426,12 +1426,12 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.GASTLY ], 25: [ Species.HAUNTER ] }, - { 1: [ Species.NATU ], 25: [ Species.XATU ] }, - { 1: [ Species.DUSKULL ], 37: [ Species.DUSCLOPS ] }, - { 1: [ Species.YAMASK ], 34: [ Species.COFAGRIGUS ] }, - { 1: [ Species.GOLETT ], 43: [ Species.GOLURK ] }, - { 1: [ Species.HONEDGE ], 35: [ Species.DOUBLADE ] } + { 1: [ Species.GASTLY ], 25: [ Species.HAUNTER ]}, + { 1: [ Species.NATU ], 25: [ Species.XATU ]}, + { 1: [ Species.DUSKULL ], 37: [ Species.DUSCLOPS ]}, + { 1: [ Species.YAMASK ], 34: [ Species.COFAGRIGUS ]}, + { 1: [ Species.GOLETT ], 43: [ Species.GOLURK ]}, + { 1: [ Species.HONEDGE ], 35: [ Species.DOUBLADE ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -1440,86 +1440,86 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.CUBONE ], 28: [ Species.MAROWAK ] }, - { 1: [ Species.BALTOY ], 36: [ Species.CLAYDOL ] }, - { 1: [ Species.CHINGLING ], 20: [ Species.CHIMECHO ] }, - { 1: [ Species.SKORUPI ], 40: [ Species.DRAPION ] }, - { 1: [ Species.LITWICK ], 41: [ Species.LAMPENT ] } + { 1: [ Species.CUBONE ], 28: [ Species.MAROWAK ]}, + { 1: [ Species.BALTOY ], 36: [ Species.CLAYDOL ]}, + { 1: [ Species.CHINGLING ], 20: [ Species.CHIMECHO ]}, + { 1: [ Species.SKORUPI ], 40: [ Species.DRAPION ]}, + { 1: [ Species.LITWICK ], 41: [ Species.LAMPENT ]} ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.GIMMIGHOUL ], 40: [ Species.GHOLDENGO ] } ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HOOPA, Species.TAPU_KOKO ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CHIMECHO, Species.COFAGRIGUS, Species.GOLURK, Species.AEGISLASH ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GHOLDENGO ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HOOPA, Species.TAPU_KOKO ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIGIGAS ] } + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.GIMMIGHOUL ], 40: [ Species.GHOLDENGO ]}]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HOOPA, Species.TAPU_KOKO ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.CHIMECHO, Species.COFAGRIGUS, Species.GOLURK, Species.AEGISLASH ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GHOLDENGO ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.HOOPA, Species.TAPU_KOKO ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.REGIGIGAS ]} }, [Biome.SLUM]: { [BiomePoolTier.COMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], - [TimeOfDay.DUSK]: [ { 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ] } ], + [TimeOfDay.DUSK]: [{ 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ]}], [TimeOfDay.ALL]: [ - { 1: [ Species.RATTATA ], 20: [ Species.RATICATE ] }, - { 1: [ Species.GRIMER ], 38: [ Species.MUK ] }, - { 1: [ Species.KOFFING ], 35: [ Species.WEEZING ] }, - { 1: [ Species.TRUBBISH ], 36: [ Species.GARBODOR ] } + { 1: [ Species.RATTATA ], 20: [ Species.RATICATE ]}, + { 1: [ Species.GRIMER ], 38: [ Species.MUK ]}, + { 1: [ Species.KOFFING ], 35: [ Species.WEEZING ]}, + { 1: [ Species.TRUBBISH ], 36: [ Species.GARBODOR ]} ] }, [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], - [TimeOfDay.DUSK]: [ { 1: [ Species.STUNKY ], 34: [ Species.SKUNTANK ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.STUNKY ], 34: [ Species.SKUNTANK ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.BURMY ], 20: [ Species.WORMADAM ] } ] + [TimeOfDay.DUSK]: [{ 1: [ Species.STUNKY ], 34: [ Species.SKUNTANK ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.STUNKY ], 34: [ Species.SKUNTANK ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.BURMY ], 20: [ Species.WORMADAM ]}] }, [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], - [TimeOfDay.DUSK]: [ Species.TOXTRICITY, { 1: [ Species.GALAR_LINOONE ], 65: [ Species.OBSTAGOON ] }, Species.GALAR_ZIGZAGOON ], - [TimeOfDay.NIGHT]: [ Species.TOXTRICITY, { 1: [ Species.GALAR_LINOONE ], 65: [ Species.OBSTAGOON ] }, Species.GALAR_ZIGZAGOON ], - [TimeOfDay.ALL]: [ { 1: [ Species.VAROOM ], 40: [ Species.REVAVROOM ] } ] + [TimeOfDay.DUSK]: [ Species.TOXTRICITY, { 1: [ Species.GALAR_LINOONE ], 65: [ Species.OBSTAGOON ]}, Species.GALAR_ZIGZAGOON ], + [TimeOfDay.NIGHT]: [ Species.TOXTRICITY, { 1: [ Species.GALAR_LINOONE ], 65: [ Species.OBSTAGOON ]}, Species.GALAR_ZIGZAGOON ], + [TimeOfDay.ALL]: [{ 1: [ Species.VAROOM ], 40: [ Species.REVAVROOM ]}] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GUZZLORD ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ Species.SKUNTANK, Species.WATCHOG ], [TimeOfDay.NIGHT]: [ Species.SKUNTANK, Species.WATCHOG ], [TimeOfDay.ALL]: [ Species.MUK, Species.WEEZING, Species.WORMADAM, Species.GARBODOR ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ Species.TOXTRICITY, Species.OBSTAGOON ], [TimeOfDay.NIGHT]: [ Species.TOXTRICITY, Species.OBSTAGOON ], [TimeOfDay.ALL]: [ Species.REVAVROOM, Species.GALAR_WEEZING ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GUZZLORD ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GUZZLORD ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ Species.SKUNTANK, Species.WATCHOG ], [TimeOfDay.NIGHT]: [ Species.SKUNTANK, Species.WATCHOG ], [TimeOfDay.ALL]: [ Species.MUK, Species.WEEZING, Species.WORMADAM, Species.GARBODOR ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ Species.TOXTRICITY, Species.OBSTAGOON ], [TimeOfDay.NIGHT]: [ Species.TOXTRICITY, Species.OBSTAGOON ], [TimeOfDay.ALL]: [ Species.REVAVROOM, Species.GALAR_WEEZING ]}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GUZZLORD ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.SNOWY_FOREST]: { [BiomePoolTier.COMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], - [TimeOfDay.DUSK]: [ Species.SNEASEL, { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ] }, { 1: [ Species.SNOM ], 20: [ Species.FROSMOTH ] } ], - [TimeOfDay.NIGHT]: [ Species.SNEASEL, { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ] }, { 1: [ Species.SNOM ], 20: [ Species.FROSMOTH ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.SWINUB ], 33: [ Species.PILOSWINE ] }, { 1: [ Species.SNOVER ], 40: [ Species.ABOMASNOW ] }, Species.EISCUE ] + [TimeOfDay.DUSK]: [ Species.SNEASEL, { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ]}, { 1: [ Species.SNOM ], 20: [ Species.FROSMOTH ]}], + [TimeOfDay.NIGHT]: [ Species.SNEASEL, { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ]}, { 1: [ Species.SNOM ], 20: [ Species.FROSMOTH ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.SWINUB ], 33: [ Species.PILOSWINE ]}, { 1: [ Species.SNOVER ], 40: [ Species.ABOMASNOW ]}, Species.EISCUE ] }, [BiomePoolTier.UNCOMMON]: { - [TimeOfDay.DAWN]: [ Species.SNEASEL, { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ] }, Species.STANTLER ], - [TimeOfDay.DAY]: [ Species.SNEASEL, { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ] }, Species.STANTLER ], + [TimeOfDay.DAWN]: [ Species.SNEASEL, { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ]}, Species.STANTLER ], + [TimeOfDay.DAY]: [ Species.SNEASEL, { 1: [ Species.TEDDIURSA ], 30: [ Species.URSARING ]}, Species.STANTLER ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, [BiomePoolTier.RARE]: { - [TimeOfDay.DAWN]: [ { 1: [ Species.GALAR_DARUMAKA ], 30: [ Species.GALAR_DARMANITAN ] } ], - [TimeOfDay.DAY]: [ { 1: [ Species.GALAR_DARUMAKA ], 30: [ Species.GALAR_DARMANITAN ] } ], + [TimeOfDay.DAWN]: [{ 1: [ Species.GALAR_DARUMAKA ], 30: [ Species.GALAR_DARMANITAN ]}], + [TimeOfDay.DAY]: [{ 1: [ Species.GALAR_DARUMAKA ], 30: [ Species.GALAR_DARMANITAN ]}], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], - [TimeOfDay.ALL]: [ Species.DELIBIRD, { 1: [ Species.ALOLA_SANDSHREW ], 30: [ Species.ALOLA_SANDSLASH ] }, { 1: [ Species.ALOLA_VULPIX ], 30: [ Species.ALOLA_NINETALES ] } ] + [TimeOfDay.ALL]: [ Species.DELIBIRD, { 1: [ Species.ALOLA_SANDSHREW ], 30: [ Species.ALOLA_SANDSLASH ]}, { 1: [ Species.ALOLA_VULPIX ], 30: [ Species.ALOLA_NINETALES ]}] }, [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [ Species.HISUI_SNEASEL ], [TimeOfDay.DAY]: [ Species.HISUI_SNEASEL ], - [TimeOfDay.DUSK]: [ { 1: [ Species.HISUI_ZORUA ], 30: [ Species.HISUI_ZOROARK ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.HISUI_ZORUA ], 30: [ Species.HISUI_ZOROARK ] } ], - [TimeOfDay.ALL]: [ { 1: [ Species.GALAR_MR_MIME ], 42: [ Species.MR_RIME ] }, Species.ARCTOZOLT, Species.HISUI_AVALUGG ] + [TimeOfDay.DUSK]: [{ 1: [ Species.HISUI_ZORUA ], 30: [ Species.HISUI_ZOROARK ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.HISUI_ZORUA ], 30: [ Species.HISUI_ZOROARK ]}], + [TimeOfDay.ALL]: [{ 1: [ Species.GALAR_MR_MIME ], 42: [ Species.MR_RIME ]}, Species.ARCTOZOLT, Species.HISUI_AVALUGG ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GLASTRIER, Species.CHIEN_PAO, Species.GALAR_ARTICUNO ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.WYRDEER ], [TimeOfDay.DAY]: [ Species.WYRDEER ], [TimeOfDay.DUSK]: [ Species.FROSMOTH ], [TimeOfDay.NIGHT]: [ Species.FROSMOTH ], [TimeOfDay.ALL]: [ Species.ABOMASNOW, Species.URSALUNA ] }, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GLASTRIER, Species.CHIEN_PAO, Species.GALAR_ARTICUNO ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.WYRDEER ], [TimeOfDay.DAY]: [ Species.WYRDEER ], [TimeOfDay.DUSK]: [ Species.FROSMOTH ], [TimeOfDay.NIGHT]: [ Species.FROSMOTH ], [TimeOfDay.ALL]: [ Species.ABOMASNOW, Species.URSALUNA ]}, [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ Species.SNEASLER, Species.GALAR_DARMANITAN ], [TimeOfDay.DAY]: [ Species.SNEASLER, Species.GALAR_DARMANITAN ], @@ -1527,22 +1527,22 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.HISUI_ZOROARK ], [TimeOfDay.ALL]: [ Species.MR_RIME, Species.ARCTOZOLT, Species.ALOLA_SANDSLASH, Species.ALOLA_NINETALES ] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GLASTRIER, Species.CHIEN_PAO ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ZACIAN, Species.GALAR_ARTICUNO ] } + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.GLASTRIER, Species.CHIEN_PAO ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ZACIAN, Species.GALAR_ARTICUNO ]} }, [Biome.ISLAND]: { [BiomePoolTier.COMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], - [TimeOfDay.DUSK]: [ { 1: [ Species.ALOLA_RATTATA ], 30: [ Species.ALOLA_RATICATE ] }, { 1: [ Species.ALOLA_MEOWTH ], 30: [ Species.ALOLA_PERSIAN ] } ], - [TimeOfDay.NIGHT]: [ { 1: [ Species.ALOLA_RATTATA ], 30: [ Species.ALOLA_RATICATE ] }, { 1: [ Species.ALOLA_MEOWTH ], 30: [ Species.ALOLA_PERSIAN ] } ], + [TimeOfDay.DUSK]: [{ 1: [ Species.ALOLA_RATTATA ], 30: [ Species.ALOLA_RATICATE ]}, { 1: [ Species.ALOLA_MEOWTH ], 30: [ Species.ALOLA_PERSIAN ]}], + [TimeOfDay.NIGHT]: [{ 1: [ Species.ALOLA_RATTATA ], 30: [ Species.ALOLA_RATICATE ]}, { 1: [ Species.ALOLA_MEOWTH ], 30: [ Species.ALOLA_PERSIAN ]}], [TimeOfDay.ALL]: [ Species.ORICORIO, - { 1: [ Species.ALOLA_SANDSHREW ], 30: [ Species.ALOLA_SANDSLASH ] }, - { 1: [ Species.ALOLA_VULPIX ], 30: [ Species.ALOLA_NINETALES ] }, - { 1: [ Species.ALOLA_DIGLETT ], 26: [ Species.ALOLA_DUGTRIO ] }, - { 1: [ Species.ALOLA_GEODUDE ], 25: [ Species.ALOLA_GRAVELER ], 40: [ Species.ALOLA_GOLEM ] }, - { 1: [ Species.ALOLA_GRIMER ], 38: [ Species.ALOLA_MUK ] } + { 1: [ Species.ALOLA_SANDSHREW ], 30: [ Species.ALOLA_SANDSLASH ]}, + { 1: [ Species.ALOLA_VULPIX ], 30: [ Species.ALOLA_NINETALES ]}, + { 1: [ Species.ALOLA_DIGLETT ], 26: [ Species.ALOLA_DUGTRIO ]}, + { 1: [ Species.ALOLA_GEODUDE ], 25: [ Species.ALOLA_GRAVELER ], 40: [ Species.ALOLA_GOLEM ]}, + { 1: [ Species.ALOLA_GRIMER ], 38: [ Species.ALOLA_MUK ]} ] }, [BiomePoolTier.UNCOMMON]: { @@ -1552,9 +1552,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.ALOLA_MAROWAK ], [TimeOfDay.ALL]: [ Species.BRUXISH ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLACEPHALON ] }, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLACEPHALON ]}, [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ Species.ALOLA_RAICHU, Species.ALOLA_EXEGGUTOR ], [TimeOfDay.DAY]: [ Species.ALOLA_RAICHU, Species.ALOLA_EXEGGUTOR ], @@ -1562,9 +1562,9 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.NIGHT]: [ Species.ALOLA_RATICATE, Species.ALOLA_PERSIAN, Species.ALOLA_MAROWAK ], [TimeOfDay.ALL]: [ Species.ORICORIO, Species.BRUXISH, Species.ALOLA_SANDSLASH, Species.ALOLA_NINETALES, Species.ALOLA_DUGTRIO, Species.ALOLA_GOLEM, Species.ALOLA_MUK ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLACEPHALON ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.BLACEPHALON ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} }, [Biome.LABORATORY]: { [BiomePoolTier.COMMON]: { @@ -1573,21 +1573,21 @@ export const biomePokemonPools: BiomePokemonPools = { [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ - { 1: [ Species.MAGNEMITE ], 30: [ Species.MAGNETON ] }, - { 1: [ Species.GRIMER ], 38: [ Species.MUK ] }, - { 1: [ Species.VOLTORB ], 30: [ Species.ELECTRODE ] }, - { 1: [ Species.BRONZOR ], 33: [ Species.BRONZONG ] }, - { 1: [ Species.KLINK ], 38: [ Species.KLANG ], 49: [ Species.KLINKLANG ] } + { 1: [ Species.MAGNEMITE ], 30: [ Species.MAGNETON ]}, + { 1: [ Species.GRIMER ], 38: [ Species.MUK ]}, + { 1: [ Species.VOLTORB ], 30: [ Species.ELECTRODE ]}, + { 1: [ Species.BRONZOR ], 33: [ Species.BRONZONG ]}, + { 1: [ Species.KLINK ], 38: [ Species.KLANG ], 49: [ Species.KLINKLANG ]} ] }, - [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ Species.SOLOSIS ], 32: [ Species.DUOSION ], 41: [ Species.REUNICLUS ] } ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO, { 1: [ Species.PORYGON ], 30: [ Species.PORYGON2 ] } ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM ] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TYPE_NULL ] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MUK, Species.ELECTRODE, Species.BRONZONG, Species.MAGNEZONE, Species.PORYGON_Z, Species.REUNICLUS, Species.KLINKLANG ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM, Species.ZYGARDE, Species.SILVALLY ] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MEWTWO, Species.MIRAIDON ] } + [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [{ 1: [ Species.SOLOSIS ], 32: [ Species.DUOSION ], 41: [ Species.REUNICLUS ]}]}, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.DITTO, { 1: [ Species.PORYGON ], 30: [ Species.PORYGON2 ]}]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM ]}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.TYPE_NULL ]}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MUK, Species.ELECTRODE, Species.BRONZONG, Species.MAGNEZONE, Species.PORYGON_Z, Species.REUNICLUS, Species.KLINKLANG ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROTOM, Species.ZYGARDE, Species.SILVALLY ]}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.MEWTWO, Species.MIRAIDON ]} }, [Biome.END]: { [BiomePoolTier.COMMON]: { @@ -1610,14 +1610,14 @@ export const biomePokemonPools: BiomePokemonPools = { Species.IRON_THORNS ] }, - [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROARING_MOON, Species.IRON_VALIANT ] }, - [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.WALKING_WAKE, Species.IRON_LEAVES, Species.GOUGING_FIRE, Species.RAGING_BOLT, Species.IRON_BOULDER, Species.IRON_CROWN ] }, - [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ETERNATUS ] }, - [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }, - [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] } + [BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ROARING_MOON, Species.IRON_VALIANT ]}, + [BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.WALKING_WAKE, Species.IRON_LEAVES, Species.GOUGING_FIRE, Species.RAGING_BOLT, Species.IRON_BOULDER, Species.IRON_CROWN ]}, + [BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ Species.ETERNATUS ]}, + [BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []}, + [BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: []} } }; @@ -2051,27 +2051,27 @@ export function initBiomes() { ] ], [ Species.CATERPIE, Type.BUG, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.METAPOD, Type.BUG, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.BUTTERFREE, Type.BUG, Type.FLYING, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.WEEDLE, Type.BUG, Type.POISON, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.KAKUNA, Type.BUG, Type.POISON, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.BEEDRILL, Type.BUG, Type.POISON, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PIDGEY, Type.NORMAL, Type.FLYING, [ @@ -2115,17 +2115,17 @@ export function initBiomes() { ] ], [ Species.EKANS, Type.POISON, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.FOREST, BiomePoolTier.UNCOMMON ], - [ Biome.SWAMP, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SWAMP, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ARBOK, Type.POISON, -1, [ [ Biome.FOREST, BiomePoolTier.UNCOMMON ], - [ Biome.SWAMP, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SWAMP, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SWAMP, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SWAMP, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PIKACHU, Type.ELECTRIC, -1, [ @@ -2215,16 +2215,16 @@ export function initBiomes() { ] ], [ Species.ODDISH, Type.GRASS, Type.POISON, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.GLOOM, Type.GRASS, Type.POISON, [ - [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.VILEPLUME, Type.GRASS, Type.POISON, [ - [ Biome.TALL_GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TALL_GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PARAS, Type.BUG, Type.GRASS, [ @@ -2261,13 +2261,13 @@ export function initBiomes() { ] ], [ Species.MEOWTH, Type.NORMAL, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PERSIAN, Type.NORMAL, -1, [ - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PSYDUCK, Type.WATER, -1, [ @@ -2282,12 +2282,12 @@ export function initBiomes() { ] ], [ Species.MANKEY, Type.FIGHTING, -1, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.DOJO, BiomePoolTier.COMMON ] ] ], [ Species.PRIMEAPE, Type.FIGHTING, -1, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.DOJO, BiomePoolTier.COMMON ] ] ], @@ -2346,16 +2346,16 @@ export function initBiomes() { ] ], [ Species.BELLSPROUT, Type.GRASS, Type.POISON, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.WEEPINBELL, Type.GRASS, Type.POISON, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.VICTREEBEL, Type.GRASS, Type.POISON, [ - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TENTACOOL, Type.WATER, Type.POISON, [ @@ -2386,25 +2386,25 @@ export function initBiomes() { ] ], [ Species.PONYTA, Type.FIRE, -1, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.VOLCANO, BiomePoolTier.COMMON ] ] ], [ Species.RAPIDASH, Type.FIRE, -1, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.VOLCANO, BiomePoolTier.COMMON ], [ Biome.VOLCANO, BiomePoolTier.BOSS ] ] ], [ Species.SLOWPOKE, Type.WATER, Type.PSYCHIC, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.LAKE, BiomePoolTier.UNCOMMON ] ] ], [ Species.SLOWBRO, Type.WATER, Type.PSYCHIC, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.LAKE, BiomePoolTier.UNCOMMON ], [ Biome.LAKE, BiomePoolTier.BOSS ] ] @@ -2429,12 +2429,12 @@ export function initBiomes() { ] ], [ Species.DODUO, Type.NORMAL, Type.FLYING, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.DODRIO, Type.NORMAL, Type.FLYING, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SEEL, Type.WATER, -1, [ @@ -2461,13 +2461,13 @@ export function initBiomes() { ] ], [ Species.SHELLDER, Type.WATER, -1, [ - [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.BEACH, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.BEACH, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.SEABED, BiomePoolTier.UNCOMMON ] ] ], [ Species.CLOYSTER, Type.WATER, Type.ICE, [ - [ Biome.BEACH, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.BEACH, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.GASTLY, Type.GHOST, Type.POISON, [ @@ -2523,12 +2523,12 @@ export function initBiomes() { ] ], [ Species.EXEGGCUTE, Type.GRASS, Type.PSYCHIC, [ - [ Biome.FOREST, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.EXEGGUTOR, Type.GRASS, Type.PSYCHIC, [ - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CUBONE, Type.GROUND, -1, [ @@ -2542,7 +2542,7 @@ export function initBiomes() { [ Biome.GRAVEYARD, BiomePoolTier.UNCOMMON ], [ Biome.TEMPLE, BiomePoolTier.UNCOMMON ], [ Biome.BADLANDS, BiomePoolTier.BOSS, TimeOfDay.NIGHT ], - [ Biome.GRAVEYARD, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY, TimeOfDay.DUSK ] ] + [ Biome.GRAVEYARD, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY, TimeOfDay.DUSK ]] ] ], [ Species.HITMONLEE, Type.FIGHTING, -1, [ @@ -2573,15 +2573,15 @@ export function initBiomes() { ] ], [ Species.RHYHORN, Type.GROUND, Type.ROCK, [ - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.BADLANDS, BiomePoolTier.COMMON ], [ Biome.CONSTRUCTION_SITE, BiomePoolTier.UNCOMMON ] ] ], [ Species.RHYDON, Type.GROUND, Type.ROCK, [ - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.BADLANDS, BiomePoolTier.COMMON ], [ Biome.CONSTRUCTION_SITE, BiomePoolTier.UNCOMMON ] ] @@ -2592,7 +2592,7 @@ export function initBiomes() { ] ], [ Species.TANGELA, Type.GRASS, -1, [ - [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.KANGASKHAN, Type.NORMAL, -1, [ @@ -2620,14 +2620,14 @@ export function initBiomes() { ] ], [ Species.STARYU, Type.WATER, -1, [ - [ Biome.BEACH, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.BEACH, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.STARMIE, Type.WATER, Type.PSYCHIC, [ - [ Biome.BEACH, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.BEACH, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.BEACH, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.BEACH, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.MR_MIME, Type.PSYCHIC, Type.FAIRY, [ @@ -2637,7 +2637,7 @@ export function initBiomes() { ], [ Species.SCYTHER, Type.BUG, Type.FLYING, [ [ Biome.TALL_GRASS, BiomePoolTier.SUPER_RARE ], - [ Biome.FOREST, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.FOREST, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.JUNGLE, BiomePoolTier.RARE ] ] ], @@ -2817,13 +2817,13 @@ export function initBiomes() { ] ], [ Species.SENTRET, Type.NORMAL, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.FURRET, Type.NORMAL, -1, [ - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HOOTHOOT, Type.NORMAL, Type.FLYING, [ @@ -2860,7 +2860,7 @@ export function initBiomes() { [ Biome.TALL_GRASS, BiomePoolTier.UNCOMMON, TimeOfDay.NIGHT ], [ Biome.FOREST, BiomePoolTier.UNCOMMON, TimeOfDay.DUSK ], [ Biome.FOREST, BiomePoolTier.COMMON, TimeOfDay.NIGHT ], - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, TimeOfDay.DUSK ], [ Biome.JUNGLE, BiomePoolTier.COMMON, TimeOfDay.NIGHT ] ] @@ -2921,17 +2921,17 @@ export function initBiomes() { ] ], [ Species.BELLOSSOM, Type.GRASS, -1, [ - [ Biome.TALL_GRASS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TALL_GRASS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.MARILL, Type.WATER, Type.FAIRY, [ - [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.FAIRY_CAVE, BiomePoolTier.COMMON ] ] ], [ Species.AZUMARILL, Type.WATER, Type.FAIRY, [ - [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.LAKE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.LAKE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.FAIRY_CAVE, BiomePoolTier.COMMON ] ] ], @@ -2946,16 +2946,16 @@ export function initBiomes() { ] ], [ Species.HOPPIP, Type.GRASS, Type.FLYING, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SKIPLOOM, Type.GRASS, Type.FLYING, [ - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.JUMPLUFF, Type.GRASS, Type.FLYING, [ - [ Biome.GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.AIPOM, Type.NORMAL, -1, [ @@ -2963,12 +2963,12 @@ export function initBiomes() { ] ], [ Species.SUNKERN, Type.GRASS, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SUNFLORA, Type.GRASS, -1, [ - [ Biome.GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.YANMA, Type.BUG, Type.FLYING, [ @@ -2977,13 +2977,13 @@ export function initBiomes() { ], [ Species.WOOPER, Type.WATER, Type.GROUND, [ [ Biome.LAKE, BiomePoolTier.UNCOMMON ], - [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.QUAGSIRE, Type.WATER, Type.GROUND, [ [ Biome.LAKE, BiomePoolTier.UNCOMMON ], - [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SWAMP, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SWAMP, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ESPEON, Type.PSYCHIC, -1, [ @@ -3024,12 +3024,12 @@ export function initBiomes() { ] ], [ Species.PINECO, Type.BUG, -1, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.FORRETRESS, Type.BUG, Type.STEEL, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.DUNSPARCE, Type.NORMAL, -1, [ @@ -3045,12 +3045,12 @@ export function initBiomes() { ] ], [ Species.SNUBBULL, Type.FAIRY, -1, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GRANBULL, Type.FAIRY, -1, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.QWILFISH, Type.WATER, Type.POISON, [ @@ -3074,23 +3074,23 @@ export function initBiomes() { ], [ Species.SNEASEL, Type.DARK, Type.ICE, [ [ Biome.ICE_CAVE, BiomePoolTier.UNCOMMON ], - [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SNOWY_FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SNOWY_FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TEDDIURSA, Type.NORMAL, -1, [ [ Biome.FOREST, BiomePoolTier.UNCOMMON ], [ Biome.CAVE, BiomePoolTier.COMMON ], - [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SNOWY_FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SNOWY_FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.URSARING, Type.NORMAL, -1, [ [ Biome.FOREST, BiomePoolTier.UNCOMMON ], [ Biome.CAVE, BiomePoolTier.COMMON ], [ Biome.CAVE, BiomePoolTier.BOSS ], - [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SNOWY_FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SNOWY_FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SLUGMA, Type.FIRE, -1, [ @@ -3160,12 +3160,12 @@ export function initBiomes() { ] ], [ Species.PHANPY, Type.GROUND, -1, [ - [ Biome.BADLANDS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.BADLANDS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.DONPHAN, Type.GROUND, -1, [ - [ Biome.BADLANDS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.BADLANDS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.BADLANDS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.BADLANDS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.PORYGON2, Type.NORMAL, -1, [ @@ -3175,9 +3175,9 @@ export function initBiomes() { ] ], [ Species.STANTLER, Type.NORMAL, -1, [ - [ Biome.FOREST, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.FOREST, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SNOWY_FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.FOREST, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SNOWY_FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SMEARGLE, Type.NORMAL, -1, [ @@ -3224,17 +3224,17 @@ export function initBiomes() { ], [ Species.LARVITAR, Type.ROCK, Type.GROUND, [ [ Biome.MOUNTAIN, BiomePoolTier.SUPER_RARE ], - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PUPITAR, Type.ROCK, Type.GROUND, [ [ Biome.MOUNTAIN, BiomePoolTier.SUPER_RARE ], - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.TYRANITAR, Type.ROCK, Type.DARK, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.LUGIA, Type.PSYCHIC, Type.FLYING, [ @@ -3287,16 +3287,16 @@ export function initBiomes() { ] ], [ Species.POOCHYENA, Type.DARK, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.MIGHTYENA, Type.DARK, -1, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ZIGZAGOON, Type.NORMAL, -1, [ @@ -3334,52 +3334,52 @@ export function initBiomes() { ] ], [ Species.LOTAD, Type.WATER, Type.GRASS, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.LOMBRE, Type.WATER, Type.GRASS, [ - [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.LUDICOLO, Type.WATER, Type.GRASS, [ - [ Biome.SWAMP, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SWAMP, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SEEDOT, Type.GRASS, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.NUZLEAF, Type.GRASS, Type.DARK, [ - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.SHIFTRY, Type.GRASS, Type.DARK, [ - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.TAILLOW, Type.NORMAL, Type.FLYING, [ [ Biome.TOWN, BiomePoolTier.COMMON ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SWELLOW, Type.NORMAL, Type.FLYING, [ - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.WINGULL, Type.WATER, Type.FLYING, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.PELIPPER, Type.WATER, Type.FLYING, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.RALTS, Type.PSYCHIC, Type.FAIRY, [ @@ -3410,17 +3410,17 @@ export function initBiomes() { ] ], [ Species.SHROOMISH, Type.GRASS, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.BRELOOM, Type.GRASS, Type.FIGHTING, [ - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.SLAKOTH, Type.NORMAL, -1, [ @@ -3482,13 +3482,13 @@ export function initBiomes() { ] ], [ Species.SKITTY, Type.NORMAL, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.DELCATTY, Type.NORMAL, -1, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SABLEYE, Type.DARK, Type.GHOST, [ @@ -3502,18 +3502,18 @@ export function initBiomes() { ] ], [ Species.ARON, Type.STEEL, Type.ROCK, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.LAIRON, Type.STEEL, Type.ROCK, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.AGGRON, Type.STEEL, Type.ROCK, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.MOUNTAIN, BiomePoolTier.BOSS ] ] ], @@ -3552,8 +3552,8 @@ export function initBiomes() { ] ], [ Species.ROSELIA, Type.GRASS, Type.POISON, [ - [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MEADOW, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MEADOW, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GULPIN, Type.POISON, -1, [ @@ -3566,12 +3566,12 @@ export function initBiomes() { ] ], [ Species.CARVANHA, Type.WATER, Type.DARK, [ - [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.SHARPEDO, Type.WATER, Type.DARK, [ - [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SEA, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.WAILMER, Type.WATER, -1, [ @@ -3617,37 +3617,37 @@ export function initBiomes() { ] ], [ Species.TRAPINCH, Type.GROUND, -1, [ - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.VIBRAVA, Type.GROUND, Type.DRAGON, [ - [ Biome.DESERT, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.DESERT, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.WASTELAND, BiomePoolTier.COMMON ] ] ], [ Species.FLYGON, Type.GROUND, Type.DRAGON, [ - [ Biome.DESERT, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.DESERT, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.WASTELAND, BiomePoolTier.COMMON ], [ Biome.WASTELAND, BiomePoolTier.BOSS ] ] ], [ Species.CACNEA, Type.GRASS, -1, [ - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.CACTURNE, Type.GRASS, Type.DARK, [ - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.SWABLU, Type.NORMAL, Type.FLYING, [ - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.WASTELAND, BiomePoolTier.UNCOMMON ] ] ], [ Species.ALTARIA, Type.DRAGON, Type.FLYING, [ - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.WASTELAND, BiomePoolTier.UNCOMMON ] ] ], @@ -3760,8 +3760,8 @@ export function initBiomes() { [ Species.TROPIUS, Type.GRASS, Type.FLYING, [ [ Biome.TALL_GRASS, BiomePoolTier.RARE ], [ Biome.FOREST, BiomePoolTier.RARE ], - [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CHIMECHO, Type.PSYCHIC, -1, [ @@ -3821,16 +3821,16 @@ export function initBiomes() { ] ], [ Species.BAGON, Type.DRAGON, -1, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SHELGON, Type.DRAGON, -1, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SALAMENCE, Type.DRAGON, Type.FLYING, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.BELDUM, Type.STEEL, Type.PSYCHIC, [ @@ -3930,20 +3930,20 @@ export function initBiomes() { ] ], [ Species.STARLY, Type.NORMAL, Type.FLYING, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.STARAVIA, Type.NORMAL, Type.FLYING, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.STARAPTOR, Type.NORMAL, Type.FLYING, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.BIDOOF, Type.NORMAL, -1, [ @@ -3957,27 +3957,27 @@ export function initBiomes() { ] ], [ Species.KRICKETOT, Type.BUG, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.KRICKETUNE, Type.BUG, -1, [ - [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.TALL_GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.TALL_GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.SHINX, Type.ELECTRIC, -1, [ - [ Biome.PLAINS, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.PLAINS, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.POWER_PLANT, BiomePoolTier.COMMON ] ] ], [ Species.LUXIO, Type.ELECTRIC, -1, [ - [ Biome.PLAINS, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.PLAINS, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.POWER_PLANT, BiomePoolTier.COMMON ] ] ], [ Species.LUXRAY, Type.ELECTRIC, -1, [ - [ Biome.PLAINS, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.PLAINS, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.POWER_PLANT, BiomePoolTier.COMMON ], [ Biome.POWER_PLANT, BiomePoolTier.BOSS ] ] @@ -3985,7 +3985,7 @@ export function initBiomes() { [ Species.BUDEW, Type.GRASS, Type.POISON, [ ] ], [ Species.ROSERADE, Type.GRASS, Type.POISON, [ - [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CRANIDOS, Type.ROCK, -1, [ @@ -4022,22 +4022,22 @@ export function initBiomes() { ] ], [ Species.MOTHIM, Type.BUG, Type.FLYING, [ - [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.COMBEE, Type.BUG, Type.FLYING, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.VESPIQUEN, Type.BUG, Type.FLYING, [ - [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.PACHIRISU, Type.ELECTRIC, -1, [ @@ -4054,15 +4054,15 @@ export function initBiomes() { ] ], [ Species.CHERUBI, Type.GRASS, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CHERRIM, Type.GRASS, -1, [ - [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SHELLOS, Type.WATER, -1, [ @@ -4122,12 +4122,12 @@ export function initBiomes() { ] ], [ Species.STUNKY, Type.POISON, Type.DARK, [ - [ Biome.SLUM, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SLUM, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.SKUNTANK, Type.POISON, Type.DARK, [ - [ Biome.SLUM, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SLUM, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SLUM, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SLUM, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.BRONZOR, Type.STEEL, Type.PSYCHIC, [ @@ -4186,12 +4186,12 @@ export function initBiomes() { ] ], [ Species.HIPPOPOTAS, Type.GROUND, -1, [ - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HIPPOWDON, Type.GROUND, -1, [ - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SKORUPI, Type.POISON, Type.BUG, [ @@ -4208,12 +4208,12 @@ export function initBiomes() { ] ], [ Species.CROAGUNK, Type.POISON, Type.FIGHTING, [ - [ Biome.SWAMP, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.SWAMP, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.DOJO, BiomePoolTier.UNCOMMON ] ] ], [ Species.TOXICROAK, Type.POISON, Type.FIGHTING, [ - [ Biome.SWAMP, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.SWAMP, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.DOJO, BiomePoolTier.UNCOMMON ], [ Biome.DOJO, BiomePoolTier.BOSS ] ] @@ -4265,7 +4265,7 @@ export function initBiomes() { ] ], [ Species.TANGROWTH, Type.GRASS, -1, [ - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ELECTIVIRE, Type.ELECTRIC, -1, [ @@ -4436,18 +4436,18 @@ export function initBiomes() { ] ], [ Species.PATRAT, Type.NORMAL, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.METROPOLIS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SLUM, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.METROPOLIS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SLUM, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.WATCHOG, Type.NORMAL, -1, [ - [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.METROPOLIS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SLUM, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SLUM, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.METROPOLIS, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SLUM, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SLUM, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.LILLIPUP, Type.NORMAL, -1, [ @@ -4465,15 +4465,15 @@ export function initBiomes() { ] ], [ Species.PURRLOIN, Type.DARK, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.ABYSS, BiomePoolTier.COMMON ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.LIEPARD, Type.DARK, -1, [ [ Biome.ABYSS, BiomePoolTier.COMMON ], [ Biome.ABYSS, BiomePoolTier.BOSS ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PANSAGE, Type.GRASS, -1, [ @@ -4519,20 +4519,20 @@ export function initBiomes() { ] ], [ Species.PIDOVE, Type.NORMAL, Type.FLYING, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TRANQUILL, Type.NORMAL, Type.FLYING, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.UNFEZANT, Type.NORMAL, Type.FLYING, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.BLITZLE, Type.ELECTRIC, -1, [ @@ -4547,15 +4547,15 @@ export function initBiomes() { ] ], [ Species.ROGGENROLA, Type.ROCK, -1, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.BADLANDS, BiomePoolTier.UNCOMMON ], [ Biome.CAVE, BiomePoolTier.COMMON ] ] ], [ Species.BOLDORE, Type.ROCK, -1, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.BADLANDS, BiomePoolTier.UNCOMMON ], [ Biome.CAVE, BiomePoolTier.COMMON ] ] @@ -4627,52 +4627,52 @@ export function initBiomes() { ] ], [ Species.SEWADDLE, Type.BUG, Type.GRASS, [ - [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SWADLOON, Type.BUG, Type.GRASS, [ - [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.LEAVANNY, Type.BUG, Type.GRASS, [ - [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.VENIPEDE, Type.BUG, Type.POISON, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.WHIRLIPEDE, Type.BUG, Type.POISON, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.SCOLIPEDE, Type.BUG, Type.POISON, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.COTTONEE, Type.GRASS, Type.FAIRY, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MEADOW, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MEADOW, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.WHIMSICOTT, Type.GRASS, Type.FAIRY, [ - [ Biome.GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.PETILIL, Type.GRASS, -1, [ - [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.LILLIGANT, Type.GRASS, -1, [ - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.BASCULIN, Type.WATER, -1, [ @@ -4680,19 +4680,19 @@ export function initBiomes() { ] ], [ Species.SANDILE, Type.GROUND, Type.DARK, [ - [ Biome.DESERT, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.DESERT, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.KROKOROK, Type.GROUND, Type.DARK, [ - [ Biome.DESERT, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.DESERT, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.KROOKODILE, Type.GROUND, Type.DARK, [ - [ Biome.DESERT, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.DESERT, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.DARUMAKA, Type.FIRE, -1, [ @@ -4786,12 +4786,12 @@ export function initBiomes() { ] ], [ Species.MINCCINO, Type.NORMAL, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MEADOW, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MEADOW, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CINCCINO, Type.NORMAL, -1, [ - [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GOTHITA, Type.PSYCHIC, -1, [ @@ -4825,12 +4825,12 @@ export function initBiomes() { ] ], [ Species.DUCKLETT, Type.WATER, Type.FLYING, [ - [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SWANNA, Type.WATER, Type.FLYING, [ - [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.LAKE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.LAKE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.VANILLITE, Type.ICE, -1, [ @@ -4847,12 +4847,12 @@ export function initBiomes() { ] ], [ Species.DEERLING, Type.NORMAL, Type.GRASS, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SAWSBUCK, Type.NORMAL, Type.GRASS, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.EMOLGA, Type.ELECTRIC, Type.FLYING, [ @@ -4868,17 +4868,17 @@ export function initBiomes() { ] ], [ Species.FOONGUS, Type.GRASS, Type.POISON, [ - [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.JUNGLE, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.JUNGLE, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.AMOONGUSS, Type.GRASS, Type.POISON, [ - [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.JUNGLE, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.JUNGLE, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.GRASS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.JUNGLE, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.JUNGLE, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.FRILLISH, Type.WATER, Type.GHOST, [ @@ -5041,26 +5041,26 @@ export function initBiomes() { ] ], [ Species.BOUFFALANT, Type.NORMAL, -1, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.RUFFLET, Type.NORMAL, Type.FLYING, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.BRAVIARY, Type.NORMAL, Type.FLYING, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.VULLABY, Type.DARK, Type.FLYING, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.MANDIBUZZ, Type.DARK, Type.FLYING, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.HEATMOR, Type.FIRE, -1, [ @@ -5074,17 +5074,17 @@ export function initBiomes() { ] ], [ Species.DEINO, Type.DARK, Type.DRAGON, [ - [ Biome.WASTELAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.WASTELAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.ABYSS, BiomePoolTier.RARE ] ] ], [ Species.ZWEILOUS, Type.DARK, Type.DRAGON, [ - [ Biome.WASTELAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.WASTELAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.ABYSS, BiomePoolTier.RARE ] ] ], [ Species.HYDREIGON, Type.DARK, Type.DRAGON, [ - [ Biome.WASTELAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.WASTELAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.ABYSS, BiomePoolTier.RARE ], [ Biome.ABYSS, BiomePoolTier.BOSS ] ] @@ -5206,30 +5206,30 @@ export function initBiomes() { [ Species.FLETCHLING, Type.NORMAL, Type.FLYING, [ [ Biome.TOWN, BiomePoolTier.COMMON ], [ Biome.PLAINS, BiomePoolTier.UNCOMMON ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.FLETCHINDER, Type.FIRE, Type.FLYING, [ [ Biome.PLAINS, BiomePoolTier.UNCOMMON ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TALONFLAME, Type.FIRE, Type.FLYING, [ [ Biome.PLAINS, BiomePoolTier.UNCOMMON ], - [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SCATTERBUG, Type.BUG, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SPEWPA, Type.BUG, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.VIVILLON, Type.BUG, Type.FLYING, [ - [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.LITLEO, Type.FIRE, Type.NORMAL, [ @@ -5264,14 +5264,14 @@ export function initBiomes() { ], [ Species.PANCHAM, Type.FIGHTING, -1, [ [ Biome.DOJO, BiomePoolTier.RARE ], - [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PANGORO, Type.FIGHTING, Type.DARK, [ [ Biome.DOJO, BiomePoolTier.RARE ], [ Biome.DOJO, BiomePoolTier.BOSS_RARE ], - [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.FURFROU, Type.NORMAL, -1, [ @@ -5280,12 +5280,12 @@ export function initBiomes() { ] ], [ Species.ESPURR, Type.PSYCHIC, -1, [ - [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.MEOWSTIC, Type.PSYCHIC, -1, [ - [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.METROPOLIS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.METROPOLIS, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.HONEDGE, Type.STEEL, Type.GHOST, [ @@ -5319,12 +5319,12 @@ export function initBiomes() { ] ], [ Species.INKAY, Type.DARK, Type.PSYCHIC, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.MALAMAR, Type.DARK, Type.PSYCHIC, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.BINACLE, Type.ROCK, Type.WATER, [ @@ -5355,11 +5355,11 @@ export function initBiomes() { ] ], [ Species.HELIOPTILE, Type.ELECTRIC, Type.NORMAL, [ - [ Biome.DESERT, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.DESERT, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HELIOLISK, Type.ELECTRIC, Type.NORMAL, [ - [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TYRUNT, Type.ROCK, Type.DRAGON, [ @@ -5402,16 +5402,16 @@ export function initBiomes() { ] ], [ Species.GOOMY, Type.DRAGON, -1, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SLIGGOO, Type.DRAGON, -1, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GOODRA, Type.DRAGON, -1, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.KLEFKI, Type.STEEL, Type.FAIRY, [ @@ -5533,13 +5533,13 @@ export function initBiomes() { ] ], [ Species.YUNGOOS, Type.NORMAL, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GUMSHOOS, Type.NORMAL, -1, [ - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GRUBBIN, Type.BUG, -1, [ @@ -5622,12 +5622,12 @@ export function initBiomes() { ] ], [ Species.DEWPIDER, Type.WATER, Type.BUG, [ - [ Biome.LAKE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.LAKE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ARAQUANID, Type.WATER, Type.BUG, [ - [ Biome.LAKE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.LAKE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.LAKE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.LAKE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.FOMANTIS, Type.GRASS, -1, [ @@ -5670,16 +5670,16 @@ export function initBiomes() { ] ], [ Species.BOUNSWEET, Type.GRASS, -1, [ - [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.STEENEE, Type.GRASS, -1, [ - [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TSAREENA, Type.GRASS, -1, [ - [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.TALL_GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TALL_GRASS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.TALL_GRASS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.COMFEY, Type.FAIRY, -1, [ @@ -5688,11 +5688,11 @@ export function initBiomes() { ] ], [ Species.ORANGURU, Type.NORMAL, Type.PSYCHIC, [ - [ Biome.JUNGLE, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.JUNGLE, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PASSIMIAN, Type.FIGHTING, -1, [ - [ Biome.JUNGLE, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.JUNGLE, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.WIMPOD, Type.BUG, Type.WATER, [ @@ -5732,8 +5732,8 @@ export function initBiomes() { ] ], [ Species.KOMALA, Type.NORMAL, -1, [ - [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.JUNGLE, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.JUNGLE, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TURTONATOR, Type.FIRE, Type.DRAGON, [ @@ -5767,16 +5767,16 @@ export function initBiomes() { ] ], [ Species.JANGMO_O, Type.DRAGON, -1, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HAKAMO_O, Type.DRAGON, Type.FIGHTING, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.KOMMO_O, Type.DRAGON, Type.FIGHTING, [ - [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.WASTELAND, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TAPU_KOKO, Type.ELECTRIC, Type.FAIRY, [ @@ -5931,43 +5931,43 @@ export function initBiomes() { ] ], [ Species.SKWOVET, Type.NORMAL, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GREEDENT, Type.NORMAL, -1, [ - [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ROOKIDEE, Type.FLYING, -1, [ [ Biome.TOWN, BiomePoolTier.RARE ], [ Biome.PLAINS, BiomePoolTier.RARE ], - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CORVISQUIRE, Type.FLYING, -1, [ [ Biome.PLAINS, BiomePoolTier.RARE ], - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CORVIKNIGHT, Type.FLYING, Type.STEEL, [ [ Biome.PLAINS, BiomePoolTier.RARE ], - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.BLIPBUG, Type.BUG, -1, [ - [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.TOWN, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.DOTTLER, Type.BUG, Type.PSYCHIC, [ - [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ORBEETLE, Type.BUG, Type.PSYCHIC, [ - [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.FOREST, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.NICKIT, Type.DARK, -1, [ @@ -6007,12 +6007,12 @@ export function initBiomes() { ] ], [ Species.YAMPER, Type.ELECTRIC, -1, [ - [ Biome.METROPOLIS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.METROPOLIS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.BOLTUND, Type.ELECTRIC, -1, [ - [ Biome.METROPOLIS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.METROPOLIS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.METROPOLIS, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.METROPOLIS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ROLYCOLY, Type.ROCK, -1, [ @@ -6050,8 +6050,8 @@ export function initBiomes() { ] ], [ Species.CRAMORANT, Type.FLYING, Type.WATER, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ARROKUDA, Type.WATER, -1, [ @@ -6066,17 +6066,17 @@ export function initBiomes() { [ Species.TOXEL, Type.ELECTRIC, Type.POISON, [ ] ], [ Species.TOXTRICITY, Type.ELECTRIC, Type.POISON, [ - [ Biome.SLUM, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SLUM, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SLUM, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SLUM, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.SIZZLIPEDE, Type.FIRE, Type.BUG, [ - [ Biome.BADLANDS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.BADLANDS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CENTISKORCH, Type.FIRE, Type.BUG, [ - [ Biome.BADLANDS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.BADLANDS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.BADLANDS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.BADLANDS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.CLOBBOPUS, Type.FIGHTING, -1, [ @@ -6124,8 +6124,8 @@ export function initBiomes() { ] ], [ Species.OBSTAGOON, Type.DARK, Type.NORMAL, [ - [ Biome.SLUM, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SLUM, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SLUM, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SLUM, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.PERRSERKER, Type.STEEL, -1, [ @@ -6148,8 +6148,8 @@ export function initBiomes() { ] ], [ Species.RUNERIGUS, Type.GROUND, Type.GHOST, [ - [ Biome.RUINS, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.RUINS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.RUINS, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.RUINS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.MILCERY, Type.FAIRY, -1, [ @@ -6172,13 +6172,13 @@ export function initBiomes() { ], [ Species.SNOM, Type.ICE, Type.BUG, [ [ Biome.ICE_CAVE, BiomePoolTier.COMMON ], - [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.FROSMOTH, Type.ICE, Type.BUG, [ [ Biome.ICE_CAVE, BiomePoolTier.COMMON ], - [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.STONJOURNER, Type.ROCK, -1, [ @@ -6191,11 +6191,11 @@ export function initBiomes() { ] ], [ Species.INDEEDEE, Type.PSYCHIC, Type.NORMAL, [ - [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.MORPEKO, Type.ELECTRIC, Type.DARK, [ - [ Biome.METROPOLIS, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.METROPOLIS, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.CUFANT, Type.STEEL, -1, [ @@ -6232,16 +6232,16 @@ export function initBiomes() { ] ], [ Species.DREEPY, Type.DRAGON, Type.GHOST, [ - [ Biome.WASTELAND, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.WASTELAND, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.DRAKLOAK, Type.DRAGON, Type.GHOST, [ - [ Biome.WASTELAND, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.WASTELAND, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.DRAGAPULT, Type.DRAGON, Type.GHOST, [ - [ Biome.WASTELAND, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.WASTELAND, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.WASTELAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ZACIAN, Type.FAIRY, -1, [ @@ -6294,7 +6294,7 @@ export function initBiomes() { ] ], [ Species.WYRDEER, Type.NORMAL, Type.PSYCHIC, [ - [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.KLEAVOR, Type.BUG, Type.ROCK, [ @@ -6311,7 +6311,7 @@ export function initBiomes() { ] ], [ Species.SNEASLER, Type.FIGHTING, Type.POISON, [ - [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.OVERQWIL, Type.DARK, Type.POISON, [ @@ -6394,31 +6394,31 @@ export function initBiomes() { ] ], [ Species.PAWMI, Type.ELECTRIC, -1, [ - [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.TOWN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.POWER_PLANT, BiomePoolTier.COMMON ] ] ], [ Species.PAWMO, Type.ELECTRIC, Type.FIGHTING, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.POWER_PLANT, BiomePoolTier.COMMON ] ] ], [ Species.PAWMOT, Type.ELECTRIC, Type.FIGHTING, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], [ Biome.POWER_PLANT, BiomePoolTier.COMMON ], [ Biome.POWER_PLANT, BiomePoolTier.BOSS ] ] ], [ Species.TANDEMAUS, Type.NORMAL, -1, [ - [ Biome.TOWN, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.METROPOLIS, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.TOWN, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.METROPOLIS, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.MAUSHOLD, Type.NORMAL, -1, [ - [ Biome.METROPOLIS, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.METROPOLIS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.METROPOLIS, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.METROPOLIS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.FIDOUGH, Type.FAIRY, -1, [ @@ -6432,16 +6432,16 @@ export function initBiomes() { ] ], [ Species.SMOLIV, Type.GRASS, Type.NORMAL, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.DOLLIV, Type.GRASS, Type.NORMAL, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ARBOLIVA, Type.GRASS, Type.NORMAL, [ - [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SQUAWKABILLY, Type.NORMAL, Type.FLYING, [ @@ -6539,30 +6539,30 @@ export function initBiomes() { ] ], [ Species.CAPSAKID, Type.GRASS, -1, [ - [ Biome.BADLANDS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.BADLANDS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.SCOVILLAIN, Type.GRASS, Type.FIRE, [ - [ Biome.BADLANDS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.BADLANDS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.BADLANDS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.BADLANDS, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.RELLOR, Type.BUG, -1, [ - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.RABSCA, Type.BUG, Type.PSYCHIC, [ - [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.DESERT, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.DESERT, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.FLITTLE, Type.PSYCHIC, -1, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ESPATHRA, Type.PSYCHIC, -1, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.MOUNTAIN, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.TINKATINK, Type.FAIRY, Type.STEEL, [ @@ -6587,16 +6587,16 @@ export function initBiomes() { ] ], [ Species.BOMBIRDIER, Type.FLYING, Type.DARK, [ - [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.FINIZEN, Type.WATER, -1, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.PALAFIN, Type.WATER, -1, [ - [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SEA, BiomePoolTier.COMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SEA, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.VAROOM, Type.STEEL, Type.POISON, [ @@ -6664,14 +6664,14 @@ export function initBiomes() { ] ], [ Species.ANNIHILAPE, Type.FIGHTING, Type.GHOST, [ - [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], + [ Biome.PLAINS, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], [ Biome.DOJO, BiomePoolTier.COMMON ], [ Biome.DOJO, BiomePoolTier.BOSS ] ] ], [ Species.CLODSIRE, Type.POISON, Type.GROUND, [ - [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SWAMP, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SWAMP, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.FARIGIRAF, Type.NORMAL, Type.PSYCHIC, [ @@ -6867,17 +6867,17 @@ export function initBiomes() { [ Species.PECHARUNT, Type.POISON, Type.GHOST, [ ] ], [ Species.ALOLA_RATTATA, Type.DARK, Type.NORMAL, [ - [ Biome.ISLAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.ISLAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ALOLA_RATICATE, Type.DARK, Type.NORMAL, [ - [ Biome.ISLAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.ISLAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ALOLA_RAICHU, Type.ELECTRIC, Type.PSYCHIC, [ - [ Biome.ISLAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.ISLAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ALOLA_SANDSHREW, Type.ICE, Type.STEEL, [ @@ -6914,12 +6914,12 @@ export function initBiomes() { ] ], [ Species.ALOLA_MEOWTH, Type.DARK, -1, [ - [ Biome.ISLAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.ISLAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ALOLA_PERSIAN, Type.DARK, -1, [ - [ Biome.ISLAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.ISLAND, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ALOLA_GEODUDE, Type.ROCK, Type.ELECTRIC, [ @@ -6945,13 +6945,13 @@ export function initBiomes() { ] ], [ Species.ALOLA_EXEGGUTOR, Type.GRASS, Type.DRAGON, [ - [ Biome.ISLAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.ISLAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.ALOLA_MAROWAK, Type.FIRE, Type.GHOST, [ - [ Biome.ISLAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.ISLAND, BiomePoolTier.UNCOMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.ISLAND, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.ETERNAL_FLOETTE, Type.FAIRY, -1, [ @@ -6973,12 +6973,12 @@ export function initBiomes() { ] ], [ Species.GALAR_SLOWPOKE, Type.PSYCHIC, -1, [ - [ Biome.SWAMP, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SWAMP, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GALAR_SLOWBRO, Type.POISON, Type.PSYCHIC, [ - [ Biome.SWAMP, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SWAMP, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SWAMP, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SWAMP, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GALAR_FARFETCHD, Type.FIGHTING, -1, [ @@ -7009,7 +7009,7 @@ export function initBiomes() { ] ], [ Species.GALAR_SLOWKING, Type.POISON, Type.PSYCHIC, [ - [ Biome.SWAMP, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SWAMP, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GALAR_CORSOLA, Type.GHOST, -1, [ @@ -7017,24 +7017,24 @@ export function initBiomes() { ] ], [ Species.GALAR_ZIGZAGOON, Type.DARK, Type.NORMAL, [ - [ Biome.SLUM, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SLUM, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.GALAR_LINOONE, Type.DARK, Type.NORMAL, [ - [ Biome.SLUM, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SLUM, BiomePoolTier.RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.GALAR_DARUMAKA, Type.ICE, -1, [ - [ Biome.SNOWY_FOREST, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GALAR_DARMANITAN, Type.ICE, -1, [ - [ Biome.SNOWY_FOREST, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.GALAR_YAMASK, Type.GROUND, Type.GHOST, [ - [ Biome.RUINS, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.RUINS, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.GALAR_STUNFISK, Type.GROUND, Type.STEEL, [ @@ -7067,7 +7067,7 @@ export function initBiomes() { ] ], [ Species.HISUI_SNEASEL, Type.FIGHTING, Type.POISON, [ - [ Biome.SNOWY_FOREST, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HISUI_SAMUROTT, Type.WATER, Type.DARK, [ @@ -7075,29 +7075,29 @@ export function initBiomes() { ] ], [ Species.HISUI_LILLIGANT, Type.GRASS, Type.FIGHTING, [ - [ Biome.MEADOW, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MEADOW, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HISUI_ZORUA, Type.NORMAL, Type.GHOST, [ - [ Biome.SNOWY_FOREST, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.HISUI_ZOROARK, Type.NORMAL, Type.GHOST, [ - [ Biome.SNOWY_FOREST, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ], - [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SNOWY_FOREST, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]], + [ Biome.SNOWY_FOREST, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.HISUI_BRAVIARY, Type.PSYCHIC, Type.FLYING, [ - [ Biome.MOUNTAIN, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.MOUNTAIN, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HISUI_SLIGGOO, Type.STEEL, Type.DRAGON, [ - [ Biome.SWAMP, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SWAMP, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HISUI_GOODRA, Type.STEEL, Type.DRAGON, [ - [ Biome.SWAMP, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.SWAMP, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.SWAMP, BiomePoolTier.SUPER_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.SWAMP, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.HISUI_AVALUGG, Type.ICE, Type.ROCK, [ @@ -7109,12 +7109,12 @@ export function initBiomes() { ] ], [ Species.PALDEA_TAUROS, Type.FIGHTING, -1, [ - [ Biome.PLAINS, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ], - [ Biome.PLAINS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ] + [ Biome.PLAINS, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]], + [ Biome.PLAINS, BiomePoolTier.BOSS_RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ]] ] ], [ Species.PALDEA_WOOPER, Type.POISON, Type.GROUND, [ - [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ] + [ Biome.SWAMP, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]] ] ], [ Species.BLOODMOON_URSALUNA, Type.GROUND, Type.NORMAL, [ @@ -7146,7 +7146,7 @@ export function initBiomes() { [ Biome.METROPOLIS, BiomePoolTier.RARE ] ] ], - [ TrainerType.BACKERS, [] ], + [ TrainerType.BACKERS, []], [ TrainerType.BACKPACKER, [ [ Biome.MOUNTAIN, BiomePoolTier.COMMON ], [ Biome.CAVE, BiomePoolTier.COMMON ], @@ -7160,7 +7160,7 @@ export function initBiomes() { ], [ TrainerType.BEAUTY, [ [ Biome.FAIRY_CAVE, BiomePoolTier.COMMON ] - ] ], + ]], [ TrainerType.BIKER, [ [ Biome.SLUM, BiomePoolTier.COMMON ] ] @@ -7190,42 +7190,42 @@ export function initBiomes() { ], [ TrainerType.CLERK, [ [ Biome.METROPOLIS, BiomePoolTier.COMMON ] - ] ], + ]], [ TrainerType.CYCLIST, [ [ Biome.PLAINS, BiomePoolTier.UNCOMMON ], [ Biome.METROPOLIS, BiomePoolTier.COMMON ] ] ], - [ TrainerType.DANCER, [] ], + [ TrainerType.DANCER, []], [ TrainerType.DEPOT_AGENT, [ [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON ] - ] ], - [ TrainerType.DOCTOR, [] ], + ]], + [ TrainerType.DOCTOR, []], [ TrainerType.FISHERMAN, [ [ Biome.LAKE, BiomePoolTier.COMMON ], [ Biome.BEACH, BiomePoolTier.COMMON ] ] ], - [ TrainerType.RICH, [] ], + [ TrainerType.RICH, []], [ TrainerType.GUITARIST, [ [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON ], [ Biome.POWER_PLANT, BiomePoolTier.COMMON ] - ] ], - [ TrainerType.HARLEQUIN, [] ], + ]], + [ TrainerType.HARLEQUIN, []], [ TrainerType.HIKER, [ [ Biome.MOUNTAIN, BiomePoolTier.COMMON ], [ Biome.CAVE, BiomePoolTier.COMMON ], [ Biome.BADLANDS, BiomePoolTier.COMMON ] ] ], - [ TrainerType.HOOLIGANS, [] ], - [ TrainerType.HOOPSTER, [] ], - [ TrainerType.INFIELDER, [] ], - [ TrainerType.JANITOR, [] ], - [ TrainerType.LINEBACKER, [] ], - [ TrainerType.MAID, [] ], - [ TrainerType.MUSICIAN, [] ], - [ TrainerType.NURSERY_AIDE, [] ], + [ TrainerType.HOOLIGANS, []], + [ TrainerType.HOOPSTER, []], + [ TrainerType.INFIELDER, []], + [ TrainerType.JANITOR, []], + [ TrainerType.LINEBACKER, []], + [ TrainerType.MAID, []], + [ TrainerType.MUSICIAN, []], + [ TrainerType.NURSERY_AIDE, []], [ TrainerType.OFFICER, [ [ Biome.METROPOLIS, BiomePoolTier.COMMON ], [ Biome.CONSTRUCTION_SITE, BiomePoolTier.COMMON ], @@ -7237,9 +7237,9 @@ export function initBiomes() { [ Biome.MEADOW, BiomePoolTier.COMMON ] ] ], - [ TrainerType.PILOT, [] ], - [ TrainerType.POKEFAN, [] ], - [ TrainerType.PRESCHOOLER, [] ], + [ TrainerType.PILOT, []], + [ TrainerType.POKEFAN, []], + [ TrainerType.PRESCHOOLER, []], [ TrainerType.PSYCHIC, [ [ Biome.GRAVEYARD, BiomePoolTier.COMMON ], [ Biome.RUINS, BiomePoolTier.COMMON ] @@ -7251,7 +7251,7 @@ export function initBiomes() { [ Biome.JUNGLE, BiomePoolTier.COMMON ] ] ], - [ TrainerType.RICH_KID, [] ], + [ TrainerType.RICH_KID, []], [ TrainerType.ROUGHNECK, [ [ Biome.SLUM, BiomePoolTier.COMMON ] ] @@ -7261,13 +7261,13 @@ export function initBiomes() { [ Biome.RUINS, BiomePoolTier.COMMON ] ] ], - [ TrainerType.SMASHER, [] ], + [ TrainerType.SMASHER, []], [ TrainerType.SNOW_WORKER, [ [ Biome.ICE_CAVE, BiomePoolTier.COMMON ], [ Biome.SNOWY_FOREST, BiomePoolTier.COMMON ] ] ], - [ TrainerType.STRIKER, [] ], + [ TrainerType.STRIKER, []], [ TrainerType.SCHOOL_KID, [ [ Biome.GRASS, BiomePoolTier.COMMON ] ] @@ -7611,57 +7611,57 @@ export function initBiomes() { [ Biome.ICE_CAVE, BiomePoolTier.BOSS ] ] ], - [ TrainerType.LORELEI, [] ], - [ TrainerType.BRUNO, [] ], - [ TrainerType.AGATHA, [] ], - [ TrainerType.LANCE, [] ], - [ TrainerType.WILL, [] ], - [ TrainerType.KOGA, [] ], - [ TrainerType.KAREN, [] ], - [ TrainerType.SIDNEY, [] ], - [ TrainerType.PHOEBE, [] ], - [ TrainerType.GLACIA, [] ], - [ TrainerType.DRAKE, [] ], - [ TrainerType.AARON, [] ], - [ TrainerType.BERTHA, [] ], - [ TrainerType.FLINT, [] ], - [ TrainerType.LUCIAN, [] ], - [ TrainerType.SHAUNTAL, [] ], - [ TrainerType.MARSHAL, [] ], - [ TrainerType.GRIMSLEY, [] ], - [ TrainerType.CAITLIN, [] ], - [ TrainerType.MALVA, [] ], - [ TrainerType.SIEBOLD, [] ], - [ TrainerType.WIKSTROM, [] ], - [ TrainerType.DRASNA, [] ], - [ TrainerType.HALA, [] ], - [ TrainerType.MOLAYNE, [] ], - [ TrainerType.OLIVIA, [] ], - [ TrainerType.ACEROLA, [] ], - [ TrainerType.KAHILI, [] ], - [ TrainerType.RIKA, [] ], - [ TrainerType.POPPY, [] ], - [ TrainerType.LARRY_ELITE, [] ], - [ TrainerType.HASSEL, [] ], - [ TrainerType.CRISPIN, [] ], - [ TrainerType.AMARYS, [] ], - [ TrainerType.LACEY, [] ], - [ TrainerType.DRAYTON, [] ], - [ TrainerType.BLUE, [] ], - [ TrainerType.RED, [] ], - [ TrainerType.LANCE_CHAMPION, [] ], - [ TrainerType.STEVEN, [] ], - [ TrainerType.WALLACE, [] ], - [ TrainerType.CYNTHIA, [] ], - [ TrainerType.ALDER, [] ], - [ TrainerType.IRIS, [] ], - [ TrainerType.DIANTHA, [] ], - [ TrainerType.HAU, [] ], - [ TrainerType.GEETA, [] ], - [ TrainerType.NEMONA, [] ], - [ TrainerType.KIERAN, [] ], - [ TrainerType.LEON, [] ], - [ TrainerType.RIVAL, [] ] + [ TrainerType.LORELEI, []], + [ TrainerType.BRUNO, []], + [ TrainerType.AGATHA, []], + [ TrainerType.LANCE, []], + [ TrainerType.WILL, []], + [ TrainerType.KOGA, []], + [ TrainerType.KAREN, []], + [ TrainerType.SIDNEY, []], + [ TrainerType.PHOEBE, []], + [ TrainerType.GLACIA, []], + [ TrainerType.DRAKE, []], + [ TrainerType.AARON, []], + [ TrainerType.BERTHA, []], + [ TrainerType.FLINT, []], + [ TrainerType.LUCIAN, []], + [ TrainerType.SHAUNTAL, []], + [ TrainerType.MARSHAL, []], + [ TrainerType.GRIMSLEY, []], + [ TrainerType.CAITLIN, []], + [ TrainerType.MALVA, []], + [ TrainerType.SIEBOLD, []], + [ TrainerType.WIKSTROM, []], + [ TrainerType.DRASNA, []], + [ TrainerType.HALA, []], + [ TrainerType.MOLAYNE, []], + [ TrainerType.OLIVIA, []], + [ TrainerType.ACEROLA, []], + [ TrainerType.KAHILI, []], + [ TrainerType.RIKA, []], + [ TrainerType.POPPY, []], + [ TrainerType.LARRY_ELITE, []], + [ TrainerType.HASSEL, []], + [ TrainerType.CRISPIN, []], + [ TrainerType.AMARYS, []], + [ TrainerType.LACEY, []], + [ TrainerType.DRAYTON, []], + [ TrainerType.BLUE, []], + [ TrainerType.RED, []], + [ TrainerType.LANCE_CHAMPION, []], + [ TrainerType.STEVEN, []], + [ TrainerType.WALLACE, []], + [ TrainerType.CYNTHIA, []], + [ TrainerType.ALDER, []], + [ TrainerType.IRIS, []], + [ TrainerType.DIANTHA, []], + [ TrainerType.HAU, []], + [ TrainerType.GEETA, []], + [ TrainerType.NEMONA, []], + [ TrainerType.KIERAN, []], + [ TrainerType.LEON, []], + [ TrainerType.RIVAL, []] ]; biomeDepths[Biome.TOWN] = [ 0, 1 ]; diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index c838f6b2c49..4a6e44e0d51 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -1,7 +1,6 @@ import { Gender } from "#app/data/gender"; import { PokeballType } from "#app/data/pokeball"; import Pokemon from "#app/field/pokemon"; -import { Stat } from "#enums/stat"; import { Type } from "#app/data/type"; import * as Utils from "#app/utils"; import { WeatherType } from "#app/data/weather"; @@ -10,7 +9,7 @@ import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { TimeOfDay } from "#enums/time-of-day"; -import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier } from "#app/modifier/modifier"; +import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier, TempExtraModifierModifier } from "#app/modifier/modifier"; import { SpeciesFormKey } from "#enums/species-form-key"; @@ -271,9 +270,21 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.MAROWAK, 28, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)) ], [Species.TYROGUE]: [ - new SpeciesEvolution(Species.HITMONLEE, 20, null, new SpeciesEvolutionCondition(p => p.stats[Stat.ATK] > p.stats[Stat.DEF])), - new SpeciesEvolution(Species.HITMONCHAN, 20, null, new SpeciesEvolutionCondition(p => p.stats[Stat.ATK] < p.stats[Stat.DEF])), - new SpeciesEvolution(Species.HITMONTOP, 20, null, new SpeciesEvolutionCondition(p => p.stats[Stat.ATK] === p.stats[Stat.DEF])) + /** + * Custom: Evolves into Hitmonlee, Hitmonchan or Hitmontop at level 20 + * if it knows Low Sweep, Mach Punch, or Rapid Spin, respectively. + * If Tyrogue knows multiple of these moves, its evolution is based on + * the first qualifying move in its moveset. + */ + new SpeciesEvolution(Species.HITMONLEE, 20, null, new SpeciesEvolutionCondition(p => + p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.LOW_SWEEP + )), + new SpeciesEvolution(Species.HITMONCHAN, 20, null, new SpeciesEvolutionCondition(p => + p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.MACH_PUNCH + )), + new SpeciesEvolution(Species.HITMONTOP, 20, null, new SpeciesEvolutionCondition(p => + p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.RAPID_SPIN + )), ], [Species.KOFFING]: [ new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), @@ -1652,11 +1663,11 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter + p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier - || m instanceof ExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG), + || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter + p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + p.scene.findModifiers(m => m instanceof MoneyMultiplierModifier - || m instanceof ExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG) + || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG) ] }; diff --git a/src/data/balance/pokemon-level-moves.ts b/src/data/balance/pokemon-level-moves.ts index b5608093df2..71d98fb4fc2 100644 --- a/src/data/balance/pokemon-level-moves.ts +++ b/src/data/balance/pokemon-level-moves.ts @@ -93,6 +93,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.GROWL ], [ 1, Moves.EMBER ], [ 1, Moves.SMOKESCREEN ], + [ 1, Moves.FIRE_SPIN ], // Previous Stage Move [ 12, Moves.DRAGON_BREATH ], [ 19, Moves.FIRE_FANG ], [ 24, Moves.SLASH ], @@ -174,6 +175,9 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.METAPOD]: [ [ EVOLVE_MOVE, Moves.HARDEN ], + [ RELEARN_MOVE, Moves.TACKLE ], // Previous Stage Move + [ RELEARN_MOVE, Moves.STRING_SHOT ], // Previous Stage Move + [ RELEARN_MOVE, Moves.BUG_BITE ], // Previous Stage Move [ 1, Moves.HARDEN ], ], [Species.BUTTERFREE]: [ @@ -203,10 +207,17 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.KAKUNA]: [ [ EVOLVE_MOVE, Moves.HARDEN ], + [ RELEARN_MOVE, Moves.POISON_STING ], // Previous Stage Move + [ RELEARN_MOVE, Moves.STRING_SHOT ], // Previous Stage Move + [ RELEARN_MOVE, Moves.BUG_BITE ], // Previous Stage Move [ 1, Moves.HARDEN ], ], [Species.BEEDRILL]: [ [ EVOLVE_MOVE, Moves.TWINEEDLE ], + [ 1, Moves.POISON_STING ], // Previous Stage Move + [ 1, Moves.STRING_SHOT ], // Previous Stage Move + [ 1, Moves.HARDEN ], // Previous Stage Move + [ 1, Moves.BUG_BITE ], // Previous Stage Move [ 1, Moves.FURY_ATTACK ], [ 11, Moves.FURY_CUTTER ], [ 14, Moves.RAGE ], @@ -454,6 +465,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.POISON_STING ], [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.CRUSH_CLAW ], + [ 1, Moves.AGILITY ], // Previous Stage Move [ 9, Moves.ROLLOUT ], [ 12, Moves.FURY_CUTTER ], [ 15, Moves.RAPID_SPIN ], @@ -961,6 +973,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.SCRATCH ], [ 1, Moves.LEER ], [ 1, Moves.FOCUS_ENERGY ], + [ 1, Moves.COVET ], // Previous Stage Move [ 1, Moves.FLING ], [ 5, Moves.FURY_SWIPES ], [ 8, Moves.LOW_KICK ], @@ -1044,10 +1057,6 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.POLIWRATH]: [ [ EVOLVE_MOVE, Moves.DYNAMIC_PUNCH ], - [ 1, Moves.BUBBLE_BEAM ], - [ 1, Moves.BODY_SLAM ], - [ 1, Moves.HYPNOSIS ], - [ 1, Moves.WATER_SPORT ], [ RELEARN_MOVE, Moves.POUND ], [ RELEARN_MOVE, Moves.DOUBLE_EDGE ], [ RELEARN_MOVE, Moves.WATER_GUN ], @@ -1057,13 +1066,18 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ RELEARN_MOVE, Moves.MUD_SHOT ], [ RELEARN_MOVE, Moves.EARTH_POWER ], [ RELEARN_MOVE, Moves.CIRCLE_THROW ], + [ 1, Moves.BUBBLE_BEAM ], + [ 1, Moves.BODY_SLAM ], + [ 1, Moves.HYPNOSIS ], + [ 1, Moves.WATER_SPORT ], ], [Species.ABRA]: [ [ 1, Moves.TELEPORT ], - [ 1, Moves.CONFUSION ], //Custom + [ 1, Moves.CONFUSION ], // Custom ], [Species.KADABRA]: [ - [ EVOLVE_MOVE, Moves.PSYBEAM ], //LGPE + [ EVOLVE_MOVE, Moves.PSYBEAM ], // LGPE + [ 1, Moves.CONFUSION ], // Previous Stage Move, Custom [ 1, Moves.DISABLE ], [ 1, Moves.TELEPORT ], [ 1, Moves.KINESIS ], @@ -1184,10 +1198,18 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ RELEARN_MOVE, Moves.STOCKPILE ], [ RELEARN_MOVE, Moves.SWALLOW ], [ RELEARN_MOVE, Moves.SPIT_UP ], + [ RELEARN_MOVE, Moves.WRAP ], // Previous Stage Move + [ RELEARN_MOVE, Moves.GROWTH ], // Previous Stage Move + [ RELEARN_MOVE, Moves.ACID ], // Previous Stage Move + [ RELEARN_MOVE, Moves.KNOCK_OFF ], // Previous Stage Move [ RELEARN_MOVE, Moves.GASTRO_ACID ], + [ RELEARN_MOVE, Moves.POISON_JAB ], // Previous Stage Move + [ RELEARN_MOVE, Moves.SLAM ], // Previous Stage Move [ RELEARN_MOVE, Moves.POWER_WHIP ], [ 1, Moves.VINE_WHIP ], [ 1, Moves.SLEEP_POWDER ], + [ 1, Moves.POISON_POWDER ], // Previous Stage Move + [ 1, Moves.STUN_SPORE ], // Previous Stage Move [ 1, Moves.SWEET_SCENT ], [ 1, Moves.RAZOR_LEAF ], [ 44, Moves.LEAF_BLADE ], @@ -1262,6 +1284,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.ROCK_POLISH ], + [ 1, Moves.ROLLOUT ], // Previous Stage Move [ 1, Moves.HEAVY_SLAM ], [ 16, Moves.ROCK_THROW ], [ 18, Moves.SMACK_DOWN ], @@ -1548,7 +1571,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.GASTLY]: [ [ 1, Moves.CONFUSE_RAY ], [ 1, Moves.LICK ], - [ 1, Moves.ACID ], //Custom + [ 1, Moves.ACID ], // Custom [ 4, Moves.HYPNOSIS ], [ 8, Moves.MEAN_LOOK ], [ 12, Moves.PAYBACK ], @@ -1567,6 +1590,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.HYPNOSIS ], [ 1, Moves.CONFUSE_RAY ], [ 1, Moves.LICK ], + [ 1, Moves.ACID ], // Previous Stage Move, Custom [ 1, Moves.MEAN_LOOK ], [ 12, Moves.PAYBACK ], [ 16, Moves.SPITE ], @@ -1583,6 +1607,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.HYPNOSIS ], [ 1, Moves.CONFUSE_RAY ], [ 1, Moves.LICK ], + [ 1, Moves.ACID ], // Previous Stage Move, Custom [ 1, Moves.PERISH_SONG ], [ 1, Moves.MEAN_LOOK ], [ 1, Moves.SHADOW_PUNCH ], @@ -1609,7 +1634,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 12, Moves.DRAGON_BREATH ], [ 16, Moves.CURSE ], [ 20, Moves.ROCK_SLIDE ], - [ 22, Moves.GYRO_BALL ], //Custom, from USUM + [ 22, Moves.GYRO_BALL ], // Custom, from USUM [ 24, Moves.SCREECH ], [ 28, Moves.SAND_TOMB ], [ 32, Moves.STEALTH_ROCK ], @@ -1810,6 +1835,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.LOW_SWEEP ], [ 1, Moves.JUMP_KICK ], [ 1, Moves.ROLLING_KICK ], + [ 1, Moves.MACH_PUNCH ], // Previous Stage Move, Custom + [ 1, Moves.RAPID_SPIN ], // Previous Stage Move, Custom [ 4, Moves.DOUBLE_KICK ], [ 8, Moves.LOW_KICK ], [ 12, Moves.ENDURE ], @@ -1832,6 +1859,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.FEINT ], [ 1, Moves.PURSUIT ], [ 1, Moves.COMET_PUNCH ], + [ 1, Moves.LOW_SWEEP ], // Previous Stage Move, Custom + [ 1, Moves.RAPID_SPIN ], // Previous Stage Move, Custom [ 4, Moves.MACH_PUNCH ], [ 8, Moves.VACUUM_WAVE ], [ 12, Moves.DETECT ], @@ -1849,7 +1878,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.LICKITUNG]: [ [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.LICK ], - [ 1, Moves.TACKLE ], //Custom + [ 1, Moves.TACKLE ], // Custom [ 6, Moves.REST ], [ 12, Moves.SUPERSONIC ], [ 18, Moves.WRAP ], @@ -2090,6 +2119,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.MR_MIME]: [ [ 1, Moves.POUND ], + [ 1, Moves.TICKLE ], // Previous Stage Move [ 1, Moves.BATON_PASS ], [ 1, Moves.ENCORE ], [ 1, Moves.COPYCAT ], @@ -2122,7 +2152,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 20, Moves.DOUBLE_HIT ], [ 24, Moves.SLASH ], [ 28, Moves.FOCUS_ENERGY ], - [ 30, Moves.STEEL_WING ], //Custom + [ 30, Moves.STEEL_WING ], // Custom [ 32, Moves.AGILITY ], [ 36, Moves.AIR_SLASH ], [ 40, Moves.X_SCISSOR ], @@ -2279,6 +2309,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.VAPOREON]: [ [ EVOLVE_MOVE, Moves.BOUNCY_BUBBLE ], + [ RELEARN_MOVE, Moves.VEEVEE_VOLLEY ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAKE_DOWN ], [ 1, Moves.DOUBLE_EDGE ], @@ -2306,6 +2337,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.JOLTEON]: [ [ EVOLVE_MOVE, Moves.BUZZY_BUZZ ], + [ RELEARN_MOVE, Moves.VEEVEE_VOLLEY ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAKE_DOWN ], [ 1, Moves.DOUBLE_EDGE ], @@ -2333,6 +2365,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.FLAREON]: [ [ EVOLVE_MOVE, Moves.SIZZLY_SLIDE ], + [ RELEARN_MOVE, Moves.VEEVEE_VOLLEY ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAKE_DOWN ], [ 1, Moves.DOUBLE_EDGE ], @@ -2463,6 +2496,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SNORLAX]: [ [ 1, Moves.TACKLE ], [ 1, Moves.SCREECH ], + [ 1, Moves.ODOR_SLEUTH ], // Previous Stage Move [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.METRONOME ], [ 1, Moves.LICK ], @@ -2632,7 +2666,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.CHIKORITA]: [ [ 1, Moves.TACKLE ], [ 1, Moves.GROWL ], - [ 5, Moves.RAZOR_LEAF ], //Custom, moved from 6 to 5 + [ 5, Moves.RAZOR_LEAF ], // Custom, moved from 6 to 5 [ 9, Moves.POISON_POWDER ], [ 12, Moves.SYNTHESIS ], [ 17, Moves.REFLECT ], @@ -2682,8 +2716,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.CYNDAQUIL]: [ [ 1, Moves.TACKLE ], [ 1, Moves.LEER ], - [ 5, Moves.EMBER ], //Custom, moved from 10 to 5 - [ 10, Moves.SMOKESCREEN ], //Custom, moved from 6 to 10 + [ 5, Moves.EMBER ], // Custom, moved from 10 to 5 + [ 10, Moves.SMOKESCREEN ], // Custom, moved from 6 to 10 [ 13, Moves.QUICK_ATTACK ], [ 19, Moves.FLAME_WHEEL ], [ 22, Moves.DEFENSE_CURL ], @@ -2737,7 +2771,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.TOTODILE]: [ [ 1, Moves.SCRATCH ], [ 1, Moves.LEER ], - [ 5, Moves.WATER_GUN ], //Custom, moved from 6 to 5 + [ 5, Moves.WATER_GUN ], // Custom, moved from 6 to 5 [ 9, Moves.BITE ], [ 13, Moves.SCARY_FACE ], [ 19, Moves.ICE_FANG ], @@ -3149,6 +3183,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.MOONBLAST ], ], [Species.MARILL]: [ + [ 1, Moves.SPLASH ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAIL_WHIP ], [ 1, Moves.WATER_GUN ], @@ -3168,6 +3203,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 36, Moves.SUPERPOWER ], ], [Species.AZUMARILL]: [ + [ 1, Moves.SPLASH ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAIL_WHIP ], [ 1, Moves.WATER_GUN ], @@ -3189,6 +3225,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SUDOWOODO]: [ [ EVOLVE_MOVE, Moves.SLAM ], [ 1, Moves.ROCK_THROW ], + [ 1, Moves.TACKLE ], // Previous Stage Move, Custom [ 1, Moves.FLAIL ], [ 1, Moves.FAKE_TEARS ], [ 1, Moves.HAMMER_ARM ], @@ -3222,6 +3259,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.HYDRO_PUMP ], [ 1, Moves.BELLY_DRUM ], [ 1, Moves.POUND ], + [ 1, Moves.WATER_SPORT ], // Previous Stage Move ], [Species.HOPPIP]: [ [ 1, Moves.TACKLE ], @@ -3315,9 +3353,12 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 39, Moves.SEED_BOMB ], ], [Species.SUNFLORA]: [ + [ RELEARN_MOVE, Moves.SEED_BOMB ], // Previous Stage Move [ 1, Moves.POUND ], [ 1, Moves.TACKLE ], [ 1, Moves.GROWTH ], + [ 1, Moves.ENDEAVOR ], // Previous Stage Move + [ 1, Moves.SYNTHESIS ], // Previous Stage Move [ 4, Moves.INGRAIN ], [ 7, Moves.ABSORB ], [ 10, Moves.MEGA_DRAIN ], @@ -3382,6 +3423,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.ESPEON]: [ [ EVOLVE_MOVE, Moves.GLITZY_GLOW ], + [ RELEARN_MOVE, Moves.VEEVEE_VOLLEY ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAKE_DOWN ], [ 1, Moves.DOUBLE_EDGE ], @@ -3408,6 +3450,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.UMBREON]: [ [ EVOLVE_MOVE, Moves.BADDY_BAD ], + [ RELEARN_MOVE, Moves.VEEVEE_VOLLEY ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAKE_DOWN ], [ 1, Moves.DOUBLE_EDGE ], @@ -3464,6 +3507,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 15, Moves.DISABLE ], [ 18, Moves.WATER_PULSE ], [ 21, Moves.HEADBUTT ], + [ 24, Moves.ZEN_HEADBUTT ], // Previous Stage Move, Galar Slowking Level [ 27, Moves.AMNESIA ], [ 30, Moves.SURF ], [ 33, Moves.SLACK_OFF ], @@ -3562,7 +3606,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.DUNSPARCE]: [ [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.FLAIL ], - [ 1, Moves.TACKLE ], //Custom + [ 1, Moves.TACKLE ], // Custom [ 4, Moves.MUD_SLAP ], [ 8, Moves.ROLLOUT ], [ 12, Moves.GLARE ], @@ -3609,6 +3653,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 12, Moves.DRAGON_BREATH ], [ 16, Moves.CURSE ], [ 20, Moves.ROCK_SLIDE ], + [ 22, Moves.GYRO_BALL ], // Custom from USUM [ 24, Moves.SCREECH ], [ 28, Moves.SAND_TOMB ], [ 32, Moves.STEALTH_ROCK ], @@ -3688,6 +3733,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 20, Moves.DOUBLE_HIT ], [ 24, Moves.SLASH ], [ 28, Moves.FOCUS_ENERGY ], + [ 30, Moves.STEEL_WING ], // Custom [ 32, Moves.IRON_DEFENSE ], [ 36, Moves.IRON_HEAD ], [ 40, Moves.X_SCISSOR ], @@ -3765,8 +3811,11 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.SCRATCH ], [ 1, Moves.LEER ], [ 1, Moves.LICK ], - [ 1, Moves.FAKE_TEARS ], [ 1, Moves.COVET ], + [ 1, Moves.FLING ], // Previous Stage Move + [ 1, Moves.BABY_DOLL_EYES ], // Previous Stage Move + [ 1, Moves.FAKE_TEARS ], + [ 1, Moves.CHARM ], // Previous Stage Move [ 8, Moves.FURY_SWIPES ], [ 13, Moves.PAYBACK ], [ 17, Moves.SWEET_SCENT ], @@ -3783,7 +3832,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SLUGMA]: [ [ 1, Moves.SMOG ], [ 1, Moves.YAWN ], - [ 5, Moves.EMBER ], //Custom, Moved from Level 6 to 5 + [ 5, Moves.EMBER ], // Custom, Moved from Level 6 to 5 [ 8, Moves.ROCK_THROW ], [ 13, Moves.HARDEN ], [ 20, Moves.CLEAR_SMOG ], @@ -3898,7 +3947,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 48, Moves.SOAK ], [ 54, Moves.HYPER_BEAM ], ], - [Species.DELIBIRD]: [ //Given a custom level up learnset + [Species.DELIBIRD]: [ // Given a custom level up learnset [ 1, Moves.PRESENT ], [ 1, Moves.METRONOME ], [ 5, Moves.FAKE_OUT ], @@ -3991,6 +4040,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 62, Moves.INFERNO ], ], [Species.KINGDRA]: [ + [ RELEARN_MOVE, Moves.LASER_FOCUS ], // Previous Stage Move [ 1, Moves.LEER ], [ 1, Moves.WATER_GUN ], [ 1, Moves.SMOKESCREEN ], @@ -4025,9 +4075,17 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.DONPHAN]: [ [ EVOLVE_MOVE, Moves.FURY_ATTACK ], - [ 1, Moves.HORN_ATTACK ], + [ 1, Moves.TACKLE ], // Previous Stage Move [ 1, Moves.GROWL ], + [ 1, Moves.HORN_ATTACK ], [ 1, Moves.DEFENSE_CURL ], + [ 1, Moves.ODOR_SLEUTH ], // Previous Stage Move + [ 1, Moves.FLAIL ], // Previous Stage Move + [ 1, Moves.ENDURE ], // Previous Stage Move + [ 1, Moves.TAKE_DOWN ], // Previous Stage Move + [ 1, Moves.CHARM ], // Previous Stage Move + [ 1, Moves.LAST_RESORT ], // Previous Stage Move + [ 1, Moves.DOUBLE_EDGE ], // Previous Stage Move [ 1, Moves.THUNDER_FANG ], [ 1, Moves.FIRE_FANG ], [ 1, Moves.BULLDOZE ], @@ -4047,6 +4105,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.CONVERSION ], [ 1, Moves.RECYCLE ], [ 1, Moves.MAGNET_RISE ], + [ 1, Moves.MAGIC_COAT ], // Previous Stage Move [ 15, Moves.THUNDER_SHOCK ], [ 20, Moves.PSYBEAM ], [ 25, Moves.CONVERSION_2 ], @@ -4093,6 +4152,9 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.FOCUS_ENERGY ], [ 1, Moves.FAKE_OUT ], [ 1, Moves.HELPING_HAND ], + [ 10, Moves.LOW_SWEEP ], // Custom + [ 10, Moves.MACH_PUNCH ], // Custom + [ 10, Moves.RAPID_SPIN ], // Custom ], [Species.HITMONTOP]: [ [ EVOLVE_MOVE, Moves.TRIPLE_KICK ], @@ -4104,6 +4166,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.FEINT ], [ 1, Moves.PURSUIT ], [ 1, Moves.ROLLING_KICK ], + [ 1, Moves.LOW_SWEEP ], // Previous Stage Move, Custom + [ 1, Moves.MACH_PUNCH ], // Previous Stage Move, Custom [ 4, Moves.QUICK_ATTACK ], [ 8, Moves.GYRO_BALL ], [ 12, Moves.DETECT ], @@ -4513,6 +4577,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.MARSHTOMP]: [ [ EVOLVE_MOVE, Moves.MUD_SHOT ], + [ RELEARN_MOVE, Moves.SURF ], // Previous Stage Move [ RELEARN_MOVE, Moves.ROCK_SMASH ], [ 1, Moves.TACKLE ], [ 1, Moves.GROWL ], @@ -4634,10 +4699,15 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.SILCOON]: [ [ EVOLVE_MOVE, Moves.HARDEN ], + [ RELEARN_MOVE, Moves.TACKLE ], // Previous Stage Move + [ RELEARN_MOVE, Moves.STRING_SHOT ], // Previous Stage Move + [ RELEARN_MOVE, Moves.POISON_STING ], // Previous Stage Move + [ RELEARN_MOVE, Moves.BUG_BITE ], // Previous Stage Move [ 1, Moves.HARDEN ], ], [Species.BEAUTIFLY]: [ [ EVOLVE_MOVE, Moves.GUST ], + [ 1, Moves.TACKLE ], // Previous Stage Move [ 1, Moves.BUG_BITE ], [ 1, Moves.GUST ], [ 1, Moves.HARDEN ], @@ -4658,10 +4728,15 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.CASCOON]: [ [ EVOLVE_MOVE, Moves.HARDEN ], + [ RELEARN_MOVE, Moves.TACKLE ], // Previous Stage Move + [ RELEARN_MOVE, Moves.STRING_SHOT ], // Previous Stage Move + [ RELEARN_MOVE, Moves.POISON_STING ], // Previous Stage Move + [ RELEARN_MOVE, Moves.BUG_BITE ], // Previous Stage Move [ 1, Moves.HARDEN ], ], [Species.DUSTOX]: [ [ EVOLVE_MOVE, Moves.GUST ], + [ 1, Moves.TACKLE ], // Previous Stage Move [ 1, Moves.BUG_BITE ], [ 1, Moves.GUST ], [ 1, Moves.HARDEN ], @@ -4701,6 +4776,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.ABSORB ], [ 1, Moves.FLAIL ], [ 1, Moves.FAKE_OUT ], + [ 1, Moves.RAIN_DANCE ], // Previous Stage Move [ 1, Moves.KNOCK_OFF ], [ 1, Moves.TEETER_DANCE ], [ 1, Moves.ASTONISH ], @@ -4728,6 +4804,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ RELEARN_MOVE, Moves.ASTONISH ], [ RELEARN_MOVE, Moves.ENERGY_BALL ], [ RELEARN_MOVE, Moves.ZEN_HEADBUTT ], + [ RELEARN_MOVE, Moves.LEECH_SEED ], // Previous Stage Move + [ RELEARN_MOVE, Moves.GIGA_DRAIN ], // Previous Stage Move [ 1, Moves.FAKE_OUT ], [ 1, Moves.BUBBLE_BEAM ], [ 1, Moves.RAIN_DANCE ], @@ -4757,8 +4835,10 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.EXPLOSION ], [ 1, Moves.TACKLE ], [ 1, Moves.HARDEN ], + [ 1, Moves.BIDE ], // Previous Stage Move [ 1, Moves.ABSORB ], [ 1, Moves.ASTONISH ], + [ 1, Moves.HEADBUTT ], // Previous Stage Move [ 9, Moves.GROWTH ], [ 12, Moves.ROLLOUT ], [ 18, Moves.MEGA_DRAIN ], @@ -4773,11 +4853,13 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ EVOLVE_MOVE, Moves.LEAF_BLADE ], [ RELEARN_MOVE, Moves.WHIRLWIND ], [ RELEARN_MOVE, Moves.TACKLE ], + [ RELEARN_MOVE, Moves.BIDE ], // Previous Stage Move [ RELEARN_MOVE, Moves.ABSORB ], [ RELEARN_MOVE, Moves.MEGA_DRAIN ], [ RELEARN_MOVE, Moves.GROWTH ], [ RELEARN_MOVE, Moves.RAZOR_LEAF ], [ RELEARN_MOVE, Moves.HARDEN ], + [ RELEARN_MOVE, Moves.HEADBUTT ], // Previous Stage Move [ RELEARN_MOVE, Moves.EXPLOSION ], [ RELEARN_MOVE, Moves.ROLLOUT ], [ RELEARN_MOVE, Moves.SWAGGER ], @@ -4930,11 +5012,17 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 38, Moves.STICKY_WEB ], ], [Species.MASQUERAIN]: [ + [ RELEARN_MOVE, Moves.BATON_PASS ], // Previous Stage Move + [ RELEARN_MOVE, Moves.STICKY_WEB ], // Previous Stage Move [ 1, Moves.WHIRLWIND ], [ 1, Moves.WATER_GUN ], [ 1, Moves.QUICK_ATTACK ], [ 1, Moves.SWEET_SCENT ], [ 1, Moves.SOAK ], + [ 1, Moves.BUBBLE_BEAM ], // Previous Stage Move + [ 1, Moves.AGILITY ], // Previous Stage Move + [ 1, Moves.MIST ], // Previous Stage Move + [ 1, Moves.HAZE ], // Previous Stage Move [ 1, Moves.OMINOUS_WIND ], [ 17, Moves.GUST ], [ 22, Moves.SCARY_FACE ], @@ -4963,6 +5051,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ EVOLVE_MOVE, Moves.MACH_PUNCH ], [ RELEARN_MOVE, Moves.SPORE ], [ 1, Moves.POISON_POWDER ], + [ 1, Moves.GIGA_DRAIN ], // Previous Stage Move [ 1, Moves.GROWTH ], [ 1, Moves.TOXIC ], [ 1, Moves.ABSORB ], @@ -4994,9 +5083,16 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 38, Moves.PLAY_ROUGH ], ], [Species.VIGOROTH]: [ + [ RELEARN_MOVE, Moves.PLAY_ROUGH ], // Previous Stage Move [ 1, Moves.SCRATCH ], + [ 1, Moves.YAWN ], // Previous Stage Move [ 1, Moves.FOCUS_ENERGY ], + [ 1, Moves.SLACK_OFF ], // Previous Stage Move [ 1, Moves.ENCORE ], + [ 1, Moves.HEADBUTT ], // Previous Stage Move + [ 1, Moves.AMNESIA ], // Previous Stage Move + [ 1, Moves.COVET ], // Previous Stage Move + [ 1, Moves.FLAIL ], // Previous Stage Move [ 1, Moves.UPROAR ], [ 14, Moves.FURY_SWIPES ], [ 17, Moves.ENDURE ], @@ -5008,11 +5104,20 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.SLAKING]: [ [ EVOLVE_MOVE, Moves.SWAGGER ], + [ RELEARN_MOVE, Moves.PLAY_ROUGH ], // Previous Stage Move + [ RELEARN_MOVE, Moves.FOCUS_PUNCH ], // Previous Stage Move [ 1, Moves.SUCKER_PUNCH ], [ 1, Moves.SCRATCH ], [ 1, Moves.YAWN ], + [ 1, Moves.FOCUS_ENERGY ], // Previous Stage Move [ 1, Moves.ENCORE ], [ 1, Moves.SLACK_OFF ], + [ 1, Moves.UPROAR ], // Previous Stage Move + [ 1, Moves.FURY_SWIPES ], // Previous Stage Move + [ 1, Moves.ENDURE ], // Previous Stage Move + [ 1, Moves.HEADBUTT ], // Previous Stage Move + [ 1, Moves.SLASH ], // Previous Stage Move + [ 1, Moves.REVERSAL ], // Previous Stage Move [ 17, Moves.AMNESIA ], [ 23, Moves.COVET ], [ 27, Moves.THROAT_CHOP ], @@ -5148,6 +5253,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.BRINE ], [ 1, Moves.TACKLE ], [ 1, Moves.FOCUS_ENERGY ], + [ 1, Moves.SAND_ATTACK ], // Previous Stage Move [ 1, Moves.ARM_THRUST ], [ 10, Moves.FAKE_OUT ], [ 13, Moves.FORCE_PALM ], @@ -5351,6 +5457,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.DETECT ], [ 1, Moves.WORK_UP ], [ 1, Moves.BIDE ], + [ 1, Moves.REVERSAL ], // Previous Stage Move [ 12, Moves.ENDURE ], [ 15, Moves.FEINT ], [ 17, Moves.FORCE_PALM ], @@ -5520,6 +5627,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.POISON_GAS ], [ 1, Moves.WRING_OUT ], [ 1, Moves.SLUDGE ], + [ 1, Moves.PAIN_SPLIT ], // Previous Stage Move [ 12, Moves.AMNESIA ], [ 17, Moves.ACID_SPRAY ], [ 20, Moves.ENCORE ], @@ -5565,7 +5673,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.WAILMER]: [ [ 1, Moves.SPLASH ], - [ 1, Moves.TACKLE ], //Custom + [ 1, Moves.TACKLE ], // Custom [ 3, Moves.GROWL ], [ 6, Moves.ASTONISH ], [ 12, Moves.WATER_GUN ], @@ -5586,6 +5694,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.SOAK ], [ 1, Moves.NOBLE_ROAR ], [ 1, Moves.SPLASH ], + [ 1, Moves.TACKLE ], // Previous Stage Move, Custom [ 1, Moves.GROWL ], [ 1, Moves.ASTONISH ], [ 1, Moves.WATER_GUN ], @@ -5620,6 +5729,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.CAMERUPT]: [ [ EVOLVE_MOVE, Moves.ROCK_SLIDE ], + [ RELEARN_MOVE, Moves.FLAMETHROWER ], // Previous Stage Move + [ RELEARN_MOVE, Moves.DOUBLE_EDGE ], // Previous Stage Move [ 1, Moves.FISSURE ], [ 1, Moves.ERUPTION ], [ 1, Moves.GROWL ], @@ -5658,7 +5769,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.SPOINK]: [ [ 1, Moves.SPLASH ], - [ 5, Moves.CONFUSION ], //Custom, Moved from Level 7 to 5 + [ 5, Moves.CONFUSION ], // Custom, Moved from Level 7 to 5 [ 10, Moves.GROWL ], [ 14, Moves.PSYBEAM ], [ 18, Moves.PSYCH_UP ], @@ -5676,6 +5787,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.BELCH ], [ 1, Moves.SPLASH ], [ 1, Moves.CONFUSION ], + [ 1, Moves.GROWL ], // Previous Stage Move [ 1, Moves.PSYBEAM ], [ 18, Moves.PSYCH_UP ], [ 22, Moves.CONFUSE_RAY ], @@ -6167,7 +6279,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.SHUPPET]: [ [ 1, Moves.ASTONISH ], - [ 1, Moves.PURSUIT ], //Custom + [ 1, Moves.PURSUIT ], // Custom [ 4, Moves.SCREECH ], [ 7, Moves.NIGHT_SHADE ], [ 10, Moves.SPITE ], @@ -6183,6 +6295,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.BANETTE]: [ [ EVOLVE_MOVE, Moves.KNOCK_OFF ], + [ 1, Moves.ASTONISH ], // Previous Stage Move + [ 1, Moves.PURSUIT ], // Previous Stage Move, Custom [ 1, Moves.SCREECH ], [ 1, Moves.NIGHT_SHADE ], [ 1, Moves.SPITE ], @@ -6199,7 +6313,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.DUSKULL]: [ [ 1, Moves.ASTONISH ], [ 1, Moves.LEER ], - [ 1, Moves.PURSUIT ], //Custom + [ 1, Moves.PURSUIT ], // Custom [ 4, Moves.DISABLE ], [ 8, Moves.SHADOW_SNEAK ], [ 12, Moves.CONFUSE_RAY ], @@ -6221,6 +6335,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.BIND ], [ 1, Moves.ASTONISH ], [ 1, Moves.LEER ], + [ 1, Moves.PURSUIT ], // Previous Stage Move, Custom [ 1, Moves.DISABLE ], [ 1, Moves.SHADOW_SNEAK ], [ 12, Moves.CONFUSE_RAY ], @@ -6252,7 +6367,10 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.CHIMECHO]: [ [ 1, Moves.HEALING_WISH ], + [ 1, Moves.LAST_RESORT ], // Previous Stage Move + [ 1, Moves.ENTRAINMENT ], // Previous Stage Move [ 1, Moves.WRAP ], + [ 1, Moves.PSYWAVE ], // Previous Stage Move, Custom [ 1, Moves.GROWL ], [ 1, Moves.ASTONISH ], [ 1, Moves.CONFUSION ], @@ -6392,6 +6510,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 50, Moves.SHELL_SMASH ], ], [Species.HUNTAIL]: [ + [ 1, Moves.CLAMP ], // Previous Stage Move [ 1, Moves.WATER_GUN ], [ 1, Moves.IRON_DEFENSE ], [ 1, Moves.SHELL_SMASH ], @@ -6412,6 +6531,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 50, Moves.HYDRO_PUMP ], ], [Species.GOREBYSS]: [ + [ 1, Moves.CLAMP ], // Previous Stage Move [ 1, Moves.WATER_GUN ], [ 1, Moves.IRON_DEFENSE ], [ 1, Moves.SHELL_SMASH ], @@ -6497,6 +6617,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.SALAMENCE]: [ [ EVOLVE_MOVE, Moves.FLY ], + [ RELEARN_MOVE, Moves.OUTRAGE ], // Previous Stage Move [ 1, Moves.PROTECT ], [ 1, Moves.DRAGON_TAIL ], [ 1, Moves.DUAL_WINGBEAT ], @@ -6712,7 +6833,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 98, Moves.DOOM_DESIRE ], ], [Species.DEOXYS]: [ - [ 1, Moves.CONFUSION ], //Custom + [ 1, Moves.CONFUSION ], // Custom [ 1, Moves.LEER ], [ 1, Moves.WRAP ], [ 7, Moves.NIGHT_SHADE ], @@ -6731,8 +6852,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.TURTWIG]: [ [ 1, Moves.TACKLE ], [ 5, Moves.WITHDRAW ], - [ 5, Moves.LEAFAGE ], //Custom, moved from 10 to 5, BDSP - [ 9, Moves.GROWTH ], //Fill empty moveslot, from BDSP level 6 + [ 5, Moves.LEAFAGE ], // Custom, moved from 10 to 5, BDSP + [ 9, Moves.GROWTH ], // Fill empty moveslot, from BDSP level 6 [ 13, Moves.RAZOR_LEAF ], [ 17, Moves.CURSE ], [ 21, Moves.BITE ], @@ -6748,6 +6869,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.ABSORB ], [ 1, Moves.WITHDRAW ], [ 1, Moves.LEAFAGE ], + [ 1, Moves.GROWTH ], // Previous Stage Move [ 13, Moves.RAZOR_LEAF ], [ 17, Moves.CURSE ], [ 22, Moves.BITE ], @@ -6763,6 +6885,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.ABSORB ], [ 1, Moves.LEAFAGE ], + [ 1, Moves.GROWTH ], // Previous Stage Move [ 1, Moves.RAZOR_LEAF ], [ 1, Moves.WITHDRAW ], [ 1, Moves.WOOD_HAMMER ], @@ -6779,7 +6902,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.CHIMCHAR]: [ [ 1, Moves.SCRATCH ], [ 1, Moves.LEER ], - [ 5, Moves.EMBER ], //Custom, moved from 7 to 5 + [ 5, Moves.EMBER ], // Custom, moved from 7 to 5 [ 9, Moves.TAUNT ], [ 15, Moves.FURY_SWIPES ], [ 17, Moves.FLAME_WHEEL ], @@ -6793,6 +6916,9 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.MONFERNO]: [ [ EVOLVE_MOVE, Moves.MACH_PUNCH ], + [ RELEARN_MOVE, Moves.NASTY_PLOT ], // Previous Stage Move + [ RELEARN_MOVE, Moves.FACADE ], // Previous Stage Move + [ RELEARN_MOVE, Moves.FLAMETHROWER ], // Previous Stage Move [ 1, Moves.SCRATCH ], [ 1, Moves.LEER ], [ 1, Moves.EMBER ], @@ -6810,7 +6936,10 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.INFERNAPE]: [ [ EVOLVE_MOVE, Moves.CLOSE_COMBAT ], [ RELEARN_MOVE, Moves.TAUNT ], + [ RELEARN_MOVE, Moves.NASTY_PLOT ], // Previous Stage Move + [ RELEARN_MOVE, Moves.FACADE ], // Previous Stage Move [ RELEARN_MOVE, Moves.SLACK_OFF ], + [ RELEARN_MOVE, Moves.FLAMETHROWER ], // Previous Stage Move [ 1, Moves.SCRATCH ], [ 1, Moves.LEER ], [ 1, Moves.EMBER ], @@ -6828,7 +6957,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.PIPLUP]: [ [ 1, Moves.POUND ], [ 4, Moves.GROWL ], - [ 5, Moves.WATER_GUN ], //Custom, moved from 8 to 5 + [ 5, Moves.WATER_GUN ], // Custom, moved from 8 to 5 [ 11, Moves.CHARM ], [ 15, Moves.PECK ], [ 18, Moves.BUBBLE_BEAM ], @@ -6845,6 +6974,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.GROWL ], [ 1, Moves.WATER_GUN ], + [ 1, Moves.CHARM ], // Previous Stage Move [ 15, Moves.PECK ], [ 19, Moves.BUBBLE_BEAM ], [ 24, Moves.SWAGGER ], @@ -6860,6 +6990,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.GROWL ], [ 1, Moves.WATER_GUN ], + [ 1, Moves.CHARM ], // Previous Stage Move [ 1, Moves.METAL_CLAW ], [ 11, Moves.SWORDS_DANCE ], [ 15, Moves.PECK ], @@ -6963,6 +7094,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.GROWL ], [ 1, Moves.BIDE ], + [ 1, Moves.STRUGGLE_BUG ], // Previous Stage Move + [ 1, Moves.BUG_BITE ], // Previous Stage Move [ 14, Moves.ABSORB ], [ 18, Moves.SING ], [ 22, Moves.FOCUS_ENERGY ], @@ -7113,13 +7246,14 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.BURMY]: [ [ 1, Moves.PROTECT ], - [ 1, Moves.STRUGGLE_BUG ], //Custom + [ 1, Moves.STRUGGLE_BUG ], // Custom [ 10, Moves.TACKLE ], [ 15, Moves.BUG_BITE ], [ 20, Moves.STRING_SHOT ], ], [Species.WORMADAM]: [ [ EVOLVE_MOVE, Moves.QUIVER_DANCE ], + [ 1, Moves.STRUGGLE_BUG ], // Previous Stage Move, Custom [ 1, Moves.TACKLE ], [ 1, Moves.PROTECT ], [ 1, Moves.SUCKER_PUNCH ], @@ -7140,6 +7274,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.MOTHIM]: [ [ EVOLVE_MOVE, Moves.QUIVER_DANCE ], + [ 1, Moves.STRUGGLE_BUG ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.PROTECT ], [ 1, Moves.BUG_BITE ], @@ -7221,6 +7356,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 49, Moves.WAVE_CRASH ], ], [Species.FLOATZEL]: [ + [ 1, Moves.TACKLE ], // Previous Stage Move [ 1, Moves.GROWL ], [ 1, Moves.QUICK_ATTACK ], [ 1, Moves.CRUNCH ], @@ -7368,6 +7504,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.LOPUNNY]: [ [ EVOLVE_MOVE, Moves.RETURN ], + [ 1, Moves.FRUSTRATION ], // Previous Stage Move [ 1, Moves.POUND ], [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.SPLASH ], @@ -7389,6 +7526,16 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 56, Moves.HIGH_JUMP_KICK ], ], [Species.MISMAGIUS]: [ + // Previous Stage Relearn Learnset + [ RELEARN_MOVE, Moves.CONFUSION ], + [ RELEARN_MOVE, Moves.CONFUSE_RAY ], + [ RELEARN_MOVE, Moves.MEAN_LOOK ], + [ RELEARN_MOVE, Moves.HEX ], + [ RELEARN_MOVE, Moves.PSYBEAM ], + [ RELEARN_MOVE, Moves.PAIN_SPLIT ], + [ RELEARN_MOVE, Moves.PAYBACK ], + [ RELEARN_MOVE, Moves.SHADOW_BALL ], + [ RELEARN_MOVE, Moves.PERISH_SONG ], [ 1, Moves.GROWL ], [ 1, Moves.SPITE ], [ 1, Moves.PSYWAVE ], @@ -7400,11 +7547,18 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.MYSTICAL_FIRE ], ], [Species.HONCHKROW]: [ - [ 1, Moves.WING_ATTACK ], - [ 1, Moves.HAZE ], + [ 1, Moves.PECK ], // Previous Stage Move [ 1, Moves.ASTONISH ], + [ 1, Moves.GUST ], // Previous Stage Move + [ 1, Moves.HAZE ], + [ 1, Moves.WING_ATTACK ], + [ 1, Moves.NIGHT_SHADE ], // Previous Stage Move + [ 1, Moves.ASSURANCE ], // Previous Stage Move + [ 1, Moves.TAUNT ], // Previous Stage Move + [ 1, Moves.MEAN_LOOK ], // Previous Stage Move [ 1, Moves.SUCKER_PUNCH ], [ 1, Moves.NIGHT_SLASH ], + [ 1, Moves.TORMENT ], // Previous Stage Move [ 1, Moves.QUASH ], [ 1, Moves.PURSUIT ], [ 25, Moves.SWAGGER ], @@ -7449,7 +7603,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.CHINGLING]: [ [ 1, Moves.WRAP ], - [ 1, Moves.PSYWAVE ], //Custom + [ 1, Moves.PSYWAVE ], // Custom [ 4, Moves.GROWL ], [ 7, Moves.ASTONISH ], [ 10, Moves.CONFUSION ], @@ -7482,6 +7636,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.SMOKESCREEN ], [ 1, Moves.POISON_GAS ], [ 1, Moves.FEINT ], + [ 1, Moves.ACID_SPRAY ], // Previous Stage Move [ 12, Moves.FURY_SWIPES ], [ 15, Moves.FOCUS_ENERGY ], [ 18, Moves.BITE ], @@ -7533,7 +7688,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.BONSLY]: [ [ 1, Moves.FAKE_TEARS ], [ 1, Moves.COPYCAT ], - [ 1, Moves.TACKLE ], //Custom + [ 1, Moves.TACKLE ], // Custom [ 4, Moves.FLAIL ], [ 8, Moves.ROCK_THROW ], [ 12, Moves.BLOCK ], @@ -7554,11 +7709,11 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 4, Moves.BATON_PASS ], [ 8, Moves.ENCORE ], [ 12, Moves.CONFUSION ], - [ 16, Moves.MIMIC ], //Custom, swapped with Role Play to be closer to USUM + [ 16, Moves.MIMIC ], // Custom, swapped with Role Play to be closer to USUM [ 20, Moves.PROTECT ], [ 24, Moves.RECYCLE ], [ 28, Moves.PSYBEAM ], - [ 32, Moves.ROLE_PLAY ], //Custom, swapped with Mimic + [ 32, Moves.ROLE_PLAY ], // Custom, swapped with Mimic [ 36, Moves.LIGHT_SCREEN ], [ 36, Moves.REFLECT ], [ 36, Moves.SAFEGUARD ], @@ -7696,6 +7851,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.LUCARIO]: [ [ EVOLVE_MOVE, Moves.AURA_SPHERE ], [ 1, Moves.QUICK_ATTACK ], + [ 1, Moves.ENDURE ], // Previous Stage Move [ 1, Moves.SCREECH ], [ 1, Moves.REVERSAL ], [ 1, Moves.DETECT ], @@ -7836,7 +7992,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.CARNIVINE]: [ [ 1, Moves.BIND ], [ 1, Moves.GROWTH ], - [ 1, Moves.LEAFAGE ], //Custom + [ 1, Moves.LEAFAGE ], // Custom [ 7, Moves.BITE ], [ 11, Moves.VINE_WHIP ], [ 17, Moves.SWEET_SCENT ], @@ -7973,6 +8129,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.SUPERSONIC ], [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.LICK ], + [ 1, Moves.TACKLE ], // Previous Stage Move, Custom [ 1, Moves.ROLLOUT ], [ 1, Moves.WRING_OUT ], [ 6, Moves.REST ], @@ -8086,7 +8243,9 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ RELEARN_MOVE, Moves.HYPNOSIS ], [ 1, Moves.TACKLE ], [ 1, Moves.DOUBLE_TEAM ], + [ 1, Moves.AIR_CUTTER ], // Previous Stage Move [ 1, Moves.NIGHT_SLASH ], + [ 1, Moves.WING_ATTACK ], // Previous Stage Move [ 1, Moves.AIR_SLASH ], [ 1, Moves.BUG_BUZZ ], [ 14, Moves.QUICK_ATTACK ], @@ -8102,6 +8261,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.LEAFEON]: [ [ EVOLVE_MOVE, Moves.SAPPY_SEED ], + [ RELEARN_MOVE, Moves.VEEVEE_VOLLEY ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAKE_DOWN ], [ 1, Moves.DOUBLE_EDGE ], @@ -8129,6 +8289,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.GLACEON]: [ [ EVOLVE_MOVE, Moves.FREEZY_FROST ], + [ RELEARN_MOVE, Moves.VEEVEE_VOLLEY ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAKE_DOWN ], [ 1, Moves.DOUBLE_EDGE ], @@ -8154,8 +8315,11 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 60, Moves.LAST_RESORT ], ], [Species.GLISCOR]: [ + [ 1, Moves.POISON_STING ], // Previous Stage Move [ 1, Moves.SAND_ATTACK ], [ 1, Moves.HARDEN ], + [ 1, Moves.POISON_TAIL ], // Previous Stage Move + [ 1, Moves.SLASH ], // Previous Stage Move [ 1, Moves.POISON_JAB ], [ 1, Moves.THUNDER_FANG ], [ 1, Moves.ICE_FANG ], @@ -8248,8 +8412,10 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.PROBOPASS]: [ [ EVOLVE_MOVE, Moves.TRI_ATTACK ], [ 1, Moves.TACKLE ], + [ 1, Moves.HARDEN ], // Previous Stage Move [ 1, Moves.IRON_DEFENSE ], [ 1, Moves.BLOCK ], + [ 1, Moves.ROCK_THROW ], // Previous Stage Move [ 1, Moves.GRAVITY ], [ 1, Moves.MAGNET_RISE ], [ 1, Moves.WIDE_GUARD ], @@ -8275,6 +8441,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.LEER ], [ 1, Moves.DISABLE ], [ 1, Moves.ASTONISH ], + [ 1, Moves.PURSUIT ], // Previous Stage Move, Custom [ 1, Moves.SHADOW_PUNCH ], [ 1, Moves.GRAVITY ], [ 1, Moves.SHADOW_SNEAK ], @@ -8298,6 +8465,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.POWDER_SNOW ], [ 1, Moves.PROTECT ], [ 1, Moves.DESTINY_BOND ], + [ 1, Moves.WEATHER_BALL ], // Previous Stage Move [ 1, Moves.CRUNCH ], [ 1, Moves.ASTONISH ], [ 1, Moves.ICE_FANG ], @@ -8538,7 +8706,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.DARKRAI]: [ [ 1, Moves.DISABLE ], [ 1, Moves.OMINOUS_WIND ], - [ 1, Moves.PURSUIT ], //Custom + [ 1, Moves.PURSUIT ], // Custom [ 11, Moves.QUICK_ATTACK ], [ 20, Moves.HYPNOSIS ], [ 29, Moves.SUCKER_PUNCH ], @@ -8551,7 +8719,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 93, Moves.DARK_PULSE ], ], [Species.SHAYMIN]: [ - [ 1, Moves.LEAFAGE ], //Custom + [ 1, Moves.LEAFAGE ], // Custom [ 1, Moves.GROWTH ], [ 10, Moves.MAGICAL_LEAF ], [ 19, Moves.LEECH_SEED ], @@ -8603,7 +8771,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SNIVY]: [ [ 1, Moves.TACKLE ], [ 4, Moves.LEER ], - [ 5, Moves.VINE_WHIP ], //Custom, moved from 7 to 5 + [ 5, Moves.VINE_WHIP ], // Custom, moved from 7 to 5 [ 10, Moves.WRAP ], [ 13, Moves.GROWTH ], [ 16, Moves.MAGICAL_LEAF ], @@ -8651,7 +8819,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.TEPIG]: [ [ 1, Moves.TACKLE ], [ 3, Moves.TAIL_WHIP ], - [ 5, Moves.EMBER ], //Custom, moved from 7 to 5 + [ 5, Moves.EMBER ], // Custom, moved from 7 to 5 [ 9, Moves.ENDURE ], [ 13, Moves.DEFENSE_CURL ], [ 15, Moves.FLAME_CHARGE ], @@ -8705,7 +8873,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.OSHAWOTT]: [ [ 1, Moves.TACKLE ], [ 5, Moves.TAIL_WHIP ], - [ 5, Moves.WATER_GUN ], //Custom, moved from 7 to 5 + [ 5, Moves.WATER_GUN ], // Custom, moved from 7 to 5 [ 11, Moves.SOAK ], [ 13, Moves.FOCUS_ENERGY ], [ 17, Moves.RAZOR_SHELL ], @@ -8776,6 +8944,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.WATCHOG]: [ [ EVOLVE_MOVE, Moves.CONFUSE_RAY ], + [ RELEARN_MOVE, Moves.WORK_UP ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.LEER ], [ 1, Moves.BITE ], @@ -8895,6 +9064,19 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 43, Moves.CRUNCH ], ], [Species.SIMISAGE]: [ + // Previous Stage Relearn Learnset + [ RELEARN_MOVE, Moves.SCRATCH ], + [ RELEARN_MOVE, Moves.PLAY_NICE ], + [ RELEARN_MOVE, Moves.VINE_WHIP ], + [ RELEARN_MOVE, Moves.LEECH_SEED ], + [ RELEARN_MOVE, Moves.BITE ], + [ RELEARN_MOVE, Moves.TORMENT ], + [ RELEARN_MOVE, Moves.FLING ], + [ RELEARN_MOVE, Moves.ACROBATICS ], + [ RELEARN_MOVE, Moves.GRASS_KNOT ], + [ RELEARN_MOVE, Moves.RECYCLE ], + [ RELEARN_MOVE, Moves.NATURAL_GIFT ], + [ RELEARN_MOVE, Moves.CRUNCH ], [ 1, Moves.LEER ], [ 1, Moves.LICK ], [ 1, Moves.FURY_SWIPES ], @@ -8919,6 +9101,19 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 43, Moves.CRUNCH ], ], [Species.SIMISEAR]: [ + // Previous Stage Relearn Learnset + [ RELEARN_MOVE, Moves.SCRATCH ], + [ RELEARN_MOVE, Moves.PLAY_NICE ], + [ RELEARN_MOVE, Moves.INCINERATE ], + [ RELEARN_MOVE, Moves.YAWN ], + [ RELEARN_MOVE, Moves.BITE ], + [ RELEARN_MOVE, Moves.AMNESIA ], + [ RELEARN_MOVE, Moves.FLING ], + [ RELEARN_MOVE, Moves.ACROBATICS ], + [ RELEARN_MOVE, Moves.FIRE_BLAST ], + [ RELEARN_MOVE, Moves.RECYCLE ], + [ RELEARN_MOVE, Moves.NATURAL_GIFT ], + [ RELEARN_MOVE, Moves.CRUNCH ], [ 1, Moves.LEER ], [ 1, Moves.LICK ], [ 1, Moves.FURY_SWIPES ], @@ -8943,6 +9138,19 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 43, Moves.CRUNCH ], ], [Species.SIMIPOUR]: [ + // Previous Stage Relearn Learnset + [ RELEARN_MOVE, Moves.SCRATCH ], + [ RELEARN_MOVE, Moves.PLAY_NICE ], + [ RELEARN_MOVE, Moves.WATER_GUN ], + [ RELEARN_MOVE, Moves.WATER_SPORT ], + [ RELEARN_MOVE, Moves.BITE ], + [ RELEARN_MOVE, Moves.TAUNT ], + [ RELEARN_MOVE, Moves.FLING ], + [ RELEARN_MOVE, Moves.ACROBATICS ], + [ RELEARN_MOVE, Moves.BRINE ], + [ RELEARN_MOVE, Moves.RECYCLE ], + [ RELEARN_MOVE, Moves.NATURAL_GIFT ], + [ RELEARN_MOVE, Moves.CRUNCH ], [ 1, Moves.LEER ], [ 1, Moves.LICK ], [ 1, Moves.FURY_SWIPES ], @@ -8967,6 +9175,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 52, Moves.WONDER_ROOM ], ], [Species.MUSHARNA]: [ + [ 1, Moves.PSYWAVE ], // Previous Stage Move [ 1, Moves.PSYBEAM ], [ 1, Moves.PSYCHIC ], [ 1, Moves.HYPNOSIS ], @@ -9295,7 +9504,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 70, Moves.HYDRO_PUMP ], ], [Species.THROH]: [ - [ 1, Moves.ROCK_SMASH ], //Custom + [ 1, Moves.ROCK_SMASH ], // Custom [ 1, Moves.LEER ], [ 1, Moves.BIDE ], [ 1, Moves.MAT_BLOCK ], @@ -9355,9 +9564,15 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.LEAVANNY]: [ [ EVOLVE_MOVE, Moves.SLASH ], [ RELEARN_MOVE, Moves.BUG_BITE ], + [ RELEARN_MOVE, Moves.STICKY_WEB ], // Previous Stage Move + [ RELEARN_MOVE, Moves.BUG_BUZZ ], // Previous Stage Move + [ 1, Moves.PROTECT ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.RAZOR_LEAF ], [ 1, Moves.STRING_SHOT ], + [ 1, Moves.GRASS_WHISTLE ], // Previous Stage Move + [ 1, Moves.ENDURE ], // Previous Stage Move + [ 1, Moves.FLAIL ], // Previous Stage Move [ 1, Moves.FALSE_SWIPE ], [ 22, Moves.STRUGGLE_BUG ], [ 29, Moves.FELL_STINGER ], @@ -9890,6 +10105,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TORMENT ], [ 1, Moves.U_TURN ], [ 1, Moves.HONE_CLAWS ], + [ 1, Moves.SCARY_FACE ], // Previous Stage Move [ 1, Moves.PURSUIT ], [ 12, Moves.FURY_SWIPES ], [ 20, Moves.TAUNT ], @@ -9964,6 +10180,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 28, Moves.FAKE_TEARS ], [ 34, Moves.HEAL_BLOCK ], [ 35, Moves.PSYCH_UP ], + [ 40, Moves.PSYCHIC ], // Previous Stage Move, Gothitelle Level [ 46, Moves.FLATTER ], [ 52, Moves.FUTURE_SIGHT ], [ 58, Moves.MAGIC_ROOM ], @@ -10081,7 +10298,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.VANILLITE]: [ [ 1, Moves.HARDEN ], [ 1, Moves.ASTONISH ], - [ 1, Moves.POWDER_SNOW ], //Custom + [ 1, Moves.POWDER_SNOW ], // Custom [ 4, Moves.TAUNT ], [ 8, Moves.MIST ], [ 12, Moves.ICY_WIND ], @@ -10100,6 +10317,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.HARDEN ], [ 1, Moves.TAUNT ], [ 1, Moves.ASTONISH ], + [ 1, Moves.POWDER_SNOW ], // Previous Stage Move, Custom [ 12, Moves.ICY_WIND ], [ 16, Moves.AVALANCHE ], [ 20, Moves.HAIL ], @@ -10116,6 +10334,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.HARDEN ], [ 1, Moves.TAUNT ], [ 1, Moves.ASTONISH ], + [ 1, Moves.POWDER_SNOW ], // Previous Stage Move, Custom [ 1, Moves.WEATHER_BALL ], [ 1, Moves.ICICLE_CRASH ], [ 1, Moves.FREEZE_DRY ], @@ -10428,6 +10647,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.EELEKTRIK]: [ [ EVOLVE_MOVE, Moves.CRUNCH ], + [ 1, Moves.TACKLE ], // Previous Stage Move [ 1, Moves.HEADBUTT ], [ 1, Moves.THUNDER_WAVE ], [ 1, Moves.SPARK ], @@ -10445,7 +10665,15 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 74, Moves.THRASH ], ], [Species.EELEKTROSS]: [ + [ RELEARN_MOVE, Moves.THUNDERBOLT ], // Previous Stage Move + [ RELEARN_MOVE, Moves.ACID_SPRAY ], // Previous Stage Move + [ 1, Moves.TACKLE ], // Previous Stage Move [ 1, Moves.HEADBUTT ], + [ 1, Moves.THUNDER_WAVE ], // Previous Stage Move + [ 1, Moves.SPARK ], // Previous Stage Move + [ 1, Moves.CHARGE_BEAM ], // Previous Stage Move + [ 1, Moves.ION_DELUGE ], // Previous Stage Move + [ 1, Moves.BIND ], // Previous Stage Move [ 1, Moves.THRASH ], [ 1, Moves.ACID ], [ 1, Moves.ZAP_CANNON ], @@ -10688,6 +10916,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.BODY_SLAM ], [ 1, Moves.ACID ], [ 1, Moves.ABSORB ], + [ 1, Moves.PROTECT ], // Previous Stage Move [ 1, Moves.QUICK_ATTACK ], [ 1, Moves.DOUBLE_TEAM ], [ 1, Moves.ACID_ARMOR ], @@ -10881,6 +11110,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.BRAVIARY]: [ [ EVOLVE_MOVE, Moves.SUPERPOWER ], + [ RELEARN_MOVE, Moves.BRAVE_BIRD ], // Previous Stage Move [ 1, Moves.WING_ATTACK ], [ 1, Moves.LEER ], [ 1, Moves.PECK ], @@ -11422,6 +11652,10 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.GROWL ], [ 1, Moves.WATER_GUN ], [ 1, Moves.QUICK_ATTACK ], + [ 1, Moves.ROUND ], // Previous Stage Move + [ 1, Moves.FLING ], // Previous Stage Move + [ 1, Moves.SMACK_DOWN ], // Previous Stage Move + [ 1, Moves.BOUNCE ], // Previous Stage Move [ 1, Moves.HAZE ], [ 1, Moves.MAT_BLOCK ], [ 1, Moves.ROLE_PLAY ], @@ -11529,10 +11763,19 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.SPEWPA]: [ [ EVOLVE_MOVE, Moves.PROTECT ], + [ RELEARN_MOVE, Moves.TACKLE ], // Previous Stage Move + [ RELEARN_MOVE, Moves.STRING_SHOT ], // Previous Stage Move + [ RELEARN_MOVE, Moves.STUN_SPORE ], // Previous Stage Move + [ RELEARN_MOVE, Moves.BUG_BITE ], // Previous Stage Move [ 1, Moves.HARDEN ], ], [Species.VIVILLON]: [ [ EVOLVE_MOVE, Moves.GUST ], + [ 1, Moves.PROTECT ], // Previous Stage Move + [ 1, Moves.TACKLE ], // Previous Stage Move + [ 1, Moves.STRING_SHOT ], // Previous Stage Move + [ 1, Moves.HARDEN ], // Previous Stage Move + [ 1, Moves.BUG_BITE ], // Previous Stage Move [ 1, Moves.POISON_POWDER ], [ 1, Moves.STUN_SPORE ], [ 1, Moves.SLEEP_POWDER ], @@ -11615,6 +11858,10 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 58, Moves.SOLAR_BEAM ], ], [Species.FLORGES]: [ + [ 1, Moves.VINE_WHIP ], // Previous Stage Move + [ 1, Moves.TACKLE ], // Previous Stage Move + [ 1, Moves.FAIRY_WIND ], // Previous Stage Move + [ 1, Moves.RAZOR_LEAF ], // Previous Stage Move [ 1, Moves.SOLAR_BEAM ], [ 1, Moves.PETAL_DANCE ], [ 1, Moves.SAFEGUARD ], @@ -12106,6 +12353,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.SYLVEON]: [ [ EVOLVE_MOVE, Moves.SPARKLY_SWIRL ], + [ RELEARN_MOVE, Moves.VEEVEE_VOLLEY ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.TAKE_DOWN ], [ 1, Moves.DOUBLE_EDGE ], @@ -12216,6 +12464,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.WATER_GUN ], [ 1, Moves.ABSORB ], + [ 1, Moves.ACID_ARMOR ], // Previous Stage Move [ 1, Moves.DRAGON_BREATH ], [ 1, Moves.POISON_TAIL ], [ 1, Moves.FEINT ], @@ -12225,6 +12474,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 20, Moves.FLAIL ], [ 25, Moves.WATER_PULSE ], [ 30, Moves.RAIN_DANCE ], + [ 35, Moves.DRAGON_PULSE ], // Previous Stage Move, NatDex / Hisui Goodra Level [ 43, Moves.CURSE ], [ 49, Moves.BODY_SLAM ], [ 58, Moves.MUDDY_WATER ], @@ -12285,7 +12535,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.PUMPKABOO]: [ [ 1, Moves.ASTONISH ], [ 1, Moves.TRICK_OR_TREAT ], - [ 1, Moves.LEAFAGE ], //Custom + [ 1, Moves.LEAFAGE ], // Custom [ 4, Moves.SHADOW_SNEAK ], [ 8, Moves.CONFUSE_RAY ], [ 12, Moves.RAZOR_LEAF ], @@ -12302,6 +12552,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.CONFUSE_RAY ], [ 1, Moves.EXPLOSION ], [ 1, Moves.ASTONISH ], + [ 1, Moves.LEAFAGE ], // Previous Stage Move, Custom [ 1, Moves.SHADOW_SNEAK ], [ 1, Moves.TRICK_OR_TREAT ], [ 1, Moves.MOONBLAST ], @@ -12813,11 +13064,14 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.CRABOMINABLE]: [ [ EVOLVE_MOVE, Moves.ICE_PUNCH ], + [ RELEARN_MOVE, Moves.CRABHAMMER ], // Previous Stage Move + [ 1, Moves.VISE_GRIP ], // Previous Stage Move [ 1, Moves.LEER ], [ 1, Moves.PROTECT ], [ 1, Moves.ROCK_SMASH ], [ 1, Moves.BUBBLE ], [ 1, Moves.PURSUIT ], + [ 1, Moves.PAYBACK ], // Previous Stage Move [ 17, Moves.BUBBLE_BEAM ], [ 22, Moves.BRICK_BREAK ], [ 25, Moves.SLAM ], @@ -13006,6 +13260,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.BUG_BITE ], [ 1, Moves.WIDE_GUARD ], [ 1, Moves.INFESTATION ], + [ 1, Moves.WATER_SPORT ], // Previous Stage Move [ 1, Moves.SPIDER_WEB ], [ 12, Moves.BUBBLE_BEAM ], [ 16, Moves.AQUA_RING ], @@ -13154,7 +13409,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.BOUNSWEET]: [ [ 1, Moves.SPLASH ], - [ 1, Moves.LEAFAGE ], //Custom + [ 1, Moves.LEAFAGE ], // Custom [ 4, Moves.PLAY_NICE ], [ 8, Moves.RAPID_SPIN ], [ 12, Moves.RAZOR_LEAF ], @@ -13165,6 +13420,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 32, Moves.AROMATIC_MIST ], ], [Species.STEENEE]: [ + [ 1, Moves.LEAFAGE ], // Previous Stage Move, Custom [ 1, Moves.RAZOR_LEAF ], [ 1, Moves.SPLASH ], [ 1, Moves.FLAIL ], @@ -13179,6 +13435,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.TSAREENA]: [ [ EVOLVE_MOVE, Moves.TROP_KICK ], + [ 1, Moves.LEAFAGE ], // Previous Stage Move, Custom [ 1, Moves.RAZOR_LEAF ], [ 1, Moves.SPLASH ], [ 1, Moves.FLAIL ], @@ -13303,7 +13560,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 68, Moves.SANDSTORM ], ], [Species.PYUKUMUKU]: [ - [ 1, Moves.COUNTER ], //Custom, Moved from Level 20 to 1 + [ 1, Moves.COUNTER ], // Custom, Moved from Level 20 to 1 [ 1, Moves.HARDEN ], [ 1, Moves.BATON_PASS ], [ 1, Moves.BIDE ], @@ -13312,7 +13569,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 5, Moves.HELPING_HAND ], [ 10, Moves.TAUNT ], [ 15, Moves.SAFEGUARD ], - [ 20, Moves.MIRROR_COAT ], //Custom + [ 20, Moves.MIRROR_COAT ], // Custom [ 25, Moves.PURIFY ], [ 30, Moves.CURSE ], [ 35, Moves.GASTRO_ACID ], @@ -13629,15 +13886,19 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.COSMOG]: [ [ 1, Moves.TELEPORT ], [ 1, Moves.SPLASH ], - [ 1, Moves.STORED_POWER ], //Custom + [ 1, Moves.STORED_POWER ], // Custom ], [Species.COSMOEM]: [ [ EVOLVE_MOVE, Moves.COSMIC_POWER ], [ 1, Moves.TELEPORT ], + [ 1, Moves.SPLASH ], // Previous Stage Move + [ 1, Moves.STORED_POWER ], // Previous Stage Move, Custom ], [Species.SOLGALEO]: [ [ EVOLVE_MOVE, Moves.SUNSTEEL_STRIKE ], [ 1, Moves.TELEPORT ], + [ 1, Moves.SPLASH ], // Previous Stage Move + [ 1, Moves.STORED_POWER ], // Previous Stage Move, Custom [ 1, Moves.METAL_CLAW ], [ 1, Moves.COSMIC_POWER ], [ 1, Moves.NOBLE_ROAR ], @@ -13660,6 +13921,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.CONFUSION ], [ 1, Moves.HYPNOSIS ], [ 1, Moves.TELEPORT ], + [ 1, Moves.SPLASH ], // Previous Stage Move + [ 1, Moves.STORED_POWER ], // Previous Stage Move, Custom [ 1, Moves.COSMIC_POWER ], [ 7, Moves.NIGHT_SHADE ], [ 14, Moves.CONFUSE_RAY ], @@ -13826,7 +14089,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.MAGEARNA]: [ [ 1, Moves.HELPING_HAND ], [ 1, Moves.GYRO_BALL ], - [ 1, Moves.DISARMING_VOICE ], //Custom + [ 1, Moves.DISARMING_VOICE ], // Custom [ 1, Moves.CRAFTY_SHIELD ], [ 1, Moves.GEAR_UP ], [ 6, Moves.DEFENSE_CURL ], @@ -13867,7 +14130,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 99, Moves.CLOSE_COMBAT ], ], [Species.POIPOLE]: [ - [ RELEARN_MOVE, Moves.DRAGON_PULSE ], //Custom, made relearn + [ RELEARN_MOVE, Moves.DRAGON_PULSE ], // Custom, made relearn [ 1, Moves.GROWL ], [ 1, Moves.ACID ], [ 1, Moves.PECK ], @@ -13986,7 +14249,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.GROOKEY]: [ [ 1, Moves.SCRATCH ], [ 1, Moves.GROWL ], - [ 5, Moves.BRANCH_POKE ], //Custom, moved from 6 to 5 + [ 5, Moves.BRANCH_POKE ], // Custom, moved from 6 to 5 [ 8, Moves.TAUNT ], [ 12, Moves.RAZOR_LEAF ], [ 17, Moves.SCREECH ], @@ -14031,7 +14294,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SCORBUNNY]: [ [ 1, Moves.TACKLE ], [ 1, Moves.GROWL ], - [ 5, Moves.EMBER ], //Custom, moved from 6 to 5 + [ 5, Moves.EMBER ], // Custom, moved from 6 to 5 [ 8, Moves.QUICK_ATTACK ], [ 12, Moves.DOUBLE_KICK ], [ 17, Moves.FLAME_CHARGE ], @@ -14073,7 +14336,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SOBBLE]: [ [ 1, Moves.POUND ], [ 1, Moves.GROWL ], - [ 5, Moves.WATER_GUN ], //Custom, moved from 6 to 5 + [ 5, Moves.WATER_GUN ], // Custom, moved from 6 to 5 [ 8, Moves.BIND ], [ 12, Moves.WATER_PULSE ], [ 17, Moves.TEARFUL_LOOK ], @@ -14400,10 +14663,11 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.APPLIN]: [ [ 1, Moves.WITHDRAW ], [ 1, Moves.ASTONISH ], - [ 1, Moves.LEAFAGE ], //Custom + [ 1, Moves.LEAFAGE ], // Custom ], [Species.FLAPPLE]: [ [ EVOLVE_MOVE, Moves.WING_ATTACK ], + [ 1, Moves.LEAFAGE ], // Previous Stage Move, Custom [ 1, Moves.GROWTH ], [ 1, Moves.WITHDRAW ], [ 1, Moves.TWISTER ], @@ -14423,6 +14687,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.APPLETUN]: [ [ EVOLVE_MOVE, Moves.HEADBUTT ], + [ 1, Moves.LEAFAGE ], // Previous Stage Move, Custom [ 1, Moves.GROWTH ], [ 1, Moves.WITHDRAW ], [ 1, Moves.SWEET_SCENT ], @@ -14443,7 +14708,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SILICOBRA]: [ [ 1, Moves.SAND_ATTACK ], [ 1, Moves.WRAP ], - [ 1, Moves.MUD_SLAP ], //Custom + [ 1, Moves.MUD_SLAP ], // Custom [ 5, Moves.MINIMIZE ], [ 10, Moves.BRUTAL_SWING ], [ 15, Moves.BULLDOZE ], @@ -14458,6 +14723,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SANDACONDA]: [ [ 1, Moves.SAND_ATTACK ], [ 1, Moves.WRAP ], + [ 1, Moves.MUD_SLAP ], // Previous Stage Move, Custom [ 1, Moves.MINIMIZE ], [ 1, Moves.BRUTAL_SWING ], [ 15, Moves.BULLDOZE ], @@ -14605,7 +14871,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.SINISTEA]: [ [ 1, Moves.WITHDRAW ], [ 1, Moves.ASTONISH ], - [ 1, Moves.ABSORB ], //Custom + [ 1, Moves.ABSORB ], // Custom [ 6, Moves.AROMATIC_MIST ], [ 12, Moves.MEGA_DRAIN ], [ 24, Moves.SUCKER_PUNCH ], @@ -14618,6 +14884,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.POLTEAGEIST]: [ [ EVOLVE_MOVE, Moves.TEATIME ], + [ 1, Moves.ABSORB ], // Previous Stage Move, Custom [ 1, Moves.MEGA_DRAIN ], [ 1, Moves.WITHDRAW ], [ 1, Moves.ASTONISH ], @@ -14805,6 +15072,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.MR_RIME]: [ [ 1, Moves.POUND ], + [ 1, Moves.BARRIER ], // Previous Stage Move + [ 1, Moves.TICKLE ], // Previous Stage Move [ 1, Moves.MIMIC ], [ 1, Moves.LIGHT_SCREEN ], [ 1, Moves.REFLECT ], @@ -15133,6 +15402,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.DRAGAPULT]: [ [ EVOLVE_MOVE, Moves.DRAGON_DARTS ], + [ RELEARN_MOVE, Moves.DRAGON_PULSE ], // Previous Stage Move [ 1, Moves.BITE ], [ 1, Moves.QUICK_ATTACK ], [ 1, Moves.DRAGON_BREATH ], @@ -15339,6 +15609,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.WYRDEER]: [ [ EVOLVE_MOVE, Moves.PSYSHIELD_BASH ], [ 1, Moves.TACKLE ], + [ 1, Moves.ME_FIRST ], // Previous Stage Move [ 3, Moves.LEER ], [ 7, Moves.ASTONISH ], [ 10, Moves.HYPNOSIS ], @@ -15355,6 +15626,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.KLEAVOR]: [ [ EVOLVE_MOVE, Moves.STONE_AXE ], + [ 1, Moves.WING_ATTACK ], // Previous Stage Move + [ 1, Moves.AIR_SLASH ], // Previous Stage Move [ 1, Moves.LEER ], [ 1, Moves.QUICK_ATTACK ], [ 4, Moves.FURY_CUTTER ], @@ -15364,6 +15637,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 20, Moves.DOUBLE_HIT ], [ 24, Moves.SLASH ], [ 28, Moves.FOCUS_ENERGY ], + [ 30, Moves.STEEL_WING ], // Custom [ 32, Moves.AGILITY ], [ 36, Moves.ROCK_SLIDE ], [ 40, Moves.X_SCISSOR ], @@ -15374,8 +15648,11 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.SCRATCH ], [ 1, Moves.LEER ], [ 1, Moves.LICK ], - [ 1, Moves.FAKE_TEARS ], [ 1, Moves.COVET ], + [ 1, Moves.FLING ], // Previous Stage Move + [ 1, Moves.BABY_DOLL_EYES ], // Previous Stage Move + [ 1, Moves.FAKE_TEARS ], + [ 1, Moves.CHARM ], // Previous Stage Moves [ 8, Moves.FURY_SWIPES ], [ 13, Moves.PAYBACK ], [ 17, Moves.SWEET_SCENT ], @@ -15390,6 +15667,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 64, Moves.HAMMER_ARM ], ], [Species.BASCULEGION]: [ + [ RELEARN_MOVE, Moves.FINAL_GAMBIT ], // Previous Stage Move, White Stripe currently shares moveset with other forms [ 1, Moves.TAIL_WHIP ], [ 1, Moves.WATER_GUN ], [ 1, Moves.SHADOW_BALL ], @@ -15949,10 +16227,12 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.GARGANACL]: [ [ EVOLVE_MOVE, Moves.HAMMER_ARM ], + [ RELEARN_MOVE, Moves.IRON_DEFENSE ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.HARDEN ], [ 1, Moves.BLOCK ], [ 1, Moves.ROCK_BLAST ], + [ 1, Moves.SMACK_DOWN ], // Previous Stage Move [ 1, Moves.WIDE_GUARD ], [ 5, Moves.ROCK_THROW ], [ 7, Moves.MUD_SHOT ], @@ -16140,6 +16420,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ EVOLVE_MOVE, Moves.DOODLE ], [ 1, Moves.SCRATCH ], [ 1, Moves.LEER ], + [ 1, Moves.BITE ], // Previous Stage Move [ 5, Moves.ACID_SPRAY ], [ 8, Moves.FURY_SWIPES ], [ 11, Moves.SWITCHEROO ], @@ -16294,6 +16575,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.CONFUSION ], [ 1, Moves.DEFENSE_CURL ], + [ 1, Moves.MUD_SHOT ], // Previous Stage Move + [ 1, Moves.DIG ], // Previous Stage Move [ 4, Moves.SAND_ATTACK ], [ 7, Moves.STRUGGLE_BUG ], [ 11, Moves.ROLLOUT ], @@ -16717,6 +17000,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.LEER ], [ 1, Moves.COUNTER ], [ 1, Moves.FOCUS_ENERGY ], + [ 1, Moves.COVET ], // Previous Stage Move [ 1, Moves.FLING ], [ 5, Moves.FURY_SWIPES ], [ 8, Moves.LOW_KICK ], @@ -16734,6 +17018,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.CLODSIRE]: [ [ EVOLVE_MOVE, Moves.AMNESIA ], + [ 1, Moves.TACKLE ], // Previous Stage Move [ 1, Moves.TAIL_WHIP ], [ 1, Moves.POISON_STING ], [ 4, Moves.TOXIC_SPIKES ], @@ -16768,6 +17053,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.DUDUNSPARCE]: [ [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.FLAIL ], + [ 1, Moves.TACKLE ], // Previous Stage Move, Custom [ 4, Moves.MUD_SLAP ], [ 8, Moves.ROLLOUT ], [ 12, Moves.GLARE ], @@ -16864,7 +17150,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.CONFUSE_RAY ], [ 1, Moves.SPITE ], [ 1, Moves.ASTONISH ], - [ 1, Moves.PSYBEAM ], //Custom, moved from 7 to 1 + [ 1, Moves.PSYBEAM ], // Custom, moved from 7 to 1 [ 14, Moves.MEAN_LOOK ], [ 21, Moves.MEMENTO ], [ 28, Moves.WISH ], @@ -16939,7 +17225,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.IRON_BUNDLE]: [ [ RELEARN_MOVE, Moves.ELECTRIC_TERRAIN ], [ 1, Moves.PRESENT ], - [ 1, Moves.WATER_GUN ], //Custom + [ 1, Moves.WATER_GUN ], // Custom [ 7, Moves.POWDER_SNOW ], [ 14, Moves.WHIRLPOOL ], [ 21, Moves.TAKE_DOWN ], @@ -17058,6 +17344,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 18, Moves.FOCUS_ENERGY ], [ 24, Moves.BITE ], [ 29, Moves.ICE_FANG ], + [ 32, Moves.DRAGON_CLAW ], // Previous Stage Move, Frigibax Level [ 40, Moves.TAKE_DOWN ], [ 45, Moves.ICE_BEAM ], [ 50, Moves.CRUNCH ], @@ -17305,6 +17592,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [Species.DIPPLIN]: [ [ EVOLVE_MOVE, Moves.DOUBLE_HIT ], [ RELEARN_MOVE, Moves.DRAGON_CHEER ], // Custom + [ 1, Moves.LEAFAGE ], [ 1, Moves.WITHDRAW ], [ 1, Moves.SWEET_SCENT ], [ 1, Moves.RECYCLE ], @@ -17324,7 +17612,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.STUN_SPORE ], [ 1, Moves.WITHDRAW ], [ 1, Moves.ASTONISH ], - [ 5, Moves.ABSORB ], //Custom, Moved from Level 6 to 5 + [ 5, Moves.ABSORB ], // Custom, Moved from Level 6 to 5 [ 12, Moves.LIFE_DEW ], [ 18, Moves.FOUL_PLAY ], [ 24, Moves.MEGA_DRAIN ], @@ -17337,6 +17625,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.SINISTCHA]: [ [ EVOLVE_MOVE, Moves.MATCHA_GOTCHA ], + [ RELEARN_MOVE, Moves.GIGA_DRAIN ], // Previous Stage Move [ 1, Moves.STUN_SPORE ], [ 1, Moves.WITHDRAW ], [ 1, Moves.ASTONISH ], @@ -17419,6 +17708,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.ARCHALUDON]: [ [ EVOLVE_MOVE, Moves.ELECTRO_SHOT ], + [ RELEARN_MOVE, Moves.LASER_FOCUS ], // Previous Stage Move [ 1, Moves.LEER ], [ 1, Moves.METAL_CLAW ], [ 6, Moves.ROCK_SMASH ], @@ -17438,6 +17728,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ RELEARN_MOVE, Moves.YAWN ], [ RELEARN_MOVE, Moves.DOUBLE_HIT ], [ RELEARN_MOVE, Moves.INFESTATION ], + [ RELEARN_MOVE, Moves.DRAGON_CHEER ], // Previous Stage Move, Custom + [ 1, Moves.LEAFAGE ], // Previous Stage Move, Custom [ 1, Moves.WITHDRAW ], [ 1, Moves.SWEET_SCENT ], [ 1, Moves.RECYCLE ], @@ -17809,6 +18101,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.DEFENSE_CURL ], [ 1, Moves.CHARGE ], [ 1, Moves.ROCK_POLISH ], + [ 1, Moves.ROLLOUT ], // Previous Stage Move [ 1, Moves.HEAVY_SLAM ], [ 12, Moves.SPARK ], [ 16, Moves.ROCK_THROW ], @@ -18051,6 +18344,8 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.GALAR_MR_MIME]: [ [ 1, Moves.POUND ], + [ 1, Moves.BARRIER ], // Previous Stage Move + [ 1, Moves.TICKLE ], // Previous Stage Move [ 1, Moves.MIMIC ], [ 1, Moves.LIGHT_SCREEN ], [ 1, Moves.REFLECT ], @@ -18411,6 +18706,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.TAIL_WHIP ], [ 1, Moves.WATER_GUN ], + [ 1, Moves.SOAK ], // Previous Stage Move [ 1, Moves.SLASH ], [ 1, Moves.MEGAHORN ], [ 1, Moves.SUCKER_PUNCH ], @@ -18436,6 +18732,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.STUN_SPORE ], [ 1, Moves.SLEEP_POWDER ], [ 1, Moves.GIGA_DRAIN ], + [ 1, Moves.CHARM ], // Previous Stage Move [ 1, Moves.SYNTHESIS ], [ 1, Moves.SUNNY_DAY ], [ 1, Moves.HELPING_HAND ], @@ -18487,6 +18784,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.HISUI_BRAVIARY]: [ [ EVOLVE_MOVE, Moves.ESPER_WING ], + [ RELEARN_MOVE, Moves.BRAVE_BIRD ], // Previous Stage Move [ 1, Moves.WING_ATTACK ], [ 1, Moves.LEER ], [ 1, Moves.PECK ], @@ -18511,6 +18809,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.ABSORB ], [ 1, Moves.ACID_ARMOR ], [ 1, Moves.DRAGON_BREATH ], + [ 1, Moves.BODY_SLAM ], // Previous Stage Move [ 15, Moves.PROTECT ], [ 20, Moves.FLAIL ], [ 25, Moves.WATER_PULSE ], @@ -18525,6 +18824,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { [ 1, Moves.TACKLE ], [ 1, Moves.WATER_GUN ], [ 1, Moves.ABSORB ], + [ 1, Moves.ACID_ARMOR ], // Previous Stage Move [ 1, Moves.DRAGON_BREATH ], [ 1, Moves.FEINT ], [ 1, Moves.ACID_SPRAY ], @@ -18565,9 +18865,11 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.HISUI_DECIDUEYE]: [ [ EVOLVE_MOVE, Moves.TRIPLE_ARROWS ], + [ RELEARN_MOVE, Moves.NASTY_PLOT ], // Previous Stage Move [ 1, Moves.TACKLE ], [ 1, Moves.GROWL ], [ 1, Moves.U_TURN ], + [ 1, Moves.ASTONISH ], // Previous Stage Move [ 1, Moves.LEAF_STORM ], [ 1, Moves.LEAFAGE ], [ 9, Moves.PECK ], @@ -18633,7 +18935,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { }; export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { - [Species.PIKACHU]: { //Custom + [Species.PIKACHU]: { // Custom 1: [ [ 1, Moves.TAIL_WHIP ], [ 1, Moves.GROWL ], @@ -18648,14 +18950,14 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 8, Moves.DOUBLE_TEAM ], [ 12, Moves.ELECTRO_BALL ], [ 16, Moves.FEINT ], - [ 20, Moves.ZIPPY_ZAP ], //Custom + [ 20, Moves.ZIPPY_ZAP ], // Custom [ 24, Moves.AGILITY ], [ 28, Moves.IRON_TAIL ], [ 32, Moves.DISCHARGE ], - [ 34, Moves.FLOATY_FALL ], //Custom + [ 34, Moves.FLOATY_FALL ], // Custom [ 36, Moves.THUNDERBOLT ], [ 40, Moves.LIGHT_SCREEN ], - [ 42, Moves.SPLISHY_SPLASH ], //Custom + [ 42, Moves.SPLISHY_SPLASH ], // Custom [ 44, Moves.THUNDER ], [ 48, Moves.PIKA_PAPOW ], ], @@ -18816,19 +19118,19 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 8, Moves.DOUBLE_TEAM ], [ 12, Moves.ELECTRO_BALL ], [ 16, Moves.FEINT ], - [ 20, Moves.ZIPPY_ZAP ], //Custom + [ 20, Moves.ZIPPY_ZAP ], // Custom [ 24, Moves.AGILITY ], [ 28, Moves.IRON_TAIL ], [ 32, Moves.DISCHARGE ], - [ 34, Moves.FLOATY_FALL ], //Custom + [ 34, Moves.FLOATY_FALL ], // Custom [ 36, Moves.THUNDERBOLT ], [ 40, Moves.LIGHT_SCREEN ], - [ 42, Moves.SPLISHY_SPLASH ], //Custom + [ 42, Moves.SPLISHY_SPLASH ], // Custom [ 44, Moves.THUNDER ], [ 48, Moves.PIKA_PAPOW ], ], }, - [Species.EEVEE]: { //Custom + [Species.EEVEE]: { // Custom 1: [ [ 1, Moves.TACKLE ], [ 1, Moves.TAIL_WHIP ], @@ -18838,21 +19140,21 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 5, Moves.SAND_ATTACK ], [ 10, Moves.QUICK_ATTACK ], [ 15, Moves.BABY_DOLL_EYES ], - [ 18, Moves.BOUNCY_BUBBLE ], //Custom - [ 18, Moves.SIZZLY_SLIDE ], //Custom - [ 18, Moves.BUZZY_BUZZ ], //Custom + [ 18, Moves.BOUNCY_BUBBLE ], // Custom + [ 18, Moves.SIZZLY_SLIDE ], // Custom + [ 18, Moves.BUZZY_BUZZ ], // Custom [ 20, Moves.SWIFT ], [ 25, Moves.BITE ], [ 30, Moves.COPYCAT ], - [ 33, Moves.BADDY_BAD ], //Custom - [ 33, Moves.GLITZY_GLOW ], //Custom + [ 33, Moves.BADDY_BAD ], // Custom + [ 33, Moves.GLITZY_GLOW ], // Custom [ 35, Moves.BATON_PASS ], - [ 40, Moves.VEEVEE_VOLLEY ], //Custom, replaces Take Down - [ 43, Moves.FREEZY_FROST ], //Custom - [ 43, Moves.SAPPY_SEED ], //Custom + [ 40, Moves.VEEVEE_VOLLEY ], // Custom, replaces Take Down + [ 43, Moves.FREEZY_FROST ], // Custom + [ 43, Moves.SAPPY_SEED ], // Custom [ 45, Moves.CHARM ], [ 50, Moves.DOUBLE_EDGE ], - [ 53, Moves.SPARKLY_SWIRL ], //Custom + [ 53, Moves.SPARKLY_SWIRL ], // Custom [ 55, Moves.LAST_RESORT ], ], 2: [ @@ -18864,27 +19166,27 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 5, Moves.SAND_ATTACK ], [ 10, Moves.QUICK_ATTACK ], [ 15, Moves.BABY_DOLL_EYES ], - [ 18, Moves.BOUNCY_BUBBLE ], //Custom - [ 18, Moves.SIZZLY_SLIDE ], //Custom - [ 18, Moves.BUZZY_BUZZ ], //Custom + [ 18, Moves.BOUNCY_BUBBLE ], // Custom + [ 18, Moves.SIZZLY_SLIDE ], // Custom + [ 18, Moves.BUZZY_BUZZ ], // Custom [ 20, Moves.SWIFT ], [ 25, Moves.BITE ], [ 30, Moves.COPYCAT ], - [ 33, Moves.BADDY_BAD ], //Custom - [ 33, Moves.GLITZY_GLOW ], //Custom + [ 33, Moves.BADDY_BAD ], // Custom + [ 33, Moves.GLITZY_GLOW ], // Custom [ 35, Moves.BATON_PASS ], - [ 40, Moves.VEEVEE_VOLLEY ], //Custom, replaces Take Down - [ 43, Moves.FREEZY_FROST ], //Custom - [ 43, Moves.SAPPY_SEED ], //Custom + [ 40, Moves.VEEVEE_VOLLEY ], // Custom, replaces Take Down + [ 43, Moves.FREEZY_FROST ], // Custom + [ 43, Moves.SAPPY_SEED ], // Custom [ 45, Moves.CHARM ], [ 50, Moves.DOUBLE_EDGE ], - [ 53, Moves.SPARKLY_SWIRL ], //Custom + [ 53, Moves.SPARKLY_SWIRL ], // Custom [ 55, Moves.LAST_RESORT ], ], }, [Species.DEOXYS]: { 1: [ - [ 1, Moves.CONFUSION ], //Custom + [ 1, Moves.CONFUSION ], // Custom [ 1, Moves.WRAP ], [ 1, Moves.LEER ], [ 7, Moves.NIGHT_SHADE ], @@ -18901,7 +19203,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 73, Moves.HYPER_BEAM ], ], 2: [ - [ 1, Moves.CONFUSION ], //Custom + [ 1, Moves.CONFUSION ], // Custom [ 1, Moves.WRAP ], [ 1, Moves.LEER ], [ 7, Moves.NIGHT_SHADE ], @@ -18920,7 +19222,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 73, Moves.MIRROR_COAT ], ], 3: [ - [ 1, Moves.CONFUSION ], //Custom + [ 1, Moves.CONFUSION ], // Custom [ 1, Moves.WRAP ], [ 1, Moves.LEER ], [ 7, Moves.NIGHT_SHADE ], @@ -18940,6 +19242,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [Species.WORMADAM]: { 1: [ [ EVOLVE_MOVE, Moves.QUIVER_DANCE ], + [ 1, Moves.STRUGGLE_BUG ], // Previous Stage Move, Custom [ 1, Moves.TACKLE ], [ 1, Moves.PROTECT ], [ 1, Moves.SUCKER_PUNCH ], @@ -18960,6 +19263,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { ], 2: [ [ EVOLVE_MOVE, Moves.QUIVER_DANCE ], + [ 1, Moves.STRUGGLE_BUG ], // Previous Stage Move, Custom [ 1, Moves.METAL_BURST ], [ 1, Moves.TACKLE ], [ 1, Moves.PROTECT ], @@ -19064,7 +19368,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { }, [Species.SHAYMIN]: { 1: [ - [ 1, Moves.LEAFAGE ], //Custom + [ 1, Moves.LEAFAGE ], // Custom [ 1, Moves.GROWTH ], [ 10, Moves.MAGICAL_LEAF ], [ 19, Moves.LEECH_SEED ], @@ -19166,6 +19470,10 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 1, Moves.GROWL ], [ 1, Moves.WATER_GUN ], [ 1, Moves.QUICK_ATTACK ], + [ 1, Moves.ROUND ], // Previous Stage Move + [ 1, Moves.FLING ], // Previous Stage Move + [ 1, Moves.SMACK_DOWN ], // Previous Stage Move + [ 1, Moves.BOUNCE ], // Previous Stage Move [ 1, Moves.HAZE ], [ 1, Moves.ROLE_PLAY ], [ 1, Moves.NIGHT_SLASH ], diff --git a/src/data/balance/species-egg-tiers.ts b/src/data/balance/species-egg-tiers.ts new file mode 100644 index 00000000000..27baa18151a --- /dev/null +++ b/src/data/balance/species-egg-tiers.ts @@ -0,0 +1,603 @@ +import { Species } from "#enums/species"; +import { EggTier } from "#enums/egg-type"; + +/** + * Map of all starters and their respective {@linkcode EggTier}, which determines the type of egg the starter hatches from. + */ +export const speciesEggTiers = { + [Species.BULBASAUR]: EggTier.COMMON, + [Species.CHARMANDER]: EggTier.COMMON, + [Species.SQUIRTLE]: EggTier.COMMON, + [Species.CATERPIE]: EggTier.COMMON, + [Species.WEEDLE]: EggTier.COMMON, + [Species.PIDGEY]: EggTier.COMMON, + [Species.RATTATA]: EggTier.COMMON, + [Species.SPEAROW]: EggTier.COMMON, + [Species.EKANS]: EggTier.COMMON, + [Species.PIKACHU]: EggTier.COMMON, + [Species.SANDSHREW]: EggTier.COMMON, + [Species.NIDORAN_F]: EggTier.COMMON, + [Species.NIDORAN_M]: EggTier.COMMON, + [Species.CLEFAIRY]: EggTier.COMMON, + [Species.VULPIX]: EggTier.COMMON, + [Species.JIGGLYPUFF]: EggTier.COMMON, + [Species.ZUBAT]: EggTier.COMMON, + [Species.ODDISH]: EggTier.COMMON, + [Species.PARAS]: EggTier.COMMON, + [Species.VENONAT]: EggTier.COMMON, + [Species.DIGLETT]: EggTier.COMMON, + [Species.MEOWTH]: EggTier.COMMON, + [Species.PSYDUCK]: EggTier.COMMON, + [Species.MANKEY]: EggTier.RARE, + [Species.GROWLITHE]: EggTier.RARE, + [Species.POLIWAG]: EggTier.COMMON, + [Species.ABRA]: EggTier.RARE, + [Species.MACHOP]: EggTier.COMMON, + [Species.BELLSPROUT]: EggTier.COMMON, + [Species.TENTACOOL]: EggTier.COMMON, + [Species.GEODUDE]: EggTier.COMMON, + [Species.PONYTA]: EggTier.COMMON, + [Species.SLOWPOKE]: EggTier.COMMON, + [Species.MAGNEMITE]: EggTier.RARE, + [Species.FARFETCHD]: EggTier.COMMON, + [Species.DODUO]: EggTier.COMMON, + [Species.SEEL]: EggTier.COMMON, + [Species.GRIMER]: EggTier.COMMON, + [Species.SHELLDER]: EggTier.RARE, + [Species.GASTLY]: EggTier.RARE, + [Species.ONIX]: EggTier.COMMON, + [Species.DROWZEE]: EggTier.COMMON, + [Species.KRABBY]: EggTier.COMMON, + [Species.VOLTORB]: EggTier.COMMON, + [Species.EXEGGCUTE]: EggTier.COMMON, + [Species.CUBONE]: EggTier.COMMON, + [Species.HITMONLEE]: EggTier.RARE, + [Species.HITMONCHAN]: EggTier.RARE, + [Species.LICKITUNG]: EggTier.COMMON, + [Species.KOFFING]: EggTier.COMMON, + [Species.RHYHORN]: EggTier.COMMON, + [Species.CHANSEY]: EggTier.COMMON, + [Species.TANGELA]: EggTier.COMMON, + [Species.KANGASKHAN]: EggTier.RARE, + [Species.HORSEA]: EggTier.COMMON, + [Species.GOLDEEN]: EggTier.COMMON, + [Species.STARYU]: EggTier.COMMON, + [Species.MR_MIME]: EggTier.COMMON, + [Species.SCYTHER]: EggTier.RARE, + [Species.JYNX]: EggTier.RARE, + [Species.ELECTABUZZ]: EggTier.RARE, + [Species.MAGMAR]: EggTier.RARE, + [Species.PINSIR]: EggTier.RARE, + [Species.TAUROS]: EggTier.RARE, + [Species.MAGIKARP]: EggTier.RARE, + [Species.LAPRAS]: EggTier.RARE, + [Species.DITTO]: EggTier.COMMON, + [Species.EEVEE]: EggTier.COMMON, + [Species.PORYGON]: EggTier.RARE, + [Species.OMANYTE]: EggTier.COMMON, + [Species.KABUTO]: EggTier.COMMON, + [Species.AERODACTYL]: EggTier.RARE, + [Species.SNORLAX]: EggTier.RARE, + [Species.ARTICUNO]: EggTier.EPIC, + [Species.ZAPDOS]: EggTier.EPIC, + [Species.MOLTRES]: EggTier.EPIC, + [Species.DRATINI]: EggTier.RARE, + [Species.MEWTWO]: EggTier.LEGENDARY, + [Species.MEW]: EggTier.EPIC, + + [Species.CHIKORITA]: EggTier.COMMON, + [Species.CYNDAQUIL]: EggTier.COMMON, + [Species.TOTODILE]: EggTier.COMMON, + [Species.SENTRET]: EggTier.COMMON, + [Species.HOOTHOOT]: EggTier.COMMON, + [Species.LEDYBA]: EggTier.COMMON, + [Species.SPINARAK]: EggTier.COMMON, + [Species.CHINCHOU]: EggTier.COMMON, + [Species.PICHU]: EggTier.COMMON, + [Species.CLEFFA]: EggTier.COMMON, + [Species.IGGLYBUFF]: EggTier.COMMON, + [Species.TOGEPI]: EggTier.COMMON, + [Species.NATU]: EggTier.COMMON, + [Species.MAREEP]: EggTier.COMMON, + [Species.MARILL]: EggTier.RARE, + [Species.SUDOWOODO]: EggTier.COMMON, + [Species.HOPPIP]: EggTier.COMMON, + [Species.AIPOM]: EggTier.COMMON, + [Species.SUNKERN]: EggTier.COMMON, + [Species.YANMA]: EggTier.COMMON, + [Species.WOOPER]: EggTier.COMMON, + [Species.MURKROW]: EggTier.COMMON, + [Species.MISDREAVUS]: EggTier.COMMON, + [Species.UNOWN]: EggTier.COMMON, + [Species.WOBBUFFET]: EggTier.COMMON, + [Species.GIRAFARIG]: EggTier.COMMON, + [Species.PINECO]: EggTier.COMMON, + [Species.DUNSPARCE]: EggTier.COMMON, + [Species.GLIGAR]: EggTier.COMMON, + [Species.SNUBBULL]: EggTier.COMMON, + [Species.QWILFISH]: EggTier.COMMON, + [Species.SHUCKLE]: EggTier.COMMON, + [Species.HERACROSS]: EggTier.RARE, + [Species.SNEASEL]: EggTier.RARE, + [Species.TEDDIURSA]: EggTier.RARE, + [Species.SLUGMA]: EggTier.COMMON, + [Species.SWINUB]: EggTier.COMMON, + [Species.CORSOLA]: EggTier.COMMON, + [Species.REMORAID]: EggTier.COMMON, + [Species.DELIBIRD]: EggTier.COMMON, + [Species.MANTINE]: EggTier.COMMON, + [Species.SKARMORY]: EggTier.RARE, + [Species.HOUNDOUR]: EggTier.COMMON, + [Species.PHANPY]: EggTier.COMMON, + [Species.STANTLER]: EggTier.COMMON, + [Species.SMEARGLE]: EggTier.COMMON, + [Species.TYROGUE]: EggTier.COMMON, + [Species.SMOOCHUM]: EggTier.COMMON, + [Species.ELEKID]: EggTier.COMMON, + [Species.MAGBY]: EggTier.COMMON, + [Species.MILTANK]: EggTier.RARE, + [Species.RAIKOU]: EggTier.EPIC, + [Species.ENTEI]: EggTier.EPIC, + [Species.SUICUNE]: EggTier.EPIC, + [Species.LARVITAR]: EggTier.RARE, + [Species.LUGIA]: EggTier.LEGENDARY, + [Species.HO_OH]: EggTier.LEGENDARY, + [Species.CELEBI]: EggTier.EPIC, + + [Species.TREECKO]: EggTier.COMMON, + [Species.TORCHIC]: EggTier.RARE, + [Species.MUDKIP]: EggTier.COMMON, + [Species.POOCHYENA]: EggTier.COMMON, + [Species.ZIGZAGOON]: EggTier.COMMON, + [Species.WURMPLE]: EggTier.COMMON, + [Species.LOTAD]: EggTier.COMMON, + [Species.SEEDOT]: EggTier.COMMON, + [Species.TAILLOW]: EggTier.COMMON, + [Species.WINGULL]: EggTier.COMMON, + [Species.RALTS]: EggTier.COMMON, + [Species.SURSKIT]: EggTier.COMMON, + [Species.SHROOMISH]: EggTier.COMMON, + [Species.SLAKOTH]: EggTier.RARE, + [Species.NINCADA]: EggTier.RARE, + [Species.WHISMUR]: EggTier.COMMON, + [Species.MAKUHITA]: EggTier.COMMON, + [Species.AZURILL]: EggTier.RARE, + [Species.NOSEPASS]: EggTier.COMMON, + [Species.SKITTY]: EggTier.COMMON, + [Species.SABLEYE]: EggTier.COMMON, + [Species.MAWILE]: EggTier.COMMON, + [Species.ARON]: EggTier.COMMON, + [Species.MEDITITE]: EggTier.COMMON, + [Species.ELECTRIKE]: EggTier.COMMON, + [Species.PLUSLE]: EggTier.COMMON, + [Species.MINUN]: EggTier.COMMON, + [Species.VOLBEAT]: EggTier.COMMON, + [Species.ILLUMISE]: EggTier.COMMON, + [Species.ROSELIA]: EggTier.COMMON, + [Species.GULPIN]: EggTier.COMMON, + [Species.CARVANHA]: EggTier.COMMON, + [Species.WAILMER]: EggTier.COMMON, + [Species.NUMEL]: EggTier.COMMON, + [Species.TORKOAL]: EggTier.COMMON, + [Species.SPOINK]: EggTier.COMMON, + [Species.SPINDA]: EggTier.COMMON, + [Species.TRAPINCH]: EggTier.COMMON, + [Species.CACNEA]: EggTier.COMMON, + [Species.SWABLU]: EggTier.COMMON, + [Species.ZANGOOSE]: EggTier.RARE, + [Species.SEVIPER]: EggTier.COMMON, + [Species.LUNATONE]: EggTier.COMMON, + [Species.SOLROCK]: EggTier.COMMON, + [Species.BARBOACH]: EggTier.COMMON, + [Species.CORPHISH]: EggTier.COMMON, + [Species.BALTOY]: EggTier.COMMON, + [Species.LILEEP]: EggTier.COMMON, + [Species.ANORITH]: EggTier.COMMON, + [Species.FEEBAS]: EggTier.RARE, + [Species.CASTFORM]: EggTier.COMMON, + [Species.KECLEON]: EggTier.COMMON, + [Species.SHUPPET]: EggTier.COMMON, + [Species.DUSKULL]: EggTier.COMMON, + [Species.TROPIUS]: EggTier.COMMON, + [Species.CHIMECHO]: EggTier.COMMON, + [Species.ABSOL]: EggTier.RARE, + [Species.WYNAUT]: EggTier.COMMON, + [Species.SNORUNT]: EggTier.COMMON, + [Species.SPHEAL]: EggTier.COMMON, + [Species.CLAMPERL]: EggTier.COMMON, + [Species.RELICANTH]: EggTier.COMMON, + [Species.LUVDISC]: EggTier.COMMON, + [Species.BAGON]: EggTier.RARE, + [Species.BELDUM]: EggTier.RARE, + [Species.REGIROCK]: EggTier.EPIC, + [Species.REGICE]: EggTier.EPIC, + [Species.REGISTEEL]: EggTier.EPIC, + [Species.LATIAS]: EggTier.EPIC, + [Species.LATIOS]: EggTier.EPIC, + [Species.KYOGRE]: EggTier.LEGENDARY, + [Species.GROUDON]: EggTier.LEGENDARY, + [Species.RAYQUAZA]: EggTier.LEGENDARY, + [Species.JIRACHI]: EggTier.EPIC, + [Species.DEOXYS]: EggTier.EPIC, + + [Species.TURTWIG]: EggTier.COMMON, + [Species.CHIMCHAR]: EggTier.COMMON, + [Species.PIPLUP]: EggTier.COMMON, + [Species.STARLY]: EggTier.COMMON, + [Species.BIDOOF]: EggTier.COMMON, + [Species.KRICKETOT]: EggTier.COMMON, + [Species.SHINX]: EggTier.COMMON, + [Species.BUDEW]: EggTier.COMMON, + [Species.CRANIDOS]: EggTier.COMMON, + [Species.SHIELDON]: EggTier.COMMON, + [Species.BURMY]: EggTier.COMMON, + [Species.COMBEE]: EggTier.COMMON, + [Species.PACHIRISU]: EggTier.COMMON, + [Species.BUIZEL]: EggTier.COMMON, + [Species.CHERUBI]: EggTier.COMMON, + [Species.SHELLOS]: EggTier.COMMON, + [Species.DRIFLOON]: EggTier.COMMON, + [Species.BUNEARY]: EggTier.COMMON, + [Species.GLAMEOW]: EggTier.COMMON, + [Species.CHINGLING]: EggTier.COMMON, + [Species.STUNKY]: EggTier.COMMON, + [Species.BRONZOR]: EggTier.COMMON, + [Species.BONSLY]: EggTier.COMMON, + [Species.MIME_JR]: EggTier.COMMON, + [Species.HAPPINY]: EggTier.COMMON, + [Species.CHATOT]: EggTier.COMMON, + [Species.SPIRITOMB]: EggTier.RARE, + [Species.GIBLE]: EggTier.RARE, + [Species.MUNCHLAX]: EggTier.RARE, + [Species.RIOLU]: EggTier.COMMON, + [Species.HIPPOPOTAS]: EggTier.COMMON, + [Species.SKORUPI]: EggTier.COMMON, + [Species.CROAGUNK]: EggTier.COMMON, + [Species.CARNIVINE]: EggTier.COMMON, + [Species.FINNEON]: EggTier.COMMON, + [Species.MANTYKE]: EggTier.COMMON, + [Species.SNOVER]: EggTier.COMMON, + [Species.ROTOM]: EggTier.RARE, + [Species.UXIE]: EggTier.EPIC, + [Species.MESPRIT]: EggTier.EPIC, + [Species.AZELF]: EggTier.EPIC, + [Species.DIALGA]: EggTier.LEGENDARY, + [Species.PALKIA]: EggTier.LEGENDARY, + [Species.HEATRAN]: EggTier.EPIC, + [Species.REGIGIGAS]: EggTier.EPIC, + [Species.GIRATINA]: EggTier.LEGENDARY, + [Species.CRESSELIA]: EggTier.EPIC, + [Species.PHIONE]: EggTier.RARE, + [Species.MANAPHY]: EggTier.EPIC, + [Species.DARKRAI]: EggTier.EPIC, + [Species.SHAYMIN]: EggTier.EPIC, + [Species.ARCEUS]: EggTier.LEGENDARY, + + [Species.VICTINI]: EggTier.EPIC, + [Species.SNIVY]: EggTier.COMMON, + [Species.TEPIG]: EggTier.COMMON, + [Species.OSHAWOTT]: EggTier.COMMON, + [Species.PATRAT]: EggTier.COMMON, + [Species.LILLIPUP]: EggTier.COMMON, + [Species.PURRLOIN]: EggTier.COMMON, + [Species.PANSAGE]: EggTier.COMMON, + [Species.PANSEAR]: EggTier.COMMON, + [Species.PANPOUR]: EggTier.COMMON, + [Species.MUNNA]: EggTier.COMMON, + [Species.PIDOVE]: EggTier.COMMON, + [Species.BLITZLE]: EggTier.COMMON, + [Species.ROGGENROLA]: EggTier.COMMON, + [Species.WOOBAT]: EggTier.COMMON, + [Species.DRILBUR]: EggTier.RARE, + [Species.AUDINO]: EggTier.COMMON, + [Species.TIMBURR]: EggTier.RARE, + [Species.TYMPOLE]: EggTier.COMMON, + [Species.THROH]: EggTier.RARE, + [Species.SAWK]: EggTier.RARE, + [Species.SEWADDLE]: EggTier.COMMON, + [Species.VENIPEDE]: EggTier.COMMON, + [Species.COTTONEE]: EggTier.COMMON, + [Species.PETILIL]: EggTier.COMMON, + [Species.BASCULIN]: EggTier.RARE, + [Species.SANDILE]: EggTier.RARE, + [Species.DARUMAKA]: EggTier.RARE, + [Species.MARACTUS]: EggTier.COMMON, + [Species.DWEBBLE]: EggTier.COMMON, + [Species.SCRAGGY]: EggTier.COMMON, + [Species.SIGILYPH]: EggTier.RARE, + [Species.YAMASK]: EggTier.COMMON, + [Species.TIRTOUGA]: EggTier.COMMON, + [Species.ARCHEN]: EggTier.COMMON, + [Species.TRUBBISH]: EggTier.COMMON, + [Species.ZORUA]: EggTier.COMMON, + [Species.MINCCINO]: EggTier.COMMON, + [Species.GOTHITA]: EggTier.COMMON, + [Species.SOLOSIS]: EggTier.COMMON, + [Species.DUCKLETT]: EggTier.COMMON, + [Species.VANILLITE]: EggTier.COMMON, + [Species.DEERLING]: EggTier.COMMON, + [Species.EMOLGA]: EggTier.COMMON, + [Species.KARRABLAST]: EggTier.COMMON, + [Species.FOONGUS]: EggTier.COMMON, + [Species.FRILLISH]: EggTier.COMMON, + [Species.ALOMOMOLA]: EggTier.RARE, + [Species.JOLTIK]: EggTier.COMMON, + [Species.FERROSEED]: EggTier.COMMON, + [Species.KLINK]: EggTier.COMMON, + [Species.TYNAMO]: EggTier.COMMON, + [Species.ELGYEM]: EggTier.COMMON, + [Species.LITWICK]: EggTier.COMMON, + [Species.AXEW]: EggTier.RARE, + [Species.CUBCHOO]: EggTier.COMMON, + [Species.CRYOGONAL]: EggTier.RARE, + [Species.SHELMET]: EggTier.COMMON, + [Species.STUNFISK]: EggTier.COMMON, + [Species.MIENFOO]: EggTier.COMMON, + [Species.DRUDDIGON]: EggTier.RARE, + [Species.GOLETT]: EggTier.COMMON, + [Species.PAWNIARD]: EggTier.RARE, + [Species.BOUFFALANT]: EggTier.RARE, + [Species.RUFFLET]: EggTier.COMMON, + [Species.VULLABY]: EggTier.COMMON, + [Species.HEATMOR]: EggTier.COMMON, + [Species.DURANT]: EggTier.RARE, + [Species.DEINO]: EggTier.RARE, + [Species.LARVESTA]: EggTier.RARE, + [Species.COBALION]: EggTier.EPIC, + [Species.TERRAKION]: EggTier.EPIC, + [Species.VIRIZION]: EggTier.EPIC, + [Species.TORNADUS]: EggTier.EPIC, + [Species.THUNDURUS]: EggTier.EPIC, + [Species.RESHIRAM]: EggTier.LEGENDARY, + [Species.ZEKROM]: EggTier.LEGENDARY, + [Species.LANDORUS]: EggTier.EPIC, + [Species.KYUREM]: EggTier.LEGENDARY, + [Species.KELDEO]: EggTier.EPIC, + [Species.MELOETTA]: EggTier.EPIC, + [Species.GENESECT]: EggTier.EPIC, + + [Species.CHESPIN]: EggTier.COMMON, + [Species.FENNEKIN]: EggTier.COMMON, + [Species.FROAKIE]: EggTier.RARE, + [Species.BUNNELBY]: EggTier.COMMON, + [Species.FLETCHLING]: EggTier.COMMON, + [Species.SCATTERBUG]: EggTier.COMMON, + [Species.LITLEO]: EggTier.COMMON, + [Species.FLABEBE]: EggTier.COMMON, + [Species.SKIDDO]: EggTier.COMMON, + [Species.PANCHAM]: EggTier.COMMON, + [Species.FURFROU]: EggTier.COMMON, + [Species.ESPURR]: EggTier.COMMON, + [Species.HONEDGE]: EggTier.RARE, + [Species.SPRITZEE]: EggTier.COMMON, + [Species.SWIRLIX]: EggTier.COMMON, + [Species.INKAY]: EggTier.COMMON, + [Species.BINACLE]: EggTier.COMMON, + [Species.SKRELP]: EggTier.COMMON, + [Species.CLAUNCHER]: EggTier.COMMON, + [Species.HELIOPTILE]: EggTier.COMMON, + [Species.TYRUNT]: EggTier.COMMON, + [Species.AMAURA]: EggTier.COMMON, + [Species.HAWLUCHA]: EggTier.RARE, + [Species.DEDENNE]: EggTier.COMMON, + [Species.CARBINK]: EggTier.COMMON, + [Species.GOOMY]: EggTier.RARE, + [Species.KLEFKI]: EggTier.COMMON, + [Species.PHANTUMP]: EggTier.COMMON, + [Species.PUMPKABOO]: EggTier.COMMON, + [Species.BERGMITE]: EggTier.COMMON, + [Species.NOIBAT]: EggTier.COMMON, + [Species.XERNEAS]: EggTier.LEGENDARY, + [Species.YVELTAL]: EggTier.LEGENDARY, + [Species.ZYGARDE]: EggTier.LEGENDARY, + [Species.DIANCIE]: EggTier.EPIC, + [Species.HOOPA]: EggTier.EPIC, + [Species.VOLCANION]: EggTier.EPIC, + [Species.ETERNAL_FLOETTE]: EggTier.RARE, + + [Species.ROWLET]: EggTier.COMMON, + [Species.LITTEN]: EggTier.COMMON, + [Species.POPPLIO]: EggTier.RARE, + [Species.PIKIPEK]: EggTier.COMMON, + [Species.YUNGOOS]: EggTier.COMMON, + [Species.GRUBBIN]: EggTier.COMMON, + [Species.CRABRAWLER]: EggTier.COMMON, + [Species.ORICORIO]: EggTier.COMMON, + [Species.CUTIEFLY]: EggTier.COMMON, + [Species.ROCKRUFF]: EggTier.COMMON, + [Species.WISHIWASHI]: EggTier.COMMON, + [Species.MAREANIE]: EggTier.COMMON, + [Species.MUDBRAY]: EggTier.COMMON, + [Species.DEWPIDER]: EggTier.COMMON, + [Species.FOMANTIS]: EggTier.COMMON, + [Species.MORELULL]: EggTier.COMMON, + [Species.SALANDIT]: EggTier.COMMON, + [Species.STUFFUL]: EggTier.COMMON, + [Species.BOUNSWEET]: EggTier.COMMON, + [Species.COMFEY]: EggTier.RARE, + [Species.ORANGURU]: EggTier.RARE, + [Species.PASSIMIAN]: EggTier.RARE, + [Species.WIMPOD]: EggTier.COMMON, + [Species.SANDYGAST]: EggTier.COMMON, + [Species.PYUKUMUKU]: EggTier.COMMON, + [Species.TYPE_NULL]: EggTier.RARE, + [Species.MINIOR]: EggTier.RARE, + [Species.KOMALA]: EggTier.COMMON, + [Species.TURTONATOR]: EggTier.RARE, + [Species.TOGEDEMARU]: EggTier.COMMON, + [Species.MIMIKYU]: EggTier.RARE, + [Species.BRUXISH]: EggTier.RARE, + [Species.DRAMPA]: EggTier.RARE, + [Species.DHELMISE]: EggTier.RARE, + [Species.JANGMO_O]: EggTier.RARE, + [Species.TAPU_KOKO]: EggTier.EPIC, + [Species.TAPU_LELE]: EggTier.EPIC, + [Species.TAPU_BULU]: EggTier.EPIC, + [Species.TAPU_FINI]: EggTier.EPIC, + [Species.COSMOG]: EggTier.EPIC, + [Species.NIHILEGO]: EggTier.EPIC, + [Species.BUZZWOLE]: EggTier.EPIC, + [Species.PHEROMOSA]: EggTier.EPIC, + [Species.XURKITREE]: EggTier.EPIC, + [Species.CELESTEELA]: EggTier.EPIC, + [Species.KARTANA]: EggTier.EPIC, + [Species.GUZZLORD]: EggTier.EPIC, + [Species.NECROZMA]: EggTier.LEGENDARY, + [Species.MAGEARNA]: EggTier.EPIC, + [Species.MARSHADOW]: EggTier.EPIC, + [Species.POIPOLE]: EggTier.EPIC, + [Species.STAKATAKA]: EggTier.EPIC, + [Species.BLACEPHALON]: EggTier.EPIC, + [Species.ZERAORA]: EggTier.EPIC, + [Species.MELTAN]: EggTier.EPIC, + [Species.ALOLA_RATTATA]: EggTier.COMMON, + [Species.ALOLA_SANDSHREW]: EggTier.COMMON, + [Species.ALOLA_VULPIX]: EggTier.COMMON, + [Species.ALOLA_DIGLETT]: EggTier.COMMON, + [Species.ALOLA_MEOWTH]: EggTier.COMMON, + [Species.ALOLA_GEODUDE]: EggTier.COMMON, + [Species.ALOLA_GRIMER]: EggTier.COMMON, + + [Species.GROOKEY]: EggTier.COMMON, + [Species.SCORBUNNY]: EggTier.RARE, + [Species.SOBBLE]: EggTier.COMMON, + [Species.SKWOVET]: EggTier.COMMON, + [Species.ROOKIDEE]: EggTier.COMMON, + [Species.BLIPBUG]: EggTier.COMMON, + [Species.NICKIT]: EggTier.COMMON, + [Species.GOSSIFLEUR]: EggTier.COMMON, + [Species.WOOLOO]: EggTier.COMMON, + [Species.CHEWTLE]: EggTier.COMMON, + [Species.YAMPER]: EggTier.COMMON, + [Species.ROLYCOLY]: EggTier.COMMON, + [Species.APPLIN]: EggTier.COMMON, + [Species.SILICOBRA]: EggTier.COMMON, + [Species.CRAMORANT]: EggTier.COMMON, + [Species.ARROKUDA]: EggTier.COMMON, + [Species.TOXEL]: EggTier.COMMON, + [Species.SIZZLIPEDE]: EggTier.COMMON, + [Species.CLOBBOPUS]: EggTier.COMMON, + [Species.SINISTEA]: EggTier.COMMON, + [Species.HATENNA]: EggTier.COMMON, + [Species.IMPIDIMP]: EggTier.COMMON, + [Species.MILCERY]: EggTier.COMMON, + [Species.FALINKS]: EggTier.RARE, + [Species.PINCURCHIN]: EggTier.COMMON, + [Species.SNOM]: EggTier.COMMON, + [Species.STONJOURNER]: EggTier.COMMON, + [Species.EISCUE]: EggTier.COMMON, + [Species.INDEEDEE]: EggTier.RARE, + [Species.MORPEKO]: EggTier.COMMON, + [Species.CUFANT]: EggTier.COMMON, + [Species.DRACOZOLT]: EggTier.RARE, + [Species.ARCTOZOLT]: EggTier.RARE, + [Species.DRACOVISH]: EggTier.RARE, + [Species.ARCTOVISH]: EggTier.RARE, + [Species.DURALUDON]: EggTier.RARE, + [Species.DREEPY]: EggTier.RARE, + [Species.ZACIAN]: EggTier.LEGENDARY, + [Species.ZAMAZENTA]: EggTier.LEGENDARY, + [Species.ETERNATUS]: EggTier.LEGENDARY, + [Species.KUBFU]: EggTier.EPIC, + [Species.ZARUDE]: EggTier.EPIC, + [Species.REGIELEKI]: EggTier.EPIC, + [Species.REGIDRAGO]: EggTier.EPIC, + [Species.GLASTRIER]: EggTier.EPIC, + [Species.SPECTRIER]: EggTier.EPIC, + [Species.CALYREX]: EggTier.LEGENDARY, + [Species.GALAR_MEOWTH]: EggTier.COMMON, + [Species.GALAR_PONYTA]: EggTier.COMMON, + [Species.GALAR_SLOWPOKE]: EggTier.COMMON, + [Species.GALAR_FARFETCHD]: EggTier.COMMON, + [Species.GALAR_CORSOLA]: EggTier.COMMON, + [Species.GALAR_ZIGZAGOON]: EggTier.COMMON, + [Species.GALAR_DARUMAKA]: EggTier.RARE, + [Species.GALAR_YAMASK]: EggTier.COMMON, + [Species.GALAR_STUNFISK]: EggTier.COMMON, + [Species.GALAR_MR_MIME]: EggTier.COMMON, + [Species.GALAR_ARTICUNO]: EggTier.EPIC, + [Species.GALAR_ZAPDOS]: EggTier.EPIC, + [Species.GALAR_MOLTRES]: EggTier.EPIC, + [Species.HISUI_GROWLITHE]: EggTier.RARE, + [Species.HISUI_VOLTORB]: EggTier.COMMON, + [Species.HISUI_QWILFISH]: EggTier.RARE, + [Species.HISUI_SNEASEL]: EggTier.RARE, + [Species.HISUI_ZORUA]: EggTier.COMMON, + [Species.ENAMORUS]: EggTier.EPIC, + + [Species.SPRIGATITO]: EggTier.RARE, + [Species.FUECOCO]: EggTier.RARE, + [Species.QUAXLY]: EggTier.RARE, + [Species.LECHONK]: EggTier.COMMON, + [Species.TAROUNTULA]: EggTier.COMMON, + [Species.NYMBLE]: EggTier.COMMON, + [Species.PAWMI]: EggTier.COMMON, + [Species.TANDEMAUS]: EggTier.RARE, + [Species.FIDOUGH]: EggTier.COMMON, + [Species.SMOLIV]: EggTier.COMMON, + [Species.SQUAWKABILLY]: EggTier.COMMON, + [Species.NACLI]: EggTier.RARE, + [Species.CHARCADET]: EggTier.RARE, + [Species.TADBULB]: EggTier.COMMON, + [Species.WATTREL]: EggTier.COMMON, + [Species.MASCHIFF]: EggTier.COMMON, + [Species.SHROODLE]: EggTier.COMMON, + [Species.BRAMBLIN]: EggTier.COMMON, + [Species.TOEDSCOOL]: EggTier.COMMON, + [Species.KLAWF]: EggTier.COMMON, + [Species.CAPSAKID]: EggTier.COMMON, + [Species.RELLOR]: EggTier.COMMON, + [Species.FLITTLE]: EggTier.COMMON, + [Species.TINKATINK]: EggTier.RARE, + [Species.WIGLETT]: EggTier.COMMON, + [Species.BOMBIRDIER]: EggTier.COMMON, + [Species.FINIZEN]: EggTier.COMMON, + [Species.VAROOM]: EggTier.RARE, + [Species.CYCLIZAR]: EggTier.RARE, + [Species.ORTHWORM]: EggTier.RARE, + [Species.GLIMMET]: EggTier.RARE, + [Species.GREAVARD]: EggTier.COMMON, + [Species.FLAMIGO]: EggTier.RARE, + [Species.CETODDLE]: EggTier.COMMON, + [Species.VELUZA]: EggTier.RARE, + [Species.DONDOZO]: EggTier.RARE, + [Species.TATSUGIRI]: EggTier.RARE, + [Species.GREAT_TUSK]: EggTier.EPIC, + [Species.SCREAM_TAIL]: EggTier.EPIC, + [Species.BRUTE_BONNET]: EggTier.EPIC, + [Species.FLUTTER_MANE]: EggTier.EPIC, + [Species.SLITHER_WING]: EggTier.EPIC, + [Species.SANDY_SHOCKS]: EggTier.EPIC, + [Species.IRON_TREADS]: EggTier.EPIC, + [Species.IRON_BUNDLE]: EggTier.EPIC, + [Species.IRON_HANDS]: EggTier.EPIC, + [Species.IRON_JUGULIS]: EggTier.EPIC, + [Species.IRON_MOTH]: EggTier.EPIC, + [Species.IRON_THORNS]: EggTier.EPIC, + [Species.FRIGIBAX]: EggTier.RARE, + [Species.GIMMIGHOUL]: EggTier.RARE, + [Species.WO_CHIEN]: EggTier.EPIC, + [Species.CHIEN_PAO]: EggTier.EPIC, + [Species.TING_LU]: EggTier.EPIC, + [Species.CHI_YU]: EggTier.EPIC, + [Species.ROARING_MOON]: EggTier.EPIC, + [Species.IRON_VALIANT]: EggTier.EPIC, + [Species.KORAIDON]: EggTier.LEGENDARY, + [Species.MIRAIDON]: EggTier.LEGENDARY, + [Species.WALKING_WAKE]: EggTier.EPIC, + [Species.IRON_LEAVES]: EggTier.EPIC, + [Species.POLTCHAGEIST]: EggTier.RARE, + [Species.OKIDOGI]: EggTier.EPIC, + [Species.MUNKIDORI]: EggTier.EPIC, + [Species.FEZANDIPITI]: EggTier.EPIC, + [Species.OGERPON]: EggTier.EPIC, + [Species.GOUGING_FIRE]: EggTier.EPIC, + [Species.RAGING_BOLT]: EggTier.EPIC, + [Species.IRON_BOULDER]: EggTier.EPIC, + [Species.IRON_CROWN]: EggTier.EPIC, + [Species.TERAPAGOS]: EggTier.LEGENDARY, + [Species.PECHARUNT]: EggTier.EPIC, + [Species.PALDEA_TAUROS]: EggTier.RARE, + [Species.PALDEA_WOOPER]: EggTier.COMMON, + [Species.BLOODMOON_URSALUNA]: EggTier.EPIC, +}; diff --git a/src/data/balance/starters.ts b/src/data/balance/starters.ts index 5117f800086..d6a1f0c3eaf 100644 --- a/src/data/balance/starters.ts +++ b/src/data/balance/starters.ts @@ -2,6 +2,12 @@ import { Species } from "#enums/species"; export const POKERUS_STARTER_COUNT = 5; +// #region Friendship constants +export const CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER = 2; +export const FRIENDSHIP_GAIN_FROM_BATTLE = 2; +export const FRIENDSHIP_GAIN_FROM_RARE_CANDY = 5; +export const FRIENDSHIP_LOSS_FROM_FAINT = 10; + /** * Function to get the cumulative friendship threshold at which a candy is earned * @param starterCost The cost of the starter, found in {@linkcode speciesStarterCosts} @@ -9,25 +15,25 @@ export const POKERUS_STARTER_COUNT = 5; */ export function getStarterValueFriendshipCap(starterCost: number): number { switch (starterCost) { - case 1: - return 20; - case 2: - return 40; - case 3: - return 60; - case 4: - return 100; - case 5: - return 140; - case 6: - return 200; - case 7: - return 280; - case 8: - case 9: - return 450; - default: - return 600; + case 1: + return 20; + case 2: + return 40; + case 3: + return 60; + case 4: + return 100; + case 5: + return 140; + case 6: + return 200; + case 7: + return 280; + case 8: + case 9: + return 450; + default: + return 600; } } @@ -630,16 +636,16 @@ export const speciesStarterCosts = { }; const starterCandyCosts: { passive: number; costReduction: [number, number]; egg: number; }[] = [ - { passive: 40, costReduction: [25, 60], egg: 30 }, // 1 Cost - { passive: 40, costReduction: [25, 60], egg: 30 }, // 2 Cost - { passive: 35, costReduction: [20, 50], egg: 25 }, // 3 Cost - { passive: 30, costReduction: [15, 40], egg: 20 }, // 4 Cost - { passive: 25, costReduction: [12, 35], egg: 18 }, // 5 Cost - { passive: 20, costReduction: [10, 30], egg: 15 }, // 6 Cost - { passive: 15, costReduction: [8, 20], egg: 12 }, // 7 Cost - { passive: 10, costReduction: [5, 15], egg: 10 }, // 8 Cost - { passive: 10, costReduction: [5, 15], egg: 10 }, // 9 Cost - { passive: 10, costReduction: [5, 15], egg: 10 }, // 10 Cost + { passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 1 Cost + { passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 2 Cost + { passive: 35, costReduction: [ 20, 50 ], egg: 25 }, // 3 Cost + { passive: 30, costReduction: [ 15, 40 ], egg: 20 }, // 4 Cost + { passive: 25, costReduction: [ 12, 35 ], egg: 18 }, // 5 Cost + { passive: 20, costReduction: [ 10, 30 ], egg: 15 }, // 6 Cost + { passive: 15, costReduction: [ 8, 20 ], egg: 12 }, // 7 Cost + { passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 8 Cost + { passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 9 Cost + { passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 10 Cost ]; /** diff --git a/src/data/balance/tms.ts b/src/data/balance/tms.ts index e08b677c30c..7b65ae65ec4 100644 --- a/src/data/balance/tms.ts +++ b/src/data/balance/tms.ts @@ -1107,12 +1107,7 @@ export const tmSpecies: TmSpecies = { Species.QUILLADIN, Species.CHESNAUGHT, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.BUNNELBY, Species.DIGGERSBY, Species.FLETCHLING, @@ -2878,12 +2873,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.BUNNELBY, Species.DIGGERSBY, Species.FLETCHLING, @@ -3910,7 +3900,6 @@ export const tmSpecies: TmSpecies = { Species.YAMPER, Species.BOLTUND, Species.ZAMAZENTA, - Species.URSHIFU, Species.ZARUDE, Species.GLASTRIER, Species.WYRDEER, @@ -3940,6 +3929,10 @@ export const tmSpecies: TmSpecies = { Species.ALOLA_NINETALES, Species.ALOLA_PERSIAN, Species.ALOLA_GOLEM, + [ + Species.URSHIFU, + "single-strike", + ], Species.HISUI_GROWLITHE, Species.HISUI_ARCANINE, Species.HISUI_TYPHLOSION, @@ -6987,14 +6980,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -8301,7 +8287,6 @@ export const tmSpecies: TmSpecies = { [ Species.WORMADAM, "sandy", - "trash", ], Species.ALOLA_SANDSHREW, Species.ALOLA_SANDSLASH, @@ -8612,12 +8597,7 @@ export const tmSpecies: TmSpecies = { Species.CHESNAUGHT, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.BUNNELBY, Species.DIGGERSBY, Species.LITLEO, @@ -9406,14 +9386,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -9766,14 +9739,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.VIVILLON, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.ESPURR, Species.MEOWSTIC, @@ -11147,14 +11113,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -12359,6 +12318,7 @@ export const tmSpecies: TmSpecies = { Species.TURTWIG, Species.GROTLE, Species.TORTERRA, + Species.BASTIODON, Species.CHINGLING, Species.BRONZOR, Species.BRONZONG, @@ -12366,6 +12326,7 @@ export const tmSpecies: TmSpecies = { Species.WEAVILE, Species.MAGNEZONE, Species.TANGROWTH, + Species.ELECTIVIRE, Species.TOGEKISS, Species.MAMOSWINE, Species.GALLADE, @@ -12398,6 +12359,8 @@ export const tmSpecies: TmSpecies = { Species.CRYOGONAL, Species.MIENFOO, Species.MIENSHAO, + Species.GOLETT, + Species.GOLURK, Species.HYDREIGON, Species.COBALION, Species.TERRAKION, @@ -13657,12 +13620,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.FLETCHLING, Species.FLETCHINDER, Species.TALONFLAME, @@ -15326,14 +15284,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -16934,14 +16885,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -18483,14 +18427,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -20250,14 +20187,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -21583,12 +21513,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.BUNNELBY, Species.DIGGERSBY, Species.LITLEO, @@ -22516,7 +22441,6 @@ export const tmSpecies: TmSpecies = { [ Species.WORMADAM, "sandy", - "trash", ], Species.ALOLA_DIGLETT, Species.ALOLA_DUGTRIO, @@ -22691,14 +22615,7 @@ export const tmSpecies: TmSpecies = { Species.CHESNAUGHT, Species.VIVILLON, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -23402,12 +23319,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.BUNNELBY, Species.DIGGERSBY, Species.FLETCHLING, @@ -24134,12 +24046,7 @@ export const tmSpecies: TmSpecies = { Species.KELDEO, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.PANCHAM, Species.PANGORO, Species.HONEDGE, @@ -24842,14 +24749,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -25712,14 +25612,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -26695,14 +26588,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -27845,14 +27731,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -28911,14 +28790,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -29514,14 +29386,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.VIVILLON, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.ESPURR, Species.MEOWSTIC, @@ -31408,14 +31273,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -32327,14 +32185,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -33037,14 +32888,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -33471,7 +33315,6 @@ export const tmSpecies: TmSpecies = { Species.ARCTOVISH, Species.ZACIAN, Species.ZAMAZENTA, - Species.URSHIFU, Species.ZARUDE, Species.REGIDRAGO, Species.GLASTRIER, @@ -33522,6 +33365,10 @@ export const tmSpecies: TmSpecies = { Species.ALOLA_MUK, Species.GALAR_MEOWTH, Species.GALAR_STUNFISK, + [ + Species.URSHIFU, + "single-strike", + ], [ Species.CALYREX, "ice", @@ -36644,14 +36491,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -37389,14 +37229,7 @@ export const tmSpecies: TmSpecies = { Species.BUNNELBY, Species.DIGGERSBY, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -38266,23 +38099,11 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -39323,12 +39144,7 @@ export const tmSpecies: TmSpecies = { Species.CHESPIN, Species.QUILLADIN, Species.CHESNAUGHT, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.BUNNELBY, Species.DIGGERSBY, Species.SKIDDO, @@ -40356,7 +40172,10 @@ export const tmSpecies: TmSpecies = { Species.FENNEKIN, Species.BRAIXEN, Species.DELPHOX, - Species.MEOWSTIC, + [ + Species.MEOWSTIC, + "male", + ], Species.KLEFKI, Species.PHANTUMP, Species.TREVENANT, @@ -40418,6 +40237,1065 @@ export const tmSpecies: TmSpecies = { Species.HISUI_ZORUA, Species.HISUI_ZOROARK, ], + [Moves.SECRET_POWER]: [ + Species.BULBASAUR, + Species.IVYSAUR, + Species.VENUSAUR, + Species.CHARMANDER, + Species.CHARMELEON, + Species.CHARIZARD, + Species.SQUIRTLE, + Species.WARTORTLE, + Species.BLASTOISE, + Species.BUTTERFREE, + Species.BEEDRILL, + Species.PIDGEY, + Species.PIDGEOTTO, + Species.PIDGEOT, + Species.RATTATA, + Species.RATICATE, + Species.SPEAROW, + Species.FEAROW, + Species.EKANS, + Species.ARBOK, + Species.PIKACHU, + Species.RAICHU, + Species.SANDSHREW, + Species.SANDSLASH, + Species.NIDORAN_F, + Species.NIDORINA, + Species.NIDOQUEEN, + Species.NIDORAN_M, + Species.NIDORINO, + Species.NIDOKING, + Species.CLEFAIRY, + Species.CLEFABLE, + Species.VULPIX, + Species.NINETALES, + Species.JIGGLYPUFF, + Species.WIGGLYTUFF, + Species.ZUBAT, + Species.GOLBAT, + Species.ODDISH, + Species.GLOOM, + Species.VILEPLUME, + Species.PARAS, + Species.PARASECT, + Species.VENONAT, + Species.VENOMOTH, + Species.DIGLETT, + Species.DUGTRIO, + Species.MEOWTH, + Species.PERSIAN, + Species.PSYDUCK, + Species.GOLDUCK, + Species.MANKEY, + Species.PRIMEAPE, + Species.GROWLITHE, + Species.ARCANINE, + Species.POLIWAG, + Species.POLIWHIRL, + Species.POLIWRATH, + Species.ABRA, + Species.KADABRA, + Species.ALAKAZAM, + Species.MACHOP, + Species.MACHOKE, + Species.MACHAMP, + Species.BELLSPROUT, + Species.WEEPINBELL, + Species.VICTREEBEL, + Species.TENTACOOL, + Species.TENTACRUEL, + Species.GEODUDE, + Species.GRAVELER, + Species.GOLEM, + Species.PONYTA, + Species.RAPIDASH, + Species.SLOWPOKE, + Species.SLOWBRO, + Species.MAGNEMITE, + Species.MAGNETON, + Species.FARFETCHD, + Species.DODUO, + Species.DODRIO, + Species.SEEL, + Species.DEWGONG, + Species.GRIMER, + Species.MUK, + Species.SHELLDER, + Species.CLOYSTER, + Species.GASTLY, + Species.HAUNTER, + Species.GENGAR, + Species.ONIX, + Species.DROWZEE, + Species.HYPNO, + Species.KRABBY, + Species.KINGLER, + Species.VOLTORB, + Species.ELECTRODE, + Species.EXEGGCUTE, + Species.EXEGGUTOR, + Species.CUBONE, + Species.MAROWAK, + Species.HITMONLEE, + Species.HITMONCHAN, + Species.LICKITUNG, + Species.KOFFING, + Species.WEEZING, + Species.RHYHORN, + Species.RHYDON, + Species.CHANSEY, + Species.TANGELA, + Species.KANGASKHAN, + Species.HORSEA, + Species.SEADRA, + Species.GOLDEEN, + Species.SEAKING, + Species.STARYU, + Species.STARMIE, + Species.MR_MIME, + Species.SCYTHER, + Species.JYNX, + Species.ELECTABUZZ, + Species.MAGMAR, + Species.PINSIR, + Species.TAUROS, + Species.GYARADOS, + Species.LAPRAS, + Species.EEVEE, + Species.VAPOREON, + Species.JOLTEON, + Species.FLAREON, + Species.PORYGON, + Species.OMANYTE, + Species.OMASTAR, + Species.KABUTO, + Species.KABUTOPS, + Species.AERODACTYL, + Species.SNORLAX, + Species.ARTICUNO, + Species.ZAPDOS, + Species.MOLTRES, + Species.DRATINI, + Species.DRAGONAIR, + Species.DRAGONITE, + Species.MEWTWO, + Species.MEW, + Species.CHIKORITA, + Species.BAYLEEF, + Species.MEGANIUM, + Species.CYNDAQUIL, + Species.QUILAVA, + Species.TYPHLOSION, + Species.TOTODILE, + Species.CROCONAW, + Species.FERALIGATR, + Species.SENTRET, + Species.FURRET, + Species.HOOTHOOT, + Species.NOCTOWL, + Species.LEDYBA, + Species.LEDIAN, + Species.SPINARAK, + Species.ARIADOS, + Species.CROBAT, + Species.CHINCHOU, + Species.LANTURN, + Species.PICHU, + Species.CLEFFA, + Species.IGGLYBUFF, + Species.TOGEPI, + Species.TOGETIC, + Species.NATU, + Species.XATU, + Species.MAREEP, + Species.FLAAFFY, + Species.AMPHAROS, + Species.BELLOSSOM, + Species.MARILL, + Species.AZUMARILL, + Species.SUDOWOODO, + Species.POLITOED, + Species.HOPPIP, + Species.SKIPLOOM, + Species.JUMPLUFF, + Species.AIPOM, + Species.SUNKERN, + Species.SUNFLORA, + Species.YANMA, + Species.WOOPER, + Species.QUAGSIRE, + Species.ESPEON, + Species.UMBREON, + Species.MURKROW, + Species.SLOWKING, + Species.MISDREAVUS, + Species.GIRAFARIG, + Species.PINECO, + Species.FORRETRESS, + Species.DUNSPARCE, + Species.GLIGAR, + Species.STEELIX, + Species.SNUBBULL, + Species.GRANBULL, + Species.QWILFISH, + Species.SCIZOR, + Species.SHUCKLE, + Species.HERACROSS, + Species.SNEASEL, + Species.TEDDIURSA, + Species.URSARING, + Species.SLUGMA, + Species.MAGCARGO, + Species.SWINUB, + Species.PILOSWINE, + Species.CORSOLA, + Species.REMORAID, + Species.OCTILLERY, + Species.DELIBIRD, + Species.MANTINE, + Species.SKARMORY, + Species.HOUNDOUR, + Species.HOUNDOOM, + Species.KINGDRA, + Species.PHANPY, + Species.DONPHAN, + Species.PORYGON2, + Species.STANTLER, + Species.TYROGUE, + Species.HITMONTOP, + Species.SMOOCHUM, + Species.ELEKID, + Species.MAGBY, + Species.MILTANK, + Species.BLISSEY, + Species.RAIKOU, + Species.ENTEI, + Species.SUICUNE, + Species.LARVITAR, + Species.PUPITAR, + Species.TYRANITAR, + Species.LUGIA, + Species.HO_OH, + Species.CELEBI, + Species.TREECKO, + Species.GROVYLE, + Species.SCEPTILE, + Species.TORCHIC, + Species.COMBUSKEN, + Species.BLAZIKEN, + Species.MUDKIP, + Species.MARSHTOMP, + Species.SWAMPERT, + Species.POOCHYENA, + Species.MIGHTYENA, + Species.ZIGZAGOON, + Species.LINOONE, + Species.BEAUTIFLY, + Species.DUSTOX, + Species.LOTAD, + Species.LOMBRE, + Species.LUDICOLO, + Species.SEEDOT, + Species.NUZLEAF, + Species.SHIFTRY, + Species.TAILLOW, + Species.SWELLOW, + Species.WINGULL, + Species.PELIPPER, + Species.RALTS, + Species.KIRLIA, + Species.GARDEVOIR, + Species.SURSKIT, + Species.MASQUERAIN, + Species.SHROOMISH, + Species.BRELOOM, + Species.SLAKOTH, + Species.VIGOROTH, + Species.SLAKING, + Species.NINCADA, + Species.NINJASK, + Species.SHEDINJA, + Species.WHISMUR, + Species.LOUDRED, + Species.EXPLOUD, + Species.MAKUHITA, + Species.HARIYAMA, + Species.AZURILL, + Species.NOSEPASS, + Species.SKITTY, + Species.DELCATTY, + Species.SABLEYE, + Species.MAWILE, + Species.ARON, + Species.LAIRON, + Species.AGGRON, + Species.MEDITITE, + Species.MEDICHAM, + Species.ELECTRIKE, + Species.MANECTRIC, + Species.PLUSLE, + Species.MINUN, + Species.VOLBEAT, + Species.ILLUMISE, + Species.ROSELIA, + Species.GULPIN, + Species.SWALOT, + Species.CARVANHA, + Species.SHARPEDO, + Species.WAILMER, + Species.WAILORD, + Species.NUMEL, + Species.CAMERUPT, + Species.TORKOAL, + Species.SPOINK, + Species.GRUMPIG, + Species.SPINDA, + Species.TRAPINCH, + Species.VIBRAVA, + Species.FLYGON, + Species.CACNEA, + Species.CACTURNE, + Species.SWABLU, + Species.ALTARIA, + Species.ZANGOOSE, + Species.SEVIPER, + Species.LUNATONE, + Species.SOLROCK, + Species.BARBOACH, + Species.WHISCASH, + Species.CORPHISH, + Species.CRAWDAUNT, + Species.BALTOY, + Species.CLAYDOL, + Species.LILEEP, + Species.CRADILY, + Species.ANORITH, + Species.ARMALDO, + Species.FEEBAS, + Species.MILOTIC, + Species.CASTFORM, + Species.KECLEON, + Species.SHUPPET, + Species.BANETTE, + Species.DUSKULL, + Species.DUSCLOPS, + Species.TROPIUS, + Species.CHIMECHO, + Species.ABSOL, + Species.SNORUNT, + Species.GLALIE, + Species.SPHEAL, + Species.SEALEO, + Species.WALREIN, + Species.CLAMPERL, + Species.HUNTAIL, + Species.GOREBYSS, + Species.RELICANTH, + Species.LUVDISC, + Species.BAGON, + Species.SHELGON, + Species.SALAMENCE, + Species.METANG, + Species.METAGROSS, + Species.REGIROCK, + Species.REGICE, + Species.REGISTEEL, + Species.LATIAS, + Species.LATIOS, + Species.KYOGRE, + Species.GROUDON, + Species.RAYQUAZA, + Species.JIRACHI, + Species.DEOXYS, + Species.TURTWIG, + Species.GROTLE, + Species.TORTERRA, + Species.CHIMCHAR, + Species.MONFERNO, + Species.INFERNAPE, + Species.PIPLUP, + Species.PRINPLUP, + Species.EMPOLEON, + Species.STARLY, + Species.STARAVIA, + Species.STARAPTOR, + Species.BIDOOF, + Species.BIBAREL, + Species.KRICKETUNE, + Species.SHINX, + Species.LUXIO, + Species.LUXRAY, + Species.BUDEW, + Species.ROSERADE, + Species.CRANIDOS, + Species.RAMPARDOS, + Species.SHIELDON, + Species.BASTIODON, + Species.WORMADAM, + Species.MOTHIM, + Species.VESPIQUEN, + Species.PACHIRISU, + Species.BUIZEL, + Species.FLOATZEL, + Species.CHERUBI, + Species.CHERRIM, + Species.SHELLOS, + Species.GASTRODON, + Species.AMBIPOM, + Species.DRIFLOON, + Species.DRIFBLIM, + Species.BUNEARY, + Species.LOPUNNY, + Species.MISMAGIUS, + Species.HONCHKROW, + Species.GLAMEOW, + Species.PURUGLY, + Species.CHINGLING, + Species.STUNKY, + Species.SKUNTANK, + Species.BRONZOR, + Species.BRONZONG, + Species.BONSLY, + Species.MIME_JR, + Species.HAPPINY, + Species.CHATOT, + Species.SPIRITOMB, + Species.GIBLE, + Species.GABITE, + Species.GARCHOMP, + Species.MUNCHLAX, + Species.RIOLU, + Species.LUCARIO, + Species.HIPPOPOTAS, + Species.HIPPOWDON, + Species.SKORUPI, + Species.DRAPION, + Species.CROAGUNK, + Species.TOXICROAK, + Species.CARNIVINE, + Species.FINNEON, + Species.LUMINEON, + Species.MANTYKE, + Species.SNOVER, + Species.ABOMASNOW, + Species.WEAVILE, + Species.MAGNEZONE, + Species.LICKILICKY, + Species.RHYPERIOR, + Species.TANGROWTH, + Species.ELECTIVIRE, + Species.MAGMORTAR, + Species.TOGEKISS, + Species.YANMEGA, + Species.LEAFEON, + Species.GLACEON, + Species.GLISCOR, + Species.MAMOSWINE, + Species.PORYGON_Z, + Species.GALLADE, + Species.PROBOPASS, + Species.DUSKNOIR, + Species.FROSLASS, + Species.ROTOM, + Species.UXIE, + Species.MESPRIT, + Species.AZELF, + Species.DIALGA, + Species.PALKIA, + Species.HEATRAN, + Species.REGIGIGAS, + Species.GIRATINA, + Species.CRESSELIA, + Species.PHIONE, + Species.MANAPHY, + Species.DARKRAI, + Species.SHAYMIN, + Species.ARCEUS, + Species.VICTINI, + Species.SNIVY, + Species.SERVINE, + Species.SERPERIOR, + Species.TEPIG, + Species.PIGNITE, + Species.EMBOAR, + Species.OSHAWOTT, + Species.DEWOTT, + Species.SAMUROTT, + Species.PATRAT, + Species.WATCHOG, + Species.LILLIPUP, + Species.HERDIER, + Species.STOUTLAND, + Species.PURRLOIN, + Species.LIEPARD, + Species.PANSAGE, + Species.SIMISAGE, + Species.PANSEAR, + Species.SIMISEAR, + Species.PANPOUR, + Species.SIMIPOUR, + Species.MUNNA, + Species.MUSHARNA, + Species.PIDOVE, + Species.TRANQUILL, + Species.UNFEZANT, + Species.BLITZLE, + Species.ZEBSTRIKA, + Species.ROGGENROLA, + Species.BOLDORE, + Species.GIGALITH, + Species.WOOBAT, + Species.SWOOBAT, + Species.DRILBUR, + Species.EXCADRILL, + Species.AUDINO, + Species.TIMBURR, + Species.GURDURR, + Species.CONKELDURR, + Species.TYMPOLE, + Species.PALPITOAD, + Species.SEISMITOAD, + Species.THROH, + Species.SAWK, + Species.SEWADDLE, + Species.SWADLOON, + Species.LEAVANNY, + Species.VENIPEDE, + Species.WHIRLIPEDE, + Species.SCOLIPEDE, + Species.COTTONEE, + Species.WHIMSICOTT, + Species.PETILIL, + Species.LILLIGANT, + Species.BASCULIN, + Species.SANDILE, + Species.KROKOROK, + Species.KROOKODILE, + Species.DARUMAKA, + Species.DARMANITAN, + Species.MARACTUS, + Species.DWEBBLE, + Species.CRUSTLE, + Species.SCRAGGY, + Species.SCRAFTY, + Species.SIGILYPH, + Species.YAMASK, + Species.COFAGRIGUS, + Species.TIRTOUGA, + Species.CARRACOSTA, + Species.ARCHEN, + Species.ARCHEOPS, + Species.TRUBBISH, + Species.GARBODOR, + Species.ZORUA, + Species.ZOROARK, + Species.MINCCINO, + Species.CINCCINO, + Species.GOTHITA, + Species.GOTHORITA, + Species.GOTHITELLE, + Species.SOLOSIS, + Species.DUOSION, + Species.REUNICLUS, + Species.DUCKLETT, + Species.SWANNA, + Species.VANILLITE, + Species.VANILLISH, + Species.VANILLUXE, + Species.DEERLING, + Species.SAWSBUCK, + Species.EMOLGA, + Species.KARRABLAST, + Species.ESCAVALIER, + Species.FOONGUS, + Species.AMOONGUSS, + Species.FRILLISH, + Species.JELLICENT, + Species.ALOMOMOLA, + Species.JOLTIK, + Species.GALVANTULA, + Species.FERROSEED, + Species.FERROTHORN, + Species.KLINK, + Species.KLANG, + Species.KLINKLANG, + Species.EELEKTRIK, + Species.EELEKTROSS, + Species.ELGYEM, + Species.BEHEEYEM, + Species.LITWICK, + Species.LAMPENT, + Species.CHANDELURE, + Species.AXEW, + Species.FRAXURE, + Species.HAXORUS, + Species.CUBCHOO, + Species.BEARTIC, + Species.CRYOGONAL, + Species.SHELMET, + Species.ACCELGOR, + Species.STUNFISK, + Species.MIENFOO, + Species.MIENSHAO, + Species.DRUDDIGON, + Species.GOLETT, + Species.GOLURK, + Species.PAWNIARD, + Species.BISHARP, + Species.BOUFFALANT, + Species.RUFFLET, + Species.BRAVIARY, + Species.VULLABY, + Species.MANDIBUZZ, + Species.HEATMOR, + Species.DURANT, + Species.DEINO, + Species.ZWEILOUS, + Species.HYDREIGON, + Species.LARVESTA, + Species.VOLCARONA, + Species.COBALION, + Species.TERRAKION, + Species.VIRIZION, + Species.TORNADUS, + Species.THUNDURUS, + Species.RESHIRAM, + Species.ZEKROM, + Species.LANDORUS, + Species.KYUREM, + Species.KELDEO, + Species.MELOETTA, + Species.GENESECT, + Species.CHESPIN, + Species.QUILLADIN, + Species.CHESNAUGHT, + Species.FENNEKIN, + Species.BRAIXEN, + Species.DELPHOX, + Species.FROAKIE, + Species.FROGADIER, + Species.GRENINJA, + Species.BUNNELBY, + Species.DIGGERSBY, + Species.FLETCHLING, + Species.FLETCHINDER, + Species.TALONFLAME, + Species.VIVILLON, + Species.LITLEO, + Species.PYROAR, + Species.FLABEBE, + Species.FLOETTE, + Species.FLORGES, + Species.SKIDDO, + Species.GOGOAT, + Species.PANCHAM, + Species.PANGORO, + Species.FURFROU, + Species.ESPURR, + Species.MEOWSTIC, + Species.HONEDGE, + Species.DOUBLADE, + Species.AEGISLASH, + Species.SPRITZEE, + Species.AROMATISSE, + Species.SWIRLIX, + Species.SLURPUFF, + Species.INKAY, + Species.MALAMAR, + Species.BINACLE, + Species.BARBARACLE, + Species.SKRELP, + Species.DRAGALGE, + Species.CLAUNCHER, + Species.CLAWITZER, + Species.HELIOPTILE, + Species.HELIOLISK, + Species.TYRUNT, + Species.TYRANTRUM, + Species.AMAURA, + Species.AURORUS, + Species.SYLVEON, + Species.HAWLUCHA, + Species.DEDENNE, + Species.CARBINK, + Species.GOOMY, + Species.SLIGGOO, + Species.GOODRA, + Species.KLEFKI, + Species.PHANTUMP, + Species.TREVENANT, + Species.PUMPKABOO, + Species.GOURGEIST, + Species.BERGMITE, + Species.AVALUGG, + Species.NOIBAT, + Species.NOIVERN, + Species.XERNEAS, + Species.YVELTAL, + Species.ZYGARDE, + Species.DIANCIE, + Species.HOOPA, + Species.VOLCANION, + Species.ROWLET, + Species.DARTRIX, + Species.DECIDUEYE, + Species.LITTEN, + Species.TORRACAT, + Species.INCINEROAR, + Species.POPPLIO, + Species.BRIONNE, + Species.PRIMARINA, + Species.PIKIPEK, + Species.TRUMBEAK, + Species.TOUCANNON, + Species.YUNGOOS, + Species.GUMSHOOS, + Species.GRUBBIN, + Species.CHARJABUG, + Species.VIKAVOLT, + Species.CRABRAWLER, + Species.CRABOMINABLE, + Species.ORICORIO, + Species.CUTIEFLY, + Species.RIBOMBEE, + Species.ROCKRUFF, + Species.LYCANROC, + Species.WISHIWASHI, + Species.MAREANIE, + Species.TOXAPEX, + Species.MUDBRAY, + Species.MUDSDALE, + Species.DEWPIDER, + Species.ARAQUANID, + Species.FOMANTIS, + Species.LURANTIS, + Species.MORELULL, + Species.SHIINOTIC, + Species.SALANDIT, + Species.SALAZZLE, + Species.STUFFUL, + Species.BEWEAR, + Species.BOUNSWEET, + Species.STEENEE, + Species.TSAREENA, + Species.COMFEY, + Species.ORANGURU, + Species.PASSIMIAN, + Species.WIMPOD, + Species.GOLISOPOD, + Species.SANDYGAST, + Species.PALOSSAND, + Species.TYPE_NULL, + Species.SILVALLY, + Species.MINIOR, + Species.KOMALA, + Species.TURTONATOR, + Species.TOGEDEMARU, + Species.MIMIKYU, + Species.BRUXISH, + Species.DRAMPA, + Species.DHELMISE, + Species.JANGMO_O, + Species.HAKAMO_O, + Species.KOMMO_O, + Species.TAPU_KOKO, + Species.TAPU_LELE, + Species.TAPU_BULU, + Species.TAPU_FINI, + Species.SOLGALEO, + Species.LUNALA, + Species.NIHILEGO, + Species.BUZZWOLE, + Species.PHEROMOSA, + Species.XURKITREE, + Species.CELESTEELA, + Species.KARTANA, + Species.GUZZLORD, + Species.NECROZMA, + Species.MAGEARNA, + Species.MARSHADOW, + Species.POIPOLE, + Species.NAGANADEL, + Species.STAKATAKA, + Species.BLACEPHALON, + Species.ZERAORA, + Species.MELTAN, + Species.MELMETAL, + Species.GROOKEY, + Species.THWACKEY, + Species.RILLABOOM, + Species.SCORBUNNY, + Species.RABOOT, + Species.CINDERACE, + Species.SOBBLE, + Species.DRIZZILE, + Species.INTELEON, + Species.SKWOVET, + Species.GREEDENT, + Species.ROOKIDEE, + Species.CORVISQUIRE, + Species.CORVIKNIGHT, + Species.DOTTLER, + Species.ORBEETLE, + Species.NICKIT, + Species.THIEVUL, + Species.GOSSIFLEUR, + Species.ELDEGOSS, + Species.WOOLOO, + Species.DUBWOOL, + Species.CHEWTLE, + Species.DREDNAW, + Species.YAMPER, + Species.BOLTUND, + Species.ROLYCOLY, + Species.CARKOL, + Species.COALOSSAL, + Species.FLAPPLE, + Species.APPLETUN, + Species.SILICOBRA, + Species.SANDACONDA, + Species.CRAMORANT, + Species.ARROKUDA, + Species.BARRASKEWDA, + Species.TOXEL, + Species.TOXTRICITY, + Species.SIZZLIPEDE, + Species.CENTISKORCH, + Species.CLOBBOPUS, + Species.GRAPPLOCT, + Species.SINISTEA, + Species.POLTEAGEIST, + Species.HATENNA, + Species.HATTREM, + Species.HATTERENE, + Species.IMPIDIMP, + Species.MORGREM, + Species.GRIMMSNARL, + Species.OBSTAGOON, + Species.PERRSERKER, + Species.CURSOLA, + Species.SIRFETCHD, + Species.MR_RIME, + Species.RUNERIGUS, + Species.MILCERY, + Species.ALCREMIE, + Species.FALINKS, + Species.PINCURCHIN, + Species.SNOM, + Species.FROSMOTH, + Species.STONJOURNER, + Species.EISCUE, + Species.INDEEDEE, + Species.MORPEKO, + Species.CUFANT, + Species.COPPERAJAH, + Species.DRACOZOLT, + Species.ARCTOZOLT, + Species.DRACOVISH, + Species.ARCTOVISH, + Species.DURALUDON, + Species.DREEPY, + Species.DRAKLOAK, + Species.DRAGAPULT, + Species.ZACIAN, + Species.ZAMAZENTA, + Species.ETERNATUS, + Species.KUBFU, + Species.URSHIFU, + Species.ZARUDE, + Species.REGIELEKI, + Species.REGIDRAGO, + Species.GLASTRIER, + Species.SPECTRIER, + Species.CALYREX, + Species.WYRDEER, + Species.KLEAVOR, + Species.URSALUNA, + Species.BASCULEGION, + Species.SNEASLER, + Species.OVERQWIL, + Species.ENAMORUS, + Species.SPRIGATITO, + Species.FLORAGATO, + Species.MEOWSCARADA, + Species.FUECOCO, + Species.CROCALOR, + Species.SKELEDIRGE, + Species.QUAXLY, + Species.QUAXWELL, + Species.QUAQUAVAL, + Species.LECHONK, + Species.OINKOLOGNE, + Species.TAROUNTULA, + Species.SPIDOPS, + Species.NYMBLE, + Species.LOKIX, + Species.PAWMI, + Species.PAWMO, + Species.PAWMOT, + Species.TANDEMAUS, + Species.MAUSHOLD, + Species.FIDOUGH, + Species.DACHSBUN, + Species.SMOLIV, + Species.DOLLIV, + Species.ARBOLIVA, + Species.SQUAWKABILLY, + Species.NACLI, + Species.NACLSTACK, + Species.GARGANACL, + Species.CHARCADET, + Species.ARMAROUGE, + Species.CERULEDGE, + Species.TADBULB, + Species.BELLIBOLT, + Species.WATTREL, + Species.KILOWATTREL, + Species.MASCHIFF, + Species.MABOSSTIFF, + Species.SHROODLE, + Species.GRAFAIAI, + Species.BRAMBLIN, + Species.BRAMBLEGHAST, + Species.TOEDSCOOL, + Species.TOEDSCRUEL, + Species.KLAWF, + Species.CAPSAKID, + Species.SCOVILLAIN, + Species.RELLOR, + Species.RABSCA, + Species.FLITTLE, + Species.ESPATHRA, + Species.TINKATINK, + Species.TINKATUFF, + Species.TINKATON, + Species.WIGLETT, + Species.WUGTRIO, + Species.BOMBIRDIER, + Species.FINIZEN, + Species.PALAFIN, + Species.VAROOM, + Species.REVAVROOM, + Species.CYCLIZAR, + Species.ORTHWORM, + Species.GLIMMET, + Species.GLIMMORA, + Species.GREAVARD, + Species.HOUNDSTONE, + Species.FLAMIGO, + Species.CETODDLE, + Species.CETITAN, + Species.VELUZA, + Species.DONDOZO, + Species.TATSUGIRI, + Species.ANNIHILAPE, + Species.CLODSIRE, + Species.FARIGIRAF, + Species.DUDUNSPARCE, + Species.KINGAMBIT, + Species.GREAT_TUSK, + Species.SCREAM_TAIL, + Species.BRUTE_BONNET, + Species.FLUTTER_MANE, + Species.SLITHER_WING, + Species.SANDY_SHOCKS, + Species.IRON_TREADS, + Species.IRON_BUNDLE, + Species.IRON_HANDS, + Species.IRON_JUGULIS, + Species.IRON_MOTH, + Species.IRON_THORNS, + Species.FRIGIBAX, + Species.ARCTIBAX, + Species.BAXCALIBUR, + Species.GIMMIGHOUL, + Species.GHOLDENGO, + Species.WO_CHIEN, + Species.CHIEN_PAO, + Species.TING_LU, + Species.CHI_YU, + Species.ROARING_MOON, + Species.IRON_VALIANT, + Species.KORAIDON, + Species.MIRAIDON, + Species.WALKING_WAKE, + Species.IRON_LEAVES, + Species.DIPPLIN, + Species.POLTCHAGEIST, + Species.SINISTCHA, + Species.OKIDOGI, + Species.MUNKIDORI, + Species.FEZANDIPITI, + Species.OGERPON, + Species.ARCHALUDON, + Species.HYDRAPPLE, + Species.GOUGING_FIRE, + Species.RAGING_BOLT, + Species.IRON_BOULDER, + Species.IRON_CROWN, + Species.TERAPAGOS, + Species.PECHARUNT, + Species.ALOLA_RATTATA, + Species.ALOLA_RATICATE, + Species.ALOLA_RAICHU, + Species.ALOLA_SANDSHREW, + Species.ALOLA_SANDSLASH, + Species.ALOLA_VULPIX, + Species.ALOLA_NINETALES, + Species.ALOLA_DIGLETT, + Species.ALOLA_DUGTRIO, + Species.ALOLA_MEOWTH, + Species.ALOLA_PERSIAN, + Species.ALOLA_GEODUDE, + Species.ALOLA_GRAVELER, + Species.ALOLA_GOLEM, + Species.ALOLA_GRIMER, + Species.ALOLA_MUK, + Species.ALOLA_EXEGGUTOR, + Species.ALOLA_MAROWAK, + Species.ETERNAL_FLOETTE, + Species.GALAR_MEOWTH, + Species.GALAR_PONYTA, + Species.GALAR_RAPIDASH, + Species.GALAR_SLOWPOKE, + Species.GALAR_SLOWBRO, + Species.GALAR_FARFETCHD, + Species.GALAR_WEEZING, + Species.GALAR_MR_MIME, + Species.GALAR_ARTICUNO, + Species.GALAR_ZAPDOS, + Species.GALAR_MOLTRES, + Species.GALAR_SLOWKING, + Species.GALAR_CORSOLA, + Species.GALAR_ZIGZAGOON, + Species.GALAR_LINOONE, + Species.GALAR_DARUMAKA, + Species.GALAR_DARMANITAN, + Species.GALAR_YAMASK, + Species.GALAR_STUNFISK, + Species.HISUI_GROWLITHE, + Species.HISUI_ARCANINE, + Species.HISUI_VOLTORB, + Species.HISUI_ELECTRODE, + Species.HISUI_TYPHLOSION, + Species.HISUI_QWILFISH, + Species.HISUI_SNEASEL, + Species.HISUI_SAMUROTT, + Species.HISUI_LILLIGANT, + Species.HISUI_ZORUA, + Species.HISUI_ZOROARK, + Species.HISUI_BRAVIARY, + Species.HISUI_SLIGGOO, + Species.HISUI_GOODRA, + Species.HISUI_AVALUGG, + Species.HISUI_DECIDUEYE, + Species.PALDEA_TAUROS, + Species.PALDEA_WOOPER, + Species.BLOODMOON_URSALUNA, + ], [Moves.DIVE]: [ Species.SQUIRTLE, Species.WARTORTLE, @@ -41805,7 +42683,6 @@ export const tmSpecies: TmSpecies = { [ Species.WORMADAM, "sandy", - "trash", ], Species.ALOLA_SANDSHREW, Species.ALOLA_SANDSLASH, @@ -43701,12 +44578,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.BUNNELBY, Species.DIGGERSBY, Species.SKIDDO, @@ -44160,14 +45032,7 @@ export const tmSpecies: TmSpecies = { Species.QUILLADIN, Species.CHESNAUGHT, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -44377,14 +45242,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.VIVILLON, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.ESPURR, Species.MEOWSTIC, @@ -45256,6 +46114,10 @@ export const tmSpecies: TmSpecies = { Species.IRON_CROWN, Species.TERAPAGOS, Species.ALOLA_EXEGGUTOR, + [ + Species.INDEEDEE, + "male", + ], ], [Moves.GYRO_BALL]: [ Species.SQUIRTLE, @@ -47501,12 +48363,7 @@ export const tmSpecies: TmSpecies = { Species.ACCELGOR, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.SKRELP, Species.DRAGALGE, Species.MAREANIE, @@ -48143,7 +49000,6 @@ export const tmSpecies: TmSpecies = { Species.RUNERIGUS, Species.MORPEKO, Species.DURALUDON, - Species.URSHIFU, Species.ZARUDE, Species.SPECTRIER, Species.OVERQWIL, @@ -48179,6 +49035,10 @@ export const tmSpecies: TmSpecies = { Species.GALAR_WEEZING, Species.GALAR_MOLTRES, Species.GALAR_YAMASK, + [ + Species.URSHIFU, + "single-strike", + ], [ Species.CALYREX, "shadow", @@ -48456,14 +49316,7 @@ export const tmSpecies: TmSpecies = { Species.QUILLADIN, Species.CHESNAUGHT, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -49622,7 +50475,10 @@ export const tmSpecies: TmSpecies = { Species.TORTERRA, Species.BUDEW, Species.ROSERADE, - Species.WORMADAM, + [ + Species.WORMADAM, + "plant", + ], Species.MOTHIM, Species.CHERUBI, Species.CHERRIM, @@ -49698,14 +50554,7 @@ export const tmSpecies: TmSpecies = { Species.CHESNAUGHT, Species.VIVILLON, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -52635,7 +53484,10 @@ export const tmSpecies: TmSpecies = { Species.TORTERRA, Species.BUDEW, Species.ROSERADE, - Species.WORMADAM, + [ + Species.WORMADAM, + "plant", + ], Species.SNOVER, Species.ABOMASNOW, Species.TANGROWTH, @@ -53751,7 +54603,10 @@ export const tmSpecies: TmSpecies = { Species.BIBAREL, Species.BUDEW, Species.ROSERADE, - Species.WORMADAM, + [ + Species.WORMADAM, + "plant", + ], Species.PACHIRISU, Species.CHERUBI, Species.CHERRIM, @@ -53863,14 +54718,7 @@ export const tmSpecies: TmSpecies = { Species.BUNNELBY, Species.DIGGERSBY, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -55590,12 +56438,7 @@ export const tmSpecies: TmSpecies = { Species.CHESPIN, Species.QUILLADIN, Species.CHESNAUGHT, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.PANCHAM, Species.PANGORO, Species.HELIOPTILE, @@ -55877,7 +56720,6 @@ export const tmSpecies: TmSpecies = { Species.MR_RIME, Species.MORPEKO, Species.DURALUDON, - Species.URSHIFU, Species.SPECTRIER, Species.MEOWSCARADA, Species.SQUAWKABILLY, @@ -55918,6 +56760,10 @@ export const tmSpecies: TmSpecies = { Species.GALAR_MOLTRES, Species.GALAR_SLOWKING, Species.GALAR_STUNFISK, + [ + Species.URSHIFU, + "single-strike", + ], [ Species.CALYREX, "shadow", @@ -56577,14 +57423,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -57019,14 +57858,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.PANCHAM, Species.PANGORO, @@ -57354,14 +58186,7 @@ export const tmSpecies: TmSpecies = { Species.BRAIXEN, Species.DELPHOX, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.ESPURR, Species.MEOWSTIC, @@ -58997,7 +59822,6 @@ export const tmSpecies: TmSpecies = { [ Species.WORMADAM, "sandy", - "trash", ], Species.ALOLA_SANDSHREW, Species.ALOLA_SANDSLASH, @@ -59768,26 +60592,6 @@ export const tmSpecies: TmSpecies = { Species.HISUI_SAMUROTT, Species.PALDEA_TAUROS, ], - [Moves.SACRED_SWORD]: [ - Species.GALLADE, - Species.OSHAWOTT, - Species.DEWOTT, - Species.SAMUROTT, - Species.COBALION, - Species.TERRAKION, - Species.VIRIZION, - Species.KELDEO, - Species.HONEDGE, - Species.DOUBLADE, - Species.AEGISLASH, - Species.KARTANA, - Species.ZACIAN, - Species.CHIEN_PAO, - Species.IRON_LEAVES, - Species.IRON_BOULDER, - Species.IRON_CROWN, - Species.HISUI_SAMUROTT, - ], [Moves.RAZOR_SHELL]: [ Species.SLOWBRO, Species.SHELLDER, @@ -60070,7 +60874,6 @@ export const tmSpecies: TmSpecies = { Species.DURALUDON, Species.ZACIAN, Species.ZAMAZENTA, - Species.URSHIFU, Species.ZARUDE, Species.GLASTRIER, Species.SPECTRIER, @@ -60116,6 +60919,10 @@ export const tmSpecies: TmSpecies = { Species.HISUI_ZOROARK, Species.HISUI_BRAVIARY, Species.BLOODMOON_URSALUNA, + [ + Species.URSHIFU, + "single-strike", + ], ], [Moves.PHANTOM_FORCE]: [ Species.HAUNTER, @@ -60446,14 +61253,7 @@ export const tmSpecies: TmSpecies = { Species.QUILLADIN, Species.CHESNAUGHT, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -60529,16 +61329,12 @@ export const tmSpecies: TmSpecies = { Species.WHIMSICOTT, Species.ALOMOMOLA, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, - Species.MEOWSTIC, + [ + Species.MEOWSTIC, + "male", + ], Species.SPRITZEE, Species.AROMATISSE, Species.SYLVEON, @@ -61402,14 +62198,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -61899,14 +62688,7 @@ export const tmSpecies: TmSpecies = { Species.MELOETTA, Species.DELPHOX, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SPRITZEE, Species.AROMATISSE, @@ -62617,7 +63399,6 @@ export const tmSpecies: TmSpecies = { Species.SIRFETCHD, Species.FALINKS, Species.PINCURCHIN, - Species.URSHIFU, Species.ZARUDE, Species.GLASTRIER, Species.TAROUNTULA, @@ -62647,6 +63428,10 @@ export const tmSpecies: TmSpecies = { Species.GALAR_ZAPDOS, Species.GALAR_CORSOLA, Species.GALAR_LINOONE, + [ + Species.URSHIFU, + "single-strike", + ], [ Species.CALYREX, "ice", @@ -63541,12 +64326,7 @@ export const tmSpecies: TmSpecies = { Species.KELDEO, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.INKAY, Species.MALAMAR, Species.BINACLE, @@ -64755,7 +65535,6 @@ export const tmSpecies: TmSpecies = { Species.OBSTAGOON, Species.PERRSERKER, Species.MORPEKO, - Species.URSHIFU, Species.ZARUDE, Species.GLASTRIER, Species.SPECTRIER, @@ -64803,6 +65582,10 @@ export const tmSpecies: TmSpecies = { Species.GALAR_LINOONE, Species.GALAR_DARMANITAN, Species.GALAR_STUNFISK, + [ + Species.URSHIFU, + "single-strike", + ], [ Species.CALYREX, "ice", @@ -65933,12 +66716,7 @@ export const tmSpecies: TmSpecies = { Species.DELPHOX, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.BUNNELBY, Species.DIGGERSBY, Species.FLETCHLING, @@ -65950,14 +66728,7 @@ export const tmSpecies: TmSpecies = { Species.LITLEO, Species.PYROAR, Species.FLABEBE, - [ - Species.FLOETTE, - "red", - "yellow", - "orange", - "blue", - "white", - ], + Species.FLOETTE, Species.FLORGES, Species.SKIDDO, Species.GOGOAT, @@ -66291,6 +67062,13 @@ export const tmSpecies: TmSpecies = { Species.MUNKIDORI, Species.FEZANDIPITI, Species.OGERPON, + Species.ARCHALUDON, + Species.HYDRAPPLE, + Species.GOUGING_FIRE, + Species.RAGING_BOLT, + Species.IRON_BOULDER, + Species.IRON_CROWN, + Species.PECHARUNT, Species.GALAR_MEOWTH, Species.GALAR_SLOWPOKE, Species.GALAR_SLOWBRO, @@ -66429,16 +67207,8 @@ export const tmSpecies: TmSpecies = { Species.PIPLUP, Species.PRINPLUP, Species.EMPOLEON, - [ - Species.SHELLOS, - "east", - "west", - ], - [ - Species.GASTRODON, - "east", - "west", - ], + Species.SHELLOS, + Species.GASTRODON, Species.MISMAGIUS, Species.HAPPINY, Species.SNOVER, @@ -66456,25 +67226,11 @@ export const tmSpecies: TmSpecies = { Species.CUBCHOO, Species.BEARTIC, Species.CRYOGONAL, - [ - Species.TORNADUS, - "incarnate", - "therian", - ], - [ - Species.KYUREM, - "", - "black", - "white", - ], + Species.TORNADUS, + Species.KYUREM, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.SKRELP, Species.DRAGALGE, Species.BERGMITE, @@ -66482,11 +67238,7 @@ export const tmSpecies: TmSpecies = { Species.DIANCIE, Species.PRIMARINA, Species.CRABOMINABLE, - [ - Species.MAGEARNA, - "", - "original", - ], + Species.MAGEARNA, Species.INTELEON, Species.FROSMOTH, Species.EISCUE, @@ -66779,12 +67531,7 @@ export const tmSpecies: TmSpecies = { Species.CHESNAUGHT, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.LITLEO, Species.PYROAR, Species.FLABEBE, @@ -67007,23 +67754,14 @@ export const tmSpecies: TmSpecies = { Species.WEAVILE, Species.GLACEON, Species.FROSLASS, - [ - Species.PALKIA, - "", - "origin", - ], + Species.PALKIA, Species.PHIONE, Species.MANAPHY, Species.ARCEUS, Species.OSHAWOTT, Species.DEWOTT, Species.SAMUROTT, - [ - Species.BASCULIN, - "red-striped", - "blue-striped", - "white-striped", - ], + Species.BASCULIN, Species.MINCCINO, Species.CINCCINO, Species.DUCKLETT, @@ -67036,12 +67774,7 @@ export const tmSpecies: TmSpecies = { Species.KELDEO, Species.FROAKIE, Species.FROGADIER, - [ - Species.GRENINJA, - "", - "battle-bond", - "ash", - ], + Species.GRENINJA, Species.FLABEBE, Species.FLOETTE, Species.FLORGES, @@ -67304,6 +68037,10 @@ export const tmSpecies: TmSpecies = { Species.FEZANDIPITI, Species.ALOLA_RAICHU, Species.ETERNAL_FLOETTE, + [ + Species.INDEEDEE, + "female", + ], ], [Moves.TEMPER_FLARE]: [ Species.CHARMANDER, @@ -67695,6 +68432,7 @@ export const tmPoolTiers: TmPoolTiers = { [Moves.ENDEAVOR]: ModifierTier.COMMON, [Moves.SKILL_SWAP]: ModifierTier.COMMON, [Moves.IMPRISON]: ModifierTier.COMMON, + [Moves.SECRET_POWER]: ModifierTier.COMMON, [Moves.DIVE]: ModifierTier.GREAT, [Moves.FEATHER_DANCE]: ModifierTier.COMMON, [Moves.BLAZE_KICK]: ModifierTier.GREAT, @@ -67823,7 +68561,6 @@ export const tmPoolTiers: TmPoolTiers = { [Moves.ELECTROWEB]: ModifierTier.GREAT, [Moves.WILD_CHARGE]: ModifierTier.GREAT, [Moves.DRILL_RUN]: ModifierTier.GREAT, - [Moves.SACRED_SWORD]: ModifierTier.ULTRA, [Moves.RAZOR_SHELL]: ModifierTier.GREAT, [Moves.HEAT_CRASH]: ModifierTier.GREAT, [Moves.TAIL_SLAP]: ModifierTier.GREAT, diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index 62ef8112e6c..37900a3ab5a 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -1,6 +1,6 @@ //import { battleAnimRawData } from "./battle-anim-raw-data"; import BattleScene from "../battle-scene"; -import { AttackMove, BeakBlastHeaderAttr, ChargeAttr, DelayedAttackAttr, MoveFlags, SelfStatusMove, allMoves } from "./move"; +import { AttackMove, BeakBlastHeaderAttr, DelayedAttackAttr, MoveFlags, SelfStatusMove, allMoves } from "./move"; import Pokemon from "../field/pokemon"; import * as Utils from "../utils"; import { BattlerIndex } from "../battle"; @@ -134,15 +134,15 @@ export class AnimConfig { for (const te of frameTimedEvents[fte]) { let timedEvent: AnimTimedEvent | undefined; switch (te.eventType) { - case "AnimTimedSoundEvent": - timedEvent = new AnimTimedSoundEvent(te.frameIndex, te.resourceName, te); - break; - case "AnimTimedAddBgEvent": - timedEvent = new AnimTimedAddBgEvent(te.frameIndex, te.resourceName, te); - break; - case "AnimTimedUpdateBgEvent": - timedEvent = new AnimTimedUpdateBgEvent(te.frameIndex, te.resourceName, te); - break; + case "AnimTimedSoundEvent": + timedEvent = new AnimTimedSoundEvent(te.frameIndex, te.resourceName, te); + break; + case "AnimTimedAddBgEvent": + timedEvent = new AnimTimedAddBgEvent(te.frameIndex, te.resourceName, te); + break; + case "AnimTimedUpdateBgEvent": + timedEvent = new AnimTimedUpdateBgEvent(te.frameIndex, te.resourceName, te); + break; } timedEvent && timedEvents.push(timedEvent); @@ -243,12 +243,12 @@ class AnimFrame { if (!init) { let target = AnimFrameTarget.GRAPHIC; switch (pattern) { - case -2: - target = AnimFrameTarget.TARGET; - break; - case -1: - target = AnimFrameTarget.USER; - break; + case -2: + target = AnimFrameTarget.TARGET; + break; + case -1: + target = AnimFrameTarget.USER; + break; } this.target = target; this.graphicFrame = pattern >= 0 ? pattern : 0; @@ -476,8 +476,11 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise { } else { const loadedCheckTimer = setInterval(() => { if (moveAnims.get(move) !== null) { - const chargeAttr = allMoves[move].getAttrs(ChargeAttr)[0] || allMoves[move].getAttrs(DelayedAttackAttr)[0]; - if (chargeAttr && chargeAnims.get(chargeAttr.chargeAnim) === null) { + const chargeAnimSource = (allMoves[move].isChargingMove()) + ? allMoves[move] + : (allMoves[move].getAttrs(DelayedAttackAttr)[0] + ?? allMoves[move].getAttrs(BeakBlastHeaderAttr)[0]); + if (chargeAnimSource && chargeAnims.get(chargeAnimSource.chargeAnim) === null) { return; } clearInterval(loadedCheckTimer); @@ -507,11 +510,12 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise { } else { populateMoveAnim(move, ba); } - const chargeAttr = allMoves[move].getAttrs(ChargeAttr)[0] - || allMoves[move].getAttrs(DelayedAttackAttr)[0] - || allMoves[move].getAttrs(BeakBlastHeaderAttr)[0]; - if (chargeAttr) { - initMoveChargeAnim(scene, chargeAttr.chargeAnim).then(() => resolve()); + const chargeAnimSource = (allMoves[move].isChargingMove()) + ? allMoves[move] + : (allMoves[move].getAttrs(DelayedAttackAttr)[0] + ?? allMoves[move].getAttrs(BeakBlastHeaderAttr)[0]); + if (chargeAnimSource) { + initMoveChargeAnim(scene, chargeAnimSource.chargeAnim).then(() => resolve()); } else { resolve(); } @@ -556,7 +560,7 @@ function logMissingMoveAnim(move: Moves, ...optionalParams: any[]) { * @param encounterAnim one or more animations to fetch */ export async function initEncounterAnims(scene: BattleScene, encounterAnim: EncounterAnim | EncounterAnim[]): Promise { - const anims = Array.isArray(encounterAnim) ? encounterAnim : [encounterAnim]; + const anims = Array.isArray(encounterAnim) ? encounterAnim : [ encounterAnim ]; const encounterAnimNames = Utils.getEnumKeys(EncounterAnim); const encounterAnimFetches: Promise>[] = []; for (const anim of anims) { @@ -638,11 +642,12 @@ export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLo return new Promise(resolve => { const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat(); for (const moveId of moveIds) { - const chargeAttr = allMoves[moveId].getAttrs(ChargeAttr)[0] - || allMoves[moveId].getAttrs(DelayedAttackAttr)[0] - || allMoves[moveId].getAttrs(BeakBlastHeaderAttr)[0]; - if (chargeAttr) { - const moveChargeAnims = chargeAnims.get(chargeAttr.chargeAnim); + const chargeAnimSource = (allMoves[moveId].isChargingMove()) + ? allMoves[moveId] + : (allMoves[moveId].getAttrs(DelayedAttackAttr)[0] + ?? allMoves[moveId].getAttrs(BeakBlastHeaderAttr)[0]); + if (chargeAnimSource) { + const moveChargeAnims = chargeAnims.get(chargeAnimSource.chargeAnim); moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims![0]); // TODO: is the bang correct? if (Array.isArray(moveChargeAnims)) { moveAnimations.push(moveChargeAnims[1]); @@ -774,9 +779,9 @@ export abstract class BattleAnim { private getGraphicFrameData(scene: BattleScene, frames: AnimFrame[], onSubstitute?: boolean): Map> { const ret: Map> = new Map([ - [AnimFrameTarget.GRAPHIC, new Map() ], - [AnimFrameTarget.USER, new Map() ], - [AnimFrameTarget.TARGET, new Map() ] + [ AnimFrameTarget.GRAPHIC, new Map() ], + [ AnimFrameTarget.USER, new Map() ], + [ AnimFrameTarget.TARGET, new Map() ] ]); const isOppAnim = this.isOppAnim(); @@ -803,23 +808,23 @@ export abstract class BattleAnim { let scaleX = (frame.zoomX / 100) * (!frame.mirror ? 1 : -1); const scaleY = (frame.zoomY / 100); switch (frame.focus) { - case AnimFocus.TARGET: - x += targetInitialX - targetFocusX; - y += (targetInitialY - targetHalfHeight) - targetFocusY; - break; - case AnimFocus.USER: - x += userInitialX - userFocusX; - y += (userInitialY - userHalfHeight) - userFocusY; - break; - case AnimFocus.USER_TARGET: - const point = transformPoint(this.srcLine[0], this.srcLine[1], this.srcLine[2], this.srcLine[3], - this.dstLine[0], this.dstLine[1] - userHalfHeight, this.dstLine[2], this.dstLine[3] - targetHalfHeight, x, y); - x = point[0]; - y = point[1]; - if (frame.target === AnimFrameTarget.GRAPHIC && isReversed(this.srcLine[0], this.srcLine[2], this.dstLine[0], this.dstLine[2])) { - scaleX = scaleX * -1; - } - break; + case AnimFocus.TARGET: + x += targetInitialX - targetFocusX; + y += (targetInitialY - targetHalfHeight) - targetFocusY; + break; + case AnimFocus.USER: + x += userInitialX - userFocusX; + y += (userInitialY - userHalfHeight) - userFocusY; + break; + case AnimFocus.USER_TARGET: + const point = transformPoint(this.srcLine[0], this.srcLine[1], this.srcLine[2], this.srcLine[3], + this.dstLine[0], this.dstLine[1] - userHalfHeight, this.dstLine[2], this.dstLine[3] - targetHalfHeight, x, y); + x = point[0]; + y = point[1]; + if (frame.target === AnimFrameTarget.GRAPHIC && isReversed(this.srcLine[0], this.srcLine[2], this.dstLine[0], this.dstLine[2])) { + scaleX = scaleX * -1; + } + break; } const angle = -frame.angle; const key = frame.target === AnimFrameTarget.GRAPHIC ? g++ : frame.target === AnimFrameTarget.USER ? u++ : t++; @@ -993,44 +998,44 @@ export abstract class BattleAnim { spritePriorities[graphicIndex] = frame.priority; const setSpritePriority = (priority: integer) => { switch (priority) { - case 0: - scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, scene.getNonSwitchedEnemyPokemon() || scene.getNonSwitchedPlayerPokemon()!); // This bang assumes that if (the EnemyPokemon is undefined, then the PlayerPokemon function must return an object), correct assumption? - break; - case 1: - scene.field.moveTo(moveSprite, scene.field.getAll().length - 1); - break; - case 2: - switch (frame.focus) { - case AnimFocus.USER: - if (this.bgSprite) { - scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.bgSprite); - } else { - scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.user!); // TODO: is this bang correct? + case 0: + scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, scene.getNonSwitchedEnemyPokemon() || scene.getNonSwitchedPlayerPokemon()!); // This bang assumes that if (the EnemyPokemon is undefined, then the PlayerPokemon function must return an object), correct assumption? + break; + case 1: + scene.field.moveTo(moveSprite, scene.field.getAll().length - 1); + break; + case 2: + switch (frame.focus) { + case AnimFocus.USER: + if (this.bgSprite) { + scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.bgSprite); + } else { + scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.user!); // TODO: is this bang correct? + } + break; + case AnimFocus.TARGET: + scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.target!); // TODO: is this bang correct? + break; + default: + setSpritePriority(1); + break; } break; - case AnimFocus.TARGET: - scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.target!); // TODO: is this bang correct? + case 3: + switch (frame.focus) { + case AnimFocus.USER: + scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.user!); // TODO: is this bang correct? + break; + case AnimFocus.TARGET: + scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.target!); // TODO: is this bang correct? + break; + default: + setSpritePriority(1); + break; + } break; default: setSpritePriority(1); - break; - } - break; - case 3: - switch (frame.focus) { - case AnimFocus.USER: - scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.user!); // TODO: is this bang correct? - break; - case AnimFocus.TARGET: - scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.target!); // TODO: is this bang correct? - break; - default: - setSpritePriority(1); - break; - } - break; - default: - setSpritePriority(1); } }; setSpritePriority(frame.priority); @@ -1093,9 +1098,9 @@ export abstract class BattleAnim { private getGraphicFrameDataWithoutTarget(frames: AnimFrame[], targetInitialX: number, targetInitialY: number): Map> { const ret: Map> = new Map([ - [AnimFrameTarget.GRAPHIC, new Map() ], - [AnimFrameTarget.USER, new Map() ], - [AnimFrameTarget.TARGET, new Map() ] + [ AnimFrameTarget.GRAPHIC, new Map() ], + [ AnimFrameTarget.USER, new Map() ], + [ AnimFrameTarget.TARGET, new Map() ] ]); let g = 0; @@ -1396,108 +1401,108 @@ export async function populateAnims() { const fieldName = field.slice(0, field.indexOf(":")); const fieldData = field.slice(fieldName.length + 1, field.lastIndexOf("\n")).trim(); switch (fieldName) { - case "array": - const framesData = fieldData.split(" - - - ").slice(1); - for (let fd = 0; fd < framesData.length; fd++) { - anim.frames.push([]); - const frameData = framesData[fd]; - const focusFramesData = frameData.split(" - - "); - for (let tf = 0; tf < focusFramesData.length; tf++) { - const values = focusFramesData[tf].replace(/ \- /g, "").split("\n"); - const targetFrame = new AnimFrame(parseFloat(values[0]), parseFloat(values[1]), parseFloat(values[2]), parseFloat(values[11]), parseFloat(values[3]), - parseInt(values[4]) === 1, parseInt(values[6]) === 1, parseInt(values[5]), parseInt(values[7]), parseInt(values[8]), parseInt(values[12]), parseInt(values[13]), - parseInt(values[14]), parseInt(values[15]), parseInt(values[16]), parseInt(values[17]), parseInt(values[18]), parseInt(values[19]), - parseInt(values[21]), parseInt(values[22]), parseInt(values[23]), parseInt(values[24]), parseInt(values[20]) === 1, parseInt(values[25]), parseInt(values[26]) as AnimFocus); - anim.frames[fd].push(targetFrame); + case "array": + const framesData = fieldData.split(" - - - ").slice(1); + for (let fd = 0; fd < framesData.length; fd++) { + anim.frames.push([]); + const frameData = framesData[fd]; + const focusFramesData = frameData.split(" - - "); + for (let tf = 0; tf < focusFramesData.length; tf++) { + const values = focusFramesData[tf].replace(/ \- /g, "").split("\n"); + const targetFrame = new AnimFrame(parseFloat(values[0]), parseFloat(values[1]), parseFloat(values[2]), parseFloat(values[11]), parseFloat(values[3]), + parseInt(values[4]) === 1, parseInt(values[6]) === 1, parseInt(values[5]), parseInt(values[7]), parseInt(values[8]), parseInt(values[12]), parseInt(values[13]), + parseInt(values[14]), parseInt(values[15]), parseInt(values[16]), parseInt(values[17]), parseInt(values[18]), parseInt(values[19]), + parseInt(values[21]), parseInt(values[22]), parseInt(values[23]), parseInt(values[24]), parseInt(values[20]) === 1, parseInt(values[25]), parseInt(values[26]) as AnimFocus); + anim.frames[fd].push(targetFrame); + } } - } - break; - case "graphic": - const graphic = fieldData !== "''" ? fieldData : ""; - anim.graphic = graphic.indexOf(".") > -1 - ? graphic.slice(0, fieldData.indexOf(".")) - : graphic; - break; - case "timing": - const timingEntries = fieldData.split("- !ruby/object:PBAnimTiming ").slice(1); - for (let t = 0; t < timingEntries.length; t++) { - const timingData = timingEntries[t].replace(/\n/g, " ").replace(/[ ]{2,}/g, " ").replace(/[a-z]+: ! '', /ig, "").replace(/name: (.*?),/, "name: \"$1\",") - .replace(/flashColor: !ruby\/object:Color { alpha: ([\d\.]+), blue: ([\d\.]+), green: ([\d\.]+), red: ([\d\.]+)}/, "flashRed: $4, flashGreen: $3, flashBlue: $2, flashAlpha: $1"); - const frameIndex = parseInt(/frame: (\d+)/.exec(timingData)![1]); // TODO: is the bang correct? - let resourceName = /name: "(.*?)"/.exec(timingData)![1].replace("''", ""); // TODO: is the bang correct? - const timingType = parseInt(/timingType: (\d)/.exec(timingData)![1]); // TODO: is the bang correct? - let timedEvent: AnimTimedEvent | undefined; - switch (timingType) { - case 0: - if (resourceName && resourceName.indexOf(".") === -1) { - let ext: string | undefined; - [ "wav", "mp3", "m4a" ].every(e => { - if (seNames.indexOf(`${resourceName}.${e}`) > -1) { - ext = e; - return false; + break; + case "graphic": + const graphic = fieldData !== "''" ? fieldData : ""; + anim.graphic = graphic.indexOf(".") > -1 + ? graphic.slice(0, fieldData.indexOf(".")) + : graphic; + break; + case "timing": + const timingEntries = fieldData.split("- !ruby/object:PBAnimTiming ").slice(1); + for (let t = 0; t < timingEntries.length; t++) { + const timingData = timingEntries[t].replace(/\n/g, " ").replace(/[ ]{2,}/g, " ").replace(/[a-z]+: ! '', /ig, "").replace(/name: (.*?),/, "name: \"$1\",") + .replace(/flashColor: !ruby\/object:Color { alpha: ([\d\.]+), blue: ([\d\.]+), green: ([\d\.]+), red: ([\d\.]+)}/, "flashRed: $4, flashGreen: $3, flashBlue: $2, flashAlpha: $1"); + const frameIndex = parseInt(/frame: (\d+)/.exec(timingData)![1]); // TODO: is the bang correct? + let resourceName = /name: "(.*?)"/.exec(timingData)![1].replace("''", ""); // TODO: is the bang correct? + const timingType = parseInt(/timingType: (\d)/.exec(timingData)![1]); // TODO: is the bang correct? + let timedEvent: AnimTimedEvent | undefined; + switch (timingType) { + case 0: + if (resourceName && resourceName.indexOf(".") === -1) { + let ext: string | undefined; + [ "wav", "mp3", "m4a" ].every(e => { + if (seNames.indexOf(`${resourceName}.${e}`) > -1) { + ext = e; + return false; + } + return true; + }); + if (!ext) { + ext = ".wav"; + } + resourceName += `.${ext}`; } - return true; - }); - if (!ext) { - ext = ".wav"; + timedEvent = new AnimTimedSoundEvent(frameIndex, resourceName); + break; + case 1: + timedEvent = new AnimTimedAddBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf("."))); + break; + case 2: + timedEvent = new AnimTimedUpdateBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf("."))); + break; + } + if (!timedEvent) { + continue; + } + const propPattern = /([a-z]+): (.*?)(?:,|\})/ig; + let propMatch: RegExpExecArray; + while ((propMatch = propPattern.exec(timingData)!)) { // TODO: is this bang correct? + const prop = propMatch[1]; + let value: any = propMatch[2]; + switch (prop) { + case "bgX": + case "bgY": + value = parseFloat(value); + break; + case "volume": + case "pitch": + case "opacity": + case "colorRed": + case "colorGreen": + case "colorBlue": + case "colorAlpha": + case "duration": + case "flashScope": + case "flashRed": + case "flashGreen": + case "flashBlue": + case "flashAlpha": + case "flashDuration": + value = parseInt(value); + break; + } + if (timedEvent.hasOwnProperty(prop)) { + timedEvent[prop] = value; } - resourceName += `.${ext}`; } - timedEvent = new AnimTimedSoundEvent(frameIndex, resourceName); - break; - case 1: - timedEvent = new AnimTimedAddBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf("."))); - break; - case 2: - timedEvent = new AnimTimedUpdateBgEvent(frameIndex, resourceName.slice(0, resourceName.indexOf("."))); - break; - } - if (!timedEvent) { - continue; - } - const propPattern = /([a-z]+): (.*?)(?:,|\})/ig; - let propMatch: RegExpExecArray; - while ((propMatch = propPattern.exec(timingData)!)) { // TODO: is this bang correct? - const prop = propMatch[1]; - let value: any = propMatch[2]; - switch (prop) { - case "bgX": - case "bgY": - value = parseFloat(value); - break; - case "volume": - case "pitch": - case "opacity": - case "colorRed": - case "colorGreen": - case "colorBlue": - case "colorAlpha": - case "duration": - case "flashScope": - case "flashRed": - case "flashGreen": - case "flashBlue": - case "flashAlpha": - case "flashDuration": - value = parseInt(value); - break; + if (!anim.frameTimedEvents.has(frameIndex)) { + anim.frameTimedEvents.set(frameIndex, []); } - if (timedEvent.hasOwnProperty(prop)) { - timedEvent[prop] = value; - } - } - if (!anim.frameTimedEvents.has(frameIndex)) { - anim.frameTimedEvents.set(frameIndex, []); - } anim.frameTimedEvents.get(frameIndex)!.push(timedEvent); // TODO: is this bang correct? - } - break; - case "position": - anim.position = parseInt(fieldData); - break; - case "hue": - anim.hue = parseInt(fieldData); - break; + } + break; + case "position": + anim.position = parseInt(fieldData); + break; + case "hue": + anim.hue = parseInt(fieldData); + break; } } } diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index d8094f96368..d671c56ab26 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1,28 +1,43 @@ -import { ChargeAnim, CommonAnim, CommonBattleAnim, MoveChargeAnim } from "./battle-anims"; -import { getPokemonNameWithAffix } from "../messages"; -import Pokemon, { MoveResult, HitResult } from "../field/pokemon"; -import { StatusEffect } from "./status-effect"; -import * as Utils from "../utils"; -import { ChargeAttr, MoveFlags, allMoves, MoveCategory, applyMoveAttrs, StatusCategoryOnAllyAttr, HealOnAllyAttr, ConsecutiveUseDoublePowerAttr } from "./move"; -import { Type } from "./type"; -import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs, ProtectStatAbAttr } from "./ability"; -import { TerrainType } from "./terrain"; -import { WeatherType } from "./weather"; -import { allAbilities } from "./ability"; -import { SpeciesFormChangeManualTrigger } from "./pokemon-forms"; -import { Abilities } from "#enums/abilities"; -import { BattlerTagType } from "#enums/battler-tag-type"; -import { Moves } from "#enums/moves"; -import { Species } from "#enums/species"; -import i18next from "#app/plugins/i18n"; -import { Stat, type BattleStat, type EffectiveStat, EFFECTIVE_STATS, getStatKey } from "#app/enums/stat"; +import BattleScene from "#app/battle-scene"; +import { + allAbilities, + applyAbAttrs, + BlockNonDirectDamageAbAttr, + FlinchEffectAbAttr, + ProtectStatAbAttr, + ReverseDrainAbAttr +} from "#app/data/ability"; +import { ChargeAnim, CommonAnim, CommonBattleAnim, MoveChargeAnim } from "#app/data/battle-anims"; +import Move, { + allMoves, + applyMoveAttrs, + ConsecutiveUseDoublePowerAttr, + HealOnAllyAttr, + MoveCategory, + MoveFlags, + StatusCategoryOnAllyAttr +} from "#app/data/move"; +import { SpeciesFormChangeManualTrigger } from "#app/data/pokemon-forms"; +import { StatusEffect } from "#app/data/status-effect"; +import { TerrainType } from "#app/data/terrain"; +import { Type } from "#app/data/type"; +import { WeatherType } from "#app/data/weather"; +import Pokemon, { HitResult, MoveResult } from "#app/field/pokemon"; +import { getPokemonNameWithAffix } from "#app/messages"; import { CommonAnimPhase } from "#app/phases/common-anim-phase"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { MovePhase } from "#app/phases/move-phase"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase"; import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; -import { StatStageChangePhase, StatStageChangeCallback } from "#app/phases/stat-stage-change-phase"; -import { PokemonAnimType } from "#app/enums/pokemon-anim-type"; +import { StatStageChangeCallback, StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; +import i18next from "#app/plugins/i18n"; +import { BooleanHolder, getFrameMs, NumberHolder, toDmgValue } from "#app/utils"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Moves } from "#enums/moves"; +import { PokemonAnimType } from "#enums/pokemon-anim-type"; +import { Species } from "#enums/species"; +import { EFFECTIVE_STATS, getStatKey, Stat, type BattleStat, type EffectiveStat } from "#enums/stat"; export enum BattlerTagLapseType { FAINT, @@ -32,6 +47,7 @@ export enum BattlerTagLapseType { MOVE_EFFECT, TURN_END, HIT, + AFTER_HIT, CUSTOM } @@ -90,6 +106,15 @@ export class BattlerTag { this.sourceMove = source.sourceMove; this.sourceId = source.sourceId; } + + /** + * Helper function that retrieves the source Pokemon object + * @param scene medium to retrieve the source Pokemon + * @returns The source {@linkcode Pokemon} or `null` if none is found + */ + public getSourcePokemon(scene: BattleScene): Pokemon | null { + return this.sourceId ? scene.getPokemonById(this.sourceId) : null; + } } export interface WeatherBattlerTag { @@ -120,7 +145,7 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag { const phase = pokemon.scene.getCurrentPhase() as MovePhase; const move = phase.move; - if (this.isMoveRestricted(move.moveId)) { + if (this.isMoveRestricted(move.moveId, pokemon)) { if (this.interruptedText(pokemon, move.moveId)) { pokemon.scene.queueMessage(this.interruptedText(pokemon, move.moveId)); } @@ -136,10 +161,11 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag { /** * Gets whether this tag is restricting a move. * - * @param {Moves} move {@linkcode Moves} ID to check restriction for. - * @returns {boolean} `true` if the move is restricted by this tag, otherwise `false`. + * @param move - {@linkcode Moves} ID to check restriction for. + * @param user - The {@linkcode Pokemon} involved + * @returns `true` if the move is restricted by this tag, otherwise `false`. */ - abstract isMoveRestricted(move: Moves): boolean; + public abstract isMoveRestricted(move: Moves, user?: Pokemon): boolean; /** * Checks if this tag is restricting a move based on a user's decisions during the target selection phase @@ -327,6 +353,16 @@ export class GorillaTacticsTag extends MoveRestrictionBattlerTag { pokemon.setStat(Stat.ATK, pokemon.getStat(Stat.ATK, false) * 1.5, false); } + /** + * Loads the Gorilla Tactics Battler Tag along with its unique class variable moveId + * @override + * @param source Gorilla Tactics' {@linkcode BattlerTag} information + */ + public override loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.moveId = source.moveId; + } + /** * * @override @@ -363,7 +399,7 @@ export class RechargingTag extends BattlerTag { super.onAdd(pokemon); // Queue a placeholder move for the Pokemon to "use" next turn - pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] }); + pokemon.getMoveQueue().push({ move: Moves.NONE, targets: []}); } /** Cancels the source's move this turn and queues a "__ must recharge!" message */ @@ -384,7 +420,7 @@ export class RechargingTag extends BattlerTag { */ export class BeakBlastChargingTag extends BattlerTag { constructor() { - super(BattlerTagType.BEAK_BLAST_CHARGING, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END ], 1, Moves.BEAK_BLAST); + super(BattlerTagType.BEAK_BLAST_CHARGING, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END, BattlerTagLapseType.AFTER_HIT ], 1, Moves.BEAK_BLAST); } onAdd(pokemon: Pokemon): void { @@ -400,16 +436,13 @@ export class BeakBlastChargingTag extends BattlerTag { * to be removed after the source makes a move (or the turn ends, whichever comes first) * @param pokemon {@linkcode Pokemon} the owner of this tag * @param lapseType {@linkcode BattlerTagLapseType} the type of functionality invoked in battle - * @returns `true` if invoked with the CUSTOM lapse type; `false` otherwise + * @returns `true` if invoked with the `AFTER_HIT` lapse type */ lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { - if (lapseType === BattlerTagLapseType.CUSTOM) { - const effectPhase = pokemon.scene.getCurrentPhase(); - if (effectPhase instanceof MoveEffectPhase) { - const attacker = effectPhase.getPokemon(); - if (effectPhase.move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { - attacker.trySetStatus(StatusEffect.BURN, true, pokemon); - } + if (lapseType === BattlerTagLapseType.AFTER_HIT) { + const phaseData = getMoveEffectPhaseData(pokemon); + if (phaseData?.move.hasFlag(MoveFlags.MAKES_CONTACT)) { + phaseData.attacker.trySetStatus(StatusEffect.BURN, true, pokemon); } return true; } @@ -423,11 +456,10 @@ export class BeakBlastChargingTag extends BattlerTag { * @see {@link https://bulbapedia.bulbagarden.net/wiki/Shell_Trap_(move) | Shell Trap} */ export class ShellTrapTag extends BattlerTag { - public activated: boolean; + public activated: boolean = false; constructor() { - super(BattlerTagType.SHELL_TRAP, BattlerTagLapseType.TURN_END, 1); - this.activated = false; + super(BattlerTagType.SHELL_TRAP, [ BattlerTagLapseType.TURN_END, BattlerTagLapseType.AFTER_HIT ], 1); } onAdd(pokemon: Pokemon): void { @@ -438,25 +470,33 @@ export class ShellTrapTag extends BattlerTag { * "Activates" the shell trap, causing the tag owner to move next. * @param pokemon {@linkcode Pokemon} the owner of this tag * @param lapseType {@linkcode BattlerTagLapseType} the type of functionality invoked in battle - * @returns `true` if invoked with the `CUSTOM` lapse type; `false` otherwise + * @returns `true` if invoked with the `AFTER_HIT` lapse type */ lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { - if (lapseType === BattlerTagLapseType.CUSTOM) { - const shellTrapPhaseIndex = pokemon.scene.phaseQueue.findIndex( - phase => phase instanceof MovePhase && phase.pokemon === pokemon - ); - const firstMovePhaseIndex = pokemon.scene.phaseQueue.findIndex( - phase => phase instanceof MovePhase - ); + if (lapseType === BattlerTagLapseType.AFTER_HIT) { + const phaseData = getMoveEffectPhaseData(pokemon); - if (shellTrapPhaseIndex !== -1 && shellTrapPhaseIndex !== firstMovePhaseIndex) { - const shellTrapMovePhase = pokemon.scene.phaseQueue.splice(shellTrapPhaseIndex, 1)[0]; - pokemon.scene.prependToPhase(shellTrapMovePhase, MovePhase); + // Trap should only be triggered by opponent's Physical moves + if (phaseData?.move.category === MoveCategory.PHYSICAL && pokemon.isOpponent(phaseData.attacker)) { + const shellTrapPhaseIndex = pokemon.scene.phaseQueue.findIndex( + phase => phase instanceof MovePhase && phase.pokemon === pokemon + ); + const firstMovePhaseIndex = pokemon.scene.phaseQueue.findIndex( + phase => phase instanceof MovePhase + ); + + // Only shift MovePhase timing if it's not already next up + if (shellTrapPhaseIndex !== -1 && shellTrapPhaseIndex !== firstMovePhaseIndex) { + const shellTrapMovePhase = pokemon.scene.phaseQueue.splice(shellTrapPhaseIndex, 1)[0]; + pokemon.scene.prependToPhase(shellTrapMovePhase, MovePhase); + } + + this.activated = true; } - this.activated = true; return true; } + return super.lapse(pokemon, lapseType); } } @@ -569,7 +609,7 @@ export class InterruptedTag extends BattlerTag { super.onAdd(pokemon); pokemon.getMoveQueue().shift(); - pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER}); + pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.OTHER }); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -620,7 +660,7 @@ export class ConfusedTag extends BattlerTag { if (pokemon.randSeedInt(3) === 0) { const atk = pokemon.getEffectiveStat(Stat.ATK); const def = pokemon.getEffectiveStat(Stat.DEF); - const damage = Utils.toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedIntRange(85, 100) / 100)); + const damage = toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedIntRange(85, 100) / 100)); pokemon.scene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself")); pokemon.damageAndUpdate(damage); pokemon.battleData.hitCount++; @@ -791,13 +831,13 @@ export class SeedTag extends BattlerTag { if (ret) { const source = pokemon.getOpponents().find(o => o.getBattlerIndex() === this.sourceIndex); if (source) { - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (!cancelled.value) { pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED)); - const damage = pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / 8)); + const damage = pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8)); const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr, false); pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(), !reverseDrain ? damage : damage * -1, @@ -817,7 +857,7 @@ export class SeedTag extends BattlerTag { export class NightmareTag extends BattlerTag { constructor() { - super(BattlerTagType.NIGHTMARE, BattlerTagLapseType.AFTER_MOVE, 1, Moves.NIGHTMARE); + super(BattlerTagType.NIGHTMARE, BattlerTagLapseType.TURN_END, 1, Moves.NIGHTMARE); } onAdd(pokemon: Pokemon): void { @@ -839,11 +879,11 @@ export class NightmareTag extends BattlerTag { pokemon.scene.queueMessage(i18next.t("battlerTags:nightmareLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (!cancelled.value) { - pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / 4)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4)); } } @@ -898,18 +938,14 @@ export class EncoreTag extends BattlerTag { } switch (repeatableMove.move) { - case Moves.MIMIC: - case Moves.MIRROR_MOVE: - case Moves.TRANSFORM: - case Moves.STRUGGLE: - case Moves.SKETCH: - case Moves.SLEEP_TALK: - case Moves.ENCORE: - return false; - } - - if (allMoves[repeatableMove.move].hasAttr(ChargeAttr) && repeatableMove.result === MoveResult.OTHER) { - return false; + case Moves.MIMIC: + case Moves.MIRROR_MOVE: + case Moves.TRANSFORM: + case Moves.STRUGGLE: + case Moves.SKETCH: + case Moves.SLEEP_TALK: + case Moves.ENCORE: + return false; } this.moveId = repeatableMove.move; @@ -983,7 +1019,7 @@ export class IngrainTag extends TrappedTag { new PokemonHealPhase( pokemon.scene, pokemon.getBattlerIndex(), - Utils.toDmgValue(pokemon.getMaxHp() / 16), + toDmgValue(pokemon.getMaxHp() / 16), i18next.t("battlerTags:ingrainLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), true ) @@ -1046,7 +1082,7 @@ export class AquaRingTag extends BattlerTag { new PokemonHealPhase( pokemon.scene, pokemon.getBattlerIndex(), - Utils.toDmgValue(pokemon.getMaxHp() / 16), + toDmgValue(pokemon.getMaxHp() / 16), i18next.t("battlerTags:aquaRingLapse", { moveName: this.getMoveName(), pokemonName: getPokemonNameWithAffix(pokemon) @@ -1140,11 +1176,11 @@ export abstract class DamagingTrapTag extends TrappedTag { ); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, this.commonAnim)); - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (!cancelled.value) { - pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / 8)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8)); } } @@ -1335,7 +1371,7 @@ export class ContactDamageProtectedTag extends ProtectedTag { if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) { const attacker = effectPhase.getPokemon(); if (!attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { - attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); + attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); } } } @@ -1376,7 +1412,7 @@ export class ContactStatStageChangeProtectedTag extends DamageProtectedTag { const effectPhase = pokemon.scene.getCurrentPhase(); if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) { const attacker = effectPhase.getPokemon(); - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), true, [ this.stat ], this.levels)); + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), false, [ this.stat ], this.levels)); } } @@ -1620,12 +1656,12 @@ export class HighestStatBoostTag extends AbilityBattlerTag { this.stat = highestStat; switch (this.stat) { - case Stat.SPD: - this.multiplier = 1.5; - break; - default: - this.multiplier = 1.3; - break; + case Stat.SPD: + this.multiplier = 1.5; + break; + default: + this.multiplier = 1.3; + break; } pokemon.scene.queueMessage(i18next.t("battlerTags:highestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: i18next.t(getStatKey(highestStat)) }), null, false, null, true); @@ -1688,7 +1724,7 @@ export class SemiInvulnerableTag extends BattlerTag { onRemove(pokemon: Pokemon): void { // Wait 2 frames before setting visible for battle animations that don't immediately show the sprite invisible pokemon.scene.tweens.addCounter({ - duration: Utils.getFrameMs(2), + duration: getFrameMs(2), onComplete: () => pokemon.setVisible(true) }); } @@ -1713,7 +1749,12 @@ export class TypeImmuneTag extends BattlerTag { } } -export class MagnetRisenTag extends TypeImmuneTag { +/** + * Battler Tag that lifts the affected Pokemon into the air and provides immunity to Ground type moves. + * @see {@link https://bulbapedia.bulbagarden.net/wiki/Magnet_Rise_(move) | Moves.MAGNET_RISE} + * @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | Moves.TELEKINESIS} + */ +export class FloatingTag extends TypeImmuneTag { constructor(tagType: BattlerTagType, sourceMove: Moves) { super(tagType, sourceMove, Type.GROUND, 5); } @@ -1721,13 +1762,17 @@ export class MagnetRisenTag extends TypeImmuneTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + if (this.sourceMove === Moves.MAGNET_RISE) { + pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } + } onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - - pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + if (this.sourceMove === Moves.MAGNET_RISE) { + pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } } } @@ -1830,12 +1875,12 @@ export class SaltCuredTag extends BattlerTag { if (ret) { pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE)); - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (!cancelled.value) { const pokemonSteelOrWater = pokemon.isOfType(Type.STEEL) || pokemon.isOfType(Type.WATER); - pokemon.damageAndUpdate(Utils.toDmgValue(pokemonSteelOrWater ? pokemon.getMaxHp() / 4 : pokemon.getMaxHp() / 8)); + pokemon.damageAndUpdate(toDmgValue(pokemonSteelOrWater ? pokemon.getMaxHp() / 4 : pokemon.getMaxHp() / 8)); pokemon.scene.queueMessage( i18next.t("battlerTags:saltCuredLapse", { @@ -1877,11 +1922,11 @@ export class CursedTag extends BattlerTag { if (ret) { pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE)); - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (!cancelled.value) { - pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / 4)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4)); pokemon.scene.queueMessage(i18next.t("battlerTags:cursedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } } @@ -1935,10 +1980,10 @@ export class RoostedTag extends BattlerTag { modifiedTypes = currentTypes.filter(type => type !== Type.NORMAL); modifiedTypes.push(Type.FLYING); } else { - modifiedTypes = [Type.FLYING]; + modifiedTypes = [ Type.FLYING ]; } } else { - modifiedTypes = [...currentTypes]; + modifiedTypes = [ ...currentTypes ]; modifiedTypes.push(Type.FLYING); } pokemon.summonData.types = modifiedTypes; @@ -1958,10 +2003,10 @@ export class RoostedTag extends BattlerTag { if (this.isBaseFlying) { let modifiedTypes: Type[]; if (this.isBasePureFlying && !isCurrentlyDualType) { - modifiedTypes = [Type.NORMAL]; + modifiedTypes = [ Type.NORMAL ]; } else { if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) { - modifiedTypes = [Type.UNKNOWN]; + modifiedTypes = [ Type.UNKNOWN ]; } else { modifiedTypes = currentTypes.filter(type => type !== Type.FLYING); } @@ -2067,8 +2112,8 @@ export class StockpilingTag extends BattlerTag { super.loadTag(source); this.stockpiledCount = source.stockpiledCount || 0; this.statChangeCounts = { - [ Stat.DEF ]: source.statChangeCounts?.[ Stat.DEF ] ?? 0, - [ Stat.SPDEF ]: source.statChangeCounts?.[ Stat.SPDEF ] ?? 0, + [Stat.DEF]: source.statChangeCounts?.[Stat.DEF] ?? 0, + [Stat.SPDEF]: source.statChangeCounts?.[Stat.SPDEF] ?? 0, }; } @@ -2090,7 +2135,7 @@ export class StockpilingTag extends BattlerTag { // Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes. pokemon.scene.unshiftPhase(new StatStageChangePhase( pokemon.scene, pokemon.getBattlerIndex(), true, - [Stat.SPDEF, Stat.DEF], 1, true, false, true, this.onStatStagesChanged + [ Stat.SPDEF, Stat.DEF ], 1, true, false, true, this.onStatStagesChanged )); } } @@ -2139,7 +2184,11 @@ export class GulpMissileTag extends BattlerTag { return false; } - const cancelled = new Utils.BooleanHolder(false); + if (moveEffectPhase.move.getMove().hitsSubstitute(attacker, pokemon)) { + return true; + } + + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled); if (!cancelled.value) { @@ -2255,7 +2304,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { * @returns `true` if the move cannot be used because the target is an ally */ override isMoveTargetRestricted(move: Moves, user: Pokemon, target: Pokemon) { - const moveCategory = new Utils.IntegerHolder(allMoves[move].category); + const moveCategory = new NumberHolder(allMoves[move].category); applyMoveAttrs(StatusCategoryOnAllyAttr, user, target, allMoves[move], moveCategory); if (allMoves[move].hasAttr(HealOnAllyAttr) && moveCategory.value === MoveCategory.STATUS ) { return true; @@ -2267,7 +2316,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { * Uses DisabledTag's selectionDeniedText() message */ override selectionDeniedText(pokemon: Pokemon, move: Moves): string { - return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name }); + return i18next.t("battle:moveDisabledHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name, healBlockName: allMoves[Moves.HEAL_BLOCK].name }); } /** @@ -2277,7 +2326,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { * @returns {string} text to display when the move is interrupted */ override interruptedText(pokemon: Pokemon, move: Moves): string { - return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name }); + return i18next.t("battle:moveDisabledHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name, healBlockName: allMoves[Moves.HEAL_BLOCK].name }); } override onRemove(pokemon: Pokemon): void { @@ -2310,6 +2359,21 @@ export class TarShotTag extends BattlerTag { } } +/** + * Battler Tag implementing the type-changing effect of {@link https://bulbapedia.bulbagarden.net/wiki/Electrify_(move) | Electrify}. + * While this tag is in effect, the afflicted Pokemon's moves are changed to Electric type. + */ +export class ElectrifiedTag extends BattlerTag { + constructor() { + super(BattlerTagType.ELECTRIFIED, BattlerTagLapseType.TURN_END, 1, Moves.ELECTRIFY); + } + + override onAdd(pokemon: Pokemon): void { + // "{pokemonNameWithAffix}'s moves have been electrified!" + pokemon.scene.queueMessage(i18next.t("battlerTags:electrifiedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } +} + /** * Battler Tag that keeps track of how many times the user has Autotomized * Each count of Autotomization reduces the weight by 100kg @@ -2354,7 +2418,7 @@ export class SubstituteTag extends BattlerTag { public sourceInFocus: boolean; constructor(sourceMove: Moves, sourceId: integer) { - super(BattlerTagType.SUBSTITUTE, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE, BattlerTagLapseType.HIT], 0, sourceMove, sourceId, true); + super(BattlerTagType.SUBSTITUTE, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE, BattlerTagLapseType.HIT ], 0, sourceMove, sourceId, true); } /** Sets the Substitute's HP and queues an on-add battle animation that initializes the Substitute's sprite. */ @@ -2378,7 +2442,7 @@ export class SubstituteTag extends BattlerTag { onRemove(pokemon: Pokemon): void { // Only play the animation if the cause of removal isn't from the source's own move if (!this.sourceInFocus) { - pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_REMOVE, [this.sprite]); + pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_REMOVE, [ this.sprite ]); } else { this.sprite.destroy(); } @@ -2387,28 +2451,28 @@ export class SubstituteTag extends BattlerTag { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { switch (lapseType) { - case BattlerTagLapseType.PRE_MOVE: - this.onPreMove(pokemon); - break; - case BattlerTagLapseType.AFTER_MOVE: - this.onAfterMove(pokemon); - break; - case BattlerTagLapseType.HIT: - this.onHit(pokemon); - break; + case BattlerTagLapseType.PRE_MOVE: + this.onPreMove(pokemon); + break; + case BattlerTagLapseType.AFTER_MOVE: + this.onAfterMove(pokemon); + break; + case BattlerTagLapseType.HIT: + this.onHit(pokemon); + break; } return lapseType !== BattlerTagLapseType.CUSTOM; // only remove this tag on custom lapse } /** Triggers an animation that brings the Pokemon into focus before it uses a move */ onPreMove(pokemon: Pokemon): void { - pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_PRE_MOVE, [this.sprite]); + pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_PRE_MOVE, [ this.sprite ]); this.sourceInFocus = true; } /** Triggers an animation that brings the Pokemon out of focus after it uses a move */ onAfterMove(pokemon: Pokemon): void { - pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_POST_MOVE, [this.sprite]); + pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_POST_MOVE, [ this.sprite ]); this.sourceInFocus = false; } @@ -2457,7 +2521,7 @@ export class MysteryEncounterPostSummonTag extends BattlerTag { const ret = super.lapse(pokemon, lapseType); if (lapseType === BattlerTagLapseType.CUSTOM) { - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(ProtectStatAbAttr, pokemon, cancelled); if (!cancelled.value) { if (pokemon.mysteryEncounterBattleEffects) { @@ -2482,8 +2546,6 @@ export class MysteryEncounterPostSummonTag extends BattlerTag { * Torment does not interrupt the move if the move is performed consecutively in the same turn and right after Torment is applied */ export class TormentTag extends MoveRestrictionBattlerTag { - private target: Pokemon; - constructor(sourceId: number) { super(BattlerTagType.TORMENT, BattlerTagLapseType.AFTER_MOVE, 1, Moves.TORMENT, sourceId); } @@ -2495,7 +2557,6 @@ export class TormentTag extends MoveRestrictionBattlerTag { */ override onAdd(pokemon: Pokemon) { super.onAdd(pokemon); - this.target = pokemon; pokemon.scene.queueMessage(i18next.t("battlerTags:tormentOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500); } @@ -2514,15 +2575,18 @@ export class TormentTag extends MoveRestrictionBattlerTag { * @param {Moves} move the move under investigation * @returns `true` if there is valid consecutive usage | `false` if the moves are different from each other */ - override isMoveRestricted(move: Moves): boolean { - const lastMove = this.target.getLastXMoves(1)[0]; + public override isMoveRestricted(move: Moves, user: Pokemon): boolean { + if (!user) { + return false; + } + const lastMove = user.getLastXMoves(1)[0]; if ( !lastMove ) { return false; } // This checks for locking / momentum moves like Rollout and Hydro Cannon + if the user is under the influence of BattlerTagType.FRENZY // Because Uproar's unique behavior is not implemented, it does not check for Uproar. Torment has been marked as partial in moves.ts const moveObj = allMoves[lastMove.move]; - const isUnaffected = moveObj.hasAttr(ConsecutiveUseDoublePowerAttr) || this.target.getTag(BattlerTagType.FRENZY) || moveObj.hasAttr(ChargeAttr); + const isUnaffected = moveObj.hasAttr(ConsecutiveUseDoublePowerAttr) || user.getTag(BattlerTagType.FRENZY); const validLastMoveResult = (lastMove.result === MoveResult.SUCCESS) || (lastMove.result === MoveResult.MISS); if (lastMove.move === move && validLastMoveResult && lastMove.move !== Moves.STRUGGLE && !isUnaffected) { return true; @@ -2530,8 +2594,8 @@ export class TormentTag extends MoveRestrictionBattlerTag { return false; } - override selectionDeniedText(_pokemon: Pokemon, move: Moves): string { - return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name }); + override selectionDeniedText(pokemon: Pokemon, _move: Moves): string { + return i18next.t("battle:moveDisabledTorment", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } } @@ -2542,7 +2606,7 @@ export class TormentTag extends MoveRestrictionBattlerTag { */ export class TauntTag extends MoveRestrictionBattlerTag { constructor() { - super(BattlerTagType.TAUNT, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE], 4, Moves.TAUNT); + super(BattlerTagType.TAUNT, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 4, Moves.TAUNT); } override onAdd(pokemon: Pokemon) { @@ -2559,12 +2623,12 @@ export class TauntTag extends MoveRestrictionBattlerTag { return allMoves[move].category === MoveCategory.STATUS; } - override selectionDeniedText(_pokemon: Pokemon, move: Moves): string { - return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name }); + override selectionDeniedText(pokemon: Pokemon, move: Moves): string { + return i18next.t("battle:moveDisabledTaunt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name }); } override interruptedText(pokemon: Pokemon, move: Moves): string { - return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name }); + return i18next.t("battle:moveDisabledTaunt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name }); } } @@ -2574,63 +2638,65 @@ export class TauntTag extends MoveRestrictionBattlerTag { * The tag is only removed when the source-user is removed from the field. */ export class ImprisonTag extends MoveRestrictionBattlerTag { - private source: Pokemon | null; - constructor(sourceId: number) { - super(BattlerTagType.IMPRISON, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE], 1, Moves.IMPRISON, sourceId); - } - - override onAdd(pokemon: Pokemon) { - if (this.sourceId) { - this.source = pokemon.scene.getPokemonById(this.sourceId); - } + super(BattlerTagType.IMPRISON, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 1, Moves.IMPRISON, sourceId); } /** * Checks if the source of Imprison is still active - * @param _pokemon - * @param _lapseType + * @override + * @param pokemon The pokemon this tag is attached to * @returns `true` if the source is still active */ - override lapse(_pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean { - return this.source?.isActive(true) ?? false; - } - - /** - * Checks if the source of the tag has the parameter move in its moveset and that the source is still active - * @param {Moves} move the move under investigation - * @returns `false` if either condition is not met - */ - override isMoveRestricted(move: Moves): boolean { - if (this.source) { - const sourceMoveset = this.source.getMoveset().map(m => m!.moveId); - return sourceMoveset?.includes(move) && this.source.isActive(true); + public override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { + const source = this.getSourcePokemon(pokemon.scene); + if (source) { + if (lapseType === BattlerTagLapseType.PRE_MOVE) { + return super.lapse(pokemon, lapseType) && source.isActive(true); + } else { + return source.isActive(true); + } } return false; } - override selectionDeniedText(_pokemon: Pokemon, move: Moves): string { - return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name }); + /** + * Checks if the source of the tag has the parameter move in its moveset and that the source is still active + * @override + * @param {Moves} move the move under investigation + * @returns `false` if either condition is not met + */ + public override isMoveRestricted(move: Moves, user: Pokemon): boolean { + const source = this.getSourcePokemon(user.scene); + if (source) { + const sourceMoveset = source.getMoveset().map(m => m!.moveId); + return sourceMoveset?.includes(move) && source.isActive(true); + } + return false; + } + + override selectionDeniedText(pokemon: Pokemon, move: Moves): string { + return i18next.t("battle:moveDisabledImprison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name }); } override interruptedText(pokemon: Pokemon, move: Moves): string { - return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name }); + return i18next.t("battle:moveDisabledImprison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name }); } } /** * Battler Tag that applies the effects of Syrup Bomb to the target Pokemon. * For three turns, starting from the turn of hit, at the end of each turn, the target Pokemon's speed will decrease by 1. - * The tag can also expire by taking the target Pokemon off the field. + * The tag can also expire by taking the target Pokemon off the field, or the Pokemon that originally used the move. */ export class SyrupBombTag extends BattlerTag { - constructor() { - super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB); + constructor(sourceId: number) { + super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB, sourceId); } /** * Adds the Syrup Bomb battler tag to the target Pokemon. - * @param {Pokemon} pokemon the target Pokemon + * @param pokemon - The target {@linkcode Pokemon} */ override onAdd(pokemon: Pokemon) { super.onAdd(pokemon); @@ -2639,201 +2705,258 @@ export class SyrupBombTag extends BattlerTag { /** * Applies the single-stage speed down to the target Pokemon and decrements the tag's turn count - * @param {Pokemon} pokemon the target Pokemon - * @param {BattlerTagLapseType} _lapseType - * @returns `true` if the turnCount is still greater than 0 | `false` if the turnCount is 0 or the target Pokemon has been removed from the field + * @param pokemon - The target {@linkcode Pokemon} + * @param _lapseType - N/A + * @returns `true` if the `turnCount` is still greater than `0`; `false` if the `turnCount` is `0` or the target or source Pokemon has been removed from the field */ override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean { - if (!pokemon.isActive(true)) { + if (this.sourceId && !pokemon.scene.getPokemonById(this.sourceId)?.isActive(true)) { return false; } - pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // Custom message in lieu of an animation in mainline + // Custom message in lieu of an animation in mainline + pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.scene.unshiftPhase(new StatStageChangePhase( pokemon.scene, pokemon.getBattlerIndex(), true, - [Stat.SPD], -1, true, false, true + [ Stat.SPD ], -1, true, false, true )); return --this.turnCount > 0; } } +/** + * Telekinesis raises the target into the air for three turns and causes all moves used against the target (aside from OHKO moves) to hit the target unless the target is in a semi-invulnerable state from Fly/Dig. + * The first effect is provided by {@linkcode FloatingTag}, the accuracy-bypass effect is provided by TelekinesisTag + * The effects of Telekinesis can be baton passed to a teammate. Unlike the mainline games, Telekinesis can be baton-passed to Mega Gengar. + * @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | Moves.TELEKINESIS} + */ +export class TelekinesisTag extends BattlerTag { + constructor(sourceMove: Moves) { + super(BattlerTagType.TELEKINESIS, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 3, sourceMove, undefined, true); + } + + override onAdd(pokemon: Pokemon) { + pokemon.scene.queueMessage(i18next.t("battlerTags:telekinesisOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } +} + +/** + * Tag that swaps the user's base ATK stat with its base DEF stat. + * @extends BattlerTag + */ +export class PowerTrickTag extends BattlerTag { + constructor(sourceMove: Moves, sourceId: number) { + super(BattlerTagType.POWER_TRICK, BattlerTagLapseType.CUSTOM, 0, sourceMove, sourceId, true); + } + + onAdd(pokemon: Pokemon): void { + this.swapStat(pokemon); + pokemon.scene.queueMessage(i18next.t("battlerTags:powerTrickActive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } + + onRemove(pokemon: Pokemon): void { + this.swapStat(pokemon); + pokemon.scene.queueMessage(i18next.t("battlerTags:powerTrickActive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } + + /** + * Removes the Power Trick tag and reverts any stat changes if the tag is already applied. + * @param {Pokemon} pokemon The {@linkcode Pokemon} that already has the Power Trick tag. + */ + onOverlap(pokemon: Pokemon): void { + pokemon.removeTag(this.tagType); + } + + /** + * Swaps the user's base ATK stat with its base DEF stat. + * @param {Pokemon} pokemon The {@linkcode Pokemon} whose stats will be swapped. + */ + swapStat(pokemon: Pokemon): void { + const temp = pokemon.getStat(Stat.ATK, false); + pokemon.setStat(Stat.ATK, pokemon.getStat(Stat.DEF, false), false); + pokemon.setStat(Stat.DEF, temp, false); + } +} + /** * Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID. - * - * @param {BattlerTagType} tagType the type of the {@linkcode BattlerTagType}. - * @param turnCount the turn count. - * @param {Moves} sourceMove the source {@linkcode Moves}. - * @param sourceId the source ID. - * @returns {BattlerTag} the corresponding {@linkcode BattlerTag} object. + * @param sourceId - The ID of the pokemon adding the tag + * @returns The corresponding {@linkcode BattlerTag} object. */ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, sourceMove: Moves, sourceId: number): BattlerTag { switch (tagType) { - case BattlerTagType.RECHARGING: - return new RechargingTag(sourceMove); - case BattlerTagType.BEAK_BLAST_CHARGING: - return new BeakBlastChargingTag(); - case BattlerTagType.SHELL_TRAP: - return new ShellTrapTag(); - case BattlerTagType.FLINCHED: - return new FlinchedTag(sourceMove); - case BattlerTagType.INTERRUPTED: - return new InterruptedTag(sourceMove); - case BattlerTagType.CONFUSED: - return new ConfusedTag(turnCount, sourceMove); - case BattlerTagType.INFATUATED: - return new InfatuatedTag(sourceMove, sourceId); - case BattlerTagType.SEEDED: - return new SeedTag(sourceId); - case BattlerTagType.NIGHTMARE: - return new NightmareTag(); - case BattlerTagType.FRENZY: - return new FrenzyTag(turnCount, sourceMove, sourceId); - case BattlerTagType.CHARGING: - return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId); - case BattlerTagType.ENCORE: - return new EncoreTag(sourceId); - case BattlerTagType.HELPING_HAND: - return new HelpingHandTag(sourceId); - case BattlerTagType.INGRAIN: - return new IngrainTag(sourceId); - case BattlerTagType.AQUA_RING: - return new AquaRingTag(); - case BattlerTagType.DROWSY: - return new DrowsyTag(); - case BattlerTagType.TRAPPED: - return new TrappedTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); - case BattlerTagType.NO_RETREAT: - return new NoRetreatTag(sourceId); - case BattlerTagType.BIND: - return new BindTag(turnCount, sourceId); - case BattlerTagType.WRAP: - return new WrapTag(turnCount, sourceId); - case BattlerTagType.FIRE_SPIN: - return new FireSpinTag(turnCount, sourceId); - case BattlerTagType.WHIRLPOOL: - return new WhirlpoolTag(turnCount, sourceId); - case BattlerTagType.CLAMP: - return new ClampTag(turnCount, sourceId); - case BattlerTagType.SAND_TOMB: - return new SandTombTag(turnCount, sourceId); - case BattlerTagType.MAGMA_STORM: - return new MagmaStormTag(turnCount, sourceId); - case BattlerTagType.SNAP_TRAP: - return new SnapTrapTag(turnCount, sourceId); - case BattlerTagType.THUNDER_CAGE: - return new ThunderCageTag(turnCount, sourceId); - case BattlerTagType.INFESTATION: - return new InfestationTag(turnCount, sourceId); - case BattlerTagType.PROTECTED: - return new ProtectedTag(sourceMove); - case BattlerTagType.SPIKY_SHIELD: - return new ContactDamageProtectedTag(sourceMove, 8); - case BattlerTagType.KINGS_SHIELD: - return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.ATK, -1); - case BattlerTagType.OBSTRUCT: - return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.DEF, -2); - case BattlerTagType.SILK_TRAP: - return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.SPD, -1); - case BattlerTagType.BANEFUL_BUNKER: - return new ContactPoisonProtectedTag(sourceMove); - case BattlerTagType.BURNING_BULWARK: - return new ContactBurnProtectedTag(sourceMove); - case BattlerTagType.ENDURING: - return new EnduringTag(sourceMove); - case BattlerTagType.STURDY: - return new SturdyTag(sourceMove); - case BattlerTagType.PERISH_SONG: - return new PerishSongTag(turnCount); - case BattlerTagType.CENTER_OF_ATTENTION: - return new CenterOfAttentionTag(sourceMove); - case BattlerTagType.TRUANT: - return new TruantTag(); - case BattlerTagType.SLOW_START: - return new SlowStartTag(); - case BattlerTagType.PROTOSYNTHESIS: - return new WeatherHighestStatBoostTag(tagType, Abilities.PROTOSYNTHESIS, WeatherType.SUNNY, WeatherType.HARSH_SUN); - case BattlerTagType.QUARK_DRIVE: - return new TerrainHighestStatBoostTag(tagType, Abilities.QUARK_DRIVE, TerrainType.ELECTRIC); - case BattlerTagType.FLYING: - case BattlerTagType.UNDERGROUND: - case BattlerTagType.UNDERWATER: - case BattlerTagType.HIDDEN: - return new SemiInvulnerableTag(tagType, turnCount, sourceMove); - case BattlerTagType.FIRE_BOOST: - return new TypeBoostTag(tagType, sourceMove, Type.FIRE, 1.5, false); - case BattlerTagType.CRIT_BOOST: - return new CritBoostTag(tagType, sourceMove); - case BattlerTagType.DRAGON_CHEER: - return new DragonCheerTag(); - case BattlerTagType.ALWAYS_CRIT: - case BattlerTagType.IGNORE_ACCURACY: - return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove); - case BattlerTagType.ALWAYS_GET_HIT: - case BattlerTagType.RECEIVE_DOUBLE_DAMAGE: - return new BattlerTag(tagType, BattlerTagLapseType.PRE_MOVE, 1, sourceMove); - case BattlerTagType.BYPASS_SLEEP: - return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove); - case BattlerTagType.IGNORE_FLYING: - return new GroundedTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); - case BattlerTagType.ROOSTED: - return new RoostedTag(); - case BattlerTagType.BURNED_UP: - return new RemovedTypeTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); - case BattlerTagType.DOUBLE_SHOCKED: - return new RemovedTypeTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); - case BattlerTagType.SALT_CURED: - return new SaltCuredTag(sourceId); - case BattlerTagType.CURSED: - return new CursedTag(sourceId); - case BattlerTagType.CHARGED: - return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); - case BattlerTagType.MAGNET_RISEN: - return new MagnetRisenTag(tagType, sourceMove); - case BattlerTagType.MINIMIZED: - return new MinimizeTag(); - case BattlerTagType.DESTINY_BOND: - return new DestinyBondTag(sourceMove, sourceId); - case BattlerTagType.ICE_FACE: - return new IceFaceBlockDamageTag(tagType); - case BattlerTagType.DISGUISE: - return new FormBlockDamageTag(tagType); - case BattlerTagType.STOCKPILING: - return new StockpilingTag(sourceMove); - case BattlerTagType.OCTOLOCK: - return new OctolockTag(sourceId); - case BattlerTagType.DISABLED: - return new DisabledTag(sourceId); - case BattlerTagType.IGNORE_GHOST: - return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]); - case BattlerTagType.IGNORE_DARK: - return new ExposedTag(tagType, sourceMove, Type.DARK, [Type.PSYCHIC]); - case BattlerTagType.GULP_MISSILE_ARROKUDA: - case BattlerTagType.GULP_MISSILE_PIKACHU: - return new GulpMissileTag(tagType, sourceMove); - case BattlerTagType.TAR_SHOT: - return new TarShotTag(); - case BattlerTagType.THROAT_CHOPPED: - return new ThroatChoppedTag(); - case BattlerTagType.GORILLA_TACTICS: - return new GorillaTacticsTag(); - case BattlerTagType.SUBSTITUTE: - return new SubstituteTag(sourceMove, sourceId); - case BattlerTagType.AUTOTOMIZED: - return new AutotomizedTag(); - case BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON: - return new MysteryEncounterPostSummonTag(); - case BattlerTagType.HEAL_BLOCK: - return new HealBlockTag(turnCount, sourceMove); - case BattlerTagType.TORMENT: - return new TormentTag(sourceId); - case BattlerTagType.TAUNT: - return new TauntTag(); - case BattlerTagType.IMPRISON: - return new ImprisonTag(sourceId); - case BattlerTagType.SYRUP_BOMB: - return new SyrupBombTag(); - case BattlerTagType.NONE: - default: - return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); + case BattlerTagType.RECHARGING: + return new RechargingTag(sourceMove); + case BattlerTagType.BEAK_BLAST_CHARGING: + return new BeakBlastChargingTag(); + case BattlerTagType.SHELL_TRAP: + return new ShellTrapTag(); + case BattlerTagType.FLINCHED: + return new FlinchedTag(sourceMove); + case BattlerTagType.INTERRUPTED: + return new InterruptedTag(sourceMove); + case BattlerTagType.CONFUSED: + return new ConfusedTag(turnCount, sourceMove); + case BattlerTagType.INFATUATED: + return new InfatuatedTag(sourceMove, sourceId); + case BattlerTagType.SEEDED: + return new SeedTag(sourceId); + case BattlerTagType.NIGHTMARE: + return new NightmareTag(); + case BattlerTagType.FRENZY: + return new FrenzyTag(turnCount, sourceMove, sourceId); + case BattlerTagType.CHARGING: + return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId); + case BattlerTagType.ENCORE: + return new EncoreTag(sourceId); + case BattlerTagType.HELPING_HAND: + return new HelpingHandTag(sourceId); + case BattlerTagType.INGRAIN: + return new IngrainTag(sourceId); + case BattlerTagType.AQUA_RING: + return new AquaRingTag(); + case BattlerTagType.DROWSY: + return new DrowsyTag(); + case BattlerTagType.TRAPPED: + return new TrappedTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); + case BattlerTagType.NO_RETREAT: + return new NoRetreatTag(sourceId); + case BattlerTagType.BIND: + return new BindTag(turnCount, sourceId); + case BattlerTagType.WRAP: + return new WrapTag(turnCount, sourceId); + case BattlerTagType.FIRE_SPIN: + return new FireSpinTag(turnCount, sourceId); + case BattlerTagType.WHIRLPOOL: + return new WhirlpoolTag(turnCount, sourceId); + case BattlerTagType.CLAMP: + return new ClampTag(turnCount, sourceId); + case BattlerTagType.SAND_TOMB: + return new SandTombTag(turnCount, sourceId); + case BattlerTagType.MAGMA_STORM: + return new MagmaStormTag(turnCount, sourceId); + case BattlerTagType.SNAP_TRAP: + return new SnapTrapTag(turnCount, sourceId); + case BattlerTagType.THUNDER_CAGE: + return new ThunderCageTag(turnCount, sourceId); + case BattlerTagType.INFESTATION: + return new InfestationTag(turnCount, sourceId); + case BattlerTagType.PROTECTED: + return new ProtectedTag(sourceMove); + case BattlerTagType.SPIKY_SHIELD: + return new ContactDamageProtectedTag(sourceMove, 8); + case BattlerTagType.KINGS_SHIELD: + return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.ATK, -1); + case BattlerTagType.OBSTRUCT: + return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.DEF, -2); + case BattlerTagType.SILK_TRAP: + return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.SPD, -1); + case BattlerTagType.BANEFUL_BUNKER: + return new ContactPoisonProtectedTag(sourceMove); + case BattlerTagType.BURNING_BULWARK: + return new ContactBurnProtectedTag(sourceMove); + case BattlerTagType.ENDURING: + return new EnduringTag(sourceMove); + case BattlerTagType.STURDY: + return new SturdyTag(sourceMove); + case BattlerTagType.PERISH_SONG: + return new PerishSongTag(turnCount); + case BattlerTagType.CENTER_OF_ATTENTION: + return new CenterOfAttentionTag(sourceMove); + case BattlerTagType.TRUANT: + return new TruantTag(); + case BattlerTagType.SLOW_START: + return new SlowStartTag(); + case BattlerTagType.PROTOSYNTHESIS: + return new WeatherHighestStatBoostTag(tagType, Abilities.PROTOSYNTHESIS, WeatherType.SUNNY, WeatherType.HARSH_SUN); + case BattlerTagType.QUARK_DRIVE: + return new TerrainHighestStatBoostTag(tagType, Abilities.QUARK_DRIVE, TerrainType.ELECTRIC); + case BattlerTagType.FLYING: + case BattlerTagType.UNDERGROUND: + case BattlerTagType.UNDERWATER: + case BattlerTagType.HIDDEN: + return new SemiInvulnerableTag(tagType, turnCount, sourceMove); + case BattlerTagType.FIRE_BOOST: + return new TypeBoostTag(tagType, sourceMove, Type.FIRE, 1.5, false); + case BattlerTagType.CRIT_BOOST: + return new CritBoostTag(tagType, sourceMove); + case BattlerTagType.DRAGON_CHEER: + return new DragonCheerTag(); + case BattlerTagType.ALWAYS_CRIT: + case BattlerTagType.IGNORE_ACCURACY: + return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove); + case BattlerTagType.ALWAYS_GET_HIT: + case BattlerTagType.RECEIVE_DOUBLE_DAMAGE: + return new BattlerTag(tagType, BattlerTagLapseType.PRE_MOVE, 1, sourceMove); + case BattlerTagType.BYPASS_SLEEP: + return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove); + case BattlerTagType.IGNORE_FLYING: + return new GroundedTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); + case BattlerTagType.ROOSTED: + return new RoostedTag(); + case BattlerTagType.BURNED_UP: + return new RemovedTypeTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); + case BattlerTagType.DOUBLE_SHOCKED: + return new RemovedTypeTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); + case BattlerTagType.SALT_CURED: + return new SaltCuredTag(sourceId); + case BattlerTagType.CURSED: + return new CursedTag(sourceId); + case BattlerTagType.CHARGED: + return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); + case BattlerTagType.FLOATING: + return new FloatingTag(tagType, sourceMove); + case BattlerTagType.MINIMIZED: + return new MinimizeTag(); + case BattlerTagType.DESTINY_BOND: + return new DestinyBondTag(sourceMove, sourceId); + case BattlerTagType.ICE_FACE: + return new IceFaceBlockDamageTag(tagType); + case BattlerTagType.DISGUISE: + return new FormBlockDamageTag(tagType); + case BattlerTagType.STOCKPILING: + return new StockpilingTag(sourceMove); + case BattlerTagType.OCTOLOCK: + return new OctolockTag(sourceId); + case BattlerTagType.DISABLED: + return new DisabledTag(sourceId); + case BattlerTagType.IGNORE_GHOST: + return new ExposedTag(tagType, sourceMove, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ]); + case BattlerTagType.IGNORE_DARK: + return new ExposedTag(tagType, sourceMove, Type.DARK, [ Type.PSYCHIC ]); + case BattlerTagType.GULP_MISSILE_ARROKUDA: + case BattlerTagType.GULP_MISSILE_PIKACHU: + return new GulpMissileTag(tagType, sourceMove); + case BattlerTagType.TAR_SHOT: + return new TarShotTag(); + case BattlerTagType.ELECTRIFIED: + return new ElectrifiedTag(); + case BattlerTagType.THROAT_CHOPPED: + return new ThroatChoppedTag(); + case BattlerTagType.GORILLA_TACTICS: + return new GorillaTacticsTag(); + case BattlerTagType.SUBSTITUTE: + return new SubstituteTag(sourceMove, sourceId); + case BattlerTagType.AUTOTOMIZED: + return new AutotomizedTag(); + case BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON: + return new MysteryEncounterPostSummonTag(); + case BattlerTagType.HEAL_BLOCK: + return new HealBlockTag(turnCount, sourceMove); + case BattlerTagType.TORMENT: + return new TormentTag(sourceId); + case BattlerTagType.TAUNT: + return new TauntTag(); + case BattlerTagType.IMPRISON: + return new ImprisonTag(sourceId); + case BattlerTagType.SYRUP_BOMB: + return new SyrupBombTag(sourceId); + case BattlerTagType.TELEKINESIS: + return new TelekinesisTag(sourceMove); + case BattlerTagType.POWER_TRICK: + return new PowerTrickTag(sourceMove, sourceId); + case BattlerTagType.NONE: + default: + return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); } } @@ -2847,3 +2970,22 @@ export function loadBattlerTag(source: BattlerTag | any): BattlerTag { tag.loadTag(source); return tag; } + +/** + * Helper function to verify that the current phase is a MoveEffectPhase and provide quick access to commonly used fields + * + * @param pokemon {@linkcode Pokemon} The Pokémon used to access the current phase + * @returns null if current phase is not MoveEffectPhase, otherwise Object containing the {@linkcode MoveEffectPhase}, and its + * corresponding {@linkcode Move} and user {@linkcode Pokemon} + */ +function getMoveEffectPhaseData(pokemon: Pokemon): {phase: MoveEffectPhase, attacker: Pokemon, move: Move} | null { + const phase = pokemon.scene.getCurrentPhase(); + if (phase instanceof MoveEffectPhase) { + return { + phase : phase, + attacker : phase.getPokemon(), + move : phase.move.getMove() + }; + } + return null; +} diff --git a/src/data/berry.ts b/src/data/berry.ts index 01325ee39dd..7243c4c1b2e 100644 --- a/src/data/berry.ts +++ b/src/data/berry.ts @@ -22,42 +22,42 @@ export type BerryPredicate = (pokemon: Pokemon) => boolean; export function getBerryPredicate(berryType: BerryType): BerryPredicate { switch (berryType) { - case BerryType.SITRUS: - return (pokemon: Pokemon) => pokemon.getHpRatio() < 0.5; - case BerryType.LUM: - return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED); - case BerryType.ENIGMA: - return (pokemon: Pokemon) => !!pokemon.turnData.attacksReceived.filter(a => a.result === HitResult.SUPER_EFFECTIVE).length; - case BerryType.LIECHI: - case BerryType.GANLON: - case BerryType.PETAYA: - case BerryType.APICOT: - case BerryType.SALAC: - return (pokemon: Pokemon) => { - const threshold = new Utils.NumberHolder(0.25); - // Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth - const stat: BattleStat = berryType - BerryType.ENIGMA; - applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); - return pokemon.getHpRatio() < threshold.value && pokemon.getStatStage(stat) < 6; - }; - case BerryType.LANSAT: - return (pokemon: Pokemon) => { - const threshold = new Utils.NumberHolder(0.25); - applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); - return pokemon.getHpRatio() < 0.25 && !pokemon.getTag(BattlerTagType.CRIT_BOOST); - }; - case BerryType.STARF: - return (pokemon: Pokemon) => { - const threshold = new Utils.NumberHolder(0.25); - applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); - return pokemon.getHpRatio() < 0.25; - }; - case BerryType.LEPPA: - return (pokemon: Pokemon) => { - const threshold = new Utils.NumberHolder(0.25); - applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); - return !!pokemon.getMoveset().find(m => !m?.getPpRatio()); - }; + case BerryType.SITRUS: + return (pokemon: Pokemon) => pokemon.getHpRatio() < 0.5; + case BerryType.LUM: + return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED); + case BerryType.ENIGMA: + return (pokemon: Pokemon) => !!pokemon.turnData.attacksReceived.filter(a => a.result === HitResult.SUPER_EFFECTIVE).length; + case BerryType.LIECHI: + case BerryType.GANLON: + case BerryType.PETAYA: + case BerryType.APICOT: + case BerryType.SALAC: + return (pokemon: Pokemon) => { + const threshold = new Utils.NumberHolder(0.25); + // Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth + const stat: BattleStat = berryType - BerryType.ENIGMA; + applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); + return pokemon.getHpRatio() < threshold.value && pokemon.getStatStage(stat) < 6; + }; + case BerryType.LANSAT: + return (pokemon: Pokemon) => { + const threshold = new Utils.NumberHolder(0.25); + applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); + return pokemon.getHpRatio() < 0.25 && !pokemon.getTag(BattlerTagType.CRIT_BOOST); + }; + case BerryType.STARF: + return (pokemon: Pokemon) => { + const threshold = new Utils.NumberHolder(0.25); + applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); + return pokemon.getHpRatio() < 0.25; + }; + case BerryType.LEPPA: + return (pokemon: Pokemon) => { + const threshold = new Utils.NumberHolder(0.25); + applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); + return !!pokemon.getMoveset().find(m => !m?.getPpRatio()); + }; } } @@ -65,70 +65,70 @@ export type BerryEffectFunc = (pokemon: Pokemon) => void; export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { switch (berryType) { - case BerryType.SITRUS: - case BerryType.ENIGMA: - return (pokemon: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - const hpHealed = new Utils.NumberHolder(Utils.toDmgValue(pokemon.getMaxHp() / 4)); - applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, hpHealed); - pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), - hpHealed.value, i18next.t("battle:hpHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: getBerryName(berryType) }), true)); - }; - case BerryType.LUM: - return (pokemon: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - if (pokemon.status) { - pokemon.scene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon))); - } - pokemon.resetStatus(true, true); - pokemon.updateInfo(); - }; - case BerryType.LIECHI: - case BerryType.GANLON: - case BerryType.PETAYA: - case BerryType.APICOT: - case BerryType.SALAC: - return (pokemon: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - // Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth - const stat: BattleStat = berryType - BerryType.ENIGMA; - const statStages = new Utils.NumberHolder(1); - applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages); - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], statStages.value)); - }; - case BerryType.LANSAT: - return (pokemon: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - pokemon.addTag(BattlerTagType.CRIT_BOOST); - }; - case BerryType.STARF: - return (pokemon: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - const randStat = Utils.randSeedInt(Stat.SPD, Stat.ATK); - const stages = new Utils.NumberHolder(2); - applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages); - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randStat ], stages.value)); - }; - case BerryType.LEPPA: - return (pokemon: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - const ppRestoreMove = pokemon.getMoveset().find(m => !m?.getPpRatio()) ? pokemon.getMoveset().find(m => !m?.getPpRatio()) : pokemon.getMoveset().find(m => m!.getPpRatio() < 1); // TODO: is this bang correct? - if (ppRestoreMove !== undefined) { + case BerryType.SITRUS: + case BerryType.ENIGMA: + return (pokemon: Pokemon) => { + if (pokemon.battleData) { + pokemon.battleData.berriesEaten.push(berryType); + } + const hpHealed = new Utils.NumberHolder(Utils.toDmgValue(pokemon.getMaxHp() / 4)); + applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, hpHealed); + pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), + hpHealed.value, i18next.t("battle:hpHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: getBerryName(berryType) }), true)); + }; + case BerryType.LUM: + return (pokemon: Pokemon) => { + if (pokemon.battleData) { + pokemon.battleData.berriesEaten.push(berryType); + } + if (pokemon.status) { + pokemon.scene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon))); + } + pokemon.resetStatus(true, true); + pokemon.updateInfo(); + }; + case BerryType.LIECHI: + case BerryType.GANLON: + case BerryType.PETAYA: + case BerryType.APICOT: + case BerryType.SALAC: + return (pokemon: Pokemon) => { + if (pokemon.battleData) { + pokemon.battleData.berriesEaten.push(berryType); + } + // Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth + const stat: BattleStat = berryType - BerryType.ENIGMA; + const statStages = new Utils.NumberHolder(1); + applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages); + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], statStages.value)); + }; + case BerryType.LANSAT: + return (pokemon: Pokemon) => { + if (pokemon.battleData) { + pokemon.battleData.berriesEaten.push(berryType); + } + pokemon.addTag(BattlerTagType.CRIT_BOOST); + }; + case BerryType.STARF: + return (pokemon: Pokemon) => { + if (pokemon.battleData) { + pokemon.battleData.berriesEaten.push(berryType); + } + const randStat = Utils.randSeedInt(Stat.SPD, Stat.ATK); + const stages = new Utils.NumberHolder(2); + applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages); + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randStat ], stages.value)); + }; + case BerryType.LEPPA: + return (pokemon: Pokemon) => { + if (pokemon.battleData) { + pokemon.battleData.berriesEaten.push(berryType); + } + const ppRestoreMove = pokemon.getMoveset().find(m => !m?.getPpRatio()) ? pokemon.getMoveset().find(m => !m?.getPpRatio()) : pokemon.getMoveset().find(m => m!.getPpRatio() < 1); // TODO: is this bang correct? + if (ppRestoreMove !== undefined) { ppRestoreMove!.ppUsed = Math.max(ppRestoreMove!.ppUsed - 10, 0); pokemon.scene.queueMessage(i18next.t("battle:ppHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: ppRestoreMove!.getName(), berryName: getBerryName(berryType) })); - } - }; + } + }; } } diff --git a/src/data/challenge.ts b/src/data/challenge.ts index e3ee818cee9..a64a90e5d14 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -185,7 +185,7 @@ export abstract class Challenge { */ getDescription(overrideValue?: number): string { const value = overrideValue ?? this.value; - return `${i18next.t([`challenges:${this.geti18nKey()}.desc.${value}`, `challenges:${this.geti18nKey()}.desc`])}`; + return `${i18next.t([ `challenges:${this.geti18nKey()}.desc.${value}`, `challenges:${this.geti18nKey()}.desc` ])}`; } /** @@ -414,9 +414,9 @@ export class SingleGenerationChallenge extends Challenge { } applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { - const generations = [pokemon.generation]; + const generations = [ pokemon.generation ]; if (soft) { - const speciesToCheck = [pokemon.speciesId]; + const speciesToCheck = [ pokemon.speciesId ]; while (speciesToCheck.length) { const checking = speciesToCheck.pop(); if (checking && pokemonEvolutions.hasOwnProperty(checking)) { @@ -448,21 +448,21 @@ export class SingleGenerationChallenge extends Challenge { applyFixedBattle(waveIndex: Number, battleConfig: FixedBattleConfig): boolean { let trainerTypes: TrainerType[] = []; switch (waveIndex) { - case 182: - trainerTypes = [ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, Utils.randSeedItem([ TrainerType.HALA, TrainerType.MOLAYNE ]), TrainerType.MARNIE_ELITE, TrainerType.RIKA ]; - break; - case 184: - trainerTypes = [ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY ]; - break; - case 186: - trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE]), TrainerType.LARRY_ELITE ]; - break; - case 188: - trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ]; - break; - case 190: - trainerTypes = [ TrainerType.BLUE, Utils.randSeedItem([ TrainerType.RED, TrainerType.LANCE_CHAMPION ]), Utils.randSeedItem([ TrainerType.STEVEN, TrainerType.WALLACE ]), TrainerType.CYNTHIA, Utils.randSeedItem([ TrainerType.ALDER, TrainerType.IRIS ]), TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, Utils.randSeedItem([ TrainerType.GEETA, TrainerType.NEMONA ]) ]; - break; + case 182: + trainerTypes = [ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, Utils.randSeedItem([ TrainerType.HALA, TrainerType.MOLAYNE ]), TrainerType.MARNIE_ELITE, TrainerType.RIKA ]; + break; + case 184: + trainerTypes = [ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY ]; + break; + case 186: + trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ]), TrainerType.LARRY_ELITE ]; + break; + case 188: + trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ]; + break; + case 190: + trainerTypes = [ TrainerType.BLUE, Utils.randSeedItem([ TrainerType.RED, TrainerType.LANCE_CHAMPION ]), Utils.randSeedItem([ TrainerType.STEVEN, TrainerType.WALLACE ]), TrainerType.CYNTHIA, Utils.randSeedItem([ TrainerType.ALDER, TrainerType.IRIS ]), TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, Utils.randSeedItem([ TrainerType.GEETA, TrainerType.NEMONA ]) ]; + break; } if (trainerTypes.length === 0) { return false; @@ -528,10 +528,10 @@ interface monotypeOverride { */ export class SingleTypeChallenge extends Challenge { private static TYPE_OVERRIDES: monotypeOverride[] = [ - {species: Species.CASTFORM, type: Type.NORMAL, fusion: false}, + { species: Species.CASTFORM, type: Type.NORMAL, fusion: false }, ]; // TODO: Find a solution for all Pokemon with this ssui issue, including Basculin and Burmy - private static SPECIES_OVERRIDES: Species[] = [Species.MELOETTA]; + private static SPECIES_OVERRIDES: Species[] = [ Species.MELOETTA ]; constructor() { super(Challenges.SINGLE_TYPE, 18); @@ -539,9 +539,9 @@ export class SingleTypeChallenge extends Challenge { override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex); - const types = [speciesForm.type1, speciesForm.type2]; + const types = [ speciesForm.type1, speciesForm.type2 ]; if (soft && !SingleTypeChallenge.SPECIES_OVERRIDES.includes(pokemon.speciesId)) { - const speciesToCheck = [pokemon.speciesId]; + const speciesToCheck = [ pokemon.speciesId ]; while (speciesToCheck.length) { const checking = speciesToCheck.pop(); if (checking && pokemonEvolutions.hasOwnProperty(checking)) { @@ -606,9 +606,9 @@ export class SingleTypeChallenge extends Challenge { overrideValue = this.value; } const type = i18next.t(`pokemonInfo:Type.${Type[this.value - 1]}`); - const typeColor = `[color=${TypeColor[Type[this.value-1]]}][shadow=${TypeShadow[Type[this.value-1]]}]${type}[/shadow][/color]`; + const typeColor = `[color=${TypeColor[Type[this.value - 1]]}][shadow=${TypeShadow[Type[this.value - 1]]}]${type}[/shadow][/color]`; const defaultDesc = i18next.t("challenges:singleType.desc_default"); - const typeDesc = i18next.t("challenges:singleType.desc", {type: typeColor}); + const typeDesc = i18next.t("challenges:singleType.desc", { type: typeColor }); return this.value === 0 ? defaultDesc : typeDesc; } @@ -653,7 +653,7 @@ export class FreshStartChallenge extends Challenge { pokemon.shiny = false; // Not shiny pokemon.variant = 0; // Not shiny pokemon.formIndex = 0; // Froakie should be base form - pokemon.ivs = [10, 10, 10, 10, 10, 10]; // Default IVs of 10 for all stats + pokemon.ivs = [ 10, 10, 10, 10, 10, 10 ]; // Default IVs of 10 for all stats return true; } @@ -891,45 +891,45 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType gameMode.challenges.forEach(c => { if (c.value !== 0) { switch (challengeType) { - case ChallengeType.STARTER_CHOICE: - ret ||= c.applyStarterChoice(args[0], args[1], args[2], args[3]); - break; - case ChallengeType.STARTER_POINTS: - ret ||= c.applyStarterPoints(args[0]); - break; - case ChallengeType.STARTER_COST: - ret ||= c.applyStarterCost(args[0], args[1]); - break; - case ChallengeType.STARTER_MODIFY: - ret ||= c.applyStarterModify(args[0]); - break; - case ChallengeType.POKEMON_IN_BATTLE: - ret ||= c.applyPokemonInBattle(args[0], args[1]); - break; - case ChallengeType.FIXED_BATTLES: - ret ||= c.applyFixedBattle(args[0], args[1]); - break; - case ChallengeType.TYPE_EFFECTIVENESS: - ret ||= c.applyTypeEffectiveness(args[0]); - break; - case ChallengeType.AI_LEVEL: - ret ||= c.applyLevelChange(args[0], args[1], args[2], args[3]); - break; - case ChallengeType.AI_MOVE_SLOTS: - ret ||= c.applyMoveSlot(args[0], args[1]); - break; - case ChallengeType.PASSIVE_ACCESS: - ret ||= c.applyPassiveAccess(args[0], args[1]); - break; - case ChallengeType.GAME_MODE_MODIFY: - ret ||= c.applyGameModeModify(gameMode); - break; - case ChallengeType.MOVE_ACCESS: - ret ||= c.applyMoveAccessLevel(args[0], args[1], args[2], args[3]); - break; - case ChallengeType.MOVE_WEIGHT: - ret ||= c.applyMoveWeight(args[0], args[1], args[2], args[3]); - break; + case ChallengeType.STARTER_CHOICE: + ret ||= c.applyStarterChoice(args[0], args[1], args[2], args[3]); + break; + case ChallengeType.STARTER_POINTS: + ret ||= c.applyStarterPoints(args[0]); + break; + case ChallengeType.STARTER_COST: + ret ||= c.applyStarterCost(args[0], args[1]); + break; + case ChallengeType.STARTER_MODIFY: + ret ||= c.applyStarterModify(args[0]); + break; + case ChallengeType.POKEMON_IN_BATTLE: + ret ||= c.applyPokemonInBattle(args[0], args[1]); + break; + case ChallengeType.FIXED_BATTLES: + ret ||= c.applyFixedBattle(args[0], args[1]); + break; + case ChallengeType.TYPE_EFFECTIVENESS: + ret ||= c.applyTypeEffectiveness(args[0]); + break; + case ChallengeType.AI_LEVEL: + ret ||= c.applyLevelChange(args[0], args[1], args[2], args[3]); + break; + case ChallengeType.AI_MOVE_SLOTS: + ret ||= c.applyMoveSlot(args[0], args[1]); + break; + case ChallengeType.PASSIVE_ACCESS: + ret ||= c.applyPassiveAccess(args[0], args[1]); + break; + case ChallengeType.GAME_MODE_MODIFY: + ret ||= c.applyGameModeModify(gameMode); + break; + case ChallengeType.MOVE_ACCESS: + ret ||= c.applyMoveAccessLevel(args[0], args[1], args[2], args[3]); + break; + case ChallengeType.MOVE_WEIGHT: + ret ||= c.applyMoveWeight(args[0], args[1], args[2], args[3]); + break; } } }); @@ -943,18 +943,18 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType */ export function copyChallenge(source: Challenge | any): Challenge { switch (source.id) { - case Challenges.SINGLE_GENERATION: - return SingleGenerationChallenge.loadChallenge(source); - case Challenges.SINGLE_TYPE: - return SingleTypeChallenge.loadChallenge(source); - case Challenges.LOWER_MAX_STARTER_COST: - return LowerStarterMaxCostChallenge.loadChallenge(source); - case Challenges.LOWER_STARTER_POINTS: - return LowerStarterPointsChallenge.loadChallenge(source); - case Challenges.FRESH_START: - return FreshStartChallenge.loadChallenge(source); - case Challenges.INVERSE_BATTLE: - return InverseBattleChallenge.loadChallenge(source); + case Challenges.SINGLE_GENERATION: + return SingleGenerationChallenge.loadChallenge(source); + case Challenges.SINGLE_TYPE: + return SingleTypeChallenge.loadChallenge(source); + case Challenges.LOWER_MAX_STARTER_COST: + return LowerStarterMaxCostChallenge.loadChallenge(source); + case Challenges.LOWER_STARTER_POINTS: + return LowerStarterPointsChallenge.loadChallenge(source); + case Challenges.FRESH_START: + return FreshStartChallenge.loadChallenge(source); + case Challenges.INVERSE_BATTLE: + return InverseBattleChallenge.loadChallenge(source); } throw new Error("Unknown challenge copied"); } diff --git a/src/data/mystery-encounters/mystery-encounter-pokemon-data.ts b/src/data/custom-pokemon-data.ts similarity index 68% rename from src/data/mystery-encounters/mystery-encounter-pokemon-data.ts rename to src/data/custom-pokemon-data.ts index fc6ce313d41..2e94123fc84 100644 --- a/src/data/mystery-encounters/mystery-encounter-pokemon-data.ts +++ b/src/data/custom-pokemon-data.ts @@ -1,18 +1,20 @@ import { Abilities } from "#enums/abilities"; import { Type } from "#app/data/type"; import { isNullOrUndefined } from "#app/utils"; +import { Nature } from "#enums/nature"; /** * Data that can customize a Pokemon in non-standard ways from its Species - * Currently only used by Mystery Encounters, may need to be renamed if it becomes more widely used + * Currently only used by Mystery Encounters and Mints. */ -export class MysteryEncounterPokemonData { +export class CustomPokemonData { public spriteScale: number; public ability: Abilities | -1; public passive: Abilities | -1; + public nature: Nature | -1; public types: Type[]; - constructor(data?: MysteryEncounterPokemonData | Partial) { + constructor(data?: CustomPokemonData | Partial) { if (!isNullOrUndefined(data)) { Object.assign(this, data); } @@ -20,6 +22,7 @@ export class MysteryEncounterPokemonData { this.spriteScale = this.spriteScale ?? -1; this.ability = this.ability ?? -1; this.passive = this.passive ?? -1; + this.nature = this.nature ?? -1; this.types = this.types ?? []; } } diff --git a/src/data/dialogue.ts b/src/data/dialogue.ts index 10c2a155e15..0ae6d8e2c16 100644 --- a/src/data/dialogue.ts +++ b/src/data/dialogue.ts @@ -3134,44 +3134,44 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { export const doubleBattleDialogue = { "blue_red_double": { - encounter: ["doubleBattleDialogue:blue_red_double.encounter.1"], - victory: ["doubleBattleDialogue:blue_red_double.victory.1"] + encounter: [ "doubleBattleDialogue:blue_red_double.encounter.1" ], + victory: [ "doubleBattleDialogue:blue_red_double.victory.1" ] }, "red_blue_double": { - encounter: ["doubleBattleDialogue:red_blue_double.encounter.1"], - victory: ["doubleBattleDialogue:red_blue_double.victory.1"] + encounter: [ "doubleBattleDialogue:red_blue_double.encounter.1" ], + victory: [ "doubleBattleDialogue:red_blue_double.victory.1" ] }, "tate_liza_double": { - encounter: ["doubleBattleDialogue:tate_liza_double.encounter.1"], - victory: ["doubleBattleDialogue:tate_liza_double.victory.1"] + encounter: [ "doubleBattleDialogue:tate_liza_double.encounter.1" ], + victory: [ "doubleBattleDialogue:tate_liza_double.victory.1" ] }, "liza_tate_double": { - encounter: ["doubleBattleDialogue:liza_tate_double.encounter.1"], - victory: [ "doubleBattleDialogue:liza_tate_double.victory.1"] + encounter: [ "doubleBattleDialogue:liza_tate_double.encounter.1" ], + victory: [ "doubleBattleDialogue:liza_tate_double.victory.1" ] }, "wallace_steven_double": { - encounter: [ "doubleBattleDialogue:wallace_steven_double.encounter.1"], - victory: [ "doubleBattleDialogue:wallace_steven_double.victory.1"] + encounter: [ "doubleBattleDialogue:wallace_steven_double.encounter.1" ], + victory: [ "doubleBattleDialogue:wallace_steven_double.victory.1" ] }, "steven_wallace_double": { - encounter: [ "doubleBattleDialogue:steven_wallace_double.encounter.1"], - victory: [ "doubleBattleDialogue:steven_wallace_double.victory.1"] + encounter: [ "doubleBattleDialogue:steven_wallace_double.encounter.1" ], + victory: [ "doubleBattleDialogue:steven_wallace_double.victory.1" ] }, "alder_iris_double": { - encounter: [ "doubleBattleDialogue:alder_iris_double.encounter.1"], - victory: [ "doubleBattleDialogue:alder_iris_double.victory.1"] + encounter: [ "doubleBattleDialogue:alder_iris_double.encounter.1" ], + victory: [ "doubleBattleDialogue:alder_iris_double.victory.1" ] }, "iris_alder_double": { - encounter: [ "doubleBattleDialogue:iris_alder_double.encounter.1"], - victory: [ "doubleBattleDialogue:iris_alder_double.victory.1"] + encounter: [ "doubleBattleDialogue:iris_alder_double.encounter.1" ], + victory: [ "doubleBattleDialogue:iris_alder_double.victory.1" ] }, "marnie_piers_double": { - encounter: [ "doubleBattleDialogue:marnie_piers_double.encounter.1"], - victory: [ "doubleBattleDialogue:marnie_piers_double.victory.1"] + encounter: [ "doubleBattleDialogue:marnie_piers_double.encounter.1" ], + victory: [ "doubleBattleDialogue:marnie_piers_double.victory.1" ] }, "piers_marnie_double": { - encounter: [ "doubleBattleDialogue:piers_marnie_double.encounter.1"], - victory: [ "doubleBattleDialogue:piers_marnie_double.victory.1"] + encounter: [ "doubleBattleDialogue:piers_marnie_double.encounter.1" ], + victory: [ "doubleBattleDialogue:piers_marnie_double.victory.1" ] }, @@ -3204,7 +3204,7 @@ export function initTrainerTypeDialogue(): void { const trainerTypes = Object.keys(trainerTypeDialogue).map(t => parseInt(t) as TrainerType); for (const trainerType of trainerTypes) { const messages = trainerTypeDialogue[trainerType]; - const messageTypes = ["encounter", "victory", "defeat"]; + const messageTypes = [ "encounter", "victory", "defeat" ]; for (const messageType of messageTypes) { if (Array.isArray(messages)) { if (messages[0][messageType]) { diff --git a/src/data/egg-hatch-data.ts b/src/data/egg-hatch-data.ts index e754a9205c4..ba553b55c4f 100644 --- a/src/data/egg-hatch-data.ts +++ b/src/data/egg-hatch-data.ts @@ -48,7 +48,7 @@ export class EggHatchData { seenCount: currDexEntry.seenCount, caughtCount: currDexEntry.caughtCount, hatchedCount: currDexEntry.hatchedCount, - ivs: [...currDexEntry.ivs] + ivs: [ ...currDexEntry.ivs ] }; this.starterDataEntryBeforeUpdate = { moveset: currStarterDataEntry.moveset, diff --git a/src/data/egg.ts b/src/data/egg.ts index c83554f2a19..f7d109dfa62 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -11,6 +11,7 @@ import { EggTier } from "#enums/egg-type"; import { Species } from "#enums/species"; import { EggSourceType } from "#enums/egg-source-types"; import { MANAPHY_EGG_MANAPHY_RATE, SAME_SPECIES_EGG_HA_RATE, GACHA_EGG_HA_RATE, GACHA_DEFAULT_RARE_EGGMOVE_RATE, SAME_SPECIES_EGG_RARE_EGGMOVE_RATE, GACHA_MOVE_UP_RARE_EGGMOVE_RATE, GACHA_DEFAULT_SHINY_RATE, GACHA_SHINY_UP_SHINY_RATE, SAME_SPECIES_EGG_SHINY_RATE, EGG_PITY_LEGENDARY_THRESHOLD, EGG_PITY_EPIC_THRESHOLD, EGG_PITY_RARE_THRESHOLD, SHINY_VARIANT_CHANCE, SHINY_EPIC_CHANCE, GACHA_DEFAULT_COMMON_EGG_THRESHOLD, GACHA_DEFAULT_RARE_EGG_THRESHOLD, GACHA_DEFAULT_EPIC_EGG_THRESHOLD, GACHA_LEGENDARY_UP_THRESHOLD_OFFSET, HATCH_WAVES_MANAPHY_EGG, HATCH_WAVES_COMMON_EGG, HATCH_WAVES_RARE_EGG, HATCH_WAVES_EPIC_EGG, HATCH_WAVES_LEGENDARY_EGG } from "#app/data/balance/rates"; +import { speciesEggTiers } from "#app/data/balance/species-egg-tiers"; export const EGG_SEED = 1073741824; @@ -160,7 +161,7 @@ export class Egg { // Override egg tier and hatchwaves if species was given if (eggOptions?.species) { - this._tier = this.getEggTierFromSpeciesStarterValue(); + this._tier = this.getEggTier(); this._hatchWaves = eggOptions.hatchWaves ?? this.getEggTierDefaultHatchWaves(); } // If species has no variant, set variantTier to common. This needs to @@ -261,14 +262,14 @@ export class Egg { return "Manaphy"; } switch (this.tier) { - case EggTier.GREAT: - return i18next.t("egg:greatTier"); - case EggTier.ULTRA: - return i18next.t("egg:ultraTier"); - case EggTier.MASTER: - return i18next.t("egg:masterTier"); - default: - return i18next.t("egg:defaultTier"); + case EggTier.RARE: + return i18next.t("egg:greatTier"); + case EggTier.EPIC: + return i18next.t("egg:ultraTier"); + case EggTier.LEGENDARY: + return i18next.t("egg:masterTier"); + default: + return i18next.t("egg:defaultTier"); } } @@ -287,19 +288,19 @@ export class Egg { public getEggTypeDescriptor(scene: BattleScene): string { switch (this.sourceType) { - case EggSourceType.SAME_SPECIES_EGG: - return this._eggDescriptor ?? i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName()}); - case EggSourceType.GACHA_LEGENDARY: - return this._eggDescriptor ?? `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`; - case EggSourceType.GACHA_SHINY: - return this._eggDescriptor ?? i18next.t("egg:gachaTypeShiny"); - case EggSourceType.GACHA_MOVE: - return this._eggDescriptor ?? i18next.t("egg:gachaTypeMove"); - case EggSourceType.EVENT: - return this._eggDescriptor ?? i18next.t("egg:eventType"); - default: - console.warn("getEggTypeDescriptor case not defined. Returning default empty string"); - return ""; + case EggSourceType.SAME_SPECIES_EGG: + return this._eggDescriptor ?? i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName() }); + case EggSourceType.GACHA_LEGENDARY: + return this._eggDescriptor ?? `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`; + case EggSourceType.GACHA_SHINY: + return this._eggDescriptor ?? i18next.t("egg:gachaTypeShiny"); + case EggSourceType.GACHA_MOVE: + return this._eggDescriptor ?? i18next.t("egg:gachaTypeMove"); + case EggSourceType.EVENT: + return this._eggDescriptor ?? i18next.t("egg:eventType"); + default: + console.warn("getEggTypeDescriptor case not defined. Returning default empty string"); + return ""; } } @@ -314,14 +315,14 @@ export class Egg { private rollEggMoveIndex() { let baseChance = GACHA_DEFAULT_RARE_EGGMOVE_RATE; switch (this._sourceType) { - case EggSourceType.SAME_SPECIES_EGG: - baseChance = SAME_SPECIES_EGG_RARE_EGGMOVE_RATE; - break; - case EggSourceType.GACHA_MOVE: - baseChance = GACHA_MOVE_UP_RARE_EGGMOVE_RATE; - break; - default: - break; + case EggSourceType.SAME_SPECIES_EGG: + baseChance = SAME_SPECIES_EGG_RARE_EGGMOVE_RATE; + break; + case EggSourceType.GACHA_MOVE: + baseChance = GACHA_MOVE_UP_RARE_EGGMOVE_RATE; + break; + default: + break; } const tierMultiplier = this.isManaphyEgg() ? 2 : Math.pow(2, 3 - this.tier); @@ -334,12 +335,12 @@ export class Egg { } switch (eggTier ?? this._tier) { - case EggTier.COMMON: - return HATCH_WAVES_COMMON_EGG; - case EggTier.GREAT: - return HATCH_WAVES_RARE_EGG; - case EggTier.ULTRA: - return HATCH_WAVES_EPIC_EGG; + case EggTier.COMMON: + return HATCH_WAVES_COMMON_EGG; + case EggTier.RARE: + return HATCH_WAVES_RARE_EGG; + case EggTier.EPIC: + return HATCH_WAVES_EPIC_EGG; } return HATCH_WAVES_LEGENDARY_EGG; } @@ -347,7 +348,7 @@ export class Egg { private rollEggTier(): EggTier { const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0; const tierValue = Utils.randInt(256); - return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.GREAT : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER; + return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.RARE : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.EPIC : EggTier.LEGENDARY; } private rollSpecies(scene: BattleScene): Species | null { @@ -367,7 +368,7 @@ export class Egg { */ const rand = (Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1); return rand ? Species.PHIONE : Species.MANAPHY; - } else if (this.tier === EggTier.MASTER + } else if (this.tier === EggTier.LEGENDARY && this._sourceType === EggSourceType.GACHA_LEGENDARY) { if (!Utils.randSeedInt(2)) { return getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp); @@ -378,28 +379,28 @@ export class Egg { let maxStarterValue: integer; switch (this.tier) { - case EggTier.GREAT: - minStarterValue = 4; - maxStarterValue = 5; - break; - case EggTier.ULTRA: - minStarterValue = 6; - maxStarterValue = 7; - break; - case EggTier.MASTER: - minStarterValue = 8; - maxStarterValue = 9; - break; - default: - minStarterValue = 1; - maxStarterValue = 3; - break; + case EggTier.RARE: + minStarterValue = 4; + maxStarterValue = 5; + break; + case EggTier.EPIC: + minStarterValue = 6; + maxStarterValue = 7; + break; + case EggTier.LEGENDARY: + minStarterValue = 8; + maxStarterValue = 9; + break; + default: + minStarterValue = 1; + maxStarterValue = 3; + break; } - const ignoredSpecies = [Species.PHIONE, Species.MANAPHY, Species.ETERNATUS]; + const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ]; - let speciesPool = Object.keys(speciesStarterCosts) - .filter(s => speciesStarterCosts[s] >= minStarterValue && speciesStarterCosts[s] <= maxStarterValue) + let speciesPool = Object.keys(speciesEggTiers) + .filter(s => speciesEggTiers[s] === this.tier) .map(s => parseInt(s) as Species) .filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1); @@ -430,7 +431,9 @@ export class Egg { let totalWeight = 0; const speciesWeights : number[] = []; for (const speciesId of speciesPool) { - let weight = Math.floor((((maxStarterValue - speciesStarterCosts[speciesId]) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100); + // Accounts for species that have starter costs outside of the normal range for their EggTier + const speciesCostClamped = Phaser.Math.Clamp(speciesStarterCosts[speciesId], minStarterValue, maxStarterValue); + let weight = Math.floor((((maxStarterValue - speciesCostClamped) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100); const species = getPokemonSpecies(speciesId); if (species.isRegional()) { weight = Math.floor(weight / 2); @@ -466,14 +469,14 @@ export class Egg { private rollShiny(): boolean { let shinyChance = GACHA_DEFAULT_SHINY_RATE; switch (this._sourceType) { - case EggSourceType.GACHA_SHINY: - shinyChance = GACHA_SHINY_UP_SHINY_RATE; - break; - case EggSourceType.SAME_SPECIES_EGG: - shinyChance = SAME_SPECIES_EGG_SHINY_RATE; - break; - default: - break; + case EggSourceType.GACHA_SHINY: + shinyChance = GACHA_SHINY_UP_SHINY_RATE; + break; + case EggSourceType.SAME_SPECIES_EGG: + shinyChance = SAME_SPECIES_EGG_SHINY_RATE; + break; + default: + break; } return !Utils.randSeedInt(shinyChance); @@ -498,16 +501,16 @@ export class Egg { private checkForPityTierOverrides(scene: BattleScene): void { const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0; - scene.gameData.eggPity[EggTier.GREAT] += 1; - scene.gameData.eggPity[EggTier.ULTRA] += 1; - scene.gameData.eggPity[EggTier.MASTER] += 1 + tierValueOffset; + scene.gameData.eggPity[EggTier.RARE] += 1; + scene.gameData.eggPity[EggTier.EPIC] += 1; + scene.gameData.eggPity[EggTier.LEGENDARY] += 1 + tierValueOffset; // These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered. - if (scene.gameData.eggPity[EggTier.MASTER] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) { - this._tier = EggTier.MASTER; - } else if (scene.gameData.eggPity[EggTier.ULTRA] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) { - this._tier = EggTier.ULTRA; - } else if (scene.gameData.eggPity[EggTier.GREAT] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) { - this._tier = EggTier.GREAT; + if (scene.gameData.eggPity[EggTier.LEGENDARY] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) { + this._tier = EggTier.LEGENDARY; + } else if (scene.gameData.eggPity[EggTier.EPIC] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) { + this._tier = EggTier.EPIC; + } else if (scene.gameData.eggPity[EggTier.RARE] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) { + this._tier = EggTier.RARE; } scene.gameData.eggPity[this._tier] = 0; } @@ -516,38 +519,24 @@ export class Egg { scene.gameData.gameStats.eggsPulled++; if (this.isManaphyEgg()) { scene.gameData.gameStats.manaphyEggsPulled++; - this._hatchWaves = this.getEggTierDefaultHatchWaves(EggTier.ULTRA); + this._hatchWaves = this.getEggTierDefaultHatchWaves(EggTier.EPIC); return; } switch (this.tier) { - case EggTier.GREAT: - scene.gameData.gameStats.rareEggsPulled++; - break; - case EggTier.ULTRA: - scene.gameData.gameStats.epicEggsPulled++; - break; - case EggTier.MASTER: - scene.gameData.gameStats.legendaryEggsPulled++; - break; + case EggTier.RARE: + scene.gameData.gameStats.rareEggsPulled++; + break; + case EggTier.EPIC: + scene.gameData.gameStats.epicEggsPulled++; + break; + case EggTier.LEGENDARY: + scene.gameData.gameStats.legendaryEggsPulled++; + break; } } - private getEggTierFromSpeciesStarterValue(): EggTier { - const speciesStartValue = speciesStarterCosts[this.species]; - if (speciesStartValue >= 1 && speciesStartValue <= 3) { - return EggTier.COMMON; - } - if (speciesStartValue >= 4 && speciesStartValue <= 5) { - return EggTier.GREAT; - } - if (speciesStartValue >= 6 && speciesStartValue <= 7) { - return EggTier.ULTRA; - } - if (speciesStartValue >= 8) { - return EggTier.MASTER; - } - - return EggTier.COMMON; + private getEggTier(): EggTier { + return speciesEggTiers[this.species]; } //// @@ -555,11 +544,15 @@ export class Egg { //// } -export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species { - const legendarySpecies = Object.entries(speciesStarterCosts) - .filter(s => s[1] >= 8 && s[1] <= 9) +export function getValidLegendaryGachaSpecies() : Species[] { + return Object.entries(speciesEggTiers) + .filter(s => s[1] === EggTier.LEGENDARY) .map(s => parseInt(s[0])) - .filter(s => getPokemonSpecies(s).isObtainable()); + .filter(s => getPokemonSpecies(s).isObtainable() && s !== Species.ETERNATUS); +} + +export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species { + const legendarySpecies = getValidLegendaryGachaSpecies(); let ret: Species; @@ -579,17 +572,9 @@ export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timesta /** * Check for a given species EggTier Value - * @param species - Species for wich we will check the egg tier it belongs to + * @param pokemonSpecies - Species for wich we will check the egg tier it belongs to * @returns The egg tier of a given pokemon species */ export function getEggTierForSpecies(pokemonSpecies :PokemonSpecies): EggTier { - const speciesBaseValue = speciesStarterCosts[pokemonSpecies.getRootSpeciesId()]; - if (speciesBaseValue <= 3) { - return EggTier.COMMON; - } else if (speciesBaseValue <= 5) { - return EggTier.GREAT; - } else if (speciesBaseValue <= 7) { - return EggTier.ULTRA; - } - return EggTier.MASTER; + return speciesEggTiers[pokemonSpecies.getRootSpeciesId()]; } diff --git a/src/data/exp.ts b/src/data/exp.ts index 3b332eb7cf2..c03abddadfc 100644 --- a/src/data/exp.ts +++ b/src/data/exp.ts @@ -28,24 +28,24 @@ export function getLevelTotalExp(level: integer, growthRate: GrowthRate): intege let ret: integer; switch (growthRate) { - case GrowthRate.ERRATIC: - ret = (Math.pow(level, 4) + (Math.pow(level, 3) * 2000)) / 3500; - break; - case GrowthRate.FAST: - ret = Math.pow(level, 3) * 4 / 5; - break; - case GrowthRate.MEDIUM_FAST: - ret = Math.pow(level, 3); - break; - case GrowthRate.MEDIUM_SLOW: - ret = (Math.pow(level, 3) * 6 / 5) - (15 * Math.pow(level, 2)) + (100 * level) - 140; - break; - case GrowthRate.SLOW: - ret = Math.pow(level, 3) * 5 / 4; - break; - case GrowthRate.FLUCTUATING: - ret = (Math.pow(level, 3) * ((level / 2) + 8)) * 4 / (100 + level); - break; + case GrowthRate.ERRATIC: + ret = (Math.pow(level, 4) + (Math.pow(level, 3) * 2000)) / 3500; + break; + case GrowthRate.FAST: + ret = Math.pow(level, 3) * 4 / 5; + break; + case GrowthRate.MEDIUM_FAST: + ret = Math.pow(level, 3); + break; + case GrowthRate.MEDIUM_SLOW: + ret = (Math.pow(level, 3) * 6 / 5) - (15 * Math.pow(level, 2)) + (100 * level) - 140; + break; + case GrowthRate.SLOW: + ret = Math.pow(level, 3) * 5 / 4; + break; + case GrowthRate.FLUCTUATING: + ret = (Math.pow(level, 3) * ((level / 2) + 8)) * 4 / (100 + level); + break; } if (growthRate !== GrowthRate.MEDIUM_FAST) { @@ -61,17 +61,17 @@ export function getLevelRelExp(level: integer, growthRate: GrowthRate): number { export function getGrowthRateColor(growthRate: GrowthRate, shadow?: boolean) { switch (growthRate) { - case GrowthRate.ERRATIC: - return !shadow ? "#f85888" : "#906060"; - case GrowthRate.FAST: - return !shadow ? "#f8d030" : "#b8a038"; - case GrowthRate.MEDIUM_FAST: - return !shadow ? "#78c850" : "#588040"; - case GrowthRate.MEDIUM_SLOW: - return !shadow ? "#6890f0" : "#807870"; - case GrowthRate.SLOW: - return !shadow ? "#f08030" : "#c03028"; - case GrowthRate.FLUCTUATING: - return !shadow ? "#a040a0" : "#483850"; + case GrowthRate.ERRATIC: + return !shadow ? "#f85888" : "#906060"; + case GrowthRate.FAST: + return !shadow ? "#f8d030" : "#b8a038"; + case GrowthRate.MEDIUM_FAST: + return !shadow ? "#78c850" : "#588040"; + case GrowthRate.MEDIUM_SLOW: + return !shadow ? "#6890f0" : "#807870"; + case GrowthRate.SLOW: + return !shadow ? "#f08030" : "#c03028"; + case GrowthRate.FLUCTUATING: + return !shadow ? "#a040a0" : "#483850"; } } diff --git a/src/data/gender.ts b/src/data/gender.ts index 0d4b76d8bd1..dae7723dd85 100644 --- a/src/data/gender.ts +++ b/src/data/gender.ts @@ -6,20 +6,20 @@ export enum Gender { export function getGenderSymbol(gender: Gender) { switch (gender) { - case Gender.MALE: - return "♂"; - case Gender.FEMALE: - return "♀"; + case Gender.MALE: + return "♂"; + case Gender.FEMALE: + return "♀"; } return ""; } export function getGenderColor(gender: Gender, shadow?: boolean) { switch (gender) { - case Gender.MALE: - return shadow ? "#006090" : "#40c8f8"; - case Gender.FEMALE: - return shadow ? "#984038" : "#f89890"; + case Gender.MALE: + return shadow ? "#006090" : "#40c8f8"; + case Gender.FEMALE: + return shadow ? "#984038" : "#f89890"; } return "#ffffff"; } diff --git a/src/data/move.ts b/src/data/move.ts index 748f81cdd8b..c5b14304fb2 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -8,7 +8,7 @@ import { Constructor, NumberHolder } from "#app/utils"; import * as Utils from "../utils"; import { WeatherType } from "./weather"; import { ArenaTagSide, ArenaTrapTag, WeakenMoveTypeTag } from "./arena-tag"; -import { allAbilities, AllyMoveCategoryPowerBoostAbAttr, applyAbAttrs, applyPostAttackAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, BlockItemTheftAbAttr, BlockNonDirectDamageAbAttr, BlockOneHitKOAbAttr, BlockRecoilDamageAttr, ConfusionOnStatusEffectAbAttr, FieldMoveTypePowerBoostAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, HealFromBerryUseAbAttr, IgnoreContactAbAttr, IgnoreMoveEffectsAbAttr, IgnoreProtectOnContactAbAttr, MaxMultiHitAbAttr, MoveAbilityBypassAbAttr, MoveEffectChanceMultiplierAbAttr, MoveTypeChangeAbAttr, ReverseDrainAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, UnswappableAbilityAbAttr, UserFieldMoveTypePowerBoostAbAttr, VariableMovePowerAbAttr, WonderSkinAbAttr } from "./ability"; +import { allAbilities, AllyMoveCategoryPowerBoostAbAttr, applyAbAttrs, applyPostAttackAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, BlockItemTheftAbAttr, BlockNonDirectDamageAbAttr, BlockOneHitKOAbAttr, BlockRecoilDamageAttr, ConfusionOnStatusEffectAbAttr, FieldMoveTypePowerBoostAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, HealFromBerryUseAbAttr, IgnoreContactAbAttr, IgnoreMoveEffectsAbAttr, IgnoreProtectOnContactAbAttr, InfiltratorAbAttr, MaxMultiHitAbAttr, MoveAbilityBypassAbAttr, MoveEffectChanceMultiplierAbAttr, MoveTypeChangeAbAttr, ReverseDrainAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, UnswappableAbilityAbAttr, UserFieldMoveTypePowerBoostAbAttr, VariableMovePowerAbAttr, WonderSkinAbAttr } from "./ability"; import { AttackTypeBoosterModifier, BerryModifier, PokemonHeldItemModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PreserveBerryModifier } from "../modifier/modifier"; import { BattlerIndex, BattleType } from "../battle"; import { TerrainType } from "./terrain"; @@ -25,7 +25,6 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { MoveUsedEvent } from "#app/events/battle-scene"; import { BATTLE_STATS, type BattleStat, EFFECTIVE_STATS, type EffectiveStat, getStatKey, Stat } from "#app/enums/stat"; -import { PartyStatusCurePhase } from "#app/phases/party-status-cure-phase"; import { BattleEndPhase } from "#app/phases/battle-end-phase"; import { MoveEndPhase } from "#app/phases/move-end-phase"; import { MovePhase } from "#app/phases/move-phase"; @@ -34,6 +33,7 @@ import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { SwitchPhase } from "#app/phases/switch-phase"; import { SwitchSummonPhase } from "#app/phases/switch-summon-phase"; +import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; import { SpeciesFormChangeRevertWeatherFormTrigger } from "./pokemon-forms"; import { GameMode } from "#app/game-mode"; import { applyChallenges, ChallengeType } from "./challenge"; @@ -274,38 +274,41 @@ export default class Move implements Localizable { */ isMultiTarget(): boolean { switch (this.moveTarget) { - case MoveTarget.ALL_OTHERS: - case MoveTarget.ALL_NEAR_OTHERS: - case MoveTarget.ALL_NEAR_ENEMIES: - case MoveTarget.ALL_ENEMIES: - case MoveTarget.USER_AND_ALLIES: - case MoveTarget.ALL: - case MoveTarget.USER_SIDE: - case MoveTarget.ENEMY_SIDE: - case MoveTarget.BOTH_SIDES: - return true; + case MoveTarget.ALL_OTHERS: + case MoveTarget.ALL_NEAR_OTHERS: + case MoveTarget.ALL_NEAR_ENEMIES: + case MoveTarget.ALL_ENEMIES: + case MoveTarget.USER_AND_ALLIES: + case MoveTarget.ALL: + case MoveTarget.USER_SIDE: + case MoveTarget.ENEMY_SIDE: + case MoveTarget.BOTH_SIDES: + return true; } return false; } /** - * Getter function that returns if the move targets itself or an ally + * Getter function that returns if the move targets the user or its ally * @returns boolean */ - isAllyTarget(): boolean { switch (this.moveTarget) { - case MoveTarget.USER: - case MoveTarget.NEAR_ALLY: - case MoveTarget.ALLY: - case MoveTarget.USER_OR_NEAR_ALLY: - case MoveTarget.USER_AND_ALLIES: - case MoveTarget.USER_SIDE: - return true; + case MoveTarget.USER: + case MoveTarget.NEAR_ALLY: + case MoveTarget.ALLY: + case MoveTarget.USER_OR_NEAR_ALLY: + case MoveTarget.USER_AND_ALLIES: + case MoveTarget.USER_SIDE: + return true; } return false; } + isChargingMove(): this is ChargingMove { + return false; + } + /** * Checks if the move is immune to certain types. * Currently looks at cases of Grass types with powder moves and Dark types with moves affected by Prankster. @@ -320,16 +323,16 @@ export default class Move implements Localizable { } switch (type) { - case Type.GRASS: - if (this.hasFlag(MoveFlags.POWDER_MOVE)) { - return true; - } - break; - case Type.DARK: - if (user.hasAbility(Abilities.PRANKSTER) && this.category === MoveCategory.STATUS && (user.isPlayer() !== target.isPlayer())) { - return true; - } - break; + case Type.GRASS: + if (this.hasFlag(MoveFlags.POWDER_MOVE)) { + return true; + } + break; + case Type.DARK: + if (user.hasAbility(Abilities.PRANKSTER) && this.category === MoveCategory.STATUS && (user.isPlayer() !== target.isPlayer())) { + return true; + } + break; } return false; } @@ -341,12 +344,16 @@ export default class Move implements Localizable { * @returns `true` if the move can bypass the target's Substitute; `false` otherwise. */ hitsSubstitute(user: Pokemon, target: Pokemon | null): boolean { - if ([MoveTarget.USER, MoveTarget.USER_SIDE, MoveTarget.ENEMY_SIDE, MoveTarget.BOTH_SIDES].includes(this.moveTarget) + if ([ MoveTarget.USER, MoveTarget.USER_SIDE, MoveTarget.ENEMY_SIDE, MoveTarget.BOTH_SIDES ].includes(this.moveTarget) || !target?.getTag(BattlerTagType.SUBSTITUTE)) { return false; } - return !user.hasAbility(Abilities.INFILTRATOR) + const bypassed = new Utils.BooleanHolder(false); + // TODO: Allow this to be simulated + applyAbAttrs(InfiltratorAbAttr, user, null, false, bypassed); + + return !bypassed.value && !this.hasFlag(MoveFlags.SOUND_BASED) && !this.hasFlag(MoveFlags.IGNORE_SUBSTITUTE); } @@ -365,6 +372,14 @@ export default class Move implements Localizable { return this; } + /** + * Internal dev flag for documenting edge cases. When using this, please document the known edge case. + * @returns the called object {@linkcode Move} + */ + edgeCase(): this { + return this; + } + /** * Marks the move as "partial": appends texts to the move name * @returns the called object {@linkcode Move} @@ -608,26 +623,26 @@ export default class Move implements Localizable { checkFlag(flag: MoveFlags, user: Pokemon, target: Pokemon | null): boolean { // special cases below, eg: if the move flag is MAKES_CONTACT, and the user pokemon has an ability that ignores contact (like "Long Reach"), then overrides and move does not make contact switch (flag) { - case MoveFlags.MAKES_CONTACT: - if (user.hasAbilityWithAttr(IgnoreContactAbAttr) || this.hitsSubstitute(user, target)) { - return false; - } - break; - case MoveFlags.IGNORE_ABILITIES: - if (user.hasAbilityWithAttr(MoveAbilityBypassAbAttr)) { - const abilityEffectsIgnored = new Utils.BooleanHolder(false); - applyAbAttrs(MoveAbilityBypassAbAttr, user, abilityEffectsIgnored, false, this); - if (abilityEffectsIgnored.value) { + case MoveFlags.MAKES_CONTACT: + if (user.hasAbilityWithAttr(IgnoreContactAbAttr) || this.hitsSubstitute(user, target)) { + return false; + } + break; + case MoveFlags.IGNORE_ABILITIES: + if (user.hasAbilityWithAttr(MoveAbilityBypassAbAttr)) { + const abilityEffectsIgnored = new Utils.BooleanHolder(false); + applyAbAttrs(MoveAbilityBypassAbAttr, user, abilityEffectsIgnored, false, this); + if (abilityEffectsIgnored.value) { + return true; + } + } + break; + case MoveFlags.IGNORE_PROTECT: + if (user.hasAbilityWithAttr(IgnoreProtectOnContactAbAttr) + && this.checkFlag(MoveFlags.MAKES_CONTACT, user, null)) { return true; } - } - break; - case MoveFlags.IGNORE_PROTECT: - if (user.hasAbilityWithAttr(IgnoreProtectOnContactAbAttr) - && this.checkFlag(MoveFlags.MAKES_CONTACT, user, null)) { - return true; - } - break; + break; } return !!(this.flags & flag); @@ -782,7 +797,7 @@ export default class Move implements Localizable { .flat(), ); for (const aura of fieldAuras) { - aura.applyPreAttack(source, null, simulated, target, this, [power]); + aura.applyPreAttack(source, null, simulated, target, this, [ power ]); } const alliedField: Pokemon[] = source instanceof PlayerPokemon ? source.scene.getPlayerField() : source.scene.getEnemyField(); @@ -800,7 +815,7 @@ export default class Move implements Localizable { source.scene.applyModifiers(PokemonMultiHitModifier, source.isPlayer(), source, new Utils.IntegerHolder(0), power); if (!this.hasAttr(TypelessAttr)) { - source.scene.arena.applyTags(WeakenMoveTypeTag, this.type, power); + source.scene.arena.applyTags(WeakenMoveTypeTag, simulated, this.type, power); source.scene.applyModifiers(AttackTypeBoosterModifier, source.isPlayer(), source, this.type, power); } @@ -881,6 +896,85 @@ export class SelfStatusMove extends Move { } } +type SubMove = new (...args: any[]) => Move; + +function ChargeMove(Base: TBase) { + return class extends Base { + /** The animation to play during the move's charging phase */ + public readonly chargeAnim: ChargeAnim = ChargeAnim[`${Moves[this.id]}_CHARGING`]; + /** The message to show during the move's charging phase */ + private _chargeText: string; + + /** Move attributes that apply during the move's charging phase */ + public chargeAttrs: MoveAttr[] = []; + + override isChargingMove(): this is ChargingMove { + return true; + } + + /** + * Sets the text to be displayed during this move's charging phase. + * References to the user Pokemon should be written as "{USER}", and + * references to the target Pokemon should be written as "{TARGET}". + * @param chargeText the text to set + * @returns this {@linkcode Move} (for chaining API purposes) + */ + chargeText(chargeText: string): this { + this._chargeText = chargeText; + return this; + } + + /** + * Queues the charge text to display to the player + * @param user the {@linkcode Pokemon} using this move + * @param target the {@linkcode Pokemon} targeted by this move (optional) + */ + showChargeText(user: Pokemon, target?: Pokemon): void { + user.scene.queueMessage(this._chargeText + .replace("{USER}", getPokemonNameWithAffix(user)) + .replace("{TARGET}", getPokemonNameWithAffix(target)) + ); + } + + /** + * Gets all charge attributes of the given attribute type. + * @param attrType any attribute that extends {@linkcode MoveAttr} + * @returns Array of attributes that match `attrType`, or an empty array if + * no matches are found. + */ + getChargeAttrs(attrType: Constructor): T[] { + return this.chargeAttrs.filter((attr): attr is T => attr instanceof attrType); + } + + /** + * Checks if this move has an attribute of the given type. + * @param attrType any attribute that extends {@linkcode MoveAttr} + * @returns `true` if a matching attribute is found; `false` otherwise + */ + hasChargeAttr(attrType: Constructor): boolean { + return this.chargeAttrs.some((attr) => attr instanceof attrType); + } + + /** + * Adds an attribute to this move to be applied during the move's charging phase + * @param ChargeAttrType the type of {@linkcode MoveAttr} being added + * @param args the parameters to construct the given {@linkcode MoveAttr} with + * @returns this {@linkcode Move} (for chaining API purposes) + */ + chargeAttr>(ChargeAttrType: T, ...args: ConstructorParameters): this { + const chargeAttr = new ChargeAttrType(...args); + this.chargeAttrs.push(chargeAttr); + + return this; + } + }; +} + +export class ChargingAttackMove extends ChargeMove(AttackMove) {} +export class ChargingSelfStatusMove extends ChargeMove(SelfStatusMove) {} + +export type ChargingMove = ChargingAttackMove | ChargingSelfStatusMove; + /** * Base class defining all {@linkcode Move} Attributes * @abstract @@ -970,13 +1064,16 @@ export class MoveEffectAttr extends MoveAttr { public lastHitOnly: boolean; /** Should this effect only apply on the first target hit? */ public firstTargetOnly: boolean; + /** Overrides the secondary effect chance for this attr if set. */ + public effectChanceOverride?: number; - constructor(selfTarget?: boolean, trigger?: MoveEffectTrigger, firstHitOnly: boolean = false, lastHitOnly: boolean = false, firstTargetOnly: boolean = false) { + constructor(selfTarget?: boolean, trigger?: MoveEffectTrigger, firstHitOnly: boolean = false, lastHitOnly: boolean = false, firstTargetOnly: boolean = false, effectChanceOverride?: number) { super(selfTarget); - this.trigger = trigger !== undefined ? trigger : MoveEffectTrigger.POST_APPLY; + this.trigger = trigger ?? MoveEffectTrigger.POST_APPLY; this.firstHitOnly = firstHitOnly; this.lastHitOnly = lastHitOnly; this.firstTargetOnly = firstTargetOnly; + this.effectChanceOverride = effectChanceOverride; } /** @@ -1001,16 +1098,23 @@ export class MoveEffectAttr extends MoveAttr { /** * Gets the used move's additional effect chance. - * If user's ability has MoveEffectChanceMultiplierAbAttr or IgnoreMoveEffectsAbAttr modifies the base chance. + * Chance is modified by {@linkcode MoveEffectChanceMultiplierAbAttr} and {@linkcode IgnoreMoveEffectsAbAttr}. * @param user {@linkcode Pokemon} using this move - * @param target {@linkcode Pokemon} target of this move + * @param target {@linkcode Pokemon | Target} of this move * @param move {@linkcode Move} being used - * @param selfEffect {@linkcode Boolean} if move targets user. - * @returns Move chance value. + * @param selfEffect `true` if move targets user. + * @returns Move effect chance value. */ getMoveChance(user: Pokemon, target: Pokemon, move: Move, selfEffect?: Boolean, showAbility?: Boolean): integer { - const moveChance = new Utils.NumberHolder(move.chance); + const moveChance = new Utils.NumberHolder(this.effectChanceOverride ?? move.chance); + applyAbAttrs(MoveEffectChanceMultiplierAbAttr, user, null, false, moveChance, move, target, selfEffect, showAbility); + + if ((!move.hasAttr(FlinchAttr) || moveChance.value <= move.chance) && !move.hasAttr(SecretPowerAttr)) { + const userSide = user.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; + user.scene.arena.applyTagsForSide(ArenaTagType.WATER_FIRE_PLEDGE, userSide, false, moveChance); + } + if (!selfEffect) { applyPreDefendAbAttrs(IgnoreMoveEffectsAbAttr, target, user, null, null, false, moveChance); } @@ -1316,6 +1420,11 @@ export class RecoilAttr extends MoveEffectAttr { return false; } + // Chloroblast and Struggle should not deal recoil damage if the move was not successful + if (this.useHp && [ MoveResult.FAIL, MoveResult.MISS ].includes(user.getLastXMoves(1)[0]?.result)) { + return false; + } + const damageValue = (!this.useHp ? user.turnData.damageDealt : user.getMaxHp()) * this.damageRatio; const minValue = user.turnData.damageDealt ? 1 : 0; const recoilDamage = Utils.toDmgValue(damageValue, minValue); @@ -1328,7 +1437,7 @@ export class RecoilAttr extends MoveEffectAttr { } user.damageAndUpdate(recoilDamage, HitResult.OTHER, false, true, true); - user.scene.queueMessage(i18next.t("moveTriggers:hitWithRecoil", {pokemonName: getPokemonNameWithAffix(user)})); + user.scene.queueMessage(i18next.t("moveTriggers:hitWithRecoil", { pokemonName: getPokemonNameWithAffix(user) })); user.turnData.damageTaken += recoilDamage; return true; @@ -1439,8 +1548,8 @@ export class HalfSacrificialAttr extends MoveEffectAttr { // Check to see if the Pokemon has an ability that blocks non-direct damage applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled); if (!cancelled.value) { - user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp()/2), HitResult.OTHER, false, true, true); - user.scene.queueMessage(i18next.t("moveTriggers:cutHpPowerUpMove", {pokemonName: getPokemonNameWithAffix(user)})); // Queue recoil message + user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), HitResult.OTHER, false, true, true); + user.scene.queueMessage(i18next.t("moveTriggers:cutHpPowerUpMove", { pokemonName: getPokemonNameWithAffix(user) })); // Queue recoil message } return true; } @@ -1449,7 +1558,7 @@ export class HalfSacrificialAttr extends MoveEffectAttr { if (user.isBoss()) { return -10; } - return Math.ceil(((1 - user.getHpRatio()/2) * 10 - 10) * (target.getAttackTypeEffectiveness(move.type, user) - 0.5)); + return Math.ceil(((1 - user.getHpRatio() / 2) * 10 - 10) * (target.getAttackTypeEffectiveness(move.type, user) - 0.5)); } } @@ -1546,7 +1655,7 @@ export class HealAttr extends MoveEffectAttr { */ addHealPhase(target: Pokemon, healRatio: number) { target.scene.unshiftPhase(new PokemonHealPhase(target.scene, target.getBattlerIndex(), - Utils.toDmgValue(target.getMaxHp() * healRatio), i18next.t("moveTriggers:healHp", {pokemonName: getPokemonNameWithAffix(target)}), true, !this.showAnim)); + Utils.toDmgValue(target.getMaxHp() * healRatio), i18next.t("moveTriggers:healHp", { pokemonName: getPokemonNameWithAffix(target) }), true, !this.showAnim)); } getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { @@ -1585,12 +1694,31 @@ export class PartyStatusCureAttr extends MoveEffectAttr { if (!this.canApply(user, target, move, args)) { return false; } - this.addPartyCurePhase(user); + const partyPokemon = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty(); + partyPokemon.forEach(p => this.cureStatus(p, user.id)); + + if (this.message) { + user.scene.queueMessage(this.message); + } + return true; } - addPartyCurePhase(user: Pokemon) { - user.scene.unshiftPhase(new PartyStatusCurePhase(user.scene, user, this.message, this.abilityCondition)); + /** + * Tries to cure the status of the given {@linkcode Pokemon} + * @param pokemon The {@linkcode Pokemon} to cure. + * @param userId The ID of the (move) {@linkcode Pokemon | user}. + */ + public cureStatus(pokemon: Pokemon, userId: number) { + if (!pokemon.isOnField() || pokemon.id === userId) { // user always cures its own status, regardless of ability + pokemon.resetStatus(false); + pokemon.updateInfo(); + } else if (!pokemon.hasAbility(this.abilityCondition)) { + pokemon.resetStatus(); + pokemon.updateInfo(); + } else { + pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, pokemon.getPassiveAbility()?.id === this.abilityCondition)); + } } } @@ -1618,7 +1746,7 @@ export class FlameBurstAttr extends MoveEffectAttr { return false; } - targetAlly.damageAndUpdate(Math.max(1, Math.floor(1/16 * targetAlly.getMaxHp())), HitResult.OTHER); + targetAlly.damageAndUpdate(Math.max(1, Math.floor(1 / 16 * targetAlly.getMaxHp())), HitResult.OTHER); return true; } @@ -1641,7 +1769,7 @@ export class SacrificialFullRestoreAttr extends SacrificialAttr { const maxPartyMemberHp = user.scene.getParty().map(p => p.getMaxHp()).reduce((maxHp: integer, hp: integer) => Math.max(hp, maxHp), 0); user.scene.pushPhase(new PokemonHealPhase(user.scene, user.getBattlerIndex(), - maxPartyMemberHp, i18next.t("moveTriggers:sacrificialFullRestore", {pokemonName: getPokemonNameWithAffix(user)}), true, false, false, true), true); + maxPartyMemberHp, i18next.t("moveTriggers:sacrificialFullRestore", { pokemonName: getPokemonNameWithAffix(user) }), true, false, false, true), true); return true; } @@ -1678,7 +1806,7 @@ export class IgnoreWeatherTypeDebuffAttr extends MoveAttr { * @returns true if the function succeeds */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const weatherModifier=args[0] as Utils.NumberHolder; + const weatherModifier = args[0] as Utils.NumberHolder; //If the type-based attack power modifier due to weather (e.g. Water moves in Sun) is below 1, set it to 1 if (user.scene.arena.weather?.weatherType === this.weather) { weatherModifier.value = Math.max(weatherModifier.value, 1); @@ -1708,17 +1836,17 @@ export abstract class WeatherHealAttr extends HealAttr { export class PlantHealAttr extends WeatherHealAttr { getWeatherHealRatio(weatherType: WeatherType): number { switch (weatherType) { - case WeatherType.SUNNY: - case WeatherType.HARSH_SUN: - return 2 / 3; - case WeatherType.RAIN: - case WeatherType.SANDSTORM: - case WeatherType.HAIL: - case WeatherType.SNOW: - case WeatherType.HEAVY_RAIN: - return 0.25; - default: - return 0.5; + case WeatherType.SUNNY: + case WeatherType.HARSH_SUN: + return 2 / 3; + case WeatherType.RAIN: + case WeatherType.SANDSTORM: + case WeatherType.HAIL: + case WeatherType.SNOW: + case WeatherType.HEAVY_RAIN: + return 0.25; + default: + return 0.5; } } } @@ -1726,10 +1854,10 @@ export class PlantHealAttr extends WeatherHealAttr { export class SandHealAttr extends WeatherHealAttr { getWeatherHealRatio(weatherType: WeatherType): number { switch (weatherType) { - case WeatherType.SANDSTORM: - return 2 / 3; - default: - return 0.5; + case WeatherType.SANDSTORM: + return 2 / 3; + default: + return 0.5; } } } @@ -1826,11 +1954,11 @@ export class HitHealAttr extends MoveEffectAttr { if (this.healStat !== null) { // Strength Sap formula healAmount = target.getEffectiveStat(this.healStat); - message = i18next.t("battle:drainMessage", {pokemonName: getPokemonNameWithAffix(target)}); + message = i18next.t("battle:drainMessage", { pokemonName: getPokemonNameWithAffix(target) }); } else { // Default healing formula used by draining moves like Absorb, Draining Kiss, Bitter Blade, etc. healAmount = Utils.toDmgValue(user.turnData.currDamageDealt * this.healRatio); - message = i18next.t("battle:regainHealth", {pokemonName: getPokemonNameWithAffix(user)}); + message = i18next.t("battle:regainHealth", { pokemonName: getPokemonNameWithAffix(user) }); } if (reverseDrain) { if (user.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { @@ -1856,7 +1984,7 @@ export class HitHealAttr extends MoveEffectAttr { getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { if (this.healStat) { const healAmount = target.getEffectiveStat(this.healStat); - return Math.floor(Math.max(0, (Math.min(1, (healAmount+user.hp)/user.getMaxHp() - 0.33))) / user.getHpRatio()); + return Math.floor(Math.max(0, (Math.min(1, (healAmount + user.hp) / user.getMaxHp() - 0.33))) / user.getHpRatio()); } return Math.floor(Math.max((1 - user.getHpRatio()) - 0.33, 0) * (move.power / 4)); } @@ -1909,12 +2037,21 @@ export class IncrementMovePriorityAttr extends MoveAttr { * @see {@linkcode apply} */ export class MultiHitAttr extends MoveAttr { + /** This move's intrinsic multi-hit type. It should never be modified. */ + private readonly intrinsicMultiHitType: MultiHitType; + /** This move's current multi-hit type. It may be temporarily modified by abilities (e.g., Battle Bond). */ private multiHitType: MultiHitType; constructor(multiHitType?: MultiHitType) { super(); - this.multiHitType = multiHitType !== undefined ? multiHitType : MultiHitType._2_TO_5; + this.intrinsicMultiHitType = multiHitType !== undefined ? multiHitType : MultiHitType._2_TO_5; + this.multiHitType = this.intrinsicMultiHitType; + } + + // Currently used by `battle_bond.test.ts` + getMultiHitType(): MultiHitType { + return this.multiHitType; } /** @@ -1928,7 +2065,7 @@ export class MultiHitAttr extends MoveAttr { * @returns True */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const hitType = new Utils.NumberHolder(this.multiHitType); + const hitType = new Utils.NumberHolder(this.intrinsicMultiHitType); applyMoveAttrs(ChangeMultiHitTypeAttr, user, target, move, hitType); this.multiHitType = hitType.value; @@ -1950,33 +2087,33 @@ export class MultiHitAttr extends MoveAttr { */ getHitCount(user: Pokemon, target: Pokemon): integer { switch (this.multiHitType) { - case MultiHitType._2_TO_5: - { - const rand = user.randSeedInt(16); - const hitValue = new Utils.IntegerHolder(rand); - applyAbAttrs(MaxMultiHitAbAttr, user, null, false, hitValue); - if (hitValue.value >= 10) { - return 2; - } else if (hitValue.value >= 4) { - return 3; - } else if (hitValue.value >= 2) { - return 4; - } else { - return 5; + case MultiHitType._2_TO_5: + { + const rand = user.randSeedInt(16); + const hitValue = new Utils.IntegerHolder(rand); + applyAbAttrs(MaxMultiHitAbAttr, user, null, false, hitValue); + if (hitValue.value >= 10) { + return 2; + } else if (hitValue.value >= 4) { + return 3; + } else if (hitValue.value >= 2) { + return 4; + } else { + return 5; + } } - } - case MultiHitType._2: - return 2; - case MultiHitType._3: - return 3; - case MultiHitType._10: - return 10; - case MultiHitType.BEAT_UP: - const party = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty(); - // No status means the ally pokemon can contribute to Beat Up - return party.reduce((total, pokemon) => { - return total + (pokemon.id === user.id ? 1 : pokemon?.status && pokemon.status.effect !== StatusEffect.NONE ? 0 : 1); - }, 0); + case MultiHitType._2: + return 2; + case MultiHitType._3: + return 3; + case MultiHitType._10: + return 10; + case MultiHitType.BEAT_UP: + const party = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty(); + // No status means the ally pokemon can contribute to Beat Up + return party.reduce((total, pokemon) => { + return total + (pokemon.id === user.id ? 1 : pokemon?.status && pokemon.status.effect !== StatusEffect.NONE ? 0 : 1); + }, 0); } } } @@ -2000,15 +2137,15 @@ export class WaterShurikenMultiHitTypeAttr extends ChangeMultiHitTypeAttr { export class StatusEffectAttr extends MoveEffectAttr { public effect: StatusEffect; - public cureTurn: integer | null; - public overrideStatus: boolean; + public turnsRemaining?: number; + public overrideStatus: boolean = false; - constructor(effect: StatusEffect, selfTarget?: boolean, cureTurn?: integer, overrideStatus?: boolean) { + constructor(effect: StatusEffect, selfTarget?: boolean, turnsRemaining?: number, overrideStatus: boolean = false) { super(selfTarget, MoveEffectTrigger.HIT); this.effect = effect; - this.cureTurn = cureTurn!; // TODO: is this bang correct? - this.overrideStatus = !!overrideStatus; + this.turnsRemaining = turnsRemaining; + this.overrideStatus = overrideStatus; } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { @@ -2028,14 +2165,14 @@ export class StatusEffectAttr extends MoveEffectAttr { } } - if (user !== target && target.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY)) { + if (user !== target && target.isSafeguarded(user)) { if (move.category === MoveCategory.STATUS) { - user.scene.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(target)})); + user.scene.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(target) })); } return false; } if ((!pokemon.status || (pokemon.status.effect === this.effect && moveChance < 0)) - && pokemon.trySetStatus(this.effect, true, user, this.cureTurn)) { + && pokemon.trySetStatus(this.effect, true, user, this.turnsRemaining)) { applyPostAttackAbAttrs(ConfusionOnStatusEffectAbAttr, user, target, move, null, false, this.effect); return true; } @@ -2045,15 +2182,18 @@ export class StatusEffectAttr extends MoveEffectAttr { getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { const moveChance = this.getMoveChance(user, target, move, this.selfTarget, false); - return !(this.selfTarget ? user : target).status && (this.selfTarget ? user : target).canSetStatus(this.effect, true, false, user) ? Math.floor(moveChance * -0.1) : 0; + const score = (moveChance < 0) ? -10 : Math.floor(moveChance * -0.1); + const pokemon = this.selfTarget ? user : target; + + return !pokemon.status && pokemon.canSetStatus(this.effect, true, false, user) ? score : 0; } } export class MultiStatusEffectAttr extends StatusEffectAttr { public effects: StatusEffect[]; - constructor(effects: StatusEffect[], selfTarget?: boolean, cureTurn?: integer, overrideStatus?: boolean) { - super(effects[0], selfTarget, cureTurn, overrideStatus); + constructor(effects: StatusEffect[], selfTarget?: boolean, turnsRemaining?: number, overrideStatus?: boolean) { + super(effects[0], selfTarget, turnsRemaining, overrideStatus); this.effects = effects; } @@ -2065,7 +2205,10 @@ export class MultiStatusEffectAttr extends StatusEffectAttr { getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { const moveChance = this.getMoveChance(user, target, move, this.selfTarget, false); - return !(this.selfTarget ? user : target).status && (this.selfTarget ? user : target).canSetStatus(this.effect, true, false, user) ? Math.floor(moveChance * -0.1) : 0; + const score = (moveChance < 0) ? -10 : Math.floor(moveChance * -0.1); + const pokemon = this.selfTarget ? user : target; + + return !pokemon.status && pokemon.canSetStatus(this.effect, true, false, user) ? score : 0; } } @@ -2096,7 +2239,7 @@ export class PsychoShiftEffectAttr extends MoveEffectAttr { } getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { - return !(this.selfTarget ? user : target).status && (this.selfTarget ? user : target).canSetStatus(user.status?.effect, true, false, user) ? Math.floor(move.chance * -0.1) : 0; + return !target.status && target.canSetStatus(user.status?.effect, true, false, user) ? -10 : 0; } } /** @@ -2129,7 +2272,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr { const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; user.scene.tryTransferHeldItemModifier(stolenItem, user, false).then(success => { if (success) { - user.scene.queueMessage(i18next.t("moveTriggers:stoleItem", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name})); + user.scene.queueMessage(i18next.t("moveTriggers:stoleItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name })); } resolve(success); }); @@ -2212,9 +2355,9 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { target.scene.updateModifiers(target.isPlayer()); if (this.berriesOnly) { - user.scene.queueMessage(i18next.t("moveTriggers:incineratedItem", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name})); + user.scene.queueMessage(i18next.t("moveTriggers:incineratedItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); } else { - user.scene.queueMessage(i18next.t("moveTriggers:knockedOffItem", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name})); + user.scene.queueMessage(i18next.t("moveTriggers:knockedOffItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); } } @@ -2324,7 +2467,7 @@ export class StealEatBerryAttr extends EatBerryAttr { } // if the target has berries, pick a random berry and steal it this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)]; - const message = i18next.t("battle:stealEatBerry", {pokemonName: user.name, targetName: target.name, berryName: this.chosenBerry.type.name}); + const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: this.chosenBerry.type.name }); user.scene.queueMessage(message); this.reduceBerryModifier(target); this.eatBerry(user); @@ -2524,6 +2667,63 @@ export class OneHitKOAttr extends MoveAttr { } } +/** + * Attribute that allows charge moves to resolve in 1 turn under a given condition. + * Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`. + * @extends MoveAttr + */ +export class InstantChargeAttr extends MoveAttr { + /** The condition in which the move with this attribute instantly charges */ + protected readonly condition: UserMoveConditionFunc; + + constructor(condition: UserMoveConditionFunc) { + super(true); + this.condition = condition; + } + + /** + * Flags the move with this attribute as instantly charged if this attribute's condition is met. + * @param user the {@linkcode Pokemon} using the move + * @param target n/a + * @param move the {@linkcode Move} associated with this attribute + * @param args + * - `[0]` a {@linkcode Utils.BooleanHolder | BooleanHolder} for the "instant charge" flag + * @returns `true` if the instant charge condition is met; `false` otherwise. + */ + override apply(user: Pokemon, target: Pokemon | null, move: Move, args: any[]): boolean { + const instantCharge = args[0]; + if (!(instantCharge instanceof Utils.BooleanHolder)) { + return false; + } + + if (this.condition(user, move)) { + instantCharge.value = true; + return true; + } + return false; + } +} + +/** + * Attribute that allows charge moves to resolve in 1 turn while specific {@linkcode WeatherType | Weather} + * is active. Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`. + * @extends InstantChargeAttr + */ +export class WeatherInstantChargeAttr extends InstantChargeAttr { + constructor(weatherTypes: WeatherType[]) { + super((user, move) => { + const currentWeather = user.scene.arena.weather; + + if (Utils.isNullOrUndefined(currentWeather?.weatherType)) { + return false; + } else { + return !currentWeather?.isEffectSuppressed(user.scene) + && weatherTypes.includes(currentWeather?.weatherType); + } + }); + } +} + export class OverrideMoveEffectAttr extends MoveAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { //const overridden = args[0] as Utils.BooleanHolder; @@ -2532,111 +2732,6 @@ export class OverrideMoveEffectAttr extends MoveAttr { } } -export class ChargeAttr extends OverrideMoveEffectAttr { - public chargeAnim: ChargeAnim; - private chargeText: string; - private tagType: BattlerTagType | null; - private chargeEffect: boolean; - public followUpPriority: integer | null; - - constructor(chargeAnim: ChargeAnim, chargeText: string, tagType?: BattlerTagType | null, chargeEffect: boolean = false) { - super(); - - this.chargeAnim = chargeAnim; - this.chargeText = chargeText; - this.tagType = tagType!; // TODO: is this bang correct? - this.chargeEffect = chargeEffect; - } - - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { - return new Promise(resolve => { - const lastMove = user.getLastXMoves().find(() => true); - if (!lastMove || lastMove.move !== move.id || (lastMove.result !== MoveResult.OTHER && lastMove.turn !== user.scene.currentBattle.turn)) { - (args[0] as Utils.BooleanHolder).value = true; - new MoveChargeAnim(this.chargeAnim, move.id, user).play(user.scene, false, () => { - user.scene.queueMessage(this.chargeText.replace("{TARGET}", getPokemonNameWithAffix(target)).replace("{USER}", getPokemonNameWithAffix(user))); - if (this.tagType) { - user.addTag(this.tagType, 1, move.id, user.id); - } - if (this.chargeEffect) { - applyMoveAttrs(MoveEffectAttr, user, target, move); - } - user.pushMoveHistory({ move: move.id, targets: [ target.getBattlerIndex() ], result: MoveResult.OTHER }); - user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true }); - user.addTag(BattlerTagType.CHARGING, 1, move.id, user.id); - resolve(true); - }); - } else { - user.lapseTag(BattlerTagType.CHARGING); - resolve(false); - } - }); - } - - usedChargeEffect(user: Pokemon, target: Pokemon | null, move: Move): boolean { - if (!this.chargeEffect) { - return false; - } - // Account for move history being populated when this function is called - const lastMoves = user.getLastXMoves(2); - return lastMoves.length === 2 && lastMoves[1].move === move.id && lastMoves[1].result === MoveResult.OTHER; - } -} - -export class SunlightChargeAttr extends ChargeAttr { - constructor(chargeAnim: ChargeAnim, chargeText: string) { - super(chargeAnim, chargeText); - } - - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { - return new Promise(resolve => { - const weatherType = user.scene.arena.weather?.weatherType; - if (!user.scene.arena.weather?.isEffectSuppressed(user.scene) && (weatherType === WeatherType.SUNNY || weatherType === WeatherType.HARSH_SUN)) { - resolve(false); - } else { - super.apply(user, target, move, args).then(result => resolve(result)); - } - }); - } -} - -export class ElectroShotChargeAttr extends ChargeAttr { - private statIncreaseApplied: boolean; - constructor() { - super(ChargeAnim.ELECTRO_SHOT_CHARGING, i18next.t("moveTriggers:absorbedElectricity", {pokemonName: "{USER}"}), null, true); - // Add a flag because ChargeAttr skills use themselves twice instead of once over one-to-two turns - this.statIncreaseApplied = false; - } - - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { - return new Promise(resolve => { - const weatherType = user.scene.arena.weather?.weatherType; - if (!user.scene.arena.weather?.isEffectSuppressed(user.scene) && (weatherType === WeatherType.RAIN || weatherType === WeatherType.HEAVY_RAIN)) { - // Apply the SPATK increase every call when used in the rain - const statChangeAttr = new StatStageChangeAttr([ Stat.SPATK ], 1, true); - statChangeAttr.apply(user, target, move, args); - // After the SPATK is raised, execute the move resolution e.g. deal damage - resolve(false); - } else { - if (!this.statIncreaseApplied) { - // Apply the SPATK increase only if it hasn't been applied before e.g. on the first turn charge up animation - const statChangeAttr = new StatStageChangeAttr([ Stat.SPATK ], 1, true); - statChangeAttr.apply(user, target, move, args); - // Set the flag to true so that on the following turn it doesn't raise SPATK a second time - this.statIncreaseApplied = true; - } - super.apply(user, target, move, args).then(result => { - if (!result) { - // On the second turn, reset the statIncreaseApplied flag without applying the SPATK increase - this.statIncreaseApplied = false; - } - resolve(result); - }); - } - }); - } -} - export class DelayedAttackAttr extends OverrideMoveEffectAttr { public tagType: ArenaTagType; public chargeAnim: ChargeAnim; @@ -2662,26 +2757,107 @@ export class DelayedAttackAttr extends OverrideMoveEffectAttr { resolve(true); }); } else { - user.scene.ui.showText(i18next.t("moveTriggers:tookMoveAttack", {pokemonName: getPokemonNameWithAffix(user.scene.getPokemonById(target.id) ?? undefined), moveName: move.name}), null, () => resolve(true)); + user.scene.ui.showText(i18next.t("moveTriggers:tookMoveAttack", { pokemonName: getPokemonNameWithAffix(user.scene.getPokemonById(target.id) ?? undefined), moveName: move.name }), null, () => resolve(true)); } }); } } +/** + * Attribute that cancels the associated move's effects when set to be combined with the user's ally's + * subsequent move this turn. Used for Grass Pledge, Water Pledge, and Fire Pledge. + * @extends OverrideMoveEffectAttr + */ +export class AwaitCombinedPledgeAttr extends OverrideMoveEffectAttr { + constructor() { + super(true); + } + /** + * If the user's ally is set to use a different move with this attribute, + * defer this move's effects for a combined move on the ally's turn. + * @param user the {@linkcode Pokemon} using this move + * @param target n/a + * @param move the {@linkcode Move} being used + * @param args + * - [0] a {@linkcode Utils.BooleanHolder} indicating whether the move's base + * effects should be overridden this turn. + * @returns `true` if base move effects were overridden; `false` otherwise + */ + override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (user.turnData.combiningPledge) { + // "The two moves have become one!\nIt's a combined move!" + user.scene.queueMessage(i18next.t("moveTriggers:combiningPledge")); + return false; + } + + const overridden = args[0] as Utils.BooleanHolder; + + const allyMovePhase = user.scene.findPhase((phase) => phase instanceof MovePhase && phase.pokemon.isPlayer() === user.isPlayer()); + if (allyMovePhase) { + const allyMove = allyMovePhase.move.getMove(); + if (allyMove !== move && allyMove.hasAttr(AwaitCombinedPledgeAttr)) { + [ user, allyMovePhase.pokemon ].forEach((p) => p.turnData.combiningPledge = move.id); + + // "{userPokemonName} is waiting for {allyPokemonName}'s move..." + user.scene.queueMessage(i18next.t("moveTriggers:awaitingPledge", { + userPokemonName: getPokemonNameWithAffix(user), + allyPokemonName: getPokemonNameWithAffix(allyMovePhase.pokemon) + })); + + // Move the ally's MovePhase (if needed) so that the ally moves next + const allyMovePhaseIndex = user.scene.phaseQueue.indexOf(allyMovePhase); + const firstMovePhaseIndex = user.scene.phaseQueue.findIndex((phase) => phase instanceof MovePhase); + if (allyMovePhaseIndex !== firstMovePhaseIndex) { + user.scene.prependToPhase(user.scene.phaseQueue.splice(allyMovePhaseIndex, 1)[0], MovePhase); + } + + overridden.value = true; + return true; + } + } + return false; + } +} + +/** + * Attribute used for moves that change stat stages + * + * @param stats {@linkcode BattleStat} Array of stat(s) to change + * @param stages How many stages to change the stat(s) by, [-6, 6] + * @param selfTarget `true` if the move is self-targetting + * @param condition {@linkcode MoveConditionFunc} Optional condition to be checked in order to apply the changes + * @param showMessage `true` to display a message; default `true` + * @param firstHitOnly `true` if only the first hit of a multi hit move should cause a stat stage change; default `false` + * @param moveEffectTrigger {@linkcode MoveEffectTrigger} When the stat change should trigger; default {@linkcode MoveEffectTrigger.HIT} + * @param firstTargetOnly `true` if a move that hits multiple pokemon should only trigger the stat change if it hits at least one pokemon, rather than once per hit pokemon; default `false` + * @param lastHitOnly `true` if the effect should only apply after the last hit of a multi hit move; default `false` + * @param effectChanceOverride Will override the move's normal secondary effect chance if specified + * + * @extends MoveEffectAttr + * @see {@linkcode apply} + */ export class StatStageChangeAttr extends MoveEffectAttr { public stats: BattleStat[]; public stages: integer; - private condition: MoveConditionFunc | null; + private condition?: MoveConditionFunc | null; private showMessage: boolean; - constructor(stats: BattleStat[], stages: integer, selfTarget?: boolean, condition?: MoveConditionFunc | null, showMessage: boolean = true, firstHitOnly: boolean = false, moveEffectTrigger: MoveEffectTrigger = MoveEffectTrigger.HIT, firstTargetOnly: boolean = false) { - super(selfTarget, moveEffectTrigger, firstHitOnly, false, firstTargetOnly); + constructor(stats: BattleStat[], stages: integer, selfTarget?: boolean, condition?: MoveConditionFunc | null, showMessage: boolean = true, firstHitOnly: boolean = false, moveEffectTrigger: MoveEffectTrigger = MoveEffectTrigger.HIT, firstTargetOnly: boolean = false, lastHitOnly: boolean = false, effectChanceOverride?: number) { + super(selfTarget, moveEffectTrigger, firstHitOnly, lastHitOnly, firstTargetOnly, effectChanceOverride); this.stats = stats; this.stages = stages; - this.condition = condition!; // TODO: is this bang correct? + this.condition = condition; this.showMessage = showMessage; } + /** + * Attempts to change stats of the user or target (depending on value of selfTarget) if conditions are met + * @param user {@linkcode Pokemon} the user of the move + * @param target {@linkcode Pokemon} the target of the move + * @param move {@linkcode Move} the move + * @param args unused + * @returns whether stat stages were changed + */ apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean | Promise { if (!super.apply(user, target, move, args) || (this.condition && !this.condition(user, target, move))) { return false; @@ -2718,26 +2894,26 @@ export class StatStageChangeAttr extends MoveEffectAttr { } let noEffect = false; switch (stat) { - case Stat.ATK: - if (this.selfTarget) { - noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.PHYSICAL); - } - break; - case Stat.DEF: - if (!this.selfTarget) { - noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.PHYSICAL); - } - break; - case Stat.SPATK: - if (this.selfTarget) { - noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.SPECIAL); - } - break; - case Stat.SPDEF: - if (!this.selfTarget) { - noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.SPECIAL); - } - break; + case Stat.ATK: + if (this.selfTarget) { + noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.PHYSICAL); + } + break; + case Stat.DEF: + if (!this.selfTarget) { + noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.PHYSICAL); + } + break; + case Stat.SPATK: + if (this.selfTarget) { + noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.SPECIAL); + } + break; + case Stat.SPDEF: + if (!this.selfTarget) { + noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.SPECIAL); + } + break; } if (noEffect) { continue; @@ -2748,6 +2924,162 @@ export class StatStageChangeAttr extends MoveEffectAttr { } } +/** + * Attribute used to determine the Biome/Terrain-based secondary effect of Secret Power + */ +export class SecretPowerAttr extends MoveEffectAttr { + constructor() { + super(false); + } + + /** + * Used to determine if the move should apply a secondary effect based on Secret Power's 30% chance + * @returns `true` if the move's secondary effect should apply + */ + override canApply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean { + this.effectChanceOverride = move.chance; + const moveChance = this.getMoveChance(user, target, move, this.selfTarget); + if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) { + return true; + } else { + return false; + } + } + + /** + * Used to apply the secondary effect to the target Pokemon + * @returns `true` if a secondary effect is successfully applied + */ + override apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean | Promise { + if (!super.apply(user, target, move, args)) { + return false; + } + let secondaryEffect: MoveEffectAttr; + const terrain = user.scene.arena.getTerrainType(); + if (terrain !== TerrainType.NONE) { + secondaryEffect = this.determineTerrainEffect(terrain); + } else { + const biome = user.scene.arena.biomeType; + secondaryEffect = this.determineBiomeEffect(biome); + } + // effectChanceOverride used in the application of the actual secondary effect + secondaryEffect.effectChanceOverride = 100; + return secondaryEffect.apply(user, target, move, []); + } + + /** + * Determines the secondary effect based on terrain. + * Takes precedence over biome-based effects. + * ``` + * Electric Terrain | Paralysis + * Misty Terrain | SpAtk -1 + * Grassy Terrain | Sleep + * Psychic Terrain | Speed -1 + * ``` + * @param terrain - {@linkcode TerrainType} The current terrain + * @returns the chosen secondary effect {@linkcode MoveEffectAttr} + */ + private determineTerrainEffect(terrain: TerrainType): MoveEffectAttr { + let secondaryEffect: MoveEffectAttr; + switch (terrain) { + case TerrainType.ELECTRIC: + default: + secondaryEffect = new StatusEffectAttr(StatusEffect.PARALYSIS, false); + break; + case TerrainType.MISTY: + secondaryEffect = new StatStageChangeAttr([ Stat.SPATK ], -1, false); + break; + case TerrainType.GRASSY: + secondaryEffect = new StatusEffectAttr(StatusEffect.SLEEP, false); + break; + case TerrainType.PSYCHIC: + secondaryEffect = new StatStageChangeAttr([ Stat.SPD ], -1, false); + break; + } + return secondaryEffect; + } + + /** + * Determines the secondary effect based on biome + * ``` + * Town, Metropolis, Slum, Dojo, Laboratory, Power Plant + Default | Paralysis + * Plains, Grass, Tall Grass, Forest, Jungle, Meadow | Sleep + * Swamp, Mountain, Temple, Ruins | Speed -1 + * Ice Cave, Snowy Forest | Freeze + * Volcano | Burn + * Fairy Cave | SpAtk -1 + * Desert, Construction Site, Beach, Island, Badlands | Accuracy -1 + * Sea, Lake, Seabed | Atk -1 + * Cave, Wasteland, Graveyard, Abyss, Space | Flinch + * End | Def -1 + * ``` + * @param biome - The current {@linkcode Biome} the battle is set in + * @returns the chosen secondary effect {@linkcode MoveEffectAttr} + */ + private determineBiomeEffect(biome: Biome): MoveEffectAttr { + let secondaryEffect: MoveEffectAttr; + switch (biome) { + case Biome.PLAINS: + case Biome.GRASS: + case Biome.TALL_GRASS: + case Biome.FOREST: + case Biome.JUNGLE: + case Biome.MEADOW: + secondaryEffect = new StatusEffectAttr(StatusEffect.SLEEP, false); + break; + case Biome.SWAMP: + case Biome.MOUNTAIN: + case Biome.TEMPLE: + case Biome.RUINS: + secondaryEffect = new StatStageChangeAttr([ Stat.SPD ], -1, false); + break; + case Biome.ICE_CAVE: + case Biome.SNOWY_FOREST: + secondaryEffect = new StatusEffectAttr(StatusEffect.FREEZE, false); + break; + case Biome.VOLCANO: + secondaryEffect = new StatusEffectAttr(StatusEffect.BURN, false); + break; + case Biome.FAIRY_CAVE: + secondaryEffect = new StatStageChangeAttr([ Stat.SPATK ], -1, false); + break; + case Biome.DESERT: + case Biome.CONSTRUCTION_SITE: + case Biome.BEACH: + case Biome.ISLAND: + case Biome.BADLANDS: + secondaryEffect = new StatStageChangeAttr([ Stat.ACC ], -1, false); + break; + case Biome.SEA: + case Biome.LAKE: + case Biome.SEABED: + secondaryEffect = new StatStageChangeAttr([ Stat.ATK ], -1, false); + break; + case Biome.CAVE: + case Biome.WASTELAND: + case Biome.GRAVEYARD: + case Biome.ABYSS: + case Biome.SPACE: + secondaryEffect = new AddBattlerTagAttr(BattlerTagType.FLINCHED, false, true); + break; + case Biome.END: + secondaryEffect = new StatStageChangeAttr([ Stat.DEF ], -1, false); + break; + case Biome.TOWN: + case Biome.METROPOLIS: + case Biome.SLUM: + case Biome.DOJO: + case Biome.FACTORY: + case Biome.LABORATORY: + case Biome.POWER_PLANT: + default: + secondaryEffect = new StatusEffectAttr(StatusEffect.PARALYSIS, false); + break; + } + return secondaryEffect; + } +} + export class PostVictoryStatStageChangeAttr extends MoveAttr { private stats: BattleStat[]; private stages: number; @@ -2778,7 +3110,7 @@ export class AcupressureStatStageChangeAttr extends MoveEffectAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { const randStats = BATTLE_STATS.filter(s => target.getStatStage(s) < 6); if (randStats.length > 0) { - const boostStat = [randStats[user.randSeedInt(randStats.length)]]; + const boostStat = [ randStats[user.randSeedInt(randStats.length)] ]; user.scene.unshiftPhase(new StatStageChangePhase(user.scene, target.getBattlerIndex(), this.selfTarget, boostStat, 2)); return true; } @@ -2849,7 +3181,7 @@ export class CopyStatsAttr extends MoveEffectAttr { } target.updateInfo(); user.updateInfo(); - target.scene.queueMessage(i18next.t("moveTriggers:copiedStatChanges", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target)})); + target.scene.queueMessage(i18next.t("moveTriggers:copiedStatChanges", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) })); return true; } @@ -2868,7 +3200,7 @@ export class InvertStatsAttr extends MoveEffectAttr { target.updateInfo(); user.updateInfo(); - target.scene.queueMessage(i18next.t("moveTriggers:invertStats", {pokemonName: getPokemonNameWithAffix(target)})); + target.scene.queueMessage(i18next.t("moveTriggers:invertStats", { pokemonName: getPokemonNameWithAffix(target) })); return true; } @@ -2889,7 +3221,7 @@ export class ResetStatsAttr extends MoveEffectAttr { } else { // Affects only the single target when Clear Smog is used if (!move.hitsSubstitute(user, target)) { promises.push(this.resetStats(target)); - target.scene.queueMessage(i18next.t("moveTriggers:resetStats", {pokemonName: getPokemonNameWithAffix(target)})); + target.scene.queueMessage(i18next.t("moveTriggers:resetStats", { pokemonName: getPokemonNameWithAffix(target) })); } } @@ -3026,21 +3358,21 @@ export class LessPPMorePowerAttr extends VariablePowerAttr { const power = args[0] as Utils.NumberHolder; switch (ppRemains) { - case 0: - power.value = 200; - break; - case 1: - power.value = 80; - break; - case 2: - power.value = 60; - break; - case 3: - power.value = 50; - break; - default: - power.value = 40; - break; + case 0: + power.value = 200; + break; + case 1: + power.value = 80; + break; + case 2: + power.value = 60; + break; + case 3: + power.value = 50; + break; + default: + power.value = 40; + break; } return true; } @@ -3113,7 +3445,7 @@ const doublePowerChanceMessageFunc = (user: Pokemon, target: Pokemon, move: Move user.scene.executeWithSeedOffset(() => { const rand = Utils.randSeedInt(100); if (rand < move.chance) { - message = i18next.t("moveTriggers:goingAllOutForAttack", {pokemonName: getPokemonNameWithAffix(user)}); + message = i18next.t("moveTriggers:goingAllOutForAttack", { pokemonName: getPokemonNameWithAffix(user) }); } }, user.scene.currentBattle.turn << 6, user.scene.waveSeed); return message; @@ -3260,24 +3592,24 @@ export class LowHpPowerAttr extends VariablePowerAttr { const hpRatio = user.getHpRatio(); switch (true) { - case (hpRatio < 0.0417): - power.value = 200; - break; - case (hpRatio < 0.1042): - power.value = 150; - break; - case (hpRatio < 0.2083): - power.value = 100; - break; - case (hpRatio < 0.3542): - power.value = 80; - break; - case (hpRatio < 0.6875): - power.value = 40; - break; - default: - power.value = 20; - break; + case (hpRatio < 0.0417): + power.value = 200; + break; + case (hpRatio < 0.1042): + power.value = 150; + break; + case (hpRatio < 0.2083): + power.value = 100; + break; + case (hpRatio < 0.3542): + power.value = 80; + break; + case (hpRatio < 0.6875): + power.value = 40; + break; + default: + power.value = 20; + break; } return true; @@ -3297,21 +3629,21 @@ export class CompareWeightPowerAttr extends VariablePowerAttr { const relativeWeight = (targetWeight / userWeight) * 100; switch (true) { - case (relativeWeight < 20.01): - power.value = 120; - break; - case (relativeWeight < 25.01): - power.value = 100; - break; - case (relativeWeight < 33.35): - power.value = 80; - break; - case (relativeWeight < 50.01): - power.value = 60; - break; - default: - power.value = 40; - break; + case (relativeWeight < 20.01): + power.value = 120; + break; + case (relativeWeight < 25.01): + power.value = 100; + break; + case (relativeWeight < 33.35): + power.value = 80; + break; + case (relativeWeight < 50.01): + power.value = 60; + break; + default: + power.value = 40; + break; } return true; @@ -3392,7 +3724,7 @@ const magnitudeMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => { } } - message = i18next.t("moveTriggers:magnitudeMessage", {magnitude: m + 4}); + message = i18next.t("moveTriggers:magnitudeMessage", { magnitude: m + 4 }); }, user.scene.currentBattle.turn << 6, user.scene.waveSeed); return message!; }; @@ -3427,13 +3759,13 @@ export class AntiSunlightPowerDecreaseAttr extends VariablePowerAttr { const power = args[0] as Utils.NumberHolder; const weatherType = user.scene.arena.weather?.weatherType || WeatherType.NONE; switch (weatherType) { - case WeatherType.RAIN: - case WeatherType.SANDSTORM: - case WeatherType.HAIL: - case WeatherType.SNOW: - case WeatherType.HEAVY_RAIN: - power.value *= 0.5; - return true; + case WeatherType.RAIN: + case WeatherType.SANDSTORM: + case WeatherType.HAIL: + case WeatherType.SNOW: + case WeatherType.HEAVY_RAIN: + power.value *= 0.5; + return true; } } @@ -3542,7 +3874,7 @@ export class PresentPowerAttr extends VariablePowerAttr { // If this move is multi-hit, disable all other hits user.stopMultiHit(); target.scene.unshiftPhase(new PokemonHealPhase(target.scene, target.getBattlerIndex(), - Utils.toDmgValue(target.getMaxHp() / 4), i18next.t("moveTriggers:regainedHealth", {pokemonName: getPokemonNameWithAffix(target)}), true)); + Utils.toDmgValue(target.getMaxHp() / 4), i18next.t("moveTriggers:regainedHealth", { pokemonName: getPokemonNameWithAffix(target) }), true)); } return true; @@ -3707,8 +4039,8 @@ export class LastMoveDoublePowerAttr extends VariablePowerAttr { for (const p of pokemonActed) { const [ lastMove ] = p.getLastXMoves(1); - if (lastMove.result !== MoveResult.FAIL) { - if ((lastMove.result === MoveResult.SUCCESS) && (lastMove.move === this.move)) { + if (lastMove?.result !== MoveResult.FAIL) { + if ((lastMove?.result === MoveResult.SUCCESS) && (lastMove?.move === this.move)) { power.value *= 2; return true; } else { @@ -3721,6 +4053,45 @@ export class LastMoveDoublePowerAttr extends VariablePowerAttr { } } +/** + * Changes a Pledge move's power to 150 when combined with another unique Pledge + * move from an ally. + */ +export class CombinedPledgePowerAttr extends VariablePowerAttr { + override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + const power = args[0]; + if (!(power instanceof Utils.NumberHolder)) { + return false; + } + const combinedPledgeMove = user.turnData.combiningPledge; + + if (combinedPledgeMove && combinedPledgeMove !== move.id) { + power.value *= 150 / 80; + return true; + } + return false; + } +} + +/** + * Applies STAB to the given Pledge move if the move is part of a combined attack. + */ +export class CombinedPledgeStabBoostAttr extends MoveAttr { + override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + const stabMultiplier = args[0]; + if (!(stabMultiplier instanceof Utils.NumberHolder)) { + return false; + } + const combinedPledgeMove = user.turnData.combiningPledge; + + if (combinedPledgeMove && combinedPledgeMove !== move.id) { + stabMultiplier.value = 1.5; + return true; + } + return false; + } +} + export class VariableAtkAttr extends MoveAttr { constructor() { super(); @@ -3791,14 +4162,14 @@ export class ThunderAccuracyAttr extends VariableAccuracyAttr { const accuracy = args[0] as Utils.NumberHolder; const weatherType = user.scene.arena.weather?.weatherType || WeatherType.NONE; switch (weatherType) { - case WeatherType.SUNNY: - case WeatherType.HARSH_SUN: - accuracy.value = 50; - return true; - case WeatherType.RAIN: - case WeatherType.HEAVY_RAIN: - accuracy.value = -1; - return true; + case WeatherType.SUNNY: + case WeatherType.HARSH_SUN: + accuracy.value = 50; + return true; + case WeatherType.RAIN: + case WeatherType.HEAVY_RAIN: + accuracy.value = -1; + return true; } } @@ -3817,10 +4188,10 @@ export class StormAccuracyAttr extends VariableAccuracyAttr { const accuracy = args[0] as Utils.NumberHolder; const weatherType = user.scene.arena.weather?.weatherType || WeatherType.NONE; switch (weatherType) { - case WeatherType.RAIN: - case WeatherType.HEAVY_RAIN: - accuracy.value = -1; - return true; + case WeatherType.RAIN: + case WeatherType.HEAVY_RAIN: + accuracy.value = -1; + return true; } } @@ -3901,7 +4272,14 @@ export class PhotonGeyserCategoryAttr extends VariableMoveCategoryAttr { } } -export class TeraBlastCategoryAttr extends VariableMoveCategoryAttr { +/** + * Attribute used for tera moves that change category based on the user's Atk and SpAtk stats + * Note: Currently, `getEffectiveStat` does not ignore all abilities that affect stats except those + * with the attribute of `StatMultiplierAbAttr` + * TODO: Remove the `.partial()` tag from Tera Blast and Tera Starstorm when the above issue is resolved + * @extends VariableMoveCategoryAttr + */ +export class TeraMoveCategoryAttr extends VariableMoveCategoryAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const category = (args[0] as Utils.NumberHolder); @@ -3951,11 +4329,11 @@ export class StatusCategoryOnAllyAttr extends VariableMoveCategoryAttr { * @param user {@linkcode Pokemon} using the move * @param target {@linkcode Pokemon} target of the move * @param move {@linkcode Move} with this attribute - * @param args [0] {@linkcode Utils.IntegerHolder} The category of the move + * @param args [0] {@linkcode Utils.NumberHolder} The category of the move * @returns true if the function succeeds */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const category = (args[0] as Utils.IntegerHolder); + const category = (args[0] as Utils.NumberHolder); if (user.getAlly() === target) { category.value = MoveCategory.STATUS; @@ -3990,6 +4368,30 @@ export class VariableMoveTypeAttr extends MoveAttr { } } +/** + * Attribute used for Tera Starstorm that changes the move type to Stellar + * @extends VariableMoveTypeAttr + */ +export class TeraStarstormTypeAttr extends VariableMoveTypeAttr { + /** + * + * @param user the {@linkcode Pokemon} using the move + * @param target n/a + * @param move n/a + * @param args[0] {@linkcode Utils.NumberHolder} the move type + * @returns `true` if the move type is changed to {@linkcode Type.STELLAR}, `false` otherwise + */ + override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (user.isTerastallized() && (user.hasFusionSpecies(Species.TERAPAGOS) || user.species.speciesId === Species.TERAPAGOS)) { + const moveType = args[0] as Utils.NumberHolder; + + moveType.value = Type.STELLAR; + return true; + } + return false; + } +} + export class FormChangeItemTypeAttr extends VariableMoveTypeAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const moveType = args[0]; @@ -3997,7 +4399,7 @@ export class FormChangeItemTypeAttr extends VariableMoveTypeAttr { return false; } - if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.ARCEUS) || [user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.SILVALLY)) { + if ([ user.species.speciesId, user.fusionSpecies?.speciesId ].includes(Species.ARCEUS) || [ user.species.speciesId, user.fusionSpecies?.speciesId ].includes(Species.SILVALLY)) { const form = user.species.speciesId === Species.ARCEUS || user.species.speciesId === Species.SILVALLY ? user.formIndex : user.fusionSpecies?.formIndex!; // TODO: is this bang correct? moveType.value = Type[Type[form]]; @@ -4015,25 +4417,25 @@ export class TechnoBlastTypeAttr extends VariableMoveTypeAttr { return false; } - if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.GENESECT)) { + if ([ user.species.speciesId, user.fusionSpecies?.speciesId ].includes(Species.GENESECT)) { const form = user.species.speciesId === Species.GENESECT ? user.formIndex : user.fusionSpecies?.formIndex; switch (form) { - case 1: // Shock Drive - moveType.value = Type.ELECTRIC; - break; - case 2: // Burn Drive - moveType.value = Type.FIRE; - break; - case 3: // Chill Drive - moveType.value = Type.ICE; - break; - case 4: // Douse Drive - moveType.value = Type.WATER; - break; - default: - moveType.value = Type.NORMAL; - break; + case 1: // Shock Drive + moveType.value = Type.ELECTRIC; + break; + case 2: // Burn Drive + moveType.value = Type.FIRE; + break; + case 3: // Chill Drive + moveType.value = Type.ICE; + break; + case 4: // Douse Drive + moveType.value = Type.WATER; + break; + default: + moveType.value = Type.NORMAL; + break; } return true; } @@ -4049,16 +4451,16 @@ export class AuraWheelTypeAttr extends VariableMoveTypeAttr { return false; } - if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.MORPEKO)) { + if ([ user.species.speciesId, user.fusionSpecies?.speciesId ].includes(Species.MORPEKO)) { const form = user.species.speciesId === Species.MORPEKO ? user.formIndex : user.fusionSpecies?.formIndex; switch (form) { - case 1: // Hangry Mode - moveType.value = Type.DARK; - break; - default: // Full Belly Mode - moveType.value = Type.ELECTRIC; - break; + case 1: // Hangry Mode + moveType.value = Type.DARK; + break; + default: // Full Belly Mode + moveType.value = Type.ELECTRIC; + break; } return true; } @@ -4074,19 +4476,19 @@ export class RagingBullTypeAttr extends VariableMoveTypeAttr { return false; } - if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.PALDEA_TAUROS)) { + if ([ user.species.speciesId, user.fusionSpecies?.speciesId ].includes(Species.PALDEA_TAUROS)) { const form = user.species.speciesId === Species.PALDEA_TAUROS ? user.formIndex : user.fusionSpecies?.formIndex; switch (form) { - case 1: // Blaze breed - moveType.value = Type.FIRE; - break; - case 2: // Aqua breed - moveType.value = Type.WATER; - break; - default: - moveType.value = Type.FIGHTING; - break; + case 1: // Blaze breed + moveType.value = Type.FIRE; + break; + case 2: // Aqua breed + moveType.value = Type.WATER; + break; + default: + moveType.value = Type.FIGHTING; + break; } return true; } @@ -4102,26 +4504,26 @@ export class IvyCudgelTypeAttr extends VariableMoveTypeAttr { return false; } - if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.OGERPON)) { + if ([ user.species.speciesId, user.fusionSpecies?.speciesId ].includes(Species.OGERPON)) { const form = user.species.speciesId === Species.OGERPON ? user.formIndex : user.fusionSpecies?.formIndex; switch (form) { - case 1: // Wellspring Mask - case 5: // Wellspring Mask Tera - moveType.value = Type.WATER; - break; - case 2: // Hearthflame Mask - case 6: // Hearthflame Mask Tera - moveType.value = Type.FIRE; - break; - case 3: // Cornerstone Mask - case 7: // Cornerstone Mask Tera - moveType.value = Type.ROCK; - break; - case 4: // Teal Mask Tera - default: - moveType.value = Type.GRASS; - break; + case 1: // Wellspring Mask + case 5: // Wellspring Mask Tera + moveType.value = Type.WATER; + break; + case 2: // Hearthflame Mask + case 6: // Hearthflame Mask Tera + moveType.value = Type.FIRE; + break; + case 3: // Cornerstone Mask + case 7: // Cornerstone Mask Tera + moveType.value = Type.ROCK; + break; + case 4: // Teal Mask Tera + default: + moveType.value = Type.GRASS; + break; } return true; } @@ -4139,23 +4541,23 @@ export class WeatherBallTypeAttr extends VariableMoveTypeAttr { if (!user.scene.arena.weather?.isEffectSuppressed(user.scene)) { switch (user.scene.arena.weather?.weatherType) { - case WeatherType.SUNNY: - case WeatherType.HARSH_SUN: - moveType.value = Type.FIRE; - break; - case WeatherType.RAIN: - case WeatherType.HEAVY_RAIN: - moveType.value = Type.WATER; - break; - case WeatherType.SANDSTORM: - moveType.value = Type.ROCK; - break; - case WeatherType.HAIL: - case WeatherType.SNOW: - moveType.value = Type.ICE; - break; - default: - return false; + case WeatherType.SUNNY: + case WeatherType.HARSH_SUN: + moveType.value = Type.FIRE; + break; + case WeatherType.RAIN: + case WeatherType.HEAVY_RAIN: + moveType.value = Type.WATER; + break; + case WeatherType.SANDSTORM: + moveType.value = Type.ROCK; + break; + case WeatherType.HAIL: + case WeatherType.SNOW: + moveType.value = Type.ICE; + break; + default: + return false; } return true; } @@ -4190,20 +4592,20 @@ export class TerrainPulseTypeAttr extends VariableMoveTypeAttr { const currentTerrain = user.scene.arena.getTerrainType(); switch (currentTerrain) { - case TerrainType.MISTY: - moveType.value = Type.FAIRY; - break; - case TerrainType.ELECTRIC: - moveType.value = Type.ELECTRIC; - break; - case TerrainType.GRASSY: - moveType.value = Type.GRASS; - break; - case TerrainType.PSYCHIC: - moveType.value = Type.PSYCHIC; - break; - default: - return false; + case TerrainType.MISTY: + moveType.value = Type.FAIRY; + break; + case TerrainType.ELECTRIC: + moveType.value = Type.ELECTRIC; + break; + case TerrainType.GRASSY: + moveType.value = Type.GRASS; + break; + case TerrainType.PSYCHIC: + moveType.value = Type.PSYCHIC; + break; + default: + return false; } return true; } @@ -4221,17 +4623,17 @@ export class HiddenPowerTypeAttr extends VariableMoveTypeAttr { } const iv_val = Math.floor(((user.ivs[Stat.HP] & 1) - +(user.ivs[Stat.ATK] & 1) * 2 - +(user.ivs[Stat.DEF] & 1) * 4 - +(user.ivs[Stat.SPD] & 1) * 8 - +(user.ivs[Stat.SPATK] & 1) * 16 - +(user.ivs[Stat.SPDEF] & 1) * 32) * 15/63); + + (user.ivs[Stat.ATK] & 1) * 2 + + (user.ivs[Stat.DEF] & 1) * 4 + + (user.ivs[Stat.SPD] & 1) * 8 + + (user.ivs[Stat.SPATK] & 1) * 16 + + (user.ivs[Stat.SPDEF] & 1) * 32) * 15 / 63); moveType.value = [ Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND, Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL, Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC, - Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK][iv_val]; + Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK ][iv_val]; return true; } @@ -4286,6 +4688,47 @@ export class MatchUserTypeAttr extends VariableMoveTypeAttr { } } +/** + * Changes the type of a Pledge move based on the Pledge move combined with it. + * @extends VariableMoveTypeAttr + */ +export class CombinedPledgeTypeAttr extends VariableMoveTypeAttr { + override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + const moveType = args[0]; + if (!(moveType instanceof Utils.NumberHolder)) { + return false; + } + + const combinedPledgeMove = user.turnData.combiningPledge; + if (!combinedPledgeMove) { + return false; + } + + switch (move.id) { + case Moves.FIRE_PLEDGE: + if (combinedPledgeMove === Moves.WATER_PLEDGE) { + moveType.value = Type.WATER; + return true; + } + return false; + case Moves.WATER_PLEDGE: + if (combinedPledgeMove === Moves.GRASS_PLEDGE) { + moveType.value = Type.GRASS; + return true; + } + return false; + case Moves.GRASS_PLEDGE: + if (combinedPledgeMove === Moves.FIRE_PLEDGE) { + moveType.value = Type.FIRE; + return true; + } + return false; + default: + return false; + } + } +} + export class VariableMoveTypeMultiplierAttr extends MoveAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { return false; @@ -4326,18 +4769,19 @@ export class WaterSuperEffectTypeMultiplierAttr extends VariableMoveTypeMultipli export class IceNoEffectTypeAttr extends VariableMoveTypeMultiplierAttr { /** * Checks to see if the Target is Ice-Type or not. If so, the move will have no effect. - * @param {Pokemon} user N/A - * @param {Pokemon} target Pokemon that is being checked whether Ice-Type or not. - * @param {Move} move N/A - * @param {any[]} args Sets to false if the target is Ice-Type, so it should do no damage/no effect. - * @returns {boolean} Returns true if move is successful, false if Ice-Type. + * @param user n/a + * @param target The {@linkcode Pokemon} targeted by the move + * @param move n/a + * @param args `[0]` a {@linkcode Utils.NumberHolder | NumberHolder} containing a type effectiveness multiplier + * @returns `true` if this Ice-type immunity applies; `false` otherwise */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + const multiplier = args[0] as Utils.NumberHolder; if (target.isOfType(Type.ICE)) { - (args[0] as Utils.BooleanHolder).value = false; - return false; + multiplier.value = 0; + return true; } - return true; + return false; } } @@ -4422,7 +4866,7 @@ const crashDamageFunc = (user: Pokemon, move: Move) => { } user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), HitResult.OTHER, false, true); - user.scene.queueMessage(i18next.t("moveTriggers:keptGoingAndCrashed", {pokemonName: getPokemonNameWithAffix(user)})); + user.scene.queueMessage(i18next.t("moveTriggers:keptGoingAndCrashed", { pokemonName: getPokemonNameWithAffix(user) })); user.turnData.damageTaken += Utils.toDmgValue(user.getMaxHp() / 2); return true; @@ -4433,7 +4877,15 @@ export class TypelessAttr extends MoveAttr { } * Attribute used for moves which ignore redirection effects, and always target their original target, i.e. Snipe Shot * Bypasses Storm Drain, Follow Me, Ally Switch, and the like. */ -export class BypassRedirectAttr extends MoveAttr { } +export class BypassRedirectAttr extends MoveAttr { + /** `true` if this move only bypasses redirection from Abilities */ + public readonly abilitiesOnly: boolean; + + constructor(abilitiesOnly: boolean = false) { + super(); + this.abilitiesOnly = abilitiesOnly; + } +} export class FrenzyAttr extends MoveEffectAttr { constructor() { @@ -4471,6 +4923,37 @@ export const frenzyMissFunc: UserMoveConditionFunc = (user: Pokemon, move: Move) return true; }; +/** + * Attribute that grants {@link https://bulbapedia.bulbagarden.net/wiki/Semi-invulnerable_turn | semi-invulnerability} to the user during + * the associated move's charging phase. Should only be used for {@linkcode ChargingMove | ChargingMoves} as a `chargeAttr`. + * @extends MoveEffectAttr + */ +export class SemiInvulnerableAttr extends MoveEffectAttr { + /** The type of {@linkcode SemiInvulnerableTag} to grant to the user */ + public tagType: BattlerTagType; + + constructor(tagType: BattlerTagType) { + super(true); + this.tagType = tagType; + } + + /** + * Grants a {@linkcode SemiInvulnerableTag} to the associated move's user. + * @param user the {@linkcode Pokemon} using the move + * @param target n/a + * @param move the {@linkcode Move} being used + * @param args n/a + * @returns `true` if semi-invulnerability was successfully granted; `false` otherwise. + */ + override apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean { + if (!super.apply(user, target, move, args)) { + return false; + } + + return user.addTag(this.tagType, 1, move.id, user.id); + } +} + export class AddBattlerTagAttr extends MoveEffectAttr { public tagType: BattlerTagType; public turnCountMin: integer; @@ -4489,7 +4972,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr { } canApply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - if (!super.canApply(user, target, move, args) || (this.cancelOnFail === true && user.getLastXMoves(1)[0].result === MoveResult.FAIL)) { + if (!super.canApply(user, target, move, args) || (this.cancelOnFail === true && user.getLastXMoves(1)[0]?.result === MoveResult.FAIL)) { return false; } else { return true; @@ -4517,48 +5000,48 @@ export class AddBattlerTagAttr extends MoveEffectAttr { getTagTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer | void { switch (this.tagType) { - case BattlerTagType.RECHARGING: - case BattlerTagType.PERISH_SONG: - return -16; - case BattlerTagType.FLINCHED: - case BattlerTagType.CONFUSED: - case BattlerTagType.INFATUATED: - case BattlerTagType.NIGHTMARE: - case BattlerTagType.DROWSY: - case BattlerTagType.DISABLED: - case BattlerTagType.HEAL_BLOCK: - case BattlerTagType.RECEIVE_DOUBLE_DAMAGE: - return -5; - case BattlerTagType.SEEDED: - case BattlerTagType.SALT_CURED: - case BattlerTagType.CURSED: - case BattlerTagType.FRENZY: - case BattlerTagType.TRAPPED: - case BattlerTagType.BIND: - case BattlerTagType.WRAP: - case BattlerTagType.FIRE_SPIN: - case BattlerTagType.WHIRLPOOL: - case BattlerTagType.CLAMP: - case BattlerTagType.SAND_TOMB: - case BattlerTagType.MAGMA_STORM: - case BattlerTagType.SNAP_TRAP: - case BattlerTagType.THUNDER_CAGE: - case BattlerTagType.INFESTATION: - return -3; - case BattlerTagType.ENCORE: - return -2; - case BattlerTagType.MINIMIZED: - case BattlerTagType.ALWAYS_GET_HIT: - return 0; - case BattlerTagType.INGRAIN: - case BattlerTagType.IGNORE_ACCURACY: - case BattlerTagType.AQUA_RING: - return 3; - case BattlerTagType.PROTECTED: - case BattlerTagType.FLYING: - case BattlerTagType.CRIT_BOOST: - case BattlerTagType.ALWAYS_CRIT: - return 5; + case BattlerTagType.RECHARGING: + case BattlerTagType.PERISH_SONG: + return -16; + case BattlerTagType.FLINCHED: + case BattlerTagType.CONFUSED: + case BattlerTagType.INFATUATED: + case BattlerTagType.NIGHTMARE: + case BattlerTagType.DROWSY: + case BattlerTagType.DISABLED: + case BattlerTagType.HEAL_BLOCK: + case BattlerTagType.RECEIVE_DOUBLE_DAMAGE: + return -5; + case BattlerTagType.SEEDED: + case BattlerTagType.SALT_CURED: + case BattlerTagType.CURSED: + case BattlerTagType.FRENZY: + case BattlerTagType.TRAPPED: + case BattlerTagType.BIND: + case BattlerTagType.WRAP: + case BattlerTagType.FIRE_SPIN: + case BattlerTagType.WHIRLPOOL: + case BattlerTagType.CLAMP: + case BattlerTagType.SAND_TOMB: + case BattlerTagType.MAGMA_STORM: + case BattlerTagType.SNAP_TRAP: + case BattlerTagType.THUNDER_CAGE: + case BattlerTagType.INFESTATION: + return -3; + case BattlerTagType.ENCORE: + return -2; + case BattlerTagType.MINIMIZED: + case BattlerTagType.ALWAYS_GET_HIT: + return 0; + case BattlerTagType.INGRAIN: + case BattlerTagType.IGNORE_ACCURACY: + case BattlerTagType.AQUA_RING: + return 3; + case BattlerTagType.PROTECTED: + case BattlerTagType.FLYING: + case BattlerTagType.CRIT_BOOST: + case BattlerTagType.ALWAYS_CRIT: + return 5; } } @@ -4606,14 +5089,14 @@ export class GulpMissileTagAttr extends MoveEffectAttr { /** * Adds BattlerTagType from GulpMissileTag based on the Pokemon's HP ratio. - * @param {Pokemon} user The Pokemon using the move. - * @param {Pokemon} target The Pokemon being targeted by the move. - * @param {Move} move The move being used. - * @param {any[]} args Additional arguments, if any. + * @param user The Pokemon using the move. + * @param _target N/A + * @param move The move being used. + * @param _args N/A * @returns Whether the BattlerTag is applied. */ - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { - if (!super.apply(user, target, move, args)) { + apply(user: Pokemon, _target: Pokemon, move: Move, _args: any[]): boolean { + if (!super.apply(user, _target, move, _args)) { return false; } @@ -4688,7 +5171,7 @@ export class CurseAttr extends MoveEffectAttr { target.addTag(BattlerTagType.CURSED, 0, move.id, user.id); return true; } else { - user.scene.unshiftPhase(new StatStageChangePhase(user.scene, user.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF], 1)); + user.scene.unshiftPhase(new StatStageChangePhase(user.scene, user.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF ], 1)); user.scene.unshiftPhase(new StatStageChangePhase(user.scene, user.getBattlerIndex(), true, [ Stat.SPD ], -1)); return true; } @@ -4758,9 +5241,9 @@ export class ConfuseAttr extends AddBattlerTagAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - if (!this.selfTarget && target.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY)) { + if (!this.selfTarget && target.isSafeguarded(user)) { if (move.category === MoveCategory.STATUS) { - user.scene.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(target)})); + user.scene.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(target) })); } return false; } @@ -4820,7 +5303,7 @@ export class IgnoreAccuracyAttr extends AddBattlerTagAttr { return false; } - user.scene.queueMessage(i18next.t("moveTriggers:tookAimAtTarget", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target)})); + user.scene.queueMessage(i18next.t("moveTriggers:tookAimAtTarget", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) })); return true; } @@ -4836,7 +5319,7 @@ export class FaintCountdownAttr extends AddBattlerTagAttr { return false; } - user.scene.queueMessage(i18next.t("moveTriggers:faintCountdown", {pokemonName: getPokemonNameWithAffix(target), turnCount: this.turnCountMin - 1})); + user.scene.queueMessage(i18next.t("moveTriggers:faintCountdown", { pokemonName: getPokemonNameWithAffix(target), turnCount: this.turnCountMin - 1 })); return true; } @@ -4927,7 +5410,7 @@ export class AddArenaTagAttr extends MoveEffectAttr { return false; } - if ((move.chance < 0 || move.chance === 100 || user.randSeedInt(100) < move.chance) && user.getLastXMoves(1)[0].result === MoveResult.SUCCESS) { + if ((move.chance < 0 || move.chance === 100 || user.randSeedInt(100) < move.chance) && user.getLastXMoves(1)[0]?.result === MoveResult.SUCCESS) { user.scene.arena.addTag(this.tagType, this.turnCount, move.id, user.id, (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY); return true; } @@ -5002,7 +5485,7 @@ export class AddArenaTrapTagHitAttr extends AddArenaTagAttr { const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); const side = (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; const tag = user.scene.arena.getTagOnSide(this.tagType, side) as ArenaTrapTag; - if ((moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) && user.getLastXMoves(1)[0].result === MoveResult.SUCCESS) { + if ((moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) && user.getLastXMoves(1)[0]?.result === MoveResult.SUCCESS) { user.scene.arena.addTag(this.tagType, 0, move.id, user.id, side); if (!tag) { return true; @@ -5119,11 +5602,37 @@ export class SwapArenaTagsAttr extends MoveEffectAttr { } - user.scene.queueMessage(i18next.t("moveTriggers:swapArenaTags", {pokemonName: getPokemonNameWithAffix(user)})); + user.scene.queueMessage(i18next.t("moveTriggers:swapArenaTags", { pokemonName: getPokemonNameWithAffix(user) })); return true; } } +/** + * Attribute that adds a secondary effect to the field when two unique Pledge moves + * are combined. The effect added varies based on the two Pledge moves combined. + */ +export class AddPledgeEffectAttr extends AddArenaTagAttr { + private readonly requiredPledge: Moves; + + constructor(tagType: ArenaTagType, requiredPledge: Moves, selfSideTarget: boolean = false) { + super(tagType, 4, false, selfSideTarget); + + this.requiredPledge = requiredPledge; + } + + override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + // TODO: add support for `HIT` effect triggering in AddArenaTagAttr to remove the need for this check + if (user.getLastXMoves(1)[0]?.result !== MoveResult.SUCCESS) { + return false; + } + + if (user.turnData.combiningPledge === this.requiredPledge) { + return super.apply(user, target, move, args); + } + return false; + } +} + /** * Attribute used for Revival Blessing. * @extends MoveEffectAttr @@ -5146,7 +5655,7 @@ export class RevivalBlessingAttr extends MoveEffectAttr { return new Promise(resolve => { // If user is player, checks if the user has fainted pokemon if (user instanceof PlayerPokemon - && user.scene.getParty().findIndex(p => p.isFainted())>-1) { + && user.scene.getParty().findIndex(p => p.isFainted()) > -1) { (user as PlayerPokemon).revivalBlessing().then(() => { resolve(true); }); @@ -5160,11 +5669,11 @@ export class RevivalBlessingAttr extends MoveEffectAttr { const slotIndex = user.scene.getEnemyParty().findIndex(p => pokemon.id === p.id); pokemon.resetStatus(); pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp())); - user.scene.queueMessage(i18next.t("moveTriggers:revivalBlessing", {pokemonName: getPokemonNameWithAffix(pokemon)}), 0, true); + user.scene.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: getPokemonNameWithAffix(pokemon) }), 0, true); if (user.scene.currentBattle.double && user.scene.getEnemyParty().length > 1) { const allyPokemon = user.getAlly(); - if (slotIndex<=1) { + if (slotIndex <= 1) { user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, SwitchType.SWITCH, pokemon.getFieldIndex(), slotIndex, false, false)); } else if (allyPokemon.isFainted()) { user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, SwitchType.SWITCH, allyPokemon.getFieldIndex(), slotIndex, false, false)); @@ -5211,38 +5720,39 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { */ const switchOutTarget = this.selfSwitch ? user : target; if (switchOutTarget instanceof PlayerPokemon) { + // Switch out logic for the player's Pokemon if (switchOutTarget.scene.getParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) { return false; } - switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); if (switchOutTarget.hp > 0) { + switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); user.scene.prependToPhase(new SwitchPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(), true, true), MoveEndPhase); return true; } return false; } else if (user.scene.currentBattle.battleType !== BattleType.WILD) { + // Switch out logic for trainer battles if (switchOutTarget.scene.getEnemyParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) { return false; } - // Switch out logic for trainer battles - switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); if (switchOutTarget.hp > 0) { // for opponent switching out + switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); user.scene.prependToPhase(new SwitchSummonPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(), (user.scene.currentBattle.trainer ? user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot) : 0), false, false), MoveEndPhase); } } else { + // Switch out logic for everything else (eg: WILD battles) if (user.scene.currentBattle.waveIndex % 10 === 0) { return false; } - // Switch out logic for everything else (eg: WILD battles) - switchOutTarget.leaveField(false); - if (switchOutTarget.hp) { - user.scene.queueMessage(i18next.t("moveTriggers:fled", {pokemonName: getPokemonNameWithAffix(switchOutTarget)}), null, true, 500); + if (switchOutTarget.hp > 0) { + switchOutTarget.leaveField(false); + user.scene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500); // in double battles redirect potential moves off fled pokemon if (switchOutTarget.scene.currentBattle.double) { @@ -5271,7 +5781,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { getFailedText(user: Pokemon, target: Pokemon, move: Move, cancelled: Utils.BooleanHolder): string | null { const blockedByAbility = new Utils.BooleanHolder(false); applyAbAttrs(ForceSwitchOutImmunityAbAttr, target, blockedByAbility); - return blockedByAbility.value ? i18next.t("moveTriggers:cannotBeSwitchedOut", {pokemonName: getPokemonNameWithAffix(target)}) : null; + return blockedByAbility.value ? i18next.t("moveTriggers:cannotBeSwitchedOut", { pokemonName: getPokemonNameWithAffix(target) }) : null; } getSwitchOutCondition(): MoveConditionFunc { @@ -5359,6 +5869,9 @@ export class RemoveTypeAttr extends MoveEffectAttr { const userTypes = user.getTypes(true); const modifiedTypes = userTypes.filter(type => type !== this.removedType); + if (modifiedTypes.length === 0) { + modifiedTypes.push(Type.UNKNOWN); + } user.summonData.types = modifiedTypes; user.updateInfo(); @@ -5381,16 +5894,20 @@ export class CopyTypeAttr extends MoveEffectAttr { return false; } - user.summonData.types = target.getTypes(true); + const targetTypes = target.getTypes(true); + if (targetTypes.includes(Type.UNKNOWN) && targetTypes.indexOf(Type.UNKNOWN) > -1) { + targetTypes[targetTypes.indexOf(Type.UNKNOWN)] = Type.NORMAL; + } + user.summonData.types = targetTypes; user.updateInfo(); - user.scene.queueMessage(i18next.t("moveTriggers:copyType", {pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target)})); + user.scene.queueMessage(i18next.t("moveTriggers:copyType", { pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target) })); return true; } getCondition(): MoveConditionFunc { - return (user, target, move) => target.getTypes()[0] !== Type.UNKNOWN; + return (user, target, move) => target.getTypes()[0] !== Type.UNKNOWN || target.summonData.addedType !== null; } } @@ -5409,7 +5926,7 @@ export class CopyBiomeTypeAttr extends MoveEffectAttr { user.summonData.types = [ biomeType ]; user.updateInfo(); - user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoType", {pokemonName: getPokemonNameWithAffix(user), typeName: i18next.t(`pokemonInfo:Type.${Type[biomeType]}`)})); + user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), typeName: i18next.t(`pokemonInfo:Type.${Type[biomeType]}`) })); return true; } @@ -5425,10 +5942,10 @@ export class ChangeTypeAttr extends MoveEffectAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - target.summonData.types = [this.type]; + target.summonData.types = [ this.type ]; target.updateInfo(); - user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoType", {pokemonName: getPokemonNameWithAffix(target), typeName: i18next.t(`pokemonInfo:Type.${Type[this.type]}`)})); + user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoType", { pokemonName: getPokemonNameWithAffix(target), typeName: i18next.t(`pokemonInfo:Type.${Type[this.type]}`) })); return true; } @@ -5448,20 +5965,16 @@ export class AddTypeAttr extends MoveEffectAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const types = target.getTypes().slice(0, 2).filter(t => t !== Type.UNKNOWN); // TODO: Figure out some way to actually check if another version of this effect is already applied - if (this.type !== Type.UNKNOWN) { - types.push(this.type); - } - target.summonData.types = types; + target.summonData.addedType = this.type; target.updateInfo(); - user.scene.queueMessage(i18next.t("moveTriggers:addType", {typeName: i18next.t(`pokemonInfo:Type.${Type[this.type]}`), pokemonName: getPokemonNameWithAffix(target)})); + user.scene.queueMessage(i18next.t("moveTriggers:addType", { typeName: i18next.t(`pokemonInfo:Type.${Type[this.type]}`), pokemonName: getPokemonNameWithAffix(target) })); return true; } getCondition(): MoveConditionFunc { - return (user, target, move) => !target.isTerastallized()&& !target.getTypes().includes(this.type); + return (user, target, move) => !target.isTerastallized() && !target.getTypes().includes(this.type); } } @@ -5477,7 +5990,7 @@ export class FirstMoveTypeAttr extends MoveEffectAttr { const firstMoveType = target.getMoveset()[0]?.getMove().type!; // TODO: is this bang correct? user.summonData.types = [ firstMoveType ]; - user.scene.queueMessage(i18next.t("battle:transformedIntoType", {pokemonName: getPokemonNameWithAffix(user), type: i18next.t(`pokemonInfo:Type.${Type[firstMoveType]}`)})); + user.scene.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: i18next.t(`pokemonInfo:Type.${Type[firstMoveType]}`) })); return true; } @@ -5504,19 +6017,19 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr { } let selectTargets: BattlerIndex[]; switch (true) { - case (moveTargets.multiple || moveTargets.targets.length === 1): { - selectTargets = moveTargets.targets; - break; - } - case (moveTargets.targets.indexOf(target.getBattlerIndex()) > -1): { - selectTargets = [ target.getBattlerIndex() ]; - break; - } - default: { - moveTargets.targets.splice(moveTargets.targets.indexOf(user.getAlly().getBattlerIndex())); - selectTargets = [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ]; - break; - } + case (moveTargets.multiple || moveTargets.targets.length === 1): { + selectTargets = moveTargets.targets; + break; + } + case (moveTargets.targets.indexOf(target.getBattlerIndex()) > -1): { + selectTargets = [ target.getBattlerIndex() ]; + break; + } + default: { + moveTargets.targets.splice(moveTargets.targets.indexOf(user.getAlly().getBattlerIndex())); + selectTargets = [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ]; + break; + } } const targets = selectTargets; user.getMoveQueue().push({ move: move?.moveId!, targets: targets, ignorePP: true }); // TODO: is this bang correct? @@ -5560,135 +6073,135 @@ export class NaturePowerAttr extends OverrideMoveEffectAttr { let moveId; switch (user.scene.arena.getTerrainType()) { // this allows terrains to 'override' the biome move - case TerrainType.NONE: - switch (user.scene.arena.biomeType) { - case Biome.TOWN: - moveId = Moves.ROUND; + case TerrainType.NONE: + switch (user.scene.arena.biomeType) { + case Biome.TOWN: + moveId = Moves.ROUND; + break; + case Biome.METROPOLIS: + moveId = Moves.TRI_ATTACK; + break; + case Biome.SLUM: + moveId = Moves.SLUDGE_BOMB; + break; + case Biome.PLAINS: + moveId = Moves.SILVER_WIND; + break; + case Biome.GRASS: + moveId = Moves.GRASS_KNOT; + break; + case Biome.TALL_GRASS: + moveId = Moves.POLLEN_PUFF; + break; + case Biome.MEADOW: + moveId = Moves.GIGA_DRAIN; + break; + case Biome.FOREST: + moveId = Moves.BUG_BUZZ; + break; + case Biome.JUNGLE: + moveId = Moves.LEAF_STORM; + break; + case Biome.SEA: + moveId = Moves.HYDRO_PUMP; + break; + case Biome.SWAMP: + moveId = Moves.MUD_BOMB; + break; + case Biome.BEACH: + moveId = Moves.SCALD; + break; + case Biome.LAKE: + moveId = Moves.BUBBLE_BEAM; + break; + case Biome.SEABED: + moveId = Moves.BRINE; + break; + case Biome.ISLAND: + moveId = Moves.LEAF_TORNADO; + break; + case Biome.MOUNTAIN: + moveId = Moves.AIR_SLASH; + break; + case Biome.BADLANDS: + moveId = Moves.EARTH_POWER; + break; + case Biome.DESERT: + moveId = Moves.SCORCHING_SANDS; + break; + case Biome.WASTELAND: + moveId = Moves.DRAGON_PULSE; + break; + case Biome.CONSTRUCTION_SITE: + moveId = Moves.STEEL_BEAM; + break; + case Biome.CAVE: + moveId = Moves.POWER_GEM; + break; + case Biome.ICE_CAVE: + moveId = Moves.ICE_BEAM; + break; + case Biome.SNOWY_FOREST: + moveId = Moves.FROST_BREATH; + break; + case Biome.VOLCANO: + moveId = Moves.LAVA_PLUME; + break; + case Biome.GRAVEYARD: + moveId = Moves.SHADOW_BALL; + break; + case Biome.RUINS: + moveId = Moves.ANCIENT_POWER; + break; + case Biome.TEMPLE: + moveId = Moves.EXTRASENSORY; + break; + case Biome.DOJO: + moveId = Moves.FOCUS_BLAST; + break; + case Biome.FAIRY_CAVE: + moveId = Moves.ALLURING_VOICE; + break; + case Biome.ABYSS: + moveId = Moves.OMINOUS_WIND; + break; + case Biome.SPACE: + moveId = Moves.DRACO_METEOR; + break; + case Biome.FACTORY: + moveId = Moves.FLASH_CANNON; + break; + case Biome.LABORATORY: + moveId = Moves.ZAP_CANNON; + break; + case Biome.POWER_PLANT: + moveId = Moves.CHARGE_BEAM; + break; + case Biome.END: + moveId = Moves.ETERNABEAM; + break; + } break; - case Biome.METROPOLIS: + case TerrainType.MISTY: + moveId = Moves.MOONBLAST; + break; + case TerrainType.ELECTRIC: + moveId = Moves.THUNDERBOLT; + break; + case TerrainType.GRASSY: + moveId = Moves.ENERGY_BALL; + break; + case TerrainType.PSYCHIC: + moveId = Moves.PSYCHIC; + break; + default: + // Just in case there's no match moveId = Moves.TRI_ATTACK; break; - case Biome.SLUM: - moveId = Moves.SLUDGE_BOMB; - break; - case Biome.PLAINS: - moveId = Moves.SILVER_WIND; - break; - case Biome.GRASS: - moveId = Moves.GRASS_KNOT; - break; - case Biome.TALL_GRASS: - moveId = Moves.POLLEN_PUFF; - break; - case Biome.MEADOW: - moveId = Moves.GIGA_DRAIN; - break; - case Biome.FOREST: - moveId = Moves.BUG_BUZZ; - break; - case Biome.JUNGLE: - moveId = Moves.LEAF_STORM; - break; - case Biome.SEA: - moveId = Moves.HYDRO_PUMP; - break; - case Biome.SWAMP: - moveId = Moves.MUD_BOMB; - break; - case Biome.BEACH: - moveId = Moves.SCALD; - break; - case Biome.LAKE: - moveId = Moves.BUBBLE_BEAM; - break; - case Biome.SEABED: - moveId = Moves.BRINE; - break; - case Biome.ISLAND: - moveId = Moves.LEAF_TORNADO; - break; - case Biome.MOUNTAIN: - moveId = Moves.AIR_SLASH; - break; - case Biome.BADLANDS: - moveId = Moves.EARTH_POWER; - break; - case Biome.DESERT: - moveId = Moves.SCORCHING_SANDS; - break; - case Biome.WASTELAND: - moveId = Moves.DRAGON_PULSE; - break; - case Biome.CONSTRUCTION_SITE: - moveId = Moves.STEEL_BEAM; - break; - case Biome.CAVE: - moveId = Moves.POWER_GEM; - break; - case Biome.ICE_CAVE: - moveId = Moves.ICE_BEAM; - break; - case Biome.SNOWY_FOREST: - moveId = Moves.FROST_BREATH; - break; - case Biome.VOLCANO: - moveId = Moves.LAVA_PLUME; - break; - case Biome.GRAVEYARD: - moveId = Moves.SHADOW_BALL; - break; - case Biome.RUINS: - moveId = Moves.ANCIENT_POWER; - break; - case Biome.TEMPLE: - moveId = Moves.EXTRASENSORY; - break; - case Biome.DOJO: - moveId = Moves.FOCUS_BLAST; - break; - case Biome.FAIRY_CAVE: - moveId = Moves.ALLURING_VOICE; - break; - case Biome.ABYSS: - moveId = Moves.OMINOUS_WIND; - break; - case Biome.SPACE: - moveId = Moves.DRACO_METEOR; - break; - case Biome.FACTORY: - moveId = Moves.FLASH_CANNON; - break; - case Biome.LABORATORY: - moveId = Moves.ZAP_CANNON; - break; - case Biome.POWER_PLANT: - moveId = Moves.CHARGE_BEAM; - break; - case Biome.END: - moveId = Moves.ETERNABEAM; - break; - } - break; - case TerrainType.MISTY: - moveId = Moves.MOONBLAST; - break; - case TerrainType.ELECTRIC: - moveId = Moves.THUNDERBOLT; - break; - case TerrainType.GRASSY: - moveId = Moves.ENERGY_BALL; - break; - case TerrainType.PSYCHIC: - moveId = Moves.PSYCHIC; - break; - default: - // Just in case there's no match - moveId = Moves.TRI_ATTACK; - break; } - user.getMoveQueue().push({ move: moveId, targets: [target.getBattlerIndex()], ignorePP: true }); - user.scene.unshiftPhase(new MovePhase(user.scene, user, [target.getBattlerIndex()], new PokemonMove(moveId, 0, 0, true), true)); + user.getMoveQueue().push({ move: moveId, targets: [ target.getBattlerIndex() ], ignorePP: true }); + user.scene.unshiftPhase(new MovePhase(user.scene, user, [ target.getBattlerIndex() ], new PokemonMove(moveId, 0, 0, true), true)); initMoveAnim(user.scene, moveId).then(() => { loadMoveAnimAssets(user.scene, [ moveId ], true) .then(() => resolve(true)); @@ -5704,7 +6217,7 @@ const lastMoveCopiableCondition: MoveConditionFunc = (user, target, move) => { return false; } - if (allMoves[copiableMove].hasAttr(ChargeAttr)) { + if (allMoves[copiableMove].isChargingMove()) { return false; } @@ -5766,7 +6279,7 @@ export class ReducePpMoveAttr extends MoveEffectAttr { const lastPpUsed = movesetMove?.ppUsed!; // TODO: is the bang correct? movesetMove!.ppUsed = Math.min((movesetMove?.ppUsed!) + this.reduction, movesetMove?.getMovePp()!); // TODO: is the bang correct? - const message = i18next.t("battle:ppReduced", {targetName: getPokemonNameWithAffix(target), moveName: movesetMove?.getName(), reduction: (movesetMove?.ppUsed!) - lastPpUsed}); // TODO: is the bang correct? + const message = i18next.t("battle:ppReduced", { targetName: getPokemonNameWithAffix(target), moveName: movesetMove?.getName(), reduction: (movesetMove?.ppUsed!) - lastPpUsed }); // TODO: is the bang correct? user.scene.eventTarget.dispatchEvent(new MoveUsedEvent(target?.id, movesetMove?.getMove()!, movesetMove?.ppUsed!)); // TODO: are these bangs correct? user.scene.queueMessage(message); @@ -5852,7 +6365,7 @@ const targetMoveCopiableCondition: MoveConditionFunc = (user, target, move) => { return false; } - if (allMoves[copiableMove.move].hasAttr(ChargeAttr) && copiableMove.result === MoveResult.OTHER) { + if (allMoves[copiableMove.move].isChargingMove() && copiableMove.result === MoveResult.OTHER) { return false; } @@ -5879,7 +6392,7 @@ export class MovesetCopyMoveAttr extends OverrideMoveEffectAttr { user.summonData.moveset = user.getMoveset().slice(0); user.summonData.moveset[thisMoveIndex] = new PokemonMove(copiedMove.id, 0, 0); - user.scene.queueMessage(i18next.t("moveTriggers:copiedMove", {pokemonName: getPokemonNameWithAffix(user), moveName: copiedMove.name})); + user.scene.queueMessage(i18next.t("moveTriggers:copiedMove", { pokemonName: getPokemonNameWithAffix(user), moveName: copiedMove.name })); return true; } @@ -5928,7 +6441,7 @@ export class SketchAttr extends MoveEffectAttr { user.setMove(sketchIndex, sketchedMove.id); - user.scene.queueMessage(i18next.t("moveTriggers:sketchedMove", {pokemonName: getPokemonNameWithAffix(user), moveName: sketchedMove.name})); + user.scene.queueMessage(i18next.t("moveTriggers:sketchedMove", { pokemonName: getPokemonNameWithAffix(user), moveName: sketchedMove.name })); return true; } @@ -5988,7 +6501,7 @@ export class AbilityChangeAttr extends MoveEffectAttr { moveTarget.summonData.ability = this.ability; user.scene.triggerPokemonFormChange(moveTarget, SpeciesFormChangeRevertWeatherFormTrigger); - user.scene.queueMessage(i18next.t("moveTriggers:acquiredAbility", {pokemonName: getPokemonNameWithAffix((this.selfTarget ? user : target)), abilityName: allAbilities[this.ability].name})); + user.scene.queueMessage(i18next.t("moveTriggers:acquiredAbility", { pokemonName: getPokemonNameWithAffix((this.selfTarget ? user : target)), abilityName: allAbilities[this.ability].name })); return true; } @@ -6014,11 +6527,11 @@ export class AbilityCopyAttr extends MoveEffectAttr { user.summonData.ability = target.getAbility().id; - user.scene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name})); + user.scene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name })); if (this.copyToPartner && user.scene.currentBattle?.double && user.getAlly().hp) { user.getAlly().summonData.ability = target.getAbility().id; - user.getAlly().scene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", {pokemonName: getPokemonNameWithAffix(user.getAlly()), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name})); + user.getAlly().scene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(user.getAlly()), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name })); } return true; @@ -6051,7 +6564,7 @@ export class AbilityGiveAttr extends MoveEffectAttr { target.summonData.ability = user.getAbility().id; - user.scene.queueMessage(i18next.t("moveTriggers:acquiredAbility", {pokemonName: getPokemonNameWithAffix(target), abilityName: allAbilities[user.getAbility().id].name})); + user.scene.queueMessage(i18next.t("moveTriggers:acquiredAbility", { pokemonName: getPokemonNameWithAffix(target), abilityName: allAbilities[user.getAbility().id].name })); return true; } @@ -6071,7 +6584,7 @@ export class SwitchAbilitiesAttr extends MoveEffectAttr { user.summonData.ability = target.getAbility().id; target.summonData.ability = tempAbilityId; - user.scene.queueMessage(i18next.t("moveTriggers:swappedAbilitiesWithTarget", {pokemonName: getPokemonNameWithAffix(user)})); + user.scene.queueMessage(i18next.t("moveTriggers:swappedAbilitiesWithTarget", { pokemonName: getPokemonNameWithAffix(user) })); // Swaps Forecast/Flower Gift from Castform/Cherrim user.scene.arena.triggerWeatherBasedFormChangesToNormal(); // Swaps Forecast/Flower Gift to Castform/Cherrim (edge case) @@ -6103,7 +6616,7 @@ export class SuppressAbilitiesAttr extends MoveEffectAttr { target.summonData.abilitySuppressed = true; target.scene.arena.triggerWeatherBasedFormChangesToNormal(); - target.scene.queueMessage(i18next.t("moveTriggers:suppressAbilities", {pokemonName: getPokemonNameWithAffix(target)})); + target.scene.queueMessage(i18next.t("moveTriggers:suppressAbilities", { pokemonName: getPokemonNameWithAffix(target) })); return true; } @@ -6144,39 +6657,52 @@ export class SuppressAbilitiesIfActedAttr extends MoveEffectAttr { } export class TransformAttr extends MoveEffectAttr { - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { - return new Promise(resolve => { - if (!super.apply(user, target, move, args)) { - return resolve(false); + async apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { + if (!super.apply(user, target, move, args)) { + return false; + } + + const promises: Promise[] = []; + user.summonData.speciesForm = target.getSpeciesForm(); + user.summonData.fusionSpeciesForm = target.getFusionSpeciesForm(); + user.summonData.ability = target.getAbility().id; + user.summonData.gender = target.getGender(); + user.summonData.fusionGender = target.getFusionGender(); + + // Power Trick's effect will not preserved after using Transform + user.removeTag(BattlerTagType.POWER_TRICK); + + // Copy all stats (except HP) + for (const s of EFFECTIVE_STATS) { + user.setStat(s, target.getStat(s, false), false); + } + + // Copy all stat stages + for (const s of BATTLE_STATS) { + user.setStatStage(s, target.getStatStage(s)); + } + + user.summonData.moveset = target.getMoveset().map((m) => { + if (m) { + // If PP value is less than 5, do nothing. If greater, we need to reduce the value to 5. + return new PokemonMove(m.moveId, 0, 0, false, Math.min(m.getMove().pp, 5)); + } else { + console.warn(`Transform: somehow iterating over a ${m} value when copying moveset!`); + return new PokemonMove(Moves.NONE); } - - user.summonData.speciesForm = target.getSpeciesForm(); - user.summonData.fusionSpeciesForm = target.getFusionSpeciesForm(); - user.summonData.ability = target.getAbility().id; - user.summonData.gender = target.getGender(); - user.summonData.fusionGender = target.getFusionGender(); - - // Copy all stats (except HP) - for (const s of EFFECTIVE_STATS) { - user.setStat(s, target.getStat(s, false), false); - } - - // Copy all stat stages - for (const s of BATTLE_STATS) { - user.setStatStage(s, target.getStatStage(s)); - } - - user.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m?.moveId!, m?.ppUsed, m?.ppUp)); // TODO: is this bang correct? - user.summonData.types = target.getTypes(); - - user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoTarget", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target)})); - - user.loadAssets(false).then(() => { - user.playAnim(); - user.updateInfo(); - resolve(true); - }); }); + user.summonData.types = target.getTypes(); + promises.push(user.updateInfo()); + + user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoTarget", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) })); + + promises.push(user.loadAssets(false).then(() => { + user.playAnim(); + user.updateInfo(); + })); + + await Promise.all(promises); + return true; } } @@ -6369,7 +6895,7 @@ export class DestinyBondAttr extends MoveEffectAttr { * @returns true */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - user.scene.queueMessage(`${i18next.t("moveTriggers:tryingToTakeFoeDown", {pokemonName: getPokemonNameWithAffix(user)})}`); + user.scene.queueMessage(`${i18next.t("moveTriggers:tryingToTakeFoeDown", { pokemonName: getPokemonNameWithAffix(user) })}`); user.addTag(BattlerTagType.DESTINY_BOND, undefined, move.id, user.id); return true; } @@ -6459,7 +6985,7 @@ export class AttackedByItemAttr extends MoveAttr { } const itemName = heldItems[0]?.type?.name ?? "item"; - target.scene.queueMessage(i18next.t("moveTriggers:attackedByItem", {pokemonName: getPokemonNameWithAffix(target), itemName: itemName})); + target.scene.queueMessage(i18next.t("moveTriggers:attackedByItem", { pokemonName: getPokemonNameWithAffix(target), itemName: itemName })); return true; }; @@ -6498,12 +7024,12 @@ export class AfterYouAttr extends MoveEffectAttr { * @returns true */ override apply(user: Pokemon, target: Pokemon, _move: Move, _args: any[]): boolean { - user.scene.queueMessage(i18next.t("moveTriggers:afterYou", {targetName: getPokemonNameWithAffix(target)})); + user.scene.queueMessage(i18next.t("moveTriggers:afterYou", { targetName: getPokemonNameWithAffix(target) })); //Will find next acting phase of the targeted pokémon, delete it and queue it next on successful delete. const nextAttackPhase = target.scene.findPhase((phase) => phase.pokemon === target); if (nextAttackPhase && target.scene.tryRemovePhase((phase: MovePhase) => phase.pokemon === target)) { - target.scene.prependToPhase(new MovePhase(target.scene, target, [...nextAttackPhase.targets], nextAttackPhase.move), MovePhase); + target.scene.prependToPhase(new MovePhase(target.scene, target, [ ...nextAttackPhase.targets ], nextAttackPhase.move), MovePhase); } return true; @@ -6521,7 +7047,7 @@ const failIfDampCondition: MoveConditionFunc = (user, target, move) => { user.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled)); // Queue a message if an ability prevented usage of the move if (cancelled.value) { - user.scene.queueMessage(i18next.t("moveTriggers:cannotUseMove", {pokemonName: getPokemonNameWithAffix(user), moveName: move.name})); + user.scene.queueMessage(i18next.t("moveTriggers:cannotUseMove", { pokemonName: getPokemonNameWithAffix(user), moveName: move.name })); } return !cancelled.value; }; @@ -6548,6 +7074,20 @@ function applyMoveAttrsInternal(attrFilter: MoveAttrFilter, user: Pokemon | null }); } +function applyMoveChargeAttrsInternal(attrFilter: MoveAttrFilter, user: Pokemon | null, target: Pokemon | null, move: ChargingMove, args: any[]): Promise { + return new Promise(resolve => { + const chargeAttrPromises: Promise[] = []; + const chargeMoveAttrs = move.chargeAttrs.filter(a => attrFilter(a)); + for (const attr of chargeMoveAttrs) { + const result = attr.apply(user, target, move, args); + if (result instanceof Promise) { + chargeAttrPromises.push(result); + } + } + Promise.allSettled(chargeAttrPromises).then(() => resolve()); + }); +} + export function applyMoveAttrs(attrType: Constructor, user: Pokemon | null, target: Pokemon | null, move: Move, ...args: any[]): Promise { return applyMoveAttrsInternal((attr: MoveAttr) => attr instanceof attrType, user, target, move, args); } @@ -6556,6 +7096,10 @@ export function applyFilteredMoveAttrs(attrFilter: MoveAttrFilter, user: Pokemon return applyMoveAttrsInternal(attrFilter, user, target, move, args); } +export function applyMoveChargeAttrs(attrType: Constructor, user: Pokemon | null, target: Pokemon | null, move: ChargingMove, ...args: any[]): Promise { + return applyMoveChargeAttrsInternal((attr: MoveAttr) => attr instanceof attrType, user, target, move, args); +} + export class MoveCondition { protected func: MoveConditionFunc; @@ -6619,7 +7163,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr { return false; } - const [targetMove] = target.getLastXMoves(1); // target's most recent move + const [ targetMove ] = target.getLastXMoves(1); // target's most recent move if (!targetMove) { return false; } @@ -6635,7 +7179,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr { } const type = validTypes[user.randSeedInt(validTypes.length)]; user.summonData.types = [ type ]; - user.scene.queueMessage(i18next.t("battle:transformedIntoType", {pokemonName: getPokemonNameWithAffix(user), type: Utils.toReadableString(Type[type])})); + user.scene.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: Utils.toReadableString(Type[type]) })); user.updateInfo(); return true; @@ -6694,7 +7238,7 @@ export class ExposedMoveAttr extends AddBattlerTagAttr { return false; } - user.scene.queueMessage(i18next.t("moveTriggers:exposedMove", { pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target)})); + user.scene.queueMessage(i18next.t("moveTriggers:exposedMove", { pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target) })); return true; } @@ -6719,47 +7263,47 @@ export function getMoveTargets(user: Pokemon, move: Moves): MoveTargetSet { let multiple = false; switch (moveTarget) { - case MoveTarget.USER: - case MoveTarget.PARTY: - set = [ user ]; - break; - case MoveTarget.NEAR_OTHER: - case MoveTarget.OTHER: - case MoveTarget.ALL_NEAR_OTHERS: - case MoveTarget.ALL_OTHERS: - set = (opponents.concat([ user.getAlly() ])); - multiple = moveTarget === MoveTarget.ALL_NEAR_OTHERS || moveTarget === MoveTarget.ALL_OTHERS; - break; - case MoveTarget.NEAR_ENEMY: - case MoveTarget.ALL_NEAR_ENEMIES: - case MoveTarget.ALL_ENEMIES: - case MoveTarget.ENEMY_SIDE: - set = opponents; - multiple = moveTarget !== MoveTarget.NEAR_ENEMY; - break; - case MoveTarget.RANDOM_NEAR_ENEMY: - set = [ opponents[user.randSeedInt(opponents.length)] ]; - break; - case MoveTarget.ATTACKER: - return { targets: [ -1 as BattlerIndex ], multiple: false }; - case MoveTarget.NEAR_ALLY: - case MoveTarget.ALLY: - set = [ user.getAlly() ]; - break; - case MoveTarget.USER_OR_NEAR_ALLY: - case MoveTarget.USER_AND_ALLIES: - case MoveTarget.USER_SIDE: - set = [ user, user.getAlly() ]; - multiple = moveTarget !== MoveTarget.USER_OR_NEAR_ALLY; - break; - case MoveTarget.ALL: - case MoveTarget.BOTH_SIDES: - set = [ user, user.getAlly() ].concat(opponents); - multiple = true; - break; - case MoveTarget.CURSE: - set = user.getTypes(true).includes(Type.GHOST) ? (opponents.concat([ user.getAlly() ])) : [ user ]; - break; + case MoveTarget.USER: + case MoveTarget.PARTY: + set = [ user ]; + break; + case MoveTarget.NEAR_OTHER: + case MoveTarget.OTHER: + case MoveTarget.ALL_NEAR_OTHERS: + case MoveTarget.ALL_OTHERS: + set = (opponents.concat([ user.getAlly() ])); + multiple = moveTarget === MoveTarget.ALL_NEAR_OTHERS || moveTarget === MoveTarget.ALL_OTHERS; + break; + case MoveTarget.NEAR_ENEMY: + case MoveTarget.ALL_NEAR_ENEMIES: + case MoveTarget.ALL_ENEMIES: + case MoveTarget.ENEMY_SIDE: + set = opponents; + multiple = moveTarget !== MoveTarget.NEAR_ENEMY; + break; + case MoveTarget.RANDOM_NEAR_ENEMY: + set = [ opponents[user.randSeedInt(opponents.length)] ]; + break; + case MoveTarget.ATTACKER: + return { targets: [ -1 as BattlerIndex ], multiple: false }; + case MoveTarget.NEAR_ALLY: + case MoveTarget.ALLY: + set = [ user.getAlly() ]; + break; + case MoveTarget.USER_OR_NEAR_ALLY: + case MoveTarget.USER_AND_ALLIES: + case MoveTarget.USER_SIDE: + set = [ user, user.getAlly() ]; + multiple = moveTarget !== MoveTarget.USER_OR_NEAR_ALLY; + break; + case MoveTarget.ALL: + case MoveTarget.BOTH_SIDES: + set = [ user, user.getAlly() ].concat(opponents); + multiple = true; + break; + case MoveTarget.CURSE: + set = user.getTypes(true).includes(Type.GHOST) ? (opponents.concat([ user.getAlly() ])) : [ user ]; + break; } return { targets: set.filter(p => p?.isActive(true)).map(p => p.getBattlerIndex()).filter(t => t !== undefined), multiple }; @@ -6800,8 +7344,8 @@ export function initMoves() { new AttackMove(Moves.GUILLOTINE, Type.NORMAL, MoveCategory.PHYSICAL, 200, 30, 5, -1, 0, 1) .attr(OneHitKOAttr) .attr(OneHitKOAccuracyAttr), - new AttackMove(Moves.RAZOR_WIND, Type.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 1) - .attr(ChargeAttr, ChargeAnim.RAZOR_WIND_CHARGING, i18next.t("moveTriggers:whippedUpAWhirlwind", {pokemonName: "{USER}"})) + new ChargingAttackMove(Moves.RAZOR_WIND, Type.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 1) + .chargeText(i18next.t("moveTriggers:whippedUpAWhirlwind", { pokemonName: "{USER}" })) .attr(HighCritAttr) .windMove() .ignoresVirtual() @@ -6819,9 +7363,11 @@ export function initMoves() { .attr(ForceSwitchOutAttr) .ignoresSubstitute() .hidesTarget() - .windMove(), - new AttackMove(Moves.FLY, Type.FLYING, MoveCategory.PHYSICAL, 90, 95, 15, -1, 0, 1) - .attr(ChargeAttr, ChargeAnim.FLY_CHARGING, i18next.t("moveTriggers:flewUpHigh", {pokemonName: "{USER}"}), BattlerTagType.FLYING) + .windMove() + .partial(), // Should force random switches + new ChargingAttackMove(Moves.FLY, Type.FLYING, MoveCategory.PHYSICAL, 90, 95, 15, -1, 0, 1) + .chargeText(i18next.t("moveTriggers:flewUpHigh", { pokemonName: "{USER}" })) + .chargeAttr(SemiInvulnerableAttr, BattlerTagType.FLYING) .condition(failOnGravityCondition) .ignoresVirtual(), new AttackMove(Moves.BIND, Type.NORMAL, MoveCategory.PHYSICAL, 15, 85, 20, -1, 0, 1) @@ -6896,7 +7442,8 @@ export function initMoves() { new StatusMove(Moves.ROAR, Type.NORMAL, -1, 20, -1, -6, 1) .attr(ForceSwitchOutAttr) .soundBased() - .hidesTarget(), + .hidesTarget() + .partial(), // Should force random switching new StatusMove(Moves.SING, Type.NORMAL, 55, 15, -1, 0, 1) .attr(StatusEffectAttr, StatusEffect.SLEEP) .soundBased(), @@ -6969,8 +7516,9 @@ export function initMoves() { .makesContact(false) .slicingMove() .target(MoveTarget.ALL_NEAR_ENEMIES), - new AttackMove(Moves.SOLAR_BEAM, Type.GRASS, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 1) - .attr(SunlightChargeAttr, ChargeAnim.SOLAR_BEAM_CHARGING, i18next.t("moveTriggers:tookInSunlight", {pokemonName: "{USER}"})) + new ChargingAttackMove(Moves.SOLAR_BEAM, Type.GRASS, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 1) + .chargeText(i18next.t("moveTriggers:tookInSunlight", { pokemonName: "{USER}" })) + .chargeAttr(WeatherInstantChargeAttr, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]) .attr(AntiSunlightPowerDecreaseAttr) .ignoresVirtual(), new StatusMove(Moves.POISON_POWDER, Type.POISON, 75, 35, -1, 0, 1) @@ -7019,8 +7567,9 @@ export function initMoves() { .attr(OneHitKOAccuracyAttr) .attr(HitsTagAttr, BattlerTagType.UNDERGROUND) .makesContact(false), - new AttackMove(Moves.DIG, Type.GROUND, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 1) - .attr(ChargeAttr, ChargeAnim.DIG_CHARGING, i18next.t("moveTriggers:dugAHole", {pokemonName: "{USER}"}), BattlerTagType.UNDERGROUND) + new ChargingAttackMove(Moves.DIG, Type.GROUND, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 1) + .chargeText(i18next.t("moveTriggers:dugAHole", { pokemonName: "{USER}" })) + .chargeAttr(SemiInvulnerableAttr, BattlerTagType.UNDERGROUND) .ignoresVirtual(), new StatusMove(Moves.TOXIC, Type.POISON, 90, 10, -1, 0, 1) .attr(StatusEffectAttr, StatusEffect.TOXIC) @@ -7037,7 +7586,7 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.SPD ], 2, true), new AttackMove(Moves.QUICK_ATTACK, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 30, -1, 1, 1), new AttackMove(Moves.RAGE, Type.NORMAL, MoveCategory.PHYSICAL, 20, 100, 20, -1, 0, 1) - .partial(), + .partial(), // No effect implemented new SelfStatusMove(Moves.TELEPORT, Type.PSYCHIC, -1, 20, -1, -6, 1) .attr(ForceSwitchOutAttr, true) .hidesUser(), @@ -7116,9 +7665,9 @@ export function initMoves() { .attr(TrapAttr, BattlerTagType.CLAMP), new AttackMove(Moves.SWIFT, Type.NORMAL, MoveCategory.SPECIAL, 60, -1, 20, -1, 0, 1) .target(MoveTarget.ALL_NEAR_ENEMIES), - new AttackMove(Moves.SKULL_BASH, Type.NORMAL, MoveCategory.PHYSICAL, 130, 100, 10, -1, 0, 1) - .attr(ChargeAttr, ChargeAnim.SKULL_BASH_CHARGING, i18next.t("moveTriggers:loweredItsHead", {pokemonName: "{USER}"}), null, true) - .attr(StatStageChangeAttr, [ Stat.DEF ], 1, true) + new ChargingAttackMove(Moves.SKULL_BASH, Type.NORMAL, MoveCategory.PHYSICAL, 130, 100, 10, -1, 0, 1) + .chargeText(i18next.t("moveTriggers:loweredItsHead", { pokemonName: "{USER}" })) + .chargeAttr(StatStageChangeAttr, [ Stat.DEF ], 1, true) .ignoresVirtual(), new AttackMove(Moves.SPIKE_CANNON, Type.NORMAL, MoveCategory.PHYSICAL, 20, 100, 15, -1, 0, 1) .attr(MultiHitAttr) @@ -7155,14 +7704,15 @@ export function initMoves() { .triageMove(), new StatusMove(Moves.LOVELY_KISS, Type.NORMAL, 75, 10, -1, 0, 1) .attr(StatusEffectAttr, StatusEffect.SLEEP), - new AttackMove(Moves.SKY_ATTACK, Type.FLYING, MoveCategory.PHYSICAL, 140, 90, 5, 30, 0, 1) - .attr(ChargeAttr, ChargeAnim.SKY_ATTACK_CHARGING, i18next.t("moveTriggers:isGlowing", {pokemonName: "{USER}"})) + new ChargingAttackMove(Moves.SKY_ATTACK, Type.FLYING, MoveCategory.PHYSICAL, 140, 90, 5, 30, 0, 1) + .chargeText(i18next.t("moveTriggers:isGlowing", { pokemonName: "{USER}" })) .attr(HighCritAttr) .attr(FlinchAttr) .makesContact(false) .ignoresVirtual(), new StatusMove(Moves.TRANSFORM, Type.NORMAL, -1, 10, -1, 0, 1) .attr(TransformAttr) + .condition((user, target, move) => !target.getTag(BattlerTagType.SUBSTITUTE)) .ignoresProtect(), new AttackMove(Moves.BUBBLE, Type.WATER, MoveCategory.SPECIAL, 40, 100, 30, 10, 0, 1) .attr(StatStageChangeAttr, [ Stat.SPD ], -1) @@ -7210,7 +7760,7 @@ export function initMoves() { new SelfStatusMove(Moves.CONVERSION, Type.NORMAL, -1, 30, -1, 0, 1) .attr(FirstMoveTypeAttr), new AttackMove(Moves.TRI_ATTACK, Type.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, 20, 0, 1) - .attr(MultiStatusEffectAttr, [StatusEffect.BURN, StatusEffect.FREEZE, StatusEffect.PARALYSIS]), + .attr(MultiStatusEffectAttr, [ StatusEffect.BURN, StatusEffect.FREEZE, StatusEffect.PARALYSIS ]), new AttackMove(Moves.SUPER_FANG, Type.NORMAL, MoveCategory.PHYSICAL, -1, 90, 10, -1, 0, 1) .attr(TargetHalfHpDamageAttr), new AttackMove(Moves.SLASH, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 1) @@ -7352,7 +7902,7 @@ export function initMoves() { new StatusMove(Moves.CHARM, Type.FAIRY, 100, 20, -1, 0, 2) .attr(StatStageChangeAttr, [ Stat.ATK ], -2), new AttackMove(Moves.ROLLOUT, Type.ROCK, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 2) - .partial() + .partial() // Does not lock the user, also does not increase damage properly .attr(ConsecutiveUseDoublePowerAttr, 5, true, true, Moves.DEFENSE_CURL), new AttackMove(Moves.FALSE_SWIPE, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 40, -1, 0, 2) .attr(SurviveDamageAttr), @@ -7423,7 +7973,7 @@ export function initMoves() { .ignoresSubstitute() .condition((user, target, move) => new EncoreTag(user.id).canAdd(target)), new AttackMove(Moves.PURSUIT, Type.DARK, MoveCategory.PHYSICAL, 40, 100, 20, -1, 0, 2) - .partial(), + .partial(), // No effect implemented new AttackMove(Moves.RAPID_SPIN, Type.NORMAL, MoveCategory.PHYSICAL, 50, 100, 40, 100, 0, 2) .attr(StatStageChangeAttr, [ Stat.SPD ], 1, true) .attr(RemoveBattlerTagAttr, [ @@ -7488,8 +8038,8 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.SPDEF ], -1) .ballBombMove(), new AttackMove(Moves.FUTURE_SIGHT, Type.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 2) - .partial() - .attr(DelayedAttackAttr, ArenaTagType.FUTURE_SIGHT, ChargeAnim.FUTURE_SIGHT_CHARGING, i18next.t("moveTriggers:foresawAnAttack", {pokemonName: "{USER}"})), + .partial() // Complete buggy mess + .attr(DelayedAttackAttr, ArenaTagType.FUTURE_SIGHT, ChargeAnim.FUTURE_SIGHT_CHARGING, i18next.t("moveTriggers:foresawAnAttack", { pokemonName: "{USER}" })), new AttackMove(Moves.ROCK_SMASH, Type.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 15, 50, 0, 2) .attr(StatStageChangeAttr, [ Stat.DEF ], -1), new AttackMove(Moves.WHIRLPOOL, Type.WATER, MoveCategory.SPECIAL, 35, 85, 15, -1, 0, 2) @@ -7506,18 +8056,18 @@ export function initMoves() { .ignoresVirtual() .soundBased() .target(MoveTarget.RANDOM_NEAR_ENEMY) - .partial(), + .partial(), // Does not lock the user, does not stop Pokemon from sleeping new SelfStatusMove(Moves.STOCKPILE, Type.NORMAL, -1, 20, -1, 0, 3) .condition(user => (user.getTag(StockpilingTag)?.stockpiledCount ?? 0) < 3) .attr(AddBattlerTagAttr, BattlerTagType.STOCKPILING, true), new AttackMove(Moves.SPIT_UP, Type.NORMAL, MoveCategory.SPECIAL, -1, -1, 10, -1, 0, 3) .condition(hasStockpileStacksCondition) .attr(SpitUpPowerAttr, 100) - .attr(RemoveBattlerTagAttr, [BattlerTagType.STOCKPILING], true), + .attr(RemoveBattlerTagAttr, [ BattlerTagType.STOCKPILING ], true), new SelfStatusMove(Moves.SWALLOW, Type.NORMAL, -1, 10, -1, 0, 3) .condition(hasStockpileStacksCondition) .attr(SwallowHealAttr) - .attr(RemoveBattlerTagAttr, [BattlerTagType.STOCKPILING], true) + .attr(RemoveBattlerTagAttr, [ BattlerTagType.STOCKPILING ], true) .triageMove(), new AttackMove(Moves.HEAT_WAVE, Type.FIRE, MoveCategory.SPECIAL, 95, 90, 10, 10, 0, 3) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) @@ -7529,7 +8079,7 @@ export function initMoves() { .target(MoveTarget.BOTH_SIDES), new StatusMove(Moves.TORMENT, Type.DARK, 100, 15, -1, 0, 3) .ignoresSubstitute() - .partial() // Incomplete implementation because of Uproar's partial implementation + .edgeCase() // Incomplete implementation because of Uproar's partial implementation .attr(AddBattlerTagAttr, BattlerTagType.TORMENT, false, true, 1), new StatusMove(Moves.FLATTER, Type.DARK, 100, 15, -1, 0, 3) .attr(StatStageChangeAttr, [ Stat.SPATK ], 1) @@ -7544,7 +8094,7 @@ export function initMoves() { && (user.status.effect === StatusEffect.BURN || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.PARALYSIS) ? 2 : 1) .attr(BypassBurnDamageReductionAttr), new AttackMove(Moves.FOCUS_PUNCH, Type.FIGHTING, MoveCategory.PHYSICAL, 150, 100, 20, -1, -3, 3) - .attr(MessageHeaderAttr, (user, move) => i18next.t("moveTriggers:isTighteningFocus", {pokemonName: getPokemonNameWithAffix(user)})) + .attr(MessageHeaderAttr, (user, move) => i18next.t("moveTriggers:isTighteningFocus", { pokemonName: getPokemonNameWithAffix(user) })) .punchingMove() .ignoresVirtual() .condition((user, target, move) => !user.turnData.attacksReceived.find(r => r.damage)), @@ -7578,7 +8128,9 @@ export function initMoves() { .attr(RandomMovesetMoveAttr, true) .ignoresVirtual(), new SelfStatusMove(Moves.INGRAIN, Type.GRASS, -1, 20, -1, 0, 3) - .attr(AddBattlerTagAttr, BattlerTagType.INGRAIN, true, true), + .attr(AddBattlerTagAttr, BattlerTagType.INGRAIN, true, true) + .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, true, true) + .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLOATING ], true), new AttackMove(Moves.SUPERPOWER, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 3) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF ], -1, true), new SelfStatusMove(Moves.MAGIC_COAT, Type.PSYCHIC, -1, 15, -1, 4, 3) @@ -7591,7 +8143,7 @@ export function initMoves() { .attr(RemoveScreensAttr), new StatusMove(Moves.YAWN, Type.NORMAL, -1, 10, -1, 0, 3) .attr(AddBattlerTagAttr, BattlerTagType.DROWSY, false, true) - .condition((user, target, move) => !target.status && !target.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY)), + .condition((user, target, move) => !target.status && !target.isSafeguarded(user)), new AttackMove(Moves.KNOCK_OFF, Type.DARK, MoveCategory.PHYSICAL, 65, 100, 20, -1, 0, 3) .attr(MovePowerMultiplierAttr, (user, target, move) => target.getHeldItems().filter(i => i.isTransferable).length > 0 ? 1.5 : 1) .attr(RemoveHeldItemAttr, false), @@ -7606,7 +8158,8 @@ export function initMoves() { .attr(SwitchAbilitiesAttr), new StatusMove(Moves.IMPRISON, Type.PSYCHIC, 100, 10, -1, 0, 3) .ignoresSubstitute() - .attr(AddArenaTagAttr, ArenaTagType.IMPRISON, 1, true, false), + .attr(AddArenaTagAttr, ArenaTagType.IMPRISON, 1, true, false) + .target(MoveTarget.ENEMY_SIDE), new SelfStatusMove(Moves.REFRESH, Type.NORMAL, -1, 20, -1, 0, 3) .attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN) .condition((user, target, move) => !!user.status && (user.status.effect === StatusEffect.PARALYSIS || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.BURN)), @@ -7616,10 +8169,11 @@ export function initMoves() { .unimplemented(), new AttackMove(Moves.SECRET_POWER, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, 30, 0, 3) .makesContact(false) - .partial(), - new AttackMove(Moves.DIVE, Type.WATER, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 3) - .attr(ChargeAttr, ChargeAnim.DIVE_CHARGING, i18next.t("moveTriggers:hidUnderwater", {pokemonName: "{USER}"}), BattlerTagType.UNDERWATER, true) - .attr(GulpMissileTagAttr) + .attr(SecretPowerAttr), + new ChargingAttackMove(Moves.DIVE, Type.WATER, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 3) + .chargeText(i18next.t("moveTriggers:hidUnderwater", { pokemonName: "{USER}" })) + .chargeAttr(SemiInvulnerableAttr, BattlerTagType.UNDERWATER) + .chargeAttr(GulpMissileTagAttr) .ignoresVirtual(), new AttackMove(Moves.ARM_THRUST, Type.FIGHTING, MoveCategory.PHYSICAL, 15, 100, 20, -1, 0, 3) .attr(MultiHitAttr), @@ -7647,7 +8201,7 @@ export function initMoves() { .attr(AddArenaTagAttr, ArenaTagType.MUD_SPORT, 5) .target(MoveTarget.BOTH_SIDES), new AttackMove(Moves.ICE_BALL, Type.ICE, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 3) - .partial() + .partial() // Does not lock the user properly, does not increase damage correctly .attr(ConsecutiveUseDoublePowerAttr, 5, true, true, Moves.DEFENSE_CURL) .ballBombMove(), new AttackMove(Moves.NEEDLE_ARM, Type.GRASS, MoveCategory.PHYSICAL, 60, 100, 15, 30, 0, 3) @@ -7674,7 +8228,7 @@ export function initMoves() { .attr(FlinchAttr), new AttackMove(Moves.WEATHER_BALL, Type.NORMAL, MoveCategory.SPECIAL, 50, 100, 10, -1, 0, 3) .attr(WeatherBallTypeAttr) - .attr(MovePowerMultiplierAttr, (user, target, move) => [WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN].includes(user.scene.arena.weather?.weatherType!) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 2 : 1) // TODO: is this bang correct? + .attr(MovePowerMultiplierAttr, (user, target, move) => [ WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN ].includes(user.scene.arena.weather?.weatherType!) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 2 : 1) // TODO: is this bang correct? .ballBombMove(), new StatusMove(Moves.AROMATHERAPY, Type.GRASS, -1, 5, -1, 0, 3) .attr(PartyStatusCureAttr, i18next.t("moveTriggers:soothingAromaWaftedThroughArea"), Abilities.SAP_SIPPER) @@ -7752,8 +8306,9 @@ export function initMoves() { .attr(RechargeAttr), new SelfStatusMove(Moves.BULK_UP, Type.FIGHTING, -1, 20, -1, 0, 3) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF ], 1, true), - new AttackMove(Moves.BOUNCE, Type.FLYING, MoveCategory.PHYSICAL, 85, 85, 5, 30, 0, 3) - .attr(ChargeAttr, ChargeAnim.BOUNCE_CHARGING, i18next.t("moveTriggers:sprangUp", {pokemonName: "{USER}"}), BattlerTagType.FLYING) + new ChargingAttackMove(Moves.BOUNCE, Type.FLYING, MoveCategory.PHYSICAL, 85, 85, 5, 30, 0, 3) + .chargeText(i18next.t("moveTriggers:sprangUp", { pokemonName: "{USER}" })) + .chargeAttr(SemiInvulnerableAttr, BattlerTagType.FLYING) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) .condition(failOnGravityCondition) .ignoresVirtual(), @@ -7790,8 +8345,8 @@ export function initMoves() { .attr(ConfuseAttr) .pulseMove(), new AttackMove(Moves.DOOM_DESIRE, Type.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3) - .partial() - .attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, i18next.t("moveTriggers:choseDoomDesireAsDestiny", {pokemonName: "{USER}"})), + .partial() // Complete buggy mess + .attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, i18next.t("moveTriggers:choseDoomDesireAsDestiny", { pokemonName: "{USER}" })), new AttackMove(Moves.PSYCHO_BOOST, Type.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 3) .attr(StatStageChangeAttr, [ Stat.SPATK ], -2, true), new SelfStatusMove(Moves.ROOST, Type.FLYING, -1, 5, -1, 0, 4) @@ -7874,7 +8429,7 @@ export function initMoves() { .attr(OpponentHighHpPowerAttr, 120) .makesContact(), new SelfStatusMove(Moves.POWER_TRICK, Type.PSYCHIC, -1, 10, -1, 0, 4) - .unimplemented(), + .attr(AddBattlerTagAttr, BattlerTagType.POWER_TRICK, true), new StatusMove(Moves.GASTRO_ACID, Type.POISON, 100, 10, -1, 0, 4) .attr(SuppressAbilitiesAttr), new StatusMove(Moves.LUCKY_CHANT, Type.NORMAL, -1, 30, -1, 0, 4) @@ -7912,8 +8467,8 @@ export function initMoves() { new SelfStatusMove(Moves.AQUA_RING, Type.WATER, -1, 20, -1, 0, 4) .attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true), new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4) - .attr(AddBattlerTagAttr, BattlerTagType.MAGNET_RISEN, true, true) - .condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) && [BattlerTagType.MAGNET_RISEN, BattlerTagType.IGNORE_FLYING, BattlerTagType.INGRAIN].every((tag) => !user.getTag(tag))), + .attr(AddBattlerTagAttr, BattlerTagType.FLOATING, true, true) + .condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) && [ BattlerTagType.FLOATING, BattlerTagType.IGNORE_FLYING, BattlerTagType.INGRAIN ].every((tag) => !user.getTag(tag))), new AttackMove(Moves.FLARE_BLITZ, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 4) .attr(RecoilAttr, false, 0.33) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) @@ -8108,8 +8663,9 @@ export function initMoves() { new AttackMove(Moves.OMINOUS_WIND, Type.GHOST, MoveCategory.SPECIAL, 60, 100, 5, 10, 0, 4) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true) .windMove(), - new AttackMove(Moves.SHADOW_FORCE, Type.GHOST, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 4) - .attr(ChargeAttr, ChargeAnim.SHADOW_FORCE_CHARGING, i18next.t("moveTriggers:vanishedInstantly", {pokemonName: "{USER}"}), BattlerTagType.HIDDEN) + new ChargingAttackMove(Moves.SHADOW_FORCE, Type.GHOST, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 4) + .chargeText(i18next.t("moveTriggers:vanishedInstantly", { pokemonName: "{USER}" })) + .chargeAttr(SemiInvulnerableAttr, BattlerTagType.HIDDEN) .ignoresProtect() .ignoresVirtual(), new SelfStatusMove(Moves.HONE_CLAWS, Type.DARK, -1, 15, -1, 0, 5) @@ -8138,7 +8694,11 @@ export function initMoves() { .attr(AddBattlerTagAttr, BattlerTagType.CENTER_OF_ATTENTION, true), new StatusMove(Moves.TELEKINESIS, Type.PSYCHIC, -1, 15, -1, 0, 5) .condition(failOnGravityCondition) - .unimplemented(), + .condition((_user, target, _move) => ![ Species.DIGLETT, Species.DUGTRIO, Species.ALOLA_DIGLETT, Species.ALOLA_DUGTRIO, Species.SANDYGAST, Species.PALOSSAND, Species.WIGLETT, Species.WUGTRIO ].includes(target.species.speciesId)) + .condition((_user, target, _move) => !(target.species.speciesId === Species.GENGAR && target.getFormKey() === "mega")) + .condition((_user, target, _move) => Utils.isNullOrUndefined(target.getTag(BattlerTagType.INGRAIN)) && Utils.isNullOrUndefined(target.getTag(BattlerTagType.IGNORE_FLYING))) + .attr(AddBattlerTagAttr, BattlerTagType.TELEKINESIS, false, true, 3) + .attr(AddBattlerTagAttr, BattlerTagType.FLOATING, false, true, 3), new StatusMove(Moves.MAGIC_ROOM, Type.PSYCHIC, -1, 10, -1, 0, 5) .ignoresProtect() .target(MoveTarget.BOTH_SIDES) @@ -8146,7 +8706,7 @@ export function initMoves() { new AttackMove(Moves.SMACK_DOWN, Type.ROCK, MoveCategory.PHYSICAL, 50, 100, 15, 100, 0, 5) .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true) .attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED) - .attr(RemoveBattlerTagAttr, [BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN]) + .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ]) .attr(HitsTagAttr, BattlerTagType.FLYING) .makesContact(false), new AttackMove(Moves.STORM_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5) @@ -8196,7 +8756,7 @@ export function initMoves() { .attr(AfterYouAttr), new AttackMove(Moves.ROUND, Type.NORMAL, MoveCategory.SPECIAL, 60, 100, 15, -1, 0, 5) .soundBased() - .partial(), + .partial(), // No effect implemented new AttackMove(Moves.ECHOED_VOICE, Type.NORMAL, MoveCategory.SPECIAL, 40, 100, 15, -1, 0, 5) .attr(ConsecutiveUseMultiBasePowerAttr, 5, false) .soundBased(), @@ -8227,18 +8787,20 @@ export function initMoves() { new AttackMove(Moves.HEX, Type.GHOST, MoveCategory.SPECIAL, 65, 100, 10, -1, 0, 5) .attr( MovePowerMultiplierAttr, - (user, target, move) => target.status || target.hasAbility(Abilities.COMATOSE)? 2 : 1), - new AttackMove(Moves.SKY_DROP, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5) - .partial() // Should immobilize the target, Flying types should take no damage. cf https://bulbapedia.bulbagarden.net/wiki/Sky_Drop_(move) and https://www.smogon.com/dex/sv/moves/sky-drop/ - .attr(ChargeAttr, ChargeAnim.SKY_DROP_CHARGING, i18next.t("moveTriggers:tookTargetIntoSky", {pokemonName: "{USER}", targetName: "{TARGET}"}), BattlerTagType.FLYING) // TODO: Add 2nd turn message + (user, target, move) => target.status || target.hasAbility(Abilities.COMATOSE) ? 2 : 1), + new ChargingAttackMove(Moves.SKY_DROP, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5) + .chargeText(i18next.t("moveTriggers:tookTargetIntoSky", { pokemonName: "{USER}", targetName: "{TARGET}" })) + .chargeAttr(SemiInvulnerableAttr, BattlerTagType.FLYING) .condition(failOnGravityCondition) .condition((user, target, move) => !target.getTag(BattlerTagType.SUBSTITUTE)) - .ignoresVirtual(), + .ignoresVirtual() + .partial(), // Should immobilize the target, Flying types should take no damage. cf https://bulbapedia.bulbagarden.net/wiki/Sky_Drop_(move) and https://www.smogon.com/dex/sv/moves/sky-drop/ new SelfStatusMove(Moves.SHIFT_GEAR, Type.STEEL, -1, 10, -1, 0, 5) .attr(StatStageChangeAttr, [ Stat.ATK ], 1, true) .attr(StatStageChangeAttr, [ Stat.SPD ], 2, true), new AttackMove(Moves.CIRCLE_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 90, 10, -1, -6, 5) - .attr(ForceSwitchOutAttr), + .attr(ForceSwitchOutAttr) + .partial(), // Should force random switches new AttackMove(Moves.INCINERATE, Type.FIRE, MoveCategory.SPECIAL, 60, 100, 15, -1, 0, 5) .target(MoveTarget.ALL_NEAR_ENEMIES) .attr(RemoveHeldItemAttr, true), @@ -8269,11 +8831,29 @@ export function initMoves() { new AttackMove(Moves.INFERNO, Type.FIRE, MoveCategory.SPECIAL, 100, 50, 5, 100, 0, 5) .attr(StatusEffectAttr, StatusEffect.BURN), new AttackMove(Moves.WATER_PLEDGE, Type.WATER, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 5) - .partial(), + .attr(AwaitCombinedPledgeAttr) + .attr(CombinedPledgeTypeAttr) + .attr(CombinedPledgePowerAttr) + .attr(CombinedPledgeStabBoostAttr) + .attr(AddPledgeEffectAttr, ArenaTagType.WATER_FIRE_PLEDGE, Moves.FIRE_PLEDGE, true) + .attr(AddPledgeEffectAttr, ArenaTagType.GRASS_WATER_PLEDGE, Moves.GRASS_PLEDGE) + .attr(BypassRedirectAttr, true), new AttackMove(Moves.FIRE_PLEDGE, Type.FIRE, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 5) - .partial(), + .attr(AwaitCombinedPledgeAttr) + .attr(CombinedPledgeTypeAttr) + .attr(CombinedPledgePowerAttr) + .attr(CombinedPledgeStabBoostAttr) + .attr(AddPledgeEffectAttr, ArenaTagType.FIRE_GRASS_PLEDGE, Moves.GRASS_PLEDGE) + .attr(AddPledgeEffectAttr, ArenaTagType.WATER_FIRE_PLEDGE, Moves.WATER_PLEDGE, true) + .attr(BypassRedirectAttr, true), new AttackMove(Moves.GRASS_PLEDGE, Type.GRASS, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 5) - .partial(), + .attr(AwaitCombinedPledgeAttr) + .attr(CombinedPledgeTypeAttr) + .attr(CombinedPledgePowerAttr) + .attr(CombinedPledgeStabBoostAttr) + .attr(AddPledgeEffectAttr, ArenaTagType.GRASS_WATER_PLEDGE, Moves.WATER_PLEDGE) + .attr(AddPledgeEffectAttr, ArenaTagType.FIRE_GRASS_PLEDGE, Moves.FIRE_PLEDGE) + .attr(BypassRedirectAttr, true), new AttackMove(Moves.VOLT_SWITCH, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 20, -1, 0, 5) .attr(ForceSwitchOutAttr, true), new AttackMove(Moves.STRUGGLE_BUG, Type.BUG, MoveCategory.SPECIAL, 50, 100, 20, 100, 0, 5) @@ -8288,7 +8868,8 @@ export function initMoves() { .attr(CritOnlyAttr), new AttackMove(Moves.DRAGON_TAIL, Type.DRAGON, MoveCategory.PHYSICAL, 60, 90, 10, -1, -6, 5) .attr(ForceSwitchOutAttr) - .hidesTarget(), + .hidesTarget() + .partial(), // Should force random switches new SelfStatusMove(Moves.WORK_UP, Type.NORMAL, -1, 30, -1, 0, 5) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], 1, true), new AttackMove(Moves.ELECTROWEB, Type.ELECTRIC, MoveCategory.SPECIAL, 55, 95, 15, 100, 0, 5) @@ -8363,12 +8944,12 @@ export function initMoves() { new AttackMove(Moves.FIERY_DANCE, Type.FIRE, MoveCategory.SPECIAL, 80, 100, 10, 50, 0, 5) .attr(StatStageChangeAttr, [ Stat.SPATK ], 1, true) .danceMove(), - new AttackMove(Moves.FREEZE_SHOCK, Type.ICE, MoveCategory.PHYSICAL, 140, 90, 5, 30, 0, 5) - .attr(ChargeAttr, ChargeAnim.FREEZE_SHOCK_CHARGING, i18next.t("moveTriggers:becameCloakedInFreezingLight", {pokemonName: "{USER}"})) + new ChargingAttackMove(Moves.FREEZE_SHOCK, Type.ICE, MoveCategory.PHYSICAL, 140, 90, 5, 30, 0, 5) + .chargeText(i18next.t("moveTriggers:becameCloakedInFreezingLight", { pokemonName: "{USER}" })) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) .makesContact(false), - new AttackMove(Moves.ICE_BURN, Type.ICE, MoveCategory.SPECIAL, 140, 90, 5, 30, 0, 5) - .attr(ChargeAttr, ChargeAnim.ICE_BURN_CHARGING, i18next.t("moveTriggers:becameCloakedInFreezingAir", {pokemonName: "{USER}"})) + new ChargingAttackMove(Moves.ICE_BURN, Type.ICE, MoveCategory.SPECIAL, 140, 90, 5, 30, 0, 5) + .chargeText(i18next.t("moveTriggers:becameCloakedInFreezingAir", { pokemonName: "{USER}" })) .attr(StatusEffectAttr, StatusEffect.BURN) .ignoresVirtual(), new AttackMove(Moves.SNARL, Type.DARK, MoveCategory.SPECIAL, 55, 95, 15, 100, 0, 5) @@ -8402,7 +8983,7 @@ export function initMoves() { .target(MoveTarget.ALL) .condition((user, target, move) => { // If any fielded pokémon is grass-type and grounded. - return [...user.scene.getEnemyParty(), ...user.scene.getParty()].some((poke) => poke.isOfType(Type.GRASS) && poke.isGrounded()); + return [ ...user.scene.getEnemyParty(), ...user.scene.getParty() ].some((poke) => poke.isOfType(Type.GRASS) && poke.isGrounded()); }) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], 1, false, (user, target, move) => target.isOfType(Type.GRASS) && target.isGrounded()), new StatusMove(Moves.STICKY_WEB, Type.BUG, -1, 20, -1, 0, 6) @@ -8410,26 +8991,25 @@ export function initMoves() { .target(MoveTarget.ENEMY_SIDE), new AttackMove(Moves.FELL_STINGER, Type.BUG, MoveCategory.PHYSICAL, 50, 100, 25, -1, 0, 6) .attr(PostVictoryStatStageChangeAttr, [ Stat.ATK ], 3, true ), - new AttackMove(Moves.PHANTOM_FORCE, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) - .attr(ChargeAttr, ChargeAnim.PHANTOM_FORCE_CHARGING, i18next.t("moveTriggers:vanishedInstantly", {pokemonName: "{USER}"}), BattlerTagType.HIDDEN) + new ChargingAttackMove(Moves.PHANTOM_FORCE, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) + .chargeText(i18next.t("moveTriggers:vanishedInstantly", { pokemonName: "{USER}" })) + .chargeAttr(SemiInvulnerableAttr, BattlerTagType.HIDDEN) .ignoresProtect() .ignoresVirtual(), new StatusMove(Moves.TRICK_OR_TREAT, Type.GHOST, 100, 20, -1, 0, 6) - .attr(AddTypeAttr, Type.GHOST) - .partial(), + .attr(AddTypeAttr, Type.GHOST), new StatusMove(Moves.NOBLE_ROAR, Type.NORMAL, 100, 30, -1, 0, 6) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1) .soundBased(), new StatusMove(Moves.ION_DELUGE, Type.ELECTRIC, -1, 25, -1, 1, 6) - .target(MoveTarget.BOTH_SIDES) - .unimplemented(), + .attr(AddArenaTagAttr, ArenaTagType.ION_DELUGE) + .target(MoveTarget.BOTH_SIDES), new AttackMove(Moves.PARABOLIC_CHARGE, Type.ELECTRIC, MoveCategory.SPECIAL, 65, 100, 20, -1, 0, 6) .attr(HitHealAttr) .target(MoveTarget.ALL_NEAR_OTHERS) .triageMove(), new StatusMove(Moves.FORESTS_CURSE, Type.GRASS, 100, 20, -1, 0, 6) - .attr(AddTypeAttr, Type.GRASS) - .partial(), + .attr(AddTypeAttr, Type.GRASS), new AttackMove(Moves.PETAL_BLIZZARD, Type.GRASS, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 6) .windMove() .makesContact(false) @@ -8437,7 +9017,7 @@ export function initMoves() { new AttackMove(Moves.FREEZE_DRY, Type.ICE, MoveCategory.SPECIAL, 70, 100, 20, 10, 0, 6) .attr(StatusEffectAttr, StatusEffect.FREEZE) .attr(WaterSuperEffectTypeMultiplierAttr) - .partial(), // This currently just multiplies the move's power instead of changing its effectiveness. It also doesn't account for abilities that modify type effectiveness such as tera shell. + .edgeCase(), // This currently just multiplies the move's power instead of changing its effectiveness. It also doesn't account for abilities that modify type effectiveness such as tera shell. new AttackMove(Moves.DISARMING_VOICE, Type.FAIRY, MoveCategory.SPECIAL, 40, -1, 15, -1, 0, 6) .soundBased() .target(MoveTarget.ALL_NEAR_ENEMIES), @@ -8465,7 +9045,7 @@ export function initMoves() { .attr(TerrainChangeAttr, TerrainType.MISTY) .target(MoveTarget.BOTH_SIDES), new StatusMove(Moves.ELECTRIFY, Type.ELECTRIC, -1, 20, -1, 0, 6) - .unimplemented(), + .attr(AddBattlerTagAttr, BattlerTagType.ELECTRIFIED, false, true), new AttackMove(Moves.PLAY_ROUGH, Type.FAIRY, MoveCategory.PHYSICAL, 90, 90, 10, 10, 0, 6) .attr(StatStageChangeAttr, [ Stat.ATK ], -1), new AttackMove(Moves.FAIRY_WIND, Type.FAIRY, MoveCategory.SPECIAL, 40, 100, 30, -1, 0, 6) @@ -8489,7 +9069,7 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.SPATK ], -1) .soundBased(), new AttackMove(Moves.DIAMOND_STORM, Type.ROCK, MoveCategory.PHYSICAL, 100, 95, 5, 50, 0, 6) - .attr(StatStageChangeAttr, [ Stat.DEF ], 2, true) + .attr(StatStageChangeAttr, [ Stat.DEF ], 2, true, undefined, undefined, undefined, undefined, true) .makesContact(false) .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.STEAM_ERUPTION, Type.WATER, MoveCategory.SPECIAL, 110, 95, 5, 30, 0, 6) @@ -8521,15 +9101,15 @@ export function initMoves() { .ignoresSubstitute() .powderMove() .unimplemented(), - new SelfStatusMove(Moves.GEOMANCY, Type.FAIRY, -1, 10, -1, 0, 6) - .attr(ChargeAttr, ChargeAnim.GEOMANCY_CHARGING, i18next.t("moveTriggers:isChargingPower", {pokemonName: "{USER}"})) + new ChargingSelfStatusMove(Moves.GEOMANCY, Type.FAIRY, -1, 10, -1, 0, 6) + .chargeText(i18next.t("moveTriggers:isChargingPower", { pokemonName: "{USER}" })) .attr(StatStageChangeAttr, [ Stat.SPATK, Stat.SPDEF, Stat.SPD ], 2, true) .ignoresVirtual(), new StatusMove(Moves.MAGNETIC_FLUX, Type.ELECTRIC, -1, 20, -1, 0, 6) - .attr(StatStageChangeAttr, [ Stat.DEF, Stat.SPDEF ], 1, false, (user, target, move) => !![ Abilities.PLUS, Abilities.MINUS].find(a => target.hasAbility(a, false))) + .attr(StatStageChangeAttr, [ Stat.DEF, Stat.SPDEF ], 1, false, (user, target, move) => !![ Abilities.PLUS, Abilities.MINUS ].find(a => target.hasAbility(a, false))) .ignoresSubstitute() .target(MoveTarget.USER_AND_ALLIES) - .condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS].find(a => p.hasAbility(a, false)))), + .condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p.hasAbility(a, false)))), new StatusMove(Moves.HAPPY_HOUR, Type.NORMAL, -1, 30, -1, 0, 6) // No animation .attr(AddArenaTagAttr, ArenaTagType.HAPPY_HOUR, null, true) .target(MoveTarget.USER_SIDE), @@ -8561,9 +9141,9 @@ export function initMoves() { .attr(NeutralDamageAgainstFlyingTypeMultiplierAttr) .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true) .attr(HitsTagAttr, BattlerTagType.FLYING) - .attr(HitsTagAttr, BattlerTagType.MAGNET_RISEN) + .attr(HitsTagAttr, BattlerTagType.FLOATING) .attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED) - .attr(RemoveBattlerTagAttr, [BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN]) + .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ]) .makesContact(false) .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.THOUSAND_WAVES, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) @@ -8723,7 +9303,7 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.SPD ], -1, true) .punchingMove(), new StatusMove(Moves.FLORAL_HEALING, Type.FAIRY, -1, 10, -1, 0, 7) - .attr(BoostHealAttr, 0.5, 2/3, true, false, (user, target, move) => user.scene.arena.terrain?.terrainType === TerrainType.GRASSY) + .attr(BoostHealAttr, 0.5, 2 / 3, true, false, (user, target, move) => user.scene.arena.terrain?.terrainType === TerrainType.GRASSY) .triageMove(), new AttackMove(Moves.HIGH_HORSEPOWER, Type.GROUND, MoveCategory.PHYSICAL, 95, 95, 10, -1, 0, 7), new StatusMove(Moves.STRENGTH_SAP, Type.GRASS, 100, 10, -1, 0, 7) @@ -8731,8 +9311,9 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.ATK ], -1) .condition((user, target, move) => target.getStatStage(Stat.ATK) > -6) .triageMove(), - new AttackMove(Moves.SOLAR_BLADE, Type.GRASS, MoveCategory.PHYSICAL, 125, 100, 10, -1, 0, 7) - .attr(SunlightChargeAttr, ChargeAnim.SOLAR_BLADE_CHARGING, i18next.t("moveTriggers:isGlowing", {pokemonName: "{USER}"})) + new ChargingAttackMove(Moves.SOLAR_BLADE, Type.GRASS, MoveCategory.PHYSICAL, 125, 100, 10, -1, 0, 7) + .chargeText(i18next.t("moveTriggers:isGlowing", { pokemonName: "{USER}" })) + .chargeAttr(WeatherInstantChargeAttr, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]) .attr(AntiSunlightPowerDecreaseAttr) .slicingMove(), new AttackMove(Moves.LEAFAGE, Type.GRASS, MoveCategory.PHYSICAL, 40, 100, 40, -1, 0, 7) @@ -8745,10 +9326,10 @@ export function initMoves() { new SelfStatusMove(Moves.LASER_FOCUS, Type.NORMAL, -1, 30, -1, 0, 7) .attr(AddBattlerTagAttr, BattlerTagType.ALWAYS_CRIT, true, false), new StatusMove(Moves.GEAR_UP, Type.STEEL, -1, 20, -1, 0, 7) - .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], 1, false, (user, target, move) => !![ Abilities.PLUS, Abilities.MINUS].find(a => target.hasAbility(a, false))) + .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], 1, false, (user, target, move) => !![ Abilities.PLUS, Abilities.MINUS ].find(a => target.hasAbility(a, false))) .ignoresSubstitute() .target(MoveTarget.USER_AND_ALLIES) - .condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS].find(a => p.hasAbility(a, false)))), + .condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p.hasAbility(a, false)))), new AttackMove(Moves.THROAT_CHOP, Type.DARK, MoveCategory.PHYSICAL, 80, 100, 15, 100, 0, 7) .attr(AddBattlerTagAttr, BattlerTagType.THROAT_CHOPPED), new AttackMove(Moves.POLLEN_PUFF, Type.BUG, MoveCategory.SPECIAL, 90, 100, 15, -1, 0, 7) @@ -8774,7 +9355,7 @@ export function initMoves() { .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) .attr(AddBattlerTagAttr, BattlerTagType.BURNED_UP, true, false) .attr(RemoveTypeAttr, Type.FIRE, (user) => { - user.scene.queueMessage(i18next.t("moveTriggers:burnedItselfOut", {pokemonName: getPokemonNameWithAffix(user)})); + user.scene.queueMessage(i18next.t("moveTriggers:burnedItselfOut", { pokemonName: getPokemonNameWithAffix(user) })); }), new StatusMove(Moves.SPEED_SWAP, Type.PSYCHIC, -1, 10, -1, 0, 7) .attr(SwapStatAttr, Stat.SPD) @@ -8815,15 +9396,15 @@ export function initMoves() { /* Unused */ new AttackMove(Moves.SINISTER_ARROW_RAID, Type.GHOST, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7) .makesContact(false) - .partial() + .edgeCase() // I assume it's because the user needs spirit shackle and decidueye .ignoresVirtual(), new AttackMove(Moves.MALICIOUS_MOONSAULT, Type.DARK, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7) .attr(AlwaysHitMinimizeAttr) .attr(HitsTagAttr, BattlerTagType.MINIMIZED, true) - .partial() + .edgeCase() // I assume it's because it needs darkest lariat and incineroar .ignoresVirtual(), new AttackMove(Moves.OCEANIC_OPERETTA, Type.WATER, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7) - .partial() + .edgeCase() // I assume it's because it needs sparkling aria and primarina .ignoresVirtual(), new AttackMove(Moves.GUARDIAN_OF_ALOLA, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) .unimplemented() @@ -8832,10 +9413,10 @@ export function initMoves() { .unimplemented() .ignoresVirtual(), new AttackMove(Moves.STOKED_SPARKSURFER, Type.ELECTRIC, MoveCategory.SPECIAL, 175, -1, 1, 100, 0, 7) - .partial() + .edgeCase() // I assume it's because it needs thunderbolt and Alola Raichu .ignoresVirtual(), new AttackMove(Moves.PULVERIZING_PANCAKE, Type.NORMAL, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7) - .partial() + .edgeCase() // I assume it's because it needs giga impact and snorlax .ignoresVirtual(), new SelfStatusMove(Moves.EXTREME_EVOBOOST, Type.NORMAL, -1, 1, -1, 0, 7) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 2, true) @@ -8866,13 +9447,13 @@ export function initMoves() { .attr(RechargeAttr), new AttackMove(Moves.SPECTRAL_THIEF, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 7) .ignoresSubstitute() - .partial(), + .partial(), // Does not steal stats new AttackMove(Moves.SUNSTEEL_STRIKE, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 7) .ignoresAbilities() - .partial(), + .edgeCase(), // Should not ignore abilities when called virtually (metronome) new AttackMove(Moves.MOONGEIST_BEAM, Type.GHOST, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7) .ignoresAbilities() - .partial(), + .edgeCase(), // Should not ignore abilities when called virtually (metronome) new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, -1, 0, 7) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1), new AttackMove(Moves.ZING_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 30, 0, 7) @@ -8883,7 +9464,7 @@ export function initMoves() { .attr(FormChangeItemTypeAttr), /* Unused */ new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7) - .partial() + .edgeCase() // I assume it's because it needs thunderbolt and pikachu in a cap .ignoresVirtual(), /* End Unused */ new AttackMove(Moves.MIND_BLOWN, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 7) @@ -8891,12 +9472,12 @@ export function initMoves() { .attr(HalfSacrificialAttr) .target(MoveTarget.ALL_NEAR_OTHERS), new AttackMove(Moves.PLASMA_FISTS, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 100, 15, -1, 0, 7) - .attr(AddArenaTagAttr, ArenaTagType.PLASMA_FISTS, 1) + .attr(AddArenaTagAttr, ArenaTagType.ION_DELUGE, 1) .punchingMove(), new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7) .attr(PhotonGeyserCategoryAttr) .ignoresAbilities() - .partial(), + .edgeCase(), // Should not ignore abilities when called virtually (metronome) /* Unused */ new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7) .attr(PhotonGeyserCategoryAttr) @@ -8909,20 +9490,20 @@ export function initMoves() { .ignoresAbilities() .ignoresVirtual(), new AttackMove(Moves.LETS_SNUGGLE_FOREVER, Type.FAIRY, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7) - .partial() + .edgeCase() // I assume it needs play rough and mimikyu .ignoresVirtual(), new AttackMove(Moves.SPLINTERED_STORMSHARDS, Type.ROCK, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7) .attr(ClearTerrainAttr) .makesContact(false) .ignoresVirtual(), new AttackMove(Moves.CLANGOROUS_SOULBLAZE, Type.DRAGON, MoveCategory.SPECIAL, 185, -1, 1, 100, 0, 7) - .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true) + .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true, undefined, undefined, undefined, undefined, true) .soundBased() .target(MoveTarget.ALL_NEAR_ENEMIES) - .partial() + .edgeCase() // I assume it needs clanging scales and Kommo-O .ignoresVirtual(), /* End Unused */ - new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, -1, 2, 7) //LGPE Implementation + new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, -1, 2, 7) // LGPE Implementation .attr(CritOnlyAttr), new AttackMove(Moves.SPLISHY_SPLASH, Type.WATER, MoveCategory.SPECIAL, 90, 100, 15, 30, 0, 7) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) @@ -8932,7 +9513,7 @@ export function initMoves() { new AttackMove(Moves.PIKA_PAPOW, Type.ELECTRIC, MoveCategory.SPECIAL, -1, -1, 20, -1, 0, 7) .attr(FriendshipPowerAttr), new AttackMove(Moves.BOUNCY_BUBBLE, Type.WATER, MoveCategory.SPECIAL, 60, 100, 20, -1, 0, 7) - .attr(HitHealAttr, 1.0) + .attr(HitHealAttr) // Custom .triageMove() .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.BUZZY_BUZZ, Type.ELECTRIC, MoveCategory.SPECIAL, 60, 100, 20, 100, 0, 7) @@ -8982,14 +9563,14 @@ export function initMoves() { new AttackMove(Moves.JAW_LOCK, Type.DARK, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 8) .attr(JawLockAttr) .bitingMove(), - new SelfStatusMove(Moves.STUFF_CHEEKS, Type.NORMAL, -1, 10, -1, 0, 8) // TODO: Stuff Cheeks should not be selectable when the user does not have a berry, see wiki + new SelfStatusMove(Moves.STUFF_CHEEKS, Type.NORMAL, -1, 10, -1, 0, 8) .attr(EatBerryAttr) .attr(StatStageChangeAttr, [ Stat.DEF ], 2, true) .condition((user) => { const userBerries = user.scene.findModifiers(m => m instanceof BerryModifier, user.isPlayer()); return userBerries.length > 0; }) - .partial(), + .edgeCase(), // Stuff Cheeks should not be selectable when the user does not have a berry, see wiki new SelfStatusMove(Moves.NO_RETREAT, Type.FIGHTING, -1, 5, -1, 0, 8) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true) .attr(AddBattlerTagAttr, BattlerTagType.NO_RETREAT, true, false) @@ -9003,7 +9584,7 @@ export function initMoves() { new AttackMove(Moves.DRAGON_DARTS, Type.DRAGON, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 8) .attr(MultiHitAttr, MultiHitType._2) .makesContact(false) - .partial(), + .partial(), // smart targetting is unimplemented new StatusMove(Moves.TEATIME, Type.NORMAL, -1, 10, -1, 0, 8) .attr(EatBerryAttr) .target(MoveTarget.ALL), @@ -9015,7 +9596,7 @@ export function initMoves() { .attr(FirstAttackDoublePowerAttr) .bitingMove(), new StatusMove(Moves.COURT_CHANGE, Type.NORMAL, 100, 10, -1, 0, 8) - .attr(SwapArenaTagsAttr, [ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.MIST, ArenaTagType.REFLECT, ArenaTagType.SPIKES, ArenaTagType.STEALTH_ROCK, ArenaTagType.STICKY_WEB, ArenaTagType.TAILWIND, ArenaTagType.TOXIC_SPIKES]), + .attr(SwapArenaTagsAttr, [ ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.MIST, ArenaTagType.REFLECT, ArenaTagType.SPIKES, ArenaTagType.STEALTH_ROCK, ArenaTagType.STICKY_WEB, ArenaTagType.TAILWIND, ArenaTagType.TOXIC_SPIKES ]), new AttackMove(Moves.MAX_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) .unimplemented() @@ -9149,19 +9730,18 @@ export function initMoves() { .attr(HalfSacrificialAttr), new AttackMove(Moves.EXPANDING_FORCE, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 8) .attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? 1.5 : 1) - .attr(VariableTargetAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? 6 : 3), + .attr(VariableTargetAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.PSYCHIC && user.isGrounded() ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER), new AttackMove(Moves.STEEL_ROLLER, Type.STEEL, MoveCategory.PHYSICAL, 130, 100, 5, -1, 0, 8) .attr(ClearTerrainAttr) .condition((user, target, move) => !!user.scene.arena.terrain), new AttackMove(Moves.SCALE_SHOT, Type.DRAGON, MoveCategory.PHYSICAL, 25, 90, 20, -1, 0, 8) - //.attr(StatStageChangeAttr, Stat.SPD, 1, true) // TODO: Have boosts only apply at end of move, not after every hit - //.attr(StatStageChangeAttr, Stat.DEF, -1, true) + .attr(StatStageChangeAttr, [ Stat.SPD ], 1, true, null, true, false, MoveEffectTrigger.HIT, false, true) + .attr(StatStageChangeAttr, [ Stat.DEF ], -1, true, null, true, false, MoveEffectTrigger.HIT, false, true) .attr(MultiHitAttr) - .makesContact(false) - .partial(), - new AttackMove(Moves.METEOR_BEAM, Type.ROCK, MoveCategory.SPECIAL, 120, 90, 10, 100, 0, 8) - .attr(ChargeAttr, ChargeAnim.METEOR_BEAM_CHARGING, i18next.t("moveTriggers:isOverflowingWithSpacePower", {pokemonName: "{USER}"}), null, true) - .attr(StatStageChangeAttr, [ Stat.SPATK ], 1, true) + .makesContact(false), + new ChargingAttackMove(Moves.METEOR_BEAM, Type.ROCK, MoveCategory.SPECIAL, 120, 90, 10, -1, 0, 8) + .chargeText(i18next.t("moveTriggers:isOverflowingWithSpacePower", { pokemonName: "{USER}" })) + .chargeAttr(StatStageChangeAttr, [ Stat.SPATK ], 1, true) .ignoresVirtual(), new AttackMove(Moves.SHELL_SIDE_ARM, Type.POISON, MoveCategory.SPECIAL, 90, 100, 10, 20, 0, 8) .attr(ShellSideArmCategoryAttr) @@ -9241,7 +9821,7 @@ export function initMoves() { .attr(AttackReducePpMoveAttr, 3) .soundBased(), new AttackMove(Moves.DIRE_CLAW, Type.POISON, MoveCategory.PHYSICAL, 80, 100, 15, 50, 0, 8) - .attr(MultiStatusEffectAttr, [StatusEffect.POISON, StatusEffect.PARALYSIS, StatusEffect.SLEEP]), + .attr(MultiStatusEffectAttr, [ StatusEffect.POISON, StatusEffect.PARALYSIS, StatusEffect.SLEEP ]), new AttackMove(Moves.PSYSHIELD_BASH, Type.PSYCHIC, MoveCategory.PHYSICAL, 70, 90, 10, 100, 0, 8) .attr(StatStageChangeAttr, [ Stat.DEF ], 1, true), new SelfStatusMove(Moves.POWER_SHIFT, Type.NORMAL, -1, 10, -1, 0, 8) @@ -9290,9 +9870,8 @@ export function initMoves() { new AttackMove(Moves.TRIPLE_ARROWS, Type.FIGHTING, MoveCategory.PHYSICAL, 90, 100, 10, 30, 0, 8) .makesContact(false) .attr(HighCritAttr) - .attr(StatStageChangeAttr, [ Stat.DEF ], -1) - .attr(FlinchAttr) - .partial(), + .attr(StatStageChangeAttr, [ Stat.DEF ], -1, undefined, undefined, undefined, undefined, undefined, undefined, undefined, 50) + .attr(FlinchAttr), new AttackMove(Moves.INFERNAL_PARADE, Type.GHOST, MoveCategory.SPECIAL, 60, 100, 15, 30, 0, 8) .attr(StatusEffectAttr, StatusEffect.BURN) .attr(MovePowerMultiplierAttr, (user, target, move) => target.status ? 2 : 1), @@ -9424,10 +10003,11 @@ export function initMoves() { .unimplemented(), End Unused */ new AttackMove(Moves.TERA_BLAST, Type.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 9) - .attr(TeraBlastCategoryAttr) + .attr(TeraMoveCategoryAttr) .attr(TeraBlastTypeAttr) .attr(TeraBlastPowerAttr) - .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR)), + .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR)) + .partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */ new SelfStatusMove(Moves.SILK_TRAP, Type.BUG, -1, 10, -1, 4, 9) .attr(ProtectAttr, BattlerTagType.SILK_TRAP) .condition(failIfLastCondition), @@ -9437,13 +10017,14 @@ export function initMoves() { .attr(ConfuseAttr) .recklessMove(), new AttackMove(Moves.LAST_RESPECTS, Type.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9) + .partial() // Counter resets every wave instead of on arena reset .attr(MovePowerMultiplierAttr, (user, target, move) => 1 + Math.min(user.isPlayer() ? user.scene.currentBattle.playerFaints : user.scene.currentBattle.enemyFaints, 100)) .makesContact(false), new AttackMove(Moves.LUMINA_CRASH, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, 100, 0, 9) .attr(StatStageChangeAttr, [ Stat.SPDEF ], -2), new AttackMove(Moves.ORDER_UP, Type.DRAGON, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 9) .makesContact(false) - .partial(), + .partial(), // No effect implemented (requires Commander) new AttackMove(Moves.JET_PUNCH, Type.WATER, MoveCategory.PHYSICAL, 60, 100, 15, -1, 1, 9) .punchingMove(), new StatusMove(Moves.SPICY_EXTRACT, Type.GRASS, -1, 15, -1, 0, 9) @@ -9516,19 +10097,19 @@ export function initMoves() { .slicingMove(), new AttackMove(Moves.HYDRO_STEAM, Type.WATER, MoveCategory.SPECIAL, 80, 100, 15, -1, 0, 9) .attr(IgnoreWeatherTypeDebuffAttr, WeatherType.SUNNY) - .attr(MovePowerMultiplierAttr, (user, target, move) => [WeatherType.SUNNY, WeatherType.HARSH_SUN].includes(user.scene.arena.weather?.weatherType!) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 1.5 : 1), // TODO: is this bang correct? + .attr(MovePowerMultiplierAttr, (user, target, move) => [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(user.scene.arena.weather?.weatherType!) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 1.5 : 1), // TODO: is this bang correct? new AttackMove(Moves.RUINATION, Type.DARK, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 9) .attr(TargetHalfHpDamageAttr), new AttackMove(Moves.COLLISION_COURSE, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 9) - .attr(MovePowerMultiplierAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2 ? 5461/4096 : 1), + .attr(MovePowerMultiplierAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2 ? 5461 / 4096 : 1), new AttackMove(Moves.ELECTRO_DRIFT, Type.ELECTRIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 9) - .attr(MovePowerMultiplierAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2 ? 5461/4096 : 1) + .attr(MovePowerMultiplierAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2 ? 5461 / 4096 : 1) .makesContact(), new SelfStatusMove(Moves.SHED_TAIL, Type.NORMAL, -1, 10, -1, 0, 9) .attr(AddSubstituteAttr, 0.5) .attr(ForceSwitchOutAttr, true, SwitchType.SHED_TAIL), new SelfStatusMove(Moves.CHILLY_RECEPTION, Type.ICE, -1, 10, -1, 0, 9) - .attr(PreMoveMessageAttr, (user, move) => i18next.t("moveTriggers:chillyReception", {pokemonName: getPokemonNameWithAffix(user)})) + .attr(PreMoveMessageAttr, (user, move) => i18next.t("moveTriggers:chillyReception", { pokemonName: getPokemonNameWithAffix(user) })) .attr(ChillyReceptionAttr, true), new SelfStatusMove(Moves.TIDY_UP, Type.NORMAL, -1, 10, -1, 0, 9) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPD ], 1, true, null, true, true) @@ -9563,7 +10144,7 @@ export function initMoves() { }) .attr(AddBattlerTagAttr, BattlerTagType.DOUBLE_SHOCKED, true, false) .attr(RemoveTypeAttr, Type.ELECTRIC, (user) => { - user.scene.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", {pokemonName: getPokemonNameWithAffix(user)})); + user.scene.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", { pokemonName: getPokemonNameWithAffix(user) })); }), new AttackMove(Moves.GIGATON_HAMMER, Type.STEEL, MoveCategory.PHYSICAL, 160, 100, 5, -1, 0, 9) .makesContact(false) @@ -9613,12 +10194,16 @@ export function initMoves() { .attr(IvyCudgelTypeAttr) .attr(HighCritAttr) .makesContact(false), - new AttackMove(Moves.ELECTRO_SHOT, Type.ELECTRIC, MoveCategory.SPECIAL, 130, 100, 10, 100, 0, 9) - .attr(ElectroShotChargeAttr) + new ChargingAttackMove(Moves.ELECTRO_SHOT, Type.ELECTRIC, MoveCategory.SPECIAL, 130, 100, 10, 100, 0, 9) + .chargeText(i18next.t("moveTriggers:absorbedElectricity", { pokemonName: "{USER}" })) + .chargeAttr(StatStageChangeAttr, [ Stat.SPATK ], 1, true) + .chargeAttr(WeatherInstantChargeAttr, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]) .ignoresVirtual(), new AttackMove(Moves.TERA_STARSTORM, Type.NORMAL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) - .attr(TeraBlastCategoryAttr) - .partial(), + .attr(TeraMoveCategoryAttr) + .attr(TeraStarstormTypeAttr) + .attr(VariableTargetAttr, (user, target, move) => (user.hasFusionSpecies(Species.TERAPAGOS) || user.species.speciesId === Species.TERAPAGOS) && user.isTerastallized() ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER) + .partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */ new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9) .attr(PreMoveMessageAttr, doublePowerChanceMessageFunc) .attr(DoublePowerChanceAttr), @@ -9653,8 +10238,7 @@ export function initMoves() { new AttackMove(Moves.UPPER_HAND, Type.FIGHTING, MoveCategory.PHYSICAL, 65, 100, 15, 100, 3, 9) .attr(FlinchAttr) .condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].priority > 0 ) // TODO: is this bang correct? - //TODO: Should also apply when target move priority increased by ability ex. gale wings - .partial(), + .partial(), // Should also apply when target move priority increased by ability ex. gale wings new AttackMove(Moves.MALIGNANT_CHAIN, Type.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9) .attr(StatusEffectAttr, StatusEffect.TOXIC) ); diff --git a/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts index 7c2d7052ff9..f0155b4f2a4 100644 --- a/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts +++ b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts @@ -44,32 +44,32 @@ export const ATrainersTestEncounter: MysteryEncounter = let spriteKeys; let trainerNameKey: string; switch (randSeedInt(5)) { - default: - case 0: - trainerType = TrainerType.BUCK; - spriteKeys = getSpriteKeysFromSpecies(Species.CLAYDOL); - trainerNameKey = "buck"; - break; - case 1: - trainerType = TrainerType.CHERYL; - spriteKeys = getSpriteKeysFromSpecies(Species.BLISSEY); - trainerNameKey = "cheryl"; - break; - case 2: - trainerType = TrainerType.MARLEY; - spriteKeys = getSpriteKeysFromSpecies(Species.ARCANINE); - trainerNameKey = "marley"; - break; - case 3: - trainerType = TrainerType.MIRA; - spriteKeys = getSpriteKeysFromSpecies(Species.ALAKAZAM, false, 1); - trainerNameKey = "mira"; - break; - case 4: - trainerType = TrainerType.RILEY; - spriteKeys = getSpriteKeysFromSpecies(Species.LUCARIO, false, 1); - trainerNameKey = "riley"; - break; + default: + case 0: + trainerType = TrainerType.BUCK; + spriteKeys = getSpriteKeysFromSpecies(Species.CLAYDOL); + trainerNameKey = "buck"; + break; + case 1: + trainerType = TrainerType.CHERYL; + spriteKeys = getSpriteKeysFromSpecies(Species.BLISSEY); + trainerNameKey = "cheryl"; + break; + case 2: + trainerType = TrainerType.MARLEY; + spriteKeys = getSpriteKeysFromSpecies(Species.ARCANINE); + trainerNameKey = "marley"; + break; + case 3: + trainerType = TrainerType.MIRA; + spriteKeys = getSpriteKeysFromSpecies(Species.ALAKAZAM, false, 1); + trainerNameKey = "mira"; + break; + case 4: + trainerType = TrainerType.RILEY; + spriteKeys = getSpriteKeysFromSpecies(Species.LUCARIO, false, 1); + trainerNameKey = "riley"; + break; } // Dialogue and tokens for trainer @@ -128,6 +128,7 @@ export const ATrainersTestEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -149,11 +150,11 @@ export const ATrainersTestEncounter: MysteryEncounter = pulled: false, sourceType: EggSourceType.EVENT, eggDescriptor: encounter.misc.trainerEggDescription, - tier: EggTier.ULTRA + tier: EggTier.EPIC }; encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`)); - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SACRED_ASH], guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ULTRA], fillRemaining: true }, [eggOptions]); - return initBattleWithEnemyConfig(scene, config); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SACRED_ASH ], guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ULTRA ], fillRemaining: true }, [ eggOptions ]); + await initBattleWithEnemyConfig(scene, config); } ) .withSimpleOption( @@ -171,10 +172,10 @@ export const ATrainersTestEncounter: MysteryEncounter = pulled: false, sourceType: EggSourceType.EVENT, eggDescriptor: encounter.misc.trainerEggDescription, - tier: EggTier.GREAT + tier: EggTier.RARE }; encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.rare`)); - setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [eggOptions]); + setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [ eggOptions ]); leaveEncounterWithoutBattle(scene); } ) diff --git a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts index 0b32f857d75..c53b802bb22 100644 --- a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts +++ b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts @@ -166,6 +166,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = text: `${namespace}:intro`, } ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -195,7 +196,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = // Can't define stack count on a ModifierType, have to just create separate instances for each stack // Overflow berries will be "lost" on the boss, but it's un-catchable anyway for (let i = 0; i < berryMod.stackCount; i++) { - const modifierType = generateModifierType(scene, modifierTypes.BERRY, [berryMod.berryType]) as PokemonHeldItemModifierType; + const modifierType = generateModifierType(scene, modifierTypes.BERRY, [ berryMod.berryType ]) as PokemonHeldItemModifierType; bossModifierConfigs.push({ modifier: modifierType }); } }); @@ -204,8 +205,8 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = // SpDef buff below wave 50, +1 to all stats otherwise const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ? - [Stat.SPDEF] : - [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD]; + [ Stat.SPDEF ] : + [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ]; // Calculate boss mon const config: EnemyPartyConfig = { @@ -215,9 +216,9 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = species: getPokemonSpecies(Species.GREEDENT), isBoss: true, bossSegments: 3, - moveSet: [Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH], + moveSet: [ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH ], modifierConfigs: bossModifierConfigs, - tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1)); @@ -226,7 +227,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = ], }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; encounter.setDialogueToken("greedentName", getPokemonSpecies(Species.GREEDENT).getName()); return true; @@ -280,12 +281,12 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = setEncounterRewards(scene, { fillRemaining: true }, undefined, givePartyPokemonReviverSeeds); encounter.startOfBattleEffects.push({ sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.ENEMY], + targets: [ BattlerIndex.ENEMY ], move: new PokemonMove(Moves.STUFF_CHEEKS), ignorePp: true }); - transitionMysteryEncounterIntroVisuals(scene, true, true, 500); + await transitionMysteryEncounterIntroVisuals(scene, true, true, 500); await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]); }) .build() @@ -320,14 +321,14 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = Phaser.Math.RND.shuffle(berryTypesAsArray); const randBerryType = berryTypesAsArray.pop(); - const berryModType = generateModifierType(scene, modifierTypes.BERRY, [randBerryType]) as BerryModifierType; + const berryModType = generateModifierType(scene, modifierTypes.BERRY, [ randBerryType ]) as BerryModifierType; applyModifierTypeToPlayerPokemon(scene, pokemon, berryModType); } } }); await scene.updateModifiers(true); - transitionMysteryEncounterIntroVisuals(scene, true, true, 500); + await transitionMysteryEncounterIntroVisuals(scene, true, true, 500); leaveEncounterWithoutBattle(scene, true); }) .build() @@ -355,10 +356,10 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = // Greedent joins the team, level equal to 2 below highest party member const level = getHighestLevelPlayerPokemon(scene, false, true).level - 2; const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false); - greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)]; + greedent.moveset = [ new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF) ]; greedent.passive = true; - transitionMysteryEncounterIntroVisuals(scene, true, true, 500); + await transitionMysteryEncounterIntroVisuals(scene, true, true, 500); await catchPokemon(scene, greedent, null, PokeballType.POKEBALL, false); leaveEncounterWithoutBattle(scene, true); }) @@ -472,7 +473,7 @@ function doGreedentEatBerries(scene: BattleScene) { */ function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) { const berryAddDelay = 150; - let animationOrder = ["starf", "sitrus", "lansat", "salac", "apicot", "enigma", "liechi", "ganlon", "lum", "petaya", "leppa"]; + let animationOrder = [ "starf", "sitrus", "lansat", "salac", "apicot", "enigma", "liechi", "ganlon", "lum", "petaya", "leppa" ]; if (isEat) { animationOrder = animationOrder.reverse(); } @@ -496,7 +497,7 @@ function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) { // Animate Petaya berry falling off the pile if (berry === "petaya" && sprite && tintSprite && !isEat) { scene.time.delayedCall(200, () => { - doBerryBounce(scene, [sprite, tintSprite], 30, 500); + doBerryBounce(scene, [ sprite, tintSprite ], 30, 500); }); } }); diff --git a/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts index e445a8f481d..1e20b73e351 100644 --- a/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts +++ b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts @@ -1,4 +1,4 @@ -import { leaveEncounterWithoutBattle, setEncounterExp, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { generateModifierType, leaveEncounterWithoutBattle, setEncounterExp, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { modifierTypes } from "#app/modifier/modifier-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { Species } from "#enums/species"; @@ -14,6 +14,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; +import i18next from "i18next"; /** the i18n namespace for this encounter */ const namespace = "mysteryEncounters/anOfferYouCantRefuse"; @@ -64,6 +65,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = speaker: `${namespace}:speaker`, }, ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -97,6 +99,8 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = } } + const shinyCharm = generateModifierType(scene, modifierTypes.SHINY_CHARM); + encounter.setDialogueToken("itemName", shinyCharm?.name ?? i18next.t("modifierType:ModifierType.SHINY_CHARM.name")); encounter.setDialogueToken("liepardName", getPokemonSpecies(Species.LIEPARD).getName()); return true; @@ -122,7 +126,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = return true; }) .withOptionPhase(async (scene: BattleScene) => { - // Give the player a Shiny charm + // Give the player a Shiny Charm scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.SHINY_CHARM)); leaveEncounterWithoutBattle(scene, true); }) @@ -131,9 +135,11 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) - .withPrimaryPokemonRequirement(new CombinationPokemonRequirement( - new MoveRequirement(EXTORTION_MOVES), - new AbilityRequirement(EXTORTION_ABILITIES)) + .withPrimaryPokemonRequirement( + CombinationPokemonRequirement.Some( + new MoveRequirement(EXTORTION_MOVES, true), + new AbilityRequirement(EXTORTION_ABILITIES, true) + ) ) .withDialogue({ buttonLabel: `${namespace}:option.2.label`, diff --git a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts index 55c66642944..095f8a8473b 100644 --- a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts +++ b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts @@ -69,7 +69,7 @@ export const BerriesAboundEncounter: MysteryEncounter = isBoss: true }], }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; // Calculate the number of extra berries that player receives // 10-40: 2, 40-120: 4, 120-160: 5, 160-180: 7 @@ -110,6 +110,7 @@ export const BerriesAboundEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -193,11 +194,11 @@ export const BerriesAboundEncounter: MysteryEncounter = // Defense/Spd buffs below wave 50, +1 to all stats otherwise const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ? - [Stat.DEF, Stat.SPDEF, Stat.SPD] : - [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD]; + [ Stat.DEF, Stat.SPDEF, Stat.SPD ] : + [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ]; const config = scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]; - config.pokemonConfigs![0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON]; + config.pokemonConfigs![0].tags = [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ]; config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => { queueEncounterMessage(pokemon.scene, `${namespace}:option.2.boss_enraged`); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1)); @@ -208,7 +209,7 @@ export const BerriesAboundEncounter: MysteryEncounter = return; } else { // Gains 1 berry for every 10% faster the player's pokemon is than the enemy, up to a max of numBerries, minimum of 2 - const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1)/0.08), numBerries), 2); + const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1) / 0.08), numBerries), 2); encounter.setDialogueToken("numBerries", String(numBerriesGrabbed)); const doFasterBerryRewards = () => { const berryText = i18next.t(`${namespace}:berries`); @@ -250,7 +251,7 @@ export const BerriesAboundEncounter: MysteryEncounter = function tryGiveBerry(scene: BattleScene, prioritizedPokemon?: PlayerPokemon) { const berryType = randSeedInt(Object.keys(BerryType).filter(s => !isNaN(Number(s))).length) as BerryType; - const berry = generateModifierType(scene, modifierTypes.BERRY, [berryType]) as BerryModifierType; + const berry = generateModifierType(scene, modifierTypes.BERRY, [ berryType ]) as BerryModifierType; const party = scene.getParty(); diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index 6847ab8b832..e24eadb56c7 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -42,6 +42,8 @@ import { AttackTypeBoosterModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, + GigantamaxAccessModifier, + MegaEvolutionAccessModifier, PokemonHeldItemModifier } from "#app/modifier/modifier"; import i18next from "i18next"; @@ -181,7 +183,7 @@ const MISC_TUTOR_MOVES = [ /** * Wave breakpoints that determine how strong to make the Bug-Type Superfan's team */ -const WAVE_LEVEL_BREAKPOINTS = [30, 50, 70, 100, 120, 140, 160]; +const WAVE_LEVEL_BREAKPOINTS = [ 30, 50, 70, 100, 120, 140, 160 ]; /** * Bug Type Superfan encounter. @@ -191,12 +193,14 @@ const WAVE_LEVEL_BREAKPOINTS = [30, 50, 70, 100, 120, 140, 160]; export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.BUG_TYPE_SUPERFAN) .withEncounterTier(MysteryEncounterTier.GREAT) - .withPrimaryPokemonRequirement(new CombinationPokemonRequirement( - // Must have at least 1 Bug type on team, OR have a bug item somewhere on the team - new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1), - new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1), - new TypeRequirement(Type.BUG, false, 1) - )) + .withPrimaryPokemonRequirement( + CombinationPokemonRequirement.Some( + // Must have at least 1 Bug type on team, OR have a bug item somewhere on the team + new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1), + new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1), + new TypeRequirement(Type.BUG, false, 1) + ) + ) .withMaxAllowedEncounters(1) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withIntroSpriteConfigs([]) // These are set in onInit() @@ -268,7 +272,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = const requiredItems = [ generateModifierType(scene, modifierTypes.QUICK_CLAW), generateModifierType(scene, modifierTypes.GRIP_CLAW), - generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.BUG]), + generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.BUG ]), ]; const requiredItemString = requiredItems.map(m => m?.name ?? "unknown").join("/"); @@ -276,6 +280,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -331,7 +336,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = encounter.setDialogueToken("numBugTypes", numBugTypesText); if (numBugTypes < 2) { - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL ], fillRemaining: false }); encounter.selectedOption!.dialogue!.selected = [ { speaker: `${namespace}:speaker`, @@ -339,7 +344,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = }, ]; } else if (numBugTypes < 4) { - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL ], fillRemaining: false }); encounter.selectedOption!.dialogue!.selected = [ { speaker: `${namespace}:speaker`, @@ -347,7 +352,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = }, ]; } else if (numBugTypes < 6) { - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL ], fillRemaining: false }); encounter.selectedOption!.dialogue!.selected = [ { speaker: `${namespace}:speaker`, @@ -355,10 +360,17 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = }, ]; } else { - // If player has any evolution/form change items that are valid for their party, will spawn one of those items in addition to a Master Ball - const modifierOptions: ModifierTypeOption[] = [generateModifierTypeOption(scene, modifierTypes.MASTER_BALL)!, generateModifierTypeOption(scene, modifierTypes.MAX_LURE)!]; + // If the player has any evolution/form change items that are valid for their party, + // spawn one of those items in addition to Dynamax Band, Mega Band, and Master Ball + const modifierOptions: ModifierTypeOption[] = [ generateModifierTypeOption(scene, modifierTypes.MASTER_BALL)! ]; const specialOptions: ModifierTypeOption[] = []; + if (!scene.findModifier(m => m instanceof MegaEvolutionAccessModifier)) { + modifierOptions.push(generateModifierTypeOption(scene, modifierTypes.MEGA_BRACELET)!); + } + if (!scene.findModifier(m => m instanceof GigantamaxAccessModifier)) { + modifierOptions.push(generateModifierTypeOption(scene, modifierTypes.DYNAMAX_BAND)!); + } const nonRareEvolutionModifier = generateModifierTypeOption(scene, modifierTypes.EVOLUTION_ITEM); if (nonRareEvolutionModifier) { specialOptions.push(nonRareEvolutionModifier); @@ -395,11 +407,13 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = .build()) .withOption(MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) - .withPrimaryPokemonRequirement(new CombinationPokemonRequirement( - // Meets one or both of the below reqs - new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1), - new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1) - )) + .withPrimaryPokemonRequirement( + CombinationPokemonRequirement.Some( + // Meets one or both of the below reqs + new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1), + new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1) + ) + ) .withDialogue({ buttonLabel: `${namespace}:option.3.label`, buttonTooltip: `${namespace}:option.3.tooltip`, @@ -474,7 +488,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = const bugNet = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!; bugNet.type.tier = ModifierTier.ROGUE; - setEncounterRewards(scene, { guaranteedModifierTypeOptions: [bugNet], guaranteedModifierTypeFuncs: [modifierTypes.REVIVER_SEED], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ bugNet ], guaranteedModifierTypeFuncs: [ modifierTypes.REVIVER_SEED ], fillRemaining: false }); leaveEncounterWithoutBattle(scene, true); }) .build()) @@ -535,7 +549,7 @@ function getTrainerConfigForWave(waveIndex: number) { })) .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)) .setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => { if (!isNullOrUndefined(pool3Mon.formIndex)) { p.formIndex = pool3Mon.formIndex; p.generateAndPopulateMoveset(); @@ -558,14 +572,14 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateName(); })) .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => { if (!isNullOrUndefined(pool3Mon.formIndex)) { p.formIndex = pool3Mon.formIndex; p.generateAndPopulateMoveset(); p.generateName(); } })) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ pool3Mon2.species ], TrainerSlot.TRAINER, true, p => { if (!isNullOrUndefined(pool3Mon2.formIndex)) { p.formIndex = pool3Mon2.formIndex; p.generateAndPopulateMoveset(); @@ -586,7 +600,7 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateName(); })) .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => { if (!isNullOrUndefined(pool3Mon.formIndex)) { p.formIndex = pool3Mon.formIndex; p.generateAndPopulateMoveset(); @@ -611,14 +625,14 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateAndPopulateMoveset(); p.generateName(); })) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => { if (!isNullOrUndefined(pool3Mon.formIndex)) { p.formIndex = pool3Mon.formIndex; p.generateAndPopulateMoveset(); p.generateName(); } })) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon2.species ], TrainerSlot.TRAINER, true, p => { if (!isNullOrUndefined(pool3Mon2.formIndex)) { p.formIndex = pool3Mon2.formIndex; p.generateAndPopulateMoveset(); diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index e2bf3bf79fe..c4b03660bde 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -11,7 +11,7 @@ import { Species } from "#enums/species"; import { TrainerType } from "#enums/trainer-type"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import { Abilities } from "#enums/abilities"; -import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { applyAbilityOverrideToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { Type } from "#app/data/type"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; @@ -28,7 +28,7 @@ import { BattlerIndex } from "#app/battle"; import { Moves } from "#enums/moves"; import { EncounterBattleAnim } from "#app/data/battle-anims"; import { MoveCategory } from "#app/data/move"; -import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; import { EncounterAnim } from "#enums/encounter-anims"; import { Challenges } from "#enums/challenges"; @@ -129,25 +129,26 @@ export const ClowningAroundEncounter: MysteryEncounter = { species: getPokemonSpecies(Species.MR_MIME), isBoss: true, - moveSet: [Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC] + moveSet: [ Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC ] }, { // Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter species: getPokemonSpecies(Species.BLACEPHALON), - mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ ability: ability, types: [randSeedInt(18), randSeedInt(18)] }), + customPokemonData: new CustomPokemonData({ ability: ability, types: [ randSeedInt(18), randSeedInt(18) ]}), isBoss: true, - moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN] + moveSet: [ Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN ] }, ], doubleBattle: true }); // Load animations/sfx for start of fight moves - loadCustomMovesForEncounter(scene, [Moves.ROLE_PLAY, Moves.TAUNT]); + loadCustomMovesForEncounter(scene, [ Moves.ROLE_PLAY, Moves.TAUNT ]); encounter.setDialogueToken("blacephalonName", getPokemonSpecies(Species.BLACEPHALON).getName()); return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -175,19 +176,19 @@ export const ClowningAroundEncounter: MysteryEncounter = encounter.startOfBattleEffects.push( { // Mr. Mime copies the Blacephalon's random ability sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.ENEMY_2], + targets: [ BattlerIndex.ENEMY_2 ], move: new PokemonMove(Moves.ROLE_PLAY), ignorePp: true }, { sourceBattlerIndex: BattlerIndex.ENEMY_2, - targets: [BattlerIndex.PLAYER], + targets: [ BattlerIndex.PLAYER ], move: new PokemonMove(Moves.TAUNT), ignorePp: true }, { sourceBattlerIndex: BattlerIndex.ENEMY_2, - targets: [BattlerIndex.PLAYER_2], + targets: [ BattlerIndex.PLAYER_2 ], move: new PokemonMove(Moves.TAUNT), ignorePp: true }); @@ -336,11 +337,11 @@ export const ClowningAroundEncounter: MysteryEncounter = .filter(move => move && !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS) .map(move => move!.getMove().type); if (priorityTypes?.length > 0) { - priorityTypes = [...new Set(priorityTypes)].sort(); + priorityTypes = [ ...new Set(priorityTypes) ].sort(); priorityTypes = randSeedShuffle(priorityTypes); } - const newTypes = [originalTypes[0]]; + const newTypes = [ originalTypes[0] ]; let secondType: Type | null = null; while (secondType === null || secondType === newTypes[0] || originalTypes.includes(secondType)) { if (priorityTypes.length > 0) { @@ -352,15 +353,15 @@ export const ClowningAroundEncounter: MysteryEncounter = newTypes.push(secondType); // Apply the type changes (to both base and fusion, if pokemon is fused) - if (!pokemon.mysteryEncounterPokemonData) { - pokemon.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(); + if (!pokemon.customPokemonData) { + pokemon.customPokemonData = new CustomPokemonData(); } - pokemon.mysteryEncounterPokemonData.types = newTypes; + pokemon.customPokemonData.types = newTypes; if (pokemon.isFusion()) { - if (!pokemon.fusionMysteryEncounterPokemonData) { - pokemon.fusionMysteryEncounterPokemonData = new MysteryEncounterPokemonData(); + if (!pokemon.fusionCustomPokemonData) { + pokemon.fusionCustomPokemonData = new CustomPokemonData(); } - pokemon.fusionMysteryEncounterPokemonData.types = newTypes; + pokemon.fusionCustomPokemonData.types = newTypes; } } }) @@ -424,17 +425,8 @@ function onYesAbilitySwap(scene: BattleScene, resolve) { const onPokemonSelected = (pokemon: PlayerPokemon) => { // Do ability swap const encounter = scene.currentBattle.mysteryEncounter!; - if (pokemon.isFusion()) { - if (!pokemon.fusionMysteryEncounterPokemonData) { - pokemon.fusionMysteryEncounterPokemonData = new MysteryEncounterPokemonData(); - } - pokemon.fusionMysteryEncounterPokemonData.ability = encounter.misc.ability; - } else { - if (!pokemon.mysteryEncounterPokemonData) { - pokemon.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(); - } - pokemon.mysteryEncounterPokemonData.ability = encounter.misc.ability; - } + + applyAbilityOverrideToPokemon(pokemon, encounter.misc.ability); encounter.setDialogueToken("chosenPokemon", pokemon.getNameToRender()); scene.ui.setMode(Mode.MESSAGE).then(() => resolve(true)); }; @@ -453,37 +445,37 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem // Pools have instances of the modifier type equal to the max stacks that modifier can be applied to any one pokemon // This is to prevent "over-generating" a random item of a certain type during item swaps const ultraPool = [ - [modifierTypes.REVIVER_SEED, 1], - [modifierTypes.GOLDEN_PUNCH, 5], - [modifierTypes.ATTACK_TYPE_BOOSTER, 99], - [modifierTypes.QUICK_CLAW, 3], - [modifierTypes.WIDE_LENS, 3] + [ modifierTypes.REVIVER_SEED, 1 ], + [ modifierTypes.GOLDEN_PUNCH, 5 ], + [ modifierTypes.ATTACK_TYPE_BOOSTER, 99 ], + [ modifierTypes.QUICK_CLAW, 3 ], + [ modifierTypes.WIDE_LENS, 3 ] ]; const roguePool = [ - [modifierTypes.LEFTOVERS, 4], - [modifierTypes.SHELL_BELL, 4], - [modifierTypes.SOUL_DEW, 10], - [modifierTypes.SOOTHE_BELL, 3], - [modifierTypes.SCOPE_LENS, 1], - [modifierTypes.BATON, 1], - [modifierTypes.FOCUS_BAND, 5], - [modifierTypes.KINGS_ROCK, 3], - [modifierTypes.GRIP_CLAW, 5] + [ modifierTypes.LEFTOVERS, 4 ], + [ modifierTypes.SHELL_BELL, 4 ], + [ modifierTypes.SOUL_DEW, 10 ], + [ modifierTypes.SOOTHE_BELL, 3 ], + [ modifierTypes.SCOPE_LENS, 1 ], + [ modifierTypes.BATON, 1 ], + [ modifierTypes.FOCUS_BAND, 5 ], + [ modifierTypes.KINGS_ROCK, 3 ], + [ modifierTypes.GRIP_CLAW, 5 ] ]; const berryPool = [ - [BerryType.APICOT, 3], - [BerryType.ENIGMA, 2], - [BerryType.GANLON, 3], - [BerryType.LANSAT, 3], - [BerryType.LEPPA, 2], - [BerryType.LIECHI, 3], - [BerryType.LUM, 2], - [BerryType.PETAYA, 3], - [BerryType.SALAC, 2], - [BerryType.SITRUS, 2], - [BerryType.STARF, 3] + [ BerryType.APICOT, 3 ], + [ BerryType.ENIGMA, 2 ], + [ BerryType.GANLON, 3 ], + [ BerryType.LANSAT, 3 ], + [ BerryType.LEPPA, 2 ], + [ BerryType.LIECHI, 3 ], + [ BerryType.LUM, 2 ], + [ BerryType.PETAYA, 3 ], + [ BerryType.SALAC, 2 ], + [ BerryType.SITRUS, 2 ], + [ BerryType.STARF, 3 ] ]; let pool: any[]; @@ -502,7 +494,7 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem const newItemType = pool[randIndex]; let newMod: PokemonHeldItemModifierType; if (tier === "Berries") { - newMod = generateModifierType(scene, modifierTypes.BERRY, [newItemType[0]]) as PokemonHeldItemModifierType; + newMod = generateModifierType(scene, modifierTypes.BERRY, [ newItemType[0] ]) as PokemonHeldItemModifierType; } else { newMod = generateModifierType(scene, newItemType[0]) as PokemonHeldItemModifierType; } diff --git a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts index 655cc3e937e..55d7ce0e92d 100644 --- a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts +++ b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts @@ -102,6 +102,7 @@ export const DancingLessonsEncounter: MysteryEncounter = text: `${namespace}:intro`, } ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -141,7 +142,7 @@ export const DancingLessonsEncounter: MysteryEncounter = scene.getEnemyParty().forEach(enemyPokemon => { scene.field.remove(enemyPokemon, true); }); - scene.currentBattle.enemyParty = [oricorio]; + scene.currentBattle.enemyParty = [ oricorio ]; scene.field.add(oricorio); // Spawns on offscreen field oricorio.x -= 300; @@ -153,14 +154,14 @@ export const DancingLessonsEncounter: MysteryEncounter = dataSource: oricorioData, isBoss: true, // Gets +1 to all stats except SPD on battle start - tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`); - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF], 1)); + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF ], 1)); } }], }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; encounter.misc = { oricorioData }; @@ -187,13 +188,13 @@ export const DancingLessonsEncounter: MysteryEncounter = encounter.startOfBattleEffects.push({ sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.PLAYER], + targets: [ BattlerIndex.PLAYER ], move: new PokemonMove(Moves.REVELATION_DANCE), ignorePp: true }); await hideOricorioPokemon(scene); - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.BATON], fillRemaining: true }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.BATON ], fillRemaining: true }); await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]); }) .build() @@ -227,7 +228,7 @@ export const DancingLessonsEncounter: MysteryEncounter = }) .withOptionPhase(async (scene: BattleScene) => { // Learn its Dance - hideOricorioPokemon(scene); + await hideOricorioPokemon(scene); leaveEncounterWithoutBattle(scene, true); }) .build() @@ -235,7 +236,7 @@ export const DancingLessonsEncounter: MysteryEncounter = .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) - .withPrimaryPokemonRequirement(new MoveRequirement(DANCING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically + .withPrimaryPokemonRequirement(new MoveRequirement(DANCING_MOVES, true)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically .withDialogue({ buttonLabel: `${namespace}:option.3.label`, buttonTooltip: `${namespace}:option.3.tooltip`, @@ -302,7 +303,7 @@ export const DancingLessonsEncounter: MysteryEncounter = } } - hideOricorioPokemon(scene); + await hideOricorioPokemon(scene); await catchPokemon(scene, oricorio, null, PokeballType.POKEBALL, false); leaveEncounterWithoutBattle(scene, true); }) diff --git a/src/data/mystery-encounters/encounters/dark-deal-encounter.ts b/src/data/mystery-encounters/encounters/dark-deal-encounter.ts index c511add0b28..8a814b58248 100644 --- a/src/data/mystery-encounters/encounters/dark-deal-encounter.ts +++ b/src/data/mystery-encounters/encounters/dark-deal-encounter.ts @@ -14,6 +14,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase"; import { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; +import { Challenges } from "#enums/challenges"; /** i18n namespace for encounter */ const namespace = "mysteryEncounters/darkDeal"; @@ -117,6 +118,7 @@ export const DarkDealEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(30, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1]) .withScenePartySizeRequirement(2, 6, true) // Must have at least 2 pokemon in party .withCatchAllowed(true) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -140,6 +142,7 @@ export const DarkDealEncounter: MysteryEncounter = // Removes random pokemon (including fainted) from party and adds name to dialogue data tokens // Will never return last battle able mon and instead pick fainted/unable to battle const removedPokemon = getRandomPlayerPokemon(scene, true, false, true); + // Get all the pokemon's held items const modifiers = removedPokemon.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier)); scene.removePokemonFromPlayerParty(removedPokemon); @@ -159,19 +162,26 @@ export const DarkDealEncounter: MysteryEncounter = scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.ROGUE_BALL)); // Start encounter with random legendary (7-10 starter strength) that has level additive - const bossTypes: Type[] = encounter.misc.removedTypes; + // If this is a mono-type challenge, always ensure the required type is filtered for + let bossTypes: Type[] = encounter.misc.removedTypes; + const singleTypeChallenges = scene.gameMode.challenges.filter(c => c.value && c.id === Challenges.SINGLE_TYPE); + if (scene.gameMode.isChallenge && singleTypeChallenges.length > 0) { + bossTypes = singleTypeChallenges.map(c => (c.value - 1) as Type); + } + const bossModifiers: PokemonHeldItemModifier[] = encounter.misc.modifiers; // Starter egg tier, 35/50/10/5 %odds for tiers 6/7/8/9+ const roll = randSeedInt(100); const starterTier: number | [number, number] = - roll >= 65 ? 6 : roll >= 15 ? 7 : roll >= 5 ? 8 : [9, 10]; + roll >= 65 ? 6 : roll >= 15 ? 7 : roll >= 5 ? 8 : [ 9, 10 ]; const bossSpecies = getPokemonSpecies(getRandomSpeciesByStarterTier(starterTier, excludedBosses, bossTypes)); const pokemonConfig: EnemyPokemonConfig = { species: bossSpecies, isBoss: true, modifierConfigs: bossModifiers.map(m => { return { - modifier: m + modifier: m, + stackCount: m.getStackCount(), }; }) }; @@ -179,9 +189,9 @@ export const DarkDealEncounter: MysteryEncounter = pokemonConfig.formIndex = 0; } const config: EnemyPartyConfig = { - pokemonConfigs: [pokemonConfig], + pokemonConfigs: [ pokemonConfig ], }; - return initBattleWithEnemyConfig(scene, config); + await initBattleWithEnemyConfig(scene, config); }) .build() ) diff --git a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts index 1246572b680..d5f9388b56c 100644 --- a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts +++ b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts @@ -22,7 +22,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; const namespace = "mysteryEncounters/delibirdy"; /** Berries only */ -const OPTION_2_ALLOWED_MODIFIERS = ["BerryModifier", "PokemonInstantReviveModifier"]; +const OPTION_2_ALLOWED_MODIFIERS = [ "BerryModifier", "PokemonInstantReviveModifier" ]; /** Disallowed items are berries, Reviver Seeds, and Vitamins (form change items and fusion items are not PokemonHeldItemModifiers) */ const OPTION_3_DISALLOWED_MODIFIERS = [ @@ -45,10 +45,13 @@ export const DelibirdyEncounter: MysteryEncounter = .withEncounterTier(MysteryEncounterTier.GREAT) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withSceneRequirement(new MoneyRequirement(0, DELIBIRDY_MONEY_PRICE_MULTIPLIER)) // Must have enough money for it to spawn at the very least - .withPrimaryPokemonRequirement(new CombinationPokemonRequirement( // Must also have either option 2 or 3 available to spawn - new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS), - new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true) - )) + .withPrimaryPokemonRequirement( + CombinationPokemonRequirement.Some( + // Must also have either option 2 or 3 available to spawn + new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS), + new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true) + ) + ) .withIntroSpriteConfigs([ { spriteKey: "", @@ -84,6 +87,7 @@ export const DelibirdyEncounter: MysteryEncounter = text: `${namespace}:intro`, } ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -195,7 +199,7 @@ export const DelibirdyEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; const modifier: BerryModifier | HealingBoosterModifier = encounter.misc.chosenModifier; - // Give the player a Candy Jar if they gave a Berry, and a Healing Charm for Reviver Seed + // Give the player a Candy Jar if they gave a Berry, and a Berry Pouch for Reviver Seed if (modifier instanceof BerryModifier) { // Check if the player has max stacks of that Candy Jar already const existing = scene.findModifier(m => m instanceof LevelIncrementBoosterModifier) as LevelIncrementBoosterModifier; @@ -210,8 +214,8 @@ export const DelibirdyEncounter: MysteryEncounter = scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.CANDY_JAR)); } } else { - // Check if the player has max stacks of that Healing Charm already - const existing = scene.findModifier(m => m instanceof HealingBoosterModifier) as HealingBoosterModifier; + // Check if the player has max stacks of that Berry Pouch already + const existing = scene.findModifier(m => m instanceof PreserveBerryModifier) as PreserveBerryModifier; if (existing && existing.getStackCount() >= existing.getMaxStackCount(scene)) { // At max stacks, give the first party pokemon a Shell Bell instead @@ -220,7 +224,7 @@ export const DelibirdyEncounter: MysteryEncounter = scene.playSound("item_fanfare"); await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true); } else { - scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.HEALING_CHARM)); + scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.BERRY_POUCH)); } } @@ -289,8 +293,8 @@ export const DelibirdyEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; const modifier = encounter.misc.chosenModifier; - // Check if the player has max stacks of Berry Pouch already - const existing = scene.findModifier(m => m instanceof PreserveBerryModifier) as PreserveBerryModifier; + // Check if the player has max stacks of Healing Charm already + const existing = scene.findModifier(m => m instanceof HealingBoosterModifier) as HealingBoosterModifier; if (existing && existing.getStackCount() >= existing.getMaxStackCount(scene)) { // At max stacks, give the first party pokemon a Shell Bell instead @@ -299,7 +303,7 @@ export const DelibirdyEncounter: MysteryEncounter = scene.playSound("item_fanfare"); await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true); } else { - scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.BERRY_POUCH)); + scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.HEALING_CHARM)); } // Remove the modifier if its stacks go to 0 diff --git a/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts b/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts index 1505768f968..10034d19263 100644 --- a/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts +++ b/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts @@ -51,6 +51,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = }, ]) .withAutoHideIntroVisuals(false) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) diff --git a/src/data/mystery-encounters/encounters/field-trip-encounter.ts b/src/data/mystery-encounters/encounters/field-trip-encounter.ts index 0a356f16b37..bf5fb28163b 100644 --- a/src/data/mystery-encounters/encounters/field-trip-encounter.ts +++ b/src/data/mystery-encounters/encounters/field-trip-encounter.ts @@ -52,6 +52,7 @@ export const FieldTripEncounter: MysteryEncounter = }, ]) .withAutoHideIntroVisuals(false) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -87,9 +88,9 @@ export const FieldTripEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; if (encounter.misc.correctMove) { const modifiers = [ - generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ATK])!, - generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.DEF])!, - generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!, + generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.ATK ])!, + generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.DEF ])!, + generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!, generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!, generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!, ]; @@ -133,9 +134,9 @@ export const FieldTripEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; if (encounter.misc.correctMove) { const modifiers = [ - generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPATK])!, - generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPDEF])!, - generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!, + generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPATK ])!, + generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPDEF ])!, + generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!, generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!, generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!, ]; @@ -179,8 +180,8 @@ export const FieldTripEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; if (encounter.misc.correctMove) { const modifiers = [ - generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ACC])!, - generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!, + generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.ACC ])!, + generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!, generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!, generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!, generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!, @@ -227,7 +228,7 @@ function pokemonAndMoveChosen(scene: BattleScene, pokemon: PlayerPokemon, move: text: `${namespace}:correct_exp`, }, ]; - setEncounterExp(scene, [pokemon.id], 100); + setEncounterExp(scene, [ pokemon.id ], 100); } encounter.misc = { correctMove: correctMove, diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index cfb87a9e862..5c16e5d8564 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -4,24 +4,30 @@ import { AttackTypeBoosterModifierType, modifierTypes, } from "#app/modifier/mod import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter"; -import { TypeRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements"; +import { AbilityRequirement, CombinationPokemonRequirement, TypeRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements"; import { Species } from "#enums/species"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import { Gender } from "#app/data/gender"; import { Type } from "#app/data/type"; import { BattlerIndex } from "#app/battle"; -import { PokemonMove } from "#app/field/pokemon"; +import Pokemon, { PokemonMove } from "#app/field/pokemon"; import { Moves } from "#enums/moves"; import { EncounterBattleAnim } from "#app/data/battle-anims"; import { WeatherType } from "#app/data/weather"; import { isNullOrUndefined, randSeedInt } from "#app/utils"; import { StatusEffect } from "#app/data/status-effect"; import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; -import { applyDamageToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { applyAbilityOverrideToPokemon, applyDamageToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { EncounterAnim } from "#enums/encounter-anims"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; +import { Stat } from "#enums/stat"; +import { Ability } from "#app/data/ability"; +import { FIRE_RESISTANT_ABILITIES } from "#app/data/mystery-encounters/requirements/requirement-groups"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounters/fieryFallout"; @@ -62,18 +68,26 @@ export const FieryFalloutEncounter: MysteryEncounter = { species: volcaronaSpecies, isBoss: false, - gender: Gender.MALE + gender: Gender.MALE, + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], + mysteryEncounterBattleEffects: (pokemon: Pokemon) => { + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.SPDEF, Stat.SPD ], 1)); + } }, { species: volcaronaSpecies, isBoss: false, - gender: Gender.FEMALE + gender: Gender.FEMALE, + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], + mysteryEncounterBattleEffects: (pokemon: Pokemon) => { + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.SPDEF, Stat.SPD ], 1)); + } } ], doubleBattle: true, - disableSwitch: true + disableSwitch: true, }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; // Load hidden Volcarona sprites encounter.spriteConfigs = [ @@ -99,7 +113,7 @@ export const FieryFalloutEncounter: MysteryEncounter = ]; // Load animations/sfx for Volcarona moves - loadCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]); + loadCustomMovesForEncounter(scene, [ Moves.FIRE_SPIN, Moves.QUIVER_DANCE ]); scene.arena.trySetWeather(WeatherType.SUNNY, true); @@ -122,6 +136,7 @@ export const FieryFalloutEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -138,32 +153,20 @@ export const FieryFalloutEncounter: MysteryEncounter = async (scene: BattleScene) => { // Pick battle const encounter = scene.currentBattle.mysteryEncounter!; - setEncounterRewards(scene, { fillRemaining: true }, undefined, () => giveLeadPokemonCharcoal(scene)); + setEncounterRewards(scene, { fillRemaining: true }, undefined, () => giveLeadPokemonAttackTypeBoostItem(scene)); encounter.startOfBattleEffects.push( { sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.PLAYER], + targets: [ BattlerIndex.PLAYER ], move: new PokemonMove(Moves.FIRE_SPIN), ignorePp: true }, { sourceBattlerIndex: BattlerIndex.ENEMY_2, - targets: [BattlerIndex.PLAYER_2], + targets: [ BattlerIndex.PLAYER_2 ], move: new PokemonMove(Moves.FIRE_SPIN), ignorePp: true - }, - { - sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.ENEMY], - move: new PokemonMove(Moves.QUIVER_DANCE), - ignorePp: true - }, - { - sourceBattlerIndex: BattlerIndex.ENEMY_2, - targets: [BattlerIndex.ENEMY_2], - move: new PokemonMove(Moves.QUIVER_DANCE), - ignorePp: true }); await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]); } @@ -179,7 +182,7 @@ export const FieryFalloutEncounter: MysteryEncounter = ], }, async (scene: BattleScene) => { - // Damage non-fire types and burn 1 random non-fire type member + // Damage non-fire types and burn 1 random non-fire type member + give it Heatproof const encounter = scene.currentBattle.mysteryEncounter!; const nonFireTypes = scene.getParty().filter((p) => p.isAllowedInBattle() && !p.getTypes().includes(Type.FIRE)); @@ -197,7 +200,11 @@ export const FieryFalloutEncounter: MysteryEncounter = if (chosenPokemon.trySetStatus(StatusEffect.BURN)) { // Burn applied encounter.setDialogueToken("burnedPokemon", chosenPokemon.getNameToRender()); + encounter.setDialogueToken("abilityName", new Ability(Abilities.HEATPROOF, 3).name); queueEncounterMessage(scene, `${namespace}:option.2.target_burned`); + + // Also permanently change the burned Pokemon's ability to Heatproof + applyAbilityOverrideToPokemon(chosenPokemon, Abilities.HEATPROOF); } } @@ -208,8 +215,12 @@ export const FieryFalloutEncounter: MysteryEncounter = .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) - .withPrimaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3PrimaryName dialogue token automatically - .withSecondaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3SecondaryName dialogue token automatically + .withPrimaryPokemonRequirement( + CombinationPokemonRequirement.Some( + new TypeRequirement(Type.FIRE, true, 1), + new AbilityRequirement(FIRE_RESISTANT_ABILITIES, true) + ) + ) // Will set option3PrimaryName dialogue token automatically .withDialogue({ buttonLabel: `${namespace}:option.3.label`, buttonTooltip: `${namespace}:option.3.tooltip`, @@ -221,36 +232,43 @@ export const FieryFalloutEncounter: MysteryEncounter = ], }) .withPreOptionPhase(async (scene: BattleScene) => { + // Do NOT await this, to prevent player from repeatedly pressing options transitionMysteryEncounterIntroVisuals(scene, false, false, 2000); }) .withOptionPhase(async (scene: BattleScene) => { // Fire types help calm the Volcarona const encounter = scene.currentBattle.mysteryEncounter!; - transitionMysteryEncounterIntroVisuals(scene); + await transitionMysteryEncounterIntroVisuals(scene); setEncounterRewards(scene, { fillRemaining: true }, undefined, () => { - giveLeadPokemonCharcoal(scene); + giveLeadPokemonAttackTypeBoostItem(scene); }); const primary = encounter.options[2].primaryPokemon!; - const secondary = encounter.options[2].secondaryPokemon![0]; - setEncounterExp(scene, [primary.id, secondary.id], getPokemonSpecies(Species.VOLCARONA).baseExp * 2); + setEncounterExp(scene, [ primary.id ], getPokemonSpecies(Species.VOLCARONA).baseExp * 2); leaveEncounterWithoutBattle(scene); }) .build() ) .build(); -function giveLeadPokemonCharcoal(scene: BattleScene) { - // Give first party pokemon Charcoal for free at end of battle +function giveLeadPokemonAttackTypeBoostItem(scene: BattleScene) { + // Give first party pokemon attack type boost item for free at end of battle const leadPokemon = scene.getParty()?.[0]; if (leadPokemon) { - const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FIRE]) as AttackTypeBoosterModifierType; - applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal); - scene.currentBattle.mysteryEncounter!.setDialogueToken("leadPokemon", leadPokemon.getNameToRender()); - queueEncounterMessage(scene, `${namespace}:found_charcoal`); + // Generate type booster held item, default to Charcoal if item fails to generate + let boosterModifierType = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER) as AttackTypeBoosterModifierType; + if (!boosterModifierType) { + boosterModifierType = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.FIRE ]) as AttackTypeBoosterModifierType; + } + applyModifierTypeToPlayerPokemon(scene, leadPokemon, boosterModifierType); + + const encounter = scene.currentBattle.mysteryEncounter!; + encounter.setDialogueToken("itemName", boosterModifierType.name); + encounter.setDialogueToken("leadPokemon", leadPokemon.getNameToRender()); + queueEncounterMessage(scene, `${namespace}:found_item`); } } diff --git a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts index aa3bace67f0..889868519d2 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -65,16 +65,16 @@ export const FightOrFlightEncounter: MysteryEncounter = species: bossSpecies, dataSource: new PokemonData(bossPokemon), isBoss: true, - tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`); // Randomly boost 1 stat 2 stages // Cannot boost Spd, Acc, or Evasion - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [randSeedInt(4, 1)], 2)); + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randSeedInt(4, 1) ], 2)); } }], }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; // Calculate item // Waves 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER @@ -90,7 +90,7 @@ export const FightOrFlightEncounter: MysteryEncounter = let item: ModifierTypeOption | null = null; // TMs and Candy Jar excluded from possible rewards as they're too swingy in value for a singular item reward while (!item || item.type.id.includes("TM_") || item.type.id === "CANDY_JAR") { - item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0]; + item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0]; } encounter.setDialogueToken("itemName", item.type.name); encounter.misc = item; @@ -120,6 +120,7 @@ export const FightOrFlightEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -137,14 +138,14 @@ export const FightOrFlightEncounter: MysteryEncounter = // Pick battle // Pokemon will randomly boost 1 stat by 2 stages const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption; - setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false }); await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]); } ) .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) - .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically + .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES, true)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically .withDialogue({ buttonLabel: `${namespace}:option.2.label`, buttonTooltip: `${namespace}:option.2.tooltip`, @@ -159,7 +160,7 @@ export const FightOrFlightEncounter: MysteryEncounter = // Pick steal const encounter = scene.currentBattle.mysteryEncounter!; const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption; - setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false }); // Use primaryPokemon to execute the thievery const primaryPokemon = encounter.options[1].primaryPokemon!; diff --git a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts index c690faf28b7..b843a929c08 100644 --- a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts +++ b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts @@ -76,6 +76,7 @@ export const FunAndGamesEncounter: MysteryEncounter = text: `${namespace}:intro_dialogue`, }, ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -151,7 +152,7 @@ export const FunAndGamesEncounter: MysteryEncounter = }, async (scene: BattleScene) => { // Leave encounter with no rewards or exp - transitionMysteryEncounterIntroVisuals(scene, true, true); + await transitionMysteryEncounterIntroVisuals(scene, true, true); leaveEncounterWithoutBattle(scene, true); return true; } @@ -197,7 +198,7 @@ async function summonPlayerPokemon(scene: BattleScene) { const enemySpecies = getPokemonSpecies(Species.WOBBUFFET); scene.currentBattle.enemyParty = []; const wobbuffet = scene.addEnemyPokemon(enemySpecies, encounter.misc.playerPokemon.level, TrainerSlot.NONE, false); - wobbuffet.ivs = [0, 0, 0, 0, 0, 0]; + wobbuffet.ivs = [ 0, 0, 0, 0, 0, 0 ]; wobbuffet.setNature(Nature.MILD); wobbuffet.setAlpha(0); wobbuffet.setVisible(false); @@ -256,15 +257,15 @@ function handleNextTurn(scene: BattleScene) { let isHealPhase = false; if (healthRatio < 0.03) { // Grand prize - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MULTI_LENS], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MULTI_LENS ], fillRemaining: false }); resultMessageKey = `${namespace}:best_result`; } else if (healthRatio < 0.15) { // 2nd prize - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SCOPE_LENS], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SCOPE_LENS ], fillRemaining: false }); resultMessageKey = `${namespace}:great_result`; } else if (healthRatio < 0.33) { // 3rd prize - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.WIDE_LENS], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.WIDE_LENS ], fillRemaining: false }); resultMessageKey = `${namespace}:good_result`; } else { // No prize @@ -411,7 +412,7 @@ function hideShowmanIntroSprite(scene: BattleScene) { // Slide the Wobbuffet and Game over slightly scene.tweens.add({ - targets: [wobbuffet, carnivalGame], + targets: [ wobbuffet, carnivalGame ], x: "+=16", ease: "Sine.easeInOut", duration: 750 diff --git a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts index cc66bdfb4c9..376bdf0c95d 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -35,15 +35,15 @@ const WONDER_TRADE_SHINY_CHANCE = 512; const MAX_WONDER_TRADE_SHINY_CHANCE = 4096; const LEGENDARY_TRADE_POOLS = { - 1: [Species.RATTATA, Species.PIDGEY, Species.WEEDLE], - 2: [Species.SENTRET, Species.HOOTHOOT, Species.LEDYBA], - 3: [Species.POOCHYENA, Species.ZIGZAGOON, Species.TAILLOW], - 4: [Species.BIDOOF, Species.STARLY, Species.KRICKETOT], - 5: [Species.PATRAT, Species.PURRLOIN, Species.PIDOVE], - 6: [Species.BUNNELBY, Species.LITLEO, Species.SCATTERBUG], - 7: [Species.PIKIPEK, Species.YUNGOOS, Species.ROCKRUFF], - 8: [Species.SKWOVET, Species.WOOLOO, Species.ROOKIDEE], - 9: [Species.LECHONK, Species.FIDOUGH, Species.TAROUNTULA] + 1: [ Species.RATTATA, Species.PIDGEY, Species.WEEDLE ], + 2: [ Species.SENTRET, Species.HOOTHOOT, Species.LEDYBA ], + 3: [ Species.POOCHYENA, Species.ZIGZAGOON, Species.TAILLOW ], + 4: [ Species.BIDOOF, Species.STARLY, Species.KRICKETOT ], + 5: [ Species.PATRAT, Species.PURRLOIN, Species.PIDOVE ], + 6: [ Species.BUNNELBY, Species.LITLEO, Species.SCATTERBUG ], + 7: [ Species.PIKIPEK, Species.YUNGOOS, Species.ROCKRUFF ], + 8: [ Species.SKWOVET, Species.WOOLOO, Species.ROOKIDEE ], + 9: [ Species.LECHONK, Species.FIDOUGH, Species.TAROUNTULA ] }; /** Exclude Paradox mons as they aren't considered legendary/mythical */ @@ -96,6 +96,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = text: `${namespace}:intro`, } ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -387,18 +388,18 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = let item: ModifierTypeOption | null = null; // TMs excluded from possible rewards while (!item || item.type.id.includes("TM_")) { - item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0]; + item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0]; } encounter.setDialogueToken("itemName", item.type.name); - setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false }); // Remove the chosen modifier if its stacks go to 0 modifier.stackCount -= 1; if (modifier.stackCount === 0) { scene.removeModifier(modifier); } - scene.updateModifiers(true, true); + await scene.updateModifiers(true, true); // Generate a trainer name const traderName = generateRandomTraderName(); @@ -650,7 +651,7 @@ function doPokemonTradeSequence(scene: BattleScene, tradedPokemon: PlayerPokemon // addPokeballOpenParticles(scene, tradedPokemon.x, tradedPokemon.y, tradedPokemon.pokeball); scene.tweens.add({ - targets: [tradedPokemonTintSprite, tradedPokemonSprite], + targets: [ tradedPokemonTintSprite, tradedPokemonSprite ], duration: 500, ease: "Sine.easeIn", scale: 0.25, @@ -726,7 +727,7 @@ function doPokemonTradeFlyBySequence(scene: BattleScene, tradedPokemonSprite: Ph duration: FADE_DELAY, onComplete: () => { scene.tweens.add({ - targets: [receivedPokemonSprite, tradedPokemonSprite], + targets: [ receivedPokemonSprite, tradedPokemonSprite ], y: tradeBaseBg.displayWidth / 2 - 100, ease: "Cubic.easeInOut", duration: BASE_ANIM_DURATION * 3, diff --git a/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts b/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts index 27b3bdd8cf7..8e7ea52a967 100644 --- a/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts +++ b/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts @@ -10,7 +10,7 @@ import { applyDamageToPokemon } from "#app/data/mystery-encounters/utils/encount import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; -import {PokemonMove} from "#app/field/pokemon"; +import { PokemonMove } from "#app/field/pokemon"; const OPTION_1_REQUIRED_MOVE = Moves.SURF; const OPTION_2_REQUIRED_MOVE = Moves.FLY; @@ -50,6 +50,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -128,7 +129,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with * * @param scene Battle scene */ -async function handlePokemonGuidingYouPhase(scene: BattleScene) { +function handlePokemonGuidingYouPhase(scene: BattleScene) { const laprasSpecies = getPokemonSpecies(Species.LAPRAS); const { mysteryEncounter } = scene.currentBattle; diff --git a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts index af01ecbb97c..7fdd29d36a2 100644 --- a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts @@ -56,7 +56,13 @@ export const MysteriousChallengersEncounter: MysteryEncounter = // Hard difficulty trainer is another random trainer, but with AVERAGE_BALANCED config // Number of mons is based off wave: 1-20 is 2, 20-40 is 3, etc. capping at 6 after wave 100 - const hardTrainerType = scene.arena.randomTrainerType(scene.currentBattle.waveIndex); + let retries = 0; + let hardTrainerType = scene.arena.randomTrainerType(scene.currentBattle.waveIndex); + while (retries < 5 && hardTrainerType === normalTrainerType) { + // Will try to use a different trainer from the normal trainer type + hardTrainerType = scene.arena.randomTrainerType(scene.currentBattle.waveIndex); + retries++; + } const hardTemplate = new TrainerPartyCompoundTemplate( new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER, false, true), new TrainerPartyTemplate( @@ -125,6 +131,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -143,14 +150,14 @@ export const MysteriousChallengersEncounter: MysteryEncounter = // Spawn standard trainer battle with memory mushroom reward const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0]; - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM], fillRemaining: true }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM ], fillRemaining: true }); // Seed offsets to remove possibility of different trainers having exact same teams - let ret; + let initBattlePromise: Promise; scene.executeWithSeedOffset(() => { - ret = initBattleWithEnemyConfig(scene, config); + initBattlePromise = initBattleWithEnemyConfig(scene, config); }, scene.currentBattle.waveIndex * 10); - return ret; + await initBattlePromise!; } ) .withSimpleOption( @@ -168,14 +175,14 @@ export const MysteriousChallengersEncounter: MysteryEncounter = // Spawn hard fight const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1]; - setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true }); + setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], fillRemaining: true }); // Seed offsets to remove possibility of different trainers having exact same teams - let ret; + let initBattlePromise: Promise; scene.executeWithSeedOffset(() => { - ret = initBattleWithEnemyConfig(scene, config); + initBattlePromise = initBattleWithEnemyConfig(scene, config); }, scene.currentBattle.waveIndex * 100); - return ret; + await initBattlePromise!; } ) .withSimpleOption( @@ -196,14 +203,14 @@ export const MysteriousChallengersEncounter: MysteryEncounter = // To avoid player level snowballing from picking this option encounter.expMultiplier = 0.9; - setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true }); + setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT ], fillRemaining: true }); // Seed offsets to remove possibility of different trainers having exact same teams - let ret; + let initBattlePromise: Promise; scene.executeWithSeedOffset(() => { - ret = initBattleWithEnemyConfig(scene, config); + initBattlePromise = initBattleWithEnemyConfig(scene, config); }, scene.currentBattle.waveIndex * 1000); - return ret; + await initBattlePromise!; } ) .withOutroDialogue([ diff --git a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts index 9221cde0844..693d935ae17 100644 --- a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts @@ -61,6 +61,7 @@ export const MysteriousChestEncounter: MysteryEncounter = text: `${namespace}:intro`, } ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -76,12 +77,12 @@ export const MysteriousChestEncounter: MysteryEncounter = species: getPokemonSpecies(Species.GIMMIGHOUL), formIndex: 0, isBoss: true, - moveSet: [Moves.NASTY_PLOT, Moves.SHADOW_BALL, Moves.POWER_GEM, Moves.THIEF] + moveSet: [ Moves.NASTY_PLOT, Moves.SHADOW_BALL, Moves.POWER_GEM, Moves.THIEF ] } ], }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; encounter.setDialogueToken("gimmighoulName", getPokemonSpecies(Species.GIMMIGHOUL).getName()); encounter.setDialogueToken("trapPercent", TRAP_PERCENT.toString()); @@ -157,13 +158,13 @@ export const MysteriousChestEncounter: MysteryEncounter = leaveEncounterWithoutBattle(scene); } else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT) { // Choose between 2 ROGUE tier items (10%) - setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE] }); + setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE ]}); // Display result message then proceed to rewards queueEncounterMessage(scene, `${namespace}:option.1.great`); leaveEncounterWithoutBattle(scene); } else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT - MASTER_REWARDS_PERCENT) { // Choose 1 MASTER tier item (5%) - setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.MASTER] }); + setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.MASTER ]}); // Display result message then proceed to rewards queueEncounterMessage(scene, `${namespace}:option.1.amazing`); leaveEncounterWithoutBattle(scene); @@ -183,7 +184,7 @@ export const MysteriousChestEncounter: MysteryEncounter = scene.unshiftPhase(new GameOverPhase(scene)); } else { // Show which Pokemon was KOed, then start battle against Gimmighoul - transitionMysteryEncounterIntroVisuals(scene, true, true, 500); + await transitionMysteryEncounterIntroVisuals(scene, true, true, 500); setEncounterRewards(scene, { fillRemaining: true }); await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]); } diff --git a/src/data/mystery-encounters/encounters/part-timer-encounter.ts b/src/data/mystery-encounters/encounters/part-timer-encounter.ts index f7eb2f2f1b4..092d2ab2673 100644 --- a/src/data/mystery-encounters/encounters/part-timer-encounter.ts +++ b/src/data/mystery-encounters/encounters/part-timer-encounter.ts @@ -69,6 +69,7 @@ export const PartTimerEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -94,7 +95,7 @@ export const PartTimerEncounter: MysteryEncounter = // Calculation from Pokemon.calculateStats const baselineValue = Math.floor(((2 * 90 + 16) * pokemon.level) * 0.01) + 5; const percentDiff = (pokemon.getStat(Stat.SPD) - baselineValue) / baselineValue; - const moneyMultiplier = Math.min(Math.max(2.5 * (1+ percentDiff), 1), 4); + const moneyMultiplier = Math.min(Math.max(2.5 * (1 + percentDiff), 1), 4); encounter.misc = { moneyMultiplier @@ -226,7 +227,7 @@ export const PartTimerEncounter: MysteryEncounter = .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) - .withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically + .withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES, true)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically .withDialogue({ buttonLabel: `${namespace}:option.3.label`, buttonTooltip: `${namespace}:option.3.tooltip`, diff --git a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts index be5b9023eea..0ee3c57b0a2 100644 --- a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts +++ b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts @@ -23,7 +23,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounters/safariZone"; -const TRAINER_THROW_ANIMATION_TIMES = [512, 184, 768]; +const TRAINER_THROW_ANIMATION_TIMES = [ 512, 184, 768 ]; const SAFARI_MONEY_MULTIPLIER = 2; @@ -54,6 +54,7 @@ export const SafariZoneEncounter: MysteryEncounter = text: `${namespace}:intro`, }, ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -260,7 +261,7 @@ async function summonSafariPokemon(scene: BattleScene) { let enemySpecies; let pokemon; scene.executeWithSeedOffset(() => { - enemySpecies = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false)); + enemySpecies = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false)); const level = scene.currentBattle.getLevelForWave(); enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(level, true, false, scene.gameMode)); pokemon = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, false); @@ -302,13 +303,16 @@ async function summonSafariPokemon(scene: BattleScene) { scene.unshiftPhase(new SummonPhase(scene, 0, false)); encounter.setDialogueToken("pokemonName", getPokemonNameWithAffix(pokemon)); - showEncounterText(scene, getEncounterText(scene, "battle:singleWildAppeared") ?? "", null, 1500, false) - .then(() => { - const ivScannerModifier = scene.findModifier(m => m instanceof IvScannerModifier); - if (ivScannerModifier) { - scene.pushPhase(new ScanIvsPhase(scene, pokemon.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6))); - } - }); + + // TODO: If we await showEncounterText here, then the text will display without + // the wild Pokemon on screen, but if we don't await it, then the text never + // shows up and the IV scanner breaks. For now, we place the IV scanner code + // separately so that at least the IV scanner works. + + const ivScannerModifier = scene.findModifier(m => m instanceof IvScannerModifier); + if (ivScannerModifier) { + scene.pushPhase(new ScanIvsPhase(scene, pokemon.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6))); + } } function throwPokeball(scene: BattleScene, pokemon: EnemyPokemon): Promise { diff --git a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts index a8ddfc28ae9..8dd730492b1 100644 --- a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts +++ b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts @@ -21,7 +21,7 @@ import i18next from "i18next"; const namespace = "mysteryEncounters/shadyVitaminDealer"; const VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER = 1.5; -const VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER = 3.5; +const VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER = 5; /** * Shady Vitamin Dealer encounter. @@ -33,7 +33,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = .withEncounterTier(MysteryEncounterTier.COMMON) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withSceneRequirement(new MoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)) // Must have the money for at least the cheap deal - .withPrimaryPokemonHealthRatioRequirement([0.51, 1]) // At least 1 Pokemon must have above half HP + .withPrimaryPokemonHealthRatioRequirement([ 0.51, 1 ]) // At least 1 Pokemon must have above half HP .withIntroSpriteConfigs([ { spriteKey: Species.KROOKODILE.toString(), @@ -62,6 +62,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = speaker: `${namespace}:speaker`, }, ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -137,11 +138,11 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = newNature = randSeedInt(25) as Nature; } - chosenPokemon.nature = newNature; + chosenPokemon.customPokemonData.nature = newNature; encounter.setDialogueToken("newNature", getNatureName(newNature)); queueEncounterMessage(scene, `${namespace}:cheap_side_effects`); - setEncounterExp(scene, [chosenPokemon.id], 100); - chosenPokemon.updateInfo(); + setEncounterExp(scene, [ chosenPokemon.id ], 100); + await chosenPokemon.updateInfo(); }) .build() ) @@ -201,9 +202,9 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = const chosenPokemon = encounter.misc.chosenPokemon; queueEncounterMessage(scene, `${namespace}:no_bad_effects`); - setEncounterExp(scene, [chosenPokemon.id], 100); + setEncounterExp(scene, [ chosenPokemon.id ], 100); - chosenPokemon.updateInfo(); + await chosenPokemon.updateInfo(); }) .build() ) diff --git a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts index 5abd4839c0c..8ea19e1225b 100644 --- a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts +++ b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts @@ -18,7 +18,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode import { PartyHealPhase } from "#app/phases/party-heal-phase"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; import { BerryType } from "#enums/berry-type"; -import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; /** i18n namespace for the encounter */ const namespace = "mysteryEncounters/slumberingSnorlax"; @@ -60,34 +60,35 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = const pokemonConfig: EnemyPokemonConfig = { species: bossSpecies, isBoss: true, - status: [StatusEffect.SLEEP, 5], // Extra turns on timer for Snorlax's start of fight moves - moveSet: [Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT], + status: [ StatusEffect.SLEEP, 5 ], // Extra turns on timer for Snorlax's start of fight moves + moveSet: [ Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT ], modifierConfigs: [ { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType, stackCount: 2 }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType, stackCount: 2 }, ], - mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ spriteScale: 1.25 }), + customPokemonData: new CustomPokemonData({ spriteScale: 1.25 }), aiType: AiType.SMART // Required to ensure Snorlax uses Sleep Talk while it is asleep }; const config: EnemyPartyConfig = { levelAdditiveModifier: 0.5, - pokemonConfigs: [pokemonConfig], + pokemonConfigs: [ pokemonConfig ], }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; // Load animations/sfx for Snorlax fight start moves - loadCustomMovesForEncounter(scene, [Moves.SNORE]); + loadCustomMovesForEncounter(scene, [ Moves.SNORE ]); encounter.setDialogueToken("snorlaxName", getPokemonSpecies(Species.SNORLAX).getName()); return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -104,17 +105,17 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = async (scene: BattleScene) => { // Pick battle const encounter = scene.currentBattle.mysteryEncounter!; - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: true}); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.LEFTOVERS ], fillRemaining: true }); encounter.startOfBattleEffects.push( { sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.PLAYER], + targets: [ BattlerIndex.PLAYER ], move: new PokemonMove(Moves.SNORE), ignorePp: true }, { sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.PLAYER], + targets: [ BattlerIndex.PLAYER ], move: new PokemonMove(Moves.SNORE), ignorePp: true }); @@ -142,7 +143,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) - .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) + .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES, true)) .withDialogue({ buttonLabel: `${namespace}:option.3.label`, buttonTooltip: `${namespace}:option.3.tooltip`, @@ -156,7 +157,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = .withOptionPhase(async (scene: BattleScene) => { // Steal the Snorlax's Leftovers const instance = scene.currentBattle.mysteryEncounter!; - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.LEFTOVERS ], fillRemaining: false }); // Snorlax exp to Pokemon that did the stealing setEncounterExp(scene, instance.primaryPokemon!.id, getPokemonSpecies(Species.SNORLAX).baseExp); leaveEncounterWithoutBattle(scene); diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts index f685bdae2a1..e8f11f02e18 100644 --- a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -26,8 +26,8 @@ import { getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIF const namespace = "mysteryEncounters/teleportingHijinks"; const MONEY_COST_MULTIPLIER = 1.75; -const BIOME_CANDIDATES = [Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO]; -const MACHINE_INTERFACING_TYPES = [Type.ELECTRIC, Type.STEEL]; +const BIOME_CANDIDATES = [ Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO ]; +const MACHINE_INTERFACING_TYPES = [ Type.ELECTRIC, Type.STEEL ]; /** * Teleporting Hijinks encounter. @@ -38,7 +38,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TELEPORTING_HIJINKS) .withEncounterTier(MysteryEncounterTier.COMMON) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) - .withSceneRequirement(new WaveModulusRequirement([1, 2, 3], 10)) // Must be in first 3 waves after boss wave + .withSceneRequirement(new WaveModulusRequirement([ 1, 2, 3 ], 10)) // Must be in first 3 waves after boss wave .withSceneRequirement(new MoneyRequirement(0, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost .withAutoHideIntroVisuals(false) .withCatchAllowed(true) @@ -58,6 +58,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter = text: `${namespace}:intro`, } ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -145,10 +146,10 @@ export const TeleportingHijinksEncounter: MysteryEncounter = }], }; - const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.STEEL])!; - const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.ELECTRIC])!; - setEncounterRewards(scene, { guaranteedModifierTypeOptions: [magnet, metalCoat], fillRemaining: true }); - transitionMysteryEncounterIntroVisuals(scene, true, true); + const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.STEEL ])!; + const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.ELECTRIC ])!; + setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ magnet, metalCoat ], fillRemaining: true }); + await transitionMysteryEncounterIntroVisuals(scene, true, true); await initBattleWithEnemyConfig(scene, config); } ) @@ -163,7 +164,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) { // Show dialogue and transition biome await showEncounterText(scene, `${namespace}:transport`); - await Promise.all([animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene)]); + await Promise.all([ animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene) ]); scene.playBgm(); await showEncounterText(scene, `${namespace}:attacked`); @@ -175,8 +176,8 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) { // Defense/Spd buffs below wave 50, +1 to all stats otherwise const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ? - [Stat.DEF, Stat.SPDEF, Stat.SPD] : - [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD]; + [ Stat.DEF, Stat.SPDEF, Stat.SPD ] : + [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ]; const config: EnemyPartyConfig = { pokemonConfigs: [{ @@ -184,7 +185,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) { species: bossSpecies, dataSource: new PokemonData(bossPokemon), isBoss: true, - tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { queueEncounterMessage(pokemon.scene, `${namespace}:boss_enraged`); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1)); @@ -198,7 +199,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) { async function animateBiomeChange(scene: BattleScene, nextBiome: Biome) { return new Promise(resolve => { scene.tweens.add({ - targets: [scene.arenaEnemy, scene.lastEnemyTrainer], + targets: [ scene.arenaEnemy, scene.lastEnemyTrainer ], x: "+=300", duration: 2000, onComplete: () => { @@ -214,7 +215,7 @@ async function animateBiomeChange(scene: BattleScene, nextBiome: Biome) { scene.arenaPlayerTransition.setVisible(true); scene.tweens.add({ - targets: [scene.arenaPlayer, scene.arenaBgTransition, scene.arenaPlayerTransition], + targets: [ scene.arenaPlayer, scene.arenaBgTransition, scene.arenaPlayerTransition ], duration: 1000, ease: "Sine.easeInOut", alpha: (target: any) => target === scene.arenaPlayer ? 0 : 1, diff --git a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts index e4c0fdc2d98..610209f8aad 100644 --- a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts @@ -25,6 +25,7 @@ import { achvs } from "#app/system/achv"; import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { Type } from "#app/data/type"; import { getPokeballTintColor } from "#app/data/pokeball"; +import { PokemonHeldItemModifier } from "#app/modifier/modifier"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounters/theExpertPokemonBreeder"; @@ -48,29 +49,29 @@ class BreederSpeciesEvolution { } const POOL_1_POKEMON: (Species | BreederSpeciesEvolution)[][] = [ - [Species.MUNCHLAX, new BreederSpeciesEvolution(Species.SNORLAX, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.HAPPINY, new BreederSpeciesEvolution(Species.CHANSEY, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.BLISSEY, FINAL_STAGE_EVOLUTION_WAVE)], - [Species.MAGBY, new BreederSpeciesEvolution(Species.MAGMAR, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MAGMORTAR, FINAL_STAGE_EVOLUTION_WAVE)], - [Species.ELEKID, new BreederSpeciesEvolution(Species.ELECTABUZZ, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ELECTIVIRE, FINAL_STAGE_EVOLUTION_WAVE)], - [Species.RIOLU, new BreederSpeciesEvolution(Species.LUCARIO, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.BUDEW, new BreederSpeciesEvolution(Species.ROSELIA, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ROSERADE, FINAL_STAGE_EVOLUTION_WAVE)], - [Species.TOXEL, new BreederSpeciesEvolution(Species.TOXTRICITY, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.MIME_JR, new BreederSpeciesEvolution(Species.GALAR_MR_MIME, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MR_RIME, FINAL_STAGE_EVOLUTION_WAVE)] + [ Species.MUNCHLAX, new BreederSpeciesEvolution(Species.SNORLAX, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.HAPPINY, new BreederSpeciesEvolution(Species.CHANSEY, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.BLISSEY, FINAL_STAGE_EVOLUTION_WAVE) ], + [ Species.MAGBY, new BreederSpeciesEvolution(Species.MAGMAR, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MAGMORTAR, FINAL_STAGE_EVOLUTION_WAVE) ], + [ Species.ELEKID, new BreederSpeciesEvolution(Species.ELECTABUZZ, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ELECTIVIRE, FINAL_STAGE_EVOLUTION_WAVE) ], + [ Species.RIOLU, new BreederSpeciesEvolution(Species.LUCARIO, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.BUDEW, new BreederSpeciesEvolution(Species.ROSELIA, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ROSERADE, FINAL_STAGE_EVOLUTION_WAVE) ], + [ Species.TOXEL, new BreederSpeciesEvolution(Species.TOXTRICITY, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.MIME_JR, new BreederSpeciesEvolution(Species.GALAR_MR_MIME, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MR_RIME, FINAL_STAGE_EVOLUTION_WAVE) ] ]; const POOL_2_POKEMON: (Species | BreederSpeciesEvolution)[][] = [ - [Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.RAICHU, FINAL_STAGE_EVOLUTION_WAVE)], - [Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ALOLA_RAICHU, FINAL_STAGE_EVOLUTION_WAVE)], - [Species.JYNX], - [Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONLEE, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONCHAN, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONTOP, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.IGGLYBUFF, new BreederSpeciesEvolution(Species.JIGGLYPUFF, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.WIGGLYTUFF, FINAL_STAGE_EVOLUTION_WAVE)], - [Species.AZURILL, new BreederSpeciesEvolution(Species.MARILL, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.AZUMARILL, FINAL_STAGE_EVOLUTION_WAVE)], - [Species.WYNAUT, new BreederSpeciesEvolution(Species.WOBBUFFET, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.CHINGLING, new BreederSpeciesEvolution(Species.CHIMECHO, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.BONSLY, new BreederSpeciesEvolution(Species.SUDOWOODO, SECOND_STAGE_EVOLUTION_WAVE)], - [Species.MANTYKE, new BreederSpeciesEvolution(Species.MANTINE, SECOND_STAGE_EVOLUTION_WAVE)] + [ Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.RAICHU, FINAL_STAGE_EVOLUTION_WAVE) ], + [ Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ALOLA_RAICHU, FINAL_STAGE_EVOLUTION_WAVE) ], + [ Species.SMOOCHUM, new BreederSpeciesEvolution(Species.JYNX, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONLEE, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONCHAN, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONTOP, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.IGGLYBUFF, new BreederSpeciesEvolution(Species.JIGGLYPUFF, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.WIGGLYTUFF, FINAL_STAGE_EVOLUTION_WAVE) ], + [ Species.AZURILL, new BreederSpeciesEvolution(Species.MARILL, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.AZUMARILL, FINAL_STAGE_EVOLUTION_WAVE) ], + [ Species.WYNAUT, new BreederSpeciesEvolution(Species.WOBBUFFET, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.CHINGLING, new BreederSpeciesEvolution(Species.CHIMECHO, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.BONSLY, new BreederSpeciesEvolution(Species.SUDOWOODO, SECOND_STAGE_EVOLUTION_WAVE) ], + [ Species.MANTYKE, new BreederSpeciesEvolution(Species.MANTINE, SECOND_STAGE_EVOLUTION_WAVE) ] ]; /** @@ -138,7 +139,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = encounter.setDialogueToken("pokemon3Name", pokemon3.getNameToRender()); // Dialogue and egg calcs for Pokemon 1 - const [pokemon1CommonEggs, pokemon1RareEggs] = calculateEggRewardsForPokemon(pokemon1); + const [ pokemon1CommonEggs, pokemon1RareEggs ] = calculateEggRewardsForPokemon(pokemon1); let pokemon1Tooltip = getEncounterText(scene, `${namespace}:option.1.tooltip_base`)!; if (pokemon1RareEggs > 0) { const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon1RareEggs, rarity: i18next.t("egg:greatTier") }); @@ -153,7 +154,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = encounter.options[0].dialogue!.buttonTooltip = pokemon1Tooltip; // Dialogue and egg calcs for Pokemon 2 - const [pokemon2CommonEggs, pokemon2RareEggs] = calculateEggRewardsForPokemon(pokemon2); + const [ pokemon2CommonEggs, pokemon2RareEggs ] = calculateEggRewardsForPokemon(pokemon2); let pokemon2Tooltip = getEncounterText(scene, `${namespace}:option.2.tooltip_base`)!; if (pokemon2RareEggs > 0) { const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon2RareEggs, rarity: i18next.t("egg:greatTier") }); @@ -163,12 +164,12 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = if (pokemon2CommonEggs > 0) { const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon2CommonEggs, rarity: i18next.t("egg:defaultTier") }); pokemon2Tooltip += i18next.t(`${namespace}:eggs_tooltip`, { eggs: eggsText }); - encounter.setDialogueToken("pokemon1CommonEggs", eggsText); + encounter.setDialogueToken("pokemon2CommonEggs", eggsText); } encounter.options[1].dialogue!.buttonTooltip = pokemon2Tooltip; // Dialogue and egg calcs for Pokemon 3 - const [pokemon3CommonEggs, pokemon3RareEggs] = calculateEggRewardsForPokemon(pokemon3); + const [ pokemon3CommonEggs, pokemon3RareEggs ] = calculateEggRewardsForPokemon(pokemon3); let pokemon3Tooltip = getEncounterText(scene, `${namespace}:option.3.tooltip_base`)!; if (pokemon3RareEggs > 0) { const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon3RareEggs, rarity: i18next.t("egg:greatTier") }); @@ -196,6 +197,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -220,7 +222,10 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = encounter.misc.chosenPokemon = pokemon1; encounter.setDialogueToken("chosenPokemon", pokemon1.getNameToRender()); const eggOptions = getEggOptions(scene, pokemon1CommonEggs, pokemon1RareEggs); - setEncounterRewards(scene, { fillRemaining: true }, eggOptions); + setEncounterRewards(scene, + { guaranteedModifierTypeFuncs: [ modifierTypes.SOOTHE_BELL ], fillRemaining: true }, + eggOptions, + () => doPostEncounterCleanup(scene)); // Remove all Pokemon from the party except the chosen Pokemon removePokemonFromPartyAndStoreHeldItems(scene, encounter, pokemon1); @@ -244,10 +249,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = } encounter.onGameOver = onGameOver; - initBattleWithEnemyConfig(scene, config); - }) - .withPostOptionPhase(async (scene: BattleScene) => { - await doPostEncounterCleanup(scene); + await initBattleWithEnemyConfig(scene, config); }) .build() ) @@ -272,7 +274,10 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = encounter.misc.chosenPokemon = pokemon2; encounter.setDialogueToken("chosenPokemon", pokemon2.getNameToRender()); const eggOptions = getEggOptions(scene, pokemon2CommonEggs, pokemon2RareEggs); - setEncounterRewards(scene, { fillRemaining: true }, eggOptions); + setEncounterRewards(scene, + { guaranteedModifierTypeFuncs: [ modifierTypes.SOOTHE_BELL ], fillRemaining: true }, + eggOptions, + () => doPostEncounterCleanup(scene)); // Remove all Pokemon from the party except the chosen Pokemon removePokemonFromPartyAndStoreHeldItems(scene, encounter, pokemon2); @@ -296,10 +301,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = } encounter.onGameOver = onGameOver; - initBattleWithEnemyConfig(scene, config); - }) - .withPostOptionPhase(async (scene: BattleScene) => { - await doPostEncounterCleanup(scene); + await initBattleWithEnemyConfig(scene, config); }) .build() ) @@ -324,7 +326,10 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = encounter.misc.chosenPokemon = pokemon3; encounter.setDialogueToken("chosenPokemon", pokemon3.getNameToRender()); const eggOptions = getEggOptions(scene, pokemon3CommonEggs, pokemon3RareEggs); - setEncounterRewards(scene, { fillRemaining: true }, eggOptions); + setEncounterRewards(scene, + { guaranteedModifierTypeFuncs: [ modifierTypes.SOOTHE_BELL ], fillRemaining: true }, + eggOptions, + () => doPostEncounterCleanup(scene)); // Remove all Pokemon from the party except the chosen Pokemon removePokemonFromPartyAndStoreHeldItems(scene, encounter, pokemon3); @@ -348,10 +353,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = } encounter.onGameOver = onGameOver; - initBattleWithEnemyConfig(scene, config); - }) - .withPostOptionPhase(async (scene: BattleScene) => { - await doPostEncounterCleanup(scene); + await initBattleWithEnemyConfig(scene, config); }) .build() ) @@ -381,11 +383,11 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig { abilityIndex: 1, // Magic Guard shiny: false, nature: Nature.ADAMANT, - moveSet: [Moves.METEOR_MASH, Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH], - ivs: [31, 31, 31, 31, 31, 31], + moveSet: [ Moves.METEOR_MASH, Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH ], + ivs: [ 31, 31, 31, 31, 31, 31 ], modifierConfigs: [ { - modifier: generateModifierType(scene, modifierTypes.TERA_SHARD, [Type.STEEL]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.TERA_SHARD, [ Type.STEEL ]) as PokemonHeldItemModifierType, } ] } @@ -402,8 +404,8 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig { shiny: true, variant: 1, nature: Nature.MODEST, - moveSet: [Moves.MOONBLAST, Moves.MYSTICAL_FIRE, Moves.ICE_BEAM, Moves.THUNDERBOLT], - ivs: [31, 31, 31, 31, 31, 31] + moveSet: [ Moves.MOONBLAST, Moves.MYSTICAL_FIRE, Moves.ICE_BEAM, Moves.THUNDERBOLT ], + ivs: [ 31, 31, 31, 31, 31, 31 ] }, { nickname: i18next.t(`${namespace}:cleffa_3_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }), @@ -413,8 +415,8 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig { shiny: true, variant: 2, nature: Nature.BOLD, - moveSet: [Moves.TRI_ATTACK, Moves.STORED_POWER, Moves.TAKE_HEART, Moves.MOONLIGHT], - ivs: [31, 31, 31, 31, 31, 31] + moveSet: [ Moves.TRI_ATTACK, Moves.STORED_POWER, Moves.TAKE_HEART, Moves.MOONLIGHT ], + ivs: [ 31, 31, 31, 31, 31, 31 ] }); } else { // Second member from pool 1 @@ -425,12 +427,12 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig { baseConfig.pokemonConfigs!.push({ species: getPokemonSpecies(pool1Species), isBoss: false, - ivs: [31, 31, 31, 31, 31, 31] + ivs: [ 31, 31, 31, 31, 31, 31 ] }, { species: getPokemonSpecies(pool2Species), isBoss: false, - ivs: [31, 31, 31, 31, 31, 31] + ivs: [ 31, 31, 31, 31, 31, 31 ] }); } @@ -461,14 +463,18 @@ function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number] } // Maximum of 30 points - const totalPoints = Math.min(pointsFromStarterTier + pointsFromBst, 30); + let totalPoints = Math.min(pointsFromStarterTier + pointsFromBst, 30); - // 1 Rare egg for every 6 points - const numRares = Math.floor(totalPoints / 6); + // First 5 points go to Common eggs + let numCommons = Math.min(totalPoints, 5); + totalPoints -= numCommons; + + // Then, 1 Rare egg for every 4 points + const numRares = Math.floor(totalPoints / 4); // 1 Common egg for every point leftover - const numCommons = totalPoints % 6; + numCommons += totalPoints % 4; - return [numCommons, numRares]; + return [ numCommons, numRares ]; } function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number) { @@ -493,7 +499,7 @@ function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number) pulled: false, sourceType: EggSourceType.EVENT, eggDescriptor: eggDescription, - tier: EggTier.GREAT + tier: EggTier.RARE }); } } @@ -520,19 +526,19 @@ function checkAchievement(scene: BattleScene) { } } -async function restorePartyAndHeldItems(scene: BattleScene) { +function restorePartyAndHeldItems(scene: BattleScene) { const encounter = scene.currentBattle.mysteryEncounter!; // Restore original party scene.getParty().push(...encounter.misc.originalParty); // Restore held items const originalHeldItems = encounter.misc.originalPartyHeldItems; - originalHeldItems.forEach(pokemonHeldItemsList => { + originalHeldItems.forEach((pokemonHeldItemsList: PokemonHeldItemModifier[]) => { pokemonHeldItemsList.forEach(heldItem => { scene.addModifier(heldItem, true, false, false, true); }); }); - await scene.updateModifiers(true); + scene.updateModifiers(true); } function onGameOver(scene: BattleScene) { @@ -608,13 +614,13 @@ function onGameOver(scene: BattleScene) { return false; } -async function doPostEncounterCleanup(scene: BattleScene) { +function doPostEncounterCleanup(scene: BattleScene) { const encounter = scene.currentBattle.mysteryEncounter!; if (!encounter.misc.encounterFailed) { // Give achievement if in Space biome checkAchievement(scene); // Give 20 friendship to the chosen pokemon encounter.misc.chosenPokemon.addFriendship(FRIENDSHIP_ADDED); - await restorePartyAndHeldItems(scene); + restorePartyAndHeldItems(scene); } } diff --git a/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts index 5486c130a28..95f359547e4 100644 --- a/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts @@ -53,18 +53,19 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = speaker: `${namespace}:speaker`, }, ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) .withOnInit((scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter!; - let species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false)); + let species = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false)); let tries = 0; // Reroll any species that don't have HAs while ((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) && tries < 5) { - species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false)); + species = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false)); tries++; } diff --git a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts index bd99c8babf7..397d2af9522 100644 --- a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts @@ -14,7 +14,7 @@ import { BattlerIndex } from "#app/battle"; import { BattlerTagType } from "#enums/battler-tag-type"; import { BerryType } from "#enums/berry-type"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; -import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { Stat } from "#enums/stat"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; @@ -79,44 +79,45 @@ export const TheStrongStuffEncounter: MysteryEncounter = species: getPokemonSpecies(Species.SHUCKLE), isBoss: true, bossSegments: 5, - mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ spriteScale: 1.25 }), + customPokemonData: new CustomPokemonData({ spriteScale: 1.25 }), nature: Nature.BOLD, - moveSet: [Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER], + moveSet: [ Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER ], modifierConfigs: [ { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.APICOT]) as PokemonHeldItemModifierType + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.APICOT ]) as PokemonHeldItemModifierType }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ]) as PokemonHeldItemModifierType }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType, stackCount: 2 } ], - tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { queueEncounterMessage(pokemon.scene, `${namespace}:option.2.stat_boost`); - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.DEF, Stat.SPDEF], 2)); + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.DEF, Stat.SPDEF ], 2)); } } ], }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; - loadCustomMovesForEncounter(scene, [Moves.GASTRO_ACID, Moves.STEALTH_ROCK]); + loadCustomMovesForEncounter(scene, [ Moves.GASTRO_ACID, Moves.STEALTH_ROCK ]); encounter.setDialogueToken("shuckleName", getPokemonSpecies(Species.SHUCKLE).getName()); return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -184,23 +185,23 @@ export const TheStrongStuffEncounter: MysteryEncounter = async (scene: BattleScene) => { // Pick battle const encounter = scene.currentBattle.mysteryEncounter!; - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SOUL_DEW], fillRemaining: true }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SOUL_DEW ], fillRemaining: true }); encounter.startOfBattleEffects.push( { sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.PLAYER], + targets: [ BattlerIndex.PLAYER ], move: new PokemonMove(Moves.GASTRO_ACID), ignorePp: true }, { sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.PLAYER], + targets: [ BattlerIndex.PLAYER ], move: new PokemonMove(Moves.STEALTH_ROCK), ignorePp: true }); encounter.dialogue.outro = []; - transitionMysteryEncounterIntroVisuals(scene, true, true, 500); + await transitionMysteryEncounterIntroVisuals(scene, true, true, 500); await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]); } ) diff --git a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts index 9e813800b59..bf322802f81 100644 --- a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts @@ -94,6 +94,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -110,8 +111,8 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = }, async (scene: BattleScene) => { // Spawn 5 trainer battles back to back with Macho Brace in rewards - scene.currentBattle.mysteryEncounter!.doContinueEncounter = (scene: BattleScene) => { - return endTrainerBattleAndShowDialogue(scene); + scene.currentBattle.mysteryEncounter!.doContinueEncounter = async (scene: BattleScene) => { + await endTrainerBattleAndShowDialogue(scene); }; await transitionMysteryEncounterIntroVisuals(scene, true, false); await spawnNextTrainerOrEndEncounter(scene); @@ -131,7 +132,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = async (scene: BattleScene) => { // Refuse the challenge, they full heal the party and give the player a Rarer Candy scene.unshiftPhase(new PartyHealPhase(scene, true)); - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.RARER_CANDY], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.RARER_CANDY ], fillRemaining: false }); leaveEncounterWithoutBattle(scene); } ) @@ -154,7 +155,7 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) { scene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in const machoBrace = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!; machoBrace.type.tier = ModifierTier.MASTER; - setEncounterRewards(scene, { guaranteedModifierTypeOptions: [machoBrace], fillRemaining: false }); + setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ machoBrace ], fillRemaining: false }); encounter.doContinueEncounter = undefined; leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.NO_BATTLE); } else { @@ -232,7 +233,7 @@ function getVictorTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 0, // Guts nature: Nature.ADAMANT, - moveSet: [Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK], + moveSet: [ Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK ], modifierConfigs: [ { modifier: generateModifierType(scene, modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType, @@ -250,7 +251,7 @@ function getVictorTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 1, // Guts nature: Nature.ADAMANT, - moveSet: [Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH], + moveSet: [ Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH ], modifierConfigs: [ { modifier: generateModifierType(scene, modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType, @@ -276,7 +277,7 @@ function getVictoriaTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 0, // Natural Cure nature: Nature.CALM, - moveSet: [Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER], + moveSet: [ Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER ], modifierConfigs: [ { modifier: generateModifierType(scene, modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType, @@ -294,15 +295,15 @@ function getVictoriaTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, formIndex: 1, nature: Nature.TIMID, - moveSet: [Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP], + moveSet: [ Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP ], modifierConfigs: [ { - modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.PSYCHIC]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.PSYCHIC ]) as PokemonHeldItemModifierType, stackCount: 1, isTransferable: false }, { - modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FAIRY]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.FAIRY ]) as PokemonHeldItemModifierType, stackCount: 1, isTransferable: false } @@ -321,15 +322,15 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 3, // Lightning Rod nature: Nature.ADAMANT, - moveSet: [Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST], + moveSet: [ Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST ], modifierConfigs: [ { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType, stackCount: 2, isTransferable: false }, { - modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.HP ]) as PokemonHeldItemModifierType, stackCount: 4, isTransferable: false } @@ -340,10 +341,10 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 1, // Poison Heal nature: Nature.JOLLY, - moveSet: [Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH], + moveSet: [ Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH ], modifierConfigs: [ { - modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.HP ]) as PokemonHeldItemModifierType, stackCount: 4, isTransferable: false }, @@ -358,7 +359,7 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, formIndex: 1, nature: Nature.CALM, - moveSet: [Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT], + moveSet: [ Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT ], modifierConfigs: [ { modifier: generateModifierType(scene, modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType, @@ -380,7 +381,7 @@ function getVickyTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, formIndex: 1, nature: Nature.IMPISH, - moveSet: [Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH], + moveSet: [ Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH ], modifierConfigs: [ { modifier: generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType, @@ -401,10 +402,10 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 0, // Soundproof nature: Nature.MODEST, - moveSet: [Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE], + moveSet: [ Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE ], modifierConfigs: [ { - modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.SPD]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.SPD ]) as PokemonHeldItemModifierType, stackCount: 2, isTransferable: false } @@ -415,50 +416,50 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 2, // Gluttony nature: Nature.QUIET, - moveSet: [Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE], + moveSet: [ Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE ], modifierConfigs: [ { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.APICOT]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.APICOT ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.STARF]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.STARF ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SALAC]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SALAC ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LANSAT]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LANSAT ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LIECHI]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LIECHI ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.PETAYA]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.PETAYA ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType, stackCount: 2, }, { - modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LEPPA]) as PokemonHeldItemModifierType, + modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LEPPA ]) as PokemonHeldItemModifierType, stackCount: 2, } ] @@ -468,7 +469,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 2, // Tangled Feet nature: Nature.JOLLY, - moveSet: [Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF], + moveSet: [ Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF ], modifierConfigs: [ { modifier: generateModifierType(scene, modifierTypes.KINGS_ROCK) as PokemonHeldItemModifierType, @@ -482,7 +483,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, formIndex: 1, nature: Nature.BOLD, - moveSet: [Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT], + moveSet: [ Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT ], modifierConfigs: [ { modifier: generateModifierType(scene, modifierTypes.WIDE_LENS) as PokemonHeldItemModifierType, @@ -496,7 +497,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig { isBoss: false, abilityIndex: 0, // Sheer Force nature: Nature.IMPISH, - moveSet: [Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE], + moveSet: [ Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE ], modifierConfigs: [ { modifier: generateModifierType(scene, modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType, diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index ff993f339cb..03341a713f2 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -37,6 +37,7 @@ export const TrainingSessionEncounter: MysteryEncounter = .withScenePartySizeRequirement(2, 6, true) // Must have at least 2 unfainted pokemon in party .withFleeAllowed(false) .withHideWildIntroMessage(true) + .withPreventGameStatsUpdates(true) // Do not count the Pokemon as seen or defeated since it is ours .withIntroSpriteConfigs([ { spriteKey: "training_session_gear", @@ -52,6 +53,7 @@ export const TrainingSessionEncounter: MysteryEncounter = text: `${namespace}:intro`, } ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -161,7 +163,7 @@ export const TrainingSessionEncounter: MysteryEncounter = setEncounterRewards(scene, { fillRemaining: true }, undefined, onBeforeRewardsPhase); - return initBattleWithEnemyConfig(scene, config); + await initBattleWithEnemyConfig(scene, config); }) .build() ) @@ -237,7 +239,7 @@ export const TrainingSessionEncounter: MysteryEncounter = setEncounterRewards(scene, { fillRemaining: true }, undefined, onBeforeRewardsPhase); - return initBattleWithEnemyConfig(scene, config); + await initBattleWithEnemyConfig(scene, config); }) .build() ) @@ -350,7 +352,7 @@ export const TrainingSessionEncounter: MysteryEncounter = setEncounterRewards(scene, { fillRemaining: true }, undefined, onBeforeRewardsPhase); - return initBattleWithEnemyConfig(scene, config); + await initBattleWithEnemyConfig(scene, config); }) .build() ) diff --git a/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts b/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts index 9673924e6d1..d3c16ce2122 100644 --- a/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts +++ b/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts @@ -54,6 +54,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = text: `${namespace}:intro`, }, ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -67,17 +68,17 @@ export const TrashToTreasureEncounter: MysteryEncounter = isBoss: true, formIndex: 1, // Gmax bossSegmentModifier: 1, // +1 Segment from normal - moveSet: [Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH] + moveSet: [ Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH ] }; const config: EnemyPartyConfig = { - levelAdditiveModifier: 1, - pokemonConfigs: [pokemonConfig], + levelAdditiveModifier: 0.5, + pokemonConfigs: [ pokemonConfig ], disableSwitch: true }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; // Load animations/sfx for Garbodor fight start moves - loadCustomMovesForEncounter(scene, [Moves.TOXIC, Moves.AMNESIA]); + loadCustomMovesForEncounter(scene, [ Moves.TOXIC, Moves.AMNESIA ]); scene.loadSe("PRSFX- Dig2", "battle_anims", "PRSFX- Dig2.wav"); scene.loadSe("PRSFX- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav"); @@ -104,10 +105,10 @@ export const TrashToTreasureEncounter: MysteryEncounter = }) .withOptionPhase(async (scene: BattleScene) => { // Gain 2 Leftovers and 2 Shell Bell - transitionMysteryEncounterIntroVisuals(scene); + await transitionMysteryEncounterIntroVisuals(scene); await tryApplyDigRewardItems(scene); - const blackSludge = generateModifierType(scene, modifierTypes.MYSTERY_ENCOUNTER_BLACK_SLUDGE, [SHOP_ITEM_COST_MULTIPLIER]); + const blackSludge = generateModifierType(scene, modifierTypes.MYSTERY_ENCOUNTER_BLACK_SLUDGE, [ SHOP_ITEM_COST_MULTIPLIER ]); const modifier = blackSludge?.newModifier(); if (modifier) { await scene.addModifier(modifier, false, false, false, true); @@ -135,21 +136,21 @@ export const TrashToTreasureEncounter: MysteryEncounter = // Investigate garbage, battle Gmax Garbodor scene.setFieldScale(0.75); await showEncounterText(scene, `${namespace}:option.2.selected_2`); - transitionMysteryEncounterIntroVisuals(scene); + await transitionMysteryEncounterIntroVisuals(scene); const encounter = scene.currentBattle.mysteryEncounter!; - setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true }); + setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT ], fillRemaining: true }); encounter.startOfBattleEffects.push( { sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.PLAYER], + targets: [ BattlerIndex.PLAYER ], move: new PokemonMove(Moves.TOXIC), ignorePp: true }, { sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.ENEMY], + targets: [ BattlerIndex.ENEMY ], move: new PokemonMove(Moves.AMNESIA), ignorePp: true }); @@ -221,7 +222,7 @@ async function tryApplyDigRewardItems(scene: BattleScene) { await showEncounterText(scene, i18next.t("battle:rewardGainCount", { modifierName: shellBell.name, count: 2 }), null, undefined, true); } -async function doGarbageDig(scene: BattleScene) { +function doGarbageDig(scene: BattleScene) { scene.playSound("battle_anims/PRSFX- Dig2"); scene.time.delayedCall(SOUND_EFFECT_WAIT_TIME, () => { scene.playSound("battle_anims/PRSFX- Dig2"); diff --git a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts index d06720400c2..b7ce3bab48c 100644 --- a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts +++ b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts @@ -74,8 +74,8 @@ export const UncommonBreedEncounter: MysteryEncounter = // Defense/Spd buffs below wave 50, +1 to all stats otherwise const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ? - [Stat.DEF, Stat.SPDEF, Stat.SPD] : - [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD]; + [ Stat.DEF, Stat.SPDEF, Stat.SPD ] : + [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ]; const config: EnemyPartyConfig = { pokemonConfigs: [{ @@ -83,14 +83,14 @@ export const UncommonBreedEncounter: MysteryEncounter = species: species, dataSource: new PokemonData(pokemon), isBoss: false, - tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1)); } }], }; - encounter.enemyPartyConfigs = [config]; + encounter.enemyPartyConfigs = [ config ]; const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(pokemon); encounter.spriteConfigs = [ @@ -125,6 +125,7 @@ export const UncommonBreedEncounter: MysteryEncounter = scene.time.delayedCall(500, () => scene.playSound("battle_anims/PRSFX- Spotlight2")); return true; }) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) @@ -152,7 +153,7 @@ export const UncommonBreedEncounter: MysteryEncounter = encounter.startOfBattleEffects.push( { sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [target], + targets: [ target ], move: pokemonMove, ignorePp: true }); @@ -181,7 +182,7 @@ export const UncommonBreedEncounter: MysteryEncounter = // Remove 4 random berries from player's party // Get all player berry items, remove from party, and store reference - const berryItems: BerryModifier[]= scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[]; + const berryItems: BerryModifier[] = scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[]; for (let i = 0; i < 4; i++) { const index = randSeedInt(berryItems.length); const randBerry = berryItems[index]; @@ -209,7 +210,7 @@ export const UncommonBreedEncounter: MysteryEncounter = .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) - .withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically + .withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES, true)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically .withDialogue({ buttonLabel: `${namespace}:option.3.label`, buttonTooltip: `${namespace}:option.3.tooltip`, diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 1e68a894bc4..2ecba6ce658 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -4,23 +4,30 @@ import { Species } from "#enums/species"; import BattleScene from "#app/battle-scene"; import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; -import { leaveEncounterWithoutBattle, setEncounterRewards, } from "../utils/encounter-phase-utils"; +import { EnemyPartyConfig, EnemyPokemonConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, } from "../utils/encounter-phase-utils"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; -import { PlayerPokemon, PokemonMove } from "#app/field/pokemon"; +import Pokemon, { PlayerPokemon, PokemonMove } from "#app/field/pokemon"; import { IntegerHolder, isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils"; import PokemonSpecies, { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species"; import { HiddenAbilityRateBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier"; import { achvs } from "#app/system/achv"; -import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import i18next from "#app/plugins/i18n"; import { doPokemonTransformationSequence, TransformationScreenPosition } from "#app/data/mystery-encounters/utils/encounter-transformation-sequence"; import { getLevelTotalExp } from "#app/data/exp"; import { Stat } from "#enums/stat"; -import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; import { Challenges } from "#enums/challenges"; +import { ModifierTier } from "#app/modifier/modifier-tier"; +import { PlayerGender } from "#enums/player-gender"; +import { TrainerType } from "#enums/trainer-type"; +import PokemonData from "#app/system/pokemon-data"; +import { Nature } from "#enums/nature"; +import HeldModifierConfig from "#app/interfaces/held-modifier-config"; +import { trainerConfigs, TrainerPartyTemplate } from "#app/data/trainer-config"; +import { PartyMemberStrength } from "#enums/party-member-strength"; /** i18n namespace for encounter */ const namespace = "mysteryEncounters/weirdDream"; @@ -80,21 +87,22 @@ const EXCLUDED_TRANSFORMATION_SPECIES = [ const SUPER_LEGENDARY_BST_THRESHOLD = 600; const NON_LEGENDARY_BST_THRESHOLD = 570; -const GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD = 450; + +const OLD_GATEAU_STATS_UP = 20; /** 0-100 */ -const PERCENT_LEVEL_LOSS_ON_REFUSE = 12.5; +const PERCENT_LEVEL_LOSS_ON_REFUSE = 10; /** * Value ranges of the resulting species BST transformations after adding values to original species * 2 Pokemon in the party use this range */ -const HIGH_BST_TRANSFORM_BASE_VALUES: [number, number] = [90, 110]; +const HIGH_BST_TRANSFORM_BASE_VALUES: [number, number] = [ 90, 110 ]; /** * Value ranges of the resulting species BST transformations after adding values to original species * All remaining Pokemon in the party use this range */ -const STANDARD_BST_TRANSFORM_BASE_VALUES: [number, number] = [40, 50]; +const STANDARD_BST_TRANSFORM_BASE_VALUES: [number, number] = [ 40, 50 ]; /** * Weird Dream encounter. @@ -105,7 +113,8 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.WEIRD_DREAM) .withEncounterTier(MysteryEncounterTier.ROGUE) .withDisallowedChallenges(Challenges.SINGLE_TYPE, Challenges.SINGLE_GENERATION) - .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) + // TODO: should reset minimum wave to 10 when there are more Rogue tiers in pool. Matching Dark Deal minimum for now. + .withSceneWaveRangeRequirement(30, 140) .withIntroSpriteConfigs([ { spriteKey: "weird_dream_woman", @@ -125,11 +134,21 @@ export const WeirdDreamEncounter: MysteryEncounter = text: `${namespace}:intro_dialogue`, }, ]) + .setLocalizationKey(`${namespace}`) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) .withQuery(`${namespace}:query`) .withOnInit((scene: BattleScene) => { scene.loadBgm("mystery_encounter_weird_dream", "mystery_encounter_weird_dream.mp3"); + + // Calculate all the newly transformed Pokemon and begin asset load + const teamTransformations = getTeamTransformations(scene); + const loadAssets = teamTransformations.map(t => (t.newPokemon as PlayerPokemon).loadAssets()); + scene.currentBattle.mysteryEncounter!.misc = { + teamTransformations, + loadAssets + }; + return true; }) .withOnVisualsStart((scene: BattleScene) => { @@ -155,13 +174,10 @@ export const WeirdDreamEncounter: MysteryEncounter = doShowDreamBackground(scene); }); - // Calculate all the newly transformed Pokemon and begin asset load - const teamTransformations = getTeamTransformations(scene); - const loadAssets = teamTransformations.map(t => (t.newPokemon as PlayerPokemon).loadAssets()); - scene.currentBattle.mysteryEncounter!.misc = { - teamTransformations, - loadAssets - }; + for (const transformation of scene.currentBattle.mysteryEncounter!.misc.teamTransformations) { + scene.removePokemonFromPlayerParty(transformation.previousPokemon, false); + scene.getParty().push(transformation.newPokemon); + } }) .withOptionPhase(async (scene: BattleScene) => { // Starts cutscene dialogue, but does not await so that cutscene plays as player goes through dialogue @@ -192,7 +208,7 @@ export const WeirdDreamEncounter: MysteryEncounter = await showEncounterText(scene, `${namespace}:option.1.dream_complete`); await doNewTeamPostProcess(scene, transformations); - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT]}); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT, modifierTypes.MINT ], fillRemaining: false }); leaveEncounterWithoutBattle(scene, true); }) .build() @@ -208,7 +224,88 @@ export const WeirdDreamEncounter: MysteryEncounter = ], }, async (scene: BattleScene) => { - // Reduce party levels by 20% + // Battle your "future" team for some item rewards + const transformations: PokemonTransformation[] = scene.currentBattle.mysteryEncounter!.misc.teamTransformations; + + // Uses the pokemon that player's party would have transformed into + const enemyPokemonConfigs: EnemyPokemonConfig[] = []; + for (const transformation of transformations) { + const newPokemon = transformation.newPokemon; + const previousPokemon = transformation.previousPokemon; + + await postProcessTransformedPokemon(scene, previousPokemon, newPokemon, newPokemon.species.getRootSpeciesId(), true); + + const dataSource = new PokemonData(newPokemon); + dataSource.player = false; + + // Copy held items to new pokemon + const newPokemonHeldItemConfigs: HeldModifierConfig[] = []; + for (const item of transformation.heldItems) { + newPokemonHeldItemConfigs.push({ + modifier: item.clone() as PokemonHeldItemModifier, + stackCount: item.getStackCount(), + isTransferable: false + }); + } + // Any pokemon that is below 570 BST gets +20 permanent BST to 3 stats + if (shouldGetOldGateau(newPokemon)) { + const stats = getOldGateauBoostedStats(newPokemon); + newPokemonHeldItemConfigs.push({ + modifier: generateModifierType(scene, modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU, [ OLD_GATEAU_STATS_UP, stats ]) as PokemonHeldItemModifierType, + stackCount: 1, + isTransferable: false + }); + } + + const enemyConfig: EnemyPokemonConfig = { + species: transformation.newSpecies, + isBoss: newPokemon.getSpeciesForm().getBaseStatTotal() > NON_LEGENDARY_BST_THRESHOLD, + level: previousPokemon.level, + dataSource: dataSource, + modifierConfigs: newPokemonHeldItemConfigs + }; + + enemyPokemonConfigs.push(enemyConfig); + } + + const genderIndex = scene.gameData.gender ?? PlayerGender.UNSET; + const trainerConfig = trainerConfigs[genderIndex === PlayerGender.FEMALE ? TrainerType.FUTURE_SELF_F : TrainerType.FUTURE_SELF_M].clone(); + trainerConfig.setPartyTemplates(new TrainerPartyTemplate(transformations.length, PartyMemberStrength.STRONG)); + const enemyPartyConfig: EnemyPartyConfig = { + trainerConfig: trainerConfig, + pokemonConfigs: enemyPokemonConfigs, + female: genderIndex === PlayerGender.FEMALE + }; + + const onBeforeRewards = () => { + // Before battle rewards, unlock the passive on a pokemon in the player's team for the rest of the run (not permanently) + // One random pokemon will get its passive unlocked + const passiveDisabledPokemon = scene.getParty().filter(p => !p.passive); + if (passiveDisabledPokemon?.length > 0) { + const enablePassiveMon = passiveDisabledPokemon[randSeedInt(passiveDisabledPokemon.length)]; + enablePassiveMon.passive = true; + enablePassiveMon.updateInfo(true); + } + }; + + setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], fillRemaining: false }, undefined, onBeforeRewards); + + await showEncounterText(scene, `${namespace}:option.2.selected_2`, null, undefined, true); + await initBattleWithEnemyConfig(scene, enemyPartyConfig); + } + ) + .withSimpleOption( + { + buttonLabel: `${namespace}:option.3.label`, + buttonTooltip: `${namespace}:option.3.tooltip`, + selected: [ + { + text: `${namespace}:option.3.selected`, + }, + ], + }, + async (scene: BattleScene) => { + // Leave, reduce party levels by 10% for (const pokemon of scene.getParty()) { pokemon.level = Math.max(Math.ceil((100 - PERCENT_LEVEL_LOSS_ON_REFUSE) / 100 * pokemon.level), 1); pokemon.exp = getLevelTotalExp(pokemon.level, pokemon.species.growthRate); @@ -234,7 +331,7 @@ interface PokemonTransformation { function getTeamTransformations(scene: BattleScene): PokemonTransformation[] { const party = scene.getParty(); // Removes all pokemon from the party - const alreadyUsedSpecies: PokemonSpecies[] = []; + const alreadyUsedSpecies: PokemonSpecies[] = party.map(p => p.species); const pokemonTransformations: PokemonTransformation[] = party.map(p => { return { previousPokemon: p @@ -249,11 +346,11 @@ function getTeamTransformations(scene: BattleScene): PokemonTransformation[] { // First, roll 2 of the party members to new Pokemon at a +90 to +110 BST difference // Then, roll the remainder of the party members at a +40 to +50 BST difference const numPokemon = party.length; + const removedPokemon = randSeedShuffle(party.slice(0)); for (let i = 0; i < numPokemon; i++) { - const removed = party[randSeedInt(party.length)]; + const removed = removedPokemon[i]; const index = pokemonTransformations.findIndex(p => p.previousPokemon.id === removed.id); pokemonTransformations[index].heldItems = removed.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier)); - scene.removePokemonFromPlayerParty(removed, false); const bst = removed.calculateBaseStats().reduce((a, b) => a + b, 0); let newBstRange: [number, number]; @@ -275,14 +372,13 @@ function getTeamTransformations(scene: BattleScene): PokemonTransformation[] { pokemonTransformations[index].newSpecies = newSpecies; + console.log("New species: " + JSON.stringify(newSpecies)); alreadyUsedSpecies.push(newSpecies); } for (const transformation of pokemonTransformations) { const newAbilityIndex = randSeedInt(transformation.newSpecies.getAbilityCount()); - const newPlayerPokemon = scene.addPlayerPokemon(transformation.newSpecies, transformation.previousPokemon.level, newAbilityIndex, undefined); - transformation.newPokemon = newPlayerPokemon; - scene.getParty().push(newPlayerPokemon); + transformation.newPokemon = scene.addPlayerPokemon(transformation.newSpecies, transformation.previousPokemon.level, newAbilityIndex, undefined); } return pokemonTransformations; @@ -295,109 +391,20 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon const newPokemon = transformation.newPokemon; const speciesRootForm = newPokemon.species.getRootSpeciesId(); - // Roll HA a second time - if (newPokemon.species.abilityHidden) { - const hiddenIndex = newPokemon.species.ability2 ? 2 : 1; - if (newPokemon.abilityIndex < hiddenIndex) { - const hiddenAbilityChance = new IntegerHolder(256); - scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); - - const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value); - - if (hasHiddenAbility) { - newPokemon.abilityIndex = hiddenIndex; - } - } + if (await postProcessTransformedPokemon(scene, previousPokemon, newPokemon, speciesRootForm)) { + atLeastOneNewStarter = true; } - // Roll IVs a second time - newPokemon.ivs = newPokemon.ivs.map(iv => { - const newValue = randSeedInt(31); - return newValue > iv ? newValue : iv; - }); - - // For pokemon at/below 570 BST or any shiny pokemon, unlock it permanently as if you had caught it - if (newPokemon.getSpeciesForm().getBaseStatTotal() <= NON_LEGENDARY_BST_THRESHOLD || newPokemon.isShiny()) { - if (newPokemon.getSpeciesForm().abilityHidden && newPokemon.abilityIndex === newPokemon.getSpeciesForm().getAbilityCount() - 1) { - scene.validateAchv(achvs.HIDDEN_ABILITY); - } - - if (newPokemon.species.subLegendary) { - scene.validateAchv(achvs.CATCH_SUB_LEGENDARY); - } - - if (newPokemon.species.legendary) { - scene.validateAchv(achvs.CATCH_LEGENDARY); - } - - if (newPokemon.species.mythical) { - scene.validateAchv(achvs.CATCH_MYTHICAL); - } - - scene.gameData.updateSpeciesDexIvs(newPokemon.species.getRootSpeciesId(true), newPokemon.ivs); - const newStarterUnlocked = await scene.gameData.setPokemonCaught(newPokemon, true, false, false); - if (newStarterUnlocked) { - atLeastOneNewStarter = true; - await showEncounterText(scene, i18next.t("battle:addedAsAStarter", { pokemonName: getPokemonSpecies(speciesRootForm).getName() })); - } - } - - // If the previous pokemon had pokerus, transfer to new pokemon - newPokemon.pokerus = previousPokemon.pokerus; - - // Transfer previous Pokemon's luck value - newPokemon.luck = previousPokemon.getLuck(); - - // If the previous pokemon had higher IVs, override to those (after updating dex IVs > prevents perfect 31s on a new unlock) - newPokemon.ivs = newPokemon.ivs.map((iv, index) => { - return previousPokemon.ivs[index] > iv ? previousPokemon.ivs[index] : iv; - }); - - // For pokemon that the player owns (including ones just caught), gain a candy - if (!!scene.gameData.dexData[speciesRootForm].caughtAttr) { - scene.gameData.addStarterCandy(getPokemonSpecies(speciesRootForm), 1); - } - - // Set the moveset of the new pokemon to be the same as previous, but with 1 egg move and 1 (attempted) STAB move of the new species - newPokemon.generateAndPopulateMoveset(); - // Store a copy of a "standard" generated moveset for the new pokemon, will be used later for finding a favored move - const newPokemonGeneratedMoveset = newPokemon.moveset; - - newPokemon.moveset = previousPokemon.moveset; - - const newEggMoveIndex = await addEggMoveToNewPokemonMoveset(scene, newPokemon, speciesRootForm); - - // Try to add a favored STAB move (might fail if Pokemon already knows a bunch of moves from newPokemonGeneratedMoveset) - addFavoredMoveToNewPokemonMoveset(newPokemon, newPokemonGeneratedMoveset, newEggMoveIndex); - - // Randomize the second type of the pokemon - // If the pokemon does not normally have a second type, it will gain 1 - const newTypes = [newPokemon.getTypes()[0]]; - let newType = randSeedInt(18) as Type; - while (newType === newTypes[0]) { - newType = randSeedInt(18) as Type; - } - newTypes.push(newType); - if (!newPokemon.mysteryEncounterPokemonData) { - newPokemon.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(); - } - newPokemon.mysteryEncounterPokemonData.types = newTypes; - + // Copy old items to new pokemon for (const item of transformation.heldItems) { item.pokemonId = newPokemon.id; await scene.addModifier(item, false, false, false, true); } - - // Any pokemon that is at or below 450 BST gets +20 permanent BST to 3 stats: HP (halved, +10), lowest of Atk/SpAtk, and lowest of Def/SpDef - if (newPokemon.getSpeciesForm().getBaseStatTotal() <= GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD) { - const stats: Stat[] = [Stat.HP]; - const baseStats = newPokemon.getSpeciesForm().baseStats.slice(0); - // Attack or SpAtk - stats.push(baseStats[Stat.ATK] < baseStats[Stat.SPATK] ? Stat.ATK : Stat.SPATK); - // Def or SpDef - stats.push(baseStats[Stat.DEF] < baseStats[Stat.SPDEF] ? Stat.DEF : Stat.SPDEF); + // Any pokemon that is below 570 BST gets +20 permanent BST to 3 stats + if (shouldGetOldGateau(newPokemon)) { + const stats = getOldGateauBoostedStats(newPokemon); const modType = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU() - .generateType(scene.getParty(), [20, stats]) + .generateType(scene.getParty(), [ OLD_GATEAU_STATS_UP, stats ]) ?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU); const modifier = modType?.newModifier(newPokemon); if (modifier) { @@ -405,9 +412,6 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon } } - // Enable passive if previous had it - newPokemon.passive = previousPokemon.passive; - newPokemon.calculateStats(); await newPokemon.updateInfo(); } @@ -426,6 +430,138 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon } } +/** + * Applies special changes to the newly transformed pokemon, such as passing previous moves, gaining egg moves, etc. + * Returns whether the transformed pokemon unlocks a new starter for the player. + * @param scene + * @param previousPokemon + * @param newPokemon + * @param speciesRootForm + * @param forBattle Default `false`. If false, will perform achievements and dex unlocks for the player. + */ +async function postProcessTransformedPokemon(scene: BattleScene, previousPokemon: PlayerPokemon, newPokemon: PlayerPokemon, speciesRootForm: Species, forBattle: boolean = false): Promise { + let isNewStarter = false; + // Roll HA a second time + if (newPokemon.species.abilityHidden) { + const hiddenIndex = newPokemon.species.ability2 ? 2 : 1; + if (newPokemon.abilityIndex < hiddenIndex) { + const hiddenAbilityChance = new IntegerHolder(256); + scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); + + const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value); + + if (hasHiddenAbility) { + newPokemon.abilityIndex = hiddenIndex; + } + } + } + + // Roll IVs a second time + newPokemon.ivs = newPokemon.ivs.map(iv => { + const newValue = randSeedInt(31); + return newValue > iv ? newValue : iv; + }); + + // Roll a neutral nature + newPokemon.nature = [ Nature.HARDY, Nature.DOCILE, Nature.BASHFUL, Nature.QUIRKY, Nature.SERIOUS ][randSeedInt(5)]; + + // For pokemon at/below 570 BST or any shiny pokemon, unlock it permanently as if you had caught it + if (!forBattle && (newPokemon.getSpeciesForm().getBaseStatTotal() <= NON_LEGENDARY_BST_THRESHOLD || newPokemon.isShiny())) { + if (newPokemon.getSpeciesForm().abilityHidden && newPokemon.abilityIndex === newPokemon.getSpeciesForm().getAbilityCount() - 1) { + scene.validateAchv(achvs.HIDDEN_ABILITY); + } + + if (newPokemon.species.subLegendary) { + scene.validateAchv(achvs.CATCH_SUB_LEGENDARY); + } + + if (newPokemon.species.legendary) { + scene.validateAchv(achvs.CATCH_LEGENDARY); + } + + if (newPokemon.species.mythical) { + scene.validateAchv(achvs.CATCH_MYTHICAL); + } + + scene.gameData.updateSpeciesDexIvs(newPokemon.species.getRootSpeciesId(true), newPokemon.ivs); + const newStarterUnlocked = await scene.gameData.setPokemonCaught(newPokemon, true, false, false); + if (newStarterUnlocked) { + isNewStarter = true; + await showEncounterText(scene, i18next.t("battle:addedAsAStarter", { pokemonName: getPokemonSpecies(speciesRootForm).getName() })); + } + } + + // If the previous pokemon had pokerus, transfer to new pokemon + newPokemon.pokerus = previousPokemon.pokerus; + + // Transfer previous Pokemon's luck value + newPokemon.luck = previousPokemon.getLuck(); + + // If the previous pokemon had higher IVs, override to those (after updating dex IVs > prevents perfect 31s on a new unlock) + newPokemon.ivs = newPokemon.ivs.map((iv, index) => { + return previousPokemon.ivs[index] > iv ? previousPokemon.ivs[index] : iv; + }); + + // For pokemon that the player owns (including ones just caught), gain a candy + if (!forBattle && !!scene.gameData.dexData[speciesRootForm].caughtAttr) { + scene.gameData.addStarterCandy(getPokemonSpecies(speciesRootForm), 1); + } + + // Set the moveset of the new pokemon to be the same as previous, but with 1 egg move and 1 (attempted) STAB move of the new species + newPokemon.generateAndPopulateMoveset(); + // Store a copy of a "standard" generated moveset for the new pokemon, will be used later for finding a favored move + const newPokemonGeneratedMoveset = newPokemon.moveset; + + newPokemon.moveset = previousPokemon.moveset.slice(0); + + const newEggMoveIndex = await addEggMoveToNewPokemonMoveset(scene, newPokemon, speciesRootForm, forBattle); + + // Try to add a favored STAB move (might fail if Pokemon already knows a bunch of moves from newPokemonGeneratedMoveset) + addFavoredMoveToNewPokemonMoveset(newPokemon, newPokemonGeneratedMoveset, newEggMoveIndex); + + // Randomize the second type of the pokemon + // If the pokemon does not normally have a second type, it will gain 1 + const newTypes = [ newPokemon.getTypes()[0] ]; + let newType = randSeedInt(18) as Type; + while (newType === newTypes[0]) { + newType = randSeedInt(18) as Type; + } + newTypes.push(newType); + if (!newPokemon.customPokemonData) { + newPokemon.customPokemonData = new CustomPokemonData(); + } + newPokemon.customPokemonData.types = newTypes; + + // Enable passive if previous had it + newPokemon.passive = previousPokemon.passive; + + return isNewStarter; +} + +/** + * @returns `true` if a given Pokemon has valid BST to be given an Old Gateau + */ +function shouldGetOldGateau(pokemon: Pokemon): boolean { + return pokemon.getSpeciesForm().getBaseStatTotal() < NON_LEGENDARY_BST_THRESHOLD; +} + +/** + * Get the lowest of HP/Spd, lowest of Atk/SpAtk, and lowest of Def/SpDef + * @returns Array of 3 {@linkcode Stat}s to boost + */ +function getOldGateauBoostedStats(pokemon: Pokemon): Stat[] { + const stats: Stat[] = []; + const baseStats = pokemon.getSpeciesForm().baseStats.slice(0); + // HP or Speed + stats.push(baseStats[Stat.HP] < baseStats[Stat.SPD] ? Stat.HP : Stat.SPD); + // Attack or SpAtk + stats.push(baseStats[Stat.ATK] < baseStats[Stat.SPATK] ? Stat.ATK : Stat.SPATK); + // Def or SpDef + stats.push(baseStats[Stat.DEF] < baseStats[Stat.SPDEF] ? Stat.DEF : Stat.SPDEF); + return stats; +} + + function getTransformedSpecies(originalBst: number, bstSearchRange: [number, number], hasPokemonBstHigherThan600: boolean, hasPokemonBstBetween570And600: boolean, alreadyUsedSpecies: PokemonSpecies[]): PokemonSpecies { let newSpecies: PokemonSpecies | undefined; while (isNullOrUndefined(newSpecies)) { @@ -549,11 +685,11 @@ function doSideBySideTransformations(scene: BattleScene, transformations: Pokemo * @param newPokemon * @param speciesRootForm */ -async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: PlayerPokemon, speciesRootForm: Species): Promise { +async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: PlayerPokemon, speciesRootForm: Species, forBattle: boolean = false): Promise { let eggMoveIndex: null | number = null; const eggMoves = newPokemon.getEggMoves()?.slice(0); if (eggMoves) { - const eggMoveIndices = randSeedShuffle([0, 1, 2, 3]); + const eggMoveIndices = randSeedShuffle([ 0, 1, 2, 3 ]); let randomEggMoveIndex = eggMoveIndices.pop(); let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null; let retries = 0; @@ -575,7 +711,7 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla } // For pokemon that the player owns (including ones just caught), unlock the egg move - if (!isNullOrUndefined(randomEggMoveIndex) && !!scene.gameData.dexData[speciesRootForm].caughtAttr) { + if (!forBattle && !isNullOrUndefined(randomEggMoveIndex) && !!scene.gameData.dexData[speciesRootForm].caughtAttr) { await scene.gameData.setEggMoveUnlocked(getPokemonSpecies(speciesRootForm), randomEggMoveIndex, true); } } diff --git a/src/data/mystery-encounters/mystery-encounter-requirements.ts b/src/data/mystery-encounters/mystery-encounter-requirements.ts index 6069e1abcfb..91ea0c5be19 100644 --- a/src/data/mystery-encounters/mystery-encounter-requirements.ts +++ b/src/data/mystery-encounters/mystery-encounter-requirements.ts @@ -15,6 +15,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { AttackTypeBoosterModifier } from "#app/modifier/modifier"; import { AttackTypeBoosterModifierType } from "#app/modifier/modifier-type"; import { SpeciesFormKey } from "#enums/species-form-key"; +import { allAbilities } from "#app/data/ability"; export interface EncounterRequirement { meetsRequirement(scene: BattleScene): boolean; // Boolean to see if a requirement is met @@ -36,31 +37,58 @@ export abstract class EncounterSceneRequirement implements EncounterRequirement abstract getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string]; } +/** + * Combination of multiple {@linkcode EncounterSceneRequirement | EncounterSceneRequirements} (OR/AND possible. See {@linkcode isAnd}) + */ export class CombinationSceneRequirement extends EncounterSceneRequirement { - orRequirements: EncounterSceneRequirement[]; + /** If `true`, all requirements must be met (AND). If `false`, any requirement must be met (OR) */ + private isAnd: boolean; + requirements: EncounterSceneRequirement[]; - constructor(... orRequirements: EncounterSceneRequirement[]) { + public static Some(...requirements: EncounterSceneRequirement[]): CombinationSceneRequirement { + return new CombinationSceneRequirement(false, ...requirements); + } + + public static Every(...requirements: EncounterSceneRequirement[]): CombinationSceneRequirement { + return new CombinationSceneRequirement(true, ...requirements); + } + + private constructor(isAnd: boolean, ...requirements: EncounterSceneRequirement[]) { super(); - this.orRequirements = orRequirements; + this.isAnd = isAnd; + this.requirements = requirements; } + /** + * Checks if all/any requirements are met (depends on {@linkcode isAnd}) + * @param scene The {@linkcode BattleScene} to check against + * @returns true if all/any requirements are met (depends on {@linkcode isAnd}) + */ override meetsRequirement(scene: BattleScene): boolean { - for (const req of this.orRequirements) { - if (req.meetsRequirement(scene)) { - return true; - } - } - return false; + return this.isAnd + ? this.requirements.every(req => req.meetsRequirement(scene)) + : this.requirements.some(req => req.meetsRequirement(scene)); } + /** + * Retrieves a dialogue token key/value pair for the given {@linkcode EncounterSceneRequirement | requirements}. + * @param scene The {@linkcode BattleScene} to check against + * @param pokemon The {@linkcode PlayerPokemon} to check against + * @returns A dialogue token key/value pair + * @throws An {@linkcode Error} if {@linkcode isAnd} is `true` (not supported) + */ override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - for (const req of this.orRequirements) { - if (req.meetsRequirement(scene)) { - return req.getDialogueToken(scene, pokemon); + if (this.isAnd) { + throw new Error("Not implemented (Sorry)"); + } else { + for (const req of this.requirements) { + if (req.meetsRequirement(scene)) { + return req.getDialogueToken(scene, pokemon); + } } - } - return this.orRequirements[0].getDialogueToken(scene, pokemon); + return this.requirements[0].getDialogueToken(scene, pokemon); + } } } @@ -89,44 +117,74 @@ export abstract class EncounterPokemonRequirement implements EncounterRequiremen abstract getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string]; } +/** + * Combination of multiple {@linkcode EncounterPokemonRequirement | EncounterPokemonRequirements} (OR/AND possible. See {@linkcode isAnd}) + */ export class CombinationPokemonRequirement extends EncounterPokemonRequirement { - orRequirements: EncounterPokemonRequirement[]; + /** If `true`, all requirements must be met (AND). If `false`, any requirement must be met (OR) */ + private isAnd: boolean; + private requirements: EncounterPokemonRequirement[]; - constructor(...orRequirements: EncounterPokemonRequirement[]) { + public static Some(...requirements: EncounterPokemonRequirement[]): CombinationPokemonRequirement { + return new CombinationPokemonRequirement(false, ...requirements); + } + + public static Every(...requirements: EncounterPokemonRequirement[]): CombinationPokemonRequirement { + return new CombinationPokemonRequirement(true, ...requirements); + } + + private constructor(isAnd: boolean, ...requirements: EncounterPokemonRequirement[]) { super(); + this.isAnd = isAnd; this.invertQuery = false; this.minNumberOfPokemon = 1; - this.orRequirements = orRequirements; + this.requirements = requirements; } + /** + * Checks if all/any requirements are met (depends on {@linkcode isAnd}) + * @param scene The {@linkcode BattleScene} to check against + * @returns true if all/any requirements are met (depends on {@linkcode isAnd}) + */ override meetsRequirement(scene: BattleScene): boolean { - for (const req of this.orRequirements) { - if (req.meetsRequirement(scene)) { - return true; - } - } - return false; + return this.isAnd + ? this.requirements.every(req => req.meetsRequirement(scene)) + : this.requirements.some(req => req.meetsRequirement(scene)); } + /** + * Queries the players party for all party members that are compatible with all/any requirements (depends on {@linkcode isAnd}) + * @param partyPokemon The party of {@linkcode PlayerPokemon} + * @returns All party members that are compatible with all/any requirements (depends on {@linkcode isAnd}) + */ override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] { - for (const req of this.orRequirements) { - const result = req.queryParty(partyPokemon); - if (result?.length > 0) { - return result; - } + if (this.isAnd) { + return this.requirements.reduce((relevantPokemon, req) => req.queryParty(relevantPokemon), partyPokemon); + } else { + const matchingRequirement = this.requirements.find(req => req.queryParty(partyPokemon).length > 0); + return matchingRequirement ? matchingRequirement.queryParty(partyPokemon) : []; } - - return []; } + /** + * Retrieves a dialogue token key/value pair for the given {@linkcode EncounterPokemonRequirement | requirements}. + * @param scene The {@linkcode BattleScene} to check against + * @param pokemon The {@linkcode PlayerPokemon} to check against + * @returns A dialogue token key/value pair + * @throws An {@linkcode Error} if {@linkcode isAnd} is `true` (not supported) + */ override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - for (const req of this.orRequirements) { - if (req.meetsRequirement(scene)) { - return req.getDialogueToken(scene, pokemon); + if (this.isAnd) { + throw new Error("Not implemented (Sorry)"); + } else { + for (const req of this.requirements) { + if (req.meetsRequirement(scene)) { + return req.getDialogueToken(scene, pokemon); + } } - } - return this.orRequirements[0].getDialogueToken(scene, pokemon); + return this.requirements[0].getDialogueToken(scene, pokemon); + } } } @@ -147,7 +205,7 @@ export class PreviousEncounterRequirement extends EncounterSceneRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["previousEncounter", scene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? ""]; + return [ "previousEncounter", scene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? "" ]; } } @@ -175,7 +233,7 @@ export class WaveRangeRequirement extends EncounterSceneRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["waveIndex", scene.currentBattle.waveIndex.toString()]; + return [ "waveIndex", scene.currentBattle.waveIndex.toString() ]; } } @@ -204,7 +262,7 @@ export class WaveModulusRequirement extends EncounterSceneRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["waveIndex", scene.currentBattle.waveIndex.toString()]; + return [ "waveIndex", scene.currentBattle.waveIndex.toString() ]; } } @@ -213,7 +271,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement { constructor(timeOfDay: TimeOfDay | TimeOfDay[]) { super(); - this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [timeOfDay]; + this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [ timeOfDay ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -226,7 +284,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase()]; + return [ "timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase() ]; } } @@ -235,7 +293,7 @@ export class WeatherRequirement extends EncounterSceneRequirement { constructor(weather: WeatherType | WeatherType[]) { super(); - this.requiredWeather = Array.isArray(weather) ? weather : [weather]; + this.requiredWeather = Array.isArray(weather) ? weather : [ weather ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -253,7 +311,7 @@ export class WeatherRequirement extends EncounterSceneRequirement { if (!isNullOrUndefined(currentWeather)) { token = WeatherType[currentWeather].replace("_", " ").toLocaleLowerCase(); } - return ["weather", token]; + return [ "weather", token ]; } } @@ -285,7 +343,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["partySize", scene.getParty().length.toString()]; + return [ "partySize", scene.getParty().length.toString() ]; } } @@ -296,7 +354,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement { constructor(heldItem: string | string[], minNumberOfItems: number = 1) { super(); this.minNumberOfItems = minNumberOfItems; - this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem]; + this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [ heldItem ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -318,7 +376,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["requiredItem", this.requiredHeldItemModifiers[0]]; + return [ "requiredItem", this.requiredHeldItemModifiers[0] ]; } } @@ -346,7 +404,7 @@ export class MoneyRequirement extends EncounterSceneRequirement { override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { const value = this.scalingMultiplier > 0 ? scene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString(); - return ["money", value]; + return [ "money", value ]; } } @@ -359,7 +417,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement { super(); this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredSpecies = Array.isArray(species) ? species : [species]; + this.requiredSpecies = Array.isArray(species) ? species : [ species ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -381,9 +439,9 @@ export class SpeciesRequirement extends EncounterPokemonRequirement { override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { if (pokemon?.species.speciesId && this.requiredSpecies.includes(pokemon.species.speciesId)) { - return ["species", Species[pokemon.species.speciesId]]; + return [ "species", Species[pokemon.species.speciesId] ]; } - return ["species", ""]; + return [ "species", "" ]; } } @@ -397,7 +455,7 @@ export class NatureRequirement extends EncounterPokemonRequirement { super(); this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredNature = Array.isArray(nature) ? nature : [nature]; + this.requiredNature = Array.isArray(nature) ? nature : [ nature ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -419,9 +477,9 @@ export class NatureRequirement extends EncounterPokemonRequirement { override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { if (!isNullOrUndefined(pokemon?.nature) && this.requiredNature.includes(pokemon.nature)) { - return ["nature", Nature[pokemon.nature]]; + return [ "nature", Nature[pokemon.nature] ]; } - return ["nature", ""]; + return [ "nature", "" ]; } } @@ -436,7 +494,7 @@ export class TypeRequirement extends EncounterPokemonRequirement { this.excludeFainted = excludeFainted; this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredType = Array.isArray(type) ? type : [type]; + this.requiredType = Array.isArray(type) ? type : [ type ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -465,9 +523,9 @@ export class TypeRequirement extends EncounterPokemonRequirement { override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { const includedTypes = this.requiredType.filter((ty) => pokemon?.getTypes().includes(ty)); if (includedTypes.length > 0) { - return ["type", Type[includedTypes[0]]]; + return [ "type", Type[includedTypes[0]] ]; } - return ["type", ""]; + return [ "type", "" ]; } } @@ -476,12 +534,14 @@ export class MoveRequirement extends EncounterPokemonRequirement { requiredMoves: Moves[] = []; minNumberOfPokemon: number; invertQuery: boolean; + excludeDisallowedPokemon: boolean; - constructor(moves: Moves | Moves[], minNumberOfPokemon: number = 1, invertQuery: boolean = false) { + constructor(moves: Moves | Moves[], excludeDisallowedPokemon: boolean, minNumberOfPokemon: number = 1, invertQuery: boolean = false) { super(); + this.excludeDisallowedPokemon = excludeDisallowedPokemon; this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredMoves = Array.isArray(moves) ? moves : [moves]; + this.requiredMoves = Array.isArray(moves) ? moves : [ moves ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -494,19 +554,24 @@ export class MoveRequirement extends EncounterPokemonRequirement { override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] { if (!this.invertQuery) { - return partyPokemon.filter((pokemon) => this.requiredMoves.filter((reqMove) => pokemon.moveset.filter((move) => move?.moveId === reqMove).length > 0).length > 0); + // get the Pokemon with at least one move in the required moves list + return partyPokemon.filter((pokemon) => + (!this.excludeDisallowedPokemon || pokemon.isAllowedInBattle()) + && pokemon.moveset.some((move) => move?.moveId && this.requiredMoves.includes(move.moveId))); } else { // for an inverted query, we only want to get the pokemon that don't have ANY of the listed moves - return partyPokemon.filter((pokemon) => this.requiredMoves.filter((reqMove) => pokemon.moveset.filter((move) => move?.moveId === reqMove).length === 0).length === 0); + return partyPokemon.filter((pokemon) => + (!this.excludeDisallowedPokemon || pokemon.isAllowedInBattle()) + && !pokemon.moveset.some((move) => move?.moveId && this.requiredMoves.includes(move.moveId))); } } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { const includedMoves = pokemon?.moveset.filter((move) => move?.moveId && this.requiredMoves.includes(move.moveId)); if (includedMoves && includedMoves.length > 0 && includedMoves[0]) { - return ["move", includedMoves[0].getName()]; + return [ "move", includedMoves[0].getName() ]; } - return ["move", ""]; + return [ "move", "" ]; } } @@ -525,7 +590,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement { super(); this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [learnableMove]; + this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [ learnableMove ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -548,9 +613,9 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement { override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { const includedCompatMoves = this.requiredMoves.filter((reqMove) => pokemon?.compatibleTms.filter((tm) => !pokemon.moveset.find(m => m?.moveId === tm)).includes(reqMove)); if (includedCompatMoves.length > 0) { - return ["compatibleMove", Moves[includedCompatMoves[0]]]; + return [ "compatibleMove", Moves[includedCompatMoves[0]] ]; } - return ["compatibleMove", ""]; + return [ "compatibleMove", "" ]; } } @@ -559,12 +624,14 @@ export class AbilityRequirement extends EncounterPokemonRequirement { requiredAbilities: Abilities[]; minNumberOfPokemon: number; invertQuery: boolean; + excludeDisallowedPokemon: boolean; - constructor(abilities: Abilities | Abilities[], minNumberOfPokemon: number = 1, invertQuery: boolean = false) { + constructor(abilities: Abilities | Abilities[], excludeDisallowedPokemon: boolean, minNumberOfPokemon: number = 1, invertQuery: boolean = false) { super(); + this.excludeDisallowedPokemon = excludeDisallowedPokemon; this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredAbilities = Array.isArray(abilities) ? abilities : [abilities]; + this.requiredAbilities = Array.isArray(abilities) ? abilities : [ abilities ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -577,18 +644,23 @@ export class AbilityRequirement extends EncounterPokemonRequirement { override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] { if (!this.invertQuery) { - return partyPokemon.filter((pokemon) => this.requiredAbilities.some((ability) => pokemon.getAbility().id === ability)); + return partyPokemon.filter((pokemon) => + (!this.excludeDisallowedPokemon || pokemon.isAllowedInBattle()) + && this.requiredAbilities.some((ability) => pokemon.hasAbility(ability, false))); } else { - // for an inverted query, we only want to get the pokemon that don't have ANY of the listed abilitiess - return partyPokemon.filter((pokemon) => this.requiredAbilities.filter((ability) => pokemon.getAbility().id === ability).length === 0); + // for an inverted query, we only want to get the pokemon that don't have ANY of the listed abilities + return partyPokemon.filter((pokemon) => + (!this.excludeDisallowedPokemon || pokemon.isAllowedInBattle()) + && this.requiredAbilities.filter((ability) => pokemon.hasAbility(ability, false)).length === 0); } } - override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - if (pokemon?.getAbility().id && this.requiredAbilities.some(a => pokemon.getAbility().id === a)) { - return ["ability", pokemon.getAbility().name]; + override getDialogueToken(_scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { + const matchingAbility = this.requiredAbilities.find(a => pokemon?.hasAbility(a, false)); + if (!isNullOrUndefined(matchingAbility)) { + return [ "ability", allAbilities[matchingAbility].name ]; } - return ["ability", ""]; + return [ "ability", "" ]; } } @@ -601,7 +673,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement { super(); this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [statusEffect]; + this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [ statusEffect ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -649,9 +721,9 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement { return pokemon!.status?.effect === a; }); if (reqStatus.length > 0) { - return ["status", StatusEffect[reqStatus[0]]]; + return [ "status", StatusEffect[reqStatus[0]] ]; } - return ["status", ""]; + return [ "status", "" ]; } } @@ -670,7 +742,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen super(); this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [formChangeItem]; + this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [ formChangeItem ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -706,9 +778,9 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { const requiredItems = this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem)); if (requiredItems.length > 0) { - return ["formChangeItem", FormChangeItem[requiredItems[0]]]; + return [ "formChangeItem", FormChangeItem[requiredItems[0]] ]; } - return ["formChangeItem", ""]; + return [ "formChangeItem", "" ]; } } @@ -722,7 +794,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement { super(); this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [evolutionItems]; + this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [ evolutionItems ]; } override meetsRequirement(scene: BattleScene): boolean { @@ -756,9 +828,9 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement { override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { const requiredItems = this.requiredEvolutionItem.filter((evoItem) => this.filterByEvo(pokemon, evoItem)); if (requiredItems.length > 0) { - return ["evolutionItem", EvolutionItem[requiredItems[0]]]; + return [ "evolutionItem", EvolutionItem[requiredItems[0]] ]; } - return ["evolutionItem", ""]; + return [ "evolutionItem", "" ]; } } @@ -772,7 +844,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement { super(); this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem]; + this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [ heldItem ]; this.requireTransferable = requireTransferable; } @@ -807,9 +879,9 @@ export class HeldItemRequirement extends EncounterPokemonRequirement { && (!this.requireTransferable || it.isTransferable); }); if (requiredItems && requiredItems.length > 0) { - return ["heldItem", requiredItems[0].type.name]; + return [ "heldItem", requiredItems[0].type.name ]; } - return ["heldItem", ""]; + return [ "heldItem", "" ]; } } @@ -823,7 +895,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe super(); this.minNumberOfPokemon = minNumberOfPokemon; this.invertQuery = invertQuery; - this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [heldItemTypes]; + this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [ heldItemTypes ]; this.requireTransferable = requireTransferable; } @@ -864,9 +936,9 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe && (!this.requireTransferable || it.isTransferable); }); if (requiredItems && requiredItems.length > 0) { - return ["heldItem", requiredItems[0].type.name]; + return [ "heldItem", requiredItems[0].type.name ]; } - return ["heldItem", ""]; + return [ "heldItem", "" ]; } } @@ -904,7 +976,7 @@ export class LevelRequirement extends EncounterPokemonRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["level", pokemon?.level.toString() ?? ""]; + return [ "level", pokemon?.level.toString() ?? "" ]; } } @@ -942,7 +1014,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["friendship", pokemon?.friendship.toString() ?? ""]; + return [ "friendship", pokemon?.friendship.toString() ?? "" ]; } } @@ -989,9 +1061,9 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement { override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { const hpRatio = pokemon?.getHpRatio(); if (!isNullOrUndefined(hpRatio)) { - return ["healthRatio", Math.floor(hpRatio * 100).toString() + "%"]; + return [ "healthRatio", Math.floor(hpRatio * 100).toString() + "%" ]; } - return ["healthRatio", ""]; + return [ "healthRatio", "" ]; } } @@ -1029,8 +1101,7 @@ export class WeightRequirement extends EncounterPokemonRequirement { } override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["weight", pokemon?.getWeight().toString() ?? ""]; + return [ "weight", pokemon?.getWeight().toString() ?? "" ]; } } - diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index da4d29c94d6..c045ee51bd7 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -53,6 +53,7 @@ export interface IMysteryEncounter { hasBattleAnimationsWithoutTargets: boolean; skipEnemyBattleTurns: boolean; skipToFightInput: boolean; + preventGameStatsUpdates: boolean; onInit?: (scene: BattleScene) => boolean; onVisualsStart?: (scene: BattleScene) => boolean; @@ -150,6 +151,10 @@ export default class MysteryEncounter implements IMysteryEncounter { * If true, will skip COMMAND input and go straight to FIGHT (move select) input menu */ skipToFightInput: boolean; + /** + * If true, will prevent updating {@linkcode GameStats} for encountering and/or defeating Pokemon + */ + preventGameStatsUpdates: boolean; // #region Event callback functions @@ -190,7 +195,7 @@ export default class MysteryEncounter implements IMysteryEncounter { secondaryPokemon?: PlayerPokemon[]; // #region Post-construct / Auto-populated params - + localizationKey: string; /** * Dialogue object containing all the dialogue, messages, tooltips, etc. for an encounter */ @@ -264,8 +269,9 @@ export default class MysteryEncounter implements IMysteryEncounter { Object.assign(this, encounter); } this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON; + this.localizationKey = this.localizationKey ?? ""; this.dialogue = this.dialogue ?? {}; - this.spriteConfigs = this.spriteConfigs ? [...this.spriteConfigs] : []; + this.spriteConfigs = this.spriteConfigs ? [ ...this.spriteConfigs ] : []; // Default max is 1 for ROGUE encounters, 2 for others this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? DEFAULT_MAX_ALLOWED_ROGUE_ENCOUNTERS : DEFAULT_MAX_ALLOWED_ENCOUNTERS; this.encounterMode = MysteryEncounterMode.DEFAULT; @@ -324,7 +330,7 @@ export default class MysteryEncounter implements IMysteryEncounter { if (activeMon.length > 0) { this.primaryPokemon = activeMon[0]; } else { - this.primaryPokemon = scene.getParty().filter(p => !p.isFainted())[0]; + this.primaryPokemon = scene.getParty().filter(p => p.isAllowedInBattle())[0]; } return true; } @@ -528,6 +534,7 @@ export class MysteryEncounterBuilder implements Partial { options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]]; enemyPartyConfigs: EnemyPartyConfig[] = []; + localizationKey: string = ""; dialogue: MysteryEncounterDialogue = {}; requirements: EncounterSceneRequirement[] = []; primaryPokemonRequirements: EncounterPokemonRequirement[] = []; @@ -546,6 +553,7 @@ export class MysteryEncounterBuilder implements Partial { hasBattleAnimationsWithoutTargets: boolean = false; skipEnemyBattleTurns: boolean = false; skipToFightInput: boolean = false; + preventGameStatsUpdates: boolean = false; maxAllowedEncounters: number = 3; expMultiplier: number = 1; @@ -573,7 +581,7 @@ export class MysteryEncounterBuilder implements Partial { */ withOption(option: MysteryEncounterOption): this & Pick { if (!this.options) { - const options = [option]; + const options = [ option ]; return Object.assign(this, { options }); } else { this.options.push(option); @@ -624,14 +632,24 @@ export class MysteryEncounterBuilder implements Partial { } withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []): this { - this.dialogue = {...this.dialogue, intro: dialogue }; + this.dialogue = { ...this.dialogue, intro: dialogue }; return this; } - withIntro({spriteConfigs, dialogue} : {spriteConfigs: MysteryEncounterSpriteConfig[], dialogue?: MysteryEncounterDialogue["intro"]}) { + withIntro({ spriteConfigs, dialogue } : {spriteConfigs: MysteryEncounterSpriteConfig[], dialogue?: MysteryEncounterDialogue["intro"]}) { return this.withIntroSpriteConfigs(spriteConfigs).withIntroDialogue(dialogue); } + /** + * Sets the localization key used by the encounter + * @param localizationKey the string used as the key + * @returns `this` + */ + setLocalizationKey(localizationKey: string): this { + this.localizationKey = localizationKey; + return this; + } + /** * OPTIONAL */ @@ -660,7 +678,7 @@ export class MysteryEncounterBuilder implements Partial { * @returns */ withAnimations(...encounterAnimations: EncounterAnim[]): this & Required> { - const animations = Array.isArray(encounterAnimations) ? encounterAnimations : [encounterAnimations]; + const animations = Array.isArray(encounterAnimations) ? encounterAnimations : [ encounterAnimations ]; return Object.assign(this, { encounterAnimations: animations }); } @@ -670,7 +688,7 @@ export class MysteryEncounterBuilder implements Partial { * @param disallowedGameModes */ withDisallowedGameModes(...disallowedGameModes: GameModes[]): this & Required> { - const gameModes = Array.isArray(disallowedGameModes) ? disallowedGameModes : [disallowedGameModes]; + const gameModes = Array.isArray(disallowedGameModes) ? disallowedGameModes : [ disallowedGameModes ]; return Object.assign(this, { disallowedGameModes: gameModes }); } @@ -680,7 +698,7 @@ export class MysteryEncounterBuilder implements Partial { * @param disallowedChallenges */ withDisallowedChallenges(...disallowedChallenges: Challenges[]): this & Required> { - const challenges = Array.isArray(disallowedChallenges) ? disallowedChallenges : [disallowedChallenges]; + const challenges = Array.isArray(disallowedChallenges) ? disallowedChallenges : [ disallowedChallenges ]; return Object.assign(this, { disallowedChallenges: challenges }); } @@ -723,6 +741,14 @@ export class MysteryEncounterBuilder implements Partial { return Object.assign(this, { skipToFightInput }); } + /** + * If true, will prevent updating {@linkcode GameStats} for encountering and/or defeating Pokemon + * Default `false` + */ + withPreventGameStatsUpdates(preventGameStatsUpdates: boolean): this & Required> { + return Object.assign(this, { preventGameStatsUpdates }); + } + /** * Sets the maximum number of times that an encounter can spawn in a given Classic run * @param maxAllowedEncounters @@ -755,7 +781,7 @@ export class MysteryEncounterBuilder implements Partial { * @returns */ withSceneWaveRangeRequirement(min: number, max?: number): this & Required> { - return this.withSceneRequirement(new WaveRangeRequirement([min, max ?? min])); + return this.withSceneRequirement(new WaveRangeRequirement([ min, max ?? min ])); } /** @@ -767,7 +793,7 @@ export class MysteryEncounterBuilder implements Partial { * @returns */ withScenePartySizeRequirement(min: number, max?: number, excludeDisallowedPokemon: boolean = false): this & Required> { - return this.withSceneRequirement(new PartySizeRequirement([min, max ?? min], excludeDisallowedPokemon)); + return this.withSceneRequirement(new PartySizeRequirement([ min, max ?? min ], excludeDisallowedPokemon)); } /** @@ -982,7 +1008,7 @@ export class MysteryEncounterBuilder implements Partial { * @returns */ withOutroDialogue(dialogue: MysteryEncounterDialogue["outro"] = []): this { - this.dialogue = {...this.dialogue, outro: dialogue }; + this.dialogue = { ...this.dialogue, outro: dialogue }; return this; } diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts index 8fde06f3b14..8c1c3bf6de4 100644 --- a/src/data/mystery-encounters/mystery-encounters.ts +++ b/src/data/mystery-encounters/mystery-encounters.ts @@ -224,72 +224,72 @@ const anyBiomeEncounters: MysteryEncounterType[] = [ * that biome groups do not cover */ export const mysteryEncountersByBiome = new Map([ - [Biome.TOWN, []], - [Biome.PLAINS, [ + [ Biome.TOWN, []], + [ Biome.PLAINS, [ MysteryEncounterType.SLUMBERING_SNORLAX, MysteryEncounterType.ABSOLUTE_AVARICE ]], - [Biome.GRASS, [ + [ Biome.GRASS, [ MysteryEncounterType.SLUMBERING_SNORLAX, MysteryEncounterType.ABSOLUTE_AVARICE ]], - [Biome.TALL_GRASS, [ + [ Biome.TALL_GRASS, [ MysteryEncounterType.ABSOLUTE_AVARICE ]], - [Biome.METROPOLIS, []], - [Biome.FOREST, [ + [ Biome.METROPOLIS, []], + [ Biome.FOREST, [ MysteryEncounterType.SAFARI_ZONE, MysteryEncounterType.ABSOLUTE_AVARICE ]], - [Biome.SEA, [ + [ Biome.SEA, [ MysteryEncounterType.LOST_AT_SEA ]], - [Biome.SWAMP, [ + [ Biome.SWAMP, [ MysteryEncounterType.SAFARI_ZONE ]], - [Biome.BEACH, []], - [Biome.LAKE, []], - [Biome.SEABED, []], - [Biome.MOUNTAIN, []], - [Biome.BADLANDS, [ + [ Biome.BEACH, []], + [ Biome.LAKE, []], + [ Biome.SEABED, []], + [ Biome.MOUNTAIN, []], + [ Biome.BADLANDS, [ MysteryEncounterType.DANCING_LESSONS ]], - [Biome.CAVE, [ + [ Biome.CAVE, [ MysteryEncounterType.THE_STRONG_STUFF ]], - [Biome.DESERT, [ + [ Biome.DESERT, [ MysteryEncounterType.DANCING_LESSONS ]], - [Biome.ICE_CAVE, []], - [Biome.MEADOW, []], - [Biome.POWER_PLANT, []], - [Biome.VOLCANO, [ + [ Biome.ICE_CAVE, []], + [ Biome.MEADOW, []], + [ Biome.POWER_PLANT, []], + [ Biome.VOLCANO, [ MysteryEncounterType.FIERY_FALLOUT, MysteryEncounterType.DANCING_LESSONS ]], - [Biome.GRAVEYARD, []], - [Biome.DOJO, []], - [Biome.FACTORY, []], - [Biome.RUINS, []], - [Biome.WASTELAND, [ + [ Biome.GRAVEYARD, []], + [ Biome.DOJO, []], + [ Biome.FACTORY, []], + [ Biome.RUINS, []], + [ Biome.WASTELAND, [ MysteryEncounterType.DANCING_LESSONS ]], - [Biome.ABYSS, [ + [ Biome.ABYSS, [ MysteryEncounterType.DANCING_LESSONS ]], - [Biome.SPACE, [ + [ Biome.SPACE, [ MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER ]], - [Biome.CONSTRUCTION_SITE, []], - [Biome.JUNGLE, [ + [ Biome.CONSTRUCTION_SITE, []], + [ Biome.JUNGLE, [ MysteryEncounterType.SAFARI_ZONE ]], - [Biome.FAIRY_CAVE, []], - [Biome.TEMPLE, []], - [Biome.SLUM, []], - [Biome.SNOWY_FOREST, []], - [Biome.ISLAND, []], - [Biome.LABORATORY, []] + [ Biome.FAIRY_CAVE, []], + [ Biome.TEMPLE, []], + [ Biome.SLUM, []], + [ Biome.SNOWY_FOREST, []], + [ Biome.ISLAND, []], + [ Biome.LABORATORY, []] ]); export function initMysteryEncounters() { diff --git a/src/data/mystery-encounters/requirements/can-learn-move-requirement.ts b/src/data/mystery-encounters/requirements/can-learn-move-requirement.ts index a0b4edd4a36..f34d383dbbc 100644 --- a/src/data/mystery-encounters/requirements/can-learn-move-requirement.ts +++ b/src/data/mystery-encounters/requirements/can-learn-move-requirement.ts @@ -28,7 +28,7 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement { constructor(requiredMoves: Moves | Moves[], options: CanLearnMoveRequirementOptions = {}) { super(); - this.requiredMoves = Array.isArray(requiredMoves) ? requiredMoves : [requiredMoves]; + this.requiredMoves = Array.isArray(requiredMoves) ? requiredMoves : [ requiredMoves ]; this.excludeLevelMoves = options.excludeLevelMoves ?? false; this.excludeTmMoves = options.excludeTmMoves ?? false; @@ -64,11 +64,11 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement { } override getDialogueToken(_scene: BattleScene, _pokemon?: PlayerPokemon): [string, string] { - return ["requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ")]; + return [ "requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ") ]; } private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] { - return pkm.getLevelMoves().map(([_level, move]) => move); + return pkm.getLevelMoves().map(([ _level, move ]) => move); } private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] { diff --git a/src/data/mystery-encounters/requirements/requirement-groups.ts b/src/data/mystery-encounters/requirements/requirement-groups.ts index 63c899fc5e9..76bbb8f03a7 100644 --- a/src/data/mystery-encounters/requirements/requirement-groups.ts +++ b/src/data/mystery-encounters/requirements/requirement-groups.ts @@ -118,3 +118,20 @@ export const EXTORTION_ABILITIES = [ Abilities.SUCTION_CUPS, Abilities.STICKY_HOLD ]; + +/** + * Abilities that signify resistance to fire + */ +export const FIRE_RESISTANT_ABILITIES = [ + Abilities.FLAME_BODY, + Abilities.FLASH_FIRE, + Abilities.WELL_BAKED_BODY, + Abilities.HEATPROOF, + Abilities.THERMAL_EXCHANGE, + Abilities.THICK_FAT, + Abilities.WATER_BUBBLE, + Abilities.MAGMA_ARMOR, + Abilities.WATER_VEIL, + Abilities.STEAM_ENGINE, + Abilities.PRIMORDIAL_SEA +]; diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index 18adaa4f6f4..5cd2fbffd5f 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -27,7 +27,7 @@ import { Status, StatusEffect } from "#app/data/status-effect"; import { TrainerConfig, trainerConfigs, TrainerSlot } from "#app/data/trainer-config"; import PokemonSpecies from "#app/data/pokemon-species"; import { Egg, IEggOptions } from "#app/data/egg"; -import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import HeldModifierConfig from "#app/interfaces/held-modifier-config"; import { MovePhase } from "#app/phases/move-phase"; import { EggLapsePhase } from "#app/phases/egg-lapse-phase"; @@ -71,7 +71,7 @@ export interface EnemyPokemonConfig { nickname?: string; bossSegments?: number; bossSegmentModifier?: number; // Additive to the determined segment number - mysteryEncounterPokemonData?: MysteryEncounterPokemonData; + customPokemonData?: CustomPokemonData; formIndex?: number; abilityIndex?: number; level?: number; @@ -145,7 +145,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig: newTrainer.setVisible(false); scene.field.add(newTrainer); scene.currentBattle.trainer = newTrainer; - loadEnemyAssets.push(newTrainer.loadAssets()); + loadEnemyAssets.push(newTrainer.loadAssets().then(() => newTrainer.initSprite())); battle.enemyLevels = scene.currentBattle.trainer.getPartyLevels(scene.currentBattle.waveIndex); } else { @@ -250,8 +250,8 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig: } // Set custom mystery encounter data fields (such as sprite scale, custom abilities, types, etc.) - if (!isNullOrUndefined(config.mysteryEncounterPokemonData)) { - enemyPokemon.mysteryEncounterPokemonData = config.mysteryEncounterPokemonData; + if (!isNullOrUndefined(config.customPokemonData)) { + enemyPokemon.customPokemonData = config.customPokemonData; } // Set Boss @@ -373,7 +373,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig: * @param moves */ export function loadCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) { - moves = Array.isArray(moves) ? moves : [moves]; + moves = Array.isArray(moves) ? moves : [ moves ]; return Promise.all(moves.map(move => initMoveAnim(scene, move))) .then(() => loadMoveAnimAssets(scene, moves)); } @@ -663,7 +663,7 @@ export function setEncounterRewards(scene: BattleScene, customShopRewards?: Cust * @param useWaveIndex - set to false when directly passing the the full exp value instead of baseExpValue */ export function setEncounterExp(scene: BattleScene, participantId: number | number[], baseExpValue: number, useWaveIndex: boolean = true) { - const participantIds = Array.isArray(participantId) ? participantId : [participantId]; + const participantIds = Array.isArray(participantId) ? participantId : [ participantId ]; scene.currentBattle.mysteryEncounter!.doEncounterExp = (scene: BattleScene) => { scene.unshiftPhase(new PartyExpPhase(scene, baseExpValue, useWaveIndex, new Set(participantIds))); @@ -800,8 +800,8 @@ export function transitionMysteryEncounterIntroVisuals(scene: BattleScene, hide: // Transition scene.tweens.add({ - targets: [introVisuals, enemyPokemon], - x: `${hide? "+" : "-"}=16`, + targets: [ introVisuals, enemyPokemon ], + x: `${hide ? "+" : "-"}=16`, y: `${hide ? "-" : "+"}=16`, alpha: hide ? 0 : 1, ease: "Sine.easeInOut", @@ -888,14 +888,14 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n const numRuns = 1000; let run = 0; const biomes = Object.keys(Biome).filter(key => isNaN(Number(key))); - const alwaysPickTheseBiomes = [Biome.ISLAND, Biome.ABYSS, Biome.WASTELAND, Biome.FAIRY_CAVE, Biome.TEMPLE, Biome.LABORATORY, Biome.SPACE, Biome.WASTELAND]; + const alwaysPickTheseBiomes = [ Biome.ISLAND, Biome.ABYSS, Biome.WASTELAND, Biome.FAIRY_CAVE, Biome.TEMPLE, Biome.LABORATORY, Biome.SPACE, Biome.WASTELAND ]; const calculateNumEncounters = (): any[] => { let encounterRate = baseSpawnWeight; // BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT - const numEncounters = [0, 0, 0, 0]; + const numEncounters = [ 0, 0, 0, 0 ]; let mostRecentEncounterWave = 0; - const encountersByBiome = new Map(biomes.map(b => [b, 0])); - const validMEfloorsByBiome = new Map(biomes.map(b => [b, 0])); + const encountersByBiome = new Map(biomes.map(b => [ b, 0 ])); + const validMEfloorsByBiome = new Map(biomes.map(b => [ b, 0 ])); let currentBiome = Biome.TOWN; let currentArena = scene.newArena(currentBiome); scene.setSeed(Utils.randomString(24)); @@ -968,7 +968,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n // Calculate encounter rarity // Common / Uncommon / Rare / Super Rare (base is out of 128) - const tierWeights = [66, 40, 19, 3]; + const tierWeights = [ 66, 40, 19, 3 ]; // Adjust tier weights by currently encountered events (pity system that lowers odds of multiple Common/Great) tierWeights[0] = tierWeights[0] - 6 * numEncounters[0]; @@ -987,7 +987,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n } } - return [numEncounters, encountersByBiome, validMEfloorsByBiome]; + return [ numEncounters, encountersByBiome, validMEfloorsByBiome ]; }; const encounterRuns: number[][] = []; @@ -995,7 +995,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n const validFloorsByBiome: Map[] = []; while (run < numRuns) { scene.executeWithSeedOffset(() => { - const [numEncounters, encountersByBiome, validMEfloorsByBiome] = calculateNumEncounters(); + const [ numEncounters, encountersByBiome, validMEfloorsByBiome ] = calculateNumEncounters(); encounterRuns.push(numEncounters); encountersByBiomeRuns.push(encountersByBiome); validFloorsByBiome.push(validMEfloorsByBiome); @@ -1036,7 +1036,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n let stats = `Starting weight: ${baseSpawnWeight}\nAverage MEs per run: ${totalMean}\nStandard Deviation: ${totalStd}\nAvg Commons: ${commonMean}\nAvg Greats: ${uncommonMean}\nAvg Ultras: ${rareMean}\nAvg Rogues: ${superRareMean}\n`; - const meanEncountersPerRunPerBiomeSorted = [...meanEncountersPerRunPerBiome.entries()].sort((e1, e2) => e2[1] - e1[1]); + const meanEncountersPerRunPerBiomeSorted = [ ...meanEncountersPerRunPerBiome.entries() ].sort((e1, e2) => e2[1] - e1[1]); meanEncountersPerRunPerBiomeSorted.forEach(value => stats = stats + `${value[0]}: avg valid floors ${meanMEFloorsPerRunPerBiome.get(value[0])}, avg MEs ${value[1]},\n`); console.log(stats); @@ -1054,7 +1054,7 @@ export function calculateRareSpawnAggregateStats(scene: BattleScene, luckValue: let run = 0; const calculateNumRareEncounters = (): any[] => { - const bossEncountersByRarity = [0, 0, 0, 0]; + const bossEncountersByRarity = [ 0, 0, 0, 0 ]; scene.setSeed(Utils.randomString(24)); scene.resetSeed(); // There are 12 wild boss floors @@ -1069,19 +1069,19 @@ export function calculateRareSpawnAggregateStats(scene: BattleScene, luckValue: const tier = tierValue >= 20 ? BiomePoolTier.BOSS : tierValue >= 6 ? BiomePoolTier.BOSS_RARE : tierValue >= 1 ? BiomePoolTier.BOSS_SUPER_RARE : BiomePoolTier.BOSS_ULTRA_RARE; switch (tier) { - default: - case BiomePoolTier.BOSS: - ++bossEncountersByRarity[0]; - break; - case BiomePoolTier.BOSS_RARE: - ++bossEncountersByRarity[1]; - break; - case BiomePoolTier.BOSS_SUPER_RARE: - ++bossEncountersByRarity[2]; - break; - case BiomePoolTier.BOSS_ULTRA_RARE: - ++bossEncountersByRarity[3]; - break; + default: + case BiomePoolTier.BOSS: + ++bossEncountersByRarity[0]; + break; + case BiomePoolTier.BOSS_RARE: + ++bossEncountersByRarity[1]; + break; + case BiomePoolTier.BOSS_SUPER_RARE: + ++bossEncountersByRarity[2]; + break; + case BiomePoolTier.BOSS_ULTRA_RARE: + ++bossEncountersByRarity[3]; + break; } } diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index fc459c78e37..b1adc478ab0 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -21,6 +21,8 @@ import { Gender } from "#app/data/gender"; import { PermanentStat } from "#enums/stat"; import { VictoryPhase } from "#app/phases/victory-phase"; import { SummaryUiMode } from "#app/ui/summary-ui-handler"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; +import { Abilities } from "#enums/abilities"; /** Will give +1 level every 10 waves */ export const STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER = 1; @@ -208,7 +210,7 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu let max = Array.isArray(starterTiers) ? starterTiers[1] : starterTiers; let filteredSpecies: [PokemonSpecies, number][] = Object.keys(speciesStarterCosts) - .map(s => [parseInt(s) as Species, speciesStarterCosts[s] as number]) + .map(s => [ parseInt(s) as Species, speciesStarterCosts[s] as number ]) .filter(s => { const pokemonSpecies = getPokemonSpecies(s[0]); return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0])) @@ -216,7 +218,7 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu && (allowLegendary || !pokemonSpecies.legendary) && (allowMythical || !pokemonSpecies.mythical); }) - .map(s => [getPokemonSpecies(s[0]), s[1]]); + .map(s => [ getPokemonSpecies(s[0]), s[1] ]); if (types && types.length > 0) { filteredSpecies = filteredSpecies.filter(s => types.includes(s[0].type1) || (!isNullOrUndefined(s[0].type2) && types.includes(s[0].type2))); @@ -313,7 +315,7 @@ export function applyHealToPokemon(scene: BattleScene, pokemon: PlayerPokemon, h */ export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) { const modType = modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE() - .generateType(pokemon.scene.getParty(), [value]) + .generateType(pokemon.scene.getParty(), [ value ]) ?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE); const modifier = modType?.newModifier(pokemon); if (modifier) { @@ -602,7 +604,7 @@ export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, po } }); }; - Promise.all([pokemon.hideInfo(), scene.gameData.setPokemonCaught(pokemon)]).then(() => { + Promise.all([ pokemon.hideInfo(), scene.gameData.setPokemonCaught(pokemon) ]).then(() => { if (scene.getParty().length === 6) { const promptRelease = () => { scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => { @@ -728,33 +730,33 @@ export function doPlayerFlee(scene: BattleScene, pokemon: EnemyPokemon): Promise * Bug Species and their corresponding weights */ const GOLDEN_BUG_NET_SPECIES_POOL: [Species, number][] = [ - [Species.SCYTHER, 40], - [Species.SCIZOR, 40], - [Species.KLEAVOR, 40], - [Species.PINSIR, 40], - [Species.HERACROSS, 40], - [Species.YANMA, 40], - [Species.YANMEGA, 40], - [Species.SHUCKLE, 40], - [Species.ANORITH, 40], - [Species.ARMALDO, 40], - [Species.ESCAVALIER, 40], - [Species.ACCELGOR, 40], - [Species.JOLTIK, 40], - [Species.GALVANTULA, 40], - [Species.DURANT, 40], - [Species.LARVESTA, 40], - [Species.VOLCARONA, 40], - [Species.DEWPIDER, 40], - [Species.ARAQUANID, 40], - [Species.WIMPOD, 40], - [Species.GOLISOPOD, 40], - [Species.SIZZLIPEDE, 40], - [Species.CENTISKORCH, 40], - [Species.NYMBLE, 40], - [Species.LOKIX, 40], - [Species.BUZZWOLE, 1], - [Species.PHEROMOSA, 1], + [ Species.SCYTHER, 40 ], + [ Species.SCIZOR, 40 ], + [ Species.KLEAVOR, 40 ], + [ Species.PINSIR, 40 ], + [ Species.HERACROSS, 40 ], + [ Species.YANMA, 40 ], + [ Species.YANMEGA, 40 ], + [ Species.SHUCKLE, 40 ], + [ Species.ANORITH, 40 ], + [ Species.ARMALDO, 40 ], + [ Species.ESCAVALIER, 40 ], + [ Species.ACCELGOR, 40 ], + [ Species.JOLTIK, 40 ], + [ Species.GALVANTULA, 40 ], + [ Species.DURANT, 40 ], + [ Species.LARVESTA, 40 ], + [ Species.VOLCARONA, 40 ], + [ Species.DEWPIDER, 40 ], + [ Species.ARAQUANID, 40 ], + [ Species.WIMPOD, 40 ], + [ Species.GOLISOPOD, 40 ], + [ Species.SIZZLIPEDE, 40 ], + [ Species.CENTISKORCH, 40 ], + [ Species.NYMBLE, 40 ], + [ Species.LOKIX, 40 ], + [ Species.BUZZWOLE, 1 ], + [ Species.PHEROMOSA, 1 ], ]; /** @@ -833,3 +835,21 @@ export function isPokemonValidForEncounterOptionSelection(pokemon: Pokemon, scen return null; } + +/** + * Permanently overrides the ability (not passive) of a pokemon. + * If the pokemon is a fusion, instead overrides the fused pokemon's ability. + */ +export function applyAbilityOverrideToPokemon(pokemon: Pokemon, ability: Abilities) { + if (pokemon.isFusion()) { + if (!pokemon.fusionCustomPokemonData) { + pokemon.fusionCustomPokemonData = new CustomPokemonData(); + } + pokemon.fusionCustomPokemonData.ability = ability; + } else { + if (!pokemon.customPokemonData) { + pokemon.customPokemonData = new CustomPokemonData(); + } + pokemon.customPokemonData.ability = ability; + } +} diff --git a/src/data/nature.ts b/src/data/nature.ts index c614be465c3..edac06f1a4f 100644 --- a/src/data/nature.ts +++ b/src/data/nature.ts @@ -37,76 +37,76 @@ export function getNatureName(nature: Nature, includeStatEffects: boolean = fals export function getNatureStatMultiplier(nature: Nature, stat: Stat): number { switch (stat) { - case Stat.ATK: - switch (nature) { - case Nature.LONELY: - case Nature.BRAVE: - case Nature.ADAMANT: - case Nature.NAUGHTY: - return 1.1; - case Nature.BOLD: - case Nature.TIMID: - case Nature.MODEST: - case Nature.CALM: - return 0.9; - } - break; - case Stat.DEF: - switch (nature) { - case Nature.BOLD: - case Nature.RELAXED: - case Nature.IMPISH: - case Nature.LAX: - return 1.1; - case Nature.LONELY: - case Nature.HASTY: - case Nature.MILD: - case Nature.GENTLE: - return 0.9; - } - break; - case Stat.SPATK: - switch (nature) { - case Nature.MODEST: - case Nature.MILD: - case Nature.QUIET: - case Nature.RASH: - return 1.1; - case Nature.ADAMANT: - case Nature.IMPISH: - case Nature.JOLLY: - case Nature.CAREFUL: - return 0.9; - } - break; - case Stat.SPDEF: - switch (nature) { - case Nature.CALM: - case Nature.GENTLE: - case Nature.SASSY: - case Nature.CAREFUL: - return 1.1; - case Nature.NAUGHTY: - case Nature.LAX: - case Nature.NAIVE: - case Nature.RASH: - return 0.9; - } - break; - case Stat.SPD: - switch (nature) { - case Nature.TIMID: - case Nature.HASTY: - case Nature.JOLLY: - case Nature.NAIVE: - return 1.1; - case Nature.BRAVE: - case Nature.RELAXED: - case Nature.QUIET: - case Nature.SASSY: - return 0.9; - } - break; + case Stat.ATK: + switch (nature) { + case Nature.LONELY: + case Nature.BRAVE: + case Nature.ADAMANT: + case Nature.NAUGHTY: + return 1.1; + case Nature.BOLD: + case Nature.TIMID: + case Nature.MODEST: + case Nature.CALM: + return 0.9; + } + break; + case Stat.DEF: + switch (nature) { + case Nature.BOLD: + case Nature.RELAXED: + case Nature.IMPISH: + case Nature.LAX: + return 1.1; + case Nature.LONELY: + case Nature.HASTY: + case Nature.MILD: + case Nature.GENTLE: + return 0.9; + } + break; + case Stat.SPATK: + switch (nature) { + case Nature.MODEST: + case Nature.MILD: + case Nature.QUIET: + case Nature.RASH: + return 1.1; + case Nature.ADAMANT: + case Nature.IMPISH: + case Nature.JOLLY: + case Nature.CAREFUL: + return 0.9; + } + break; + case Stat.SPDEF: + switch (nature) { + case Nature.CALM: + case Nature.GENTLE: + case Nature.SASSY: + case Nature.CAREFUL: + return 1.1; + case Nature.NAUGHTY: + case Nature.LAX: + case Nature.NAIVE: + case Nature.RASH: + return 0.9; + } + break; + case Stat.SPD: + switch (nature) { + case Nature.TIMID: + case Nature.HASTY: + case Nature.JOLLY: + case Nature.NAIVE: + return 1.1; + case Nature.BRAVE: + case Nature.RELAXED: + case Nature.QUIET: + case Nature.SASSY: + return 0.9; + } + break; } return 1; diff --git a/src/data/pokeball.ts b/src/data/pokeball.ts index 59ff4ed86ce..57a78e2cd61 100644 --- a/src/data/pokeball.ts +++ b/src/data/pokeball.ts @@ -8,77 +8,77 @@ export const MAX_PER_TYPE_POKEBALLS: integer = 99; export function getPokeballAtlasKey(type: PokeballType): string { switch (type) { - case PokeballType.POKEBALL: - return "pb"; - case PokeballType.GREAT_BALL: - return "gb"; - case PokeballType.ULTRA_BALL: - return "ub"; - case PokeballType.ROGUE_BALL: - return "rb"; - case PokeballType.MASTER_BALL: - return "mb"; - case PokeballType.LUXURY_BALL: - return "lb"; + case PokeballType.POKEBALL: + return "pb"; + case PokeballType.GREAT_BALL: + return "gb"; + case PokeballType.ULTRA_BALL: + return "ub"; + case PokeballType.ROGUE_BALL: + return "rb"; + case PokeballType.MASTER_BALL: + return "mb"; + case PokeballType.LUXURY_BALL: + return "lb"; } } export function getPokeballName(type: PokeballType): string { let ret: string; switch (type) { - case PokeballType.POKEBALL: - ret = i18next.t("pokeball:pokeBall"); - break; - case PokeballType.GREAT_BALL: - ret = i18next.t("pokeball:greatBall"); - break; - case PokeballType.ULTRA_BALL: - ret = i18next.t("pokeball:ultraBall"); - break; - case PokeballType.ROGUE_BALL: - ret = i18next.t("pokeball:rogueBall"); - break; - case PokeballType.MASTER_BALL: - ret = i18next.t("pokeball:masterBall"); - break; - case PokeballType.LUXURY_BALL: - ret = i18next.t("pokeball:luxuryBall"); - break; + case PokeballType.POKEBALL: + ret = i18next.t("pokeball:pokeBall"); + break; + case PokeballType.GREAT_BALL: + ret = i18next.t("pokeball:greatBall"); + break; + case PokeballType.ULTRA_BALL: + ret = i18next.t("pokeball:ultraBall"); + break; + case PokeballType.ROGUE_BALL: + ret = i18next.t("pokeball:rogueBall"); + break; + case PokeballType.MASTER_BALL: + ret = i18next.t("pokeball:masterBall"); + break; + case PokeballType.LUXURY_BALL: + ret = i18next.t("pokeball:luxuryBall"); + break; } return ret; } export function getPokeballCatchMultiplier(type: PokeballType): number { switch (type) { - case PokeballType.POKEBALL: - return 1; - case PokeballType.GREAT_BALL: - return 1.5; - case PokeballType.ULTRA_BALL: - return 2; - case PokeballType.ROGUE_BALL: - return 3; - case PokeballType.MASTER_BALL: - return -1; - case PokeballType.LUXURY_BALL: - return 1; + case PokeballType.POKEBALL: + return 1; + case PokeballType.GREAT_BALL: + return 1.5; + case PokeballType.ULTRA_BALL: + return 2; + case PokeballType.ROGUE_BALL: + return 3; + case PokeballType.MASTER_BALL: + return -1; + case PokeballType.LUXURY_BALL: + return 1; } } export function getPokeballTintColor(type: PokeballType): number { switch (type) { - case PokeballType.POKEBALL: - return 0xd52929; - case PokeballType.GREAT_BALL: - return 0x94b4de; - case PokeballType.ULTRA_BALL: - return 0xe6cd31; - case PokeballType.ROGUE_BALL: - return 0xd52929; - case PokeballType.MASTER_BALL: - return 0xa441bd; - case PokeballType.LUXURY_BALL: - return 0xffde6a; + case PokeballType.POKEBALL: + return 0xd52929; + case PokeballType.GREAT_BALL: + return 0x94b4de; + case PokeballType.ULTRA_BALL: + return 0xe6cd31; + case PokeballType.ROGUE_BALL: + return 0xd52929; + case PokeballType.MASTER_BALL: + return 0xa441bd; + case PokeballType.LUXURY_BALL: + return 0xffde6a; } } diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index 37d8e5d2ffb..7cc20d50fb9 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -640,18 +640,18 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.ALTARIA, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE)) ], [Species.CASTFORM]: [ - new SpeciesFormChange(Species.CASTFORM, "", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true), - new SpeciesFormChange(Species.CASTFORM, "rainy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true), - new SpeciesFormChange(Species.CASTFORM, "snowy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true), - new SpeciesFormChange(Species.CASTFORM, "", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true), - new SpeciesFormChange(Species.CASTFORM, "sunny", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true), - new SpeciesFormChange(Species.CASTFORM, "snowy", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true), - new SpeciesFormChange(Species.CASTFORM, "", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true), - new SpeciesFormChange(Species.CASTFORM, "sunny", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true), - new SpeciesFormChange(Species.CASTFORM, "rainy", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true), - new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true), - new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true), - new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true), + new SpeciesFormChange(Species.CASTFORM, "", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true), + new SpeciesFormChange(Species.CASTFORM, "rainy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true), + new SpeciesFormChange(Species.CASTFORM, "snowy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true), + new SpeciesFormChange(Species.CASTFORM, "", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true), + new SpeciesFormChange(Species.CASTFORM, "sunny", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true), + new SpeciesFormChange(Species.CASTFORM, "snowy", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true), + new SpeciesFormChange(Species.CASTFORM, "", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true), + new SpeciesFormChange(Species.CASTFORM, "sunny", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true), + new SpeciesFormChange(Species.CASTFORM, "rainy", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true), + new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true), + new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true), + new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true), new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeActiveTrigger(), true), new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeActiveTrigger(), true), new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeActiveTrigger(), true) @@ -799,8 +799,8 @@ export const pokemonFormChanges: PokemonFormChanges = { [Species.ZYGARDE]: [ new SpeciesFormChange(Species.ZYGARDE, "50-pc", "complete", new SpeciesFormChangeManualTrigger(), true), new SpeciesFormChange(Species.ZYGARDE, "complete", "50-pc", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.ZYGARDE, "10-pc", "complete", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.ZYGARDE, "complete", "10-pc", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.ZYGARDE, "10-pc", "10-complete", new SpeciesFormChangeManualTrigger(), true), + new SpeciesFormChange(Species.ZYGARDE, "10-complete", "10-pc", new SpeciesFormChangeManualTrigger(), true) ], [Species.DIANCIE]: [ new SpeciesFormChange(Species.DIANCIE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE)) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index b710c40e1d5..a93c35829ea 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -238,8 +238,8 @@ export abstract class PokemonSpeciesForm { isRareRegional(): boolean { switch (this.getRegion()) { - case Region.HISUI: - return true; + case Region.HISUI: + return true; } return false; @@ -265,14 +265,14 @@ export abstract class PokemonSpeciesForm { getBaseExp(): number { let ret = this.baseExp; switch (this.getFormSpriteKey()) { - case SpeciesFormKey.MEGA: - case SpeciesFormKey.MEGA_X: - case SpeciesFormKey.MEGA_Y: - case SpeciesFormKey.PRIMAL: - case SpeciesFormKey.GIGANTAMAX: - case SpeciesFormKey.ETERNAMAX: - ret *= 1.5; - break; + case SpeciesFormKey.MEGA: + case SpeciesFormKey.MEGA_X: + case SpeciesFormKey.MEGA_Y: + case SpeciesFormKey.PRIMAL: + case SpeciesFormKey.GIGANTAMAX: + case SpeciesFormKey.ETERNAMAX: + ret *= 1.5; + break; } return ret; } @@ -346,29 +346,29 @@ export abstract class PokemonSpeciesForm { } switch (this.speciesId) { - case Species.HIPPOPOTAS: - case Species.HIPPOWDON: - case Species.UNFEZANT: - case Species.FRILLISH: - case Species.JELLICENT: - case Species.PYROAR: - ret += female ? "-f" : ""; - break; + case Species.HIPPOPOTAS: + case Species.HIPPOWDON: + case Species.UNFEZANT: + case Species.FRILLISH: + case Species.JELLICENT: + case Species.PYROAR: + ret += female ? "-f" : ""; + break; } let formSpriteKey = this.getFormSpriteKey(formIndex); if (formSpriteKey) { switch (this.speciesId) { - case Species.DUDUNSPARCE: - break; - case Species.ZACIAN: - case Species.ZAMAZENTA: - if (formSpriteKey.startsWith("behemoth")) { - formSpriteKey = "crowned"; - } - default: - ret += `-${formSpriteKey}`; - break; + case Species.DUDUNSPARCE: + break; + case Species.ZACIAN: + case Species.ZAMAZENTA: + if (formSpriteKey.startsWith("behemoth")) { + formSpriteKey = "crowned"; + } + default: + ret += `-${formSpriteKey}`; + break; } } @@ -383,15 +383,15 @@ export abstract class PokemonSpeciesForm { let speciesId = this.speciesId; if (this.speciesId > 2000) { switch (this.speciesId) { - case Species.GALAR_SLOWPOKE: - break; - case Species.ETERNAL_FLOETTE: - break; - case Species.BLOODMOON_URSALUNA: - break; - default: - speciesId = speciesId % 2000; - break; + case Species.GALAR_SLOWPOKE: + break; + case Species.ETERNAL_FLOETTE: + break; + case Species.BLOODMOON_URSALUNA: + break; + default: + speciesId = speciesId % 2000; + break; } } let ret = speciesId.toString(); @@ -403,43 +403,44 @@ export abstract class PokemonSpeciesForm { } const formKey = forms[formIndex || 0].formKey; switch (formKey) { - case SpeciesFormKey.MEGA: - case SpeciesFormKey.MEGA_X: - case SpeciesFormKey.MEGA_Y: - case SpeciesFormKey.GIGANTAMAX: - case SpeciesFormKey.GIGANTAMAX_SINGLE: - case SpeciesFormKey.GIGANTAMAX_RAPID: - case "white": - case "black": - case "therian": - case "sky": - case "gorging": - case "gulping": - case "no-ice": - case "hangry": - case "crowned": - case "eternamax": - case "four": - case "droopy": - case "stretchy": - case "hero": - case "roaming": - case "complete": - case "10": - case "10-pc": - case "super": - case "unbound": - case "pau": - case "pompom": - case "sensu": - case "dusk": - case "midnight": - case "school": - case "dawn-wings": - case "dusk-mane": - case "ultra": - ret += `-${formKey}`; - break; + case SpeciesFormKey.MEGA: + case SpeciesFormKey.MEGA_X: + case SpeciesFormKey.MEGA_Y: + case SpeciesFormKey.GIGANTAMAX: + case SpeciesFormKey.GIGANTAMAX_SINGLE: + case SpeciesFormKey.GIGANTAMAX_RAPID: + case "white": + case "black": + case "therian": + case "sky": + case "gorging": + case "gulping": + case "no-ice": + case "hangry": + case "crowned": + case "eternamax": + case "four": + case "droopy": + case "stretchy": + case "hero": + case "roaming": + case "complete": + case "10-complete": + case "10": + case "10-pc": + case "super": + case "unbound": + case "pau": + case "pompom": + case "sensu": + case "dusk": + case "midnight": + case "school": + case "dawn-wings": + case "dusk-mane": + case "ultra": + ret += `-${formKey}`; + break; } } return ret; @@ -484,6 +485,8 @@ export abstract class PokemonSpeciesForm { frameRate: 12, repeat: -1 }); + } else { + scene.anims.get(spriteKey).frameRate = 12; } let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, ""); const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey); @@ -633,23 +636,23 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali const form = this.forms[formIndex]; let key: string | null; switch (form.formKey) { - case SpeciesFormKey.MEGA: - case SpeciesFormKey.PRIMAL: - case SpeciesFormKey.ETERNAMAX: - case SpeciesFormKey.MEGA_X: - case SpeciesFormKey.MEGA_Y: - key = form.formKey; - break; - default: - if (form.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1) { - key = "gigantamax"; - } else { - key = null; - } + case SpeciesFormKey.MEGA: + case SpeciesFormKey.PRIMAL: + case SpeciesFormKey.ETERNAMAX: + case SpeciesFormKey.MEGA_X: + case SpeciesFormKey.MEGA_Y: + key = form.formKey; + break; + default: + if (form.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1) { + key = "gigantamax"; + } else { + key = null; + } } if (key) { - return i18next.t(`battlePokemonForm:${key}`, {pokemonName: this.name}); + return i18next.t(`battlePokemonForm:${key}`, { pokemonName: this.name }); } } return this.name; @@ -687,18 +690,18 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali */ private getStrengthLevelDiff(strength: PartyMemberStrength): integer { switch (Math.min(strength, PartyMemberStrength.STRONGER)) { - case PartyMemberStrength.WEAKEST: - return 60; - case PartyMemberStrength.WEAKER: - return 40; - case PartyMemberStrength.WEAK: - return 20; - case PartyMemberStrength.AVERAGE: - return 8; - case PartyMemberStrength.STRONG: - return 4; - default: - return 0; + case PartyMemberStrength.WEAKEST: + return 60; + case PartyMemberStrength.WEAKER: + return 40; + case PartyMemberStrength.WEAK: + return 20; + case PartyMemberStrength.AVERAGE: + return 8; + case PartyMemberStrength.STRONG: + return 4; + default: + return 0; } } @@ -913,7 +916,7 @@ export class PokemonForm extends PokemonSpeciesForm { public formSpriteKey: string | null; // This is a collection of form keys that have in-run form changes, but should still be separately selectable from the start screen - private starterSelectableKeys: string[] = ["10", "50", "10-pc", "50-pc", "red", "orange", "yellow", "green", "blue", "indigo", "violet"]; + private starterSelectableKeys: string[] = [ "10", "50", "10-pc", "50-pc", "red", "orange", "yellow", "green", "blue", "indigo", "violet" ]; constructor(formName: string, formKey: string, type1: Type, type2: Type | null, height: number, weight: number, ability1: Abilities, ability2: Abilities, abilityHidden: Abilities, baseTotal: integer, baseHp: integer, baseAtk: integer, baseDef: integer, baseSpatk: integer, baseSpdef: integer, baseSpd: integer, @@ -973,7 +976,7 @@ export function initSpecies() { new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true, new PokemonForm("Normal", "", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GRASS, Type.POISON, 2.4, 155.5, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.NONE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), ), new PokemonSpecies(Species.CHARMANDER, 1, false, false, false, "Lizard Pokémon", Type.FIRE, null, 0.6, 8.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.CHARMELEON, 1, false, false, false, "Flame Pokémon", Type.FIRE, null, 1.1, 19, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), @@ -981,20 +984,20 @@ export function initSpecies() { new PokemonForm("Normal", "", Type.FIRE, Type.FLYING, 1.7, 90.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, false, null, true), new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, Type.FIRE, Type.DRAGON, 1.7, 110.5, Abilities.TOUGH_CLAWS, Abilities.NONE, Abilities.TOUGH_CLAWS, 634, 78, 130, 111, 130, 85, 100, 45, 50, 267), new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, Type.FIRE, Type.FLYING, 1.7, 100.5, Abilities.DROUGHT, Abilities.NONE, Abilities.DROUGHT, 634, 78, 104, 78, 159, 115, 100, 45, 50, 267), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.FLYING, 28, 999.9, Abilities.BERSERK, Abilities.BERSERK, Abilities.BERSERK, 634, 118, 84, 93, 139, 110, 100, 45, 50, 267), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.FLYING, 28, 999.9, Abilities.BERSERK, Abilities.NONE, Abilities.BERSERK, 634, 118, 84, 93, 139, 100, 100, 45, 50, 267), ), new PokemonSpecies(Species.SQUIRTLE, 1, false, false, false, "Tiny Turtle Pokémon", Type.WATER, null, 0.5, 9, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 314, 44, 48, 65, 50, 64, 43, 45, 50, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.WARTORTLE, 1, false, false, false, "Turtle Pokémon", Type.WATER, null, 1, 22.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 405, 59, 63, 80, 65, 80, 58, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.WATER, null, 1.6, 101.1, Abilities.MEGA_LAUNCHER, Abilities.NONE, Abilities.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.NONE, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265), ), new PokemonSpecies(Species.CATERPIE, 1, false, false, false, "Worm Pokémon", Type.BUG, null, 0.3, 2.9, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true, new PokemonForm("Normal", "", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 999.9, Abilities.COMPOUND_EYES, Abilities.COMPOUND_EYES, Abilities.COMPOUND_EYES, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 999.9, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.COMPOUND_EYES, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true), ), new PokemonSpecies(Species.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", Type.BUG, Type.POISON, 0.3, 3.2, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.KAKUNA, 1, false, false, false, "Cocoon Pokémon", Type.BUG, Type.POISON, 0.6, 10, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), @@ -1023,7 +1026,7 @@ export function initSpecies() { new PokemonForm("Cute Cosplay", "cute-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom new PokemonForm("Smart Cosplay", "smart-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom new PokemonForm("Tough Cosplay", "tough-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, null, 21, 999.9, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112), //+100 BST from Partner Form + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, null, 21, 999.9, Abilities.LIGHTNING_ROD, Abilities.NONE, Abilities.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112), //+100 BST from Partner Form ), new PokemonSpecies(Species.RAICHU, 1, false, false, false, "Mouse Pokémon", Type.ELECTRIC, null, 0.8, 30, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 485, 60, 90, 55, 90, 80, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, true), new PokemonSpecies(Species.SANDSHREW, 1, false, false, false, "Mouse Pokémon", Type.GROUND, null, 0.6, 12, Abilities.SAND_VEIL, Abilities.NONE, Abilities.SAND_RUSH, 300, 50, 75, 85, 20, 30, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), @@ -1108,7 +1111,7 @@ export function initSpecies() { new PokemonSpecies(Species.GENGAR, 1, false, false, false, "Shadow Pokémon", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false, true, new PokemonForm("Normal", "", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GHOST, Type.POISON, 1.4, 40.5, Abilities.SHADOW_TAG, Abilities.NONE, Abilities.NONE, 600, 60, 65, 80, 170, 95, 130, 45, 50, 250), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GHOST, Type.POISON, 20, 999.9, Abilities.CURSED_BODY, Abilities.CURSED_BODY, Abilities.CURSED_BODY, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GHOST, Type.POISON, 20, 999.9, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250), ), new PokemonSpecies(Species.ONIX, 1, false, false, false, "Rock Snake Pokémon", Type.ROCK, Type.GROUND, 8.8, 210, Abilities.ROCK_HEAD, Abilities.STURDY, Abilities.WEAK_ARMOR, 385, 35, 45, 160, 30, 45, 70, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DROWZEE, 1, false, false, false, "Hypnosis Pokémon", Type.PSYCHIC, null, 1, 32.4, Abilities.INSOMNIA, Abilities.FOREWARN, Abilities.INNER_FOCUS, 328, 60, 48, 45, 43, 90, 42, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), @@ -1116,7 +1119,7 @@ export function initSpecies() { new PokemonSpecies(Species.KRABBY, 1, false, false, false, "River Crab Pokémon", Type.WATER, null, 0.4, 6.5, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 325, 30, 105, 90, 25, 25, 50, 225, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.KINGLER, 1, false, false, false, "Pincer Pokémon", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 19, 999.9, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, 575, 90, 155, 140, 50, 80, 70, 60, 50, 166), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 19, 999.9, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, 575, 90, 155, 140, 50, 70, 70, 60, 50, 166), ), new PokemonSpecies(Species.VOLTORB, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 0.5, 10.4, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 70, 66, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.ELECTRODE, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 1.2, 66.6, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false), @@ -1861,7 +1864,7 @@ export function initSpecies() { new PokemonSpecies(Species.ALOMOMOLA, 5, false, false, false, "Caring Pokémon", Type.WATER, null, 1.2, 31.6, Abilities.HEALER, Abilities.HYDRATION, Abilities.REGENERATOR, 470, 165, 75, 80, 40, 45, 65, 75, 70, 165, GrowthRate.FAST, 50, false), new PokemonSpecies(Species.JOLTIK, 5, false, false, false, "Attaching Pokémon", Type.BUG, Type.ELECTRIC, 0.1, 0.6, Abilities.COMPOUND_EYES, Abilities.UNNERVE, Abilities.SWARM, 319, 50, 47, 50, 57, 50, 65, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GALVANTULA, 5, false, false, false, "EleSpider Pokémon", Type.BUG, Type.ELECTRIC, 0.8, 14.3, Abilities.COMPOUND_EYES, Abilities.UNNERVE, Abilities.SWARM, 472, 70, 77, 60, 97, 60, 108, 75, 50, 165, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(Species.FERROSEED, 5, false, false, false, "Thorn Seed Pokémon", Type.GRASS, Type.STEEL, 0.6, 18.8, Abilities.IRON_BARBS, Abilities.NONE, Abilities.IRON_BARBS, 305, 44, 50, 91, 24, 86, 10, 255, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(Species.FERROSEED, 5, false, false, false, "Thorn Seed Pokémon", Type.GRASS, Type.STEEL, 0.6, 18.8, Abilities.IRON_BARBS, Abilities.NONE, Abilities.ANTICIPATION, 305, 44, 50, 91, 24, 86, 10, 255, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.FERROTHORN, 5, false, false, false, "Thorn Pod Pokémon", Type.GRASS, Type.STEEL, 1, 110, Abilities.IRON_BARBS, Abilities.NONE, Abilities.ANTICIPATION, 489, 74, 94, 131, 54, 116, 20, 90, 50, 171, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.KLINK, 5, false, false, false, "Gear Pokémon", Type.STEEL, null, 0.3, 21, Abilities.PLUS, Abilities.MINUS, Abilities.CLEAR_BODY, 300, 40, 55, 70, 45, 60, 30, 130, 50, 60, GrowthRate.MEDIUM_SLOW, null, false), new PokemonSpecies(Species.KLANG, 5, false, false, false, "Gear Pokémon", Type.STEEL, null, 0.6, 51, Abilities.PLUS, Abilities.MINUS, Abilities.CLEAR_BODY, 440, 60, 80, 95, 70, 85, 50, 60, 50, 154, GrowthRate.MEDIUM_SLOW, null, false), @@ -2133,7 +2136,8 @@ export function initSpecies() { new PokemonForm("10% Forme", "10", Type.DRAGON, Type.GROUND, 1.2, 33.5, Abilities.AURA_BREAK, Abilities.NONE, Abilities.NONE, 486, 54, 100, 71, 61, 85, 115, 3, 0, 300, false, null, true), new PokemonForm("50% Forme Power Construct", "50-pc", Type.DRAGON, Type.GROUND, 5, 305, Abilities.POWER_CONSTRUCT, Abilities.NONE, Abilities.NONE, 600, 108, 100, 121, 81, 95, 95, 3, 0, 300, false, "", true), new PokemonForm("10% Forme Power Construct", "10-pc", Type.DRAGON, Type.GROUND, 1.2, 33.5, Abilities.POWER_CONSTRUCT, Abilities.NONE, Abilities.NONE, 486, 54, 100, 71, 61, 85, 115, 3, 0, 300, false, "10", true), - new PokemonForm("Complete Forme", "complete", Type.DRAGON, Type.GROUND, 4.5, 610, Abilities.POWER_CONSTRUCT, Abilities.NONE, Abilities.NONE, 708, 216, 100, 121, 91, 95, 85, 3, 0, 300), + new PokemonForm("Complete Forme (50% PC)", "complete", Type.DRAGON, Type.GROUND, 4.5, 610, Abilities.POWER_CONSTRUCT, Abilities.NONE, Abilities.NONE, 708, 216, 100, 121, 91, 95, 85, 3, 0, 300), + new PokemonForm("Complete Forme (10% PC)", "10-complete", Type.DRAGON, Type.GROUND, 4.5, 610, Abilities.POWER_CONSTRUCT, Abilities.NONE, Abilities.NONE, 708, 216, 100, 121, 91, 95, 85, 3, 0, 300, false, "complete"), ), new PokemonSpecies(Species.DIANCIE, 6, false, false, true, "Jewel Pokémon", Type.ROCK, Type.FAIRY, 0.7, 8.8, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.NONE, 600, 50, 100, 150, 100, 150, 50, 3, 50, 300, GrowthRate.SLOW, null, false, true, new PokemonForm("Normal", "", Type.ROCK, Type.FAIRY, 0.7, 8.8, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.NONE, 600, 50, 100, 150, 100, 150, 50, 3, 50, 300, false, null, true), @@ -2296,25 +2300,25 @@ export function initSpecies() { new PokemonSpecies(Species.MELTAN, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 0.2, 8, Abilities.MAGNET_PULL, Abilities.NONE, Abilities.NONE, 300, 46, 65, 65, 55, 35, 34, 3, 0, 150, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.MELMETAL, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, GrowthRate.SLOW, null, false, true, new PokemonForm("Normal", "", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 25, 999.9, Abilities.IRON_FIST, Abilities.IRON_FIST, Abilities.IRON_FIST, 700, 175, 165, 155, 85, 75, 45, 3, 0, 300), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 25, 999.9, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 700, 175, 165, 155, 85, 75, 45, 3, 0, 300), ), new PokemonSpecies(Species.GROOKEY, 8, false, false, false, "Chimp Pokémon", Type.GRASS, null, 0.3, 5, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 310, 50, 65, 50, 40, 40, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.THWACKEY, 8, false, false, false, "Beat Pokémon", Type.GRASS, null, 0.7, 14, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 420, 70, 85, 70, 55, 60, 80, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.RILLABOOM, 8, false, false, false, "Drummer Pokémon", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, null, 28, 999.9, Abilities.GRASSY_SURGE, Abilities.GRASSY_SURGE, Abilities.GRASSY_SURGE, 630, 125, 150, 105, 85, 85, 80, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, null, 28, 999.9, Abilities.GRASSY_SURGE, Abilities.NONE, Abilities.GRASSY_SURGE, 630, 125, 150, 105, 85, 85, 80, 45, 50, 265), ), new PokemonSpecies(Species.SCORBUNNY, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.3, 4.5, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 310, 50, 71, 40, 40, 40, 69, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.RABOOT, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.6, 9, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 420, 65, 86, 60, 55, 60, 94, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.CINDERACE, 8, false, false, false, "Striker Pokémon", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, null, 27, 999.9, Abilities.LIBERO, Abilities.LIBERO, Abilities.LIBERO, 630, 100, 146, 80, 90, 80, 134, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, null, 27, 999.9, Abilities.LIBERO, Abilities.NONE, Abilities.LIBERO, 630, 100, 146, 80, 90, 80, 134, 45, 50, 265), ), new PokemonSpecies(Species.SOBBLE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.3, 4, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 310, 50, 40, 40, 70, 40, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.DRIZZILE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.7, 11.5, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 420, 65, 60, 55, 95, 55, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.INTELEON, 8, false, false, false, "Secret Agent Pokémon", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 40, 999.9, Abilities.SNIPER, Abilities.SNIPER, Abilities.SNIPER, 630, 95, 97, 77, 147, 77, 137, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 40, 999.9, Abilities.SNIPER, Abilities.NONE, Abilities.SNIPER, 630, 95, 97, 77, 147, 77, 137, 45, 50, 265), ), new PokemonSpecies(Species.SKWOVET, 8, false, false, false, "Cheeky Pokémon", Type.NORMAL, null, 0.3, 2.5, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 275, 70, 55, 55, 35, 35, 25, 255, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GREEDENT, 8, false, false, false, "Greedy Pokémon", Type.NORMAL, null, 0.6, 6, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 460, 120, 95, 95, 55, 75, 20, 90, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), @@ -2420,7 +2424,7 @@ export function initSpecies() { new PokemonForm("Ruby Swirl", "ruby-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), new PokemonForm("Caramel Swirl", "caramel-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), new PokemonForm("Rainbow Swirl", "rainbow-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FAIRY, null, 30, 999.9, Abilities.MISTY_SURGE, Abilities.MISTY_SURGE, Abilities.MISTY_SURGE, 595, 135, 60, 75, 130, 131, 64, 100, 50, 173), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FAIRY, null, 30, 999.9, Abilities.MISTY_SURGE, Abilities.NONE, Abilities.MISTY_SURGE, 595, 135, 60, 75, 130, 131, 64, 100, 50, 173), ), new PokemonSpecies(Species.FALINKS, 8, false, false, false, "Formation Pokémon", Type.FIGHTING, null, 3, 62, Abilities.BATTLE_ARMOR, Abilities.NONE, Abilities.DEFIANT, 470, 65, 100, 100, 70, 60, 75, 45, 50, 165, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.PINCURCHIN, 8, false, false, false, "Sea Urchin Pokémon", Type.ELECTRIC, null, 0.3, 1, Abilities.LIGHTNING_ROD, Abilities.NONE, Abilities.ELECTRIC_SURGE, 435, 48, 101, 95, 91, 85, 15, 75, 50, 152, GrowthRate.MEDIUM_FAST, 50, false), @@ -2442,7 +2446,7 @@ export function initSpecies() { new PokemonSpecies(Species.CUFANT, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 1.2, 100, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 330, 72, 80, 49, 40, 49, 40, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.COPPERAJAH, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.GROUND, 23, 999.9, Abilities.MOLD_BREAKER, Abilities.MOLD_BREAKER, Abilities.MOLD_BREAKER, 600, 167, 155, 89, 80, 89, 20, 90, 50, 175), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.GROUND, 23, 999.9, Abilities.MOLD_BREAKER, Abilities.NONE, Abilities.MOLD_BREAKER, 600, 167, 155, 89, 80, 89, 20, 90, 50, 175), ), new PokemonSpecies(Species.DRACOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.DRAGON, 1.8, 190, Abilities.VOLT_ABSORB, Abilities.HUSTLE, Abilities.SAND_RUSH, 505, 90, 100, 90, 80, 70, 75, 45, 50, 177, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.ARCTOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.ICE, 2.3, 150, Abilities.VOLT_ABSORB, Abilities.STATIC, Abilities.SLUSH_RUSH, 505, 90, 100, 90, 90, 80, 55, 45, 50, 177, GrowthRate.SLOW, null, false), @@ -2576,11 +2580,11 @@ export function initSpecies() { new PokemonSpecies(Species.VAROOM, 9, false, false, false, "Single-Cyl Pokémon", Type.STEEL, Type.POISON, 1, 35, Abilities.OVERCOAT, Abilities.NONE, Abilities.SLOW_START, 300, 45, 70, 63, 30, 45, 47, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.REVAVROOM, 9, false, false, false, "Multi-Cyl Pokémon", Type.STEEL, Type.POISON, 1.8, 120, Abilities.OVERCOAT, Abilities.NONE, Abilities.FILTER, 500, 80, 119, 90, 54, 67, 90, 75, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, false, new PokemonForm("Normal", "", Type.STEEL, Type.POISON, 1.8, 120, Abilities.OVERCOAT, Abilities.NONE, Abilities.FILTER, 500, 80, 119, 90, 54, 67, 90, 75, 50, 175, false, null, true), - new PokemonForm("Segin Starmobile", "segin-starmobile", Type.STEEL, Type.DARK, 1.8, 240, Abilities.INTIMIDATE, Abilities.NONE, Abilities.INTIMIDATE, 600, 120, 129, 100, 59, 77, 115, 75, 50, 175), - new PokemonForm("Schedar Starmobile", "schedar-starmobile", Type.STEEL, Type.FIRE, 1.8, 240, Abilities.SPEED_BOOST, Abilities.NONE, Abilities.SPEED_BOOST, 600, 120, 129, 100, 59, 77, 115, 75, 50, 175), - new PokemonForm("Navi Starmobile", "navi-starmobile", Type.STEEL, Type.POISON, 1.8, 240, Abilities.TOXIC_DEBRIS, Abilities.NONE, Abilities.TOXIC_DEBRIS, 600, 120, 129, 100, 59, 77, 115, 75, 50, 175), - new PokemonForm("Ruchbah Starmobile", "ruchbah-starmobile", Type.STEEL, Type.FAIRY, 1.8, 240, Abilities.MISTY_SURGE, Abilities.NONE, Abilities.MISTY_SURGE, 600, 120, 129, 100, 59, 77, 115, 75, 50, 175), - new PokemonForm("Caph Starmobile", "caph-starmobile", Type.STEEL, Type.FIGHTING, 1.8, 240, Abilities.STAMINA, Abilities.NONE, Abilities.STAMINA, 600, 120, 129, 100, 59, 77, 115, 75, 50, 175), + new PokemonForm("Segin Starmobile", "segin-starmobile", Type.STEEL, Type.DARK, 1.8, 240, Abilities.INTIMIDATE, Abilities.NONE, Abilities.INTIMIDATE, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175), + new PokemonForm("Schedar Starmobile", "schedar-starmobile", Type.STEEL, Type.FIRE, 1.8, 240, Abilities.SPEED_BOOST, Abilities.NONE, Abilities.SPEED_BOOST, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175), + new PokemonForm("Navi Starmobile", "navi-starmobile", Type.STEEL, Type.POISON, 1.8, 240, Abilities.TOXIC_DEBRIS, Abilities.NONE, Abilities.TOXIC_DEBRIS, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175), + new PokemonForm("Ruchbah Starmobile", "ruchbah-starmobile", Type.STEEL, Type.FAIRY, 1.8, 240, Abilities.MISTY_SURGE, Abilities.NONE, Abilities.MISTY_SURGE, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175), + new PokemonForm("Caph Starmobile", "caph-starmobile", Type.STEEL, Type.FIGHTING, 1.8, 240, Abilities.STAMINA, Abilities.NONE, Abilities.STAMINA, 600, 110, 129, 100, 77, 79, 105, 75, 50, 175), ), new PokemonSpecies(Species.CYCLIZAR, 9, false, false, false, "Mount Pokémon", Type.DRAGON, Type.NORMAL, 1.6, 63, Abilities.SHED_SKIN, Abilities.NONE, Abilities.REGENERATOR, 501, 70, 95, 65, 85, 65, 121, 190, 50, 175, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.ORTHWORM, 9, false, false, false, "Earthworm Pokémon", Type.STEEL, null, 2.5, 310, Abilities.EARTH_EATER, Abilities.NONE, Abilities.SAND_VEIL, 480, 70, 85, 145, 60, 55, 65, 25, 50, 240, GrowthRate.SLOW, 50, false), diff --git a/src/data/splash-messages.ts b/src/data/splash-messages.ts index a257b748734..1f00ce0d555 100644 --- a/src/data/splash-messages.ts +++ b/src/data/splash-messages.ts @@ -185,26 +185,26 @@ const seasonalSplashMessages: Season[] = [ name: "Halloween", start: "09-15", end: "10-31", - messages: ["halloween.pumpkabooAbout", "halloween.mayContainSpiders", "halloween.spookyScarySkeledirge", "halloween.gourgeistUsedTrickOrTreat", "halloween.letsSnuggleForever"], + messages: [ "halloween.pumpkabooAbout", "halloween.mayContainSpiders", "halloween.spookyScarySkeledirge", "halloween.gourgeistUsedTrickOrTreat", "halloween.letsSnuggleForever" ], }, { name: "XMAS", start: "12-01", end: "12-26", - messages: ["xmas.happyHolidays", "xmas.unaffilicatedWithDelibirdServices", "xmas.delibirdSeason", "xmas.diamondsFromTheSky", "xmas.holidayStylePikachuNotIncluded"], + messages: [ "xmas.happyHolidays", "xmas.unaffilicatedWithDelibirdServices", "xmas.delibirdSeason", "xmas.diamondsFromTheSky", "xmas.holidayStylePikachuNotIncluded" ], }, { name: "New Year's", start: "01-01", end: "01-31", - messages: ["newYears.happyNewYear"], + messages: [ "newYears.happyNewYear" ], }, ]; //#endregion export function getSplashMessages(): string[] { - const splashMessages: string[] = [...commonSplashMessages]; + const splashMessages: string[] = [ ...commonSplashMessages ]; console.log("use seasonal splash messages", USE_SEASONAL_SPLASH_MESSAGES); if (USE_SEASONAL_SPLASH_MESSAGES) { // add seasonal splash messages if the season is active diff --git a/src/data/status-effect.ts b/src/data/status-effect.ts index ffe32a02aeb..56e754ac407 100644 --- a/src/data/status-effect.ts +++ b/src/data/status-effect.ts @@ -1,4 +1,4 @@ -import * as Utils from "../utils"; +import { randIntRange } from "#app/utils"; import { StatusEffect } from "#enums/status-effect"; import i18next, { ParseKeys } from "i18next"; @@ -6,17 +6,21 @@ export { StatusEffect }; export class Status { public effect: StatusEffect; - public turnCount: integer; - public cureTurn: integer | null; + /** Toxic damage is `1/16 max HP * toxicTurnCount` */ + public toxicTurnCount: number = 0; + public sleepTurnsRemaining?: number; - constructor(effect: StatusEffect, turnCount: integer = 0, cureTurn?: integer) { + constructor(effect: StatusEffect, toxicTurnCount: number = 0, sleepTurnsRemaining?: number) { this.effect = effect; - this.turnCount = turnCount === undefined ? 0 : turnCount; - this.cureTurn = cureTurn!; // TODO: is this bang correct? + this.toxicTurnCount = toxicTurnCount; + this.sleepTurnsRemaining = sleepTurnsRemaining; } incrementTurn(): void { - this.turnCount++; + this.toxicTurnCount++; + if (this.sleepTurnsRemaining) { + this.sleepTurnsRemaining--; + } } isPostTurn(): boolean { @@ -26,20 +30,20 @@ export class Status { function getStatusEffectMessageKey(statusEffect: StatusEffect | undefined): string { switch (statusEffect) { - case StatusEffect.POISON: - return "statusEffect:poison"; - case StatusEffect.TOXIC: - return "statusEffect:toxic"; - case StatusEffect.PARALYSIS: - return "statusEffect:paralysis"; - case StatusEffect.SLEEP: - return "statusEffect:sleep"; - case StatusEffect.FREEZE: - return "statusEffect:freeze"; - case StatusEffect.BURN: - return "statusEffect:burn"; - default: - return "statusEffect:none"; + case StatusEffect.POISON: + return "statusEffect:poison"; + case StatusEffect.TOXIC: + return "statusEffect:toxic"; + case StatusEffect.PARALYSIS: + return "statusEffect:paralysis"; + case StatusEffect.SLEEP: + return "statusEffect:sleep"; + case StatusEffect.FREEZE: + return "statusEffect:freeze"; + case StatusEffect.BURN: + return "statusEffect:burn"; + default: + return "statusEffect:none"; } } @@ -90,14 +94,14 @@ export function getStatusEffectDescriptor(statusEffect: StatusEffect): string { export function getStatusEffectCatchRateMultiplier(statusEffect: StatusEffect): number { switch (statusEffect) { - case StatusEffect.POISON: - case StatusEffect.TOXIC: - case StatusEffect.PARALYSIS: - case StatusEffect.BURN: - return 1.5; - case StatusEffect.SLEEP: - case StatusEffect.FREEZE: - return 2.5; + case StatusEffect.POISON: + case StatusEffect.TOXIC: + case StatusEffect.PARALYSIS: + case StatusEffect.BURN: + return 1.5; + case StatusEffect.SLEEP: + case StatusEffect.FREEZE: + return 2.5; } return 1; @@ -107,7 +111,7 @@ export function getStatusEffectCatchRateMultiplier(statusEffect: StatusEffect): * Returns a random non-volatile StatusEffect */ export function generateRandomStatusEffect(): StatusEffect { - return Utils.randIntRange(1, 6); + return randIntRange(1, 6); } /** @@ -123,7 +127,7 @@ export function getRandomStatusEffect(statusEffectA: StatusEffect, statusEffectB return statusEffectA; } - return Utils.randIntRange(0, 2) ? statusEffectA : statusEffectB; + return randIntRange(0, 2) ? statusEffectA : statusEffectB; } /** @@ -140,7 +144,7 @@ export function getRandomStatus(statusA: Status | null, statusB: Status | null): } - return Utils.randIntRange(0, 2) ? statusA : statusB; + return randIntRange(0, 2) ? statusA : statusB; } /** diff --git a/src/data/terrain.ts b/src/data/terrain.ts index 6db68b92239..d8ee8d67925 100644 --- a/src/data/terrain.ts +++ b/src/data/terrain.ts @@ -34,21 +34,21 @@ export class Terrain { getAttackTypeMultiplier(attackType: Type): number { switch (this.terrainType) { - case TerrainType.ELECTRIC: - if (attackType === Type.ELECTRIC) { - return 1.3; - } - break; - case TerrainType.GRASSY: - if (attackType === Type.GRASS) { - return 1.3; - } - break; - case TerrainType.PSYCHIC: - if (attackType === Type.PSYCHIC) { - return 1.3; - } - break; + case TerrainType.ELECTRIC: + if (attackType === Type.ELECTRIC) { + return 1.3; + } + break; + case TerrainType.GRASSY: + if (attackType === Type.GRASS) { + return 1.3; + } + break; + case TerrainType.PSYCHIC: + if (attackType === Type.PSYCHIC) { + return 1.3; + } + break; } return 1; @@ -56,13 +56,13 @@ export class Terrain { isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean { switch (this.terrainType) { - case TerrainType.PSYCHIC: - if (!move.hasAttr(ProtectAttr)) { - const priority = new Utils.IntegerHolder(move.priority); - applyAbAttrs(ChangeMovePriorityAbAttr, user, null, false, move, priority); - // Cancels move if the move has positive priority and targets a Pokemon grounded on the Psychic Terrain - return priority.value > 0 && user.getOpponents().some(o => targets.includes(o.getBattlerIndex()) && o.isGrounded()); - } + case TerrainType.PSYCHIC: + if (!move.hasAttr(ProtectAttr)) { + const priority = new Utils.IntegerHolder(move.priority); + applyAbAttrs(ChangeMovePriorityAbAttr, user, null, false, move, priority); + // Cancels move if the move has positive priority and targets a Pokemon grounded on the Psychic Terrain + return priority.value > 0 && user.getOpponents().some(o => targets.includes(o.getBattlerIndex()) && o.isGrounded()); + } } return false; @@ -71,14 +71,14 @@ export class Terrain { export function getTerrainName(terrainType: TerrainType): string { switch (terrainType) { - case TerrainType.MISTY: - return i18next.t("terrain:misty"); - case TerrainType.ELECTRIC: - return i18next.t("terrain:electric"); - case TerrainType.GRASSY: - return i18next.t("terrain:grassy"); - case TerrainType.PSYCHIC: - return i18next.t("terrain:psychic"); + case TerrainType.MISTY: + return i18next.t("terrain:misty"); + case TerrainType.ELECTRIC: + return i18next.t("terrain:electric"); + case TerrainType.GRASSY: + return i18next.t("terrain:grassy"); + case TerrainType.PSYCHIC: + return i18next.t("terrain:psychic"); } return ""; @@ -87,14 +87,14 @@ export function getTerrainName(terrainType: TerrainType): string { export function getTerrainColor(terrainType: TerrainType): [ integer, integer, integer ] { switch (terrainType) { - case TerrainType.MISTY: - return [ 232, 136, 200 ]; - case TerrainType.ELECTRIC: - return [ 248, 248, 120 ]; - case TerrainType.GRASSY: - return [ 120, 200, 80 ]; - case TerrainType.PSYCHIC: - return [ 160, 64, 160 ]; + case TerrainType.MISTY: + return [ 232, 136, 200 ]; + case TerrainType.ELECTRIC: + return [ 248, 248, 120 ]; + case TerrainType.GRASSY: + return [ 120, 200, 80 ]; + case TerrainType.PSYCHIC: + return [ 160, 64, 160 ]; } return [ 0, 0, 0 ]; diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index e9c5dfdf292..3a361304a82 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -204,6 +204,7 @@ export class TrainerConfig { public modifierRewardFuncs: ModifierTypeFunc[] = []; public partyTemplates: TrainerPartyTemplate[]; public partyTemplateFunc: PartyTemplateFunc; + public eventRewardFuncs: ModifierTypeFunc[] = []; public partyMemberFuncs: PartyMemberFuncs = {}; public speciesPools: TrainerTierPools; public speciesFilter: PokemonSpeciesFilter; @@ -228,7 +229,7 @@ export class TrainerConfig { this.battleBgm = "battle_trainer"; this.mixedBattleBgm = "battle_trainer"; this.victoryBgm = "victory_trainer"; - this.partyTemplates = [trainerPartyTemplates.TWO_AVG]; + this.partyTemplates = [ trainerPartyTemplates.TWO_AVG ]; this.speciesFilter = species => (allowLegendaries || (!species.legendary && !species.subLegendary && !species.mythical)) && !species.isTrainerForbidden(); } @@ -300,65 +301,65 @@ export class TrainerConfig { getDerivedType(trainerTypeToDeriveFrom: TrainerType | null = null): TrainerType { let trainerType = trainerTypeToDeriveFrom ? trainerTypeToDeriveFrom : this.trainerType; switch (trainerType) { - case TrainerType.RIVAL_2: - case TrainerType.RIVAL_3: - case TrainerType.RIVAL_4: - case TrainerType.RIVAL_5: - case TrainerType.RIVAL_6: - trainerType = TrainerType.RIVAL; - break; - case TrainerType.LANCE_CHAMPION: - trainerType = TrainerType.LANCE; - break; - case TrainerType.LARRY_ELITE: - trainerType = TrainerType.LARRY; - break; - case TrainerType.ROCKET_BOSS_GIOVANNI_1: - case TrainerType.ROCKET_BOSS_GIOVANNI_2: - trainerType = TrainerType.GIOVANNI; - break; - case TrainerType.MAXIE_2: - trainerType = TrainerType.MAXIE; - break; - case TrainerType.ARCHIE_2: - trainerType = TrainerType.ARCHIE; - break; - case TrainerType.CYRUS_2: - trainerType = TrainerType.CYRUS; - break; - case TrainerType.GHETSIS_2: - trainerType = TrainerType.GHETSIS; - break; - case TrainerType.LYSANDRE_2: - trainerType = TrainerType.LYSANDRE; - break; - case TrainerType.LUSAMINE_2: - trainerType = TrainerType.LUSAMINE; - break; - case TrainerType.GUZMA_2: - trainerType = TrainerType.GUZMA; - break; - case TrainerType.ROSE_2: - trainerType = TrainerType.ROSE; - break; - case TrainerType.PENNY_2: - trainerType = TrainerType.PENNY; - break; - case TrainerType.MARNIE_ELITE: - trainerType = TrainerType.MARNIE; - break; - case TrainerType.NESSA_ELITE: - trainerType = TrainerType.NESSA; - break; - case TrainerType.BEA_ELITE: - trainerType = TrainerType.BEA; - break; - case TrainerType.ALLISTER_ELITE: - trainerType = TrainerType.ALLISTER; - break; - case TrainerType.RAIHAN_ELITE: - trainerType = TrainerType.RAIHAN; - break; + case TrainerType.RIVAL_2: + case TrainerType.RIVAL_3: + case TrainerType.RIVAL_4: + case TrainerType.RIVAL_5: + case TrainerType.RIVAL_6: + trainerType = TrainerType.RIVAL; + break; + case TrainerType.LANCE_CHAMPION: + trainerType = TrainerType.LANCE; + break; + case TrainerType.LARRY_ELITE: + trainerType = TrainerType.LARRY; + break; + case TrainerType.ROCKET_BOSS_GIOVANNI_1: + case TrainerType.ROCKET_BOSS_GIOVANNI_2: + trainerType = TrainerType.GIOVANNI; + break; + case TrainerType.MAXIE_2: + trainerType = TrainerType.MAXIE; + break; + case TrainerType.ARCHIE_2: + trainerType = TrainerType.ARCHIE; + break; + case TrainerType.CYRUS_2: + trainerType = TrainerType.CYRUS; + break; + case TrainerType.GHETSIS_2: + trainerType = TrainerType.GHETSIS; + break; + case TrainerType.LYSANDRE_2: + trainerType = TrainerType.LYSANDRE; + break; + case TrainerType.LUSAMINE_2: + trainerType = TrainerType.LUSAMINE; + break; + case TrainerType.GUZMA_2: + trainerType = TrainerType.GUZMA; + break; + case TrainerType.ROSE_2: + trainerType = TrainerType.ROSE; + break; + case TrainerType.PENNY_2: + trainerType = TrainerType.PENNY; + break; + case TrainerType.MARNIE_ELITE: + trainerType = TrainerType.MARNIE; + break; + case TrainerType.NESSA_ELITE: + trainerType = TrainerType.NESSA; + break; + case TrainerType.BEA_ELITE: + trainerType = TrainerType.BEA; + break; + case TrainerType.ALLISTER_ELITE: + trainerType = TrainerType.ALLISTER; + break; + case TrainerType.RAIHAN_ELITE: + trainerType = TrainerType.RAIHAN; + break; case TrainerType.KOGA_GYM: trainerType = TrainerType.KOGA; break; @@ -535,7 +536,7 @@ export class TrainerConfig { } setSpeciesPools(speciesPools: TrainerTierPools | Species[]): TrainerConfig { - this.speciesPools = (Array.isArray(speciesPools) ? {[TrainerPoolTier.COMMON]: speciesPools} : speciesPools) as unknown as TrainerTierPools; + this.speciesPools = (Array.isArray(speciesPools) ? { [TrainerPoolTier.COMMON]: speciesPools } : speciesPools) as unknown as TrainerTierPools; return this; } @@ -555,6 +556,17 @@ export class TrainerConfig { return this; } + setEventModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig { + this.eventRewardFuncs = modifierTypeFuncs.map(func => () => { + const modifierTypeFunc = func(); + const modifierType = modifierTypeFunc(); + modifierType.withIdFromFunc(modifierTypeFunc); + return modifierType; + }); + return this; + } + + setModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig { this.modifierRewardFuncs = modifierTypeFuncs.map(func => () => { const modifierTypeFunc = func(); @@ -573,104 +585,104 @@ export class TrainerConfig { speciesPoolPerEvilTeamAdmin(team): TrainerTierPools { team = team.toLowerCase(); switch (team) { - case "rocket": { - return { - [TrainerPoolTier.COMMON]: [Species.RATTATA, Species.KOFFING, Species.EKANS, Species.ZUBAT, Species.MAGIKARP, Species.HOUNDOUR, Species.ONIX, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB, Species.DROWZEE, Species.VILEPLUME], - [TrainerPoolTier.UNCOMMON]: [Species.PORYGON, Species.MANKEY, Species.MAGNEMITE, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE, Species.PALDEA_TAUROS, Species.OMANYTE, Species.KABUTO, Species.MAGBY, Species.ELEKID], - [TrainerPoolTier.RARE]: [Species.DRATINI, Species.LARVITAR] - }; - } - case "magma": { - return { - [TrainerPoolTier.COMMON]: [Species.GROWLITHE, Species.SLUGMA, Species.SOLROCK, Species.HIPPOPOTAS, Species.BALTOY, Species.ROLYCOLY, Species.GLIGAR, Species.TORKOAL, Species.HOUNDOUR, Species.MAGBY], - [TrainerPoolTier.UNCOMMON]: [Species.TRAPINCH, Species.SILICOBRA, Species.RHYHORN, Species.ANORITH, Species.LILEEP, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON, Species.BARBOACH], - [TrainerPoolTier.RARE]: [Species.CAPSAKID, Species.CHARCADET] - }; - } - case "aqua": { - return { - [TrainerPoolTier.COMMON]: [Species.CORPHISH, Species.SPHEAL, Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.AZURILL, Species.LOTAD, Species.WAILMER, Species.REMORAID], - [TrainerPoolTier.UNCOMMON]: [Species.MANTYKE, Species.HISUI_QWILFISH, Species.ARROKUDA, Species.DHELMISE, Species.CLOBBOPUS, Species.FEEBAS, Species.PALDEA_WOOPER, Species.HORSEA, Species.SKRELP], - [TrainerPoolTier.RARE]: [Species.DONDOZO, Species.BASCULEGION] - }; - } - case "galactic": { - return { - [TrainerPoolTier.COMMON]: [Species.BRONZOR, Species.SWINUB, Species.YANMA, Species.LICKITUNG, Species.TANGELA, Species.MAGBY, Species.ELEKID, Species.SKORUPI, Species.ZUBAT, Species.MURKROW, Species.MAGIKARP, Species.VOLTORB], - [TrainerPoolTier.UNCOMMON]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.SNEASEL, Species.DUSKULL, Species.ROTOM, Species.HISUI_VOLTORB, Species.GLIGAR, Species.ABRA], - [TrainerPoolTier.RARE]: [Species.URSALUNA, Species.HISUI_LILLIGANT, Species.SPIRITOMB, Species.HISUI_SNEASEL] - }; - } - case "plasma": { - return { - [TrainerPoolTier.COMMON]: [Species.YAMASK, Species.ROGGENROLA, Species.JOLTIK, Species.TYMPOLE, Species.FRILLISH, Species.FERROSEED, Species.SANDILE, Species.TIMBURR, Species.DARUMAKA, Species.FOONGUS, Species.CUBCHOO, Species.VANILLITE], - [TrainerPoolTier.UNCOMMON]: [Species.PAWNIARD, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK, Species.TYNAMO, Species.GALAR_DARUMAKA, Species.GOLETT, Species.MIENFOO, Species.DURANT, Species.SIGILYPH], - [TrainerPoolTier.RARE]: [Species.HISUI_ZORUA, Species.AXEW, Species.DEINO, Species.HISUI_BRAVIARY] - }; - } - case "flare": { - return { - [TrainerPoolTier.COMMON]: [Species.FLETCHLING, Species.LITLEO, Species.INKAY, Species.HELIOPTILE, Species.ELECTRIKE, Species.SKORUPI, Species.PURRLOIN, Species.CLAWITZER, Species.PANCHAM, Species.ESPURR, Species.BUNNELBY], - [TrainerPoolTier.UNCOMMON]: [Species.LITWICK, Species.SNEASEL, Species.PUMPKABOO, Species.PHANTUMP, Species.HONEDGE, Species.BINACLE, Species.HOUNDOUR, Species.SKRELP, Species.SLIGGOO], - [TrainerPoolTier.RARE]: [Species.NOIVERN, Species.HISUI_AVALUGG, Species.HISUI_SLIGGOO] - }; - } - case "aether": { - return { - [TrainerPoolTier.COMMON]: [ Species.BRUXISH, Species.SLOWPOKE, Species.BALTOY, Species.EXEGGCUTE, Species.ABRA, Species.ALOLA_RAICHU, Species.ELGYEM, Species.NATU, Species.BLIPBUG, Species.GIRAFARIG, Species.ORANGURU], - [TrainerPoolTier.UNCOMMON]: [Species.GALAR_SLOWPOKE, Species.MEDITITE, Species.BELDUM, Species.HATENNA, Species.INKAY, Species.RALTS, Species.GALAR_MR_MIME], - [TrainerPoolTier.RARE]: [Species.ARMAROUGE, Species.HISUI_BRAVIARY, Species.PORYGON] - }; - } - case "skull": { - return { - [TrainerPoolTier.COMMON]: [ Species.MAREANIE, Species.ALOLA_GRIMER, Species.GASTLY, Species.ZUBAT, Species.FOMANTIS, Species.VENIPEDE, Species.BUDEW, Species.KOFFING, Species.STUNKY, Species.CROAGUNK, Species.NIDORAN_F], - [TrainerPoolTier.UNCOMMON]: [Species.GALAR_SLOWPOKE, Species.SKORUPI, Species.PALDEA_WOOPER, Species.VULLABY, Species.HISUI_QWILFISH, Species.GLIMMET], - [TrainerPoolTier.RARE]: [Species.SKRELP, Species.HISUI_SNEASEL] - }; - } - case "macro": { - return { - [TrainerPoolTier.COMMON]: [ Species.HATENNA, Species.FEEBAS, Species.BOUNSWEET, Species.SALANDIT, Species.GALAR_PONYTA, Species.GOTHITA, Species.FROSLASS, Species.VULPIX, Species.FRILLISH, Species.ODDISH, Species.SINISTEA], - [TrainerPoolTier.UNCOMMON]: [Species.VULLABY, Species.MAREANIE, Species.ALOLA_VULPIX, Species.TOGEPI, Species.GALAR_CORSOLA, Species.APPLIN], - [TrainerPoolTier.RARE]: [Species.TINKATINK, Species.HISUI_LILLIGANT] - }; - } - case "star_1": { - return { - [TrainerPoolTier.COMMON]: [ Species.MURKROW, Species.SEEDOT, Species.CACNEA, Species.STUNKY, Species.SANDILE, Species.NYMBLE, Species.MASCHIFF, Species.GALAR_ZIGZAGOON ], - [TrainerPoolTier.UNCOMMON]: [ Species.UMBREON, Species.SNEASEL, Species.CORPHISH, Species.ZORUA, Species.INKAY, Species.BOMBIRDIER ], - [TrainerPoolTier.RARE]: [ Species.DEINO, Species.SPRIGATITO ] - }; - } - case "star_2": { - return { - [TrainerPoolTier.COMMON]: [ Species.GROWLITHE, Species.HOUNDOUR, Species.NUMEL, Species.LITWICK, Species.FLETCHLING, Species.LITLEO, Species.ROLYCOLY, Species.CAPSAKID ], - [TrainerPoolTier.UNCOMMON]: [ Species.PONYTA, Species.FLAREON, Species.MAGBY, Species.TORKOAL, Species.SALANDIT, Species.TURTONATOR ], - [TrainerPoolTier.RARE]: [ Species.LARVESTA, Species.FUECOCO ] - }; - } - case "star_3": { - return { - [TrainerPoolTier.COMMON]: [ Species.ZUBAT, Species.GRIMER, Species.STUNKY, Species.FOONGUS, Species.MAREANIE, Species.TOXEL, Species.SHROODLE, Species.PALDEA_WOOPER ], - [TrainerPoolTier.UNCOMMON]: [ Species.GASTLY, Species.SEVIPER, Species.SKRELP, Species.ALOLA_GRIMER, Species.GALAR_SLOWPOKE, Species.HISUI_QWILFISH ], - [TrainerPoolTier.RARE]: [ Species.GLIMMET, Species.BULBASAUR ] - }; - } - case "star_4": { - return { - [TrainerPoolTier.COMMON]: [ Species.CLEFFA, Species.IGGLYBUFF, Species.AZURILL, Species.COTTONEE, Species.FLABEBE, Species.HATENNA, Species.IMPIDIMP, Species.TINKATINK ], - [TrainerPoolTier.UNCOMMON]: [ Species.TOGEPI, Species.GARDEVOIR, Species.SYLVEON, Species.KLEFKI, Species.MIMIKYU, Species.ALOLA_VULPIX ], - [TrainerPoolTier.RARE]: [ Species.GALAR_PONYTA, Species.POPPLIO ] - }; - } - case "star_5": { - return { - [TrainerPoolTier.COMMON]: [ Species.SHROOMISH, Species.MAKUHITA, Species.MEDITITE, Species.CROAGUNK, Species.SCRAGGY, Species.MIENFOO, Species.PAWMI, Species.PALDEA_TAUROS ], - [TrainerPoolTier.UNCOMMON]: [ Species.RIOLU, Species.TIMBURR, Species.HAWLUCHA, Species.PASSIMIAN, Species.FALINKS, Species.FLAMIGO ], - [TrainerPoolTier.RARE]: [ Species.JANGMO_O, Species.QUAXLY ] - }; - } + case "rocket": { + return { + [TrainerPoolTier.COMMON]: [ Species.RATTATA, Species.KOFFING, Species.EKANS, Species.ZUBAT, Species.MAGIKARP, Species.HOUNDOUR, Species.ONIX, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB, Species.DROWZEE, Species.VILEPLUME ], + [TrainerPoolTier.UNCOMMON]: [ Species.PORYGON, Species.MANKEY, Species.MAGNEMITE, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE, Species.PALDEA_TAUROS, Species.OMANYTE, Species.KABUTO, Species.MAGBY, Species.ELEKID ], + [TrainerPoolTier.RARE]: [ Species.DRATINI, Species.LARVITAR ] + }; + } + case "magma": { + return { + [TrainerPoolTier.COMMON]: [ Species.GROWLITHE, Species.SLUGMA, Species.SOLROCK, Species.HIPPOPOTAS, Species.BALTOY, Species.ROLYCOLY, Species.GLIGAR, Species.TORKOAL, Species.HOUNDOUR, Species.MAGBY ], + [TrainerPoolTier.UNCOMMON]: [ Species.TRAPINCH, Species.SILICOBRA, Species.RHYHORN, Species.ANORITH, Species.LILEEP, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON, Species.TOEDSCOOL ], + [TrainerPoolTier.RARE]: [ Species.CAPSAKID, Species.CHARCADET ] + }; + } + case "aqua": { + return { + [TrainerPoolTier.COMMON]: [ Species.CORPHISH, Species.SPHEAL, Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.AZURILL, Species.LOTAD, Species.WAILMER, Species.REMORAID, Species.BARBOACH ], + [TrainerPoolTier.UNCOMMON]: [ Species.MANTYKE, Species.HISUI_QWILFISH, Species.ARROKUDA, Species.DHELMISE, Species.CLOBBOPUS, Species.FEEBAS, Species.PALDEA_WOOPER, Species.HORSEA, Species.SKRELP ], + [TrainerPoolTier.RARE]: [ Species.DONDOZO, Species.BASCULEGION ] + }; + } + case "galactic": { + return { + [TrainerPoolTier.COMMON]: [ Species.BRONZOR, Species.SWINUB, Species.YANMA, Species.LICKITUNG, Species.TANGELA, Species.MAGBY, Species.ELEKID, Species.SKORUPI, Species.ZUBAT, Species.MURKROW, Species.MAGIKARP, Species.VOLTORB ], + [TrainerPoolTier.UNCOMMON]: [ Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.SNEASEL, Species.DUSKULL, Species.ROTOM, Species.HISUI_VOLTORB, Species.GLIGAR, Species.ABRA ], + [TrainerPoolTier.RARE]: [ Species.URSALUNA, Species.HISUI_LILLIGANT, Species.SPIRITOMB, Species.HISUI_SNEASEL ] + }; + } + case "plasma": { + return { + [TrainerPoolTier.COMMON]: [ Species.YAMASK, Species.ROGGENROLA, Species.JOLTIK, Species.TYMPOLE, Species.FRILLISH, Species.FERROSEED, Species.SANDILE, Species.TIMBURR, Species.DARUMAKA, Species.FOONGUS, Species.CUBCHOO, Species.VANILLITE ], + [TrainerPoolTier.UNCOMMON]: [ Species.PAWNIARD, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK, Species.TYNAMO, Species.GALAR_DARUMAKA, Species.GOLETT, Species.MIENFOO, Species.DURANT, Species.SIGILYPH ], + [TrainerPoolTier.RARE]: [ Species.HISUI_ZORUA, Species.AXEW, Species.DEINO, Species.HISUI_BRAVIARY ] + }; + } + case "flare": { + return { + [TrainerPoolTier.COMMON]: [ Species.FLETCHLING, Species.LITLEO, Species.INKAY, Species.FOONGUS, Species.HELIOPTILE, Species.ELECTRIKE, Species.SKORUPI, Species.PURRLOIN, Species.CLAWITZER, Species.PANCHAM, Species.ESPURR, Species.BUNNELBY ], + [TrainerPoolTier.UNCOMMON]: [ Species.LITWICK, Species.SNEASEL, Species.PUMPKABOO, Species.PHANTUMP, Species.HONEDGE, Species.BINACLE, Species.HOUNDOUR, Species.SKRELP, Species.SLIGGOO ], + [TrainerPoolTier.RARE]: [ Species.NOIBAT, Species.HISUI_AVALUGG, Species.HISUI_SLIGGOO ] + }; + } + case "aether": { + return { + [TrainerPoolTier.COMMON]: [ Species.BRUXISH, Species.SLOWPOKE, Species.BALTOY, Species.EXEGGCUTE, Species.ABRA, Species.ALOLA_RAICHU, Species.ELGYEM, Species.NATU, Species.BLIPBUG, Species.GIRAFARIG, Species.ORANGURU ], + [TrainerPoolTier.UNCOMMON]: [ Species.GALAR_SLOWPOKE, Species.MEDITITE, Species.BELDUM, Species.HATENNA, Species.INKAY, Species.RALTS, Species.GALAR_MR_MIME ], + [TrainerPoolTier.RARE]: [ Species.ARMAROUGE, Species.HISUI_BRAVIARY, Species.PORYGON ] + }; + } + case "skull": { + return { + [TrainerPoolTier.COMMON]: [ Species.MAREANIE, Species.ALOLA_GRIMER, Species.GASTLY, Species.ZUBAT, Species.FOMANTIS, Species.VENIPEDE, Species.BUDEW, Species.KOFFING, Species.STUNKY, Species.CROAGUNK, Species.NIDORAN_F ], + [TrainerPoolTier.UNCOMMON]: [ Species.GALAR_SLOWPOKE, Species.SKORUPI, Species.PALDEA_WOOPER, Species.VULLABY, Species.HISUI_QWILFISH, Species.GLIMMET ], + [TrainerPoolTier.RARE]: [ Species.SKRELP, Species.HISUI_SNEASEL ] + }; + } + case "macro": { + return { + [TrainerPoolTier.COMMON]: [ Species.HATENNA, Species.FEEBAS, Species.BOUNSWEET, Species.SALANDIT, Species.GALAR_PONYTA, Species.GOTHITA, Species.FROSLASS, Species.VULPIX, Species.FRILLISH, Species.ODDISH, Species.SINISTEA ], + [TrainerPoolTier.UNCOMMON]: [ Species.VULLABY, Species.MAREANIE, Species.ALOLA_VULPIX, Species.TOGEPI, Species.GALAR_CORSOLA, Species.APPLIN ], + [TrainerPoolTier.RARE]: [ Species.TINKATINK, Species.HISUI_LILLIGANT ] + }; + } + case "star_1": { + return { + [TrainerPoolTier.COMMON]: [ Species.MURKROW, Species.SEEDOT, Species.CACNEA, Species.STUNKY, Species.SANDILE, Species.NYMBLE, Species.MASCHIFF, Species.GALAR_ZIGZAGOON ], + [TrainerPoolTier.UNCOMMON]: [ Species.UMBREON, Species.SNEASEL, Species.CORPHISH, Species.ZORUA, Species.INKAY, Species.BOMBIRDIER ], + [TrainerPoolTier.RARE]: [ Species.DEINO, Species.SPRIGATITO ] + }; + } + case "star_2": { + return { + [TrainerPoolTier.COMMON]: [ Species.GROWLITHE, Species.HOUNDOUR, Species.NUMEL, Species.LITWICK, Species.FLETCHLING, Species.LITLEO, Species.ROLYCOLY, Species.CAPSAKID ], + [TrainerPoolTier.UNCOMMON]: [ Species.PONYTA, Species.FLAREON, Species.MAGBY, Species.TORKOAL, Species.SALANDIT, Species.TURTONATOR ], + [TrainerPoolTier.RARE]: [ Species.LARVESTA, Species.FUECOCO ] + }; + } + case "star_3": { + return { + [TrainerPoolTier.COMMON]: [ Species.ZUBAT, Species.GRIMER, Species.STUNKY, Species.FOONGUS, Species.MAREANIE, Species.TOXEL, Species.SHROODLE, Species.PALDEA_WOOPER ], + [TrainerPoolTier.UNCOMMON]: [ Species.GASTLY, Species.SEVIPER, Species.SKRELP, Species.ALOLA_GRIMER, Species.GALAR_SLOWPOKE, Species.HISUI_QWILFISH ], + [TrainerPoolTier.RARE]: [ Species.GLIMMET, Species.BULBASAUR ] + }; + } + case "star_4": { + return { + [TrainerPoolTier.COMMON]: [ Species.CLEFFA, Species.IGGLYBUFF, Species.AZURILL, Species.COTTONEE, Species.FLABEBE, Species.HATENNA, Species.IMPIDIMP, Species.TINKATINK ], + [TrainerPoolTier.UNCOMMON]: [ Species.TOGEPI, Species.GARDEVOIR, Species.SYLVEON, Species.KLEFKI, Species.MIMIKYU, Species.ALOLA_VULPIX ], + [TrainerPoolTier.RARE]: [ Species.GALAR_PONYTA, Species.POPPLIO ] + }; + } + case "star_5": { + return { + [TrainerPoolTier.COMMON]: [ Species.SHROOMISH, Species.MAKUHITA, Species.MEDITITE, Species.CROAGUNK, Species.SCRAGGY, Species.MIENFOO, Species.PAWMI, Species.PALDEA_TAUROS ], + [TrainerPoolTier.UNCOMMON]: [ Species.RIOLU, Species.TIMBURR, Species.HAWLUCHA, Species.PASSIMIAN, Species.FALINKS, Species.FLAMIGO ], + [TrainerPoolTier.RARE]: [ Species.JANGMO_O, Species.QUAXLY ] + }; + } } console.warn(`Evil team admin for ${team} not found. Returning empty species pools.`); @@ -696,7 +708,7 @@ export class TrainerConfig { signatureSpecies.forEach((speciesPool, s) => { if (!Array.isArray(speciesPool)) { - speciesPool = [speciesPool]; + speciesPool = [ speciesPool ]; } this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); }); @@ -734,7 +746,7 @@ export class TrainerConfig { signatureSpecies.forEach((speciesPool, s) => { if (!Array.isArray(speciesPool)) { - speciesPool = [speciesPool]; + speciesPool = [ speciesPool ]; } this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); }); @@ -773,7 +785,7 @@ export class TrainerConfig { } signatureSpecies.forEach((speciesPool, s) => { if (!Array.isArray(speciesPool)) { - speciesPool = [speciesPool]; + speciesPool = [ speciesPool ]; } this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); }); @@ -814,7 +826,7 @@ export class TrainerConfig { signatureSpecies.forEach((speciesPool, s) => { // Ensure speciesPool is an array. if (!Array.isArray(speciesPool)) { - speciesPool = [speciesPool]; + speciesPool = [ speciesPool ]; } // Set a function to get a random party member from the species pool. this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); @@ -871,7 +883,7 @@ export class TrainerConfig { signatureSpecies.forEach((speciesPool, s) => { // Ensure speciesPool is an array. if (!Array.isArray(speciesPool)) { - speciesPool = [speciesPool]; + speciesPool = [ speciesPool ]; } // Set a function to get a random party member from the species pool. this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); @@ -926,7 +938,7 @@ export class TrainerConfig { signatureSpecies.forEach((speciesPool, s) => { // Ensure speciesPool is an array. if (!Array.isArray(speciesPool)) { - speciesPool = [speciesPool]; + speciesPool = [ speciesPool ]; } // Set a function to get a random party member from the species pool. this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); @@ -1211,7 +1223,7 @@ function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, type?: Ty for (; t < Math.min(count, party.length); t++) { const randomIndex = Utils.randSeedItem(partyMemberIndexes); partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1); - ret.push(modifierTypes.TERA_SHARD().generateType([], [Utils.randSeedItem(type ? [type] : party[randomIndex].getTypes())])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct? + ret.push(modifierTypes.TERA_SHARD().generateType([], [ Utils.randSeedItem(type ? [type] : party[randomIndex].getTypes()) ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct? } return ret; } @@ -1363,15 +1375,15 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders("Ace Trainer Female").setHasDouble("Ace Duo").setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER) .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.THREE_WEAK_BALANCED, trainerPartyTemplates.FOUR_WEAK_BALANCED, trainerPartyTemplates.FIVE_WEAK_BALANCED, trainerPartyTemplates.SIX_WEAK_BALANCED)), [TrainerType.ARTIST]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.THREE_AVG) - .setSpeciesPools([Species.SMEARGLE]), + .setSpeciesPools([ Species.SMEARGLE ]), [TrainerType.BACKERS]: new TrainerConfig(++t).setHasGenders("Backers").setDoubleOnly().setEncounterBgm(TrainerType.CYCLIST), [TrainerType.BACKPACKER]: new TrainerConfig(++t).setHasGenders("Backpacker Female").setHasDouble("Backpackers").setSpeciesFilter(s => s.isOfType(Type.FLYING) || s.isOfType(Type.ROCK)).setEncounterBgm(TrainerType.BACKPACKER) .setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.ONE_WEAK_ONE_STRONG, trainerPartyTemplates.ONE_AVG_ONE_STRONG) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.RHYHORN, Species.AIPOM, Species.MAKUHITA, Species.MAWILE, Species.NUMEL, Species.LILLIPUP, Species.SANDILE, Species.WOOLOO], - [TrainerPoolTier.UNCOMMON]: [Species.GIRAFARIG, Species.ZANGOOSE, Species.SEVIPER, Species.CUBCHOO, Species.PANCHAM, Species.SKIDDO, Species.MUDBRAY], - [TrainerPoolTier.RARE]: [Species.TAUROS, Species.STANTLER, Species.DARUMAKA, Species.BOUFFALANT, Species.DEERLING, Species.IMPIDIMP], - [TrainerPoolTier.SUPER_RARE]: [Species.GALAR_DARUMAKA, Species.TEDDIURSA] + [TrainerPoolTier.COMMON]: [ Species.RHYHORN, Species.AIPOM, Species.MAKUHITA, Species.MAWILE, Species.NUMEL, Species.LILLIPUP, Species.SANDILE, Species.WOOLOO ], + [TrainerPoolTier.UNCOMMON]: [ Species.GIRAFARIG, Species.ZANGOOSE, Species.SEVIPER, Species.CUBCHOO, Species.PANCHAM, Species.SKIDDO, Species.MUDBRAY ], + [TrainerPoolTier.RARE]: [ Species.TAUROS, Species.STANTLER, Species.DARUMAKA, Species.BOUFFALANT, Species.DEERLING, Species.IMPIDIMP ], + [TrainerPoolTier.SUPER_RARE]: [ Species.GALAR_DARUMAKA, Species.TEDDIURSA ] }), [TrainerType.BAKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.35).setSpeciesFilter(s => s.isOfType(Type.GRASS) || s.isOfType(Type.FIRE)), [TrainerType.BEAUTY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY), @@ -1379,11 +1391,11 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.BLACK_BELT]: new TrainerConfig(++t).setHasGenders("Battle Girl", TrainerType.PSYCHIC).setHasDouble("Crush Kin").setEncounterBgm(TrainerType.ROUGHNECK).setSpecialtyType(Type.FIGHTING) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_ONE_STRONG, trainerPartyTemplates.THREE_AVG, trainerPartyTemplates.TWO_AVG_ONE_STRONG) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.NIDORAN_F, Species.NIDORAN_M, Species.MACHOP, Species.MAKUHITA, Species.MEDITITE, Species.CROAGUNK, Species.TIMBURR], - [TrainerPoolTier.UNCOMMON]: [Species.MANKEY, Species.POLIWRATH, Species.TYROGUE, Species.BRELOOM, Species.SCRAGGY, Species.MIENFOO, Species.PANCHAM, Species.STUFFUL, Species.CRABRAWLER], - [TrainerPoolTier.RARE]: [Species.HERACROSS, Species.RIOLU, Species.THROH, Species.SAWK, Species.PASSIMIAN, Species.CLOBBOPUS], - [TrainerPoolTier.SUPER_RARE]: [Species.HITMONTOP, Species.INFERNAPE, Species.GALLADE, Species.HAWLUCHA, Species.HAKAMO_O], - [TrainerPoolTier.ULTRA_RARE]: [Species.KUBFU] + [TrainerPoolTier.COMMON]: [ Species.NIDORAN_F, Species.NIDORAN_M, Species.MACHOP, Species.MAKUHITA, Species.MEDITITE, Species.CROAGUNK, Species.TIMBURR ], + [TrainerPoolTier.UNCOMMON]: [ Species.MANKEY, Species.POLIWRATH, Species.TYROGUE, Species.BRELOOM, Species.SCRAGGY, Species.MIENFOO, Species.PANCHAM, Species.STUFFUL, Species.CRABRAWLER ], + [TrainerPoolTier.RARE]: [ Species.HERACROSS, Species.RIOLU, Species.THROH, Species.SAWK, Species.PASSIMIAN, Species.CLOBBOPUS ], + [TrainerPoolTier.SUPER_RARE]: [ Species.HITMONTOP, Species.INFERNAPE, Species.GALLADE, Species.HAWLUCHA, Species.HAKAMO_O ], + [TrainerPoolTier.ULTRA_RARE]: [ Species.KUBFU ] }), [TrainerType.BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(1.325).setEncounterBgm(TrainerType.POKEFAN).setHasGenders("Breeder Female").setHasDouble("Breeders") .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.FIVE_WEAKER, trainerPartyTemplates.SIX_WEAKER)) @@ -1391,25 +1403,25 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders("Clerk Female").setHasDouble("Colleagues").setEncounterBgm(TrainerType.CLERK) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.THREE_WEAK, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.MEOWTH, Species.PSYDUCK, Species.BUDEW, Species.PIDOVE, Species.CINCCINO, Species.LITLEO], - [TrainerPoolTier.UNCOMMON]: [Species.JIGGLYPUFF, Species.MAGNEMITE, Species.MARILL, Species.COTTONEE, Species.SKIDDO], - [TrainerPoolTier.RARE]: [Species.BUIZEL, Species.SNEASEL, Species.KLEFKI, Species.INDEEDEE] + [TrainerPoolTier.COMMON]: [ Species.MEOWTH, Species.PSYDUCK, Species.BUDEW, Species.PIDOVE, Species.CINCCINO, Species.LITLEO ], + [TrainerPoolTier.UNCOMMON]: [ Species.JIGGLYPUFF, Species.MAGNEMITE, Species.MARILL, Species.COTTONEE, Species.SKIDDO ], + [TrainerPoolTier.RARE]: [ Species.BUIZEL, Species.SNEASEL, Species.KLEFKI, Species.INDEEDEE ] }), [TrainerType.CYCLIST]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setHasGenders("Cyclist Female").setHasDouble("Cyclists").setEncounterBgm(TrainerType.CYCLIST) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.ONE_AVG) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.PICHU, Species.STARLY, Species.TAILLOW, Species.BOLTUND], - [TrainerPoolTier.UNCOMMON]: [Species.DODUO, Species.ELECTRIKE, Species.BLITZLE, Species.WATTREL], - [TrainerPoolTier.RARE]: [Species.YANMA, Species.NINJASK, Species.WHIRLIPEDE, Species.EMOLGA], - [TrainerPoolTier.SUPER_RARE]: [Species.ACCELGOR, Species.DREEPY] + [TrainerPoolTier.COMMON]: [ Species.PICHU, Species.STARLY, Species.TAILLOW, Species.BOLTUND ], + [TrainerPoolTier.UNCOMMON]: [ Species.DODUO, Species.ELECTRIKE, Species.BLITZLE, Species.WATTREL ], + [TrainerPoolTier.RARE]: [ Species.YANMA, Species.NINJASK, Species.WHIRLIPEDE, Species.EMOLGA ], + [TrainerPoolTier.SUPER_RARE]: [ Species.ACCELGOR, Species.DREEPY ] }), [TrainerType.DANCER]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.CYCLIST) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_TWO_WEAK_SAME) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.RALTS, Species.SPOINK, Species.LOTAD, Species.BUDEW], - [TrainerPoolTier.UNCOMMON]: [Species.SPINDA, Species.SWABLU, Species.MARACTUS,], - [TrainerPoolTier.RARE]: [Species.BELLOSSOM, Species.HITMONTOP, Species.MIME_JR, Species.ORICORIO], - [TrainerPoolTier.SUPER_RARE]: [Species.POPPLIO] + [TrainerPoolTier.COMMON]: [ Species.RALTS, Species.SPOINK, Species.LOTAD, Species.BUDEW ], + [TrainerPoolTier.UNCOMMON]: [ Species.SPINDA, Species.SWABLU, Species.MARACTUS, ], + [TrainerPoolTier.RARE]: [ Species.BELLOSSOM, Species.HITMONTOP, Species.MIME_JR, Species.ORICORIO ], + [TrainerPoolTier.SUPER_RARE]: [ Species.POPPLIO ] }), [TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setMoneyMultiplier(1.45).setEncounterBgm(TrainerType.CLERK), [TrainerType.DOCTOR]: new TrainerConfig(++t).setHasGenders("Nurse", "lass").setHasDouble("Medical Team").setMoneyMultiplier(3).setEncounterBgm(TrainerType.CLERK) @@ -1419,20 +1431,20 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.FISHERMAN]: new TrainerConfig(++t).setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.BACKPACKER).setSpecialtyType(Type.WATER) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.THREE_WEAK_SAME, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.SIX_WEAKER) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.TENTACOOL, Species.MAGIKARP, Species.GOLDEEN, Species.STARYU, Species.REMORAID, Species.SKRELP, Species.CLAUNCHER, Species.ARROKUDA], - [TrainerPoolTier.UNCOMMON]: [Species.POLIWAG, Species.SHELLDER, Species.KRABBY, Species.HORSEA, Species.CARVANHA, Species.BARBOACH, Species.CORPHISH, Species.FINNEON, Species.TYMPOLE, Species.BASCULIN, Species.FRILLISH, Species.INKAY], - [TrainerPoolTier.RARE]: [Species.CHINCHOU, Species.CORSOLA, Species.WAILMER, Species.BARBOACH, Species.CLAMPERL, Species.LUVDISC, Species.MANTYKE, Species.ALOMOMOLA, Species.TATSUGIRI, Species.VELUZA], - [TrainerPoolTier.SUPER_RARE]: [Species.LAPRAS, Species.FEEBAS, Species.RELICANTH, Species.DONDOZO] + [TrainerPoolTier.COMMON]: [ Species.TENTACOOL, Species.MAGIKARP, Species.GOLDEEN, Species.STARYU, Species.REMORAID, Species.SKRELP, Species.CLAUNCHER, Species.ARROKUDA ], + [TrainerPoolTier.UNCOMMON]: [ Species.POLIWAG, Species.SHELLDER, Species.KRABBY, Species.HORSEA, Species.CARVANHA, Species.BARBOACH, Species.CORPHISH, Species.FINNEON, Species.TYMPOLE, Species.BASCULIN, Species.FRILLISH, Species.INKAY ], + [TrainerPoolTier.RARE]: [ Species.CHINCHOU, Species.CORSOLA, Species.WAILMER, Species.BARBOACH, Species.CLAMPERL, Species.LUVDISC, Species.MANTYKE, Species.ALOMOMOLA, Species.TATSUGIRI, Species.VELUZA ], + [TrainerPoolTier.SUPER_RARE]: [ Species.LAPRAS, Species.FEEBAS, Species.RELICANTH, Species.DONDOZO ] }), [TrainerType.GUITARIST]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.ROUGHNECK).setSpecialtyType(Type.ELECTRIC).setSpeciesFilter(s => s.isOfType(Type.ELECTRIC)), [TrainerType.HARLEQUIN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PSYCHIC).setSpeciesFilter(s => tmSpecies[Moves.TRICK_ROOM].indexOf(s.speciesId) > -1), [TrainerType.HIKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.BACKPACKER) .setPartyTemplates(trainerPartyTemplates.TWO_AVG_SAME_ONE_AVG, trainerPartyTemplates.TWO_AVG_SAME_ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.ONE_STRONG) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.SANDSHREW, Species.DIGLETT, Species.GEODUDE, Species.MACHOP, Species.ARON, Species.ROGGENROLA, Species.DRILBUR, Species.NACLI], - [TrainerPoolTier.UNCOMMON]: [Species.ZUBAT, Species.RHYHORN, Species.ONIX, Species.CUBONE, Species.WOOBAT, Species.SWINUB, Species.NOSEPASS, Species.HIPPOPOTAS, Species.DWEBBLE, Species.KLAWF, Species.TOEDSCOOL], - [TrainerPoolTier.RARE]: [Species.TORKOAL, Species.TRAPINCH, Species.BARBOACH, Species.GOLETT, Species.ALOLA_DIGLETT, Species.ALOLA_GEODUDE, Species.GALAR_STUNFISK, Species.PALDEA_WOOPER], - [TrainerPoolTier.SUPER_RARE]: [Species.MAGBY, Species.LARVITAR] + [TrainerPoolTier.COMMON]: [ Species.SANDSHREW, Species.DIGLETT, Species.GEODUDE, Species.MACHOP, Species.ARON, Species.ROGGENROLA, Species.DRILBUR, Species.NACLI ], + [TrainerPoolTier.UNCOMMON]: [ Species.ZUBAT, Species.RHYHORN, Species.ONIX, Species.CUBONE, Species.WOOBAT, Species.SWINUB, Species.NOSEPASS, Species.HIPPOPOTAS, Species.DWEBBLE, Species.KLAWF, Species.TOEDSCOOL ], + [TrainerPoolTier.RARE]: [ Species.TORKOAL, Species.TRAPINCH, Species.BARBOACH, Species.GOLETT, Species.ALOLA_DIGLETT, Species.ALOLA_GEODUDE, Species.GALAR_STUNFISK, Species.PALDEA_WOOPER ], + [TrainerPoolTier.SUPER_RARE]: [ Species.MAGBY, Species.LARVITAR ] }), [TrainerType.HOOLIGANS]: new TrainerConfig(++t).setDoubleOnly().setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.POISON) || s.isOfType(Type.DARK)), [TrainerType.HOOPSTER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), @@ -1448,11 +1460,11 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.OFFICER]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.CLERK) .setPartyTemplates(trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.VULPIX, Species.GROWLITHE, Species.SNUBBULL, Species.POOCHYENA, Species.ELECTRIKE, Species.LILLIPUP, Species.YAMPER, Species.FIDOUGH], - [TrainerPoolTier.UNCOMMON]: [Species.HOUNDOUR, Species.ROCKRUFF, Species.MASCHIFF], - [TrainerPoolTier.RARE]: [Species.JOLTEON, Species.RIOLU], + [TrainerPoolTier.COMMON]: [ Species.VULPIX, Species.GROWLITHE, Species.SNUBBULL, Species.POOCHYENA, Species.ELECTRIKE, Species.LILLIPUP, Species.YAMPER, Species.FIDOUGH ], + [TrainerPoolTier.UNCOMMON]: [ Species.HOUNDOUR, Species.ROCKRUFF, Species.MASCHIFF ], + [TrainerPoolTier.RARE]: [ Species.JOLTEON, Species.RIOLU ], [TrainerPoolTier.SUPER_RARE]: [], - [TrainerPoolTier.ULTRA_RARE]: [Species.ENTEI, Species.SUICUNE, Species.RAIKOU] + [TrainerPoolTier.ULTRA_RARE]: [ Species.ENTEI, Species.SUICUNE, Species.RAIKOU ] }), [TrainerType.PARASOL_LADY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY).setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.PILOT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => tmSpecies[Moves.FLY].indexOf(s.speciesId) > -1), @@ -1461,25 +1473,25 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.PRESCHOOLER]: new TrainerConfig(++t).setMoneyMultiplier(0.2).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("Preschooler Female", "lass").setHasDouble("Preschoolers") .setPartyTemplates(trainerPartyTemplates.THREE_WEAK, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.FIVE_WEAKER) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.CATERPIE, Species.PICHU, Species.SANDSHREW, Species.LEDYBA, Species.BUDEW, Species.BURMY, Species.WOOLOO, Species.PAWMI, Species.SMOLIV], - [TrainerPoolTier.UNCOMMON]: [Species.EEVEE, Species.CLEFFA, Species.IGGLYBUFF, Species.SWINUB, Species.WOOPER, Species.DRIFLOON, Species.DEDENNE, Species.STUFFUL], - [TrainerPoolTier.RARE]: [Species.RALTS, Species.RIOLU, Species.JOLTIK, Species.TANDEMAUS], - [TrainerPoolTier.SUPER_RARE]: [Species.DARUMAKA, Species.TINKATINK], + [TrainerPoolTier.COMMON]: [ Species.CATERPIE, Species.PICHU, Species.SANDSHREW, Species.LEDYBA, Species.BUDEW, Species.BURMY, Species.WOOLOO, Species.PAWMI, Species.SMOLIV ], + [TrainerPoolTier.UNCOMMON]: [ Species.EEVEE, Species.CLEFFA, Species.IGGLYBUFF, Species.SWINUB, Species.WOOPER, Species.DRIFLOON, Species.DEDENNE, Species.STUFFUL ], + [TrainerPoolTier.RARE]: [ Species.RALTS, Species.RIOLU, Species.JOLTIK, Species.TANDEMAUS ], + [TrainerPoolTier.SUPER_RARE]: [ Species.DARUMAKA, Species.TINKATINK ], }), [TrainerType.PSYCHIC]: new TrainerConfig(++t).setHasGenders("Psychic Female").setHasDouble("Psychics").setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.PSYCHIC) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.TWO_WEAK_SAME_TWO_WEAK_SAME, trainerPartyTemplates.ONE_STRONGER) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.ABRA, Species.DROWZEE, Species.RALTS, Species.SPOINK, Species.GOTHITA, Species.SOLOSIS, Species.BLIPBUG, Species.ESPURR, Species.HATENNA], - [TrainerPoolTier.UNCOMMON]: [Species.MIME_JR, Species.EXEGGCUTE, Species.MEDITITE, Species.NATU, Species.EXEGGCUTE, Species.WOOBAT, Species.INKAY, Species.ORANGURU], - [TrainerPoolTier.RARE]: [Species.ELGYEM, Species.SIGILYPH, Species.BALTOY, Species.GIRAFARIG, Species.MEOWSTIC], - [TrainerPoolTier.SUPER_RARE]: [Species.BELDUM, Species.ESPEON, Species.STANTLER], + [TrainerPoolTier.COMMON]: [ Species.ABRA, Species.DROWZEE, Species.RALTS, Species.SPOINK, Species.GOTHITA, Species.SOLOSIS, Species.BLIPBUG, Species.ESPURR, Species.HATENNA ], + [TrainerPoolTier.UNCOMMON]: [ Species.MIME_JR, Species.EXEGGCUTE, Species.MEDITITE, Species.NATU, Species.EXEGGCUTE, Species.WOOBAT, Species.INKAY, Species.ORANGURU ], + [TrainerPoolTier.RARE]: [ Species.ELGYEM, Species.SIGILYPH, Species.BALTOY, Species.GIRAFARIG, Species.MEOWSTIC ], + [TrainerPoolTier.SUPER_RARE]: [ Species.BELDUM, Species.ESPEON, Species.STANTLER ], }), [TrainerType.RANGER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setName("Pokémon Ranger").setEncounterBgm(TrainerType.BACKPACKER).setHasGenders("Pokémon Ranger Female").setHasDouble("Pokémon Rangers") .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.PICHU, Species.GROWLITHE, Species.PONYTA, Species.ZIGZAGOON, Species.SEEDOT, Species.BIDOOF, Species.RIOLU, Species.SEWADDLE, Species.SKIDDO, Species.SALANDIT, Species.YAMPER], - [TrainerPoolTier.UNCOMMON]: [Species.AZURILL, Species.TAUROS, Species.MAREEP, Species.FARFETCHD, Species.TEDDIURSA, Species.SHROOMISH, Species.ELECTRIKE, Species.BUDEW, Species.BUIZEL, Species.MUDBRAY, Species.STUFFUL], - [TrainerPoolTier.RARE]: [Species.EEVEE, Species.SCYTHER, Species.KANGASKHAN, Species.RALTS, Species.MUNCHLAX, Species.ZORUA, Species.PALDEA_TAUROS, Species.TINKATINK, Species.CYCLIZAR, Species.FLAMIGO], - [TrainerPoolTier.SUPER_RARE]: [Species.LARVESTA], + [TrainerPoolTier.COMMON]: [ Species.PICHU, Species.GROWLITHE, Species.PONYTA, Species.ZIGZAGOON, Species.SEEDOT, Species.BIDOOF, Species.RIOLU, Species.SEWADDLE, Species.SKIDDO, Species.SALANDIT, Species.YAMPER ], + [TrainerPoolTier.UNCOMMON]: [ Species.AZURILL, Species.TAUROS, Species.MAREEP, Species.FARFETCHD, Species.TEDDIURSA, Species.SHROOMISH, Species.ELECTRIKE, Species.BUDEW, Species.BUIZEL, Species.MUDBRAY, Species.STUFFUL ], + [TrainerPoolTier.RARE]: [ Species.EEVEE, Species.SCYTHER, Species.KANGASKHAN, Species.RALTS, Species.MUNCHLAX, Species.ZORUA, Species.PALDEA_TAUROS, Species.TINKATINK, Species.CYCLIZAR, Species.FLAMIGO ], + [TrainerPoolTier.SUPER_RARE]: [ Species.LARVESTA ], }), [TrainerType.RICH]: new TrainerConfig(++t).setMoneyMultiplier(5).setName("Gentleman").setHasGenders("Madame").setHasDouble("Rich Couple"), [TrainerType.RICH_KID]: new TrainerConfig(++t).setMoneyMultiplier(3.75).setName("Rich Boy").setHasGenders("Lady").setHasDouble("Rich Kids").setEncounterBgm(TrainerType.RICH), @@ -1487,150 +1499,150 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.SAILOR]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.BACKPACKER).setSpeciesFilter(s => s.isOfType(Type.WATER) || s.isOfType(Type.FIGHTING)), [TrainerType.SCIENTIST]: new TrainerConfig(++t).setHasGenders("Scientist Female").setHasDouble("Scientists").setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.SCIENTIST) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.MAGNEMITE, Species.GRIMER, Species.DROWZEE, Species.VOLTORB, Species.KOFFING], - [TrainerPoolTier.UNCOMMON]: [Species.BALTOY, Species.BRONZOR, Species.FERROSEED, Species.KLINK, Species.CHARJABUG, Species.BLIPBUG, Species.HELIOPTILE], - [TrainerPoolTier.RARE]: [Species.ABRA, Species.DITTO, Species.PORYGON, Species.ELEKID, Species.SOLOSIS, Species.GALAR_WEEZING], - [TrainerPoolTier.SUPER_RARE]: [Species.OMANYTE, Species.KABUTO, Species.AERODACTYL, Species.LILEEP, Species.ANORITH, Species.CRANIDOS, Species.SHIELDON, Species.TIRTOUGA, Species.ARCHEN, Species.ARCTOVISH, Species.ARCTOZOLT, Species.DRACOVISH, Species.DRACOZOLT], - [TrainerPoolTier.ULTRA_RARE]: [Species.ROTOM, Species.MELTAN] + [TrainerPoolTier.COMMON]: [ Species.MAGNEMITE, Species.GRIMER, Species.DROWZEE, Species.VOLTORB, Species.KOFFING ], + [TrainerPoolTier.UNCOMMON]: [ Species.BALTOY, Species.BRONZOR, Species.FERROSEED, Species.KLINK, Species.CHARJABUG, Species.BLIPBUG, Species.HELIOPTILE ], + [TrainerPoolTier.RARE]: [ Species.ABRA, Species.DITTO, Species.PORYGON, Species.ELEKID, Species.SOLOSIS, Species.GALAR_WEEZING ], + [TrainerPoolTier.SUPER_RARE]: [ Species.OMANYTE, Species.KABUTO, Species.AERODACTYL, Species.LILEEP, Species.ANORITH, Species.CRANIDOS, Species.SHIELDON, Species.TIRTOUGA, Species.ARCHEN, Species.ARCTOVISH, Species.ARCTOZOLT, Species.DRACOVISH, Species.DRACOZOLT ], + [TrainerPoolTier.ULTRA_RARE]: [ Species.ROTOM, Species.MELTAN ] }), [TrainerType.SMASHER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.SNOW_WORKER]: new TrainerConfig(++t).setName("Worker").setHasDouble("Workers").setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ICE) || s.isOfType(Type.STEEL)), [TrainerType.STRIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.SCHOOL_KID]: new TrainerConfig(++t).setMoneyMultiplier(0.75).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("School Kid Female", "lass").setHasDouble("School Kids") .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.ODDISH, Species.EXEGGCUTE, Species.TEDDIURSA, Species.WURMPLE, Species.RALTS, Species.SHROOMISH, Species.FLETCHLING], - [TrainerPoolTier.UNCOMMON]: [Species.VOLTORB, Species.WHISMUR, Species.MEDITITE, Species.MIME_JR, Species.NYMBLE], - [TrainerPoolTier.RARE]: [Species.TANGELA, Species.EEVEE, Species.YANMA], - [TrainerPoolTier.SUPER_RARE]: [Species.TADBULB] + [TrainerPoolTier.COMMON]: [ Species.ODDISH, Species.EXEGGCUTE, Species.TEDDIURSA, Species.WURMPLE, Species.RALTS, Species.SHROOMISH, Species.FLETCHLING ], + [TrainerPoolTier.UNCOMMON]: [ Species.VOLTORB, Species.WHISMUR, Species.MEDITITE, Species.MIME_JR, Species.NYMBLE ], + [TrainerPoolTier.RARE]: [ Species.TANGELA, Species.EEVEE, Species.YANMA ], + [TrainerPoolTier.SUPER_RARE]: [ Species.TADBULB ] }), [TrainerType.SWIMMER]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders("Swimmer Female").setHasDouble("Swimmers").setSpecialtyType(Type.WATER).setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.TWINS]: new TrainerConfig(++t).setDoubleOnly().setMoneyMultiplier(0.65).setUseSameSeedForAllMembers() .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_STRONG)) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PLUSLE, Species.VOLBEAT, Species.PACHIRISU, Species.SILCOON, Species.METAPOD, Species.IGGLYBUFF, Species.PETILIL, Species.EEVEE])) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.MINUN, Species.ILLUMISE, Species.EMOLGA, Species.CASCOON, Species.KAKUNA, Species.CLEFFA, Species.COTTONEE, Species.EEVEE], TrainerSlot.TRAINER_PARTNER)) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PLUSLE, Species.VOLBEAT, Species.PACHIRISU, Species.SILCOON, Species.METAPOD, Species.IGGLYBUFF, Species.PETILIL, Species.EEVEE ])) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.MINUN, Species.ILLUMISE, Species.EMOLGA, Species.CASCOON, Species.KAKUNA, Species.CLEFFA, Species.COTTONEE, Species.EEVEE ], TrainerSlot.TRAINER_PARTNER)) .setEncounterBgm(TrainerType.TWINS), [TrainerType.VETERAN]: new TrainerConfig(++t).setHasGenders("Veteran Female").setHasDouble("Veteran Duo").setMoneyMultiplier(2.5).setEncounterBgm(TrainerType.ACE_TRAINER).setSpeciesFilter(s => s.isOfType(Type.DRAGON)), [TrainerType.WAITER]: new TrainerConfig(++t).setHasGenders("Waitress").setHasDouble("Restaurant Staff").setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.CLERK) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.CLEFFA, Species.CHATOT, Species.PANSAGE, Species.PANSEAR, Species.PANPOUR, Species.MINCCINO], - [TrainerPoolTier.UNCOMMON]: [Species.TROPIUS, Species.PETILIL, Species.BOUNSWEET, Species.INDEEDEE], - [TrainerPoolTier.RARE]: [Species.APPLIN, Species.SINISTEA, Species.POLTCHAGEIST] + [TrainerPoolTier.COMMON]: [ Species.CLEFFA, Species.CHATOT, Species.PANSAGE, Species.PANSEAR, Species.PANPOUR, Species.MINCCINO ], + [TrainerPoolTier.UNCOMMON]: [ Species.TROPIUS, Species.PETILIL, Species.BOUNSWEET, Species.INDEEDEE ], + [TrainerPoolTier.RARE]: [ Species.APPLIN, Species.SINISTEA, Species.POLTCHAGEIST ] }), [TrainerType.WORKER]: new TrainerConfig(++t).setHasGenders("Worker Female").setHasDouble("Workers").setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.7).setSpeciesFilter(s => s.isOfType(Type.ROCK) || s.isOfType(Type.STEEL)), [TrainerType.YOUNGSTER]: new TrainerConfig(++t).setMoneyMultiplier(0.5).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders("Lass", "lass").setHasDouble("Beginners").setPartyTemplates(trainerPartyTemplates.TWO_WEAKER) .setSpeciesPools( - [Species.CATERPIE, Species.WEEDLE, Species.RATTATA, Species.SENTRET, Species.POOCHYENA, Species.ZIGZAGOON, Species.WURMPLE, Species.BIDOOF, Species.PATRAT, Species.LILLIPUP] + [ Species.CATERPIE, Species.WEEDLE, Species.RATTATA, Species.SENTRET, Species.POOCHYENA, Species.ZIGZAGOON, Species.WURMPLE, Species.BIDOOF, Species.PATRAT, Species.LILLIPUP ] ), [TrainerType.ROCKET_GRUNT]: new TrainerConfig(++t).setHasGenders("Rocket Grunt Female").setHasDouble("Rocket Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.WEEDLE, Species.RATTATA, Species.EKANS, Species.SANDSHREW, Species.ZUBAT, Species.GEODUDE, Species.KOFFING, Species.GRIMER, Species.ODDISH, Species.SLOWPOKE], - [TrainerPoolTier.UNCOMMON]: [Species.GYARADOS, Species.LICKITUNG, Species.TAUROS, Species.MANKEY, Species.SCYTHER, Species.ELEKID, Species.MAGBY, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB, Species.MAGNEMITE], - [TrainerPoolTier.RARE]: [Species.PORYGON, Species.ALOLA_RATTATA, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE, Species.PALDEA_TAUROS, Species.OMANYTE, Species.KABUTO], - [TrainerPoolTier.SUPER_RARE]: [Species.DRATINI, Species.LARVITAR] + [TrainerPoolTier.COMMON]: [ Species.WEEDLE, Species.RATTATA, Species.EKANS, Species.SANDSHREW, Species.ZUBAT, Species.GEODUDE, Species.KOFFING, Species.GRIMER, Species.ODDISH, Species.SLOWPOKE ], + [TrainerPoolTier.UNCOMMON]: [ Species.GYARADOS, Species.LICKITUNG, Species.TAUROS, Species.MANKEY, Species.SCYTHER, Species.ELEKID, Species.MAGBY, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB, Species.MAGNEMITE ], + [TrainerPoolTier.RARE]: [ Species.PORYGON, Species.ALOLA_RATTATA, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE, Species.PALDEA_TAUROS, Species.OMANYTE, Species.KABUTO ], + [TrainerPoolTier.SUPER_RARE]: [ Species.DRATINI, Species.LARVITAR ] }), - [TrainerType.ARCHER]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin", "rocket", [Species.HOUNDOOM]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.ARIANA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin_female", "rocket", [Species.ARBOK]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.PROTON]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin", "rocket", [Species.CROBAT]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.PETREL]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin", "rocket", [Species.WEEZING]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.ARCHER]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin", "rocket", [ Species.HOUNDOOM ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.ARIANA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin_female", "rocket", [ Species.ARBOK ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.PROTON]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin", "rocket", [ Species.CROBAT ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.PETREL]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin", "rocket", [ Species.WEEZING ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.MAGMA_GRUNT]: new TrainerConfig(++t).setHasGenders("Magma Grunt Female").setHasDouble("Magma Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.SLUGMA, Species.POOCHYENA, Species.NUMEL, Species.ZIGZAGOON, Species.DIGLETT, Species.MAGBY, Species.TORKOAL, Species.GROWLITHE, Species.BALTOY], - [TrainerPoolTier.UNCOMMON]: [Species.SOLROCK, Species.HIPPOPOTAS, Species.SANDACONDA, Species.PHANPY, Species.ROLYCOLY, Species.GLIGAR, Species.RHYHORN, Species.HEATMOR], - [TrainerPoolTier.RARE]: [Species.TRAPINCH, Species.LILEEP, Species.ANORITH, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON], - [TrainerPoolTier.SUPER_RARE]: [Species.CAPSAKID, Species.CHARCADET] + [TrainerPoolTier.COMMON]: [ Species.SLUGMA, Species.POOCHYENA, Species.NUMEL, Species.ZIGZAGOON, Species.DIGLETT, Species.MAGBY, Species.TORKOAL, Species.GROWLITHE, Species.BALTOY ], + [TrainerPoolTier.UNCOMMON]: [ Species.SOLROCK, Species.HIPPOPOTAS, Species.SANDACONDA, Species.PHANPY, Species.ROLYCOLY, Species.GLIGAR, Species.RHYHORN, Species.HEATMOR ], + [TrainerPoolTier.RARE]: [ Species.TRAPINCH, Species.LILEEP, Species.ANORITH, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON, Species.TOEDSCOOL ], + [TrainerPoolTier.SUPER_RARE]: [ Species.CAPSAKID, Species.CHARCADET ] }), - [TrainerType.TABITHA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("magma_admin", "magma", [Species.CAMERUPT]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.COURTNEY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("magma_admin_female", "magma", [Species.CAMERUPT]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.TABITHA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("magma_admin", "magma", [ Species.CAMERUPT ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.COURTNEY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("magma_admin_female", "magma", [ Species.CAMERUPT ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.AQUA_GRUNT]: new TrainerConfig(++t).setHasGenders("Aqua Grunt Female").setHasDouble("Aqua Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.CARVANHA, Species.WAILMER, Species.ZIGZAGOON, Species.LOTAD, Species.CORPHISH, Species.SPHEAL, Species.REMORAID, Species.QWILFISH, Species.BARBOACH], - [TrainerPoolTier.UNCOMMON]: [Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.AZURILL, Species.CLOBBOPUS, Species.HORSEA], - [TrainerPoolTier.RARE]: [Species.MANTYKE, Species.DHELMISE, Species.HISUI_QWILFISH, Species.ARROKUDA, Species.PALDEA_WOOPER, Species.SKRELP], - [TrainerPoolTier.SUPER_RARE]: [Species.DONDOZO, Species.BASCULEGION] + [TrainerPoolTier.COMMON]: [ Species.CARVANHA, Species.WAILMER, Species.ZIGZAGOON, Species.LOTAD, Species.CORPHISH, Species.SPHEAL, Species.REMORAID, Species.QWILFISH, Species.BARBOACH ], + [TrainerPoolTier.UNCOMMON]: [ Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.AZURILL, Species.CLOBBOPUS, Species.HORSEA ], + [TrainerPoolTier.RARE]: [ Species.MANTYKE, Species.DHELMISE, Species.HISUI_QWILFISH, Species.ARROKUDA, Species.PALDEA_WOOPER, Species.SKRELP ], + [TrainerPoolTier.SUPER_RARE]: [ Species.DONDOZO, Species.BASCULEGION ] }), - [TrainerType.MATT]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aqua_admin", "aqua", [Species.SHARPEDO]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.SHELLY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aqua_admin_female", "aqua", [Species.SHARPEDO]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.MATT]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aqua_admin", "aqua", [ Species.SHARPEDO ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.SHELLY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aqua_admin_female", "aqua", [ Species.SHARPEDO ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.GALACTIC_GRUNT]: new TrainerConfig(++t).setHasGenders("Galactic Grunt Female").setHasDouble("Galactic Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.GLAMEOW, Species.STUNKY, Species.CROAGUNK, Species.SHINX, Species.WURMPLE, Species.BRONZOR, Species.DRIFLOON, Species.BURMY, Species.CARNIVINE], - [TrainerPoolTier.UNCOMMON]: [Species.LICKITUNG, Species.RHYHORN, Species.TANGELA, Species.ZUBAT, Species.YANMA, Species.SKORUPI, Species.GLIGAR, Species.SWINUB], - [TrainerPoolTier.RARE]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.SNEASEL, Species.ELEKID, Species.MAGBY, Species.DUSKULL], - [TrainerPoolTier.SUPER_RARE]: [Species.ROTOM, Species.SPIRITOMB, Species.HISUI_SNEASEL] + [TrainerPoolTier.COMMON]: [ Species.GLAMEOW, Species.STUNKY, Species.CROAGUNK, Species.SHINX, Species.WURMPLE, Species.BRONZOR, Species.DRIFLOON, Species.BURMY, Species.CARNIVINE ], + [TrainerPoolTier.UNCOMMON]: [ Species.LICKITUNG, Species.RHYHORN, Species.TANGELA, Species.ZUBAT, Species.YANMA, Species.SKORUPI, Species.GLIGAR, Species.SWINUB ], + [TrainerPoolTier.RARE]: [ Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.SNEASEL, Species.ELEKID, Species.MAGBY, Species.DUSKULL ], + [TrainerPoolTier.SUPER_RARE]: [ Species.ROTOM, Species.SPIRITOMB, Species.HISUI_SNEASEL ] }), - [TrainerType.JUPITER]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander_female", "galactic", [Species.SKUNTANK]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.MARS]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander_female", "galactic", [Species.PURUGLY]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.SATURN]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander", "galactic", [Species.TOXICROAK]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.JUPITER]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander_female", "galactic", [ Species.SKUNTANK ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.MARS]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander_female", "galactic", [ Species.PURUGLY ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.SATURN]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander", "galactic", [ Species.TOXICROAK ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.PLASMA_GRUNT]: new TrainerConfig(++t).setHasGenders("Plasma Grunt Female").setHasDouble("Plasma Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.PATRAT, Species.LILLIPUP, Species.PURRLOIN, Species.SCRAFTY, Species.WOOBAT, Species.VANILLITE, Species.SANDILE, Species.TRUBBISH, Species.TYMPOLE], - [TrainerPoolTier.UNCOMMON]: [Species.FRILLISH, Species.VENIPEDE, Species.GOLETT, Species.TIMBURR, Species.DARUMAKA, Species.FOONGUS, Species.JOLTIK, Species.CUBCHOO, Species.KLINK], - [TrainerPoolTier.RARE]: [Species.PAWNIARD, Species.RUFFLET, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.MIENFOO, Species.DURANT, Species.BOUFFALANT], - [TrainerPoolTier.SUPER_RARE]: [Species.DRUDDIGON, Species.HISUI_ZORUA, Species.AXEW, Species.DEINO] + [TrainerPoolTier.COMMON]: [ Species.PATRAT, Species.LILLIPUP, Species.PURRLOIN, Species.SCRAFTY, Species.WOOBAT, Species.VANILLITE, Species.SANDILE, Species.TRUBBISH, Species.TYMPOLE ], + [TrainerPoolTier.UNCOMMON]: [ Species.FRILLISH, Species.VENIPEDE, Species.GOLETT, Species.TIMBURR, Species.DARUMAKA, Species.FOONGUS, Species.JOLTIK, Species.CUBCHOO, Species.KLINK ], + [TrainerPoolTier.RARE]: [ Species.PAWNIARD, Species.RUFFLET, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.MIENFOO, Species.DURANT, Species.BOUFFALANT ], + [TrainerPoolTier.SUPER_RARE]: [ Species.DRUDDIGON, Species.HISUI_ZORUA, Species.AXEW, Species.DEINO ] }), - [TrainerType.ZINZOLIN]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("plasma_sage", "plasma", [Species.CRYOGONAL]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.ROOD]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("plasma_sage", "plasma", [Species.SWOOBAT]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.ZINZOLIN]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("plasma_sage", "plasma", [ Species.CRYOGONAL ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.ROOD]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("plasma_sage", "plasma", [ Species.SWOOBAT ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.FLARE_GRUNT]: new TrainerConfig(++t).setHasGenders("Flare Grunt Female").setHasDouble("Flare Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.FLETCHLING, Species.LITLEO, Species.PONYTA, Species.INKAY, Species.HOUNDOUR, Species.SKORUPI, Species.SCRAFTY, Species.CROAGUNK, Species.SCATTERBUG, Species.ESPURR], - [TrainerPoolTier.UNCOMMON]: [Species.HELIOPTILE, Species.ELECTRIKE, Species.SKRELP, Species.PANCHAM, Species.PURRLOIN, Species.POOCHYENA, Species.BINACLE, Species.CLAUNCHER, Species.PUMPKABOO, Species.PHANTUMP], - [TrainerPoolTier.RARE]: [Species.LITWICK, Species.SNEASEL, Species.PAWNIARD, Species.SLIGGOO], - [TrainerPoolTier.SUPER_RARE]: [Species.NOIVERN, Species.HISUI_SLIGGOO, Species.HISUI_AVALUGG] + [TrainerPoolTier.COMMON]: [ Species.FLETCHLING, Species.LITLEO, Species.PONYTA, Species.INKAY, Species.HOUNDOUR, Species.SKORUPI, Species.SCRAFTY, Species.CROAGUNK, Species.SCATTERBUG, Species.ESPURR ], + [TrainerPoolTier.UNCOMMON]: [ Species.HELIOPTILE, Species.ELECTRIKE, Species.SKRELP, Species.PANCHAM, Species.PURRLOIN, Species.POOCHYENA, Species.BINACLE, Species.CLAUNCHER, Species.PUMPKABOO, Species.PHANTUMP, Species.FOONGUS ], + [TrainerPoolTier.RARE]: [ Species.LITWICK, Species.SNEASEL, Species.PAWNIARD, Species.SLIGGOO ], + [TrainerPoolTier.SUPER_RARE]: [ Species.NOIBAT, Species.HISUI_SLIGGOO, Species.HISUI_AVALUGG ] }), - [TrainerType.BRYONY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("flare_admin_female", "flare", [Species.LIEPARD]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), - [TrainerType.XEROSIC]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("flare_admin", "flare", [Species.MALAMAR]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.BRYONY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("flare_admin_female", "flare", [ Species.LIEPARD ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.XEROSIC]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("flare_admin", "flare", [ Species.MALAMAR ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.AETHER_GRUNT]: new TrainerConfig(++t).setHasGenders("Aether Grunt Female").setHasDouble("Aether Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aether_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [ Species.PIKIPEK, Species.ROCKRUFF, Species.ALOLA_DIGLETT, Species.ALOLA_EXEGGUTOR, Species.YUNGOOS, Species.CORSOLA, Species.ALOLA_GEODUDE, Species.ALOLA_RAICHU, Species.BOUNSWEET, Species.LILLIPUP, Species.KOMALA, Species.MORELULL, Species.COMFEY, Species.TOGEDEMARU], - [TrainerPoolTier.UNCOMMON]: [ Species.POLIWAG, Species.STUFFUL, Species.ORANGURU, Species.PASSIMIAN, Species.BRUXISH, Species.MINIOR, Species.WISHIWASHI, Species.ALOLA_SANDSHREW, Species.ALOLA_VULPIX, Species.CRABRAWLER, Species.CUTIEFLY, Species.ORICORIO, Species.MUDBRAY, Species.PYUKUMUKU, Species.ALOLA_MAROWAK], - [TrainerPoolTier.RARE]: [ Species.GALAR_CORSOLA, Species.TURTONATOR, Species.MIMIKYU, Species.MAGNEMITE, Species.DRAMPA], - [TrainerPoolTier.SUPER_RARE]: [Species.JANGMO_O, Species.PORYGON] + [TrainerPoolTier.COMMON]: [ Species.PIKIPEK, Species.ROCKRUFF, Species.ALOLA_DIGLETT, Species.ALOLA_EXEGGUTOR, Species.YUNGOOS, Species.CORSOLA, Species.ALOLA_GEODUDE, Species.ALOLA_RAICHU, Species.BOUNSWEET, Species.LILLIPUP, Species.KOMALA, Species.MORELULL, Species.COMFEY, Species.TOGEDEMARU ], + [TrainerPoolTier.UNCOMMON]: [ Species.POLIWAG, Species.STUFFUL, Species.ORANGURU, Species.PASSIMIAN, Species.BRUXISH, Species.MINIOR, Species.WISHIWASHI, Species.ALOLA_SANDSHREW, Species.ALOLA_VULPIX, Species.CRABRAWLER, Species.CUTIEFLY, Species.ORICORIO, Species.MUDBRAY, Species.PYUKUMUKU, Species.ALOLA_MAROWAK ], + [TrainerPoolTier.RARE]: [ Species.GALAR_CORSOLA, Species.TURTONATOR, Species.MIMIKYU, Species.MAGNEMITE, Species.DRAMPA ], + [TrainerPoolTier.SUPER_RARE]: [ Species.JANGMO_O, Species.PORYGON ] }), - [TrainerType.FABA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aether_admin", "aether", [Species.HYPNO]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aether_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.FABA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aether_admin", "aether", [ Species.HYPNO ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aether_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.SKULL_GRUNT]: new TrainerConfig(++t).setHasGenders("Skull Grunt Female").setHasDouble("Skull Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_skull_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [ Species.SALANDIT, Species.ALOLA_RATTATA, Species.EKANS, Species.ALOLA_MEOWTH, Species.SCRAGGY, Species.KOFFING, Species.ALOLA_GRIMER, Species.MAREANIE, Species.SPINARAK, Species.TRUBBISH, Species.DROWZEE], - [TrainerPoolTier.UNCOMMON]: [ Species.FOMANTIS, Species.SABLEYE, Species.SANDILE, Species.HOUNDOUR, Species.ALOLA_MAROWAK, Species.GASTLY, Species.PANCHAM, Species.ZUBAT, Species.VENIPEDE, Species.VULLABY], - [TrainerPoolTier.RARE]: [Species.SANDYGAST, Species.PAWNIARD, Species.MIMIKYU, Species.DHELMISE, Species.WISHIWASHI, Species.NYMBLE], - [TrainerPoolTier.SUPER_RARE]: [Species.GRUBBIN, Species.DEWPIDER] + [TrainerPoolTier.COMMON]: [ Species.SALANDIT, Species.ALOLA_RATTATA, Species.EKANS, Species.ALOLA_MEOWTH, Species.SCRAGGY, Species.KOFFING, Species.ALOLA_GRIMER, Species.MAREANIE, Species.SPINARAK, Species.TRUBBISH, Species.DROWZEE ], + [TrainerPoolTier.UNCOMMON]: [ Species.FOMANTIS, Species.SABLEYE, Species.SANDILE, Species.HOUNDOUR, Species.ALOLA_MAROWAK, Species.GASTLY, Species.PANCHAM, Species.ZUBAT, Species.VENIPEDE, Species.VULLABY ], + [TrainerPoolTier.RARE]: [ Species.SANDYGAST, Species.PAWNIARD, Species.MIMIKYU, Species.DHELMISE, Species.WISHIWASHI, Species.NYMBLE ], + [TrainerPoolTier.SUPER_RARE]: [ Species.GRUBBIN, Species.DEWPIDER ] }), - [TrainerType.PLUMERIA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("skull_admin", "skull", [Species.SALAZZLE]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_skull_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.PLUMERIA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("skull_admin", "skull", [ Species.SALAZZLE ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_skull_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.MACRO_GRUNT]: new TrainerConfig(++t).setHasGenders("Macro Grunt Female").setHasDouble("Macro Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_macro_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [ Species.CUFANT, Species.GALAR_MEOWTH, Species.KLINK, Species.ROOKIDEE, Species.CRAMORANT, Species.GALAR_ZIGZAGOON, Species.SKWOVET, Species.STEELIX, Species.MAWILE, Species.FERROSEED], - [TrainerPoolTier.UNCOMMON]: [ Species.DRILBUR, Species.MAGNEMITE, Species.HATENNA, Species.ARROKUDA, Species.APPLIN, Species.GALAR_PONYTA, Species.GALAR_YAMASK, Species.SINISTEA, Species.RIOLU], - [TrainerPoolTier.RARE]: [Species.FALINKS, Species.BELDUM, Species.GALAR_FARFETCHD, Species.GALAR_MR_MIME, Species.HONEDGE, Species.SCIZOR, Species.GALAR_DARUMAKA], - [TrainerPoolTier.SUPER_RARE]: [Species.DURALUDON, Species.DREEPY] + [TrainerPoolTier.COMMON]: [ Species.CUFANT, Species.GALAR_MEOWTH, Species.KLINK, Species.ROOKIDEE, Species.CRAMORANT, Species.GALAR_ZIGZAGOON, Species.SKWOVET, Species.STEELIX, Species.MAWILE, Species.FERROSEED ], + [TrainerPoolTier.UNCOMMON]: [ Species.DRILBUR, Species.MAGNEMITE, Species.HATENNA, Species.ARROKUDA, Species.APPLIN, Species.GALAR_PONYTA, Species.GALAR_YAMASK, Species.SINISTEA, Species.RIOLU ], + [TrainerPoolTier.RARE]: [ Species.FALINKS, Species.BELDUM, Species.GALAR_FARFETCHD, Species.GALAR_MR_MIME, Species.HONEDGE, Species.SCIZOR, Species.GALAR_DARUMAKA ], + [TrainerPoolTier.SUPER_RARE]: [ Species.DURALUDON, Species.DREEPY ] }), - [TrainerType.OLEANA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("macro_admin", "macro", [Species.GARBODOR]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_oleana").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), + [TrainerType.OLEANA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("macro_admin", "macro", [ Species.GARBODOR ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_oleana").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.STAR_GRUNT]: new TrainerConfig(++t).setHasGenders("Star Grunt Female").setHasDouble("Star Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.DUNSPARCE, Species.HOUNDOUR, Species.AZURILL, Species.GULPIN, Species.FOONGUS, Species.FLETCHLING, Species.LITLEO, Species.FLABEBE, Species.CRABRAWLER, Species.NYMBLE, Species.PAWMI, Species.FIDOUGH, Species.SQUAWKABILLY, Species.MASCHIFF, Species.SHROODLE, Species.KLAWF, Species.WIGLETT, Species.PALDEA_WOOPER ], [TrainerPoolTier.UNCOMMON]: [ Species.KOFFING, Species.EEVEE, Species.GIRAFARIG, Species.RALTS, Species.TORKOAL, Species.SEVIPER, Species.SCRAGGY, Species.ZORUA, Species.MIMIKYU, Species.IMPIDIMP, Species.FALINKS, Species.CAPSAKID, Species.TINKATINK, Species.BOMBIRDIER, Species.CYCLIZAR, Species.FLAMIGO, Species.PALDEA_TAUROS ], - [TrainerPoolTier.RARE]: [ Species.MANKEY, Species.PAWNIARD, Species.CHARCADET, Species.FLITTLE, Species.VAROOM, Species.ORTHWORM], + [TrainerPoolTier.RARE]: [ Species.MANKEY, Species.PAWNIARD, Species.CHARCADET, Species.FLITTLE, Species.VAROOM, Species.ORTHWORM ], [TrainerPoolTier.SUPER_RARE]: [ Species.DONDOZO, Species.GIMMIGHOUL ] }), - [TrainerType.GIACOMO]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_1", [Species.KINGAMBIT]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { + [TrainerType.GIACOMO]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_1", [ Species.KINGAMBIT ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Segin Starmobile p.moveset = [ new PokemonMove(Moves.WICKED_TORQUE), new PokemonMove(Moves.SPIN_OUT), new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(Moves.HIGH_HORSEPOWER) ]; })), - [TrainerType.MELA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_2", [Species.ARMAROUGE]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { + [TrainerType.MELA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_2", [ Species.ARMAROUGE ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { p.formIndex = 2; // Schedar Starmobile p.moveset = [ new PokemonMove(Moves.BLAZING_TORQUE), new PokemonMove(Moves.SPIN_OUT), new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(Moves.HIGH_HORSEPOWER) ]; })), - [TrainerType.ATTICUS]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_3", [Species.REVAVROOM]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { + [TrainerType.ATTICUS]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_3", [ Species.REVAVROOM ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { p.formIndex = 3; // Navi Starmobile p.moveset = [ new PokemonMove(Moves.NOXIOUS_TORQUE), new PokemonMove(Moves.SPIN_OUT), new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(Moves.HIGH_HORSEPOWER) ]; })), - [TrainerType.ORTEGA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_4", [Species.DACHSBUN]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { + [TrainerType.ORTEGA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_4", [ Species.DACHSBUN ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { p.formIndex = 4; // Ruchbah Starmobile p.moveset = [ new PokemonMove(Moves.MAGICAL_TORQUE), new PokemonMove(Moves.SPIN_OUT), new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(Moves.HIGH_HORSEPOWER) ]; })), - [TrainerType.ERI]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_5", [Species.ANNIHILAPE]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { + [TrainerType.ERI]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("star_admin", "star_5", [ Species.ANNIHILAPE ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_star_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { p.formIndex = 5; // Caph Starmobile p.moveset = [ new PokemonMove(Moves.COMBAT_TORQUE), new PokemonMove(Moves.SPIN_OUT), new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(Moves.HIGH_HORSEPOWER) ]; })), @@ -1754,141 +1766,143 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.DRAYTON]: new TrainerConfig(++t).initForEliteFour(signatureSpecies["DRAYTON"], true, Type.DRAGON).setMixedBattleBgm("battle_bb_elite"), [TrainerType.BLUE]: new TrainerConfig((t = TrainerType.BLUE)).initForChampion(signatureSpecies["BLUE"], true).setBattleBgm("battle_kanto_champion").setMixedBattleBgm("battle_kanto_champion").setHasDouble("blue_red_double").setDoubleTrainerType(TrainerType.RED).setDoubleTitle("champion_double") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALAKAZAM], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ALAKAZAM ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Pidgeot p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.RED]: new TrainerConfig(++t).initForChampion(signatureSpecies["RED"], true).setBattleBgm("battle_johto_champion").setMixedBattleBgm("battle_johto_champion").setHasDouble("red_blue_double").setDoubleTrainerType(TrainerType.BLUE).setDoubleTitle("champion_double") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PIKACHU], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PIKACHU ], TrainerSlot.TRAINER, true, p => { p.formIndex = 8; // G-Max Pikachu p.generateAndPopulateMoveset(); p.generateName(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Venusaur, Mega Charizard X, or Mega Blastoise p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t).setName("Lance").initForChampion(signatureSpecies["LANCE_CHAMPION"], true).setBattleBgm("battle_johto_champion").setMixedBattleBgm("battle_johto_champion") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.AERODACTYL], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.AERODACTYL ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.LATIAS, Species.LATIOS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.LATIAS, Species.LATIOS ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Latias or Mega Latios p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion(signatureSpecies["STEVEN"], true).setBattleBgm("battle_hoenn_champion_g5").setMixedBattleBgm("battle_hoenn_champion_g6").setHasDouble("steven_wallace_double").setDoubleTrainerType(TrainerType.WALLACE).setDoubleTitle("champion_double") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SKARMORY], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SKARMORY ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.METAGROSS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.METAGROSS ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Metagross p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion(signatureSpecies["WALLACE"], true).setBattleBgm("battle_hoenn_champion_g5").setMixedBattleBgm("battle_hoenn_champion_g6").setHasDouble("wallace_steven_double").setDoubleTrainerType(TrainerType.STEVEN).setDoubleTitle("champion_double") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PELIPPER ], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Drizzle p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.SWAMPERT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.SWAMPERT ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Swampert p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.CYNTHIA]: new TrainerConfig(++t).initForChampion(signatureSpecies["CYNTHIA"], false).setBattleBgm("battle_sinnoh_champion").setMixedBattleBgm("battle_sinnoh_champion") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SPIRITOMB], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SPIRITOMB ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.GARCHOMP], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.GARCHOMP ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Garchomp p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.ALDER]: new TrainerConfig(++t).initForChampion(signatureSpecies["ALDER"], true).setHasDouble("alder_iris_double").setDoubleTrainerType(TrainerType.IRIS).setDoubleTitle("champion_double").setBattleBgm("battle_champion_alder").setMixedBattleBgm("battle_champion_alder") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.BOUFFALANT, Species.BRAVIARY], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BOUFFALANT, Species.BRAVIARY ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })), [TrainerType.IRIS]: new TrainerConfig(++t).initForChampion(signatureSpecies["IRIS"], false).setBattleBgm("battle_champion_iris").setMixedBattleBgm("battle_champion_iris").setHasDouble("iris_alder_double").setDoubleTrainerType(TrainerType.ALDER).setDoubleTitle("champion_double") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.DRUDDIGON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.DRUDDIGON ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.LAPRAS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.LAPRAS ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // G-Max Lapras p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.DIANTHA]: new TrainerConfig(++t).initForChampion(signatureSpecies["DIANTHA"], false).setMixedBattleBgm("battle_kalos_champion") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GOURGEIST], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.GOURGEIST ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.GARDEVOIR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.GARDEVOIR ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Gardevoir p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.HAU]: new TrainerConfig(++t).initForChampion(signatureSpecies["HAU"], true).setMixedBattleBgm("battle_alola_champion") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALOLA_RAICHU], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ALOLA_RAICHU ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })), [TrainerType.LEON]: new TrainerConfig(++t).initForChampion(signatureSpecies["LEON"], true).setMixedBattleBgm("battle_galar_champion") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.RILLABOOM, Species.CINDERACE, Species.INTELEON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.RILLABOOM, Species.CINDERACE, Species.INTELEON ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.CHARIZARD], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.CHARIZARD ], TrainerSlot.TRAINER, true, p => { p.formIndex = 3; // G-Max Charizard p.generateAndPopulateMoveset(); p.generateName(); })), [TrainerType.GEETA]: new TrainerConfig(++t).initForChampion(signatureSpecies["GEETA"], false).setMixedBattleBgm("battle_champion_geeta") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GLIMMORA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.GLIMMORA ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })), [TrainerType.NEMONA]: new TrainerConfig(++t).initForChampion(signatureSpecies["NEMONA"], false).setMixedBattleBgm("battle_champion_nemona") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.LYCANROC ], TrainerSlot.TRAINER, true, p => { p.formIndex = 0; // Midday form p.generateAndPopulateMoveset(); })), [TrainerType.KIERAN]: new TrainerConfig(++t).initForChampion(signatureSpecies["KIERAN"], true).setMixedBattleBgm("battle_champion_kieran") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.POLIWRATH, Species.POLITOED], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.POLIWRATH, Species.POLITOED ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })), [TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL) .setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY], TrainerSlot.TRAINER, true)) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL], TrainerSlot.TRAINER, true)), + .setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM, () => modifierTypes.ABILITY_CHARM) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL ], TrainerSlot.TRAINER, true)), [TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2) .setModifierRewardFuncs(() => modifierTypes.EXP_SHARE) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL], TrainerSlot.TRAINER, true)) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL], TrainerSlot.TRAINER, true)) + .setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)), [TrainerType.RIVAL_3]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_3) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true)) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setSpeciesFilter(species => species.baseTotal >= 540), [TrainerType.RIVAL_4]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_2").setMixedBattleBgm("battle_rival_2").setPartyTemplates(trainerPartyTemplates.RIVAL_4) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true)) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setSpeciesFilter(species => species.baseTotal >= 540) .setGenModifiersFunc(party => { const starter = party[0]; - return [modifierTypes.TERA_SHARD().generateType([], [starter.species.type1])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier]; // TODO: is the bang correct? + return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; // TODO: is the bang correct? }), [TrainerType.RIVAL_5]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_5) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true, + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, p => p.setBoss(true, 2))) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setSpeciesFilter(species => species.baseTotal >= 540) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.RAYQUAZA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.RAYQUAZA ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 3); p.pokeball = PokeballType.MASTER_BALL; p.shiny = true; @@ -1896,22 +1910,22 @@ export const trainerConfigs: TrainerConfigs = { })) .setGenModifiersFunc(party => { const starter = party[0]; - return [modifierTypes.TERA_SHARD().generateType([], [starter.species.type1])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier]; //TODO: is the bang correct? + return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; //TODO: is the bang correct? }), [TrainerType.RIVAL_6]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm("final").setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_6) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true, + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 3); p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL], TrainerSlot.TRAINER, true, + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); })) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setSpeciesFilter(species => species.baseTotal >= 540) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.RAYQUAZA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.RAYQUAZA ], TrainerSlot.TRAINER, true, p => { p.setBoss(); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; @@ -1922,16 +1936,19 @@ export const trainerConfigs: TrainerConfigs = { })) .setGenModifiersFunc(party => { const starter = party[0]; - return [modifierTypes.TERA_SHARD().generateType([], [starter.species.type1])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier]; // TODO: is the bang correct? + return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; // TODO: is the bang correct? }), [TrainerType.ROCKET_BOSS_GIOVANNI_1]: new TrainerConfig(t = TrainerType.ROCKET_BOSS_GIOVANNI_1).setName("Giovanni").initForEvilTeamLeader("Rocket Boss", []).setMixedBattleBgm("battle_rocket_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PERSIAN, Species.ALOLA_PERSIAN])) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.DUGTRIO, Species.ALOLA_DUGTRIO])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.HONCHKROW])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.NIDOKING, Species.NIDOQUEEN])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.RHYPERIOR])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.KANGASKHAN], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PERSIAN, Species.ALOLA_PERSIAN ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.gender = Gender.MALE; + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.DUGTRIO, Species.ALOLA_DUGTRIO ])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.HONCHKROW ])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.NIDOKING, Species.NIDOQUEEN ])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.RHYPERIOR ])) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.KANGASKHAN ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; @@ -1939,21 +1956,21 @@ export const trainerConfigs: TrainerConfigs = { p.generateName(); })), [TrainerType.ROCKET_BOSS_GIOVANNI_2]: new TrainerConfig(++t).setName("Giovanni").initForEvilTeamLeader("Rocket Boss", [], true).setMixedBattleBgm("battle_rocket_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.TYRANITAR, Species.IRON_THORNS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.TYRANITAR, Species.IRON_THORNS ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.HIPPOWDON])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.EXCADRILL, Species.GARCHOMP])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.KANGASKHAN], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.HIPPOWDON ])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.EXCADRILL, Species.GARCHOMP ])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.KANGASKHAN ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Kangaskhan p.generateName(); })) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.GASTRODON, Species.SEISMITOAD], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.GASTRODON, Species.SEISMITOAD ], TrainerSlot.TRAINER, true, p => { //Storm Drain Gastrodon, Water Absorb Seismitoad if (p.species.speciesId === Species.GASTRODON) { p.abilityIndex = 0; @@ -1961,75 +1978,78 @@ export const trainerConfigs: TrainerConfigs = { p.abilityIndex = 2; } })) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.MEWTWO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.MEWTWO ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; })), [TrainerType.MAXIE]: new TrainerConfig(++t).setName("Maxie").initForEvilTeamLeader("Magma Boss", []).setMixedBattleBgm("battle_aqua_magma_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.MIGHTYENA])) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.CROBAT, Species.GLISCOR])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.WEEZING, Species.GALAR_WEEZING])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.MAGMORTAR, Species.TORKOAL])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.FLYGON])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.CAMERUPT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.MIGHTYENA ])) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.CROBAT, Species.GLISCOR ])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.WEEZING, Species.GALAR_WEEZING ])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.MAGMORTAR, Species.TORKOAL ])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.FLYGON ])) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.CAMERUPT ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Camerupt p.generateName(); + p.gender = Gender.MALE; })), [TrainerType.MAXIE_2]: new TrainerConfig(++t).setName("Maxie").initForEvilTeamLeader("Magma Boss", [], true).setMixedBattleBgm("battle_aqua_magma_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SOLROCK, Species.TYPHLOSION], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SOLROCK, Species.TYPHLOSION ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.TORKOAL, Species.NINETALES], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.TORKOAL, Species.NINETALES ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.abilityIndex = 2; // Drought })) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SHIFTRY, Species.SCOVILLAIN], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.SHIFTRY, Species.SCOVILLAIN ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.abilityIndex = 0; // Chlorophyll })) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GREAT_TUSK])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.CAMERUPT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GREAT_TUSK ])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.CAMERUPT ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Camerupt p.generateName(); + p.gender = Gender.MALE; })) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.GROUDON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.GROUDON ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; })), [TrainerType.ARCHIE]: new TrainerConfig(++t).setName("Archie").initForEvilTeamLeader("Aqua Boss", []).setMixedBattleBgm("battle_aqua_magma_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.LINOONE])) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.CROBAT, Species.PELIPPER])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.MUK, Species.ALOLA_MUK])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.TENTACRUEL])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.RELICANTH, Species.WAILORD])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.SHARPEDO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.LINOONE ])) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.CROBAT, Species.PELIPPER ])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.MUK, Species.ALOLA_MUK ])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.TENTACRUEL ])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.RELICANTH, Species.WAILORD ])) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.SHARPEDO ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Sharpedo p.generateName(); + p.gender = Gender.MALE; })), [TrainerType.ARCHIE_2]: new TrainerConfig(++t).setName("Archie").initForEvilTeamLeader("Aqua Boss", [], true).setMixedBattleBgm("battle_aqua_magma_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.EMPOLEON, Species.LUDICOLO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.EMPOLEON, Species.LUDICOLO ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.POLITOED, Species.PELIPPER], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.POLITOED, Species.PELIPPER ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.abilityIndex = 2; // Drizzle })) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.BEARTIC, Species.ARMALDO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.BEARTIC, Species.ARMALDO ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.abilityIndex = 2; // Swift Swim })) @@ -2037,14 +2057,15 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.abilityIndex = 1; // Swift Swim })) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.SHARPEDO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.SHARPEDO ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Sharpedo p.generateName(); + p.gender = Gender.MALE; })) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.KYOGRE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.KYOGRE ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; @@ -2060,44 +2081,47 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; // Mega Houndoom p.generateName(); })) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.WEAVILE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.WEAVILE ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.MALE; })), [TrainerType.CYRUS_2]: new TrainerConfig(++t).setName("Cyrus").initForEvilTeamLeader("Galactic Boss", [], true).setMixedBattleBgm("battle_galactic_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.AZELF, Species.UXIE, Species.MESPRIT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.AZELF, Species.UXIE, Species.MESPRIT ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); })) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.ELECTRODE, Species.HISUI_ELECTRODE])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SALAMENCE, Species.ROARING_MOON])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.HOUNDOOM], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.ELECTRODE, Species.HISUI_ELECTRODE ])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.SALAMENCE, Species.ROARING_MOON ])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.HOUNDOOM ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Houndoom p.generateName(); })) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.WEAVILE, Species.SNEASLER], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.WEAVILE, Species.SNEASLER ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.MALE; })) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.DARKRAI], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.DARKRAI ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; })), [TrainerType.GHETSIS]: new TrainerConfig(++t).setName("Ghetsis").initForEvilTeamLeader("Plasma Boss", []).setMixedBattleBgm("battle_plasma_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.COFAGRIGUS, Species.RUNERIGUS])) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.BOUFFALANT])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SEISMITOAD, Species.CARRACOSTA])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.EELEKTROSS, Species.GALVANTULA])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.VOLCARONA])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.HYDREIGON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.COFAGRIGUS, Species.RUNERIGUS ])) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BOUFFALANT ])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.SEISMITOAD, Species.CARRACOSTA ])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.EELEKTROSS, Species.GALVANTULA ])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.VOLCARONA ])) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.HYDREIGON ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.MALE; })), [TrainerType.GHETSIS_2]: new TrainerConfig(++t).setName("Ghetsis").initForEvilTeamLeader("Plasma Boss", [], true).setMixedBattleBgm("battle_plasma_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.GENESECT ], TrainerSlot.TRAINER, true, p => { @@ -2117,8 +2141,13 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + if (p.species.speciesId === Species.HYDREIGON) { + p.gender = Gender.MALE; + } else if (p.species.speciesId === Species.IRON_JUGULIS) { + p.gender = Gender.GENDERLESS; + } })) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.KYUREM], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.KYUREM ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; @@ -2138,9 +2167,10 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Gyarados p.generateName(); + p.gender = Gender.MALE; })), [TrainerType.LYSANDRE_2]: new TrainerConfig(++t).setName("Lysandre").initForEvilTeamLeader("Flare Boss", [], true).setMixedBattleBgm("battle_flare_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SCREAM_TAIL, Species.FLUTTER_MANE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SCREAM_TAIL, Species.FLUTTER_MANE ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; @@ -2157,14 +2187,18 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Gyardos p.generateName(); + p.gender = Gender.MALE; })) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.YVELTAL], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.YVELTAL ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; })), [TrainerType.LUSAMINE]: new TrainerConfig(++t).setName("Lusamine").initForEvilTeamLeader("Aether Boss", []).setMixedBattleBgm("battle_aether_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLEFABLE ])) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLEFABLE ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.gender = Gender.FEMALE; + })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.LILLIGANT, Species.HISUI_LILLIGANT ])) .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.MILOTIC, Species.PRIMARINA ])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GALAR_SLOWBRO, Species.GALAR_SLOWKING ])) @@ -2181,7 +2215,10 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ROGUE_BALL; })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.MILOTIC, Species.PRIMARINA ])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.CLEFABLE ])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.CLEFABLE ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.gender = Gender.FEMALE; + })) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.STAKATAKA, Species.CELESTEELA, Species.GUZZLORD ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ROGUE_BALL; @@ -2214,7 +2251,7 @@ export const trainerConfigs: TrainerConfigs = { p.abilityIndex = 2; } })) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GALVANTULA, Species.VIKAVOLT])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GALVANTULA, Species.VIKAVOLT ])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.PINSIR ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.formIndex = 1; // Mega Pinsir @@ -2224,6 +2261,7 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.GOLISOPOD ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); + p.gender = Gender.MALE; p.pokeball = PokeballType.ULTRA_BALL; })), [TrainerType.GUZMA_2]: new TrainerConfig(++t).setName("Guzma").initForEvilTeamLeader("Skull Boss", [], true).setMixedBattleBgm("battle_skull_boss").setVictoryBgm("victory_team_plasma") @@ -2231,6 +2269,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.abilityIndex = 2; //Anticipation + p.gender = Gender.MALE; p.pokeball = PokeballType.ULTRA_BALL; })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.SCIZOR, Species.KLEAVOR ], TrainerSlot.TRAINER, true, p => { @@ -2272,6 +2311,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; // G-Max Copperajah p.generateName(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.FEMALE; })), [TrainerType.ROSE_2]: new TrainerConfig(++t).setName("Rose").initForEvilTeamLeader("Macro Boss", [], true).setMixedBattleBgm("battle_macro_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ARCHALUDON ], TrainerSlot.TRAINER, true, p => { @@ -2295,6 +2335,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; // G-Max Copperajah p.generateName(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.FEMALE; })), [TrainerType.PENNY]: new TrainerConfig(++t).setName("Cassiopeia").initForEvilTeamLeader("Star Boss", []).setMixedBattleBgm("battle_star_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VAPOREON, Species.JOLTEON, Species.FLAREON ])) @@ -2308,8 +2349,9 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = Utils.randSeedInt(5, 1); // Heat, Wash, Frost, Fan, or Mow })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => { - p.generateAndPopulateMoveset(); p.abilityIndex = 2; // Pixilate + p.generateAndPopulateMoveset(); + p.gender = Gender.FEMALE; })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.EEVEE ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2320,23 +2362,24 @@ export const trainerConfigs: TrainerConfigs = { })) .setGenModifiersFunc(party => { const teraPokemon = party[4]; - return [modifierTypes.TERA_SHARD().generateType([], [teraPokemon.species.type1])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier]; //TODO: is the bang correct? + return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; //TODO: is the bang correct? }), [TrainerType.PENNY_2]: new TrainerConfig(++t).setName("Cassiopeia").initForEvilTeamLeader("Star Boss", [], true).setMixedBattleBgm("battle_star_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); - p.formIndex = Utils.randSeedInt(5, 1); //Random Starmobile form + p.abilityIndex = 2; // Pixilate p.generateAndPopulateMoveset(); - p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.FEMALE; })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.ENTEI, Species.RAIKOU, Species.SUICUNE ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; })) .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.WALKING_WAKE, Species.GOUGING_FIRE, Species.RAGING_BOLT ])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { + p.formIndex = Utils.randSeedInt(5, 1); //Random Starmobile form p.generateAndPopulateMoveset(); - p.abilityIndex = 2; // Pixilate + p.pokeball = PokeballType.ROGUE_BALL; })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.EEVEE ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2351,8 +2394,8 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.MASTER_BALL; })) .setGenModifiersFunc(party => { - const teraPokemon = party[3]; - return [modifierTypes.TERA_SHARD().generateType([], [teraPokemon.species.type1])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier]; //TODO: is the bang correct? + const teraPokemon = party[0]; + return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; //TODO: is the bang correct? }), [TrainerType.BUCK]: new TrainerConfig(++t).setName("Buck").initForStatTrainer([], true) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLAYDOL ], TrainerSlot.TRAINER, true, p => { @@ -2504,6 +2547,22 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.BUG_TYPE_SUPERFAN]: new TrainerConfig(++t).setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER) .setPartyTemplates(new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE)), [TrainerType.EXPERT_POKEMON_BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(3).setEncounterBgm(TrainerType.ACE_TRAINER).setLocalizedName("Expert Pokemon Breeder") - .setPartyTemplates(new TrainerPartyTemplate(3, PartyMemberStrength.STRONG)) + .setPartyTemplates(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE)), + [TrainerType.FUTURE_SELF_M]: new TrainerConfig(++t) + .setMoneyMultiplier(0) + .setEncounterBgm("mystery_encounter_weird_dream") + .setBattleBgm("mystery_encounter_weird_dream") + .setMixedBattleBgm("mystery_encounter_weird_dream") + .setVictoryBgm("mystery_encounter_weird_dream") + .setLocalizedName("Future Self M") + .setPartyTemplates(new TrainerPartyTemplate(6, PartyMemberStrength.STRONG)), + [TrainerType.FUTURE_SELF_F]: new TrainerConfig(++t) + .setMoneyMultiplier(0) + .setEncounterBgm("mystery_encounter_weird_dream") + .setBattleBgm("mystery_encounter_weird_dream") + .setMixedBattleBgm("mystery_encounter_weird_dream") + .setVictoryBgm("mystery_encounter_weird_dream") + .setLocalizedName("Future Self F") + .setPartyTemplates(new TrainerPartyTemplate(6, PartyMemberStrength.STRONG)) }; diff --git a/src/data/trainer-names.ts b/src/data/trainer-names.ts index 899702ff193..d075b7121f2 100644 --- a/src/data/trainer-names.ts +++ b/src/data/trainer-names.ts @@ -75,56 +75,56 @@ const trainerNameConfigs: TrainerNameConfigs = { }; export const trainerNamePools = { - [TrainerType.ACE_TRAINER]: [["Aaron", "Allen", "Blake", "Brian", "Gaven", "Jake", "Kevin", "Mike", "Nick", "Paul", "Ryan", "Sean", "Darin", "Albert", "Berke", "Clyde", "Edgar", "George", "Leroy", "Owen", "Parker", "Randall", "Ruben", "Samuel", "Vincent", "Warren", "Wilton", "Zane", "Alfred", "Braxton", "Felix", "Gerald", "Jonathan", "Leonel", "Marcel", "Mitchell", "Quincy", "Roderick", "Colby", "Rolando", "Yuji", "Abel", "Anton", "Arthur", "Cesar", "Dalton", "Dennis", "Ernest", "Garrett", "Graham", "Henry", "Isaiah", "Jonah", "Jose", "Keenan", "Micah", "Omar", "Quinn", "Rodolfo", "Saul", "Sergio", "Skylar", "Stefan", "Zachery", "Alton", "Arabella", "Bonita", "Cal", "Cody", "French", "Kobe", "Paulo", "Shaye", "Austin", "Beckett", "Charlie", "Corky", "David", "Dwayne", "Elmer", "Jesse", "Jared", "Johan", "Jordan", "Kipp", "Lou", "Terry", "Tom", "Webster", "Billy", "Doyle", "Enzio", "Geoff", "Grant", "Kelsey", "Miguel", "Pierce", "Ray", "Santino", "Shel", "Adelbert", "Bence", "Emil", "Evan", "Mathis", "Maxim", "Neil", "Rico", "Robbie", "Theo", "Viktor", "Benedict", "Cornelius", "Hisato", "Leopold", "Neville", "Vito", "Chase", "Cole", "Hiroshi", "Jackson", "Jim", "Kekoa", "Makana", "Yuki", "Elwood", "Seth", "Alvin", "Arjun", "Arnold", "Cameron", "Carl", "Carlton", "Christopher", "Dave", "Dax", "Dominic", "Edmund", "Finn", "Fred", "Garret", "Grayson", "Jace", "Jaxson", "Jay", "Jirard", "Johnson", "Kayden", "Kite", "Louis", "Mac", "Marty", "Percy", "Raymond", "Ronnie", "Satch", "Tim", "Zach", "Conner", "Vince", "Bedro", "Boda", "Botan", "Daras", "Dury", "Herton", "Rewn", "Stum", "Tock", "Trilo", "Berki", "Cruik", "Dazon", "Desid", "Dillot", "Farfin", "Forgon", "Hebel", "Morfon", "Moril", "Shadd", "Vanhub", "Bardo", "Carben", "Degin", "Gorps", "Klept", "Lask", "Malex", "Mopar", "Niled", "Noxon", "Teslor", "Tetil"], ["Beth", "Carol", "Cybil", "Emma", "Fran", "Gwen", "Irene", "Jenn", "Joyce", "Kate", "Kelly", "Lois", "Lola", "Megan", "Quinn", "Reena", "Cara", "Alexa", "Brooke", "Caroline", "Elaine", "Hope", "Jennifer", "Jody", "Julie", "Lori", "Mary", "Michelle", "Shannon", "Wendy", "Alexia", "Alicia", "Athena", "Carolina", "Cristin", "Darcy", "Dianne", "Halle", "Jazmyn", "Katelynn", "Keira", "Marley", "Allyson", "Kathleen", "Naomi", "Alyssa", "Ariana", "Brandi", "Breanna", "Brenda", "Brenna", "Catherine", "Clarice", "Dana", "Deanna", "Destiny", "Jamie", "Jasmin", "Kassandra", "Laura", "Maria", "Mariah", "Maya", "Meagan", "Mikayla", "Monique", "Natasha", "Olivia", "Sandra", "Savannah", "Sydney", "Moira", "Piper", "Salma", "Allison", "Beverly", "Cathy", "Cheyenne", "Clara", "Dara", "Eileen", "Glinda", "Junko", "Lena", "Lucille", "Mariana", "Olwen", "Shanta", "Stella", "Angi", "Belle", "Chandra", "Cora", "Eve", "Jacqueline", "Jeanne", "Juliet", "Kathrine", "Layla", "Lucca", "Melina", "Miki", "Nina", "Sable", "Shelly", "Summer", "Trish", "Vicki", "Alanza", "Cordelia", "Hilde", "Imelda", "Michele", "Mireille", "Claudia", "Constance", "Harriet", "Honor", "Melba", "Portia", "Alexis", "Angela", "Karla", "Lindsey", "Tori", "Sheri", "Jada", "Kailee", "Amanda", "Annie", "Kindra", "Kyla", "Sofia", "Yvette", "Becky", "Flora", "Gloria", "Buna", "Ferda", "Lehan", "Liqui", "Lomen", "Neira", "Atilo", "Detta", "Gilly", "Gosney", "Levens", "Moden", "Rask", "Rateis", "Rosno", "Tynan", "Veron", "Zoel", "Cida", "Dibsin", "Dodin", "Ebson", "Equin", "Flostin", "Gabsen", "Halsion", "Hileon", "Quelor", "Rapeel", "Roze", "Tensin"]], - [TrainerType.ARTIST]: [["Ismael", "William", "Horton", "Pierre", "Zach", "Gough", "Salvador", "Vincent", "Duncan"], ["Georgia"]], - [TrainerType.BACKERS]: [["Alf & Fred", "Hawk & Dar", "Joe & Ross", "Les & Web", "Masa & Yas", "Stu & Art"], ["Ai & Ciel", "Ami & Eira", "Cam & Abby", "Fey & Sue", "Kat & Phae", "Kay & Ali", "Ava & Aya", "Cleo & Rio", "May & Mal"]], - [TrainerType.BACKPACKER]: [["Alexander", "Carlos", "Herman", "Jerome", "Keane", "Kelsey", "Kiyo", "Michael", "Nate", "Peter", "Sam", "Stephen", "Talon", "Terrance", "Toru", "Waylon", "Boone", "Clifford", "Ivan", "Kendall", "Lowell", "Randall", "Reece", "Roland", "Shane", "Walt", "Farid", "Heike", "Joren", "Lane", "Roderick", "Darnell", "Deon", "Emory", "Graeme", "Grayson", "Aitor", "Alex", "Arturo", "Asier", "Jaime", "Jonathan", "Julio", "Kevin", "Kosuke", "Lander", "Markel", "Mateo", "Nil", "Pau", "Samuel"], ["Anna", "Corin", "Elaine", "Emi", "Jill", "Kumiko", "Liz", "Lois", "Lora", "Molly", "Patty", "Ruth", "Vicki", "Annie", "Blossom", "Clara", "Eileen", "Mae", "Myra", "Rachel", "Tami", "Ashley", "Mikiko", "Kiana", "Perdy", "Maria", "Yuho", "Peren", "Barbara", "Diane"]], - [TrainerType.BAKER]: ["Chris", "Jenn", "Lilly"], - [TrainerType.BEAUTY]: ["Cassie", "Julia", "Olivia", "Samantha", "Valerie", "Victoria", "Bridget", "Connie", "Jessica", "Johanna", "Melissa", "Sheila", "Shirley", "Tiffany", "Namiko", "Thalia", "Grace", "Lola", "Lori", "Maura", "Tamia", "Cyndy", "Devon", "Gabriella", "Harley", "Lindsay", "Nicola", "Callie", "Charlotte", "Kassandra", "December", "Fleming", "Nikola", "Aimee", "Anais", "Brigitte", "Cassandra", "Andrea", "Brittney", "Carolyn", "Krystal", "Alexis", "Alice", "Aina", "Anya", "Arianna", "Aubrey", "Beverly", "Camille", "Beauty", "Evette", "Hansol", "Haruka", "Jill", "Jo", "Lana", "Lois", "Lucy", "Mai", "Nickie", "Nicole", "Prita", "Rose", "Shelly", "Suzy", "Tessa", "Anita", "Alissa", "Rita", "Cudsy", "Eloff", "Miru", "Minot", "Nevah", "Niven", "Ogoin"], - [TrainerType.BIKER]: ["Charles", "Dwayne", "Glenn", "Harris", "Joel", "Riley", "Zeke", "Alex", "Billy", "Ernest", "Gerald", "Hideo", "Isaac", "Jared", "Jaren", "Jaxon", "Jordy", "Lao", "Lukas", "Malik", "Nikolas", "Ricardo", "Ruben", "Virgil", "William", "Aiden", "Dale", "Dan", "Jacob", "Markey", "Reese", "Teddy", "Theron", "Jeremy", "Morgann", "Phillip", "Philip", "Stanley", "Dillon"], - [TrainerType.BLACK_BELT]: [["Kenji", "Lao", "Lung", "Nob", "Wai", "Yoshi", "Atsushi", "Daisuke", "Hideki", "Hitoshi", "Kiyo", "Koichi", "Koji", "Yuji", "Cristian", "Rhett", "Takao", "Theodore", "Zander", "Aaron", "Hugh", "Mike", "Nicolas", "Shea", "Takashi", "Adam", "Carl", "Colby", "Darren", "David", "Davon", "Derek", "Eddie", "Gregory", "Griffin", "Jarrett", "Jeffery", "Kendal", "Kyle", "Luke", "Miles", "Nathaniel", "Philip", "Rafael", "Ray", "Ricky", "Sean", "Willie", "Ander", "Manford", "Benjamin", "Corey", "Edward", "Grant", "Jay", "Kendrew", "Kentaro", "Ryder", "Teppei", "Thomas", "Tyrone", "Andrey", "Donny", "Drago", "Gordon", "Grigor", "Jeriel", "Kenneth", "Martell", "Mathis", "Rich", "Rocky", "Rodrigo", "Wesley", "Zachery", "Alonzo", "Cadoc", "Gunnar", "Igor", "Killian", "Markus", "Ricardo", "Yanis", "Banting", "Clayton", "Duane", "Earl", "Greg", "Roy", "Terry", "Tracy", "Walter", "Alvaro", "Curtis", "Francis", "Ross", "Brice", "Cheng", "Dudley", "Eric", "Kano", "Masahiro", "Randy", "Ryuji", "Steve", "Tadashi", "Wong", "Yuen", "Brian", "Carter", "Reece", "Nick", "Yang"], ["Cora", "Cyndy", "Jill", "Laura", "Sadie", "Tessa", "Vivian", "Aisha", "Callie", "Danielle", "Helene", "Jocelyn", "Lilith", "Paula", "Reyna", "Helen", "Kelsey", "Tyler", "Amy", "Chandra", "Hillary", "Janie", "Lee", "Maggie", "Mikiko", "Miriam", "Sharon", "Susie", "Xiao", "Alize", "Azra", "Brenda", "Chalina", "Chan", "Glinda", "Maki", "Tia", "Tiffany", "Wendy", "Andrea", "Gabrielle", "Gerardine", "Hailey", "Hedvig", "Justine", "Kinsey", "Sigrid", "Veronique", "Tess"]], - [TrainerType.BREEDER]: [["Isaac", "Myles", "Salvadore", "Albert", "Kahlil", "Eustace", "Galen", "Owen", "Addison", "Marcus", "Foster", "Cory", "Glenn", "Jay", "Wesley", "William", "Adrian", "Bradley", "Jaime"], ["Allison", "Alize", "Bethany", "Lily", "Lydia", "Gabrielle", "Jayden", "Pat", "Veronica", "Amber", "Jennifer", "Kaylee", "Adelaide", "Brooke", "Ethel", "April", "Irene", "Magnolia", "Amala", "Mercy", "Amanda", "Ikue", "Savannah", "Yuka", "Chloe", "Debra", "Denise", "Elena"]], - [TrainerType.CLERK]: [["Chaz", "Clemens", "Doug", "Fredric", "Ivan", "Isaac", "Nelson", "Wade", "Warren", "Augustin", "Gilligan", "Cody", "Jeremy", "Shane", "Dugal", "Royce", "Ronald"], ["Alberta", "Ingrid", "Katie", "Piper", "Trisha", "Wren", "Britney", "Lana", "Jessica", "Kristen", "Michelle", "Gabrielle"]], - [TrainerType.CYCLIST]: [["Axel", "James", "John", "Ryan", "Hector", "Jeremiah"], ["Kayla", "Megan", "Nicole", "Rachel", "Krissa", "Adelaide"]], - [TrainerType.DANCER]: ["Brian", "Davey", "Dirk", "Edmond", "Mickey", "Raymond", "Cara", "Julia", "Maika", "Mireille", "Ronda", "Zoe"], - [TrainerType.DEPOT_AGENT]: ["Josh", "Hank", "Vincent"], - [TrainerType.DOCTOR]: [["Hank", "Jerry", "Jules", "Logan", "Wayne", "Braid", "Derek", "Heath", "Julius", "Kit", "Graham"], ["Kirsten", "Sachiko", "Shery", "Carol", "Dixie", "Mariah"]], - [TrainerType.FIREBREATHER]: ["Bill", "Burt", "Cliff", "Dick", "Lyle", "Ned", "Otis", "Ray", "Richard", "Walt"], - [TrainerType.FISHERMAN]: ["Andre", "Arnold", "Barney", "Chris", "Edgar", "Henry", "Jonah", "Justin", "Kyle", "Martin", "Marvin", "Ralph", "Raymond", "Scott", "Stephen", "Wilton", "Tully", "Andrew", "Barny", "Carter", "Claude", "Dale", "Elliot", "Eugene", "Ivan", "Ned", "Nolan", "Roger", "Ronald", "Wade", "Wayne", "Darian", "Kai", "Chip", "Hank", "Kaden", "Tommy", "Tylor", "Alec", "Brett", "Cameron", "Cody", "Cole", "Cory", "Erick", "George", "Joseph", "Juan", "Kenneth", "Luc", "Miguel", "Travis", "Walter", "Zachary", "Josh", "Gideon", "Kyler", "Liam", "Murphy", "Bruce", "Damon", "Devon", "Hubert", "Jones", "Lydon", "Mick", "Pete", "Sean", "Sid", "Vince", "Bucky", "Dean", "Eustace", "Kenzo", "Leroy", "Mack", "Ryder", "Ewan", "Finn", "Murray", "Seward", "Shad", "Wharton", "Finley", "Fisher", "Fisk", "River", "Sheaffer", "Timin", "Carl", "Ernest", "Hal", "Herbert", "Hisato", "Mike", "Vernon", "Harriet", "Marina", "Chase"], - [TrainerType.GUITARIST]: ["Anna", "Beverly", "January", "Tina", "Alicia", "Claudia", "Julia", "Lidia", "Mireia", "Noelia", "Sara", "Sheila", "Tatiana"], - [TrainerType.HARLEQUIN]: ["Charley", "Ian", "Jack", "Kerry", "Louis", "Pat", "Paul", "Rick", "Anders", "Clarence", "Gary"], - [TrainerType.HIKER]: ["Anthony", "Bailey", "Benjamin", "Daniel", "Erik", "Jim", "Kenny", "Leonard", "Michael", "Parry", "Phillip", "Russell", "Sidney", "Tim", "Timothy", "Alan", "Brice", "Clark", "Eric", "Lenny", "Lucas", "Mike", "Trent", "Devan", "Eli", "Marc", "Sawyer", "Allen", "Daryl", "Dudley", "Earl", "Franklin", "Jeremy", "Marcos", "Nob", "Oliver", "Wayne", "Alexander", "Damon", "Jonathan", "Justin", "Kevin", "Lorenzo", "Louis", "Maurice", "Nicholas", "Reginald", "Robert", "Theodore", "Bruce", "Clarke", "Devin", "Dwight", "Edwin", "Eoin", "Noland", "Russel", "Andy", "Bret", "Darrell", "Gene", "Hardy", "Hugh", "Jebediah", "Jeremiah", "Kit", "Neil", "Terrell", "Don", "Doug", "Hunter", "Jared", "Jerome", "Keith", "Manuel", "Markus", "Otto", "Shelby", "Stephen", "Teppei", "Tobias", "Wade", "Zaiem", "Aaron", "Alain", "Bergin", "Bernard", "Brent", "Corwin", "Craig", "Delmon", "Dunstan", "Orestes", "Ross", "Davian", "Calhoun", "David", "Gabriel", "Ryan", "Thomas", "Travis", "Zachary", "Anuhea", "Barnaby", "Claus", "Collin", "Colson", "Dexter", "Dillan", "Eugine", "Farkas", "Hisato", "Julius", "Kenji", "Irwin", "Lionel", "Paul", "Richter", "Valentino", "Donald", "Douglas", "Kevyn", "Chester"], //["Angela","Carla","Celia","Daniela","Estela","Fatima","Helena","Leire","Lucia","Luna","Manuela","Mar","Marina","Miyu","Nancy","Nerea","Paula","Rocio","Yanira"] - [TrainerType.HOOLIGANS]: ["Jim & Cas", "Rob & Sal"], - [TrainerType.HOOPSTER]: ["Bobby", "John", "Lamarcus", "Derrick", "Nicolas"], - [TrainerType.INFIELDER]: ["Alex", "Connor", "Todd"], - [TrainerType.JANITOR]: ["Caleb", "Geoff", "Brady", "Felix", "Orville", "Melvin", "Shawn"], - [TrainerType.LINEBACKER]: ["Bob", "Dan", "Jonah"], - [TrainerType.MAID]: ["Belinda", "Sophie", "Emily", "Elena", "Clare", "Alica", "Tanya", "Tammy"], - [TrainerType.MUSICIAN]: ["Boris", "Preston", "Charles", "Clyde", "Vincent", "Dalton", "Kirk", "Shawn", "Fabian", "Fernando", "Joseph", "Marcos", "Arturo", "Jerry", "Lonnie", "Tony"], - [TrainerType.NURSERY_AIDE]: ["Autumn", "Briana", "Leah", "Miho", "Ethel", "Hollie", "Ilse", "June", "Kimya", "Rosalyn"], - [TrainerType.OFFICER]: ["Dirk", "Keith", "Alex", "Bobby", "Caleb", "Danny", "Dylan", "Thomas", "Daniel", "Jeff", "Braven", "Dell", "Neagle", "Haruki", "Mitchell", "Raymond"], - [TrainerType.PARASOL_LADY]: ["Angelica", "Clarissa", "Madeline", "Akari", "Annabell", "Kayley", "Rachel", "Alexa", "Sabrina", "April", "Gwyneth", "Laura", "Lumi", "Mariah", "Melita", "Nicole", "Tihana", "Ingrid", "Tyra"], - [TrainerType.PILOT]: ["Chase", "Leonard", "Ted", "Elron", "Ewing", "Flynn", "Winslow"], - [TrainerType.POKEFAN]: [["Alex", "Allan", "Brandon", "Carter", "Colin", "Derek", "Jeremy", "Joshua", "Rex", "Robert", "Trevor", "William", "Colton", "Miguel", "Francisco", "Kaleb", "Leonard", "Boone", "Elliot", "Jude", "Norbert", "Corey", "Gabe", "Baxter"], ["Beverly", "Georgia", "Jaime", "Ruth", "Isabel", "Marissa", "Vanessa", "Annika", "Bethany", "Kimberly", "Meredith", "Rebekah", "Eleanor", "Darcy", "Lydia", "Sachiko", "Abigail", "Agnes", "Lydie", "Roisin", "Tara", "Carmen", "Janet"]], - [TrainerType.PRESCHOOLER]: [["Billy", "Doyle", "Evan", "Homer", "Tully", "Albert", "Buster", "Greg", "Ike", "Jojo", "Tyrone", "Adrian", "Oliver", "Hayden", "Hunter", "Kaleb", "Liam", "Dylan"], ["Juliet", "Mia", "Sarah", "Wendy", "Winter", "Chrissy", "Eva", "Lin", "Samantha", "Ella", "Lily", "Natalie", "Ailey", "Hannah", "Malia", "Kindra", "Nancy"]], - [TrainerType.PSYCHIC]: [["Fidel", "Franklin", "Gilbert", "Greg", "Herman", "Jared", "Mark", "Nathan", "Norman", "Phil", "Richard", "Rodney", "Cameron", "Edward", "Fritz", "Joshua", "Preston", "Virgil", "William", "Alvaro", "Blake", "Cedric", "Keenan", "Nicholas", "Dario", "Johan", "Lorenzo", "Tyron", "Bryce", "Corbin", "Deandre", "Elijah", "Kody", "Landon", "Maxwell", "Mitchell", "Sterling", "Eli", "Nelson", "Vernon", "Gaven", "Gerard", "Low", "Micki", "Perry", "Rudolf", "Tommy", "Al", "Nandor", "Tully", "Arthur", "Emanuel", "Franz", "Harry", "Paschal", "Robert", "Sayid", "Angelo", "Anton", "Arin", "Avery", "Danny", "Frasier", "Harrison", "Jaime", "Ross", "Rui", "Vlad", "Mason"], ["Alexis", "Hannah", "Jacki", "Jaclyn", "Kayla", "Maura", "Samantha", "Alix", "Brandi", "Edie", "Macey", "Mariella", "Marlene", "Laura", "Rodette", "Abigail", "Brittney", "Chelsey", "Daisy", "Desiree", "Kendra", "Lindsey", "Rachael", "Valencia", "Belle", "Cybil", "Doreen", "Dua", "Future", "Lin", "Madhu", "Alia", "Ena", "Joyce", "Lynette", "Olesia", "Sarah"]], - [TrainerType.RANGER]: [["Carlos", "Jackson", "Sebastian", "Gav", "Lorenzo", "Logan", "Nicolas", "Trenton", "Deshawn", "Dwayne", "Jeffery", "Kyler", "Taylor", "Alain", "Claude", "Crofton", "Forrest", "Harry", "Jaden", "Keith", "Lewis", "Miguel", "Pedro", "Ralph", "Richard", "Bret", "Daryl", "Eddie", "Johan", "Leaf", "Louis", "Maxwell", "Parker", "Rick", "Steve", "Bjorn", "Chaise", "Dean", "Lee", "Maurice", "Nash", "Ralf", "Reed", "Shinobu", "Silas"], ["Catherine", "Jenna", "Sophia", "Merdith", "Nora", "Beth", "Chelsea", "Katelyn", "Madeline", "Allison", "Ashlee", "Felicia", "Krista", "Annie", "Audra", "Brenda", "Chloris", "Eliza", "Heidi", "Irene", "Mary", "Mylene", "Shanti", "Shelly", "Thalia", "Anja", "Briana", "Dianna", "Elaine", "Elle", "Hillary", "Katie", "Lena", "Lois", "Malory", "Melita", "Mikiko", "Naoko", "Serenity", "Ambre", "Brooke", "Clementine", "Melina", "Petra", "Twiggy"]], - [TrainerType.RICH]: [["Alfred", "Edward", "Gregory", "Preston", "Thomas", "Tucker", "Walter", "Clifford", "Everett", "Micah", "Nate", "Pierre", "Terrance", "Arthur", "Brooks", "Emanuel", "Lamar", "Jeremy", "Leonardo", "Milton", "Frederic", "Renaud", "Robert", "Yan", "Daniel", "Sheldon", "Stonewall", "Gerald", "Ronald", "Smith", "Stanley", "Reginald", "Orson", "Wilco", "Caden", "Glenn"], ["Rebecca", "Reina", "Cassandra", "Emilia", "Grace", "Marian", "Elizabeth", "Kathleen", "Sayuri", "Caroline", "Judy"]], - [TrainerType.RICH_KID]: [["Garret", "Winston", "Dawson", "Enrique", "Jason", "Roman", "Trey", "Liam", "Anthony", "Brad", "Cody", "Manuel", "Martin", "Pierce", "Rolan", "Keenan", "Filbert", "Antoin", "Cyus", "Diek", "Dugo", "Flitz", "Jurek", "Lond", "Perd", "Quint", "Basto", "Benit", "Brot", "Denc", "Guyit", "Marcon", "Perc", "Puros", "Roex", "Sainz", "Symin", "Tark", "Venak"], ["Anette", "Brianna", "Cindy", "Colleen", "Daphne", "Elizabeth", "Naomi", "Sarah", "Charlotte", "Gillian", "Jacki", "Lady", "Melissa", "Celeste", "Colette", "Elizandra", "Isabel", "Lynette", "Magnolia", "Sophie", "Lina", "Dulcie", "Auro", "Brin", "Caril", "Eloos", "Gwin", "Illa", "Kowly", "Rima", "Ristin", "Vesey", "Brena", "Deasy", "Denslon", "Kylet", "Nemi", "Rene", "Sanol", "Stouner", "Sturk", "Talmen", "Zoila"]], - [TrainerType.ROUGHNECK]: ["Camron", "Corey", "Gabriel", "Isaiah", "Jamal", "Koji", "Luke", "Paxton", "Raul", "Zeek", "Kirby", "Chance", "Dave", "Fletcher", "Johnny", "Reese", "Joey", "Ricky", "Silvester", "Martin"], - [TrainerType.SAILOR]: ["Alberto", "Bost", "Brennan", "Brenden", "Claude", "Cory", "Damian", "Dirk", "Duncan", "Dwayne", "Dylan", "Eddie", "Edmond", "Elijah", "Ernest", "Eugene", "Garrett", "Golos", "Gratin", "Grestly", "Harry", "Hols", "Hudson", "Huey", "Jebol", "Jeff", "Leonald", "Luther", "Kelvin", "Kenneth", "Kent", "Knook", "Marc", "Mifis", "Monar", "Morkor", "Ordes", "Oxlin", "Parker", "Paul", "Philip", "Roberto", "Samson", "Skyler", "Stanly", "Tebu", "Terrell", "Trevor", "Yasu", "Zachariah"], - [TrainerType.SCIENTIST]: [["Jed", "Marc", "Mitch", "Rich", "Ross", "Beau", "Braydon", "Connor", "Ed", "Ivan", "Jerry", "Jose", "Joshua", "Parker", "Rodney", "Taylor", "Ted", "Travis", "Zackery", "Darrius", "Emilio", "Fredrick", "Shaun", "Stefano", "Travon", "Daniel", "Garett", "Gregg", "Linden", "Lowell", "Trenton", "Dudley", "Luke", "Markus", "Nathan", "Orville", "Randall", "Ron", "Ronald", "Simon", "Steve", "William", "Franklin", "Clarke", "Jacques", "Terrance", "Ernst", "Justus", "Ikaika", "Jayson", "Kyle", "Reid", "Tyrone", "Adam", "Albert", "Alphonse", "Cory", "Donnie", "Elton", "Francis", "Gordon", "Herbert", "Humphrey", "Jordan", "Julian", "Keaton", "Levi", "Melvin", "Murray", "West", "Craig", "Coren", "Dubik", "Kotan", "Lethco", "Mante", "Mort", "Myron", "Odlow", "Ribek", "Roeck", "Vogi", "Vonder", "Zogo", "Doimo", "Doton", "Durel", "Hildon", "Kukla", "Messa", "Nanot", "Platen", "Raburn", "Reman", "Acrod", "Coffy", "Elrok", "Foss", "Hardig", "Hombol", "Hospel", "Kaller", "Klots", "Krilok", "Limar", "Loket", "Mesak", "Morbit", "Newin", "Orill", "Tabor", "Tekot"], ["Blythe", "Chan", "Kathrine", "Marie", "Maria", "Naoko", "Samantha", "Satomi", "Shannon", "Athena", "Caroline", "Lumi", "Lumina", "Marissa", "Sonia"]], - [TrainerType.SMASHER]: ["Aspen", "Elena", "Mari", "Amy", "Lizzy"], - [TrainerType.SNOW_WORKER]: [["Braden", "Brendon", "Colin", "Conrad", "Dillan", "Gary", "Gerardo", "Holden", "Jackson", "Mason", "Quentin", "Willy", "Noel", "Arnold", "Brady", "Brand", "Cairn", "Cliff", "Don", "Eddie", "Felix", "Filipe", "Glenn", "Gus", "Heath", "Matthew", "Patton", "Rich", "Rob", "Ryan", "Scott", "Shelby", "Sterling", "Tyler", "Victor", "Zack", "Friedrich", "Herman", "Isaac", "Leo", "Maynard", "Mitchell", "Morgann", "Nathan", "Niel", "Pasqual", "Paul", "Tavarius", "Tibor", "Dimitri", "Narek", "Yusif", "Frank", "Jeff", "Vaclav", "Ovid", "Francis", "Keith", "Russel", "Sangon", "Toway", "Bomber", "Chean", "Demit", "Hubor", "Kebile", "Laber", "Ordo", "Retay", "Ronix", "Wagel", "Dobit", "Kaster", "Lobel", "Releo", "Saken", "Rustix"], ["Georgia", "Sandra", "Yvonne"]], - [TrainerType.STRIKER]: ["Marco", "Roberto", "Tony"], - [TrainerType.SCHOOL_KID]: [["Alan", "Billy", "Chad", "Danny", "Dudley", "Jack", "Joe", "Johnny", "Kipp", "Nate", "Ricky", "Tommy", "Jerry", "Paul", "Ted", "Chance", "Esteban", "Forrest", "Harrison", "Connor", "Sherman", "Torin", "Travis", "Al", "Carter", "Edgar", "Jem", "Sammy", "Shane", "Shayne", "Alvin", "Keston", "Neil", "Seymour", "William", "Carson", "Clark", "Nolan"], ["Georgia", "Karen", "Meiko", "Christine", "Mackenzie", "Tiera", "Ann", "Gina", "Lydia", "Marsha", "Millie", "Sally", "Serena", "Silvia", "Alberta", "Cassie", "Mara", "Rita", "Georgie", "Meena", "Nitzel"]], - [TrainerType.SWIMMER]: [["Berke", "Cameron", "Charlie", "George", "Harold", "Jerome", "Kirk", "Mathew", "Parker", "Randall", "Seth", "Simon", "Tucker", "Austin", "Barry", "Chad", "Cody", "Darrin", "David", "Dean", "Douglas", "Franklin", "Gilbert", "Herman", "Jack", "Luis", "Matthew", "Reed", "Richard", "Rodney", "Roland", "Spencer", "Stan", "Tony", "Clarence", "Declan", "Dominik", "Harrison", "Kevin", "Leonardo", "Nolen", "Pete", "Santiago", "Axle", "Braden", "Finn", "Garrett", "Mymo", "Reece", "Samir", "Toby", "Adrian", "Colton", "Dillon", "Erik", "Evan", "Francisco", "Glenn", "Kurt", "Oscar", "Ricardo", "Sam", "Sheltin", "Troy", "Vincent", "Wade", "Wesley", "Duane", "Elmo", "Esteban", "Frankie", "Ronald", "Tyson", "Bart", "Matt", "Tim", "Wright", "Jeffery", "Kyle", "Alessandro", "Estaban", "Kieran", "Ramses", "Casey", "Dakota", "Jared", "Kalani", "Keoni", "Lawrence", "Logan", "Robert", "Roddy", "Yasu", "Derek", "Jacob", "Bruce", "Clayton"], ["Briana", "Dawn", "Denise", "Diana", "Elaine", "Kara", "Kaylee", "Lori", "Nicole", "Nikki", "Paula", "Susie", "Wendy", "Alice", "Beth", "Beverly", "Brenda", "Dana", "Debra", "Grace", "Jenny", "Katie", "Laurel", "Linda", "Missy", "Sharon", "Tanya", "Tara", "Tisha", "Carlee", "Imani", "Isabelle", "Kyla", "Sienna", "Abigail", "Amara", "Anya", "Connie", "Maria", "Melissa", "Nora", "Shirley", "Shania", "Tiffany", "Aubree", "Cassandra", "Claire", "Crystal", "Erica", "Gabrielle", "Haley", "Jessica", "Joanna", "Lydia", "Mallory", "Mary", "Miranda", "Paige", "Sophia", "Vanessa", "Chelan", "Debbie", "Joy", "Kendra", "Leona", "Mina", "Caroline", "Joyce", "Larissa", "Rebecca", "Tyra", "Dara", "Desiree", "Kaoru", "Ruth", "Coral", "Genevieve", "Isla", "Marissa", "Romy", "Sheryl", "Alexandria", "Alicia", "Chelsea", "Jade", "Kelsie", "Laura", "Portia", "Shelby", "Sara", "Tiare", "Kyra", "Natasha", "Layla", "Scarlett", "Cora"]], - [TrainerType.TWINS]: ["Amy & May", "Jo & Zoe", "Meg & Peg", "Ann & Anne", "Lea & Pia", "Amy & Liv", "Gina & Mia", "Miu & Yuki", "Tori & Tia", "Eli & Anne", "Jen & Kira", "Joy & Meg", "Kiri & Jan", "Miu & Mia", "Emma & Lil", "Liv & Liz", "Teri & Tia", "Amy & Mimi", "Clea & Gil", "Day & Dani", "Kay & Tia", "Tori & Til", "Saya & Aya", "Emy & Lin", "Kumi & Amy", "Mayo & May", "Ally & Amy", "Lia & Lily", "Rae & Ula", "Sola & Ana", "Tara & Val", "Faith & Joy", "Nana & Nina"], - [TrainerType.VETERAN]: [["Armando", "Brenden", "Brian", "Clayton", "Edgar", "Emanuel", "Grant", "Harlan", "Terrell", "Arlen", "Chester", "Hugo", "Martell", "Ray", "Shaun", "Abraham", "Carter", "Claude", "Jerry", "Lucius", "Murphy", "Rayne", "Ron", "Sinan", "Sterling", "Vincent", "Zach", "Gerard", "Gilles", "Louis", "Timeo", "Akira", "Don", "Eric", "Harry", "Leon", "Roger", "Angus", "Aristo", "Brone", "Johnny"], ["Julia", "Karla", "Kim", "Sayuri", "Tiffany", "Cathy", "Cecile", "Chloris", "Denae", "Gina", "Maya", "Oriana", "Portia", "Rhona", "Rosaline", "Catrina", "Inga", "Trisha", "Heather", "Lynn", "Sheri", "Alonsa", "Ella", "Leticia", "Kiara"]], - [TrainerType.WAITER]: [["Bert", "Clint", "Maxwell", "Lou"], ["Kati", "Aurora", "Bonita", "Flo", "Tia", "Jan", "Olwen", "Paget", "Paula", "Talia"]], - [TrainerType.WORKER]: [["Braden", "Brendon", "Colin", "Conrad", "Dillan", "Gary", "Gerardo", "Holden", "Jackson", "Mason", "Quentin", "Willy", "Noel", "Arnold", "Brady", "Brand", "Cairn", "Cliff", "Don", "Eddie", "Felix", "Filipe", "Glenn", "Gus", "Heath", "Matthew", "Patton", "Rich", "Rob", "Ryan", "Scott", "Shelby", "Sterling", "Tyler", "Victor", "Zack", "Friedrich", "Herman", "Isaac", "Leo", "Maynard", "Mitchell", "Morgann", "Nathan", "Niel", "Pasqual", "Paul", "Tavarius", "Tibor", "Dimitri", "Narek", "Yusif", "Frank", "Jeff", "Vaclav", "Ovid", "Francis", "Keith", "Russel", "Sangon", "Toway", "Bomber", "Chean", "Demit", "Hubor", "Kebile", "Laber", "Ordo", "Retay", "Ronix", "Wagel", "Dobit", "Kaster", "Lobel", "Releo", "Saken", "Rustix"], ["Georgia", "Sandra", "Yvonne"]], - [TrainerType.YOUNGSTER]: [["Albert", "Gordon", "Ian", "Jason", "Jimmy", "Mikey", "Owen", "Samuel", "Warren", "Allen", "Ben", "Billy", "Calvin", "Dillion", "Eddie", "Joey", "Josh", "Neal", "Timmy", "Tommy", "Breyden", "Deandre", "Demetrius", "Dillon", "Jaylen", "Johnson", "Shigenobu", "Chad", "Cole", "Cordell", "Dan", "Dave", "Destin", "Nash", "Tyler", "Yasu", "Austin", "Dallas", "Darius", "Donny", "Jonathon", "Logan", "Michael", "Oliver", "Sebastian", "Tristan", "Wayne", "Norman", "Roland", "Regis", "Abe", "Astor", "Keita", "Kenneth", "Kevin", "Kyle", "Lester", "Masao", "Nicholas", "Parker", "Wes", "Zachary", "Cody", "Henley", "Jaye", "Karl", "Kenny", "Masahiro", "Pedro", "Petey", "Sinclair", "Terrell", "Waylon", "Aidan", "Anthony", "David", "Jacob", "Jayden", "Cutler", "Ham", "Caleb", "Kai", "Honus", "Kenway", "Bret", "Chris", "Cid", "Dennis", "Easton", "Ken", "Robby", "Ronny", "Shawn", "Benjamin", "Jake", "Travis", "Adan", "Aday", "Beltran", "Elian", "Hernan", "Julen", "Luka", "Roi", "Bernie", "Dustin", "Jonathan", "Wyatt"], ["Alice", "Bridget", "Carrie", "Connie", "Dana", "Ellen", "Krise", "Laura", "Linda", "Michelle", "Shannon", "Andrea", "Crissy", "Janice", "Robin", "Sally", "Tiana", "Haley", "Ali", "Ann", "Dalia", "Dawn", "Iris", "Joana", "Julia", "Kay", "Lisa", "Megan", "Mikaela", "Miriam", "Paige", "Reli", "Blythe", "Briana", "Caroline", "Cassidy", "Kaitlin", "Madeline", "Molly", "Natalie", "Samantha", "Sarah", "Cathy", "Dye", "Eri", "Eva", "Fey", "Kara", "Lurleen", "Maki", "Mali", "Maya", "Miki", "Sibyl", "Daya", "Diana", "Flo", "Helia", "Henrietta", "Isabel", "Mai", "Persephone", "Serena", "Anna", "Charlotte", "Elin", "Elsa", "Lise", "Sara", "Suzette", "Audrey", "Emmy", "Isabella", "Madison", "Rika", "Rylee", "Salla", "Ellie", "Alexandra", "Amy", "Lass", "Brittany", "Chel", "Cindy", "Dianne", "Emily", "Emma", "Evelyn", "Hana", "Harleen", "Hazel", "Jocelyn", "Katrina", "Kimberly", "Lina", "Marge", "Mila", "Mizuki", "Rena", "Sal", "Satoko", "Summer", "Tomoe", "Vicky", "Yue", "Yumi", "Lauren", "Rei", "Riley", "Lois", "Nancy", "Tammy", "Terry"]], - [TrainerType.HEX_MANIAC]: ["Kindra", "Patricia", "Tammy", "Tasha", "Valerie", "Alaina", "Kathleen", "Leah", "Makie", "Sylvia", "Anina", "Arachna", "Carrie", "Desdemona", "Josette", "Luna", "Melanie", "Osanna", "Raziah"], + [TrainerType.ACE_TRAINER]: [[ "Aaron", "Allen", "Blake", "Brian", "Gaven", "Jake", "Kevin", "Mike", "Nick", "Paul", "Ryan", "Sean", "Darin", "Albert", "Berke", "Clyde", "Edgar", "George", "Leroy", "Owen", "Parker", "Randall", "Ruben", "Samuel", "Vincent", "Warren", "Wilton", "Zane", "Alfred", "Braxton", "Felix", "Gerald", "Jonathan", "Leonel", "Marcel", "Mitchell", "Quincy", "Roderick", "Colby", "Rolando", "Yuji", "Abel", "Anton", "Arthur", "Cesar", "Dalton", "Dennis", "Ernest", "Garrett", "Graham", "Henry", "Isaiah", "Jonah", "Jose", "Keenan", "Micah", "Omar", "Quinn", "Rodolfo", "Saul", "Sergio", "Skylar", "Stefan", "Zachery", "Alton", "Arabella", "Bonita", "Cal", "Cody", "French", "Kobe", "Paulo", "Shaye", "Austin", "Beckett", "Charlie", "Corky", "David", "Dwayne", "Elmer", "Jesse", "Jared", "Johan", "Jordan", "Kipp", "Lou", "Terry", "Tom", "Webster", "Billy", "Doyle", "Enzio", "Geoff", "Grant", "Kelsey", "Miguel", "Pierce", "Ray", "Santino", "Shel", "Adelbert", "Bence", "Emil", "Evan", "Mathis", "Maxim", "Neil", "Rico", "Robbie", "Theo", "Viktor", "Benedict", "Cornelius", "Hisato", "Leopold", "Neville", "Vito", "Chase", "Cole", "Hiroshi", "Jackson", "Jim", "Kekoa", "Makana", "Yuki", "Elwood", "Seth", "Alvin", "Arjun", "Arnold", "Cameron", "Carl", "Carlton", "Christopher", "Dave", "Dax", "Dominic", "Edmund", "Finn", "Fred", "Garret", "Grayson", "Jace", "Jaxson", "Jay", "Jirard", "Johnson", "Kayden", "Kite", "Louis", "Mac", "Marty", "Percy", "Raymond", "Ronnie", "Satch", "Tim", "Zach", "Conner", "Vince", "Bedro", "Boda", "Botan", "Daras", "Dury", "Herton", "Rewn", "Stum", "Tock", "Trilo", "Berki", "Cruik", "Dazon", "Desid", "Dillot", "Farfin", "Forgon", "Hebel", "Morfon", "Moril", "Shadd", "Vanhub", "Bardo", "Carben", "Degin", "Gorps", "Klept", "Lask", "Malex", "Mopar", "Niled", "Noxon", "Teslor", "Tetil" ], [ "Beth", "Carol", "Cybil", "Emma", "Fran", "Gwen", "Irene", "Jenn", "Joyce", "Kate", "Kelly", "Lois", "Lola", "Megan", "Quinn", "Reena", "Cara", "Alexa", "Brooke", "Caroline", "Elaine", "Hope", "Jennifer", "Jody", "Julie", "Lori", "Mary", "Michelle", "Shannon", "Wendy", "Alexia", "Alicia", "Athena", "Carolina", "Cristin", "Darcy", "Dianne", "Halle", "Jazmyn", "Katelynn", "Keira", "Marley", "Allyson", "Kathleen", "Naomi", "Alyssa", "Ariana", "Brandi", "Breanna", "Brenda", "Brenna", "Catherine", "Clarice", "Dana", "Deanna", "Destiny", "Jamie", "Jasmin", "Kassandra", "Laura", "Maria", "Mariah", "Maya", "Meagan", "Mikayla", "Monique", "Natasha", "Olivia", "Sandra", "Savannah", "Sydney", "Moira", "Piper", "Salma", "Allison", "Beverly", "Cathy", "Cheyenne", "Clara", "Dara", "Eileen", "Glinda", "Junko", "Lena", "Lucille", "Mariana", "Olwen", "Shanta", "Stella", "Angi", "Belle", "Chandra", "Cora", "Eve", "Jacqueline", "Jeanne", "Juliet", "Kathrine", "Layla", "Lucca", "Melina", "Miki", "Nina", "Sable", "Shelly", "Summer", "Trish", "Vicki", "Alanza", "Cordelia", "Hilde", "Imelda", "Michele", "Mireille", "Claudia", "Constance", "Harriet", "Honor", "Melba", "Portia", "Alexis", "Angela", "Karla", "Lindsey", "Tori", "Sheri", "Jada", "Kailee", "Amanda", "Annie", "Kindra", "Kyla", "Sofia", "Yvette", "Becky", "Flora", "Gloria", "Buna", "Ferda", "Lehan", "Liqui", "Lomen", "Neira", "Atilo", "Detta", "Gilly", "Gosney", "Levens", "Moden", "Rask", "Rateis", "Rosno", "Tynan", "Veron", "Zoel", "Cida", "Dibsin", "Dodin", "Ebson", "Equin", "Flostin", "Gabsen", "Halsion", "Hileon", "Quelor", "Rapeel", "Roze", "Tensin" ]], + [TrainerType.ARTIST]: [[ "Ismael", "William", "Horton", "Pierre", "Zach", "Gough", "Salvador", "Vincent", "Duncan" ], [ "Georgia" ]], + [TrainerType.BACKERS]: [[ "Alf & Fred", "Hawk & Dar", "Joe & Ross", "Les & Web", "Masa & Yas", "Stu & Art" ], [ "Ai & Ciel", "Ami & Eira", "Cam & Abby", "Fey & Sue", "Kat & Phae", "Kay & Ali", "Ava & Aya", "Cleo & Rio", "May & Mal" ]], + [TrainerType.BACKPACKER]: [[ "Alexander", "Carlos", "Herman", "Jerome", "Keane", "Kelsey", "Kiyo", "Michael", "Nate", "Peter", "Sam", "Stephen", "Talon", "Terrance", "Toru", "Waylon", "Boone", "Clifford", "Ivan", "Kendall", "Lowell", "Randall", "Reece", "Roland", "Shane", "Walt", "Farid", "Heike", "Joren", "Lane", "Roderick", "Darnell", "Deon", "Emory", "Graeme", "Grayson", "Aitor", "Alex", "Arturo", "Asier", "Jaime", "Jonathan", "Julio", "Kevin", "Kosuke", "Lander", "Markel", "Mateo", "Nil", "Pau", "Samuel" ], [ "Anna", "Corin", "Elaine", "Emi", "Jill", "Kumiko", "Liz", "Lois", "Lora", "Molly", "Patty", "Ruth", "Vicki", "Annie", "Blossom", "Clara", "Eileen", "Mae", "Myra", "Rachel", "Tami", "Ashley", "Mikiko", "Kiana", "Perdy", "Maria", "Yuho", "Peren", "Barbara", "Diane" ]], + [TrainerType.BAKER]: [ "Chris", "Jenn", "Lilly" ], + [TrainerType.BEAUTY]: [ "Cassie", "Julia", "Olivia", "Samantha", "Valerie", "Victoria", "Bridget", "Connie", "Jessica", "Johanna", "Melissa", "Sheila", "Shirley", "Tiffany", "Namiko", "Thalia", "Grace", "Lola", "Lori", "Maura", "Tamia", "Cyndy", "Devon", "Gabriella", "Harley", "Lindsay", "Nicola", "Callie", "Charlotte", "Kassandra", "December", "Fleming", "Nikola", "Aimee", "Anais", "Brigitte", "Cassandra", "Andrea", "Brittney", "Carolyn", "Krystal", "Alexis", "Alice", "Aina", "Anya", "Arianna", "Aubrey", "Beverly", "Camille", "Beauty", "Evette", "Hansol", "Haruka", "Jill", "Jo", "Lana", "Lois", "Lucy", "Mai", "Nickie", "Nicole", "Prita", "Rose", "Shelly", "Suzy", "Tessa", "Anita", "Alissa", "Rita", "Cudsy", "Eloff", "Miru", "Minot", "Nevah", "Niven", "Ogoin" ], + [TrainerType.BIKER]: [ "Charles", "Dwayne", "Glenn", "Harris", "Joel", "Riley", "Zeke", "Alex", "Billy", "Ernest", "Gerald", "Hideo", "Isaac", "Jared", "Jaren", "Jaxon", "Jordy", "Lao", "Lukas", "Malik", "Nikolas", "Ricardo", "Ruben", "Virgil", "William", "Aiden", "Dale", "Dan", "Jacob", "Markey", "Reese", "Teddy", "Theron", "Jeremy", "Morgann", "Phillip", "Philip", "Stanley", "Dillon" ], + [TrainerType.BLACK_BELT]: [[ "Kenji", "Lao", "Lung", "Nob", "Wai", "Yoshi", "Atsushi", "Daisuke", "Hideki", "Hitoshi", "Kiyo", "Koichi", "Koji", "Yuji", "Cristian", "Rhett", "Takao", "Theodore", "Zander", "Aaron", "Hugh", "Mike", "Nicolas", "Shea", "Takashi", "Adam", "Carl", "Colby", "Darren", "David", "Davon", "Derek", "Eddie", "Gregory", "Griffin", "Jarrett", "Jeffery", "Kendal", "Kyle", "Luke", "Miles", "Nathaniel", "Philip", "Rafael", "Ray", "Ricky", "Sean", "Willie", "Ander", "Manford", "Benjamin", "Corey", "Edward", "Grant", "Jay", "Kendrew", "Kentaro", "Ryder", "Teppei", "Thomas", "Tyrone", "Andrey", "Donny", "Drago", "Gordon", "Grigor", "Jeriel", "Kenneth", "Martell", "Mathis", "Rich", "Rocky", "Rodrigo", "Wesley", "Zachery", "Alonzo", "Cadoc", "Gunnar", "Igor", "Killian", "Markus", "Ricardo", "Yanis", "Banting", "Clayton", "Duane", "Earl", "Greg", "Roy", "Terry", "Tracy", "Walter", "Alvaro", "Curtis", "Francis", "Ross", "Brice", "Cheng", "Dudley", "Eric", "Kano", "Masahiro", "Randy", "Ryuji", "Steve", "Tadashi", "Wong", "Yuen", "Brian", "Carter", "Reece", "Nick", "Yang" ], [ "Cora", "Cyndy", "Jill", "Laura", "Sadie", "Tessa", "Vivian", "Aisha", "Callie", "Danielle", "Helene", "Jocelyn", "Lilith", "Paula", "Reyna", "Helen", "Kelsey", "Tyler", "Amy", "Chandra", "Hillary", "Janie", "Lee", "Maggie", "Mikiko", "Miriam", "Sharon", "Susie", "Xiao", "Alize", "Azra", "Brenda", "Chalina", "Chan", "Glinda", "Maki", "Tia", "Tiffany", "Wendy", "Andrea", "Gabrielle", "Gerardine", "Hailey", "Hedvig", "Justine", "Kinsey", "Sigrid", "Veronique", "Tess" ]], + [TrainerType.BREEDER]: [[ "Isaac", "Myles", "Salvadore", "Albert", "Kahlil", "Eustace", "Galen", "Owen", "Addison", "Marcus", "Foster", "Cory", "Glenn", "Jay", "Wesley", "William", "Adrian", "Bradley", "Jaime" ], [ "Allison", "Alize", "Bethany", "Lily", "Lydia", "Gabrielle", "Jayden", "Pat", "Veronica", "Amber", "Jennifer", "Kaylee", "Adelaide", "Brooke", "Ethel", "April", "Irene", "Magnolia", "Amala", "Mercy", "Amanda", "Ikue", "Savannah", "Yuka", "Chloe", "Debra", "Denise", "Elena" ]], + [TrainerType.CLERK]: [[ "Chaz", "Clemens", "Doug", "Fredric", "Ivan", "Isaac", "Nelson", "Wade", "Warren", "Augustin", "Gilligan", "Cody", "Jeremy", "Shane", "Dugal", "Royce", "Ronald" ], [ "Alberta", "Ingrid", "Katie", "Piper", "Trisha", "Wren", "Britney", "Lana", "Jessica", "Kristen", "Michelle", "Gabrielle" ]], + [TrainerType.CYCLIST]: [[ "Axel", "James", "John", "Ryan", "Hector", "Jeremiah" ], [ "Kayla", "Megan", "Nicole", "Rachel", "Krissa", "Adelaide" ]], + [TrainerType.DANCER]: [ "Brian", "Davey", "Dirk", "Edmond", "Mickey", "Raymond", "Cara", "Julia", "Maika", "Mireille", "Ronda", "Zoe" ], + [TrainerType.DEPOT_AGENT]: [ "Josh", "Hank", "Vincent" ], + [TrainerType.DOCTOR]: [[ "Hank", "Jerry", "Jules", "Logan", "Wayne", "Braid", "Derek", "Heath", "Julius", "Kit", "Graham" ], [ "Kirsten", "Sachiko", "Shery", "Carol", "Dixie", "Mariah" ]], + [TrainerType.FIREBREATHER]: [ "Bill", "Burt", "Cliff", "Dick", "Lyle", "Ned", "Otis", "Ray", "Richard", "Walt" ], + [TrainerType.FISHERMAN]: [ "Andre", "Arnold", "Barney", "Chris", "Edgar", "Henry", "Jonah", "Justin", "Kyle", "Martin", "Marvin", "Ralph", "Raymond", "Scott", "Stephen", "Wilton", "Tully", "Andrew", "Barny", "Carter", "Claude", "Dale", "Elliot", "Eugene", "Ivan", "Ned", "Nolan", "Roger", "Ronald", "Wade", "Wayne", "Darian", "Kai", "Chip", "Hank", "Kaden", "Tommy", "Tylor", "Alec", "Brett", "Cameron", "Cody", "Cole", "Cory", "Erick", "George", "Joseph", "Juan", "Kenneth", "Luc", "Miguel", "Travis", "Walter", "Zachary", "Josh", "Gideon", "Kyler", "Liam", "Murphy", "Bruce", "Damon", "Devon", "Hubert", "Jones", "Lydon", "Mick", "Pete", "Sean", "Sid", "Vince", "Bucky", "Dean", "Eustace", "Kenzo", "Leroy", "Mack", "Ryder", "Ewan", "Finn", "Murray", "Seward", "Shad", "Wharton", "Finley", "Fisher", "Fisk", "River", "Sheaffer", "Timin", "Carl", "Ernest", "Hal", "Herbert", "Hisato", "Mike", "Vernon", "Harriet", "Marina", "Chase" ], + [TrainerType.GUITARIST]: [ "Anna", "Beverly", "January", "Tina", "Alicia", "Claudia", "Julia", "Lidia", "Mireia", "Noelia", "Sara", "Sheila", "Tatiana" ], + [TrainerType.HARLEQUIN]: [ "Charley", "Ian", "Jack", "Kerry", "Louis", "Pat", "Paul", "Rick", "Anders", "Clarence", "Gary" ], + [TrainerType.HIKER]: [ "Anthony", "Bailey", "Benjamin", "Daniel", "Erik", "Jim", "Kenny", "Leonard", "Michael", "Parry", "Phillip", "Russell", "Sidney", "Tim", "Timothy", "Alan", "Brice", "Clark", "Eric", "Lenny", "Lucas", "Mike", "Trent", "Devan", "Eli", "Marc", "Sawyer", "Allen", "Daryl", "Dudley", "Earl", "Franklin", "Jeremy", "Marcos", "Nob", "Oliver", "Wayne", "Alexander", "Damon", "Jonathan", "Justin", "Kevin", "Lorenzo", "Louis", "Maurice", "Nicholas", "Reginald", "Robert", "Theodore", "Bruce", "Clarke", "Devin", "Dwight", "Edwin", "Eoin", "Noland", "Russel", "Andy", "Bret", "Darrell", "Gene", "Hardy", "Hugh", "Jebediah", "Jeremiah", "Kit", "Neil", "Terrell", "Don", "Doug", "Hunter", "Jared", "Jerome", "Keith", "Manuel", "Markus", "Otto", "Shelby", "Stephen", "Teppei", "Tobias", "Wade", "Zaiem", "Aaron", "Alain", "Bergin", "Bernard", "Brent", "Corwin", "Craig", "Delmon", "Dunstan", "Orestes", "Ross", "Davian", "Calhoun", "David", "Gabriel", "Ryan", "Thomas", "Travis", "Zachary", "Anuhea", "Barnaby", "Claus", "Collin", "Colson", "Dexter", "Dillan", "Eugine", "Farkas", "Hisato", "Julius", "Kenji", "Irwin", "Lionel", "Paul", "Richter", "Valentino", "Donald", "Douglas", "Kevyn", "Chester" ], //["Angela","Carla","Celia","Daniela","Estela","Fatima","Helena","Leire","Lucia","Luna","Manuela","Mar","Marina","Miyu","Nancy","Nerea","Paula","Rocio","Yanira"] + [TrainerType.HOOLIGANS]: [ "Jim & Cas", "Rob & Sal" ], + [TrainerType.HOOPSTER]: [ "Bobby", "John", "Lamarcus", "Derrick", "Nicolas" ], + [TrainerType.INFIELDER]: [ "Alex", "Connor", "Todd" ], + [TrainerType.JANITOR]: [ "Caleb", "Geoff", "Brady", "Felix", "Orville", "Melvin", "Shawn" ], + [TrainerType.LINEBACKER]: [ "Bob", "Dan", "Jonah" ], + [TrainerType.MAID]: [ "Belinda", "Sophie", "Emily", "Elena", "Clare", "Alica", "Tanya", "Tammy" ], + [TrainerType.MUSICIAN]: [ "Boris", "Preston", "Charles", "Clyde", "Vincent", "Dalton", "Kirk", "Shawn", "Fabian", "Fernando", "Joseph", "Marcos", "Arturo", "Jerry", "Lonnie", "Tony" ], + [TrainerType.NURSERY_AIDE]: [ "Autumn", "Briana", "Leah", "Miho", "Ethel", "Hollie", "Ilse", "June", "Kimya", "Rosalyn" ], + [TrainerType.OFFICER]: [ "Dirk", "Keith", "Alex", "Bobby", "Caleb", "Danny", "Dylan", "Thomas", "Daniel", "Jeff", "Braven", "Dell", "Neagle", "Haruki", "Mitchell", "Raymond" ], + [TrainerType.PARASOL_LADY]: [ "Angelica", "Clarissa", "Madeline", "Akari", "Annabell", "Kayley", "Rachel", "Alexa", "Sabrina", "April", "Gwyneth", "Laura", "Lumi", "Mariah", "Melita", "Nicole", "Tihana", "Ingrid", "Tyra" ], + [TrainerType.PILOT]: [ "Chase", "Leonard", "Ted", "Elron", "Ewing", "Flynn", "Winslow" ], + [TrainerType.POKEFAN]: [[ "Alex", "Allan", "Brandon", "Carter", "Colin", "Derek", "Jeremy", "Joshua", "Rex", "Robert", "Trevor", "William", "Colton", "Miguel", "Francisco", "Kaleb", "Leonard", "Boone", "Elliot", "Jude", "Norbert", "Corey", "Gabe", "Baxter" ], [ "Beverly", "Georgia", "Jaime", "Ruth", "Isabel", "Marissa", "Vanessa", "Annika", "Bethany", "Kimberly", "Meredith", "Rebekah", "Eleanor", "Darcy", "Lydia", "Sachiko", "Abigail", "Agnes", "Lydie", "Roisin", "Tara", "Carmen", "Janet" ]], + [TrainerType.PRESCHOOLER]: [[ "Billy", "Doyle", "Evan", "Homer", "Tully", "Albert", "Buster", "Greg", "Ike", "Jojo", "Tyrone", "Adrian", "Oliver", "Hayden", "Hunter", "Kaleb", "Liam", "Dylan" ], [ "Juliet", "Mia", "Sarah", "Wendy", "Winter", "Chrissy", "Eva", "Lin", "Samantha", "Ella", "Lily", "Natalie", "Ailey", "Hannah", "Malia", "Kindra", "Nancy" ]], + [TrainerType.PSYCHIC]: [[ "Fidel", "Franklin", "Gilbert", "Greg", "Herman", "Jared", "Mark", "Nathan", "Norman", "Phil", "Richard", "Rodney", "Cameron", "Edward", "Fritz", "Joshua", "Preston", "Virgil", "William", "Alvaro", "Blake", "Cedric", "Keenan", "Nicholas", "Dario", "Johan", "Lorenzo", "Tyron", "Bryce", "Corbin", "Deandre", "Elijah", "Kody", "Landon", "Maxwell", "Mitchell", "Sterling", "Eli", "Nelson", "Vernon", "Gaven", "Gerard", "Low", "Micki", "Perry", "Rudolf", "Tommy", "Al", "Nandor", "Tully", "Arthur", "Emanuel", "Franz", "Harry", "Paschal", "Robert", "Sayid", "Angelo", "Anton", "Arin", "Avery", "Danny", "Frasier", "Harrison", "Jaime", "Ross", "Rui", "Vlad", "Mason" ], [ "Alexis", "Hannah", "Jacki", "Jaclyn", "Kayla", "Maura", "Samantha", "Alix", "Brandi", "Edie", "Macey", "Mariella", "Marlene", "Laura", "Rodette", "Abigail", "Brittney", "Chelsey", "Daisy", "Desiree", "Kendra", "Lindsey", "Rachael", "Valencia", "Belle", "Cybil", "Doreen", "Dua", "Future", "Lin", "Madhu", "Alia", "Ena", "Joyce", "Lynette", "Olesia", "Sarah" ]], + [TrainerType.RANGER]: [[ "Carlos", "Jackson", "Sebastian", "Gav", "Lorenzo", "Logan", "Nicolas", "Trenton", "Deshawn", "Dwayne", "Jeffery", "Kyler", "Taylor", "Alain", "Claude", "Crofton", "Forrest", "Harry", "Jaden", "Keith", "Lewis", "Miguel", "Pedro", "Ralph", "Richard", "Bret", "Daryl", "Eddie", "Johan", "Leaf", "Louis", "Maxwell", "Parker", "Rick", "Steve", "Bjorn", "Chaise", "Dean", "Lee", "Maurice", "Nash", "Ralf", "Reed", "Shinobu", "Silas" ], [ "Catherine", "Jenna", "Sophia", "Merdith", "Nora", "Beth", "Chelsea", "Katelyn", "Madeline", "Allison", "Ashlee", "Felicia", "Krista", "Annie", "Audra", "Brenda", "Chloris", "Eliza", "Heidi", "Irene", "Mary", "Mylene", "Shanti", "Shelly", "Thalia", "Anja", "Briana", "Dianna", "Elaine", "Elle", "Hillary", "Katie", "Lena", "Lois", "Malory", "Melita", "Mikiko", "Naoko", "Serenity", "Ambre", "Brooke", "Clementine", "Melina", "Petra", "Twiggy" ]], + [TrainerType.RICH]: [[ "Alfred", "Edward", "Gregory", "Preston", "Thomas", "Tucker", "Walter", "Clifford", "Everett", "Micah", "Nate", "Pierre", "Terrance", "Arthur", "Brooks", "Emanuel", "Lamar", "Jeremy", "Leonardo", "Milton", "Frederic", "Renaud", "Robert", "Yan", "Daniel", "Sheldon", "Stonewall", "Gerald", "Ronald", "Smith", "Stanley", "Reginald", "Orson", "Wilco", "Caden", "Glenn" ], [ "Rebecca", "Reina", "Cassandra", "Emilia", "Grace", "Marian", "Elizabeth", "Kathleen", "Sayuri", "Caroline", "Judy" ]], + [TrainerType.RICH_KID]: [[ "Garret", "Winston", "Dawson", "Enrique", "Jason", "Roman", "Trey", "Liam", "Anthony", "Brad", "Cody", "Manuel", "Martin", "Pierce", "Rolan", "Keenan", "Filbert", "Antoin", "Cyus", "Diek", "Dugo", "Flitz", "Jurek", "Lond", "Perd", "Quint", "Basto", "Benit", "Brot", "Denc", "Guyit", "Marcon", "Perc", "Puros", "Roex", "Sainz", "Symin", "Tark", "Venak" ], [ "Anette", "Brianna", "Cindy", "Colleen", "Daphne", "Elizabeth", "Naomi", "Sarah", "Charlotte", "Gillian", "Jacki", "Lady", "Melissa", "Celeste", "Colette", "Elizandra", "Isabel", "Lynette", "Magnolia", "Sophie", "Lina", "Dulcie", "Auro", "Brin", "Caril", "Eloos", "Gwin", "Illa", "Kowly", "Rima", "Ristin", "Vesey", "Brena", "Deasy", "Denslon", "Kylet", "Nemi", "Rene", "Sanol", "Stouner", "Sturk", "Talmen", "Zoila" ]], + [TrainerType.ROUGHNECK]: [ "Camron", "Corey", "Gabriel", "Isaiah", "Jamal", "Koji", "Luke", "Paxton", "Raul", "Zeek", "Kirby", "Chance", "Dave", "Fletcher", "Johnny", "Reese", "Joey", "Ricky", "Silvester", "Martin" ], + [TrainerType.SAILOR]: [ "Alberto", "Bost", "Brennan", "Brenden", "Claude", "Cory", "Damian", "Dirk", "Duncan", "Dwayne", "Dylan", "Eddie", "Edmond", "Elijah", "Ernest", "Eugene", "Garrett", "Golos", "Gratin", "Grestly", "Harry", "Hols", "Hudson", "Huey", "Jebol", "Jeff", "Leonald", "Luther", "Kelvin", "Kenneth", "Kent", "Knook", "Marc", "Mifis", "Monar", "Morkor", "Ordes", "Oxlin", "Parker", "Paul", "Philip", "Roberto", "Samson", "Skyler", "Stanly", "Tebu", "Terrell", "Trevor", "Yasu", "Zachariah" ], + [TrainerType.SCIENTIST]: [[ "Jed", "Marc", "Mitch", "Rich", "Ross", "Beau", "Braydon", "Connor", "Ed", "Ivan", "Jerry", "Jose", "Joshua", "Parker", "Rodney", "Taylor", "Ted", "Travis", "Zackery", "Darrius", "Emilio", "Fredrick", "Shaun", "Stefano", "Travon", "Daniel", "Garett", "Gregg", "Linden", "Lowell", "Trenton", "Dudley", "Luke", "Markus", "Nathan", "Orville", "Randall", "Ron", "Ronald", "Simon", "Steve", "William", "Franklin", "Clarke", "Jacques", "Terrance", "Ernst", "Justus", "Ikaika", "Jayson", "Kyle", "Reid", "Tyrone", "Adam", "Albert", "Alphonse", "Cory", "Donnie", "Elton", "Francis", "Gordon", "Herbert", "Humphrey", "Jordan", "Julian", "Keaton", "Levi", "Melvin", "Murray", "West", "Craig", "Coren", "Dubik", "Kotan", "Lethco", "Mante", "Mort", "Myron", "Odlow", "Ribek", "Roeck", "Vogi", "Vonder", "Zogo", "Doimo", "Doton", "Durel", "Hildon", "Kukla", "Messa", "Nanot", "Platen", "Raburn", "Reman", "Acrod", "Coffy", "Elrok", "Foss", "Hardig", "Hombol", "Hospel", "Kaller", "Klots", "Krilok", "Limar", "Loket", "Mesak", "Morbit", "Newin", "Orill", "Tabor", "Tekot" ], [ "Blythe", "Chan", "Kathrine", "Marie", "Maria", "Naoko", "Samantha", "Satomi", "Shannon", "Athena", "Caroline", "Lumi", "Lumina", "Marissa", "Sonia" ]], + [TrainerType.SMASHER]: [ "Aspen", "Elena", "Mari", "Amy", "Lizzy" ], + [TrainerType.SNOW_WORKER]: [[ "Braden", "Brendon", "Colin", "Conrad", "Dillan", "Gary", "Gerardo", "Holden", "Jackson", "Mason", "Quentin", "Willy", "Noel", "Arnold", "Brady", "Brand", "Cairn", "Cliff", "Don", "Eddie", "Felix", "Filipe", "Glenn", "Gus", "Heath", "Matthew", "Patton", "Rich", "Rob", "Ryan", "Scott", "Shelby", "Sterling", "Tyler", "Victor", "Zack", "Friedrich", "Herman", "Isaac", "Leo", "Maynard", "Mitchell", "Morgann", "Nathan", "Niel", "Pasqual", "Paul", "Tavarius", "Tibor", "Dimitri", "Narek", "Yusif", "Frank", "Jeff", "Vaclav", "Ovid", "Francis", "Keith", "Russel", "Sangon", "Toway", "Bomber", "Chean", "Demit", "Hubor", "Kebile", "Laber", "Ordo", "Retay", "Ronix", "Wagel", "Dobit", "Kaster", "Lobel", "Releo", "Saken", "Rustix" ], [ "Georgia", "Sandra", "Yvonne" ]], + [TrainerType.STRIKER]: [ "Marco", "Roberto", "Tony" ], + [TrainerType.SCHOOL_KID]: [[ "Alan", "Billy", "Chad", "Danny", "Dudley", "Jack", "Joe", "Johnny", "Kipp", "Nate", "Ricky", "Tommy", "Jerry", "Paul", "Ted", "Chance", "Esteban", "Forrest", "Harrison", "Connor", "Sherman", "Torin", "Travis", "Al", "Carter", "Edgar", "Jem", "Sammy", "Shane", "Shayne", "Alvin", "Keston", "Neil", "Seymour", "William", "Carson", "Clark", "Nolan" ], [ "Georgia", "Karen", "Meiko", "Christine", "Mackenzie", "Tiera", "Ann", "Gina", "Lydia", "Marsha", "Millie", "Sally", "Serena", "Silvia", "Alberta", "Cassie", "Mara", "Rita", "Georgie", "Meena", "Nitzel" ]], + [TrainerType.SWIMMER]: [[ "Berke", "Cameron", "Charlie", "George", "Harold", "Jerome", "Kirk", "Mathew", "Parker", "Randall", "Seth", "Simon", "Tucker", "Austin", "Barry", "Chad", "Cody", "Darrin", "David", "Dean", "Douglas", "Franklin", "Gilbert", "Herman", "Jack", "Luis", "Matthew", "Reed", "Richard", "Rodney", "Roland", "Spencer", "Stan", "Tony", "Clarence", "Declan", "Dominik", "Harrison", "Kevin", "Leonardo", "Nolen", "Pete", "Santiago", "Axle", "Braden", "Finn", "Garrett", "Mymo", "Reece", "Samir", "Toby", "Adrian", "Colton", "Dillon", "Erik", "Evan", "Francisco", "Glenn", "Kurt", "Oscar", "Ricardo", "Sam", "Sheltin", "Troy", "Vincent", "Wade", "Wesley", "Duane", "Elmo", "Esteban", "Frankie", "Ronald", "Tyson", "Bart", "Matt", "Tim", "Wright", "Jeffery", "Kyle", "Alessandro", "Estaban", "Kieran", "Ramses", "Casey", "Dakota", "Jared", "Kalani", "Keoni", "Lawrence", "Logan", "Robert", "Roddy", "Yasu", "Derek", "Jacob", "Bruce", "Clayton" ], [ "Briana", "Dawn", "Denise", "Diana", "Elaine", "Kara", "Kaylee", "Lori", "Nicole", "Nikki", "Paula", "Susie", "Wendy", "Alice", "Beth", "Beverly", "Brenda", "Dana", "Debra", "Grace", "Jenny", "Katie", "Laurel", "Linda", "Missy", "Sharon", "Tanya", "Tara", "Tisha", "Carlee", "Imani", "Isabelle", "Kyla", "Sienna", "Abigail", "Amara", "Anya", "Connie", "Maria", "Melissa", "Nora", "Shirley", "Shania", "Tiffany", "Aubree", "Cassandra", "Claire", "Crystal", "Erica", "Gabrielle", "Haley", "Jessica", "Joanna", "Lydia", "Mallory", "Mary", "Miranda", "Paige", "Sophia", "Vanessa", "Chelan", "Debbie", "Joy", "Kendra", "Leona", "Mina", "Caroline", "Joyce", "Larissa", "Rebecca", "Tyra", "Dara", "Desiree", "Kaoru", "Ruth", "Coral", "Genevieve", "Isla", "Marissa", "Romy", "Sheryl", "Alexandria", "Alicia", "Chelsea", "Jade", "Kelsie", "Laura", "Portia", "Shelby", "Sara", "Tiare", "Kyra", "Natasha", "Layla", "Scarlett", "Cora" ]], + [TrainerType.TWINS]: [ "Amy & May", "Jo & Zoe", "Meg & Peg", "Ann & Anne", "Lea & Pia", "Amy & Liv", "Gina & Mia", "Miu & Yuki", "Tori & Tia", "Eli & Anne", "Jen & Kira", "Joy & Meg", "Kiri & Jan", "Miu & Mia", "Emma & Lil", "Liv & Liz", "Teri & Tia", "Amy & Mimi", "Clea & Gil", "Day & Dani", "Kay & Tia", "Tori & Til", "Saya & Aya", "Emy & Lin", "Kumi & Amy", "Mayo & May", "Ally & Amy", "Lia & Lily", "Rae & Ula", "Sola & Ana", "Tara & Val", "Faith & Joy", "Nana & Nina" ], + [TrainerType.VETERAN]: [[ "Armando", "Brenden", "Brian", "Clayton", "Edgar", "Emanuel", "Grant", "Harlan", "Terrell", "Arlen", "Chester", "Hugo", "Martell", "Ray", "Shaun", "Abraham", "Carter", "Claude", "Jerry", "Lucius", "Murphy", "Rayne", "Ron", "Sinan", "Sterling", "Vincent", "Zach", "Gerard", "Gilles", "Louis", "Timeo", "Akira", "Don", "Eric", "Harry", "Leon", "Roger", "Angus", "Aristo", "Brone", "Johnny" ], [ "Julia", "Karla", "Kim", "Sayuri", "Tiffany", "Cathy", "Cecile", "Chloris", "Denae", "Gina", "Maya", "Oriana", "Portia", "Rhona", "Rosaline", "Catrina", "Inga", "Trisha", "Heather", "Lynn", "Sheri", "Alonsa", "Ella", "Leticia", "Kiara" ]], + [TrainerType.WAITER]: [[ "Bert", "Clint", "Maxwell", "Lou" ], [ "Kati", "Aurora", "Bonita", "Flo", "Tia", "Jan", "Olwen", "Paget", "Paula", "Talia" ]], + [TrainerType.WORKER]: [[ "Braden", "Brendon", "Colin", "Conrad", "Dillan", "Gary", "Gerardo", "Holden", "Jackson", "Mason", "Quentin", "Willy", "Noel", "Arnold", "Brady", "Brand", "Cairn", "Cliff", "Don", "Eddie", "Felix", "Filipe", "Glenn", "Gus", "Heath", "Matthew", "Patton", "Rich", "Rob", "Ryan", "Scott", "Shelby", "Sterling", "Tyler", "Victor", "Zack", "Friedrich", "Herman", "Isaac", "Leo", "Maynard", "Mitchell", "Morgann", "Nathan", "Niel", "Pasqual", "Paul", "Tavarius", "Tibor", "Dimitri", "Narek", "Yusif", "Frank", "Jeff", "Vaclav", "Ovid", "Francis", "Keith", "Russel", "Sangon", "Toway", "Bomber", "Chean", "Demit", "Hubor", "Kebile", "Laber", "Ordo", "Retay", "Ronix", "Wagel", "Dobit", "Kaster", "Lobel", "Releo", "Saken", "Rustix" ], [ "Georgia", "Sandra", "Yvonne" ]], + [TrainerType.YOUNGSTER]: [[ "Albert", "Gordon", "Ian", "Jason", "Jimmy", "Mikey", "Owen", "Samuel", "Warren", "Allen", "Ben", "Billy", "Calvin", "Dillion", "Eddie", "Joey", "Josh", "Neal", "Timmy", "Tommy", "Breyden", "Deandre", "Demetrius", "Dillon", "Jaylen", "Johnson", "Shigenobu", "Chad", "Cole", "Cordell", "Dan", "Dave", "Destin", "Nash", "Tyler", "Yasu", "Austin", "Dallas", "Darius", "Donny", "Jonathon", "Logan", "Michael", "Oliver", "Sebastian", "Tristan", "Wayne", "Norman", "Roland", "Regis", "Abe", "Astor", "Keita", "Kenneth", "Kevin", "Kyle", "Lester", "Masao", "Nicholas", "Parker", "Wes", "Zachary", "Cody", "Henley", "Jaye", "Karl", "Kenny", "Masahiro", "Pedro", "Petey", "Sinclair", "Terrell", "Waylon", "Aidan", "Anthony", "David", "Jacob", "Jayden", "Cutler", "Ham", "Caleb", "Kai", "Honus", "Kenway", "Bret", "Chris", "Cid", "Dennis", "Easton", "Ken", "Robby", "Ronny", "Shawn", "Benjamin", "Jake", "Travis", "Adan", "Aday", "Beltran", "Elian", "Hernan", "Julen", "Luka", "Roi", "Bernie", "Dustin", "Jonathan", "Wyatt" ], [ "Alice", "Bridget", "Carrie", "Connie", "Dana", "Ellen", "Krise", "Laura", "Linda", "Michelle", "Shannon", "Andrea", "Crissy", "Janice", "Robin", "Sally", "Tiana", "Haley", "Ali", "Ann", "Dalia", "Dawn", "Iris", "Joana", "Julia", "Kay", "Lisa", "Megan", "Mikaela", "Miriam", "Paige", "Reli", "Blythe", "Briana", "Caroline", "Cassidy", "Kaitlin", "Madeline", "Molly", "Natalie", "Samantha", "Sarah", "Cathy", "Dye", "Eri", "Eva", "Fey", "Kara", "Lurleen", "Maki", "Mali", "Maya", "Miki", "Sibyl", "Daya", "Diana", "Flo", "Helia", "Henrietta", "Isabel", "Mai", "Persephone", "Serena", "Anna", "Charlotte", "Elin", "Elsa", "Lise", "Sara", "Suzette", "Audrey", "Emmy", "Isabella", "Madison", "Rika", "Rylee", "Salla", "Ellie", "Alexandra", "Amy", "Lass", "Brittany", "Chel", "Cindy", "Dianne", "Emily", "Emma", "Evelyn", "Hana", "Harleen", "Hazel", "Jocelyn", "Katrina", "Kimberly", "Lina", "Marge", "Mila", "Mizuki", "Rena", "Sal", "Satoko", "Summer", "Tomoe", "Vicky", "Yue", "Yumi", "Lauren", "Rei", "Riley", "Lois", "Nancy", "Tammy", "Terry" ]], + [TrainerType.HEX_MANIAC]: [ "Kindra", "Patricia", "Tammy", "Tasha", "Valerie", "Alaina", "Kathleen", "Leah", "Makie", "Sylvia", "Anina", "Arachna", "Carrie", "Desdemona", "Josette", "Luna", "Melanie", "Osanna", "Raziah" ], }; // function used in a commented code @@ -140,7 +140,7 @@ function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNam if (!trainerListHeader) { return []; } - const elements = [...(trainerListHeader?.parentElement?.childNodes ?? [])]; + const elements = [ ...(trainerListHeader?.parentElement?.childNodes ?? []) ]; const startChildIndex = elements.indexOf(trainerListHeader); const endChildIndex = elements.findIndex(h => h.nodeName === "H2" && elements.indexOf(h) > startChildIndex); const tables = elements.filter(t => { @@ -152,7 +152,7 @@ function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNam }).map(t => t as Element); console.log(url, tables); for (const table of tables) { - const trainerRows = [...table.querySelectorAll("tr:not(:first-child)")].filter(r => r.children.length === 9); + const trainerRows = [ ...table.querySelectorAll("tr:not(:first-child)") ].filter(r => r.children.length === 9); for (const row of trainerRows) { const nameCell = row.firstElementChild; if (!nameCell) { diff --git a/src/data/type.ts b/src/data/type.ts index 47bea8dd72b..483ec068d3c 100644 --- a/src/data/type.ts +++ b/src/data/type.ts @@ -29,260 +29,260 @@ export function getTypeDamageMultiplier(attackType: Type, defType: Type): TypeDa } switch (defType) { - case Type.NORMAL: - switch (attackType) { - case Type.FIGHTING: - return 2; - case Type.GHOST: - return 0; - default: - return 1; - } - case Type.FIGHTING: - switch (attackType) { - case Type.FLYING: - case Type.PSYCHIC: - case Type.FAIRY: - return 2; - case Type.ROCK: - case Type.BUG: - case Type.DARK: - return 0.5; - default: - return 1; - } - case Type.FLYING: - switch (attackType) { - case Type.ROCK: - case Type.ELECTRIC: - case Type.ICE: - return 2; - case Type.FIGHTING: - case Type.BUG: - case Type.GRASS: - return 0.5; - case Type.GROUND: - return 0; - default: - return 1; - } - case Type.POISON: - switch (attackType) { - case Type.GROUND: - case Type.PSYCHIC: - return 2; - case Type.FIGHTING: - case Type.POISON: - case Type.BUG: - case Type.GRASS: - case Type.FAIRY: - return 0.5; - default: - return 1; - } - case Type.GROUND: - switch (attackType) { - case Type.WATER: - case Type.GRASS: - case Type.ICE: - return 2; - case Type.POISON: - case Type.ROCK: - return 0.5; - case Type.ELECTRIC: - return 0; - default: - return 1; - } - case Type.ROCK: - switch (attackType) { - case Type.FIGHTING: - case Type.GROUND: - case Type.STEEL: - case Type.WATER: - case Type.GRASS: - return 2; case Type.NORMAL: - case Type.FLYING: - case Type.POISON: - case Type.FIRE: - return 0.5; - default: - return 1; - } - case Type.BUG: - switch (attackType) { - case Type.FLYING: - case Type.ROCK: - case Type.FIRE: - return 2; + switch (attackType) { + case Type.FIGHTING: + return 2; + case Type.GHOST: + return 0; + default: + return 1; + } case Type.FIGHTING: + switch (attackType) { + case Type.FLYING: + case Type.PSYCHIC: + case Type.FAIRY: + return 2; + case Type.ROCK: + case Type.BUG: + case Type.DARK: + return 0.5; + default: + return 1; + } + case Type.FLYING: + switch (attackType) { + case Type.ROCK: + case Type.ELECTRIC: + case Type.ICE: + return 2; + case Type.FIGHTING: + case Type.BUG: + case Type.GRASS: + return 0.5; + case Type.GROUND: + return 0; + default: + return 1; + } + case Type.POISON: + switch (attackType) { + case Type.GROUND: + case Type.PSYCHIC: + return 2; + case Type.FIGHTING: + case Type.POISON: + case Type.BUG: + case Type.GRASS: + case Type.FAIRY: + return 0.5; + default: + return 1; + } case Type.GROUND: - case Type.GRASS: - return 0.5; - default: - return 1; - } - case Type.GHOST: - switch (attackType) { + switch (attackType) { + case Type.WATER: + case Type.GRASS: + case Type.ICE: + return 2; + case Type.POISON: + case Type.ROCK: + return 0.5; + case Type.ELECTRIC: + return 0; + default: + return 1; + } + case Type.ROCK: + switch (attackType) { + case Type.FIGHTING: + case Type.GROUND: + case Type.STEEL: + case Type.WATER: + case Type.GRASS: + return 2; + case Type.NORMAL: + case Type.FLYING: + case Type.POISON: + case Type.FIRE: + return 0.5; + default: + return 1; + } + case Type.BUG: + switch (attackType) { + case Type.FLYING: + case Type.ROCK: + case Type.FIRE: + return 2; + case Type.FIGHTING: + case Type.GROUND: + case Type.GRASS: + return 0.5; + default: + return 1; + } case Type.GHOST: - case Type.DARK: - return 2; - case Type.POISON: - case Type.BUG: - return 0.5; - case Type.NORMAL: - case Type.FIGHTING: - return 0; - default: - return 1; - } - case Type.STEEL: - switch (attackType) { - case Type.FIGHTING: - case Type.GROUND: - case Type.FIRE: - return 2; - case Type.NORMAL: - case Type.FLYING: - case Type.ROCK: - case Type.BUG: + switch (attackType) { + case Type.GHOST: + case Type.DARK: + return 2; + case Type.POISON: + case Type.BUG: + return 0.5; + case Type.NORMAL: + case Type.FIGHTING: + return 0; + default: + return 1; + } case Type.STEEL: + switch (attackType) { + case Type.FIGHTING: + case Type.GROUND: + case Type.FIRE: + return 2; + case Type.NORMAL: + case Type.FLYING: + case Type.ROCK: + case Type.BUG: + case Type.STEEL: + case Type.GRASS: + case Type.PSYCHIC: + case Type.ICE: + case Type.DRAGON: + case Type.FAIRY: + return 0.5; + case Type.POISON: + return 0; + default: + return 1; + } + case Type.FIRE: + switch (attackType) { + case Type.GROUND: + case Type.ROCK: + case Type.WATER: + return 2; + case Type.BUG: + case Type.STEEL: + case Type.FIRE: + case Type.GRASS: + case Type.ICE: + case Type.FAIRY: + return 0.5; + default: + return 1; + } + case Type.WATER: + switch (attackType) { + case Type.GRASS: + case Type.ELECTRIC: + return 2; + case Type.STEEL: + case Type.FIRE: + case Type.WATER: + case Type.ICE: + return 0.5; + default: + return 1; + } case Type.GRASS: + switch (attackType) { + case Type.FLYING: + case Type.POISON: + case Type.BUG: + case Type.FIRE: + case Type.ICE: + return 2; + case Type.GROUND: + case Type.WATER: + case Type.GRASS: + case Type.ELECTRIC: + return 0.5; + default: + return 1; + } + case Type.ELECTRIC: + switch (attackType) { + case Type.GROUND: + return 2; + case Type.FLYING: + case Type.STEEL: + case Type.ELECTRIC: + return 0.5; + default: + return 1; + } case Type.PSYCHIC: + switch (attackType) { + case Type.BUG: + case Type.GHOST: + case Type.DARK: + return 2; + case Type.FIGHTING: + case Type.PSYCHIC: + return 0.5; + default: + return 1; + } case Type.ICE: + switch (attackType) { + case Type.FIGHTING: + case Type.ROCK: + case Type.STEEL: + case Type.FIRE: + return 2; + case Type.ICE: + return 0.5; + default: + return 1; + } case Type.DRAGON: - case Type.FAIRY: - return 0.5; - case Type.POISON: - return 0; - default: - return 1; - } - case Type.FIRE: - switch (attackType) { - case Type.GROUND: - case Type.ROCK: - case Type.WATER: - return 2; - case Type.BUG: - case Type.STEEL: - case Type.FIRE: - case Type.GRASS: - case Type.ICE: - case Type.FAIRY: - return 0.5; - default: - return 1; - } - case Type.WATER: - switch (attackType) { - case Type.GRASS: - case Type.ELECTRIC: - return 2; - case Type.STEEL: - case Type.FIRE: - case Type.WATER: - case Type.ICE: - return 0.5; - default: - return 1; - } - case Type.GRASS: - switch (attackType) { - case Type.FLYING: - case Type.POISON: - case Type.BUG: - case Type.FIRE: - case Type.ICE: - return 2; - case Type.GROUND: - case Type.WATER: - case Type.GRASS: - case Type.ELECTRIC: - return 0.5; - default: - return 1; - } - case Type.ELECTRIC: - switch (attackType) { - case Type.GROUND: - return 2; - case Type.FLYING: - case Type.STEEL: - case Type.ELECTRIC: - return 0.5; - default: - return 1; - } - case Type.PSYCHIC: - switch (attackType) { - case Type.BUG: - case Type.GHOST: + switch (attackType) { + case Type.ICE: + case Type.DRAGON: + case Type.FAIRY: + return 2; + case Type.FIRE: + case Type.WATER: + case Type.GRASS: + case Type.ELECTRIC: + return 0.5; + default: + return 1; + } case Type.DARK: - return 2; - case Type.FIGHTING: - case Type.PSYCHIC: - return 0.5; - default: - return 1; - } - case Type.ICE: - switch (attackType) { - case Type.FIGHTING: - case Type.ROCK: - case Type.STEEL: - case Type.FIRE: - return 2; - case Type.ICE: - return 0.5; - default: - return 1; - } - case Type.DRAGON: - switch (attackType) { - case Type.ICE: - case Type.DRAGON: + switch (attackType) { + case Type.FIGHTING: + case Type.BUG: + case Type.FAIRY: + return 2; + case Type.GHOST: + case Type.DARK: + return 0.5; + case Type.PSYCHIC: + return 0; + default: + return 1; + } case Type.FAIRY: - return 2; - case Type.FIRE: - case Type.WATER: - case Type.GRASS: - case Type.ELECTRIC: - return 0.5; - default: + switch (attackType) { + case Type.POISON: + case Type.STEEL: + return 2; + case Type.FIGHTING: + case Type.BUG: + case Type.DARK: + return 0.5; + case Type.DRAGON: + return 0; + default: + return 1; + } + case Type.STELLAR: return 1; - } - case Type.DARK: - switch (attackType) { - case Type.FIGHTING: - case Type.BUG: - case Type.FAIRY: - return 2; - case Type.GHOST: - case Type.DARK: - return 0.5; - case Type.PSYCHIC: - return 0; - default: - return 1; - } - case Type.FAIRY: - switch (attackType) { - case Type.POISON: - case Type.STEEL: - return 2; - case Type.FIGHTING: - case Type.BUG: - case Type.DARK: - return 0.5; - case Type.DRAGON: - return 0; - default: - return 1; - } - case Type.STELLAR: - return 1; } return 1; @@ -295,86 +295,86 @@ export function getTypeDamageMultiplier(attackType: Type, defType: Type): TypeDa export function getTypeDamageMultiplierColor(multiplier: TypeDamageMultiplier, side: "defense" | "offense"): string | undefined { if (side === "offense") { switch (multiplier) { - case 0: - return "#929292"; - case 0.125: - return "#FF5500"; - case 0.25: - return "#FF7400"; - case 0.5: - return "#FE8E00"; - case 1: - return undefined; - case 2: - return "#4AA500"; - case 4: - return "#4BB400"; - case 8: - return "#52C200"; + case 0: + return "#929292"; + case 0.125: + return "#FF5500"; + case 0.25: + return "#FF7400"; + case 0.5: + return "#FE8E00"; + case 1: + return undefined; + case 2: + return "#4AA500"; + case 4: + return "#4BB400"; + case 8: + return "#52C200"; } } else if (side === "defense") { switch (multiplier) { - case 0: - return "#B1B100"; - case 0.125: - return "#2DB4FF"; - case 0.25: - return "#00A4FF"; - case 0.5: - return "#0093FF"; - case 1: - return undefined; - case 2: - return "#FE8E00"; - case 4: - return "#FF7400"; - case 8: - return "#FF5500"; + case 0: + return "#B1B100"; + case 0.125: + return "#2DB4FF"; + case 0.25: + return "#00A4FF"; + case 0.5: + return "#0093FF"; + case 1: + return undefined; + case 2: + return "#FE8E00"; + case 4: + return "#FF7400"; + case 8: + return "#FF5500"; } } } export function getTypeRgb(type: Type): [ integer, integer, integer ] { switch (type) { - case Type.NORMAL: - return [ 168, 168, 120 ]; - case Type.FIGHTING: - return [ 192, 48, 40 ]; - case Type.FLYING: - return [ 168, 144, 240 ]; - case Type.POISON: - return [ 160, 64, 160 ]; - case Type.GROUND: - return [ 224, 192, 104 ]; - case Type.ROCK: - return [ 184, 160, 56 ]; - case Type.BUG: - return [ 168, 184, 32 ]; - case Type.GHOST: - return [ 112, 88, 152 ]; - case Type.STEEL: - return [ 184, 184, 208 ]; - case Type.FIRE: - return [ 240, 128, 48 ]; - case Type.WATER: - return [ 104, 144, 240 ]; - case Type.GRASS: - return [ 120, 200, 80 ]; - case Type.ELECTRIC: - return [ 248, 208, 48 ]; - case Type.PSYCHIC: - return [ 248, 88, 136 ]; - case Type.ICE: - return [ 152, 216, 216 ]; - case Type.DRAGON: - return [ 112, 56, 248 ]; - case Type.DARK: - return [ 112, 88, 72 ]; - case Type.FAIRY: - return [ 232, 136, 200 ]; - case Type.STELLAR: - return [ 255, 255, 255 ]; - default: - return [ 0, 0, 0 ]; + case Type.NORMAL: + return [ 168, 168, 120 ]; + case Type.FIGHTING: + return [ 192, 48, 40 ]; + case Type.FLYING: + return [ 168, 144, 240 ]; + case Type.POISON: + return [ 160, 64, 160 ]; + case Type.GROUND: + return [ 224, 192, 104 ]; + case Type.ROCK: + return [ 184, 160, 56 ]; + case Type.BUG: + return [ 168, 184, 32 ]; + case Type.GHOST: + return [ 112, 88, 152 ]; + case Type.STEEL: + return [ 184, 184, 208 ]; + case Type.FIRE: + return [ 240, 128, 48 ]; + case Type.WATER: + return [ 104, 144, 240 ]; + case Type.GRASS: + return [ 120, 200, 80 ]; + case Type.ELECTRIC: + return [ 248, 208, 48 ]; + case Type.PSYCHIC: + return [ 248, 88, 136 ]; + case Type.ICE: + return [ 152, 216, 216 ]; + case Type.DRAGON: + return [ 112, 56, 248 ]; + case Type.DARK: + return [ 112, 88, 72 ]; + case Type.FAIRY: + return [ 232, 136, 200 ]; + case Type.STELLAR: + return [ 255, 255, 255 ]; + default: + return [ 0, 0, 0 ]; } } diff --git a/src/data/variant.ts b/src/data/variant.ts index b7a01a4be89..13869635f1e 100644 --- a/src/data/variant.ts +++ b/src/data/variant.ts @@ -10,22 +10,22 @@ export const variantColorCache = {}; export function getVariantTint(variant: Variant): integer { switch (variant) { - case 0: - return 0xf8c020; - case 1: - return 0x20f8f0; - case 2: - return 0xe81048; + case 0: + return 0xf8c020; + case 1: + return 0x20f8f0; + case 2: + return 0xe81048; } } export function getVariantIcon(variant: Variant): integer { switch (variant) { - case 0: - return VariantTier.STANDARD; - case 1: - return VariantTier.RARE; - case 2: - return VariantTier.EPIC; + case 0: + return VariantTier.STANDARD; + case 1: + return VariantTier.RARE; + case 2: + return VariantTier.EPIC; } } diff --git a/src/data/weather.ts b/src/data/weather.ts index afdd0a958cf..20c03af77c8 100644 --- a/src/data/weather.ts +++ b/src/data/weather.ts @@ -33,10 +33,10 @@ export class Weather { isImmutable(): boolean { switch (this.weatherType) { - case WeatherType.HEAVY_RAIN: - case WeatherType.HARSH_SUN: - case WeatherType.STRONG_WINDS: - return true; + case WeatherType.HEAVY_RAIN: + case WeatherType.HARSH_SUN: + case WeatherType.STRONG_WINDS: + return true; } return false; @@ -44,9 +44,9 @@ export class Weather { isDamaging(): boolean { switch (this.weatherType) { - case WeatherType.SANDSTORM: - case WeatherType.HAIL: - return true; + case WeatherType.SANDSTORM: + case WeatherType.HAIL: + return true; } return false; @@ -54,10 +54,10 @@ export class Weather { isTypeDamageImmune(type: Type): boolean { switch (this.weatherType) { - case WeatherType.SANDSTORM: - return type === Type.GROUND || type === Type.ROCK || type === Type.STEEL; - case WeatherType.HAIL: - return type === Type.ICE; + case WeatherType.SANDSTORM: + return type === Type.GROUND || type === Type.ROCK || type === Type.STEEL; + case WeatherType.HAIL: + return type === Type.ICE; } return false; @@ -65,24 +65,24 @@ export class Weather { getAttackTypeMultiplier(attackType: Type): number { switch (this.weatherType) { - case WeatherType.SUNNY: - case WeatherType.HARSH_SUN: - if (attackType === Type.FIRE) { - return 1.5; - } - if (attackType === Type.WATER) { - return 0.5; - } - break; - case WeatherType.RAIN: - case WeatherType.HEAVY_RAIN: - if (attackType === Type.FIRE) { - return 0.5; - } - if (attackType === Type.WATER) { - return 1.5; - } - break; + case WeatherType.SUNNY: + case WeatherType.HARSH_SUN: + if (attackType === Type.FIRE) { + return 1.5; + } + if (attackType === Type.WATER) { + return 0.5; + } + break; + case WeatherType.RAIN: + case WeatherType.HEAVY_RAIN: + if (attackType === Type.FIRE) { + return 0.5; + } + if (attackType === Type.WATER) { + return 1.5; + } + break; } return 1; @@ -92,10 +92,10 @@ export class Weather { const moveType = user.getMoveType(move); switch (this.weatherType) { - case WeatherType.HARSH_SUN: - return move instanceof AttackMove && moveType === Type.WATER; - case WeatherType.HEAVY_RAIN: - return move instanceof AttackMove && moveType === Type.FIRE; + case WeatherType.HARSH_SUN: + return move instanceof AttackMove && moveType === Type.WATER; + case WeatherType.HEAVY_RAIN: + return move instanceof AttackMove && moveType === Type.FIRE; } return false; @@ -120,24 +120,24 @@ export class Weather { export function getWeatherStartMessage(weatherType: WeatherType): string | null { switch (weatherType) { - case WeatherType.SUNNY: - return i18next.t("weather:sunnyStartMessage"); - case WeatherType.RAIN: - return i18next.t("weather:rainStartMessage"); - case WeatherType.SANDSTORM: - return i18next.t("weather:sandstormStartMessage"); - case WeatherType.HAIL: - return i18next.t("weather:hailStartMessage"); - case WeatherType.SNOW: - return i18next.t("weather:snowStartMessage"); - case WeatherType.FOG: - return i18next.t("weather:fogStartMessage"); - case WeatherType.HEAVY_RAIN: - return i18next.t("weather:heavyRainStartMessage"); - case WeatherType.HARSH_SUN: - return i18next.t("weather:harshSunStartMessage"); - case WeatherType.STRONG_WINDS: - return i18next.t("weather:strongWindsStartMessage"); + case WeatherType.SUNNY: + return i18next.t("weather:sunnyStartMessage"); + case WeatherType.RAIN: + return i18next.t("weather:rainStartMessage"); + case WeatherType.SANDSTORM: + return i18next.t("weather:sandstormStartMessage"); + case WeatherType.HAIL: + return i18next.t("weather:hailStartMessage"); + case WeatherType.SNOW: + return i18next.t("weather:snowStartMessage"); + case WeatherType.FOG: + return i18next.t("weather:fogStartMessage"); + case WeatherType.HEAVY_RAIN: + return i18next.t("weather:heavyRainStartMessage"); + case WeatherType.HARSH_SUN: + return i18next.t("weather:harshSunStartMessage"); + case WeatherType.STRONG_WINDS: + return i18next.t("weather:strongWindsStartMessage"); } return null; @@ -145,24 +145,24 @@ export function getWeatherStartMessage(weatherType: WeatherType): string | null export function getWeatherLapseMessage(weatherType: WeatherType): string | null { switch (weatherType) { - case WeatherType.SUNNY: - return i18next.t("weather:sunnyLapseMessage"); - case WeatherType.RAIN: - return i18next.t("weather:rainLapseMessage"); - case WeatherType.SANDSTORM: - return i18next.t("weather:sandstormLapseMessage"); - case WeatherType.HAIL: - return i18next.t("weather:hailLapseMessage"); - case WeatherType.SNOW: - return i18next.t("weather:snowLapseMessage"); - case WeatherType.FOG: - return i18next.t("weather:fogLapseMessage"); - case WeatherType.HEAVY_RAIN: - return i18next.t("weather:heavyRainLapseMessage"); - case WeatherType.HARSH_SUN: - return i18next.t("weather:harshSunLapseMessage"); - case WeatherType.STRONG_WINDS: - return i18next.t("weather:strongWindsLapseMessage"); + case WeatherType.SUNNY: + return i18next.t("weather:sunnyLapseMessage"); + case WeatherType.RAIN: + return i18next.t("weather:rainLapseMessage"); + case WeatherType.SANDSTORM: + return i18next.t("weather:sandstormLapseMessage"); + case WeatherType.HAIL: + return i18next.t("weather:hailLapseMessage"); + case WeatherType.SNOW: + return i18next.t("weather:snowLapseMessage"); + case WeatherType.FOG: + return i18next.t("weather:fogLapseMessage"); + case WeatherType.HEAVY_RAIN: + return i18next.t("weather:heavyRainLapseMessage"); + case WeatherType.HARSH_SUN: + return i18next.t("weather:harshSunLapseMessage"); + case WeatherType.STRONG_WINDS: + return i18next.t("weather:strongWindsLapseMessage"); } return null; @@ -170,10 +170,10 @@ export function getWeatherLapseMessage(weatherType: WeatherType): string | null export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string | null { switch (weatherType) { - case WeatherType.SANDSTORM: - return i18next.t("weather:sandstormDamageMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)}); - case WeatherType.HAIL: - return i18next.t("weather:hailDamageMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)}); + case WeatherType.SANDSTORM: + return i18next.t("weather:sandstormDamageMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); + case WeatherType.HAIL: + return i18next.t("weather:hailDamageMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } return null; @@ -181,24 +181,24 @@ export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokem export function getWeatherClearMessage(weatherType: WeatherType): string | null { switch (weatherType) { - case WeatherType.SUNNY: - return i18next.t("weather:sunnyClearMessage"); - case WeatherType.RAIN: - return i18next.t("weather:rainClearMessage"); - case WeatherType.SANDSTORM: - return i18next.t("weather:sandstormClearMessage"); - case WeatherType.HAIL: - return i18next.t("weather:hailClearMessage"); - case WeatherType.SNOW: - return i18next.t("weather:snowClearMessage"); - case WeatherType.FOG: - return i18next.t("weather:fogClearMessage"); - case WeatherType.HEAVY_RAIN: - return i18next.t("weather:heavyRainClearMessage"); - case WeatherType.HARSH_SUN: - return i18next.t("weather:harshSunClearMessage"); - case WeatherType.STRONG_WINDS: - return i18next.t("weather:strongWindsClearMessage"); + case WeatherType.SUNNY: + return i18next.t("weather:sunnyClearMessage"); + case WeatherType.RAIN: + return i18next.t("weather:rainClearMessage"); + case WeatherType.SANDSTORM: + return i18next.t("weather:sandstormClearMessage"); + case WeatherType.HAIL: + return i18next.t("weather:hailClearMessage"); + case WeatherType.SNOW: + return i18next.t("weather:snowClearMessage"); + case WeatherType.FOG: + return i18next.t("weather:fogClearMessage"); + case WeatherType.HEAVY_RAIN: + return i18next.t("weather:heavyRainClearMessage"); + case WeatherType.HARSH_SUN: + return i18next.t("weather:harshSunClearMessage"); + case WeatherType.STRONG_WINDS: + return i18next.t("weather:strongWindsClearMessage"); } return null; @@ -206,41 +206,41 @@ export function getWeatherClearMessage(weatherType: WeatherType): string | null export function getTerrainStartMessage(terrainType: TerrainType): string | null { switch (terrainType) { - case TerrainType.MISTY: - return i18next.t("terrain:mistyStartMessage"); - case TerrainType.ELECTRIC: - return i18next.t("terrain:electricStartMessage"); - case TerrainType.GRASSY: - return i18next.t("terrain:grassyStartMessage"); - case TerrainType.PSYCHIC: - return i18next.t("terrain:psychicStartMessage"); - default: - console.warn("getTerrainStartMessage not defined. Using default null"); - return null; + case TerrainType.MISTY: + return i18next.t("terrain:mistyStartMessage"); + case TerrainType.ELECTRIC: + return i18next.t("terrain:electricStartMessage"); + case TerrainType.GRASSY: + return i18next.t("terrain:grassyStartMessage"); + case TerrainType.PSYCHIC: + return i18next.t("terrain:psychicStartMessage"); + default: + console.warn("getTerrainStartMessage not defined. Using default null"); + return null; } } export function getTerrainClearMessage(terrainType: TerrainType): string | null { switch (terrainType) { - case TerrainType.MISTY: - return i18next.t("terrain:mistyClearMessage"); - case TerrainType.ELECTRIC: - return i18next.t("terrain:electricClearMessage"); - case TerrainType.GRASSY: - return i18next.t("terrain:grassyClearMessage"); - case TerrainType.PSYCHIC: - return i18next.t("terrain:psychicClearMessage"); - default: - console.warn("getTerrainClearMessage not defined. Using default null"); - return null; + case TerrainType.MISTY: + return i18next.t("terrain:mistyClearMessage"); + case TerrainType.ELECTRIC: + return i18next.t("terrain:electricClearMessage"); + case TerrainType.GRASSY: + return i18next.t("terrain:grassyClearMessage"); + case TerrainType.PSYCHIC: + return i18next.t("terrain:psychicClearMessage"); + default: + console.warn("getTerrainClearMessage not defined. Using default null"); + return null; } } export function getTerrainBlockMessage(pokemon: Pokemon, terrainType: TerrainType): string { if (terrainType === TerrainType.MISTY) { - return i18next.t("terrain:mistyBlockMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)}); + return i18next.t("terrain:mistyBlockMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } - return i18next.t("terrain:defaultBlockMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), terrainName: getTerrainName(terrainType)}); + return i18next.t("terrain:defaultBlockMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), terrainName: getTerrainName(terrainType) }); } interface WeatherPoolEntry { @@ -252,126 +252,126 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a let weatherPool: WeatherPoolEntry[] = []; const hasSun = arena.getTimeOfDay() < 2; switch (arena.biomeType) { - case Biome.GRASS: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 7 } - ]; - if (hasSun) { - weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 3 }); - } - break; - case Biome.TALL_GRASS: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 8 }, - { weatherType: WeatherType.RAIN, weight: 5 }, - ]; - if (hasSun) { - weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 8 }); - } - break; - case Biome.FOREST: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 8 }, - { weatherType: WeatherType.RAIN, weight: 5 } - ]; - break; - case Biome.SEA: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 3 }, - { weatherType: WeatherType.RAIN, weight: 12 } - ]; - break; - case Biome.SWAMP: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 3 }, - { weatherType: WeatherType.RAIN, weight: 4 }, - { weatherType: WeatherType.FOG, weight: 1 } - ]; - break; - case Biome.BEACH: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 8 }, - { weatherType: WeatherType.RAIN, weight: 3 } - ]; - if (hasSun) { - weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 }); - } - break; - case Biome.LAKE: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 10 }, - { weatherType: WeatherType.RAIN, weight: 5 }, - { weatherType: WeatherType.FOG, weight: 1 } - ]; - break; - case Biome.SEABED: - weatherPool = [ - { weatherType: WeatherType.RAIN, weight: 1 } - ]; - break; - case Biome.BADLANDS: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 8 }, - { weatherType: WeatherType.SANDSTORM, weight: 2 } - ]; - if (hasSun) { - weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 }); - } - break; - case Biome.DESERT: - weatherPool = [ - { weatherType: WeatherType.SANDSTORM, weight: 2 } - ]; - if (hasSun) { - weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); - } - break; - case Biome.ICE_CAVE: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 3 }, - { weatherType: WeatherType.SNOW, weight: 4 }, - { weatherType: WeatherType.HAIL, weight: 1 } - ]; - break; - case Biome.MEADOW: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 2 } - ]; - if (hasSun) { - weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); - } - case Biome.VOLCANO: - weatherPool = [ - { weatherType: hasSun ? WeatherType.SUNNY : WeatherType.NONE, weight: 1 } - ]; - break; - case Biome.GRAVEYARD: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 3 }, - { weatherType: WeatherType.FOG, weight: 1 } - ]; - break; - case Biome.JUNGLE: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 8 }, - { weatherType: WeatherType.RAIN, weight: 2 } - ]; - break; - case Biome.SNOWY_FOREST: - weatherPool = [ - { weatherType: WeatherType.SNOW, weight: 7 }, - { weatherType: WeatherType.HAIL, weight: 1 } - ]; - break; - case Biome.ISLAND: - weatherPool = [ - { weatherType: WeatherType.NONE, weight: 5 }, - { weatherType: WeatherType.RAIN, weight: 1 }, - ]; - if (hasSun) { - weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); - } - break; + case Biome.GRASS: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 7 } + ]; + if (hasSun) { + weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 3 }); + } + break; + case Biome.TALL_GRASS: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 8 }, + { weatherType: WeatherType.RAIN, weight: 5 }, + ]; + if (hasSun) { + weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 8 }); + } + break; + case Biome.FOREST: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 8 }, + { weatherType: WeatherType.RAIN, weight: 5 } + ]; + break; + case Biome.SEA: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 3 }, + { weatherType: WeatherType.RAIN, weight: 12 } + ]; + break; + case Biome.SWAMP: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 3 }, + { weatherType: WeatherType.RAIN, weight: 4 }, + { weatherType: WeatherType.FOG, weight: 1 } + ]; + break; + case Biome.BEACH: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 8 }, + { weatherType: WeatherType.RAIN, weight: 3 } + ]; + if (hasSun) { + weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 }); + } + break; + case Biome.LAKE: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 10 }, + { weatherType: WeatherType.RAIN, weight: 5 }, + { weatherType: WeatherType.FOG, weight: 1 } + ]; + break; + case Biome.SEABED: + weatherPool = [ + { weatherType: WeatherType.RAIN, weight: 1 } + ]; + break; + case Biome.BADLANDS: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 8 }, + { weatherType: WeatherType.SANDSTORM, weight: 2 } + ]; + if (hasSun) { + weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 }); + } + break; + case Biome.DESERT: + weatherPool = [ + { weatherType: WeatherType.SANDSTORM, weight: 2 } + ]; + if (hasSun) { + weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); + } + break; + case Biome.ICE_CAVE: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 3 }, + { weatherType: WeatherType.SNOW, weight: 4 }, + { weatherType: WeatherType.HAIL, weight: 1 } + ]; + break; + case Biome.MEADOW: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 2 } + ]; + if (hasSun) { + weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); + } + case Biome.VOLCANO: + weatherPool = [ + { weatherType: hasSun ? WeatherType.SUNNY : WeatherType.NONE, weight: 1 } + ]; + break; + case Biome.GRAVEYARD: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 3 }, + { weatherType: WeatherType.FOG, weight: 1 } + ]; + break; + case Biome.JUNGLE: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 8 }, + { weatherType: WeatherType.RAIN, weight: 2 } + ]; + break; + case Biome.SNOWY_FOREST: + weatherPool = [ + { weatherType: WeatherType.SNOW, weight: 7 }, + { weatherType: WeatherType.HAIL, weight: 1 } + ]; + break; + case Biome.ISLAND: + weatherPool = [ + { weatherType: WeatherType.NONE, weight: 5 }, + { weatherType: WeatherType.RAIN, weight: 1 }, + ]; + if (hasSun) { + weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); + } + break; } if (weatherPool.length > 1) { diff --git a/src/enums/arena-tag-type.ts b/src/enums/arena-tag-type.ts index 123d70b64fa..c73f4ec2ae5 100644 --- a/src/enums/arena-tag-type.ts +++ b/src/enums/arena-tag-type.ts @@ -1,4 +1,3 @@ - export enum ArenaTagType { NONE = "NONE", MUD_SPORT = "MUD_SPORT", @@ -25,5 +24,8 @@ export enum ArenaTagType { SAFEGUARD = "SAFEGUARD", NO_CRIT = "NO_CRIT", IMPRISON = "IMPRISON", - PLASMA_FISTS = "PLASMA_FISTS", + ION_DELUGE = "ION_DELUGE", + FIRE_GRASS_PLEDGE = "FIRE_GRASS_PLEDGE", + WATER_FIRE_PLEDGE = "WATER_FIRE_PLEDGE", + GRASS_WATER_PLEDGE = "GRASS_WATER_PLEDGE", } diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 209d36316f9..680dedb93cc 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -1,4 +1,3 @@ - export enum BattlerTagType { NONE = "NONE", RECHARGING = "RECHARGING", @@ -55,7 +54,7 @@ export enum BattlerTagType { CURSED = "CURSED", CHARGED = "CHARGED", ROOSTED = "ROOSTED", - MAGNET_RISEN = "MAGNET_RISEN", + FLOATING = "FLOATING", MINIMIZED = "MINIMIZED", DESTINY_BOND = "DESTINY_BOND", CENTER_OF_ATTENTION = "CENTER_OF_ATTENTION", @@ -81,9 +80,12 @@ export enum BattlerTagType { DOUBLE_SHOCKED = "DOUBLE_SHOCKED", AUTOTOMIZED = "AUTOTOMIZED", MYSTERY_ENCOUNTER_POST_SUMMON = "MYSTERY_ENCOUNTER_POST_SUMMON", + POWER_TRICK = "POWER_TRICK", HEAL_BLOCK = "HEAL_BLOCK", TORMENT = "TORMENT", TAUNT = "TAUNT", IMPRISON = "IMPRISON", SYRUP_BOMB = "SYRUP_BOMB", + ELECTRIFIED = "ELECTRIFIED", + TELEKINESIS = "TELEKINESIS" } diff --git a/src/enums/berry-type.ts b/src/enums/berry-type.ts index 8b7aab16010..97c69148146 100644 --- a/src/enums/berry-type.ts +++ b/src/enums/berry-type.ts @@ -1,4 +1,3 @@ - export enum BerryType { SITRUS, LUM, diff --git a/src/enums/biome.ts b/src/enums/biome.ts index 7088b2e99ac..bb9eaf454cc 100644 --- a/src/enums/biome.ts +++ b/src/enums/biome.ts @@ -1,4 +1,3 @@ - export enum Biome { TOWN, PLAINS, diff --git a/src/enums/egg-type.ts b/src/enums/egg-type.ts index d8d0facb020..901e60b3c76 100644 --- a/src/enums/egg-type.ts +++ b/src/enums/egg-type.ts @@ -1,6 +1,6 @@ export enum EggTier { COMMON, - GREAT, - ULTRA, - MASTER + RARE, + EPIC, + LEGENDARY } diff --git a/src/enums/stat.ts b/src/enums/stat.ts index a12d53e8559..6b3f7dc6d79 100644 --- a/src/enums/stat.ts +++ b/src/enums/stat.ts @@ -50,7 +50,7 @@ export function getStatStageChangeDescriptionKey(stages: number, isIncrease: boo return isIncrease ? "battle:statRose" : "battle:statFell"; } else if (stages === 2) { return isIncrease ? "battle:statSharplyRose" : "battle:statHarshlyFell"; - } else if (stages <= 6) { + } else if (stages > 2 && stages <= 6) { return isIncrease ? "battle:statRoseDrastically" : "battle:statSeverelyFell"; } return isIncrease ? "battle:statWontGoAnyHigher" : "battle:statWontGoAnyLower"; diff --git a/src/enums/switch-type.ts b/src/enums/switch-type.ts index b25ba6ad119..752c0902636 100644 --- a/src/enums/switch-type.ts +++ b/src/enums/switch-type.ts @@ -3,6 +3,8 @@ * or {@linkcode SwitchSummonPhase} will carry out. */ export enum SwitchType { + /** Switchout specifically for when combat starts and the player is prompted if they will switch Pokemon */ + INITIAL_SWITCH, /** Basic switchout where the Pokemon to switch in is selected */ SWITCH, /** Transfers stat stages and other effects from the returning Pokemon to the switched in Pokemon */ diff --git a/src/enums/time-of-day.ts b/src/enums/time-of-day.ts index 9363aa4c73a..3fd05308cc6 100644 --- a/src/enums/time-of-day.ts +++ b/src/enums/time-of-day.ts @@ -1,4 +1,3 @@ - export enum TimeOfDay { ALL = -1, DAWN, diff --git a/src/enums/trainer-type.ts b/src/enums/trainer-type.ts index 7de4a6af36a..b13543ace54 100644 --- a/src/enums/trainer-type.ts +++ b/src/enums/trainer-type.ts @@ -116,6 +116,8 @@ export enum TrainerType { VITO, BUG_TYPE_SUPERFAN, EXPERT_POKEMON_BREEDER, + FUTURE_SELF_M, + FUTURE_SELF_F, BROCK = 200, MISTY, diff --git a/src/field/anims.ts b/src/field/anims.ts index 52a15aa4f20..c73c52027c5 100644 --- a/src/field/anims.ts +++ b/src/field/anims.ts @@ -4,21 +4,21 @@ import * as Utils from "../utils"; export function addPokeballOpenParticles(scene: BattleScene, x: number, y: number, pokeballType: PokeballType): void { switch (pokeballType) { - case PokeballType.POKEBALL: - doDefaultPbOpenParticles(scene, x, y, 48); - break; - case PokeballType.GREAT_BALL: - doDefaultPbOpenParticles(scene, x, y, 96); - break; - case PokeballType.ULTRA_BALL: - doUbOpenParticles(scene, x, y, 8); - break; - case PokeballType.ROGUE_BALL: - doUbOpenParticles(scene, x, y, 10); - break; - case PokeballType.MASTER_BALL: - doMbOpenParticles(scene, x, y); - break; + case PokeballType.POKEBALL: + doDefaultPbOpenParticles(scene, x, y, 48); + break; + case PokeballType.GREAT_BALL: + doDefaultPbOpenParticles(scene, x, y, 96); + break; + case PokeballType.ULTRA_BALL: + doUbOpenParticles(scene, x, y, 8); + break; + case PokeballType.ROGUE_BALL: + doUbOpenParticles(scene, x, y, 10); + break; + case PokeballType.MASTER_BALL: + doMbOpenParticles(scene, x, y); + break; } } diff --git a/src/field/arena.ts b/src/field/arena.ts index 9d5f1eb0a4e..09faee49d56 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -10,7 +10,14 @@ import Move from "#app/data/move"; import { ArenaTag, ArenaTagSide, ArenaTrapTag, getArenaTag } from "#app/data/arena-tag"; import { BattlerIndex } from "#app/battle"; import { Terrain, TerrainType } from "#app/data/terrain"; -import { applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs, PostTerrainChangeAbAttr, PostWeatherChangeAbAttr } from "#app/data/ability"; +import { + applyAbAttrs, + applyPostTerrainChangeAbAttrs, + applyPostWeatherChangeAbAttrs, + PostTerrainChangeAbAttr, + PostWeatherChangeAbAttr, + TerrainEventTypeChangeAbAttr +} from "#app/data/ability"; import Pokemon from "#app/field/pokemon"; import Overrides from "#app/overrides"; import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; @@ -129,18 +136,18 @@ export class Arena { if (ret.subLegendary || ret.legendary || ret.mythical) { switch (true) { - case (ret.baseTotal >= 720): - regen = level < 90; - break; - case (ret.baseTotal >= 670): - regen = level < 70; - break; - case (ret.baseTotal >= 580): - regen = level < 50; - break; - default: - regen = level < 30; - break; + case (ret.baseTotal >= 720): + regen = level < 90; + break; + case (ret.baseTotal >= 670): + regen = level < 70; + break; + case (ret.baseTotal >= 580): + regen = level < 50; + break; + default: + regen = level < 30; + break; } } } @@ -177,41 +184,41 @@ export class Arena { getSpeciesFormIndex(species: PokemonSpecies): integer { switch (species.speciesId) { - case Species.BURMY: - case Species.WORMADAM: - switch (this.biomeType) { - case Biome.BEACH: - return 1; - case Biome.SLUM: - return 2; - } - break; - case Species.ROTOM: - switch (this.biomeType) { - case Biome.VOLCANO: - return 1; - case Biome.SEA: - return 2; - case Biome.ICE_CAVE: - return 3; - case Biome.MOUNTAIN: - return 4; - case Biome.TALL_GRASS: - return 5; - } - break; - case Species.LYCANROC: - const timeOfDay = this.getTimeOfDay(); - switch (timeOfDay) { - case TimeOfDay.DAY: - case TimeOfDay.DAWN: - return 0; - case TimeOfDay.DUSK: - return 2; - case TimeOfDay.NIGHT: - return 1; - } - break; + case Species.BURMY: + case Species.WORMADAM: + switch (this.biomeType) { + case Biome.BEACH: + return 1; + case Biome.SLUM: + return 2; + } + break; + case Species.ROTOM: + switch (this.biomeType) { + case Biome.VOLCANO: + return 1; + case Biome.SEA: + return 2; + case Biome.ICE_CAVE: + return 3; + case Biome.MOUNTAIN: + return 4; + case Biome.TALL_GRASS: + return 5; + } + break; + case Species.LYCANROC: + const timeOfDay = this.getTimeOfDay(); + switch (timeOfDay) { + case TimeOfDay.DAY: + case TimeOfDay.DAWN: + return 0; + case TimeOfDay.DUSK: + return 2; + case TimeOfDay.NIGHT: + return 1; + } + break; } return 0; @@ -219,70 +226,70 @@ export class Arena { getTypeForBiome() { switch (this.biomeType) { - case Biome.TOWN: - case Biome.PLAINS: - case Biome.METROPOLIS: - return Type.NORMAL; - case Biome.GRASS: - case Biome.TALL_GRASS: - return Type.GRASS; - case Biome.FOREST: - case Biome.JUNGLE: - return Type.BUG; - case Biome.SLUM: - case Biome.SWAMP: - return Type.POISON; - case Biome.SEA: - case Biome.BEACH: - case Biome.LAKE: - case Biome.SEABED: - return Type.WATER; - case Biome.MOUNTAIN: - return Type.FLYING; - case Biome.BADLANDS: - return Type.GROUND; - case Biome.CAVE: - case Biome.DESERT: - return Type.ROCK; - case Biome.ICE_CAVE: - case Biome.SNOWY_FOREST: - return Type.ICE; - case Biome.MEADOW: - case Biome.FAIRY_CAVE: - case Biome.ISLAND: - return Type.FAIRY; - case Biome.POWER_PLANT: - return Type.ELECTRIC; - case Biome.VOLCANO: - return Type.FIRE; - case Biome.GRAVEYARD: - case Biome.TEMPLE: - return Type.GHOST; - case Biome.DOJO: - case Biome.CONSTRUCTION_SITE: - return Type.FIGHTING; - case Biome.FACTORY: - case Biome.LABORATORY: - return Type.STEEL; - case Biome.RUINS: - case Biome.SPACE: - return Type.PSYCHIC; - case Biome.WASTELAND: - case Biome.END: - return Type.DRAGON; - case Biome.ABYSS: - return Type.DARK; - default: - return Type.UNKNOWN; + case Biome.TOWN: + case Biome.PLAINS: + case Biome.METROPOLIS: + return Type.NORMAL; + case Biome.GRASS: + case Biome.TALL_GRASS: + return Type.GRASS; + case Biome.FOREST: + case Biome.JUNGLE: + return Type.BUG; + case Biome.SLUM: + case Biome.SWAMP: + return Type.POISON; + case Biome.SEA: + case Biome.BEACH: + case Biome.LAKE: + case Biome.SEABED: + return Type.WATER; + case Biome.MOUNTAIN: + return Type.FLYING; + case Biome.BADLANDS: + return Type.GROUND; + case Biome.CAVE: + case Biome.DESERT: + return Type.ROCK; + case Biome.ICE_CAVE: + case Biome.SNOWY_FOREST: + return Type.ICE; + case Biome.MEADOW: + case Biome.FAIRY_CAVE: + case Biome.ISLAND: + return Type.FAIRY; + case Biome.POWER_PLANT: + return Type.ELECTRIC; + case Biome.VOLCANO: + return Type.FIRE; + case Biome.GRAVEYARD: + case Biome.TEMPLE: + return Type.GHOST; + case Biome.DOJO: + case Biome.CONSTRUCTION_SITE: + return Type.FIGHTING; + case Biome.FACTORY: + case Biome.LABORATORY: + return Type.STEEL; + case Biome.RUINS: + case Biome.SPACE: + return Type.PSYCHIC; + case Biome.WASTELAND: + case Biome.END: + return Type.DRAGON; + case Biome.ABYSS: + return Type.DARK; + default: + return Type.UNKNOWN; } } getBgTerrainColorRatioForBiome(): number { switch (this.biomeType) { - case Biome.SPACE: - return 1; - case Biome.END: - return 0; + case Biome.SPACE: + return 1; + case Biome.END: + return 0; } return 131 / 180; @@ -387,21 +394,22 @@ export class Arena { this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => { pokemon.findAndRemoveTags(t => "terrainTypes" in t && !(t.terrainTypes as TerrainType[]).find(t => t === terrain)); applyPostTerrainChangeAbAttrs(PostTerrainChangeAbAttr, pokemon, terrain); + applyAbAttrs(TerrainEventTypeChangeAbAttr, pokemon, null, false); }); return true; } - isMoveWeatherCancelled(user: Pokemon, move: Move) { - return this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(user, move); + public isMoveWeatherCancelled(user: Pokemon, move: Move): boolean { + return !!this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(user, move); } - isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move) { - return this.terrain && this.terrain.isMoveTerrainCancelled(user, targets, move); + public isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean { + return !!this.terrain && this.terrain.isMoveTerrainCancelled(user, targets, move); } - getTerrainType() : TerrainType { - return this.terrain?.terrainType || TerrainType.NONE; + public getTerrainType(): TerrainType { + return this.terrain?.terrainType ?? TerrainType.NONE; } getAttackTypeMultiplier(attackType: Type, grounded: boolean): number { @@ -424,52 +432,52 @@ export class Arena { */ getTrainerChance(): integer { switch (this.biomeType) { - case Biome.METROPOLIS: - return 2; - case Biome.SLUM: - case Biome.BEACH: - case Biome.DOJO: - case Biome.CONSTRUCTION_SITE: - return 4; - case Biome.PLAINS: - case Biome.GRASS: - case Biome.LAKE: - case Biome.CAVE: - return 6; - case Biome.TALL_GRASS: - case Biome.FOREST: - case Biome.SEA: - case Biome.SWAMP: - case Biome.MOUNTAIN: - case Biome.BADLANDS: - case Biome.DESERT: - case Biome.MEADOW: - case Biome.POWER_PLANT: - case Biome.GRAVEYARD: - case Biome.FACTORY: - case Biome.SNOWY_FOREST: - return 8; - case Biome.ICE_CAVE: - case Biome.VOLCANO: - case Biome.RUINS: - case Biome.WASTELAND: - case Biome.JUNGLE: - case Biome.FAIRY_CAVE: - return 12; - case Biome.SEABED: - case Biome.ABYSS: - case Biome.SPACE: - case Biome.TEMPLE: - return 16; - default: - return 0; + case Biome.METROPOLIS: + return 2; + case Biome.SLUM: + case Biome.BEACH: + case Biome.DOJO: + case Biome.CONSTRUCTION_SITE: + return 4; + case Biome.PLAINS: + case Biome.GRASS: + case Biome.LAKE: + case Biome.CAVE: + return 6; + case Biome.TALL_GRASS: + case Biome.FOREST: + case Biome.SEA: + case Biome.SWAMP: + case Biome.MOUNTAIN: + case Biome.BADLANDS: + case Biome.DESERT: + case Biome.MEADOW: + case Biome.POWER_PLANT: + case Biome.GRAVEYARD: + case Biome.FACTORY: + case Biome.SNOWY_FOREST: + return 8; + case Biome.ICE_CAVE: + case Biome.VOLCANO: + case Biome.RUINS: + case Biome.WASTELAND: + case Biome.JUNGLE: + case Biome.FAIRY_CAVE: + return 12; + case Biome.SEABED: + case Biome.ABYSS: + case Biome.SPACE: + case Biome.TEMPLE: + return 16; + default: + return 0; } } getTimeOfDay(): TimeOfDay { switch (this.biomeType) { - case Biome.ABYSS: - return TimeOfDay.NIGHT; + case Biome.ABYSS: + return TimeOfDay.NIGHT; } const waveCycle = ((this.scene.currentBattle?.waveIndex || 0) + this.scene.waveCycleOffset) % 40; @@ -491,35 +499,35 @@ export class Arena { isOutside(): boolean { switch (this.biomeType) { - case Biome.SEABED: - case Biome.CAVE: - case Biome.ICE_CAVE: - case Biome.POWER_PLANT: - case Biome.DOJO: - case Biome.FACTORY: - case Biome.ABYSS: - case Biome.FAIRY_CAVE: - case Biome.TEMPLE: - case Biome.LABORATORY: - return false; - default: - return true; + case Biome.SEABED: + case Biome.CAVE: + case Biome.ICE_CAVE: + case Biome.POWER_PLANT: + case Biome.DOJO: + case Biome.FACTORY: + case Biome.ABYSS: + case Biome.FAIRY_CAVE: + case Biome.TEMPLE: + case Biome.LABORATORY: + return false; + default: + return true; } } overrideTint(): [integer, integer, integer] { switch (Overrides.ARENA_TINT_OVERRIDE) { - case TimeOfDay.DUSK: - return [ 98, 48, 73 ].map(c => Math.round((c + 128) / 2)) as [integer, integer, integer]; - break; - case (TimeOfDay.NIGHT): - return [ 64, 64, 64 ]; - break; - case TimeOfDay.DAWN: - case TimeOfDay.DAY: - default: - return [ 128, 128, 128 ]; - break; + case TimeOfDay.DUSK: + return [ 98, 48, 73 ].map(c => Math.round((c + 128) / 2)) as [integer, integer, integer]; + break; + case (TimeOfDay.NIGHT): + return [ 64, 64, 64 ]; + break; + case TimeOfDay.DAWN: + case TimeOfDay.DAY: + default: + return [ 128, 128, 128 ]; + break; } } @@ -528,10 +536,10 @@ export class Arena { return this.overrideTint(); } switch (this.biomeType) { - case Biome.ABYSS: - return [ 64, 64, 64 ]; - default: - return [ 128, 128, 128 ]; + case Biome.ABYSS: + return [ 64, 64, 64 ]; + default: + return [ 128, 128, 128 ]; } } @@ -544,8 +552,8 @@ export class Arena { } switch (this.biomeType) { - default: - return [ 98, 48, 73 ].map(c => Math.round((c + 128) / 2)) as [integer, integer, integer]; + default: + return [ 98, 48, 73 ].map(c => Math.round((c + 128) / 2)) as [integer, integer, integer]; } } @@ -554,10 +562,10 @@ export class Arena { return this.overrideTint(); } switch (this.biomeType) { - case Biome.ABYSS: - case Biome.SPACE: - case Biome.END: - return this.getDayTint(); + case Biome.ABYSS: + case Biome.SPACE: + case Biome.END: + return this.getDayTint(); } if (!this.isOutside()) { @@ -565,8 +573,8 @@ export class Arena { } switch (this.biomeType) { - default: - return [ 48, 48, 98 ]; + default: + return [ 48, 48, 98 ]; } } @@ -579,26 +587,28 @@ export class Arena { * Applies each `ArenaTag` in this Arena, based on which side (self, enemy, or both) is passed in as a parameter * @param tagType Either an {@linkcode ArenaTagType} string, or an actual {@linkcode ArenaTag} class to filter which ones to apply * @param side {@linkcode ArenaTagSide} which side's arena tags to apply + * @param simulated if `true`, this applies arena tags without changing game state * @param args array of parameters that the called upon tags may need */ - applyTagsForSide(tagType: ArenaTagType | Constructor, side: ArenaTagSide, ...args: unknown[]): void { + applyTagsForSide(tagType: ArenaTagType | Constructor, side: ArenaTagSide, simulated: boolean, ...args: unknown[]): void { let tags = typeof tagType === "string" ? this.tags.filter(t => t.tagType === tagType) : this.tags.filter(t => t instanceof tagType); if (side !== ArenaTagSide.BOTH) { tags = tags.filter(t => t.side === side); } - tags.forEach(t => t.apply(this, args)); + tags.forEach(t => t.apply(this, simulated, ...args)); } /** * Applies the specified tag to both sides (ie: both user and trainer's tag that match the Tag specified) * by calling {@linkcode applyTagsForSide()} * @param tagType Either an {@linkcode ArenaTagType} string, or an actual {@linkcode ArenaTag} class to filter which ones to apply + * @param simulated if `true`, this applies arena tags without changing game state * @param args array of parameters that the called upon tags may need */ - applyTags(tagType: ArenaTagType | Constructor, ...args: unknown[]): void { - this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args); + applyTags(tagType: ArenaTagType | Constructor, simulated: boolean, ...args: unknown[]): void { + this.applyTagsForSide(tagType, ArenaTagSide.BOTH, simulated, ...args); } /** @@ -745,77 +755,77 @@ export class Arena { getBgmLoopPoint(): number { switch (this.biomeType) { - case Biome.TOWN: - return 7.288; - case Biome.PLAINS: - return 17.485; - case Biome.GRASS: - return 1.995; - case Biome.TALL_GRASS: - return 9.608; - case Biome.METROPOLIS: - return 141.470; - case Biome.FOREST: - return 4.294; - case Biome.SEA: - return 0.024; - case Biome.SWAMP: - return 4.461; - case Biome.BEACH: - return 3.462; - case Biome.LAKE: - return 7.215; - case Biome.SEABED: - return 2.600; - case Biome.MOUNTAIN: - return 4.018; - case Biome.BADLANDS: - return 17.790; - case Biome.CAVE: - return 14.240; - case Biome.DESERT: - return 1.143; - case Biome.ICE_CAVE: - return 0.000; - case Biome.MEADOW: - return 3.891; - case Biome.POWER_PLANT: - return 9.447; - case Biome.VOLCANO: - return 17.637; - case Biome.GRAVEYARD: - return 3.232; - case Biome.DOJO: - return 6.205; - case Biome.FACTORY: - return 4.985; - case Biome.RUINS: - return 0.000; - case Biome.WASTELAND: - return 6.336; - case Biome.ABYSS: - return 5.130; - case Biome.SPACE: - return 20.036; - case Biome.CONSTRUCTION_SITE: - return 1.222; - case Biome.JUNGLE: - return 0.000; - case Biome.FAIRY_CAVE: - return 4.542; - case Biome.TEMPLE: - return 2.547; - case Biome.ISLAND: - return 2.751; - case Biome.LABORATORY: - return 114.862; - case Biome.SLUM: - return 0.000; - case Biome.SNOWY_FOREST: - return 3.047; - default: - console.warn(`missing bgm loop-point for biome "${Biome[this.biomeType]}" (=${this.biomeType})`); - return 0; + case Biome.TOWN: + return 7.288; + case Biome.PLAINS: + return 17.485; + case Biome.GRASS: + return 1.995; + case Biome.TALL_GRASS: + return 9.608; + case Biome.METROPOLIS: + return 141.470; + case Biome.FOREST: + return 4.294; + case Biome.SEA: + return 0.024; + case Biome.SWAMP: + return 4.461; + case Biome.BEACH: + return 3.462; + case Biome.LAKE: + return 7.215; + case Biome.SEABED: + return 2.600; + case Biome.MOUNTAIN: + return 4.018; + case Biome.BADLANDS: + return 17.790; + case Biome.CAVE: + return 14.240; + case Biome.DESERT: + return 1.143; + case Biome.ICE_CAVE: + return 0.000; + case Biome.MEADOW: + return 3.891; + case Biome.POWER_PLANT: + return 9.447; + case Biome.VOLCANO: + return 17.637; + case Biome.GRAVEYARD: + return 3.232; + case Biome.DOJO: + return 6.205; + case Biome.FACTORY: + return 4.985; + case Biome.RUINS: + return 0.000; + case Biome.WASTELAND: + return 6.336; + case Biome.ABYSS: + return 5.130; + case Biome.SPACE: + return 20.036; + case Biome.CONSTRUCTION_SITE: + return 1.222; + case Biome.JUNGLE: + return 0.000; + case Biome.FAIRY_CAVE: + return 4.542; + case Biome.TEMPLE: + return 2.547; + case Biome.ISLAND: + return 2.751; + case Biome.LABORATORY: + return 114.862; + case Biome.SLUM: + return 0.000; + case Biome.SNOWY_FOREST: + return 3.047; + default: + console.warn(`missing bgm loop-point for biome "${Biome[this.biomeType]}" (=${this.biomeType})`); + return 0; } } } @@ -826,32 +836,32 @@ export function getBiomeKey(biome: Biome): string { export function getBiomeHasProps(biomeType: Biome): boolean { switch (biomeType) { - case Biome.METROPOLIS: - case Biome.BEACH: - case Biome.LAKE: - case Biome.SEABED: - case Biome.MOUNTAIN: - case Biome.BADLANDS: - case Biome.CAVE: - case Biome.DESERT: - case Biome.ICE_CAVE: - case Biome.MEADOW: - case Biome.POWER_PLANT: - case Biome.VOLCANO: - case Biome.GRAVEYARD: - case Biome.FACTORY: - case Biome.RUINS: - case Biome.WASTELAND: - case Biome.ABYSS: - case Biome.CONSTRUCTION_SITE: - case Biome.JUNGLE: - case Biome.FAIRY_CAVE: - case Biome.TEMPLE: - case Biome.SNOWY_FOREST: - case Biome.ISLAND: - case Biome.LABORATORY: - case Biome.END: - return true; + case Biome.METROPOLIS: + case Biome.BEACH: + case Biome.LAKE: + case Biome.SEABED: + case Biome.MOUNTAIN: + case Biome.BADLANDS: + case Biome.CAVE: + case Biome.DESERT: + case Biome.ICE_CAVE: + case Biome.MEADOW: + case Biome.POWER_PLANT: + case Biome.VOLCANO: + case Biome.GRAVEYARD: + case Biome.FACTORY: + case Biome.RUINS: + case Biome.WASTELAND: + case Biome.ABYSS: + case Biome.CONSTRUCTION_SITE: + case Biome.JUNGLE: + case Biome.FAIRY_CAVE: + case Biome.TEMPLE: + case Biome.SNOWY_FOREST: + case Biome.ISLAND: + case Biome.LABORATORY: + case Biome.END: + return true; } return false; diff --git a/src/field/damage-number-handler.ts b/src/field/damage-number-handler.ts index ae0692da342..4ddcd2d3ee7 100644 --- a/src/field/damage-number-handler.ts +++ b/src/field/damage-number-handler.ts @@ -29,21 +29,21 @@ export default class DamageNumberHandler { let [ textColor, shadowColor ] : TextAndShadowArr = [ null, null ]; switch (result) { - case HitResult.SUPER_EFFECTIVE: - [ textColor, shadowColor ] = [ "#f8d030", "#b8a038" ]; - break; - case HitResult.NOT_VERY_EFFECTIVE: - [ textColor, shadowColor ] = [ "#f08030", "#c03028" ]; - break; - case HitResult.ONE_HIT_KO: - [ textColor, shadowColor ] = [ "#a040a0", "#483850" ]; - break; - case HitResult.HEAL: - [ textColor, shadowColor ] = [ "#78c850", "#588040" ]; - break; - default: - [ textColor, shadowColor ] = [ "#ffffff", "#636363" ]; - break; + case HitResult.SUPER_EFFECTIVE: + [ textColor, shadowColor ] = [ "#f8d030", "#b8a038" ]; + break; + case HitResult.NOT_VERY_EFFECTIVE: + [ textColor, shadowColor ] = [ "#f08030", "#c03028" ]; + break; + case HitResult.ONE_HIT_KO: + [ textColor, shadowColor ] = [ "#a040a0", "#483850" ]; + break; + case HitResult.HEAL: + [ textColor, shadowColor ] = [ "#78c850", "#588040" ]; + break; + default: + [ textColor, shadowColor ] = [ "#ffffff", "#636363" ]; + break; } if (textColor) { diff --git a/src/field/mystery-encounter-intro.ts b/src/field/mystery-encounter-intro.ts index 70588da5d44..12bcace500c 100644 --- a/src/field/mystery-encounter-intro.ts +++ b/src/field/mystery-encounter-intro.ts @@ -101,14 +101,14 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con const getSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => { const ret = this.scene.addFieldSprite(0, 0, spriteKey); ret.setOrigin(0.5, 1); - ret.setPipeline(this.scene.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 }); + ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 }); return ret; }; const getItemSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => { const icon = this.scene.add.sprite(-19, 2, "items", spriteKey); icon.setOrigin(0.5, 1); - icon.setPipeline(this.scene.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 }); + icon.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 }); return icon; }; diff --git a/src/field/pokemon-sprite-sparkle-handler.ts b/src/field/pokemon-sprite-sparkle-handler.ts index ccf6a098667..2c4c295eaa4 100644 --- a/src/field/pokemon-sprite-sparkle-handler.ts +++ b/src/field/pokemon-sprite-sparkle-handler.ts @@ -36,7 +36,7 @@ export default class PokemonSpriteSparkleHandler { const ratioY = s.height / height; const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, "__BASE"); if (pixel?.alpha) { - const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height]; + const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height ]; const sparkle = (s.scene as BattleScene).addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), "tera_sparkle"); sparkle.pipelineData["ignoreTimeTint"] = s.pipelineData["ignoreTimeTint"]; sparkle.setName("sprite-tera-sparkle"); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index d5411496223..321532fffa7 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3,9 +3,9 @@ import BattleScene, { AnySound } from "#app/battle-scene"; import { Variant, VariantSet, variantColorCache } from "#app/data/variant"; import { variantData } from "#app/data/variant"; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "#app/ui/battle-info"; -import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "#app/data/move"; +import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget, CombinedPledgeStabBoostAttr } from "#app/data/move"; import { default as PokemonSpecies, PokemonSpeciesForm, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species"; -import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters"; +import { CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER, getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters"; import { starterPassiveAbilities } from "#app/data/balance/passives"; import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils"; import * as Utils from "#app/utils"; @@ -19,10 +19,10 @@ import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; import { Status, StatusEffect, getRandomStatus } from "#app/data/status-effect"; import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions"; import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "#app/data/balance/tms"; -import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag } from "../data/battler-tags"; +import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag, PowerTrickTag } from "../data/battler-tags"; import { WeatherType } from "#app/data/weather"; import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag"; -import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs } from "#app/data/ability"; +import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs, InfiltratorAbAttr, AlliedFieldDamageReductionAbAttr } from "#app/data/ability"; import PokemonData from "#app/system/pokemon-data"; import { BattlerIndex } from "#app/battle"; import { Mode } from "#app/ui/ui"; @@ -62,7 +62,7 @@ import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-ph import { Challenges } from "#enums/challenges"; import { PokemonAnimType } from "#enums/pokemon-anim-type"; import { PLAYER_PARTY_MAX_SIZE } from "#app/constants"; -import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { SwitchType } from "#enums/switch-type"; import { SpeciesFormKey } from "#enums/species-form-key"; import { BASE_HIDDEN_ABILITY_CHANCE, BASE_SHINY_CHANCE, SHINY_EPIC_CHANCE, SHINY_VARIANT_CHANCE } from "#app/data/balance/rates"; @@ -93,7 +93,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public stats: integer[]; public ivs: integer[]; public nature: Nature; - public natureOverride: Nature | -1; public moveset: (PokemonMove | null)[]; public status: Status | null; public friendship: integer; @@ -114,7 +113,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public fusionVariant: Variant; public fusionGender: Gender; public fusionLuck: integer; - public fusionMysteryEncounterPokemonData: MysteryEncounterPokemonData | null; + public fusionCustomPokemonData: CustomPokemonData | null; private summonDataPrimer: PokemonSummonData | null; @@ -122,7 +121,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public battleData: PokemonBattleData; public battleSummonData: PokemonBattleSummonData; public turnData: PokemonTurnData; - public mysteryEncounterPokemonData: MysteryEncounterPokemonData; + public customPokemonData: CustomPokemonData; /** Used by Mystery Encounters to execute pokemon-specific logic (such as stat boosts) at start of battle */ public mysteryEncounterBattleEffects?: (pokemon: Pokemon) => void; @@ -193,7 +192,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } this.nature = dataSource.nature || 0 as Nature; this.nickname = dataSource.nickname; - this.natureOverride = dataSource.natureOverride !== undefined ? dataSource.natureOverride : -1; this.moveset = dataSource.moveset; this.status = dataSource.status!; // TODO: is this bang correct? this.friendship = dataSource.friendship !== undefined ? dataSource.friendship : this.species.baseFriendship; @@ -212,9 +210,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.fusionVariant = dataSource.fusionVariant || 0; this.fusionGender = dataSource.fusionGender; this.fusionLuck = dataSource.fusionLuck; - this.fusionMysteryEncounterPokemonData = dataSource.fusionMysteryEncounterPokemonData; + this.fusionCustomPokemonData = dataSource.fusionCustomPokemonData; this.usedTMs = dataSource.usedTMs ?? []; - this.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(dataSource.mysteryEncounterPokemonData); + this.customPokemonData = new CustomPokemonData(dataSource.customPokemonData); } else { this.id = Utils.randSeedInt(4294967296); this.ivs = ivs || Utils.getIvsFromId(this.id); @@ -235,7 +233,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.variant = this.shiny ? this.generateVariant() : 0; } - this.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(); + this.customPokemonData = new CustomPokemonData(); if (nature !== undefined) { this.setNature(nature); @@ -243,8 +241,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.generateNature(); } - this.natureOverride = -1; - this.friendship = species.baseFriendship; this.metLevel = level; this.metBiome = scene.currentBattle ? scene.arena.biomeType : -1; @@ -593,8 +589,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const formKey = this.getFormKey(); if (this.isMax() === true || formKey === "segin-starmobile" || formKey === "schedar-starmobile" || formKey === "navi-starmobile" || formKey === "ruchbah-starmobile" || formKey === "caph-starmobile") { return 1.5; - } else if (this.mysteryEncounterPokemonData.spriteScale > 0) { - return this.mysteryEncounterPokemonData.spriteScale; + } else if (this.customPokemonData.spriteScale > 0) { + return this.customPokemonData.spriteScale; } return 1; } @@ -680,12 +676,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { getFieldPositionOffset(): [ number, number ] { switch (this.fieldPosition) { - case FieldPosition.CENTER: - return [ 0, 0 ]; - case FieldPosition.LEFT: - return [ -32, -8 ]; - case FieldPosition.RIGHT: - return [ 32, 0 ]; + case FieldPosition.CENTER: + return [ 0, 0 ]; + case FieldPosition.LEFT: + return [ -32, -8 ]; + case FieldPosition.RIGHT: + return [ 32, 0 ]; } } @@ -696,7 +692,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @see {@linkcode getFieldPositionOffset} */ getSubstituteOffset(): [ number, number ] { - return this.isPlayer() ? [-30, 10] : [30, -10]; + return this.isPlayer() ? [ -30, 10 ] : [ 30, -10 ]; } /** @@ -749,9 +745,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const relX = newOffset[0] - initialOffset[0]; const relY = newOffset[1] - initialOffset[1]; + const subTag = this.getTag(SubstituteTag); + if (duration) { + // TODO: can this use stricter typing? + const targets: any[] = [ this ]; + if (subTag?.sprite) { + targets.push(subTag.sprite); + } this.scene.tweens.add({ - targets: this, + targets: targets, x: (_target, _key, value: number) => value + relX, y: (_target, _key, value: number) => value + relY, duration: duration, @@ -761,6 +764,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } else { this.x += relX; this.y += relY; + if (subTag?.sprite) { + subTag.sprite.x += relX; + subTag.sprite.y += relY; + } } }); } @@ -906,37 +913,39 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { let ret = statValue.value * this.getStatStageMultiplier(stat, opponent, move, ignoreOppAbility, isCritical, simulated); switch (stat) { - case Stat.ATK: - if (this.getTag(BattlerTagType.SLOW_START)) { - ret >>= 1; - } - break; - case Stat.DEF: - if (this.isOfType(Type.ICE) && this.scene.arena.weather?.weatherType === WeatherType.SNOW) { - ret *= 1.5; - } - break; - case Stat.SPATK: - break; - case Stat.SPDEF: - if (this.isOfType(Type.ROCK) && this.scene.arena.weather?.weatherType === WeatherType.SANDSTORM) { - ret *= 1.5; - } - break; - case Stat.SPD: - // Check both the player and enemy to see if Tailwind should be multiplying the speed of the Pokemon - if ((this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.PLAYER)) - || (!this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.ENEMY))) { - ret *= 2; - } + case Stat.ATK: + if (this.getTag(BattlerTagType.SLOW_START)) { + ret >>= 1; + } + break; + case Stat.DEF: + if (this.isOfType(Type.ICE) && this.scene.arena.weather?.weatherType === WeatherType.SNOW) { + ret *= 1.5; + } + break; + case Stat.SPATK: + break; + case Stat.SPDEF: + if (this.isOfType(Type.ROCK) && this.scene.arena.weather?.weatherType === WeatherType.SANDSTORM) { + ret *= 1.5; + } + break; + case Stat.SPD: + const side = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; + if (this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, side)) { + ret *= 2; + } + if (this.scene.arena.getTagOnSide(ArenaTagType.GRASS_WATER_PLEDGE, side)) { + ret >>= 2; + } - if (this.getTag(BattlerTagType.SLOW_START)) { - ret >>= 1; - } - if (this.status && this.status.effect === StatusEffect.PARALYSIS) { - ret >>= 1; - } - break; + if (this.getTag(BattlerTagType.SLOW_START)) { + ret >>= 1; + } + if (this.status && this.status.effect === StatusEffect.PARALYSIS) { + ret >>= 1; + } + break; } const highestStatBoost = this.findTag(t => t instanceof HighestStatBoostTag && (t as HighestStatBoostTag).stat === stat) as HighestStatBoostTag; @@ -981,7 +990,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder); } - statHolder.value = Utils.clampInt(statHolder.value, 1, Number.MAX_SAFE_INTEGER); + statHolder.value = Phaser.Math.Clamp(statHolder.value, 1, Number.MAX_SAFE_INTEGER); this.setStat(s, statHolder.value); } @@ -1010,7 +1019,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getNature(): Nature { - return this.natureOverride !== -1 ? this.natureOverride : this.nature; + return this.customPokemonData.nature !== -1 ? this.customPokemonData.nature : this.nature; } setNature(nature: Nature): void { @@ -1087,6 +1096,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return !!this.fusionSpecies; } + /** + * Checks if the {@linkcode Pokemon} has a fusion with the specified {@linkcode Species}. + * @param species the pokemon {@linkcode Species} to check + * @returns `true` if the {@linkcode Pokemon} has a fusion with the specified {@linkcode Species}, `false` otherwise + */ + hasFusionSpecies(species: Species): boolean { + return this.fusionSpecies?.speciesId === species; + } + abstract isBoss(): boolean; getMoveset(ignoreOverride?: boolean): (PokemonMove | null)[] { @@ -1097,7 +1115,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // Overrides moveset based on arrays specified in overrides.ts let overrideArray: Moves | Array = this.isPlayer() ? Overrides.MOVESET_OVERRIDE : Overrides.OPP_MOVESET_OVERRIDE; if (!Array.isArray(overrideArray)) { - overrideArray = [overrideArray]; + overrideArray = [ overrideArray ]; } if (overrideArray.length > 0) { if (!this.isPlayer()) { @@ -1176,15 +1194,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (!types.length || !includeTeraType) { if (!ignoreOverride && this.summonData?.types && this.summonData.types.length > 0) { this.summonData.types.forEach(t => types.push(t)); - } else if (this.mysteryEncounterPokemonData.types && this.mysteryEncounterPokemonData.types.length > 0) { + } else if (this.customPokemonData.types && this.customPokemonData.types.length > 0) { // "Permanent" override for a Pokemon's normal types, currently only used by Mystery Encounters - types.push(this.mysteryEncounterPokemonData.types[0]); + types.push(this.customPokemonData.types[0]); // Fusing a Pokemon onto something with "permanently changed" types will still apply the fusion's types as normal const fusionSpeciesForm = this.getFusionSpeciesForm(ignoreOverride); if (fusionSpeciesForm) { // Check if the fusion Pokemon also had "permanently changed" types - const fusionMETypes = this.fusionMysteryEncounterPokemonData?.types; + const fusionMETypes = this.fusionCustomPokemonData?.types; if (fusionMETypes && fusionMETypes.length >= 2 && fusionMETypes[1] !== types[0]) { types.push(fusionMETypes[1]); } else if (fusionMETypes && fusionMETypes.length === 1 && fusionMETypes[0] !== types[0]) { @@ -1196,8 +1214,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } - if (types.length === 1 && this.mysteryEncounterPokemonData.types.length >= 2) { - types.push(this.mysteryEncounterPokemonData.types[1]); + if (types.length === 1 && this.customPokemonData.types.length >= 2) { + types.push(this.customPokemonData.types[1]); } } else { const speciesForm = this.getSpeciesForm(ignoreOverride); @@ -1208,7 +1226,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (fusionSpeciesForm) { // Check if the fusion Pokemon also had "permanently changed" types // Otherwise, use standard fusion type logic - const fusionMETypes = this.fusionMysteryEncounterPokemonData?.types; + const fusionMETypes = this.fusionCustomPokemonData?.types; if (fusionMETypes && fusionMETypes.length >= 2 && fusionMETypes[1] !== types[0]) { types.push(fusionMETypes[1]); } else if (fusionMETypes && fusionMETypes.length === 1 && fusionMETypes[0] !== types[0]) { @@ -1240,6 +1258,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + // the type added to Pokemon from moves like Forest's Curse or Trick Or Treat + if (!ignoreOverride && this.summonData && this.summonData.addedType && !types.includes(this.summonData.addedType)) { + types.push(this.summonData.addedType); + } + + // If both types are the same (can happen in weird custom typing scenarios), reduce to single type + if (types.length > 1 && types[0] === types[1]) { + types.splice(0, 1); + } + return types; } @@ -1266,14 +1294,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return allAbilities[Overrides.OPP_ABILITY_OVERRIDE]; } if (this.isFusion()) { - if (!isNullOrUndefined(this.fusionMysteryEncounterPokemonData?.ability) && this.fusionMysteryEncounterPokemonData.ability !== -1) { - return allAbilities[this.fusionMysteryEncounterPokemonData.ability]; + if (!isNullOrUndefined(this.fusionCustomPokemonData?.ability) && this.fusionCustomPokemonData.ability !== -1) { + return allAbilities[this.fusionCustomPokemonData.ability]; } else { return allAbilities[this.getFusionSpeciesForm(ignoreOverride).getAbility(this.fusionAbilityIndex)]; } } - if (!isNullOrUndefined(this.mysteryEncounterPokemonData.ability) && this.mysteryEncounterPokemonData.ability !== -1) { - return allAbilities[this.mysteryEncounterPokemonData.ability]; + if (!isNullOrUndefined(this.customPokemonData.ability) && this.customPokemonData.ability !== -1) { + return allAbilities[this.customPokemonData.ability]; } let abilityId = this.getSpeciesForm(ignoreOverride).getAbility(this.abilityIndex); if (abilityId === Abilities.NONE) { @@ -1296,8 +1324,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE && !this.isPlayer()) { return allAbilities[Overrides.OPP_PASSIVE_ABILITY_OVERRIDE]; } - if (!isNullOrUndefined(this.mysteryEncounterPokemonData.passive) && this.mysteryEncounterPokemonData.passive !== -1) { - return allAbilities[this.mysteryEncounterPokemonData.passive]; + if (!isNullOrUndefined(this.customPokemonData.passive) && this.customPokemonData.passive !== -1) { + return allAbilities[this.customPokemonData.passive]; } let starterSpeciesId = this.species.speciesId; @@ -1383,10 +1411,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const suppressed = new Utils.BooleanHolder(false); this.scene.getField(true).filter(p => p !== this).map(p => { if (p.getAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility()) { - p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, false, suppressed, [ability])); + p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, false, suppressed, [ ability ])); } if (p.getPassiveAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility(true)) { - p.getPassiveAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, true, false, suppressed, [ability])); + p.getPassiveAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, true, false, suppressed, [ ability ])); } }); if (suppressed.value) { @@ -1406,10 +1434,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns {boolean} Whether the ability is present and active */ hasAbility(ability: Abilities, canApply: boolean = true, ignoreOverride?: boolean): boolean { - if ((!canApply || this.canApplyAbility()) && this.getAbility(ignoreOverride).id === ability) { + if (this.getAbility(ignoreOverride).id === ability && (!canApply || this.canApplyAbility())) { return true; } - if (this.hasPassive() && (!canApply || this.canApplyAbility(true)) && this.getPassiveAbility().id === ability) { + if (this.getPassiveAbility().id === ability && this.hasPassive() && (!canApply || this.canApplyAbility(true))) { return true; } return false; @@ -1477,7 +1505,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } isGrounded(): boolean { - return !!this.getTag(GroundedTag) || (!this.isOfType(Type.FLYING, true, true) && !this.hasAbility(Abilities.LEVITATE) && !this.getTag(BattlerTagType.MAGNET_RISEN) && !this.getTag(SemiInvulnerableTag)); + return !!this.getTag(GroundedTag) || (!this.isOfType(Type.FLYING, true, true) && !this.hasAbility(Abilities.LEVITATE) && !this.getTag(BattlerTagType.FLOATING) && !this.getTag(SemiInvulnerableTag)); } /** @@ -1516,13 +1544,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder); applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder); - this.scene.arena.applyTags(ArenaTagType.PLASMA_FISTS, moveTypeHolder); + this.scene.arena.applyTags(ArenaTagType.ION_DELUGE, simulated, moveTypeHolder); + if (this.getTag(BattlerTagType.ELECTRIFIED)) { + moveTypeHolder.value = Type.ELECTRIC; + } return moveTypeHolder.value as Type; } - /** * Calculates the effectiveness of a move against the Pokémon. * This includes modifiers from move and ability attributes. @@ -1694,7 +1724,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (pokemonEvolutions.hasOwnProperty(this.species.speciesId)) { const evolutions = pokemonEvolutions[this.species.speciesId]; for (const e of evolutions) { - if (!e.item && this.level >= e.level && (!e.preFormKey || this.getFormKey() === e.preFormKey)) { + if (!e.item && this.level >= e.level && (isNullOrUndefined(e.preFormKey) || this.getFormKey() === e.preFormKey)) { if (e.condition === null || (e.condition as SpeciesEvolutionCondition).predicate(this)) { return e; } @@ -1705,7 +1735,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (this.isFusion() && this.fusionSpecies && pokemonEvolutions.hasOwnProperty(this.fusionSpecies.speciesId)) { const fusionEvolutions = pokemonEvolutions[this.fusionSpecies.speciesId].map(e => new FusionSpeciesFormEvolution(this.species.speciesId, e)); for (const fe of fusionEvolutions) { - if (!fe.item && this.level >= fe.level && (!fe.preFormKey || this.getFusionFormKey() === fe.preFormKey)) { + if (!fe.item && this.level >= fe.level && (isNullOrUndefined(fe.preFormKey) || this.getFusionFormKey() === fe.preFormKey)) { if (fe.condition === null || (fe.condition as SpeciesEvolutionCondition).predicate(this)) { return fe; } @@ -1956,7 +1986,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { && species.speciesId !== this.species.speciesId; }; - this.fusionSpecies = this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true); + let fusionOverride: PokemonSpecies | undefined = undefined; + + if (forStarter && this instanceof PlayerPokemon && Overrides.STARTER_FUSION_SPECIES_OVERRIDE) { + fusionOverride = getPokemonSpecies(Overrides.STARTER_FUSION_SPECIES_OVERRIDE); + } else if (this instanceof EnemyPokemon && Overrides.OPP_FUSION_SPECIES_OVERRIDE) { + fusionOverride = getPokemonSpecies(Overrides.OPP_FUSION_SPECIES_OVERRIDE); + } + + this.fusionSpecies = fusionOverride ?? this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true); this.fusionAbilityIndex = (this.fusionSpecies.abilityHidden && hasHiddenAbility ? 2 : this.fusionSpecies.ability2 !== this.fusionSpecies.ability1 ? randAbilityIndex : 0); this.fusionShiny = this.shiny; this.fusionVariant = this.variant; @@ -1986,7 +2024,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.fusionVariant = 0; this.fusionGender = 0; this.fusionLuck = 0; - this.fusionMysteryEncounterPokemonData = null; + this.fusionCustomPokemonData = null; this.generateName(); this.calculateStats(); @@ -2017,7 +2055,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { weight /= 100; } // Unimplemented level up moves are possible to generate, but 1% of their normal chance. if (!movePool.some(m => m[0] === levelMove[1])) { - movePool.push([levelMove[1], weight]); + movePool.push([ levelMove[1], weight ]); } } @@ -2039,11 +2077,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } if (compatible && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) { if (tmPoolTiers[moveId] === ModifierTier.COMMON && this.level >= 15) { - movePool.push([moveId, 4]); + movePool.push([ moveId, 4 ]); } else if (tmPoolTiers[moveId] === ModifierTier.GREAT && this.level >= 30) { - movePool.push([moveId, 8]); + movePool.push([ moveId, 8 ]); } else if (tmPoolTiers[moveId] === ModifierTier.ULTRA && this.level >= 50) { - movePool.push([moveId, 14]); + movePool.push([ moveId, 14 ]); } } } @@ -2052,23 +2090,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { for (let i = 0; i < 3; i++) { const moveId = speciesEggMoves[this.species.getRootSpeciesId()][i]; if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) { - movePool.push([moveId, 40]); + movePool.push([ moveId, 40 ]); } } const moveId = speciesEggMoves[this.species.getRootSpeciesId()][3]; if (this.level >= 170 && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)") && !this.isBoss()) { // No rare egg moves before e4 - movePool.push([moveId, 30]); + movePool.push([ moveId, 30 ]); } if (this.fusionSpecies) { for (let i = 0; i < 3; i++) { const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][i]; if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) { - movePool.push([moveId, 40]); + movePool.push([ moveId, 40 ]); } } const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][3]; if (this.level >= 170 && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)") && !this.isBoss()) {// No rare egg moves before e4 - movePool.push([moveId, 30]); + movePool.push([ moveId, 30 ]); } } } @@ -2082,26 +2120,26 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // Trainers never get OHKO moves movePool = movePool.filter(m => !allMoves[m[0]].hasAttr(OneHitKOAttr)); // Half the weight of self KO moves - movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1)]); - movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1)]); + movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1) ]); + movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1) ]); // Trainers get a weight bump to stat buffing moves - movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].getAttrs(StatStageChangeAttr).some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1)]); + movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].getAttrs(StatStageChangeAttr).some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1) ]); // Trainers get a weight decrease to multiturn moves - movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(ChargeAttr) || !!allMoves[m[0]].hasAttr(RechargeAttr) ? 0.7 : 1)]); + movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].isChargingMove() || !!allMoves[m[0]].hasAttr(RechargeAttr) ? 0.7 : 1) ]); } // Weight towards higher power moves, by reducing the power of moves below the highest power. // Caps max power at 90 to avoid something like hyper beam ruining the stats. // This is a pretty soft weighting factor, although it is scaled with the weight multiplier. const maxPower = Math.min(movePool.reduce((v, m) => Math.max(allMoves[m[0]].power, v), 40), 90); - movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power/maxPower, 1), 0.5))]); + movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power / maxPower, 1), 0.5)) ]); // Weight damaging moves against the lower stat const atk = this.getStat(Stat.ATK); const spAtk = this.getStat(Stat.SPATK); const worseCategory: MoveCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL; const statRatio = worseCategory === MoveCategory.PHYSICAL ? atk / spAtk : spAtk / atk; - movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1)]); + movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1) ]); let weightMultiplier = 0.9; // The higher this is the more the game weights towards higher level moves. At 0 all moves are equal weight. if (this.hasTrainer()) { @@ -2110,7 +2148,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (this.isBoss()) { weightMultiplier += 0.4; } - const baseWeights: [Moves, number][] = movePool.map(m => [m[0], Math.ceil(Math.pow(m[1], weightMultiplier)*100)]); + const baseWeights: [Moves, number][] = movePool.map(m => [ m[0], Math.ceil(Math.pow(m[1], weightMultiplier) * 100) ]); if (this.hasTrainer() || this.isBoss()) { // Trainers and bosses always force a stab move const stabMovePool = baseWeights.filter(m => allMoves[m[0]].category !== MoveCategory.STATUS && this.isOfType(allMoves[m[0]].type)); @@ -2142,7 +2180,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // Sqrt the weight of any damaging moves with overlapping types. This is about a 0.05 - 0.1 multiplier. // Other damaging moves 2x weight if 0-1 damaging moves, 0.5x if 2, 0.125x if 3. These weights double if STAB. // Status moves remain unchanged on weight, this encourages 1-2 - movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)).map(m => [m[0], this.moveset.some(mo => mo?.getMove().category !== MoveCategory.STATUS && mo?.getMove().type === allMoves[m[0]].type) ? Math.ceil(Math.sqrt(m[1])) : allMoves[m[0]].category !== MoveCategory.STATUS ? Math.ceil(m[1]/Math.max(Math.pow(4, this.moveset.filter(mo => (mo?.getMove().power!) > 1).length)/8, 0.5) * (this.isOfType(allMoves[m[0]].type) ? 2 : 1)) : m[1]]); // TODO: is this bang correct? + movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)).map(m => [ m[0], this.moveset.some(mo => mo?.getMove().category !== MoveCategory.STATUS && mo?.getMove().type === allMoves[m[0]].type) ? Math.ceil(Math.sqrt(m[1])) : allMoves[m[0]].category !== MoveCategory.STATUS ? Math.ceil(m[1] / Math.max(Math.pow(4, this.moveset.filter(mo => (mo?.getMove().power!) > 1).length) / 8, 0.5) * (this.isOfType(allMoves[m[0]].type) ? 2 : 1)) : m[1] ]); // TODO: is this bang correct? } else { // Non-trainer pokemon just use normal weights movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)); } @@ -2155,7 +2193,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.moveset.push(new PokemonMove(movePool[index][0], 0, 0)); } - this.scene.triggerPokemonFormChange(this, SpeciesFormChangeMoveLearnedTrigger); + // Trigger FormChange, except for enemy Pokemon during Mystery Encounters, to avoid crashes + if (this.isPlayer() || !this.scene.currentBattle?.isBattleMysteryEncounter() || !this.scene.currentBattle?.mysteryEncounter) { + this.scene.triggerPokemonFormChange(this, SpeciesFormChangeMoveLearnedTrigger); + } } trySelectMove(moveIndex: integer, ignorePp?: boolean): boolean { @@ -2253,6 +2294,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.levelExp = this.exp - getLevelTotalExp(this.level, this.species.growthRate); } + /** + * Compares if `this` and {@linkcode target} are on the same team. + * @param target the {@linkcode Pokemon} to compare against. + * @returns `true` if the two pokemon are allies, `false` otherwise + */ + public isOpponent(target: Pokemon): boolean { + return this.isPlayer() !== target.isPlayer(); + } + getOpponent(targetIndex: integer): Pokemon | null { const ret = this.getOpponents()[targetIndex]; if (ret.summonData) { @@ -2306,14 +2356,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (opponent) { if (isCritical) { switch (stat) { - case Stat.ATK: - case Stat.SPATK: - statStage.value = Math.max(statStage.value, 0); - break; - case Stat.DEF: - case Stat.SPDEF: - statStage.value = Math.min(statStage.value, 0); - break; + case Stat.ATK: + case Stat.SPATK: + statStage.value = Math.max(statStage.value, 0); + break; + case Stat.DEF: + case Stat.SPDEF: + statStage.value = Math.min(statStage.value, 0); + break; } } if (!ignoreOppAbility) { @@ -2546,6 +2596,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (matchesSourceType) { stabMultiplier.value += 0.5; } + applyMoveAttrs(CombinedPledgeStabBoostAttr, source, this, move, stabMultiplier); if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === moveType) { stabMultiplier.value += 0.5; } @@ -2572,7 +2623,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** Reduces damage if this Pokemon has a relevant screen (e.g. Light Screen for special attacks) */ const screenMultiplier = new Utils.NumberHolder(1); - this.scene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, move.category, this.scene.currentBattle.double, screenMultiplier); + this.scene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, simulated, source, moveCategory, screenMultiplier); /** * For each {@linkcode HitsTagAttr} the move has, doubles the damage of the move if: @@ -2621,9 +2672,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.applyModifiers(EnemyDamageReducerModifier, false, damage); } + /** Apply this Pokemon's post-calc defensive modifiers (e.g. Fur Coat) */ if (!ignoreAbility) { applyPreDefendAbAttrs(ReceivedMoveDamageMultiplierAbAttr, this, source, move, cancelled, simulated, damage); + + /** Additionally apply friend guard damage reduction if ally has it. */ + if (this.scene.currentBattle.double && this.getAlly()?.isActive(true)) { + applyPreDefendAbAttrs(AlliedFieldDamageReductionAbAttr, this.getAlly(), source, move, cancelled, simulated, damage); + } } // This attribute may modify damage arbitrarily, so be careful about changing its order of application. @@ -2662,7 +2719,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ apply(source: Pokemon, move: Move): HitResult { const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; - if (move.category === MoveCategory.STATUS) { + const moveCategory = new Utils.NumberHolder(move.category); + applyMoveAttrs(VariableMoveCategoryAttr, source, this, move, moveCategory); + if (moveCategory.value === MoveCategory.STATUS) { const cancelled = new Utils.BooleanHolder(false); const typeMultiplier = this.getMoveEffectiveness(source, move, false, false, cancelled); @@ -2680,7 +2739,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (critOnly.value || critAlways) { isCritical = true; } else { - const critChance = [24, 8, 2, 1][Math.max(0, Math.min(this.getCritStage(source, move), 3))]; + const critChance = [ 24, 8, 2, 1 ][Math.max(0, Math.min(this.getCritStage(source, move), 3))]; isCritical = critChance === 1 || !this.scene.randBattleSeedInt(critChance); } @@ -2736,7 +2795,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (damage > 0) { if (source.isPlayer()) { - this.scene.validateAchvs(DamageAchv, damage); + this.scene.validateAchvs(DamageAchv, new Utils.NumberHolder(damage)); if (damage > this.scene.gameData.gameStats.highestDamage) { this.scene.gameData.gameStats.highestDamage = damage; } @@ -2760,30 +2819,31 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // want to include is.Fainted() in case multi hit move ends early, still want to render message if (source.turnData.hitsLeft === 1 || this.isFainted()) { switch (result) { - case HitResult.SUPER_EFFECTIVE: - this.scene.queueMessage(i18next.t("battle:hitResultSuperEffective")); - break; - case HitResult.NOT_VERY_EFFECTIVE: - this.scene.queueMessage(i18next.t("battle:hitResultNotVeryEffective")); - break; - case HitResult.ONE_HIT_KO: - this.scene.queueMessage(i18next.t("battle:hitResultOneHitKO")); - break; + case HitResult.SUPER_EFFECTIVE: + this.scene.queueMessage(i18next.t("battle:hitResultSuperEffective")); + break; + case HitResult.NOT_VERY_EFFECTIVE: + this.scene.queueMessage(i18next.t("battle:hitResultNotVeryEffective")); + break; + case HitResult.ONE_HIT_KO: + this.scene.queueMessage(i18next.t("battle:hitResultOneHitKO")); + break; } } if (this.isFainted()) { // set splice index here, so future scene queues happen before FaintedPhase this.scene.setPhaseQueueSplice(); - this.scene.unshiftPhase(new FaintPhase(this.scene, this.getBattlerIndex(), isOneHitKo)); + if (!isNullOrUndefined(destinyTag) && dmg) { + // Destiny Bond will activate during FaintPhase + this.scene.unshiftPhase(new FaintPhase(this.scene, this.getBattlerIndex(), isOneHitKo, destinyTag, source)); + } else { + this.scene.unshiftPhase(new FaintPhase(this.scene, this.getBattlerIndex(), isOneHitKo)); + } this.destroySubstitute(); this.resetSummonData(); } - if (dmg) { - destinyTag?.lapse(source, BattlerTagLapseType.CUSTOM); - } - return result; } } @@ -2865,7 +2925,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } isMax(): boolean { - const maxForms = [SpeciesFormKey.GIGANTAMAX, SpeciesFormKey.GIGANTAMAX_RAPID, SpeciesFormKey.GIGANTAMAX_SINGLE, SpeciesFormKey.ETERNAMAX] as string[]; + const maxForms = [ SpeciesFormKey.GIGANTAMAX, SpeciesFormKey.GIGANTAMAX_RAPID, SpeciesFormKey.GIGANTAMAX_SINGLE, SpeciesFormKey.ETERNAMAX ] as string[]; return maxForms.includes(this.getFormKey()) || (!!this.getFusionFormKey() && maxForms.includes(this.getFusionFormKey()!)); } @@ -3013,6 +3073,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { continue; } + if (tag instanceof PowerTrickTag) { + tag.swapStat(this); + } + this.summonData.tags.push(tag); } @@ -3027,8 +3091,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * * @see {@linkcode MoveRestrictionBattlerTag} */ - isMoveRestricted(moveId: Moves): boolean { - return this.getRestrictingTag(moveId) !== null; + public isMoveRestricted(moveId: Moves, pokemon?: Pokemon): boolean { + return this.getRestrictingTag(moveId, pokemon) !== null; } /** @@ -3061,7 +3125,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ getRestrictingTag(moveId: Moves, user?: Pokemon, target?: Pokemon): MoveRestrictionBattlerTag | null { for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) { - if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId)) { + if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId, user)) { return tag as MoveRestrictionBattlerTag; } else if (user && target && (tag as MoveRestrictionBattlerTag).isMoveTargetRestricted(moveId, user, target)) { return tag as MoveRestrictionBattlerTag; @@ -3307,61 +3371,60 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } - const types = this.getTypes(true, true); - - const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; - if (sourcePokemon && sourcePokemon !== this && this.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, defendingSide)) { + if (sourcePokemon && sourcePokemon !== this && this.isSafeguarded(sourcePokemon)) { return false; } - switch (effect) { - case StatusEffect.POISON: - case StatusEffect.TOXIC: - // Check if the Pokemon is immune to Poison/Toxic or if the source pokemon is canceling the immunity - const poisonImmunity = types.map(defType => { - // Check if the Pokemon is not immune to Poison/Toxic - if (defType !== Type.POISON && defType !== Type.STEEL) { - return false; - } + const types = this.getTypes(true, true); - // Check if the source Pokemon has an ability that cancels the Poison/Toxic immunity - const cancelImmunity = new Utils.BooleanHolder(false); - if (sourcePokemon) { - applyAbAttrs(IgnoreTypeStatusEffectImmunityAbAttr, sourcePokemon, cancelImmunity, false, effect, defType); - if (cancelImmunity.value) { + switch (effect) { + case StatusEffect.POISON: + case StatusEffect.TOXIC: + // Check if the Pokemon is immune to Poison/Toxic or if the source pokemon is canceling the immunity + const poisonImmunity = types.map(defType => { + // Check if the Pokemon is not immune to Poison/Toxic + if (defType !== Type.POISON && defType !== Type.STEEL) { + return false; + } + + // Check if the source Pokemon has an ability that cancels the Poison/Toxic immunity + const cancelImmunity = new Utils.BooleanHolder(false); + if (sourcePokemon) { + applyAbAttrs(IgnoreTypeStatusEffectImmunityAbAttr, sourcePokemon, cancelImmunity, false, effect, defType); + if (cancelImmunity.value) { + return false; + } + } + + return true; + }); + + if (this.isOfType(Type.POISON) || this.isOfType(Type.STEEL)) { + if (poisonImmunity.includes(true)) { return false; } } - - return true; - }); - - if (this.isOfType(Type.POISON) || this.isOfType(Type.STEEL)) { - if (poisonImmunity.includes(true)) { + break; + case StatusEffect.PARALYSIS: + if (this.isOfType(Type.ELECTRIC)) { return false; } - } - break; - case StatusEffect.PARALYSIS: - if (this.isOfType(Type.ELECTRIC)) { - return false; - } - break; - case StatusEffect.SLEEP: - if (this.isGrounded() && this.scene.arena.terrain?.terrainType === TerrainType.ELECTRIC) { - return false; - } - break; - case StatusEffect.FREEZE: - if (this.isOfType(Type.ICE) || (this.scene?.arena?.weather?.weatherType &&[WeatherType.SUNNY, WeatherType.HARSH_SUN].includes(this.scene.arena.weather.weatherType))) { - return false; - } - break; - case StatusEffect.BURN: - if (this.isOfType(Type.FIRE)) { - return false; - } - break; + break; + case StatusEffect.SLEEP: + if (this.isGrounded() && this.scene.arena.terrain?.terrainType === TerrainType.ELECTRIC) { + return false; + } + break; + case StatusEffect.FREEZE: + if (this.isOfType(Type.ICE) || (this.scene?.arena?.weather?.weatherType && [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(this.scene.arena.weather.weatherType))) { + return false; + } + break; + case StatusEffect.BURN: + if (this.isOfType(Type.FIRE)) { + return false; + } + break; } const cancelled = new Utils.BooleanHolder(false); @@ -3377,7 +3440,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return true; } - trySetStatus(effect: StatusEffect | undefined, asPhase: boolean = false, sourcePokemon: Pokemon | null = null, cureTurn: integer | null = 0, sourceText: string | null = null): boolean { + trySetStatus(effect?: StatusEffect, asPhase: boolean = false, sourcePokemon: Pokemon | null = null, turnsRemaining: number = 0, sourceText: string | null = null): boolean { if (!this.canSetStatus(effect, asPhase, false, sourcePokemon)) { return false; } @@ -3391,15 +3454,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } if (asPhase) { - this.scene.unshiftPhase(new ObtainStatusEffectPhase(this.scene, this.getBattlerIndex(), effect, cureTurn, sourceText, sourcePokemon)); + this.scene.unshiftPhase(new ObtainStatusEffectPhase(this.scene, this.getBattlerIndex(), effect, turnsRemaining, sourceText, sourcePokemon)); return true; } - let statusCureTurn: Utils.IntegerHolder; + let sleepTurnsRemaining: Utils.NumberHolder; if (effect === StatusEffect.SLEEP) { - statusCureTurn = new Utils.IntegerHolder(this.randSeedIntRange(2, 4)); - applyAbAttrs(ReduceStatusEffectDurationAbAttr, this, null, false, effect, statusCureTurn); + sleepTurnsRemaining = new Utils.NumberHolder(this.randSeedIntRange(2, 4)); this.setFrameRate(4); @@ -3419,9 +3481,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } - statusCureTurn = statusCureTurn!; // tell TS compiler it's defined + sleepTurnsRemaining = sleepTurnsRemaining!; // tell TS compiler it's defined effect = effect!; // If `effect` is undefined then `trySetStatus()` will have already returned early via the `canSetStatus()` call - this.status = new Status(effect, 0, statusCureTurn?.value); + this.status = new Status(effect, 0, sleepTurnsRemaining?.value); if (effect !== StatusEffect.FAINT) { this.scene.triggerPokemonFormChange(this, SpeciesFormChangeStatusEffectTrigger, true); @@ -3459,6 +3521,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + /** + * Checks if this Pokemon is protected by Safeguard + * @param attacker the {@linkcode Pokemon} inflicting status on this Pokemon + * @returns `true` if this Pokemon is protected by Safeguard; `false` otherwise. + */ + isSafeguarded(attacker: Pokemon): boolean { + const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; + if (this.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, defendingSide)) { + const bypassed = new Utils.BooleanHolder(false); + if (attacker) { + applyAbAttrs(InfiltratorAbAttr, attacker, null, false, bypassed); + } + return !bypassed.value; + } + return false; + } + primeSummonData(summonDataPrimer: PokemonSummonData): void { this.summonDataPrimer = summonDataPrimer; } @@ -3646,7 +3725,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const pixel = pixelData[f].slice(i, i + 4); let [ r, g, b, a ] = pixel; if (variantColors) { - const color = Utils.rgbaToInt([r, g, b, a]); + const color = Utils.rgbaToInt([ r, g, b, a ]); if (variantColorSet.has(color)) { const mappedPixel = variantColorSet.get(color); if (mappedPixel) { @@ -3690,7 +3769,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } let [ r, g, b, a ] = [ pixelData[2 + f][i], pixelData[2 + f][i + 1], pixelData[2 + f][i + 2], pixelData[2 + f][i + 3] ]; if (variantColors) { - const color = Utils.rgbaToInt([r, g, b, a]); + const color = Utils.rgbaToInt([ r, g, b, a ]); if (variantColorSet.has(color)) { const mappedPixel = variantColorSet.get(color); if (mappedPixel) { @@ -3931,16 +4010,20 @@ export class PlayerPokemon extends Pokemon { super(scene, 106, 148, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource); if (Overrides.STATUS_OVERRIDE) { - this.status = new Status(Overrides.STATUS_OVERRIDE); + this.status = new Status(Overrides.STATUS_OVERRIDE, 0, 4); } if (Overrides.SHINY_OVERRIDE) { this.shiny = true; this.initShinySparkle(); - if (Overrides.VARIANT_OVERRIDE) { - this.variant = Overrides.VARIANT_OVERRIDE; - } + } else if (Overrides.SHINY_OVERRIDE === false) { + this.shiny = false; } + + if (Overrides.VARIANT_OVERRIDE !== null && this.shiny) { + this.variant = Overrides.VARIANT_OVERRIDE; + } + if (!dataSource) { if (this.scene.gameMode.isDaily) { this.generateAndPopulateMoveset(); @@ -3985,7 +4068,7 @@ export class PlayerPokemon extends Pokemon { let compatible = false; for (const p of tmSpecies[tm]) { if (Array.isArray(p)) { - const [pkm, form] = p; + const [ pkm, form ] = p; if ((pkm === this.species.speciesId || this.fusionSpecies && pkm === this.fusionSpecies.speciesId) && form === this.getFormKey()) { compatible = true; break; @@ -4042,7 +4125,11 @@ export class PlayerPokemon extends Pokemon { fusionStarterSpeciesId ? this.scene.gameData.starterData[fusionStarterSpeciesId] : null ].filter(d => !!d); const amount = new Utils.IntegerHolder(friendship); - const starterAmount = new Utils.IntegerHolder(Math.floor(friendship * (this.scene.gameMode.isClassic && friendship > 0 ? 2 : 1) / (fusionStarterSpeciesId ? 2 : 1))); + let candyFriendshipMultiplier = CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER; + if (this.scene.eventManager.isEventActive()) { + candyFriendshipMultiplier *= this.scene.eventManager.getFriendshipMultiplier(); + } + const starterAmount = new Utils.IntegerHolder(Math.floor(friendship * (this.scene.gameMode.isClassic && friendship > 0 ? candyFriendshipMultiplier : 1) / (fusionStarterSpeciesId ? 2 : 1))); if (amount.value > 0) { this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount); this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, starterAmount); @@ -4074,7 +4161,7 @@ export class PlayerPokemon extends Pokemon { revivalBlessing(): Promise { return new Promise(resolve => { this.scene.ui.setMode(Mode.PARTY, PartyUiMode.REVIVAL_BLESSING, this.getFieldIndex(), (slotIndex:integer, option: PartyOption) => { - if (slotIndex >= 0 && slotIndex<6) { + if (slotIndex >= 0 && slotIndex < 6) { const pokemon = this.scene.getParty()[slotIndex]; if (!pokemon || !pokemon.isFainted()) { resolve(); @@ -4083,11 +4170,11 @@ export class PlayerPokemon extends Pokemon { pokemon.resetTurnData(); pokemon.resetStatus(); pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp())); - this.scene.queueMessage(i18next.t("moveTriggers:revivalBlessing", {pokemonName: pokemon.name}), 0, true); + this.scene.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: pokemon.name }), 0, true); if (this.scene.currentBattle.double && this.scene.getParty().length > 1) { const allyPokemon = this.getAlly(); - if (slotIndex<=1) { + if (slotIndex <= 1) { // Revived ally pokemon this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, SwitchType.SWITCH, pokemon.getFieldIndex(), slotIndex, false, true)); this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true)); @@ -4154,7 +4241,7 @@ export class PlayerPokemon extends Pokemon { if (!isFusion) { const abilityCount = this.getSpeciesForm().getAbilityCount(); const preEvoAbilityCount = preEvolution.getAbilityCount(); - if ([0, 1, 2].includes(this.abilityIndex)) { + if ([ 0, 1, 2 ].includes(this.abilityIndex)) { // Handles cases where a Pokemon with 3 abilities evolves into a Pokemon with 2 abilities (ie: Eevee -> any Eeveelution) if (this.abilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) { this.abilityIndex = 1; @@ -4167,7 +4254,7 @@ export class PlayerPokemon extends Pokemon { } else { // Do the same as above, but for fusions const abilityCount = this.getFusionSpeciesForm().getAbilityCount(); const preEvoAbilityCount = preEvolution.getAbilityCount(); - if ([0, 1, 2].includes(this.fusionAbilityIndex)) { + if ([ 0, 1, 2 ].includes(this.fusionAbilityIndex)) { if (this.fusionAbilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) { this.fusionAbilityIndex = 1; } @@ -4210,7 +4297,6 @@ export class PlayerPokemon extends Pokemon { if (newEvolution.condition?.predicate(this)) { const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, undefined, this.shiny, this.variant, this.ivs, this.nature); - newPokemon.natureOverride = this.natureOverride; newPokemon.passive = this.passive; newPokemon.moveset = this.moveset.slice(); newPokemon.moveset = this.copyMoveset(); @@ -4252,12 +4338,33 @@ export class PlayerPokemon extends Pokemon { changeForm(formChange: SpeciesFormChange): Promise { return new Promise(resolve => { + const previousFormIndex = this.formIndex; this.formIndex = Math.max(this.species.forms.findIndex(f => f.formKey === formChange.formKey), 0); this.generateName(); const abilityCount = this.getSpeciesForm().getAbilityCount(); if (this.abilityIndex >= abilityCount) { // Shouldn't happen this.abilityIndex = abilityCount - 1; } + + // In cases where a form change updates the type of a Pokemon from its previous form (Arceus, Silvally, Castform, etc.), + // persist that type change in customPokemonData if necessary + const baseForm = this.species.forms[previousFormIndex]; + const baseFormTypes = [ baseForm.type1, baseForm.type2 ]; + if (this.customPokemonData.types.length > 0) { + if (this.getSpeciesForm().type1 !== baseFormTypes[0]) { + this.customPokemonData.types[0] = this.getSpeciesForm().type1; + } + + const type2 = this.getSpeciesForm().type2; + if (!isNullOrUndefined(type2) && type2 !== baseFormTypes[1]) { + if (this.customPokemonData.types.length > 1) { + this.customPokemonData.types[1] = type2; + } else { + this.customPokemonData.types.push(type2); + } + } + } + this.compatibleTms.splice(0, this.compatibleTms.length); this.generateCompatibleTms(); const updateAndResolve = () => { @@ -4294,7 +4401,7 @@ export class PlayerPokemon extends Pokemon { this.fusionVariant = pokemon.variant; this.fusionGender = pokemon.gender; this.fusionLuck = pokemon.luck; - this.fusionMysteryEncounterPokemonData = pokemon.mysteryEncounterPokemonData; + this.fusionCustomPokemonData = pokemon.customPokemonData; if ((pokemon.pauseEvolutions) || (this.pauseEvolutions)) { this.pauseEvolutions = true; } @@ -4339,7 +4446,7 @@ export class PlayerPokemon extends Pokemon { this.scene.removePartyMemberModifiers(fusedPartyMemberIndex); this.scene.getParty().splice(fusedPartyMemberIndex, 1)[0]; const newPartyMemberIndex = this.scene.getParty().indexOf(this); - pokemon.getMoveset(true).map(m => this.scene.unshiftPhase(new LearnMovePhase(this.scene, newPartyMemberIndex, m!.getMove().id))); // TODO: is the bang correct? + pokemon.getMoveset(true).map((m: PokemonMove) => this.scene.unshiftPhase(new LearnMovePhase(this.scene, newPartyMemberIndex, m.getMove().id))); pokemon.destroy(); this.updateFusionPalette(); resolve(); @@ -4360,8 +4467,12 @@ export class PlayerPokemon extends Pokemon { /** Returns a deep copy of this Pokemon's moveset array */ copyMoveset(): PokemonMove[] { const newMoveset : PokemonMove[] = []; - this.moveset.forEach(move => - newMoveset.push(new PokemonMove(move!.moveId, 0, move!.ppUp, move!.virtual))); // TODO: are those bangs correct? + this.moveset.forEach((move) => { + // TODO: refactor `moveset` to not accept `null`s + if (move) { + newMoveset.push(new PokemonMove(move.moveId, 0, move.ppUp, move.virtual, move.maxPpOverride)); + } + }); return newMoveset; } @@ -4386,7 +4497,7 @@ export class EnemyPokemon extends Pokemon { } if (Overrides.OPP_STATUS_OVERRIDE) { - this.status = new Status(Overrides.OPP_STATUS_OVERRIDE); + this.status = new Status(Overrides.OPP_STATUS_OVERRIDE, 0, 4); } if (Overrides.OPP_GENDER_OVERRIDE) { @@ -4395,9 +4506,11 @@ export class EnemyPokemon extends Pokemon { const speciesId = this.species.speciesId; - if (speciesId in Overrides.OPP_FORM_OVERRIDES + if ( + speciesId in Overrides.OPP_FORM_OVERRIDES && Overrides.OPP_FORM_OVERRIDES[speciesId] - && this.species.forms[Overrides.OPP_FORM_OVERRIDES[speciesId]]) { + && this.species.forms[Overrides.OPP_FORM_OVERRIDES[speciesId]] + ) { this.formIndex = Overrides.OPP_FORM_OVERRIDES[speciesId] ?? 0; } @@ -4408,10 +4521,13 @@ export class EnemyPokemon extends Pokemon { if (Overrides.OPP_SHINY_OVERRIDE) { this.shiny = true; this.initShinySparkle(); + } else if (Overrides.OPP_SHINY_OVERRIDE === false) { + this.shiny = false; } + if (this.shiny) { this.variant = this.generateVariant(); - if (Overrides.OPP_VARIANT_OVERRIDE) { + if (Overrides.OPP_VARIANT_OVERRIDE !== null) { this.variant = Overrides.OPP_VARIANT_OVERRIDE; } } @@ -4461,35 +4577,35 @@ export class EnemyPokemon extends Pokemon { generateAndPopulateMoveset(formIndex?: integer): void { switch (true) { - case (this.species.speciesId === Species.SMEARGLE): - this.moveset = [ - new PokemonMove(Moves.SKETCH), - new PokemonMove(Moves.SKETCH), - new PokemonMove(Moves.SKETCH), - new PokemonMove(Moves.SKETCH) - ]; - break; - case (this.species.speciesId === Species.ETERNATUS): - this.moveset = (formIndex !== undefined ? formIndex : this.formIndex) - ? [ - new PokemonMove(Moves.DYNAMAX_CANNON), - new PokemonMove(Moves.CROSS_POISON), - new PokemonMove(Moves.FLAMETHROWER), - new PokemonMove(Moves.RECOVER, 0, -4) - ] - : [ - new PokemonMove(Moves.ETERNABEAM), - new PokemonMove(Moves.SLUDGE_BOMB), - new PokemonMove(Moves.FLAMETHROWER), - new PokemonMove(Moves.COSMIC_POWER) + case (this.species.speciesId === Species.SMEARGLE): + this.moveset = [ + new PokemonMove(Moves.SKETCH), + new PokemonMove(Moves.SKETCH), + new PokemonMove(Moves.SKETCH), + new PokemonMove(Moves.SKETCH) ]; - if (this.scene.gameMode.hasChallenge(Challenges.INVERSE_BATTLE)) { - this.moveset[2] = new PokemonMove(Moves.THUNDERBOLT); - } - break; - default: - super.generateAndPopulateMoveset(); - break; + break; + case (this.species.speciesId === Species.ETERNATUS): + this.moveset = (formIndex !== undefined ? formIndex : this.formIndex) + ? [ + new PokemonMove(Moves.DYNAMAX_CANNON), + new PokemonMove(Moves.CROSS_POISON), + new PokemonMove(Moves.FLAMETHROWER), + new PokemonMove(Moves.RECOVER, 0, -4) + ] + : [ + new PokemonMove(Moves.ETERNABEAM), + new PokemonMove(Moves.SLUDGE_BOMB), + new PokemonMove(Moves.FLAMETHROWER), + new PokemonMove(Moves.COSMIC_POWER) + ]; + if (this.scene.gameMode.hasChallenge(Challenges.INVERSE_BATTLE)) { + this.moveset[2] = new PokemonMove(Moves.THUNDERBOLT); + } + break; + default: + super.generateAndPopulateMoveset(); + break; } } @@ -4529,135 +4645,135 @@ export class EnemyPokemon extends Pokemon { } } switch (this.aiType) { - case AiType.RANDOM: // No enemy should spawn with this AI type in-game - const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)]!.moveId; // TODO: is the bang correct? - return { move: moveId, targets: this.getNextTargets(moveId) }; - case AiType.SMART_RANDOM: - case AiType.SMART: + case AiType.RANDOM: // No enemy should spawn with this AI type in-game + const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)]!.moveId; // TODO: is the bang correct? + return { move: moveId, targets: this.getNextTargets(moveId) }; + case AiType.SMART_RANDOM: + case AiType.SMART: /** * Search this Pokemon's move pool for moves that will KO an opposing target. * If there are any moves that can KO an opponent (i.e. a player Pokemon), * those moves are the only ones considered for selection on this turn. */ - const koMoves = movePool.filter(pkmnMove => { - if (!pkmnMove) { - return false; - } + const koMoves = movePool.filter(pkmnMove => { + if (!pkmnMove) { + return false; + } - const move = pkmnMove.getMove()!; - if (move.moveTarget === MoveTarget.ATTACKER) { - return false; - } + const move = pkmnMove.getMove()!; + if (move.moveTarget === MoveTarget.ATTACKER) { + return false; + } - const fieldPokemon = this.scene.getField(); - const moveTargets = getMoveTargets(this, move.id).targets - .map(ind => fieldPokemon[ind]) - .filter(p => this.isPlayer() !== p.isPlayer()); - // Only considers critical hits for crit-only moves or when this Pokemon is under the effect of Laser Focus - const isCritical = move.hasAttr(CritOnlyAttr) || !!this.getTag(BattlerTagType.ALWAYS_CRIT); + const fieldPokemon = this.scene.getField(); + const moveTargets = getMoveTargets(this, move.id).targets + .map(ind => fieldPokemon[ind]) + .filter(p => this.isPlayer() !== p.isPlayer()); + // Only considers critical hits for crit-only moves or when this Pokemon is under the effect of Laser Focus + const isCritical = move.hasAttr(CritOnlyAttr) || !!this.getTag(BattlerTagType.ALWAYS_CRIT); - return move.category !== MoveCategory.STATUS + return move.category !== MoveCategory.STATUS && moveTargets.some(p => { - const doesNotFail = move.applyConditions(this, p, move) || [Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id); + const doesNotFail = move.applyConditions(this, p, move) || [ Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP ].includes(move.id); return doesNotFail && p.getAttackDamage(this, move, !p.battleData.abilityRevealed, false, isCritical).damage >= p.hp; }); - }, this); + }, this); - if (koMoves.length > 0) { - movePool = koMoves; - } + if (koMoves.length > 0) { + movePool = koMoves; + } - /** + /** * Move selection is based on the move's calculated "benefit score" against the * best possible target(s) (as determined by {@linkcode getNextTargets}). * For more information on how benefit scores are calculated, see `docs/enemy-ai.md`. */ - const moveScores = movePool.map(() => 0); - const moveTargets = Object.fromEntries(movePool.map(m => [ m!.moveId, this.getNextTargets(m!.moveId) ])); // TODO: are those bangs correct? - for (const m in movePool) { - const pokemonMove = movePool[m]!; // TODO: is the bang correct? - const move = pokemonMove.getMove(); + const moveScores = movePool.map(() => 0); + const moveTargets = Object.fromEntries(movePool.map(m => [ m!.moveId, this.getNextTargets(m!.moveId) ])); // TODO: are those bangs correct? + for (const m in movePool) { + const pokemonMove = movePool[m]!; // TODO: is the bang correct? + const move = pokemonMove.getMove(); - let moveScore = moveScores[m]; - const targetScores: integer[] = []; + let moveScore = moveScores[m]; + const targetScores: integer[] = []; - for (const mt of moveTargets[move.id]) { + for (const mt of moveTargets[move.id]) { // Prevent a target score from being calculated when the target is whoever attacks the user - if (mt === BattlerIndex.ATTACKER) { - break; - } + if (mt === BattlerIndex.ATTACKER) { + break; + } - const target = this.scene.getField()[mt]; - /** + const target = this.scene.getField()[mt]; + /** * The "target score" of a move is given by the move's user benefit score + the move's target benefit score. * If the target is an ally, the target benefit score is multiplied by -1. */ - let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1); - if (Number.isNaN(targetScore)) { - console.error(`Move ${move.name} returned score of NaN`); - targetScore = 0; - } - /** + let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1); + if (Number.isNaN(targetScore)) { + console.error(`Move ${move.name} returned score of NaN`); + targetScore = 0; + } + /** * If this move is unimplemented, or the move is known to fail when used, set its * target score to -20 */ - if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id)) { - targetScore = -20; - } else if (move instanceof AttackMove) { + if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![ Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP ].includes(move.id)) { + targetScore = -20; + } else if (move instanceof AttackMove) { /** * Attack moves are given extra multipliers to their base benefit score based on * the move's type effectiveness against the target and whether the move is a STAB move. */ - const effectiveness = target.getMoveEffectiveness(this, move, !target.battleData?.abilityRevealed); - if (target.isPlayer() !== this.isPlayer()) { - targetScore *= effectiveness; - if (this.isOfType(move.type)) { - targetScore *= 1.5; + const effectiveness = target.getMoveEffectiveness(this, move, !target.battleData?.abilityRevealed); + if (target.isPlayer() !== this.isPlayer()) { + targetScore *= effectiveness; + if (this.isOfType(move.type)) { + targetScore *= 1.5; + } + } else if (effectiveness) { + targetScore /= effectiveness; + if (this.isOfType(move.type)) { + targetScore /= 1.5; + } } - } else if (effectiveness) { - targetScore /= effectiveness; - if (this.isOfType(move.type)) { - targetScore /= 1.5; + /** If a move has a base benefit score of 0, its benefit score is assumed to be unimplemented at this point */ + if (!targetScore) { + targetScore = -20; } } - /** If a move has a base benefit score of 0, its benefit score is assumed to be unimplemented at this point */ - if (!targetScore) { - targetScore = -20; - } + targetScores.push(targetScore); } - targetScores.push(targetScore); + // When a move has multiple targets, its score is equal to the maximum target score across all targets + moveScore += Math.max(...targetScores); + + // could make smarter by checking opponent def/spdef + moveScores[m] = moveScore; } - // When a move has multiple targets, its score is equal to the maximum target score across all targets - moveScore += Math.max(...targetScores); - // could make smarter by checking opponent def/spdef - moveScores[m] = moveScore; - } + console.log(moveScores); - console.log(moveScores); - - // Sort the move pool in decreasing order of move score - const sortedMovePool = movePool.slice(0); - sortedMovePool.sort((a, b) => { - const scoreA = moveScores[movePool.indexOf(a)]; - const scoreB = moveScores[movePool.indexOf(b)]; - return scoreA < scoreB ? 1 : scoreA > scoreB ? -1 : 0; - }); - let r = 0; - if (this.aiType === AiType.SMART_RANDOM) { + // Sort the move pool in decreasing order of move score + const sortedMovePool = movePool.slice(0); + sortedMovePool.sort((a, b) => { + const scoreA = moveScores[movePool.indexOf(a)]; + const scoreB = moveScores[movePool.indexOf(b)]; + return scoreA < scoreB ? 1 : scoreA > scoreB ? -1 : 0; + }); + let r = 0; + if (this.aiType === AiType.SMART_RANDOM) { // Has a 5/8 chance to select the best move, and a 3/8 chance to advance to the next best move (and repeat this roll) - while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8) >= 5) { - r++; - } - } else if (this.aiType === AiType.SMART) { + while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8) >= 5) { + r++; + } + } else if (this.aiType === AiType.SMART) { // The chance to advance to the next best move increases when the compared moves' scores are closer to each other. - while (r < sortedMovePool.length - 1 && (moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) >= 0 + while (r < sortedMovePool.length - 1 && (moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) >= 0 && this.scene.randBattleSeedInt(100) < Math.round((moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) * 50)) { - r++; + r++; + } } - } - console.log(movePool.map(m => m!.getName()), moveScores, r, sortedMovePool.map(m => m!.getName())); // TODO: are those bangs correct? - return { move: sortedMovePool[r]!.moveId, targets: moveTargets[sortedMovePool[r]!.moveId] }; + console.log(movePool.map(m => m!.getName()), moveScores, r, sortedMovePool.map(m => m!.getName())); // TODO: are those bangs correct? + return { move: sortedMovePool[r]!.moveId, targets: moveTargets[sortedMovePool[r]!.moveId] }; } } @@ -4697,7 +4813,7 @@ export class EnemyPokemon extends Pokemon { // Set target to BattlerIndex.ATTACKER when using a counter move // This is the same as when the player does so if (move.hasAttr(CounterDamageAttr)) { - return [BattlerIndex.ATTACKER]; + return [ BattlerIndex.ATTACKER ]; } return []; @@ -4805,10 +4921,10 @@ export class EnemyPokemon extends Pokemon { } switch (this.scene.currentBattle.battleSpec) { - case BattleSpec.FINAL_BOSS: - if (!this.formIndex && this.bossSegmentIndex < 1) { - damage = Math.min(damage, this.hp - 1); - } + case BattleSpec.FINAL_BOSS: + if (!this.formIndex && this.bossSegmentIndex < 1) { + damage = Math.min(damage, this.hp - 1); + } } const ret = super.damage(damage, ignoreSegments, preventEndure, ignoreFaintPhase); @@ -4989,6 +5105,7 @@ export class PokemonSummonData { public moveset: (PokemonMove | null)[]; // If not initialized this value will not be populated from save data. public types: Type[] = []; + public addedType: Type | null = null; } export class PokemonBattleData { @@ -5011,8 +5128,12 @@ export class PokemonBattleSummonData { export class PokemonTurnData { public flinched: boolean = false; public acted: boolean = false; - public hitCount: number; - public hitsLeft: number; + public hitCount: number = 0; + /** + * - `-1` = Calculate how many hits are left + * - `0` = Move is finished + */ + public hitsLeft: number = -1; public damageDealt: number = 0; public currDamageDealt: number = 0; public damageTaken: number = 0; @@ -5021,6 +5142,9 @@ export class PokemonTurnData { public statStagesIncreased: boolean = false; public statStagesDecreased: boolean = false; public moveEffectiveness: TypeDamageMultiplier | null = null; + public combiningPledge?: Moves; + public switchedInThisTurn: boolean = false; + public failedRunAway: boolean = false; } export enum AiType { @@ -5078,15 +5202,22 @@ export interface DamageCalculationResult { **/ export class PokemonMove { public moveId: Moves; - public ppUsed: integer; - public ppUp: integer; + public ppUsed: number; + public ppUp: number; public virtual: boolean; - constructor(moveId: Moves, ppUsed?: integer, ppUp?: integer, virtual?: boolean) { + /** + * If defined and nonzero, overrides the maximum PP of the move (e.g., due to move being copied by Transform). + * This also nullifies all effects of `ppUp`. + */ + public maxPpOverride?: number; + + constructor(moveId: Moves, ppUsed: number = 0, ppUp: number = 0, virtual: boolean = false, maxPpOverride?: number) { this.moveId = moveId; - this.ppUsed = ppUsed || 0; - this.ppUp = ppUp || 0; - this.virtual = !!virtual; + this.ppUsed = ppUsed; + this.ppUp = ppUp; + this.virtual = virtual; + this.maxPpOverride = maxPpOverride; } /** @@ -5098,8 +5229,8 @@ export class PokemonMove { * @param {boolean} ignoreRestrictionTags If `true`, skips the check for move restriction tags (see {@link MoveRestrictionBattlerTag}) * @returns `true` if the move can be selected and used by the Pokemon, otherwise `false`. */ - isUsable(pokemon: Pokemon, ignorePp?: boolean, ignoreRestrictionTags?: boolean): boolean { - if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId)) { + isUsable(pokemon: Pokemon, ignorePp: boolean = false, ignoreRestrictionTags: boolean = false): boolean { + if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId, pokemon)) { return false; } @@ -5123,7 +5254,7 @@ export class PokemonMove { } getMovePp(): integer { - return this.getMove().pp + this.ppUp * Utils.toDmgValue(this.getMove().pp / 5); + return this.maxPpOverride || (this.getMove().pp + this.ppUp * Utils.toDmgValue(this.getMove().pp / 5)); } getPpRatio(): number { @@ -5140,6 +5271,6 @@ export class PokemonMove { * @return {PokemonMove} A valid pokemonmove object */ static loadMove(source: PokemonMove | any): PokemonMove { - return new PokemonMove(source.moveId, source.ppUsed, source.ppUp, source.virtual); + return new PokemonMove(source.moveId, source.ppUsed, source.ppUp, source.virtual, source.maxPpOverride); } } diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 1023802134a..4c1432b15f0 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -1,6 +1,6 @@ import BattleScene from "#app/battle-scene"; -import {pokemonPrevolutions} from "#app/data/balance/pokemon-evolutions"; -import PokemonSpecies, {getPokemonSpecies} from "#app/data/pokemon-species"; +import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; +import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species"; import { TrainerConfig, TrainerPartyCompoundTemplate, @@ -11,7 +11,7 @@ import { trainerPartyTemplates, signatureSpecies } from "#app/data/trainer-config"; -import {EnemyPokemon} from "#app/field/pokemon"; +import { EnemyPokemon } from "#app/field/pokemon"; import * as Utils from "#app/utils"; import { PersistentModifier } from "#app/modifier/modifier"; import { trainerNamePools } from "#app/data/trainer-names"; @@ -56,7 +56,7 @@ export default class Trainer extends Phaser.GameObjects.Container { if (partnerName) { this.partnerName = partnerName; } else { - [this.name, this.partnerName] = this.name.split(" & "); + [ this.name, this.partnerName ] = this.name.split(" & "); } } else { this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool); @@ -65,16 +65,16 @@ export default class Trainer extends Phaser.GameObjects.Container { } switch (this.variant) { - case TrainerVariant.FEMALE: - if (!this.config.hasGenders) { - variant = TrainerVariant.DEFAULT; - } - break; - case TrainerVariant.DOUBLE: - if (!this.config.hasDouble) { - variant = TrainerVariant.DEFAULT; - } - break; + case TrainerVariant.FEMALE: + if (!this.config.hasGenders) { + variant = TrainerVariant.DEFAULT; + } + break; + case TrainerVariant.DOUBLE: + if (!this.config.hasDouble) { + variant = TrainerVariant.DEFAULT; + } + break; } console.log(Object.keys(trainerPartyTemplates)[Object.values(trainerPartyTemplates).indexOf(this.getPartyTemplate())]); @@ -82,7 +82,7 @@ export default class Trainer extends Phaser.GameObjects.Container { const getSprite = (hasShadow?: boolean, forceFemale?: boolean) => { const ret = this.scene.addFieldSprite(0, 0, this.config.getSpriteKey(variant === TrainerVariant.FEMALE || forceFemale, this.isDouble())); ret.setOrigin(0.5, 1); - ret.setPipeline(this.scene.spritePipeline, {tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow}); + ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow }); return ret; }; @@ -126,7 +126,7 @@ export default class Trainer extends Phaser.GameObjects.Container { // Determine the title to include based on the configuration and includeTitle flag. let title = includeTitle && this.config.title ? this.config.title : null; - const evilTeamTitles = ["grunt"]; + const evilTeamTitles = [ "grunt" ]; if (this.name === "" && evilTeamTitles.some(t => name.toLocaleLowerCase().includes(t))) { // This is a evil team grunt so we localize it by only using the "name" as the title title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`); @@ -229,21 +229,21 @@ export default class Trainer extends Phaser.GameObjects.Container { const strength = partyTemplate.getStrength(i); switch (strength) { - case PartyMemberStrength.WEAKER: - multiplier = 0.95; - break; - case PartyMemberStrength.WEAK: - multiplier = 1.0; - break; - case PartyMemberStrength.AVERAGE: - multiplier = 1.1; - break; - case PartyMemberStrength.STRONG: - multiplier = 1.2; - break; - case PartyMemberStrength.STRONGER: - multiplier = 1.25; - break; + case PartyMemberStrength.WEAKER: + multiplier = 0.95; + break; + case PartyMemberStrength.WEAK: + multiplier = 1.0; + break; + case PartyMemberStrength.AVERAGE: + multiplier = 1.1; + break; + case PartyMemberStrength.STRONG: + multiplier = 1.2; + break; + case PartyMemberStrength.STRONGER: + multiplier = 1.25; + break; } let levelOffset = 0; @@ -336,9 +336,9 @@ export default class Trainer extends Phaser.GameObjects.Container { if (!(index % 2)) { // Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza if (index === 0 && (TrainerType[this.config.trainerType] === TrainerType[TrainerType.TATE])) { - newSpeciesPool = [Species.SOLROCK]; + newSpeciesPool = [ Species.SOLROCK ]; } else if (index === 0 && (TrainerType[this.config.trainerType] === TrainerType[TrainerType.LIZA])) { - newSpeciesPool = [Species.LUNATONE]; + newSpeciesPool = [ Species.LUNATONE ]; } else { newSpeciesPool = speciesPoolFiltered; } @@ -346,9 +346,9 @@ export default class Trainer extends Phaser.GameObjects.Container { // If the index is odd, use the species pool for the partner trainer (that way he only uses his own pokemon in battle) // Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza if (index === 1 && (TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.TATE])) { - newSpeciesPool = [Species.SOLROCK]; + newSpeciesPool = [ Species.SOLROCK ]; } else if (index === 1 && (TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.LIZA])) { - newSpeciesPool = [Species.LUNATONE]; + newSpeciesPool = [ Species.LUNATONE ]; } else { newSpeciesPool = speciesPoolPartnerFiltered; } @@ -383,7 +383,7 @@ export default class Trainer extends Phaser.GameObjects.Container { const battle = this.scene.currentBattle; const template = this.getPartyTemplate(); - let species: PokemonSpecies; + let baseSpecies: PokemonSpecies; if (this.config.speciesPools) { const tierValue = Utils.randSeedInt(512); let tier = tierValue >= 156 ? TrainerPoolTier.COMMON : tierValue >= 32 ? TrainerPoolTier.UNCOMMON : tierValue >= 6 ? TrainerPoolTier.RARE : tierValue >= 1 ? TrainerPoolTier.SUPER_RARE : TrainerPoolTier.ULTRA_RARE; @@ -393,17 +393,17 @@ export default class Trainer extends Phaser.GameObjects.Container { tier--; } const tierPool = this.config.speciesPools[tier]; - species = getPokemonSpecies(Utils.randSeedItem(tierPool)); + baseSpecies = getPokemonSpecies(Utils.randSeedItem(tierPool)); } else { - species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter); + baseSpecies = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter); } - let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex)); + let ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex)); let retry = false; console.log(ret.getName()); - if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId) { + if (pokemonPrevolutions.hasOwnProperty(baseSpecies.speciesId) && ret.speciesId !== baseSpecies.speciesId) { retry = true; } else if (template.isBalanced(battle.enemyParty.length)) { const partyMemberTypes = battle.enemyParty.map(p => p.getTypes(true)).flat(); @@ -417,7 +417,7 @@ export default class Trainer extends Phaser.GameObjects.Container { console.log("Attempting reroll of species evolution to fit specialty type..."); let evoAttempt = 0; while (retry && evoAttempt++ < 10) { - ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex)); + ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex)); console.log(ret.name); if (ret.isOfType(this.config.specialtyType)) { retry = false; @@ -426,7 +426,7 @@ export default class Trainer extends Phaser.GameObjects.Container { } // Prompts reroll of party member species if species already present in the enemy party - if (this.checkDuplicateSpecies(ret)) { + if (this.checkDuplicateSpecies(ret, baseSpecies)) { console.log("Duplicate species detected, prompting reroll..."); retry = true; } @@ -442,13 +442,16 @@ export default class Trainer extends Phaser.GameObjects.Container { /** * Checks if the enemy trainer already has the Pokemon species in their party * @param {PokemonSpecies} species {@linkcode PokemonSpecies} + * @param {PokemonSpecies} baseSpecies {@linkcode PokemonSpecies} - baseSpecies of the Pokemon if species is forced to evolve * @returns `true` if the species is already present in the party */ - checkDuplicateSpecies(species: PokemonSpecies): boolean { + checkDuplicateSpecies(species: PokemonSpecies, baseSpecies: PokemonSpecies): boolean { + const staticPartyPokemon = (signatureSpecies[TrainerType[this.config.trainerType]] ?? []).flat(1); + const currentPartySpecies = this.scene.getEnemyParty().map(p => { return p.species.speciesId; }); - return currentPartySpecies.includes(species.speciesId); + return currentPartySpecies.includes(species.speciesId) || staticPartyPokemon.includes(baseSpecies.speciesId); } getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE, forSwitch: boolean = false): [integer, integer][] { @@ -475,7 +478,7 @@ export default class Trainer extends Phaser.GameObjects.Container { } } - return [party.indexOf(p), score]; + return [ party.indexOf(p), score ]; }) as [integer, integer][]; return partyMemberScores; @@ -512,19 +515,19 @@ export default class Trainer extends Phaser.GameObjects.Container { getPartyMemberModifierChanceMultiplier(index: integer): number { switch (this.getPartyTemplate().getStrength(index)) { - case PartyMemberStrength.WEAKER: - return 0.75; - case PartyMemberStrength.WEAK: - return 0.675; - case PartyMemberStrength.AVERAGE: - return 0.5625; - case PartyMemberStrength.STRONG: - return 0.45; - case PartyMemberStrength.STRONGER: - return 0.375; - default: - console.warn("getPartyMemberModifierChanceMultiplier not defined. Using default 0"); - return 0; + case PartyMemberStrength.WEAKER: + return 0.75; + case PartyMemberStrength.WEAK: + return 0.675; + case PartyMemberStrength.AVERAGE: + return 0.5625; + case PartyMemberStrength.STRONG: + return 0.45; + case PartyMemberStrength.STRONGER: + return 0.375; + default: + console.warn("getPartyMemberModifierChanceMultiplier not defined. Using default 0"); + return 0; } } diff --git a/src/game-mode.ts b/src/game-mode.ts index 525c975a19b..8f1bb9356e6 100644 --- a/src/game-mode.ts +++ b/src/game-mode.ts @@ -33,8 +33,8 @@ interface GameModeConfig { } // Describes min and max waves for MEs in specific game modes -export const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180]; -export const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180]; +export const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [ 10, 180 ]; +export const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [ 10, 180 ]; export class GameMode implements GameModeConfig { public modeId: GameModes; @@ -92,10 +92,10 @@ export class GameMode implements GameModeConfig { return Overrides.STARTING_LEVEL_OVERRIDE; } switch (this.modeId) { - case GameModes.DAILY: - return 20; - default: - return 5; + case GameModes.DAILY: + return 20; + default: + return 5; } } @@ -117,19 +117,19 @@ export class GameMode implements GameModeConfig { */ getStartingBiome(scene: BattleScene): Biome { switch (this.modeId) { - case GameModes.DAILY: - return scene.generateRandomBiome(this.getWaveForDifficulty(1)); - default: - return Overrides.STARTING_BIOME_OVERRIDE || Biome.TOWN; + case GameModes.DAILY: + return scene.generateRandomBiome(this.getWaveForDifficulty(1)); + default: + return Overrides.STARTING_BIOME_OVERRIDE || Biome.TOWN; } } getWaveForDifficulty(waveIndex: integer, ignoreCurveChanges: boolean = false): integer { switch (this.modeId) { - case GameModes.DAILY: - return waveIndex + 30 + (!ignoreCurveChanges ? Math.floor(waveIndex / 5) : 0); - default: - return waveIndex; + case GameModes.DAILY: + return waveIndex + 30 + (!ignoreCurveChanges ? Math.floor(waveIndex / 5) : 0); + default: + return waveIndex; } } @@ -186,10 +186,10 @@ export class GameMode implements GameModeConfig { isTrainerBoss(waveIndex: integer, biomeType: Biome, offsetGym: boolean): boolean { switch (this.modeId) { - case GameModes.DAILY: - return waveIndex > 10 && waveIndex < 50 && !(waveIndex % 10); - default: - return (waveIndex % 30) === (offsetGym ? 0 : 20) && (biomeType !== Biome.END || this.isClassic || this.isWaveFinal(waveIndex)); + case GameModes.DAILY: + return waveIndex > 10 && waveIndex < 50 && !(waveIndex % 10); + default: + return (waveIndex % 30) === (offsetGym ? 0 : 20) && (biomeType !== Biome.END || this.isClassic || this.isWaveFinal(waveIndex)); } } @@ -211,14 +211,14 @@ export class GameMode implements GameModeConfig { */ isWaveFinal(waveIndex: integer, modeId: GameModes = this.modeId): boolean { switch (modeId) { - case GameModes.CLASSIC: - case GameModes.CHALLENGE: - return waveIndex === 200; - case GameModes.ENDLESS: - case GameModes.SPLICED_ENDLESS: - return !(waveIndex % 250); - case GameModes.DAILY: - return waveIndex === 50; + case GameModes.CLASSIC: + case GameModes.CHALLENGE: + return waveIndex === 200; + case GameModes.ENDLESS: + case GameModes.SPLICED_ENDLESS: + return !(waveIndex % 250); + case GameModes.DAILY: + return waveIndex === 50; } } @@ -287,40 +287,40 @@ export class GameMode implements GameModeConfig { getClearScoreBonus(): integer { switch (this.modeId) { - case GameModes.CLASSIC: - case GameModes.CHALLENGE: - return 5000; - case GameModes.DAILY: - return 2500; - default: - return 0; + case GameModes.CLASSIC: + case GameModes.CHALLENGE: + return 5000; + case GameModes.DAILY: + return 2500; + default: + return 0; } } getEnemyModifierChance(isBoss: boolean): integer { switch (this.modeId) { - case GameModes.CLASSIC: - case GameModes.CHALLENGE: - case GameModes.DAILY: - return !isBoss ? 18 : 6; - case GameModes.ENDLESS: - case GameModes.SPLICED_ENDLESS: - return !isBoss ? 12 : 4; + case GameModes.CLASSIC: + case GameModes.CHALLENGE: + case GameModes.DAILY: + return !isBoss ? 18 : 6; + case GameModes.ENDLESS: + case GameModes.SPLICED_ENDLESS: + return !isBoss ? 12 : 4; } } getName(): string { switch (this.modeId) { - case GameModes.CLASSIC: - return i18next.t("gameMode:classic"); - case GameModes.ENDLESS: - return i18next.t("gameMode:endless"); - case GameModes.SPLICED_ENDLESS: - return i18next.t("gameMode:endlessSpliced"); - case GameModes.DAILY: - return i18next.t("gameMode:dailyRun"); - case GameModes.CHALLENGE: - return i18next.t("gameMode:challenge"); + case GameModes.CLASSIC: + return i18next.t("gameMode:classic"); + case GameModes.ENDLESS: + return i18next.t("gameMode:endless"); + case GameModes.SPLICED_ENDLESS: + return i18next.t("gameMode:endlessSpliced"); + case GameModes.DAILY: + return i18next.t("gameMode:dailyRun"); + case GameModes.CHALLENGE: + return i18next.t("gameMode:challenge"); } } @@ -329,42 +329,42 @@ export class GameMode implements GameModeConfig { */ getMysteryEncounterLegalWaves(): [number, number] { switch (this.modeId) { - default: - return [0, 0]; - case GameModes.CLASSIC: - return CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES; - case GameModes.CHALLENGE: - return CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES; + default: + return [ 0, 0 ]; + case GameModes.CLASSIC: + return CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES; + case GameModes.CHALLENGE: + return CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES; } } static getModeName(modeId: GameModes): string { switch (modeId) { - case GameModes.CLASSIC: - return i18next.t("gameMode:classic"); - case GameModes.ENDLESS: - return i18next.t("gameMode:endless"); - case GameModes.SPLICED_ENDLESS: - return i18next.t("gameMode:endlessSpliced"); - case GameModes.DAILY: - return i18next.t("gameMode:dailyRun"); - case GameModes.CHALLENGE: - return i18next.t("gameMode:challenge"); + case GameModes.CLASSIC: + return i18next.t("gameMode:classic"); + case GameModes.ENDLESS: + return i18next.t("gameMode:endless"); + case GameModes.SPLICED_ENDLESS: + return i18next.t("gameMode:endlessSpliced"); + case GameModes.DAILY: + return i18next.t("gameMode:dailyRun"); + case GameModes.CHALLENGE: + return i18next.t("gameMode:challenge"); } } } export function getGameMode(gameMode: GameModes): GameMode { switch (gameMode) { - case GameModes.CLASSIC: - return new GameMode(GameModes.CLASSIC, { isClassic: true, hasTrainers: true, hasMysteryEncounters: true }, classicFixedBattles); - case GameModes.ENDLESS: - return new GameMode(GameModes.ENDLESS, { isEndless: true, hasShortBiomes: true, hasRandomBosses: true }); - case GameModes.SPLICED_ENDLESS: - return new GameMode(GameModes.SPLICED_ENDLESS, { isEndless: true, hasShortBiomes: true, hasRandomBosses: true, isSplicedOnly: true }); - case GameModes.DAILY: - return new GameMode(GameModes.DAILY, { isDaily: true, hasTrainers: true, hasNoShop: true }); - case GameModes.CHALLENGE: - return new GameMode(GameModes.CHALLENGE, { isClassic: true, hasTrainers: true, isChallenge: true, hasMysteryEncounters: true }, classicFixedBattles); + case GameModes.CLASSIC: + return new GameMode(GameModes.CLASSIC, { isClassic: true, hasTrainers: true, hasMysteryEncounters: true }, classicFixedBattles); + case GameModes.ENDLESS: + return new GameMode(GameModes.ENDLESS, { isEndless: true, hasShortBiomes: true, hasRandomBosses: true }); + case GameModes.SPLICED_ENDLESS: + return new GameMode(GameModes.SPLICED_ENDLESS, { isEndless: true, hasShortBiomes: true, hasRandomBosses: true, isSplicedOnly: true }); + case GameModes.DAILY: + return new GameMode(GameModes.DAILY, { isDaily: true, hasTrainers: true, hasNoShop: true }); + case GameModes.CHALLENGE: + return new GameMode(GameModes.CHALLENGE, { isClassic: true, hasTrainers: true, isChallenge: true, hasMysteryEncounters: true }, classicFixedBattles); } } diff --git a/src/inputs-controller.ts b/src/inputs-controller.ts index bb3cfcbeb3b..537d2870259 100644 --- a/src/inputs-controller.ts +++ b/src/inputs-controller.ts @@ -1,12 +1,12 @@ import Phaser from "phaser"; import * as Utils from "./utils"; -import {deepCopy} from "./utils"; +import { deepCopy } from "./utils"; import pad_generic from "./configs/inputs/pad_generic"; import pad_unlicensedSNES from "./configs/inputs/pad_unlicensedSNES"; import pad_xbox360 from "./configs/inputs/pad_xbox360"; import pad_dualshock from "./configs/inputs/pad_dualshock"; import pad_procon from "./configs/inputs/pad_procon"; -import {Mode} from "./ui/ui"; +import { Mode } from "./ui/ui"; import SettingsGamepadUiHandler from "./ui/settings/settings-gamepad-ui-handler"; import SettingsKeyboardUiHandler from "./ui/settings/settings-keyboard-ui-handler"; import cfg_keyboard_qwerty from "./configs/inputs/cfg_keyboard_qwerty"; @@ -16,8 +16,8 @@ import { getIconForLatestInput, swap, } from "#app/configs/inputs/configHandler"; import BattleScene from "./battle-scene"; -import {SettingGamepad} from "#app/system/settings/settings-gamepad"; -import {SettingKeyboard} from "#app/system/settings/settings-keyboard"; +import { SettingGamepad } from "#app/system/settings/settings-gamepad"; +import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; import TouchControl from "#app/touch-controls"; import { Button } from "#enums/buttons"; import { Device } from "#enums/devices"; @@ -294,7 +294,7 @@ export class InputsController { this.setChosenGamepad(gamepadID); } const config = deepCopy(this.getConfig(gamepadID)) as InterfaceConfig; - config.custom = this.configs[gamepadID]?.custom || {...config.default}; + config.custom = this.configs[gamepadID]?.custom || { ...config.default }; this.configs[gamepadID] = config; this.scene.gameData?.saveMappingConfigs(gamepadID, this.configs[gamepadID]); } @@ -307,9 +307,9 @@ export class InputsController { * Initializes or updates configurations for connected keyboards. */ setupKeyboard(): void { - for (const layout of ["default"]) { + for (const layout of [ "default" ]) { const config = deepCopy(this.getConfigKeyboard(layout)) as InterfaceConfig; - config.custom = this.configs[layout]?.custom || {...config.default}; + config.custom = this.configs[layout]?.custom || { ...config.default }; this.configs[layout] = config; this.scene.gameData?.saveMappingConfigs(this.selectedDevice[Device.KEYBOARD], this.configs[layout]); } @@ -330,7 +330,7 @@ export class InputsController { return el !== null; }) ?? []; - for (const [index, thisGamepad] of this.gamepads.entries()) { + for (const [ index, thisGamepad ] of this.gamepads.entries()) { thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier } } diff --git a/src/loading-scene.ts b/src/loading-scene.ts index e71082ca8f5..578b9aba4fc 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -19,7 +19,7 @@ import i18next from "i18next"; import { initStatsKeys } from "#app/ui/game-stats-ui-handler"; import { initVouchers } from "#app/system/voucher"; import { Biome } from "#enums/biome"; -import {initMysteryEncounters} from "#app/data/mystery-encounters/mystery-encounters"; +import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters"; export class LoadingScene extends SceneBase { public static readonly KEY = "loading"; @@ -44,6 +44,8 @@ export class LoadingScene extends SceneBase { this.loadAtlas("prompt", "ui"); this.loadImage("candy", "ui"); this.loadImage("candy_overlay", "ui"); + this.loadImage("friendship", "ui"); + this.loadImage("friendship_overlay", "ui"); this.loadImage("cursor", "ui"); this.loadImage("cursor_reverse", "ui"); for (const wv of Utils.getEnumValues(WindowVariant)) { @@ -163,6 +165,8 @@ export class LoadingScene extends SceneBase { this.loadImage("discord", "ui"); this.loadImage("google", "ui"); this.loadImage("settings_icon", "ui"); + this.loadImage("link_icon", "ui"); + this.loadImage("unlink_icon", "ui"); this.loadImage("default_bg", "arenas"); // Load arena images @@ -240,11 +244,11 @@ export class LoadingScene extends SceneBase { this.loadAtlas("statuses", ""); this.loadAtlas("types", ""); } - const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"]; + const availableLangs = [ "en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN" ]; if (lang && availableLangs.includes(lang)) { - this.loadImage("egg-update_"+lang, "events"); + this.loadImage("halloween2024-event-" + lang, "events"); } else { - this.loadImage("egg-update_en", "events"); + this.loadImage("halloween2024-event-en", "events"); } this.loadAtlas("statuses", ""); @@ -475,18 +479,18 @@ export class LoadingScene extends SceneBase { this.load.on(this.LOAD_EVENTS.FILE_COMPLETE, (key: string) => { assetText.setText(i18next.t("menu:loadingAsset", { assetName: key })); switch (key) { - case "loading_bg": - bg.setTexture("loading_bg"); - if (mobile) { - bg.setVisible(true); - } - break; - case "logo": - logo.setTexture("logo"); - if (mobile) { - logo.setVisible(true); - } - break; + case "loading_bg": + bg.setTexture("loading_bg"); + if (mobile) { + bg.setVisible(true); + } + break; + case "logo": + logo.setTexture("logo"); + if (mobile) { + logo.setVisible(true); + } + break; } }); diff --git a/src/main.ts b/src/main.ts index 92ee267bf65..993bd1018ae 100644 --- a/src/main.ts +++ b/src/main.ts @@ -44,7 +44,7 @@ document.fonts.load("16px emerald").then(() => document.fonts.load("10px pkmnems let game; -const startGame = async () => { +const startGame = async (manifest?: any) => { await initI18n(); const LoadingScene = (await import("./loading-scene")).LoadingScene; const BattleScene = (await import("./battle-scene")).default; @@ -94,13 +94,15 @@ const startGame = async () => { version: version }); game.sound.pauseOnBlur = false; + if (manifest) { + game["manifest"] = manifest; + } }; fetch("/manifest.json") .then(res => res.json()) .then(jsonResponse => { - startGame(); - game["manifest"] = jsonResponse.manifest; + startGame(jsonResponse.manifest); }).catch(() => { // Manifest not found (likely local build) startGame(); diff --git a/src/messages.ts b/src/messages.ts index 1cd6a5966b6..91f550918e5 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -13,21 +13,21 @@ export function getPokemonNameWithAffix(pokemon: Pokemon | undefined): string { } switch (pokemon.scene.currentBattle.battleSpec) { - case BattleSpec.DEFAULT: - return !pokemon.isPlayer() - ? pokemon.hasTrainer() - ? i18next.t("battle:foePokemonWithAffix", { - pokemonName: pokemon.getNameToRender(), - }) - : i18next.t("battle:wildPokemonWithAffix", { - pokemonName: pokemon.getNameToRender(), - }) - : pokemon.getNameToRender(); - case BattleSpec.FINAL_BOSS: - return !pokemon.isPlayer() - ? i18next.t("battle:foePokemonWithAffix", { pokemonName: pokemon.getNameToRender() }) - : pokemon.getNameToRender(); - default: - return pokemon.getNameToRender(); + case BattleSpec.DEFAULT: + return !pokemon.isPlayer() + ? pokemon.hasTrainer() + ? i18next.t("battle:foePokemonWithAffix", { + pokemonName: pokemon.getNameToRender(), + }) + : i18next.t("battle:wildPokemonWithAffix", { + pokemonName: pokemon.getNameToRender(), + }) + : pokemon.getNameToRender(); + case BattleSpec.FINAL_BOSS: + return !pokemon.isPlayer() + ? i18next.t("battle:foePokemonWithAffix", { pokemonName: pokemon.getNameToRender() }) + : pokemon.getNameToRender(); + default: + return pokemon.getNameToRender(); } } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 238d2f0debf..e68e9a06fae 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1,38 +1,37 @@ -import * as Modifiers from "#app/modifier/modifier"; -import { MoneyMultiplierModifier } from "#app/modifier/modifier"; -import { allMoves, AttackMove, selfStatLowerMoves } from "#app/data/move"; -import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS, PokeballType } from "#app/data/pokeball"; -import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon"; +import BattleScene from "#app/battle-scene"; import { EvolutionItem, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { tmPoolTiers, tmSpecies } from "#app/data/balance/tms"; -import { Type } from "#app/data/type"; -import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler"; -import * as Utils from "#app/utils"; import { getBerryEffectDescription, getBerryName } from "#app/data/berry"; -import { Unlockables } from "#app/system/unlockables"; -import { getStatusEffectDescriptor, StatusEffect } from "#app/data/status-effect"; -import BattleScene from "#app/battle-scene"; -import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system/voucher"; -import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeCondition, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms"; -import { ModifierTier } from "#app/modifier/modifier-tier"; +import { allMoves, AttackMove, selfStatLowerMoves } from "#app/data/move"; import { getNatureName, getNatureStatMultiplier, Nature } from "#app/data/nature"; -import i18next from "i18next"; -import { getModifierTierTextTint } from "#app/ui/text"; +import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS, PokeballType } from "#app/data/pokeball"; +import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeCondition, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms"; +import { getStatusEffectDescriptor, StatusEffect } from "#app/data/status-effect"; +import { Type } from "#app/data/type"; +import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon"; +import { getPokemonNameWithAffix } from "#app/messages"; +import { + AddPokeballModifier, AddVoucherModifier, AttackTypeBoosterModifier, BaseStatModifier, BerryModifier, BoostBugSpawnModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, CritBoosterModifier, DamageMoneyRewardModifier, DoubleBattleChanceBoosterModifier, EnemyAttackStatusEffectChanceModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, EvolutionItemModifier, EvolutionStatBoosterModifier, EvoTrackerModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, GigantamaxAccessModifier, HealingBoosterModifier, HealShopCostModifier, HiddenAbilityRateBoosterModifier, HitHealModifier, IvScannerModifier, LevelIncrementBoosterModifier, LockModifierTiersModifier, MapModifier, MegaEvolutionAccessModifier, MoneyInterestModifier, MoneyMultiplierModifier, MoneyRewardModifier, MultipleParticipantExpBonusModifier, PokemonAllMovePpRestoreModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, PokemonInstantReviveModifier, PokemonLevelIncrementModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PokemonNatureChangeModifier, PokemonNatureWeightModifier, PokemonPpRestoreModifier, PokemonPpUpModifier, PokemonStatusHealModifier, PreserveBerryModifier, RememberMoveModifier, ResetNegativeStatStageModifier, ShinyRateBoosterModifier, SpeciesCritBoosterModifier, SpeciesStatBoosterModifier, SurviveDamageModifier, SwitchEffectTransferModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeAccessModifier, TerastallizeModifier, TmModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier, type EnemyPersistentModifier, type Modifier, type PersistentModifier, TempExtraModifierModifier +} from "#app/modifier/modifier"; +import { ModifierTier } from "#app/modifier/modifier-tier"; import Overrides from "#app/overrides"; +import { Unlockables } from "#app/system/unlockables"; +import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system/voucher"; +import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler"; +import { getModifierTierTextTint } from "#app/ui/text"; +import { formatMoney, getEnumKeys, getEnumValues, IntegerHolder, NumberHolder, padInt, randSeedInt, randSeedItem } from "#app/utils"; import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; import { BerryType } from "#enums/berry-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { getPokemonNameWithAffix } from "#app/messages"; -import { PermanentStat, TEMP_BATTLE_STATS, TempBattleStat, Stat, getStatKey } from "#enums/stat"; import { SpeciesFormKey } from "#enums/species-form-key"; +import { getStatKey, PermanentStat, Stat, TEMP_BATTLE_STATS, TempBattleStat } from "#enums/stat"; +import i18next from "i18next"; const outputModifierData = false; const useMaxWeightForOutput = false; -type Modifier = Modifiers.Modifier; - export enum ModifierPoolType { PLAYER, WILD, @@ -81,23 +80,23 @@ export class ModifierType { } let poolTypes: ModifierPoolType[]; switch (poolType) { - case ModifierPoolType.PLAYER: - poolTypes = [ poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD ]; - break; - case ModifierPoolType.WILD: - poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.TRAINER ]; - break; - case ModifierPoolType.TRAINER: - poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.WILD ]; - break; - default: - poolTypes = [ poolType ]; - break; + case ModifierPoolType.PLAYER: + poolTypes = [ poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD ]; + break; + case ModifierPoolType.WILD: + poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.TRAINER ]; + break; + case ModifierPoolType.TRAINER: + poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.WILD ]; + break; + default: + poolTypes = [ poolType ]; + break; } // Try multiple pool types in case of stolen items for (const type of poolTypes) { const pool = getModifierPoolForType(type); - for (const tier of Utils.getEnumValues(ModifierTier)) { + for (const tier of getEnumValues(ModifierTier)) { if (!pool.hasOwnProperty(tier)) { continue; } @@ -171,7 +170,7 @@ class AddPokeballModifierType extends ModifierType { private count: integer; constructor(iconImage: string, pokeballType: PokeballType, count: integer) { - super("", iconImage, (_type, _args) => new Modifiers.AddPokeballModifier(this, pokeballType, count), "pb", "se/pb_bounce_1"); + super("", iconImage, (_type, _args) => new AddPokeballModifier(this, pokeballType, count), "pb", "se/pb_bounce_1"); this.pokeballType = pokeballType; this.count = count; } @@ -198,7 +197,7 @@ class AddVoucherModifierType extends ModifierType { private count: integer; constructor(voucherType: VoucherType, count: integer) { - super("", getVoucherTypeIcon(voucherType), (_type, _args) => new Modifiers.AddVoucherModifier(this, voucherType, count), "voucher"); + super("", getVoucherTypeIcon(voucherType), (_type, _args) => new AddVoucherModifier(this, voucherType, count), "voucher"); this.count = count; this.voucherType = voucherType; } @@ -232,7 +231,7 @@ export class PokemonHeldItemModifierType extends PokemonModifierType { constructor(localeKey: string, iconImage: string, newModifierFunc: NewModifierFunc, group?: string, soundName?: string) { super(localeKey, iconImage, newModifierFunc, (pokemon: PlayerPokemon) => { const dummyModifier = this.newModifier(pokemon); - const matchingModifier = pokemon.scene.findModifier(m => m instanceof Modifiers.PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(dummyModifier)) as Modifiers.PokemonHeldItemModifier; + const matchingModifier = pokemon.scene.findModifier(m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(dummyModifier)) as PokemonHeldItemModifier; const maxStackCount = dummyModifier.getMaxStackCount(pokemon.scene); if (!maxStackCount) { return i18next.t("modifierType:ModifierType.PokemonHeldItemModifierType.extra.inoperable", { "pokemonName": getPokemonNameWithAffix(pokemon) }); @@ -244,8 +243,8 @@ export class PokemonHeldItemModifierType extends PokemonModifierType { }, group, soundName); } - newModifier(...args: any[]): Modifiers.PokemonHeldItemModifier { - return super.newModifier(...args) as Modifiers.PokemonHeldItemModifier; + newModifier(...args: any[]): PokemonHeldItemModifier { + return super.newModifier(...args) as PokemonHeldItemModifier; } } @@ -255,7 +254,7 @@ export class PokemonHpRestoreModifierType extends PokemonModifierType { protected healStatus: boolean; constructor(localeKey: string, iconImage: string, restorePoints: integer, restorePercent: integer, healStatus: boolean = false, newModifierFunc?: NewModifierFunc, selectFilter?: PokemonSelectFilter, group?: string) { - super(localeKey, iconImage, newModifierFunc || ((_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, this.healStatus, false)), + super(localeKey, iconImage, newModifierFunc || ((_type, args) => new PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, this.healStatus, false)), selectFilter || ((pokemon: PlayerPokemon) => { if (!pokemon.hp || (pokemon.isFullHp() && (!this.healStatus || (!pokemon.status && !pokemon.getTag(BattlerTagType.CONFUSED))))) { return PartyUiHandler.NoEffectMessage; @@ -282,7 +281,7 @@ export class PokemonHpRestoreModifierType extends PokemonModifierType { export class PokemonReviveModifierType extends PokemonHpRestoreModifierType { constructor(localeKey: string, iconImage: string, restorePercent: integer) { - super(localeKey, iconImage, 0, restorePercent, false, (_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, 0, this.restorePercent, false, true), + super(localeKey, iconImage, 0, restorePercent, false, (_type, args) => new PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, 0, this.restorePercent, false, true), ((pokemon: PlayerPokemon) => { if (!pokemon.isFainted()) { return PartyUiHandler.NoEffectMessage; @@ -305,7 +304,7 @@ export class PokemonReviveModifierType extends PokemonHpRestoreModifierType { export class PokemonStatusHealModifierType extends PokemonModifierType { constructor(localeKey: string, iconImage: string) { - super(localeKey, iconImage, ((_type, args) => new Modifiers.PokemonStatusHealModifier(this, (args[0] as PlayerPokemon).id)), + super(localeKey, iconImage, ((_type, args) => new PokemonStatusHealModifier(this, (args[0] as PlayerPokemon).id)), ((pokemon: PlayerPokemon) => { if (!pokemon.hp || (!pokemon.status && !pokemon.getTag(BattlerTagType.CONFUSED))) { return PartyUiHandler.NoEffectMessage; @@ -333,7 +332,7 @@ export class PokemonPpRestoreModifierType extends PokemonMoveModifierType { protected restorePoints: integer; constructor(localeKey: string, iconImage: string, restorePoints: integer) { - super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonPpRestoreModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.restorePoints), + super(localeKey, iconImage, (_type, args) => new PokemonPpRestoreModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.restorePoints), (_pokemon: PlayerPokemon) => { return null; }, (pokemonMove: PokemonMove) => { @@ -358,7 +357,7 @@ export class PokemonAllMovePpRestoreModifierType extends PokemonModifierType { protected restorePoints: integer; constructor(localeKey: string, iconImage: string, restorePoints: integer) { - super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonAllMovePpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints), + super(localeKey, iconImage, (_type, args) => new PokemonAllMovePpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints), (pokemon: PlayerPokemon) => { if (!pokemon.getMoveset().filter(m => m?.ppUsed).length) { return PartyUiHandler.NoEffectMessage; @@ -381,11 +380,11 @@ export class PokemonPpUpModifierType extends PokemonMoveModifierType { protected upPoints: integer; constructor(localeKey: string, iconImage: string, upPoints: integer) { - super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonPpUpModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.upPoints), + super(localeKey, iconImage, (_type, args) => new PokemonPpUpModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.upPoints), (_pokemon: PlayerPokemon) => { return null; }, (pokemonMove: PokemonMove) => { - if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3) { + if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3 || pokemonMove.maxPpOverride) { return PartyUiHandler.NoEffectMessage; } return null; @@ -403,7 +402,7 @@ export class PokemonNatureChangeModifierType extends PokemonModifierType { protected nature: Nature; constructor(nature: Nature) { - super("", `mint_${Utils.getEnumKeys(Stat).find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)?.toLowerCase() || "neutral" }`, ((_type, args) => new Modifiers.PokemonNatureChangeModifier(this, (args[0] as PlayerPokemon).id, this.nature)), + super("", `mint_${getEnumKeys(Stat).find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)?.toLowerCase() || "neutral" }`, ((_type, args) => new PokemonNatureChangeModifier(this, (args[0] as PlayerPokemon).id, this.nature)), ((pokemon: PlayerPokemon) => { if (pokemon.getNature() === this.nature) { return PartyUiHandler.NoEffectMessage; @@ -425,7 +424,7 @@ export class PokemonNatureChangeModifierType extends PokemonModifierType { export class RememberMoveModifierType extends PokemonModifierType { constructor(localeKey: string, iconImage: string, group?: string) { - super(localeKey, iconImage, (type, args) => new Modifiers.RememberMoveModifier(type, (args[0] as PlayerPokemon).id, (args[1] as integer)), + super(localeKey, iconImage, (type, args) => new RememberMoveModifier(type, (args[0] as PlayerPokemon).id, (args[1] as integer)), (pokemon: PlayerPokemon) => { if (!pokemon.getLearnableLevelMoves().length) { return PartyUiHandler.NoEffectMessage; @@ -439,7 +438,7 @@ export class DoubleBattleChanceBoosterModifierType extends ModifierType { private maxBattles: number; constructor(localeKey: string, iconImage: string, maxBattles: number) { - super(localeKey, iconImage, (_type, _args) => new Modifiers.DoubleBattleChanceBoosterModifier(this, maxBattles), "lure"); + super(localeKey, iconImage, (_type, _args) => new DoubleBattleChanceBoosterModifier(this, maxBattles), "lure"); this.maxBattles = maxBattles; } @@ -458,7 +457,7 @@ export class TempStatStageBoosterModifierType extends ModifierType implements Ge constructor(stat: TempBattleStat) { const nameKey = TempStatStageBoosterModifierTypeGenerator.items[stat]; - super("", nameKey, (_type, _args) => new Modifiers.TempStatStageBoosterModifier(this, this.stat, 5)); + super("", nameKey, (_type, _args) => new TempStatStageBoosterModifier(this, this.stat, 5)); this.stat = stat; this.nameKey = nameKey; @@ -485,7 +484,7 @@ export class BerryModifierType extends PokemonHeldItemModifierType implements Ge private berryType: BerryType; constructor(berryType: BerryType) { - super("", `${BerryType[berryType].toLowerCase()}_berry`, (type, args) => new Modifiers.BerryModifier(type, (args[0] as Pokemon).id, berryType), "berry"); + super("", `${BerryType[berryType].toLowerCase()}_berry`, (type, args) => new BerryModifier(type, (args[0] as Pokemon).id, berryType), "berry"); this.berryType = berryType; } @@ -503,45 +502,25 @@ export class BerryModifierType extends PokemonHeldItemModifierType implements Ge } } -function getAttackTypeBoosterItemName(type: Type) { - switch (type) { - case Type.NORMAL: - return "Silk Scarf"; - case Type.FIGHTING: - return "Black Belt"; - case Type.FLYING: - return "Sharp Beak"; - case Type.POISON: - return "Poison Barb"; - case Type.GROUND: - return "Soft Sand"; - case Type.ROCK: - return "Hard Stone"; - case Type.BUG: - return "Silver Powder"; - case Type.GHOST: - return "Spell Tag"; - case Type.STEEL: - return "Metal Coat"; - case Type.FIRE: - return "Charcoal"; - case Type.WATER: - return "Mystic Water"; - case Type.GRASS: - return "Miracle Seed"; - case Type.ELECTRIC: - return "Magnet"; - case Type.PSYCHIC: - return "Twisted Spoon"; - case Type.ICE: - return "Never-Melt Ice"; - case Type.DRAGON: - return "Dragon Fang"; - case Type.DARK: - return "Black Glasses"; - case Type.FAIRY: - return "Fairy Feather"; - } +enum AttackTypeBoosterItem { + SILK_SCARF, + BLACK_BELT, + SHARP_BEAK, + POISON_BARB, + SOFT_SAND, + HARD_STONE, + SILVER_POWDER, + SPELL_TAG, + METAL_COAT, + CHARCOAL, + MYSTIC_WATER, + MIRACLE_SEED, + MAGNET, + TWISTED_SPOON, + NEVER_MELT_ICE, + DRAGON_FANG, + BLACK_GLASSES, + FAIRY_FEATHER } export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType { @@ -549,15 +528,15 @@ export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType i public boostPercent: integer; constructor(moveType: Type, boostPercent: integer) { - super("", `${getAttackTypeBoosterItemName(moveType)?.replace(/[ \-]/g, "_").toLowerCase()}`, - (_type, args) => new Modifiers.AttackTypeBoosterModifier(this, (args[0] as Pokemon).id, moveType, boostPercent)); + super("", `${AttackTypeBoosterItem[moveType]?.toLowerCase()}`, + (_type, args) => new AttackTypeBoosterModifier(this, (args[0] as Pokemon).id, moveType, boostPercent)); this.moveType = moveType; this.boostPercent = boostPercent; } get name(): string { - return i18next.t(`modifierType:AttackTypeBoosterItem.${getAttackTypeBoosterItemName(this.moveType)?.replace(/[ \-]/g, "_").toLowerCase()}`); + return i18next.t(`modifierType:AttackTypeBoosterItem.${AttackTypeBoosterItem[this.moveType]?.toLowerCase()}`); } getDescription(scene: BattleScene): string { @@ -573,7 +552,7 @@ export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType i export type SpeciesStatBoosterItem = keyof typeof SpeciesStatBoosterModifierTypeGenerator.items; /** - * Modifier type for {@linkcode Modifiers.SpeciesStatBoosterModifier} + * Modifier type for {@linkcode SpeciesStatBoosterModifier} * @extends PokemonHeldItemModifierType * @implements GeneratedPersistentModifierType */ @@ -582,7 +561,7 @@ export class SpeciesStatBoosterModifierType extends PokemonHeldItemModifierType constructor(key: SpeciesStatBoosterItem) { const item = SpeciesStatBoosterModifierTypeGenerator.items[key]; - super(`modifierType:SpeciesBoosterItem.${key}`, key.toLowerCase(), (type, args) => new Modifiers.SpeciesStatBoosterModifier(type, (args[0] as Pokemon).id, item.stats, item.multiplier, item.species)); + super(`modifierType:SpeciesBoosterItem.${key}`, key.toLowerCase(), (type, args) => new SpeciesStatBoosterModifier(type, (args[0] as Pokemon).id, item.stats, item.multiplier, item.species)); this.key = key; } @@ -594,12 +573,12 @@ export class SpeciesStatBoosterModifierType extends PokemonHeldItemModifierType export class PokemonLevelIncrementModifierType extends PokemonModifierType { constructor(localeKey: string, iconImage: string) { - super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonLevelIncrementModifier(this, (args[0] as PlayerPokemon).id), (_pokemon: PlayerPokemon) => null); + super(localeKey, iconImage, (_type, args) => new PokemonLevelIncrementModifier(this, (args[0] as PlayerPokemon).id), (_pokemon: PlayerPokemon) => null); } getDescription(scene: BattleScene): string { let levels = 1; - const hasCandyJar = scene.modifiers.find(modifier => modifier instanceof Modifiers.LevelIncrementBoosterModifier); + const hasCandyJar = scene.modifiers.find(modifier => modifier instanceof LevelIncrementBoosterModifier); if (hasCandyJar) { levels += hasCandyJar.stackCount; } @@ -609,12 +588,12 @@ export class PokemonLevelIncrementModifierType extends PokemonModifierType { export class AllPokemonLevelIncrementModifierType extends ModifierType { constructor(localeKey: string, iconImage: string) { - super(localeKey, iconImage, (_type, _args) => new Modifiers.PokemonLevelIncrementModifier(this, -1)); + super(localeKey, iconImage, (_type, _args) => new PokemonLevelIncrementModifier(this, -1)); } getDescription(scene: BattleScene): string { let levels = 1; - const hasCandyJar = scene.modifiers.find(modifier => modifier instanceof Modifiers.LevelIncrementBoosterModifier); + const hasCandyJar = scene.modifiers.find(modifier => modifier instanceof LevelIncrementBoosterModifier); if (hasCandyJar) { levels += hasCandyJar.stackCount; } @@ -628,7 +607,7 @@ export class BaseStatBoosterModifierType extends PokemonHeldItemModifierType imp constructor(stat: PermanentStat) { const key = BaseStatBoosterModifierTypeGenerator.items[stat]; - super("", key, (_type, args) => new Modifiers.BaseStatModifier(this, (args[0] as Pokemon).id, this.stat)); + super("", key, (_type, args) => new BaseStatModifier(this, (args[0] as Pokemon).id, this.stat)); this.stat = stat; this.key = key; @@ -654,7 +633,7 @@ export class PokemonBaseStatTotalModifierType extends PokemonHeldItemModifierTyp private readonly statModifier: integer; constructor(statModifier: integer) { - super("modifierType:ModifierType.MYSTERY_ENCOUNTER_SHUCKLE_JUICE", "berry_juice", (_type, args) => new Modifiers.PokemonBaseStatTotalModifier(this, (args[0] as Pokemon).id, this.statModifier)); + super("modifierType:ModifierType.MYSTERY_ENCOUNTER_SHUCKLE_JUICE", "berry_juice", (_type, args) => new PokemonBaseStatTotalModifier(this, (args[0] as Pokemon).id, this.statModifier)); this.statModifier = statModifier; } @@ -679,7 +658,7 @@ export class PokemonBaseStatFlatModifierType extends PokemonHeldItemModifierType private readonly stats: Stat[]; constructor(statModifier: integer, stats: Stat[]) { - super("modifierType:ModifierType.MYSTERY_ENCOUNTER_OLD_GATEAU", "old_gateau", (_type, args) => new Modifiers.PokemonBaseStatFlatModifier(this, (args[0] as Pokemon).id, this.statModifier, this.stats)); + super("modifierType:ModifierType.MYSTERY_ENCOUNTER_OLD_GATEAU", "old_gateau", (_type, args) => new PokemonBaseStatFlatModifier(this, (args[0] as Pokemon).id, this.statModifier, this.stats)); this.statModifier = statModifier; this.stats = stats; } @@ -700,7 +679,7 @@ class AllPokemonFullHpRestoreModifierType extends ModifierType { private descriptionKey: string; constructor(localeKey: string, iconImage: string, descriptionKey?: string, newModifierFunc?: NewModifierFunc) { - super(localeKey, iconImage, newModifierFunc || ((_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 0, 100, false))); + super(localeKey, iconImage, newModifierFunc || ((_type, _args) => new PokemonHpRestoreModifier(this, -1, 0, 100, false))); this.descriptionKey = descriptionKey!; // TODO: is this bang correct? } @@ -712,7 +691,7 @@ class AllPokemonFullHpRestoreModifierType extends ModifierType { class AllPokemonFullReviveModifierType extends AllPokemonFullHpRestoreModifierType { constructor(localeKey: string, iconImage: string) { - super(localeKey, iconImage, "modifierType:ModifierType.AllPokemonFullReviveModifierType", (_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 0, 100, false, true)); + super(localeKey, iconImage, "modifierType:ModifierType.AllPokemonFullReviveModifierType", (_type, _args) => new PokemonHpRestoreModifier(this, -1, 0, 100, false, true)); } } @@ -721,16 +700,16 @@ export class MoneyRewardModifierType extends ModifierType { private moneyMultiplierDescriptorKey: string; constructor(localeKey: string, iconImage: string, moneyMultiplier: number, moneyMultiplierDescriptorKey: string) { - super(localeKey, iconImage, (_type, _args) => new Modifiers.MoneyRewardModifier(this, moneyMultiplier), "money", "se/buy"); + super(localeKey, iconImage, (_type, _args) => new MoneyRewardModifier(this, moneyMultiplier), "money", "se/buy"); this.moneyMultiplier = moneyMultiplier; this.moneyMultiplierDescriptorKey = moneyMultiplierDescriptorKey; } getDescription(scene: BattleScene): string { - const moneyAmount = new Utils.IntegerHolder(scene.getWaveMoneyAmount(this.moneyMultiplier)); + const moneyAmount = new IntegerHolder(scene.getWaveMoneyAmount(this.moneyMultiplier)); scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); - const formattedMoney = Utils.formatMoney(scene.moneyFormat, moneyAmount.value); + const formattedMoney = formatMoney(scene.moneyFormat, moneyAmount.value); return i18next.t("modifierType:ModifierType.MoneyRewardModifierType.description", { moneyMultiplier: i18next.t(this.moneyMultiplierDescriptorKey as any), @@ -743,7 +722,7 @@ export class ExpBoosterModifierType extends ModifierType { private boostPercent: integer; constructor(localeKey: string, iconImage: string, boostPercent: integer) { - super(localeKey, iconImage, () => new Modifiers.ExpBoosterModifier(this, boostPercent)); + super(localeKey, iconImage, () => new ExpBoosterModifier(this, boostPercent)); this.boostPercent = boostPercent; } @@ -757,7 +736,7 @@ export class PokemonExpBoosterModifierType extends PokemonHeldItemModifierType { private boostPercent: integer; constructor(localeKey: string, iconImage: string, boostPercent: integer) { - super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonExpBoosterModifier(this, (args[0] as Pokemon).id, boostPercent)); + super(localeKey, iconImage, (_type, args) => new PokemonExpBoosterModifier(this, (args[0] as Pokemon).id, boostPercent)); this.boostPercent = boostPercent; } @@ -769,7 +748,7 @@ export class PokemonExpBoosterModifierType extends PokemonHeldItemModifierType { export class PokemonFriendshipBoosterModifierType extends PokemonHeldItemModifierType { constructor(localeKey: string, iconImage: string) { - super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonFriendshipBoosterModifier(this, (args[0] as Pokemon).id)); + super(localeKey, iconImage, (_type, args) => new PokemonFriendshipBoosterModifier(this, (args[0] as Pokemon).id)); } getDescription(scene: BattleScene): string { @@ -781,7 +760,7 @@ export class PokemonMoveAccuracyBoosterModifierType extends PokemonHeldItemModif private amount: integer; constructor(localeKey: string, iconImage: string, amount: integer, group?: string, soundName?: string) { - super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonMoveAccuracyBoosterModifier(this, (args[0] as Pokemon).id, amount), group, soundName); + super(localeKey, iconImage, (_type, args) => new PokemonMoveAccuracyBoosterModifier(this, (args[0] as Pokemon).id, amount), group, soundName); this.amount = amount; } @@ -793,7 +772,7 @@ export class PokemonMoveAccuracyBoosterModifierType extends PokemonHeldItemModif export class PokemonMultiHitModifierType extends PokemonHeldItemModifierType { constructor(localeKey: string, iconImage: string) { - super(localeKey, iconImage, (type, args) => new Modifiers.PokemonMultiHitModifier(type as PokemonMultiHitModifierType, (args[0] as Pokemon).id)); + super(localeKey, iconImage, (type, args) => new PokemonMultiHitModifier(type as PokemonMultiHitModifierType, (args[0] as Pokemon).id)); } getDescription(scene: BattleScene): string { @@ -805,7 +784,7 @@ export class TmModifierType extends PokemonModifierType { public moveId: Moves; constructor(moveId: Moves) { - super("", `tm_${Type[allMoves[moveId].type].toLowerCase()}`, (_type, args) => new Modifiers.TmModifier(this, (args[0] as PlayerPokemon).id), + super("", `tm_${Type[allMoves[moveId].type].toLowerCase()}`, (_type, args) => new TmModifier(this, (args[0] as PlayerPokemon).id), (pokemon: PlayerPokemon) => { if (pokemon.compatibleTms.indexOf(moveId) === -1 || pokemon.getMoveset().filter(m => m?.moveId === moveId).length) { return PartyUiHandler.NoEffectMessage; @@ -818,7 +797,7 @@ export class TmModifierType extends PokemonModifierType { get name(): string { return i18next.t("modifierType:ModifierType.TmModifierType.name", { - moveId: Utils.padInt(Object.keys(tmSpecies).indexOf(this.moveId.toString()) + 1, 3), + moveId: padInt(Object.keys(tmSpecies).indexOf(this.moveId.toString()) + 1, 3), moveName: allMoves[this.moveId].name, }); } @@ -832,7 +811,7 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge public evolutionItem: EvolutionItem; constructor(evolutionItem: EvolutionItem) { - super("", EvolutionItem[evolutionItem].toLowerCase(), (_type, args) => new Modifiers.EvolutionItemModifier(this, (args[0] as PlayerPokemon).id), + super("", EvolutionItem[evolutionItem].toLowerCase(), (_type, args) => new EvolutionItemModifier(this, (args[0] as PlayerPokemon).id), (pokemon: PlayerPokemon) => { if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem && (!e.condition || e.condition.predicate(pokemon)) && (e.preFormKey === null || e.preFormKey === pokemon.getFormKey())).length && (pokemon.getFormKey() !== SpeciesFormKey.GIGANTAMAX)) { @@ -868,7 +847,7 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G public formChangeItem: FormChangeItem; constructor(formChangeItem: FormChangeItem) { - super("", FormChangeItem[formChangeItem].toLowerCase(), (_type, args) => new Modifiers.PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true), + super("", FormChangeItem[formChangeItem].toLowerCase(), (_type, args) => new PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true), (pokemon: PlayerPokemon) => { // Make sure the Pokemon has alternate forms if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId) @@ -902,7 +881,7 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G export class FusePokemonModifierType extends PokemonModifierType { constructor(localeKey: string, iconImage: string) { - super(localeKey, iconImage, (_type, args) => new Modifiers.FusePokemonModifier(this, (args[0] as PlayerPokemon).id, (args[1] as PlayerPokemon).id), + super(localeKey, iconImage, (_type, args) => new FusePokemonModifier(this, (args[0] as PlayerPokemon).id, (args[1] as PlayerPokemon).id), (pokemon: PlayerPokemon) => { if (pokemon.isFusion()) { return PartyUiHandler.NoEffectMessage; @@ -949,7 +928,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator { let type: Type; - const randInt = Utils.randSeedInt(totalWeight); + const randInt = randSeedInt(totalWeight); let weight = 0; for (const t of attackMoveTypeWeights.keys()) { @@ -981,7 +960,7 @@ class BaseStatBoosterModifierTypeGenerator extends ModifierTypeGenerator { if (pregenArgs) { return new BaseStatBoosterModifierType(pregenArgs[0]); } - const randStat: PermanentStat = Utils.randSeedInt(Stat.SPD + 1); + const randStat: PermanentStat = randSeedInt(Stat.SPD + 1); return new BaseStatBoosterModifierType(randStat); }); } @@ -1002,7 +981,7 @@ class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator { if (pregenArgs && (pregenArgs.length === 1) && TEMP_BATTLE_STATS.includes(pregenArgs[0])) { return new TempStatStageBoosterModifierType(pregenArgs[0]); } - const randStat: TempBattleStat = Utils.randSeedInt(Stat.ACC, Stat.ATK); + const randStat: TempBattleStat = randSeedInt(Stat.ACC, Stat.ATK); return new TempStatStageBoosterModifierType(randStat); }); } @@ -1017,10 +996,10 @@ class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator { class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator { /** Object comprised of the currently available species-based stat boosting held items */ public static readonly items = { - LIGHT_BALL: { stats: [Stat.ATK, Stat.SPATK], multiplier: 2, species: [Species.PIKACHU] }, - THICK_CLUB: { stats: [Stat.ATK], multiplier: 2, species: [Species.CUBONE, Species.MAROWAK, Species.ALOLA_MAROWAK] }, - METAL_POWDER: { stats: [Stat.DEF], multiplier: 2, species: [Species.DITTO] }, - QUICK_POWDER: { stats: [Stat.SPD], multiplier: 2, species: [Species.DITTO] }, + LIGHT_BALL: { stats: [ Stat.ATK, Stat.SPATK ], multiplier: 2, species: [ Species.PIKACHU ]}, + THICK_CLUB: { stats: [ Stat.ATK ], multiplier: 2, species: [ Species.CUBONE, Species.MAROWAK, Species.ALOLA_MAROWAK ]}, + METAL_POWDER: { stats: [ Stat.DEF ], multiplier: 2, species: [ Species.DITTO ]}, + QUICK_POWDER: { stats: [ Stat.SPD ], multiplier: 2, species: [ Species.DITTO ]}, }; constructor() { @@ -1044,8 +1023,8 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator { const checkedStats = values[i].stats; // If party member already has the item being weighted currently, skip to the next item - const hasItem = p.getHeldItems().some(m => m instanceof Modifiers.SpeciesStatBoosterModifier - && (m as Modifiers.SpeciesStatBoosterModifier).contains(checkedSpecies[0], checkedStats[0])); + const hasItem = p.getHeldItems().some(m => m instanceof SpeciesStatBoosterModifier + && (m as SpeciesStatBoosterModifier).contains(checkedSpecies[0], checkedStats[0])); if (!hasItem) { if (checkedSpecies.includes(speciesId) || (!!fusionSpeciesId && checkedSpecies.includes(fusionSpeciesId))) { @@ -1065,7 +1044,7 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator { } if (totalWeight !== 0) { - const randInt = Utils.randSeedInt(totalWeight, 1); + const randInt = randSeedInt(totalWeight, 1); let weight = 0; for (const i in weights) { @@ -1095,7 +1074,7 @@ class TmModifierTypeGenerator extends ModifierTypeGenerator { if (!tierUniqueCompatibleTms.length) { return null; } - const randTmIndex = Utils.randSeedInt(tierUniqueCompatibleTms.length); + const randTmIndex = randSeedInt(tierUniqueCompatibleTms.length); return new TmModifierType(tierUniqueCompatibleTms[randTmIndex]); }); } @@ -1123,26 +1102,26 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator { return null; } - return new EvolutionItemModifierType(evolutionItemPool[Utils.randSeedInt(evolutionItemPool.length)]!); // TODO: is the bang correct? + return new EvolutionItemModifierType(evolutionItemPool[randSeedInt(evolutionItemPool.length)]!); // TODO: is the bang correct? }); } } class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { - constructor(rare: boolean) { + constructor(isRareFormChangeItem: boolean) { super((party: Pokemon[], pregenArgs?: any[]) => { if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in FormChangeItem)) { return new FormChangeItemModifierType(pregenArgs[0] as FormChangeItem); } - const formChangeItemPool = [...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => { + const formChangeItemPool = [ ...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => { const formChanges = pokemonFormChanges[p.species.speciesId]; - let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || party[0].scene.getModifiers(Modifiers.MegaEvolutionAccessModifier).length) - && ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || party[0].scene.getModifiers(Modifiers.GigantamaxAccessModifier).length) + let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || party[0].scene.getModifiers(MegaEvolutionAccessModifier).length) + && ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || party[0].scene.getModifiers(GigantamaxAccessModifier).length) && (!fc.conditions.length || fc.conditions.filter(cond => cond instanceof SpeciesFormChangeCondition && cond.predicate(p)).length) && (fc.preFormKey === p.getFormKey())) .map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger) - .filter(t => t && t.active && !p.scene.findModifier(m => m instanceof Modifiers.PokemonFormChangeItemModifier && m.pokemonId === p.id && m.formChangeItem === t.item)); + .filter(t => t && t.active && !p.scene.findModifier(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === p.id && m.formChangeItem === t.item)); if (p.species.speciesId === Species.NECROZMA) { // technically we could use a simplified version and check for formChanges.length > 3, but in case any code changes later, this might break... @@ -1152,15 +1131,15 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { foundN_SOLAR = false; formChangeItemTriggers.forEach((fc, i) => { switch (fc.item) { - case FormChangeItem.ULTRANECROZIUM_Z: - foundULTRA_Z = true; - break; - case FormChangeItem.N_LUNARIZER: - foundN_LUNA = true; - break; - case FormChangeItem.N_SOLARIZER: - foundN_SOLAR = true; - break; + case FormChangeItem.ULTRANECROZIUM_Z: + foundULTRA_Z = true; + break; + case FormChangeItem.N_LUNARIZER: + foundN_LUNA = true; + break; + case FormChangeItem.N_SOLARIZER: + foundN_SOLAR = true; + break; } }); if (foundULTRA_Z && foundN_LUNA && foundN_SOLAR) { @@ -1170,14 +1149,14 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { } return formChangeItemTriggers; }).flat()) - ].flat().flatMap(fc => fc.item).filter(i => (i && i < 100) === rare); + ].flat().flatMap(fc => fc.item).filter(i => (i && i < 100) === isRareFormChangeItem); // convert it into a set to remove duplicate values, which can appear when the same species with a potential form change is in the party. if (!formChangeItemPool.length) { return null; } - return new FormChangeItemModifierType(formChangeItemPool[Utils.randSeedInt(formChangeItemPool.length)]); + return new FormChangeItemModifierType(formChangeItemPool[randSeedInt(formChangeItemPool.length)]); }); } } @@ -1186,7 +1165,7 @@ export class TerastallizeModifierType extends PokemonHeldItemModifierType implem private teraType: Type; constructor(teraType: Type) { - super("", `${Type[teraType].toLowerCase()}_tera_shard`, (type, args) => new Modifiers.TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), "tera_shard"); + super("", `${Type[teraType].toLowerCase()}_tera_shard`, (type, args) => new TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), "tera_shard"); this.teraType = teraType; } @@ -1208,7 +1187,7 @@ export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemMo private chancePercent: integer; constructor(localeKey: string, iconImage: string, chancePercent: integer, group?: string, soundName?: string) { - super(localeKey, iconImage, (type, args) => new Modifiers.ContactHeldItemTransferChanceModifier(type, (args[0] as Pokemon).id, chancePercent), group, soundName); + super(localeKey, iconImage, (type, args) => new ContactHeldItemTransferChanceModifier(type, (args[0] as Pokemon).id, chancePercent), group, soundName); this.chancePercent = chancePercent; } @@ -1220,7 +1199,7 @@ export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemMo export class TurnHeldItemTransferModifierType extends PokemonHeldItemModifierType { constructor(localeKey: string, iconImage: string, group?: string, soundName?: string) { - super(localeKey, iconImage, (type, args) => new Modifiers.TurnHeldItemTransferModifier(type, (args[0] as Pokemon).id), group, soundName); + super(localeKey, iconImage, (type, args) => new TurnHeldItemTransferModifier(type, (args[0] as Pokemon).id), group, soundName); } getDescription(scene: BattleScene): string { @@ -1233,7 +1212,7 @@ export class EnemyAttackStatusEffectChanceModifierType extends ModifierType { private effect: StatusEffect; constructor(localeKey: string, iconImage: string, chancePercent: integer, effect: StatusEffect, stackCount?: integer) { - super(localeKey, iconImage, (type, args) => new Modifiers.EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent, stackCount), "enemy_status_chance"); + super(localeKey, iconImage, (type, args) => new EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent, stackCount), "enemy_status_chance"); this.chancePercent = chancePercent; this.effect = effect; @@ -1251,7 +1230,7 @@ export class EnemyEndureChanceModifierType extends ModifierType { private chancePercent: number; constructor(localeKey: string, iconImage: string, chancePercent: number) { - super(localeKey, iconImage, (type, _args) => new Modifiers.EnemyEndureChanceModifier(type, chancePercent), "enemy_endure"); + super(localeKey, iconImage, (type, _args) => new EnemyEndureChanceModifier(type, chancePercent), "enemy_endure"); this.chancePercent = chancePercent; } @@ -1298,17 +1277,16 @@ function skipInLastClassicWaveOrDefault(defaultWeight: integer) : WeightedModifi */ function lureWeightFunc(maxBattles: number, weight: number): WeightedModifierTypeWeightFunc { return (party: Pokemon[]) => { - const lures = party[0].scene.getModifiers(Modifiers.DoubleBattleChanceBoosterModifier); + const lures = party[0].scene.getModifiers(DoubleBattleChanceBoosterModifier); return !(party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex === 199) && (lures.length === 0 || lures.filter(m => m.getMaxBattles() === maxBattles && m.getBattleCount() >= maxBattles * 0.6).length === 0) ? weight : 0; }; } - class WeightedModifierType { public modifierType: ModifierType; public weight: integer | WeightedModifierTypeWeightFunc; - public maxWeight: integer; + public maxWeight: integer | WeightedModifierTypeWeightFunc; - constructor(modifierTypeFunc: ModifierTypeFunc, weight: integer | WeightedModifierTypeWeightFunc, maxWeight?: integer) { + constructor(modifierTypeFunc: ModifierTypeFunc, weight: integer | WeightedModifierTypeWeightFunc, maxWeight?: integer | WeightedModifierTypeWeightFunc) { this.modifierType = modifierTypeFunc(); this.modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc)!; // TODO: is this bang correct? this.weight = weight; @@ -1388,13 +1366,13 @@ export const modifierTypes = { RARE_FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(true), EVOLUTION_TRACKER_GIMMIGHOUL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVOLUTION_TRACKER_GIMMIGHOUL", "relic_gold", - (type, args) => new Modifiers.EvoTrackerModifier(type, (args[0] as Pokemon).id, Species.GIMMIGHOUL, 10)), + (type, args) => new EvoTrackerModifier(type, (args[0] as Pokemon).id, Species.GIMMIGHOUL, 10)), - MEGA_BRACELET: () => new ModifierType("modifierType:ModifierType.MEGA_BRACELET", "mega_bracelet", (type, _args) => new Modifiers.MegaEvolutionAccessModifier(type)), - DYNAMAX_BAND: () => new ModifierType("modifierType:ModifierType.DYNAMAX_BAND", "dynamax_band", (type, _args) => new Modifiers.GigantamaxAccessModifier(type)), - TERA_ORB: () => new ModifierType("modifierType:ModifierType.TERA_ORB", "tera_orb", (type, _args) => new Modifiers.TerastallizeAccessModifier(type)), + MEGA_BRACELET: () => new ModifierType("modifierType:ModifierType.MEGA_BRACELET", "mega_bracelet", (type, _args) => new MegaEvolutionAccessModifier(type)), + DYNAMAX_BAND: () => new ModifierType("modifierType:ModifierType.DYNAMAX_BAND", "dynamax_band", (type, _args) => new GigantamaxAccessModifier(type)), + TERA_ORB: () => new ModifierType("modifierType:ModifierType.TERA_ORB", "tera_orb", (type, _args) => new TerastallizeAccessModifier(type)), - MAP: () => new ModifierType("modifierType:ModifierType.MAP", "map", (type, _args) => new Modifiers.MapModifier(type)), + MAP: () => new ModifierType("modifierType:ModifierType.MAP", "map", (type, _args) => new MapModifier(type)), POTION: () => new PokemonHpRestoreModifierType("modifierType:ModifierType.POTION", "potion", 20, 10), SUPER_POTION: () => new PokemonHpRestoreModifierType("modifierType:ModifierType.SUPER_POTION", "super_potion", 50, 25), @@ -1409,8 +1387,8 @@ export const modifierTypes = { SACRED_ASH: () => new AllPokemonFullReviveModifierType("modifierType:ModifierType.SACRED_ASH", "sacred_ash"), - REVIVER_SEED: () => new PokemonHeldItemModifierType("modifierType:ModifierType.REVIVER_SEED", "reviver_seed", (type, args) => new Modifiers.PokemonInstantReviveModifier(type, (args[0] as Pokemon).id)), - WHITE_HERB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.WHITE_HERB", "white_herb", (type, args) => new Modifiers.ResetNegativeStatStageModifier(type, (args[0] as Pokemon).id)), + REVIVER_SEED: () => new PokemonHeldItemModifierType("modifierType:ModifierType.REVIVER_SEED", "reviver_seed", (type, args) => new PokemonInstantReviveModifier(type, (args[0] as Pokemon).id)), + WHITE_HERB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.WHITE_HERB", "white_herb", (type, args) => new ResetNegativeStatStageModifier(type, (args[0] as Pokemon).id)), ETHER: () => new PokemonPpRestoreModifierType("modifierType:ModifierType.ETHER", "ether", 10), MAX_ETHER: () => new PokemonPpRestoreModifierType("modifierType:ModifierType.MAX_ETHER", "max_ether", -1), @@ -1440,7 +1418,7 @@ export const modifierTypes = { amount: i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.extra.stage") }); } - }("modifierType:ModifierType.DIRE_HIT", "dire_hit", (type, _args) => new Modifiers.TempCritBoosterModifier(type, 5)), + }("modifierType:ModifierType.DIRE_HIT", "dire_hit", (type, _args) => new TempCritBoosterModifier(type, 5)), BASE_STAT_BOOSTER: () => new BaseStatBoosterModifierTypeGenerator(), @@ -1450,22 +1428,22 @@ export const modifierTypes = { if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Nature)) { return new PokemonNatureChangeModifierType(pregenArgs[0] as Nature); } - return new PokemonNatureChangeModifierType(Utils.randSeedInt(Utils.getEnumValues(Nature).length) as Nature); + return new PokemonNatureChangeModifierType(randSeedInt(getEnumValues(Nature).length) as Nature); }), TERA_SHARD: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Type)) { return new TerastallizeModifierType(pregenArgs[0] as Type); } - if (!party[0].scene.getModifiers(Modifiers.TerastallizeAccessModifier).length) { + if (!party[0].scene.getModifiers(TerastallizeAccessModifier).length) { return null; } let type: Type; - if (!Utils.randSeedInt(3)) { + if (!randSeedInt(3)) { const partyMemberTypes = party.map(p => p.getTypes(false, false, true)).flat(); - type = Utils.randSeedItem(partyMemberTypes); + type = randSeedItem(partyMemberTypes); } else { - type = Utils.randSeedInt(64) ? Utils.randSeedInt(18) as Type : Type.STELLAR; + type = randSeedInt(64) ? randSeedInt(18) as Type : Type.STELLAR; } return new TerastallizeModifierType(type); }), @@ -1474,9 +1452,9 @@ export const modifierTypes = { if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in BerryType)) { return new BerryModifierType(pregenArgs[0] as BerryType); } - const berryTypes = Utils.getEnumValues(BerryType); + const berryTypes = getEnumValues(BerryType); let randBerryType: BerryType; - const rand = Utils.randSeedInt(12); + const rand = randSeedInt(12); if (rand < 2) { randBerryType = BerryType.SITRUS; } else if (rand < 4) { @@ -1484,7 +1462,7 @@ export const modifierTypes = { } else if (rand < 6) { randBerryType = BerryType.LEPPA; } else { - randBerryType = berryTypes[Utils.randSeedInt(berryTypes.length - 3) + 2]; + randBerryType = berryTypes[randSeedInt(berryTypes.length - 3) + 2]; } return new BerryModifierType(randBerryType); }), @@ -1495,10 +1473,10 @@ export const modifierTypes = { MEMORY_MUSHROOM: () => new RememberMoveModifierType("modifierType:ModifierType.MEMORY_MUSHROOM", "big_mushroom"), - EXP_SHARE: () => new ModifierType("modifierType:ModifierType.EXP_SHARE", "exp_share", (type, _args) => new Modifiers.ExpShareModifier(type)), - EXP_BALANCE: () => new ModifierType("modifierType:ModifierType.EXP_BALANCE", "exp_balance", (type, _args) => new Modifiers.ExpBalanceModifier(type)), + EXP_SHARE: () => new ModifierType("modifierType:ModifierType.EXP_SHARE", "exp_share", (type, _args) => new ExpShareModifier(type)), + EXP_BALANCE: () => new ModifierType("modifierType:ModifierType.EXP_BALANCE", "exp_balance", (type, _args) => new ExpBalanceModifier(type)), - OVAL_CHARM: () => new ModifierType("modifierType:ModifierType.OVAL_CHARM", "oval_charm", (type, _args) => new Modifiers.MultipleParticipantExpBonusModifier(type)), + OVAL_CHARM: () => new ModifierType("modifierType:ModifierType.OVAL_CHARM", "oval_charm", (type, _args) => new MultipleParticipantExpBonusModifier(type)), EXP_CHARM: () => new ExpBoosterModifierType("modifierType:ModifierType.EXP_CHARM", "exp_charm", 25), SUPER_EXP_CHARM: () => new ExpBoosterModifierType("modifierType:ModifierType.SUPER_EXP_CHARM", "super_exp_charm", 60), @@ -1509,51 +1487,51 @@ export const modifierTypes = { SOOTHE_BELL: () => new PokemonFriendshipBoosterModifierType("modifierType:ModifierType.SOOTHE_BELL", "soothe_bell"), - SCOPE_LENS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SCOPE_LENS", "scope_lens", (type, args) => new Modifiers.CritBoosterModifier(type, (args[0] as Pokemon).id, 1)), - LEEK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEEK", "leek", (type, args) => new Modifiers.SpeciesCritBoosterModifier(type, (args[0] as Pokemon).id, 2, [Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD])), + SCOPE_LENS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SCOPE_LENS", "scope_lens", (type, args) => new CritBoosterModifier(type, (args[0] as Pokemon).id, 1)), + LEEK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEEK", "leek", (type, args) => new SpeciesCritBoosterModifier(type, (args[0] as Pokemon).id, 2, [ Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD ])), - EVIOLITE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVIOLITE", "eviolite", (type, args) => new Modifiers.EvolutionStatBoosterModifier(type, (args[0] as Pokemon).id, [Stat.DEF, Stat.SPDEF], 1.5)), + EVIOLITE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVIOLITE", "eviolite", (type, args) => new EvolutionStatBoosterModifier(type, (args[0] as Pokemon).id, [ Stat.DEF, Stat.SPDEF ], 1.5)), - SOUL_DEW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SOUL_DEW", "soul_dew", (type, args) => new Modifiers.PokemonNatureWeightModifier(type, (args[0] as Pokemon).id)), + SOUL_DEW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SOUL_DEW", "soul_dew", (type, args) => new PokemonNatureWeightModifier(type, (args[0] as Pokemon).id)), NUGGET: () => new MoneyRewardModifierType("modifierType:ModifierType.NUGGET", "nugget", 1, "modifierType:ModifierType.MoneyRewardModifierType.extra.small"), BIG_NUGGET: () => new MoneyRewardModifierType("modifierType:ModifierType.BIG_NUGGET", "big_nugget", 2.5, "modifierType:ModifierType.MoneyRewardModifierType.extra.moderate"), RELIC_GOLD: () => new MoneyRewardModifierType("modifierType:ModifierType.RELIC_GOLD", "relic_gold", 10, "modifierType:ModifierType.MoneyRewardModifierType.extra.large"), - AMULET_COIN: () => new ModifierType("modifierType:ModifierType.AMULET_COIN", "amulet_coin", (type, _args) => new Modifiers.MoneyMultiplierModifier(type)), - GOLDEN_PUNCH: () => new PokemonHeldItemModifierType("modifierType:ModifierType.GOLDEN_PUNCH", "golden_punch", (type, args) => new Modifiers.DamageMoneyRewardModifier(type, (args[0] as Pokemon).id)), - COIN_CASE: () => new ModifierType("modifierType:ModifierType.COIN_CASE", "coin_case", (type, _args) => new Modifiers.MoneyInterestModifier(type)), + AMULET_COIN: () => new ModifierType("modifierType:ModifierType.AMULET_COIN", "amulet_coin", (type, _args) => new MoneyMultiplierModifier(type)), + GOLDEN_PUNCH: () => new PokemonHeldItemModifierType("modifierType:ModifierType.GOLDEN_PUNCH", "golden_punch", (type, args) => new DamageMoneyRewardModifier(type, (args[0] as Pokemon).id)), + COIN_CASE: () => new ModifierType("modifierType:ModifierType.COIN_CASE", "coin_case", (type, _args) => new MoneyInterestModifier(type)), - LOCK_CAPSULE: () => new ModifierType("modifierType:ModifierType.LOCK_CAPSULE", "lock_capsule", (type, _args) => new Modifiers.LockModifierTiersModifier(type)), + LOCK_CAPSULE: () => new ModifierType("modifierType:ModifierType.LOCK_CAPSULE", "lock_capsule", (type, _args) => new LockModifierTiersModifier(type)), GRIP_CLAW: () => new ContactHeldItemTransferChanceModifierType("modifierType:ModifierType.GRIP_CLAW", "grip_claw", 10), WIDE_LENS: () => new PokemonMoveAccuracyBoosterModifierType("modifierType:ModifierType.WIDE_LENS", "wide_lens", 5), MULTI_LENS: () => new PokemonMultiHitModifierType("modifierType:ModifierType.MULTI_LENS", "zoom_lens"), - HEALING_CHARM: () => new ModifierType("modifierType:ModifierType.HEALING_CHARM", "healing_charm", (type, _args) => new Modifiers.HealingBoosterModifier(type, 1.1)), - CANDY_JAR: () => new ModifierType("modifierType:ModifierType.CANDY_JAR", "candy_jar", (type, _args) => new Modifiers.LevelIncrementBoosterModifier(type)), + HEALING_CHARM: () => new ModifierType("modifierType:ModifierType.HEALING_CHARM", "healing_charm", (type, _args) => new HealingBoosterModifier(type, 1.1)), + CANDY_JAR: () => new ModifierType("modifierType:ModifierType.CANDY_JAR", "candy_jar", (type, _args) => new LevelIncrementBoosterModifier(type)), - BERRY_POUCH: () => new ModifierType("modifierType:ModifierType.BERRY_POUCH", "berry_pouch", (type, _args) => new Modifiers.PreserveBerryModifier(type)), + BERRY_POUCH: () => new ModifierType("modifierType:ModifierType.BERRY_POUCH", "berry_pouch", (type, _args) => new PreserveBerryModifier(type)), - FOCUS_BAND: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FOCUS_BAND", "focus_band", (type, args) => new Modifiers.SurviveDamageModifier(type, (args[0] as Pokemon).id)), + FOCUS_BAND: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FOCUS_BAND", "focus_band", (type, args) => new SurviveDamageModifier(type, (args[0] as Pokemon).id)), - QUICK_CLAW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.QUICK_CLAW", "quick_claw", (type, args) => new Modifiers.BypassSpeedChanceModifier(type, (args[0] as Pokemon).id)), + QUICK_CLAW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.QUICK_CLAW", "quick_claw", (type, args) => new BypassSpeedChanceModifier(type, (args[0] as Pokemon).id)), - KINGS_ROCK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.KINGS_ROCK", "kings_rock", (type, args) => new Modifiers.FlinchChanceModifier(type, (args[0] as Pokemon).id)), + KINGS_ROCK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.KINGS_ROCK", "kings_rock", (type, args) => new FlinchChanceModifier(type, (args[0] as Pokemon).id)), - LEFTOVERS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEFTOVERS", "leftovers", (type, args) => new Modifiers.TurnHealModifier(type, (args[0] as Pokemon).id)), - SHELL_BELL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SHELL_BELL", "shell_bell", (type, args) => new Modifiers.HitHealModifier(type, (args[0] as Pokemon).id)), + LEFTOVERS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEFTOVERS", "leftovers", (type, args) => new TurnHealModifier(type, (args[0] as Pokemon).id)), + SHELL_BELL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SHELL_BELL", "shell_bell", (type, args) => new HitHealModifier(type, (args[0] as Pokemon).id)), - TOXIC_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.TOXIC_ORB", "toxic_orb", (type, args) => new Modifiers.TurnStatusEffectModifier(type, (args[0] as Pokemon).id)), - FLAME_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FLAME_ORB", "flame_orb", (type, args) => new Modifiers.TurnStatusEffectModifier(type, (args[0] as Pokemon).id)), + TOXIC_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.TOXIC_ORB", "toxic_orb", (type, args) => new TurnStatusEffectModifier(type, (args[0] as Pokemon).id)), + FLAME_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FLAME_ORB", "flame_orb", (type, args) => new TurnStatusEffectModifier(type, (args[0] as Pokemon).id)), - BATON: () => new PokemonHeldItemModifierType("modifierType:ModifierType.BATON", "baton", (type, args) => new Modifiers.SwitchEffectTransferModifier(type, (args[0] as Pokemon).id)), + BATON: () => new PokemonHeldItemModifierType("modifierType:ModifierType.BATON", "baton", (type, args) => new SwitchEffectTransferModifier(type, (args[0] as Pokemon).id)), - SHINY_CHARM: () => new ModifierType("modifierType:ModifierType.SHINY_CHARM", "shiny_charm", (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)), - ABILITY_CHARM: () => new ModifierType("modifierType:ModifierType.ABILITY_CHARM", "ability_charm", (type, _args) => new Modifiers.HiddenAbilityRateBoosterModifier(type)), + SHINY_CHARM: () => new ModifierType("modifierType:ModifierType.SHINY_CHARM", "shiny_charm", (type, _args) => new ShinyRateBoosterModifier(type)), + ABILITY_CHARM: () => new ModifierType("modifierType:ModifierType.ABILITY_CHARM", "ability_charm", (type, _args) => new HiddenAbilityRateBoosterModifier(type)), - IV_SCANNER: () => new ModifierType("modifierType:ModifierType.IV_SCANNER", "scanner", (type, _args) => new Modifiers.IvScannerModifier(type)), + IV_SCANNER: () => new ModifierType("modifierType:ModifierType.IV_SCANNER", "scanner", (type, _args) => new IvScannerModifier(type)), DNA_SPLICERS: () => new FusePokemonModifierType("modifierType:ModifierType.DNA_SPLICERS", "dna_splicers"), @@ -1563,39 +1541,40 @@ export const modifierTypes = { VOUCHER_PLUS: () => new AddVoucherModifierType(VoucherType.PLUS, 1), VOUCHER_PREMIUM: () => new AddVoucherModifierType(VoucherType.PREMIUM, 1), - GOLDEN_POKEBALL: () => new ModifierType("modifierType:ModifierType.GOLDEN_POKEBALL", "pb_gold", (type, _args) => new Modifiers.ExtraModifierModifier(type), undefined, "se/pb_bounce_1"), + GOLDEN_POKEBALL: () => new ModifierType("modifierType:ModifierType.GOLDEN_POKEBALL", "pb_gold", (type, _args) => new ExtraModifierModifier(type), undefined, "se/pb_bounce_1"), + SILVER_POKEBALL: () => new ModifierType("modifierType:ModifierType.SILVER_POKEBALL", "pb_silver", (type, _args) => new TempExtraModifierModifier(type, 100), undefined, "se/pb_bounce_1"), - ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5)), - ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5)), - //ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'), - ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2, 10)), + ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new EnemyDamageBoosterModifier(type, 5)), + ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new EnemyDamageReducerModifier(type, 2.5)), + //ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'), + ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new EnemyTurnHealModifier(type, 2, 10)), ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_POISON_CHANCE", "wl_antidote", 5, StatusEffect.POISON, 10), ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_PARALYZE_CHANCE", "wl_paralyze_heal", 2.5, StatusEffect.PARALYSIS, 10), ENEMY_ATTACK_BURN_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_BURN_CHANCE", "wl_burn_heal", 5, StatusEffect.BURN, 10), - ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 2.5, 10)), + ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new EnemyStatusEffectHealChanceModifier(type, 2.5, 10)), ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2), - ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new Modifiers.EnemyFusionChanceModifier(type, 1)), + ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new EnemyFusionChanceModifier(type, 1)), MYSTERY_ENCOUNTER_SHUCKLE_JUICE: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { if (pregenArgs) { return new PokemonBaseStatTotalModifierType(pregenArgs[0] as number); } - return new PokemonBaseStatTotalModifierType(Utils.randSeedInt(20)); + return new PokemonBaseStatTotalModifierType(randSeedInt(20, 1)); }), MYSTERY_ENCOUNTER_OLD_GATEAU: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { if (pregenArgs) { return new PokemonBaseStatFlatModifierType(pregenArgs[0] as number, pregenArgs[1] as Stat[]); } - return new PokemonBaseStatFlatModifierType(Utils.randSeedInt(20), [Stat.HP, Stat.ATK, Stat.DEF]); + return new PokemonBaseStatFlatModifierType(randSeedInt(20, 1), [ Stat.HP, Stat.ATK, Stat.DEF ]); }), MYSTERY_ENCOUNTER_BLACK_SLUDGE: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { if (pregenArgs) { - return new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new Modifiers.HealShopCostModifier(type, pregenArgs[0] as number)); + return new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new HealShopCostModifier(type, pregenArgs[0] as number)); } - return new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new Modifiers.HealShopCostModifier(type, 2.5)); + return new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new HealShopCostModifier(type, 2.5)); }), - MYSTERY_ENCOUNTER_MACHO_BRACE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_MACHO_BRACE", "macho_brace", (type, args) => new Modifiers.PokemonIncrementingStatModifier(type, (args[0] as Pokemon).id)), - MYSTERY_ENCOUNTER_GOLDEN_BUG_NET: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET", "golden_net", (type, _args) => new Modifiers.BoostBugSpawnModifier(type)), + MYSTERY_ENCOUNTER_MACHO_BRACE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_MACHO_BRACE", "macho_brace", (type, args) => new PokemonIncrementingStatModifier(type, (args[0] as Pokemon).id)), + MYSTERY_ENCOUNTER_GOLDEN_BUG_NET: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET", "golden_net", (type, _args) => new BoostBugSpawnModifier(type)), }; interface ModifierPool { @@ -1644,8 +1623,8 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.PP_UP, 2), new WeightedModifierType(modifierTypes.FULL_HEAL, (party: Pokemon[]) => { const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status && !p.getHeldItems().some(i => { - if (i instanceof Modifiers.TurnStatusEffectModifier) { - return (i as Modifiers.TurnStatusEffectModifier).getStatusEffect() === p.status?.effect; + if (i instanceof TurnStatusEffectModifier) { + return (i as TurnStatusEffectModifier).getStatusEffect() === p.status?.effect; } return false; })).length, 3); @@ -1672,8 +1651,8 @@ const modifierPool: ModifierPool = { }, 3), new WeightedModifierType(modifierTypes.FULL_RESTORE, (party: Pokemon[]) => { const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status && !p.getHeldItems().some(i => { - if (i instanceof Modifiers.TurnStatusEffectModifier) { - return (i as Modifiers.TurnStatusEffectModifier).getStatusEffect() === p.status?.effect; + if (i instanceof TurnStatusEffectModifier) { + return (i as TurnStatusEffectModifier).getStatusEffect() === p.status?.effect; } return false; })).length, 3); @@ -1694,7 +1673,10 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, (party: Pokemon[]) => { return Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15), 8); }, 8), - new WeightedModifierType(modifierTypes.MAP, (party: Pokemon[]) => party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex < 180 ? 1 : 0, 1), + new WeightedModifierType(modifierTypes.MAP, + (party: Pokemon[]) => party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex < 180 ? party[0].scene.eventManager.isEventActive() ? 2 : 1 : 0, + (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 2 : 1), + new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 3 : 0), new WeightedModifierType(modifierTypes.TM_GREAT, 3), new WeightedModifierType(modifierTypes.MEMORY_MUSHROOM, (party: Pokemon[]) => { if (!party.find(p => p.getLearnableLevelMoves().length)) { @@ -1723,7 +1705,7 @@ const modifierPool: ModifierPool = { const { gameMode, gameData } = party[0].scene; if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) { return party.some(p => ((p.getSpeciesForm(true).speciesId in pokemonEvolutions) || (p.isFusion() && (p.getFusionSpeciesForm(true).speciesId in pokemonEvolutions))) - && !p.getHeldItems().some(i => i instanceof Modifiers.EvolutionStatBoosterModifier) && !p.isMax()) ? 10 : 0; + && !p.getHeldItems().some(i => i instanceof EvolutionStatBoosterModifier) && !p.isMax()) ? 10 : 0; } return 0; }), @@ -1731,29 +1713,29 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.LEEK, (party: Pokemon[]) => { const checkedSpecies = [ Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD ]; // If a party member doesn't already have a Leek and is one of the relevant species, Leek can appear - return party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.SpeciesCritBoosterModifier) + return party.some(p => !p.getHeldItems().some(i => i instanceof SpeciesCritBoosterModifier) && (checkedSpecies.includes(p.getSpeciesForm(true).speciesId) || (p.isFusion() && checkedSpecies.includes(p.getFusionSpeciesForm(true).speciesId)))) ? 12 : 0; }, 12), new WeightedModifierType(modifierTypes.TOXIC_ORB, (party: Pokemon[]) => { - const checkedAbilities = [Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.TOXIC_BOOST, Abilities.POISON_HEAL, Abilities.MAGIC_GUARD]; - const checkedMoves = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT]; + const checkedAbilities = [ Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.TOXIC_BOOST, Abilities.POISON_HEAL, Abilities.MAGIC_GUARD ]; + const checkedMoves = [ Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT ]; // If a party member doesn't already have one of these two orbs and has one of the above moves or abilities, the orb can appear - return party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.TurnStatusEffectModifier) + return party.some(p => !p.getHeldItems().some(i => i instanceof TurnStatusEffectModifier) && (checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId)))) ? 10 : 0; }, 10), new WeightedModifierType(modifierTypes.FLAME_ORB, (party: Pokemon[]) => { - const checkedAbilities = [Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.FLARE_BOOST, Abilities.MAGIC_GUARD]; - const checkedMoves = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT]; + const checkedAbilities = [ Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.FLARE_BOOST, Abilities.MAGIC_GUARD ]; + const checkedMoves = [ Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT ]; // If a party member doesn't already have one of these two orbs and has one of the above moves or abilities, the orb can appear - return party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.TurnStatusEffectModifier) + return party.some(p => !p.getHeldItems().some(i => i instanceof TurnStatusEffectModifier) && (checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId)))) ? 10 : 0; }, 10), new WeightedModifierType(modifierTypes.WHITE_HERB, (party: Pokemon[]) => { - const checkedAbilities = [Abilities.WEAK_ARMOR, Abilities.CONTRARY, Abilities.MOODY, Abilities.ANGER_SHELL, Abilities.COMPETITIVE, Abilities.DEFIANT]; + const checkedAbilities = [ Abilities.WEAK_ARMOR, Abilities.CONTRARY, Abilities.MOODY, Abilities.ANGER_SHELL, Abilities.COMPETITIVE, Abilities.DEFIANT ]; const weightMultiplier = party.filter( - p => !p.getHeldItems().some(i => i instanceof Modifiers.ResetNegativeStatStageModifier && i.stackCount >= i.getMaxHeldItemCount(p)) && + p => !p.getHeldItems().some(i => i instanceof ResetNegativeStatStageModifier && i.stackCount >= i.getMaxHeldItemCount(p)) && (checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && selfStatLowerMoves.includes(m.moveId)))).length; // If a party member has one of the above moves or abilities and doesn't have max herbs, the herb will appear more frequently return 0 * (weightMultiplier ? 2 : 1) + (weightMultiplier ? weightMultiplier * 0 : 0); @@ -1762,7 +1744,7 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)), new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9), new WeightedModifierType(modifierTypes.TM_ULTRA, 11), - new WeightedModifierType(modifierTypes.RARER_CANDY, 4), + new WeightedModifierType(modifierTypes.RARER_CANDY, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 6 : 4), new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)), new WeightedModifierType(modifierTypes.IV_SCANNER, skipInLastClassicWaveOrDefault(4)), new WeightedModifierType(modifierTypes.EXP_CHARM, skipInLastClassicWaveOrDefault(8)), @@ -1785,7 +1767,7 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.BATON, 2), new WeightedModifierType(modifierTypes.SOUL_DEW, 7), //new WeightedModifierType(modifierTypes.OVAL_CHARM, 6), - new WeightedModifierType(modifierTypes.SOOTHE_BELL, 4), + new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 0 : 4), new WeightedModifierType(modifierTypes.ABILITY_CHARM, skipInClassicAfterWave(189, 6)), new WeightedModifierType(modifierTypes.FOCUS_BAND, 5), new WeightedModifierType(modifierTypes.KINGS_ROCK, 3), @@ -1978,21 +1960,21 @@ let enemyBuffIgnoredPoolIndexes = {}; // eslint-disable-line @typescript-eslint/ export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool { let pool: ModifierPool; switch (poolType) { - case ModifierPoolType.PLAYER: - pool = modifierPool; - break; - case ModifierPoolType.WILD: - pool = wildModifierPool; - break; - case ModifierPoolType.TRAINER: - pool = trainerModifierPool; - break; - case ModifierPoolType.ENEMY_BUFF: - pool = enemyBuffModifierPool; - break; - case ModifierPoolType.DAILY_STARTER: - pool = dailyStarterModifierPool; - break; + case ModifierPoolType.PLAYER: + pool = modifierPool; + break; + case ModifierPoolType.WILD: + pool = wildModifierPool; + break; + case ModifierPoolType.TRAINER: + pool = trainerModifierPool; + break; + case ModifierPoolType.ENEMY_BUFF: + pool = enemyBuffModifierPool; + break; + case ModifierPoolType.DAILY_STARTER: + pool = dailyStarterModifierPool; + break; } return pool; } @@ -2063,23 +2045,23 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod console.table(modifierTableData); } switch (poolType) { - case ModifierPoolType.PLAYER: - modifierPoolThresholds = thresholds; - ignoredPoolIndexes = ignoredIndexes; - break; - case ModifierPoolType.WILD: - case ModifierPoolType.TRAINER: - enemyModifierPoolThresholds = thresholds; - enemyIgnoredPoolIndexes = ignoredIndexes; - break; - case ModifierPoolType.ENEMY_BUFF: - enemyBuffModifierPoolThresholds = thresholds; - enemyBuffIgnoredPoolIndexes = ignoredIndexes; - break; - case ModifierPoolType.DAILY_STARTER: - dailyStarterModifierPoolThresholds = thresholds; - ignoredDailyStarterPoolIndexes = ignoredIndexes; - break; + case ModifierPoolType.PLAYER: + modifierPoolThresholds = thresholds; + ignoredPoolIndexes = ignoredIndexes; + break; + case ModifierPoolType.WILD: + case ModifierPoolType.TRAINER: + enemyModifierPoolThresholds = thresholds; + enemyIgnoredPoolIndexes = ignoredIndexes; + break; + case ModifierPoolType.ENEMY_BUFF: + enemyBuffModifierPoolThresholds = thresholds; + enemyBuffIgnoredPoolIndexes = ignoredIndexes; + break; + case ModifierPoolType.DAILY_STARTER: + dailyStarterModifierPoolThresholds = thresholds; + ignoredDailyStarterPoolIndexes = ignoredIndexes; + break; } } @@ -2199,7 +2181,7 @@ export function overridePlayerModifierTypeOptions(options: ModifierTypeOption[], let modifierType: ModifierType | null = modifierFunc(); if (modifierType instanceof ModifierTypeGenerator) { - const pregenArgs = ("type" in override) && (override.type !== null) ? [override.type] : undefined; + const pregenArgs = ("type" in override) && (override.type !== null) ? [ override.type ] : undefined; modifierType = modifierType.generateType(party, pregenArgs); } @@ -2230,7 +2212,8 @@ export function getPlayerShopModifierTypeOptionsForWave(waveIndex: integer, base ], [ new ModifierTypeOption(modifierTypes.HYPER_POTION(), 0, baseCost * 0.8), - new ModifierTypeOption(modifierTypes.MAX_REVIVE(), 0, baseCost * 2.75) + new ModifierTypeOption(modifierTypes.MAX_REVIVE(), 0, baseCost * 2.75), + new ModifierTypeOption(modifierTypes.MEMORY_MUSHROOM(), 0, baseCost * 4) ], [ new ModifierTypeOption(modifierTypes.MAX_POTION(), 0, baseCost * 1.5), @@ -2246,47 +2229,47 @@ export function getPlayerShopModifierTypeOptionsForWave(waveIndex: integer, base return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat(); } -export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: Modifiers.PersistentModifier[], scene: BattleScene): Modifiers.EnemyPersistentModifier { +export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: PersistentModifier[], scene: BattleScene): EnemyPersistentModifier { let tierStackCount: number; switch (tier) { - case ModifierTier.ULTRA: - tierStackCount = 5; - break; - case ModifierTier.GREAT: - tierStackCount = 3; - break; - default: - tierStackCount = 1; - break; + case ModifierTier.ULTRA: + tierStackCount = 5; + break; + case ModifierTier.GREAT: + tierStackCount = 3; + break; + default: + tierStackCount = 1; + break; } const retryCount = 50; let candidate = getNewModifierTypeOption([], ModifierPoolType.ENEMY_BUFF, tier); let r = 0; - let matchingModifier: Modifiers.PersistentModifier | undefined; + let matchingModifier: PersistentModifier | undefined; while (++r < retryCount && (matchingModifier = enemyModifiers.find(m => m.type.id === candidate?.type?.id)) && matchingModifier.getMaxStackCount(scene) < matchingModifier.stackCount + (r < 10 ? tierStackCount : 1)) { candidate = getNewModifierTypeOption([], ModifierPoolType.ENEMY_BUFF, tier); } - const modifier = candidate?.type?.newModifier() as Modifiers.EnemyPersistentModifier; + const modifier = candidate?.type?.newModifier() as EnemyPersistentModifier; modifier.stackCount = tierStackCount; return modifier; } export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER, upgradeChance: integer = 0): PokemonHeldItemModifierType[] { - const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !Utils.randSeedInt(upgradeChance) ? 1 : 0)?.type as PokemonHeldItemModifierType); + const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !randSeedInt(upgradeChance) ? 1 : 0)?.type as PokemonHeldItemModifierType); if (!(waveIndex % 1000)) { ret.push(getModifierType(modifierTypes.MINI_BLACK_HOLE) as PokemonHeldItemModifierType); } return ret; } -export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.PokemonHeldItemModifier[] { - const ret: Modifiers.PokemonHeldItemModifier[] = []; +export function getDailyRunStarterModifiers(party: PlayerPokemon[]): PokemonHeldItemModifier[] { + const ret: PokemonHeldItemModifier[] = []; for (const p of party) { for (let m = 0; m < 3; m++) { - const tierValue = Utils.randSeedInt(64); + const tierValue = randSeedInt(64); let tier: ModifierTier; if (tierValue > 25) { @@ -2301,7 +2284,7 @@ export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.P tier = ModifierTier.MASTER; } - const modifier = getNewModifierTypeOption(party, ModifierPoolType.DAILY_STARTER, tier)?.type?.newModifier(p) as Modifiers.PokemonHeldItemModifier; + const modifier = getNewModifierTypeOption(party, ModifierPoolType.DAILY_STARTER, tier)?.type?.newModifier(p) as PokemonHeldItemModifier; ret.push(modifier); } } @@ -2323,24 +2306,24 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, const pool = getModifierPoolForType(poolType); let thresholds: object; switch (poolType) { - case ModifierPoolType.PLAYER: - thresholds = modifierPoolThresholds; - break; - case ModifierPoolType.WILD: - thresholds = enemyModifierPoolThresholds; - break; - case ModifierPoolType.TRAINER: - thresholds = enemyModifierPoolThresholds; - break; - case ModifierPoolType.ENEMY_BUFF: - thresholds = enemyBuffModifierPoolThresholds; - break; - case ModifierPoolType.DAILY_STARTER: - thresholds = dailyStarterModifierPoolThresholds; - break; + case ModifierPoolType.PLAYER: + thresholds = modifierPoolThresholds; + break; + case ModifierPoolType.WILD: + thresholds = enemyModifierPoolThresholds; + break; + case ModifierPoolType.TRAINER: + thresholds = enemyModifierPoolThresholds; + break; + case ModifierPoolType.ENEMY_BUFF: + thresholds = enemyBuffModifierPoolThresholds; + break; + case ModifierPoolType.DAILY_STARTER: + thresholds = dailyStarterModifierPoolThresholds; + break; } if (tier === undefined) { - const tierValue = Utils.randSeedInt(1024); + const tierValue = randSeedInt(1024); if (!upgradeCount) { upgradeCount = 0; } @@ -2349,7 +2332,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, const upgradeOdds = Math.floor(128 / ((partyLuckValue + 4) / 4)); let upgraded = false; do { - upgraded = Utils.randSeedInt(upgradeOdds) < 4; + upgraded = randSeedInt(upgradeOdds) < 4; if (upgraded) { upgradeCount++; } @@ -2381,7 +2364,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, const partyShinyCount = party.filter(p => p.isShiny() && !p.isFainted()).length; const upgradeOdds = Math.floor(32 / ((partyShinyCount + 2) / 2)); while (modifierPool.hasOwnProperty(tier + upgradeCount + 1) && modifierPool[tier + upgradeCount + 1].length) { - if (!Utils.randSeedInt(upgradeOdds)) { + if (!randSeedInt(upgradeOdds)) { upgradeCount++; } else { break; @@ -2396,7 +2379,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, const tierThresholds = Object.keys(thresholds[tier]); const totalWeight = parseInt(tierThresholds[tierThresholds.length - 1]); - const value = Utils.randSeedInt(totalWeight); + const value = randSeedInt(totalWeight); let index: integer | undefined; for (const t of tierThresholds) { const threshold = parseInt(t); @@ -2456,9 +2439,9 @@ export class ModifierTypeOption { */ export function getPartyLuckValue(party: Pokemon[]): integer { if (party[0].scene.gameMode.isDaily) { - const DailyLuck = new Utils.NumberHolder(0); + const DailyLuck = new NumberHolder(0); party[0].scene.executeWithSeedOffset(() => { - DailyLuck.value = Utils.randSeedInt(15); // Random number between 0 and 14 + DailyLuck.value = randSeedInt(15); // Random number between 0 and 14 }, 0, party[0].scene.seed); return DailyLuck.value; } diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 4c20b454081..36f94b99b20 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1,33 +1,36 @@ -import * as ModifierTypes from "#app/modifier/modifier-type"; -import { getModifierType, ModifierType, modifierTypes } from "#app/modifier/modifier-type"; -import BattleScene from "#app/battle-scene"; -import { getLevelTotalExp } from "#app/data/exp"; -import { MAX_PER_TYPE_POKEBALLS, PokeballType } from "#app/data/pokeball"; -import Pokemon, { PlayerPokemon } from "#app/field/pokemon"; -import { addTextObject, TextStyle } from "#app/ui/text"; -import { Type } from "#app/data/type"; -import { EvolutionPhase } from "#app/phases/evolution-phase"; +import type BattleScene from "#app/battle-scene"; import { FusionSpeciesFormEvolution, pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; -import { getPokemonNameWithAffix } from "#app/messages"; -import * as Utils from "#app/utils"; import { getBerryEffectFunc, getBerryPredicate } from "#app/data/berry"; -import { BattlerTagType } from "#enums/battler-tag-type"; -import { BerryType } from "#enums/berry-type"; -import { getStatusEffectHealText, StatusEffect } from "#app/data/status-effect"; -import { achvs } from "#app/system/achv"; -import { VoucherType } from "#app/system/voucher"; -import { FormChangeItem, SpeciesFormChangeItemTrigger, SpeciesFormChangeLapseTeraTrigger, SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms"; -import { Nature } from "#app/data/nature"; -import Overrides from "#app/overrides"; -import { Command } from "#app/ui/command-ui-handler"; -import { Species } from "#enums/species"; -import { BATTLE_STATS, type PermanentStat, Stat, TEMP_BATTLE_STATS, type TempBattleStat } from "#enums/stat"; -import i18next from "i18next"; +import { getLevelTotalExp } from "#app/data/exp"; import { allMoves } from "#app/data/move"; -import { Abilities } from "#enums/abilities"; -import { LearnMovePhase } from "#app/phases/learn-move-phase"; +import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball"; +import { type FormChangeItem, SpeciesFormChangeItemTrigger, SpeciesFormChangeLapseTeraTrigger, SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms"; +import { getStatusEffectHealText } from "#app/data/status-effect"; +import { Type } from "#app/data/type"; +import Pokemon, { type PlayerPokemon } from "#app/field/pokemon"; +import { getPokemonNameWithAffix } from "#app/messages"; +import Overrides from "#app/overrides"; +import { EvolutionPhase } from "#app/phases/evolution-phase"; +import { LearnMovePhase, LearnMoveType } from "#app/phases/learn-move-phase"; import { LevelUpPhase } from "#app/phases/level-up-phase"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase"; +import { achvs } from "#app/system/achv"; +import type { VoucherType } from "#app/system/voucher"; +import { Command } from "#app/ui/command-ui-handler"; +import { addTextObject, TextStyle } from "#app/ui/text"; +import { BooleanHolder, hslToHex, isNullOrUndefined, NumberHolder, toDmgValue } from "#app/utils"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { BerryType } from "#enums/berry-type"; +import type { Nature } from "#enums/nature"; +import type { PokeballType } from "#enums/pokeball"; +import { Species } from "#enums/species"; +import { type PermanentStat, type TempBattleStat, BATTLE_STATS, Stat, TEMP_BATTLE_STATS } from "#enums/stat"; +import { StatusEffect } from "#enums/status-effect"; +import i18next from "i18next"; +import { type DoubleBattleChanceBoosterModifierType, type EvolutionItemModifierType, type FormChangeItemModifierType, type ModifierOverride, type ModifierType, type PokemonBaseStatTotalModifierType, type PokemonExpBoosterModifierType, type PokemonFriendshipBoosterModifierType, type PokemonMoveAccuracyBoosterModifierType, type PokemonMultiHitModifierType, type TerastallizeModifierType, type TmModifierType, getModifierType, ModifierPoolType, ModifierTypeGenerator, modifierTypes, PokemonHeldItemModifierType } from "./modifier-type"; +import { Color, ShadowColor } from "#enums/color"; +import { FRIENDSHIP_GAIN_FROM_RARE_CANDY } from "#app/data/balance/starters"; export type ModifierPredicate = (modifier: Modifier) => boolean; @@ -84,7 +87,7 @@ export class ModifierBar extends Phaser.GameObjects.Container { const thisArg = this; - sortedVisibleIconModifiers.forEach((modifier: PersistentModifier, i: integer) => { + sortedVisibleIconModifiers.forEach((modifier: PersistentModifier, i: number) => { const icon = modifier.getIcon(this.scene as BattleScene); if (i >= iconOverflowIndex) { icon.setVisible(false); @@ -120,8 +123,8 @@ export class ModifierBar extends Phaser.GameObjects.Container { } } - setModifierIconPosition(icon: Phaser.GameObjects.Container, modifierCount: integer) { - const rowIcons: integer = 12 + 6 * Math.max((Math.ceil(Math.min(modifierCount, 24) / 12) - 2), 0); + setModifierIconPosition(icon: Phaser.GameObjects.Container, modifierCount: number) { + const rowIcons: number = 12 + 6 * Math.max((Math.ceil(Math.min(modifierCount, 24) / 12) - 2), 0); const x = (this.getIndex(icon) % rowIcons) * 26 / (rowIcons / 12); const y = Math.floor(this.getIndex(icon) / rowIcons) * 20; @@ -141,18 +144,27 @@ export abstract class Modifier { return false; } - shouldApply(_args: any[]): boolean { + /** + * Checks if {@linkcode Modifier} should be applied + * @param _args parameters passed to {@linkcode Modifier.apply} + * @returns always `true` by default + */ + shouldApply(..._args: Parameters): boolean { return true; } - abstract apply(args: any[]): boolean | Promise; + /** + * Handles applying of {@linkcode Modifier} + * @param args collection of all passed parameters + */ + abstract apply(...args: unknown[]): boolean | Promise; } export abstract class PersistentModifier extends Modifier { - public stackCount: integer; - public virtualStackCount: integer; + public stackCount: number; + public virtualStackCount: number; - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type); this.stackCount = stackCount === undefined ? 1 : stackCount; this.virtualStackCount = 0; @@ -179,7 +191,7 @@ export abstract class PersistentModifier extends Modifier { return []; } - incrementStack(scene: BattleScene, amount: integer, virtual: boolean): boolean { + incrementStack(scene: BattleScene, amount: number, virtual: boolean): boolean { if (this.getStackCount() + amount <= this.getMaxStackCount(scene)) { if (!virtual) { this.stackCount += amount; @@ -192,11 +204,11 @@ export abstract class PersistentModifier extends Modifier { return false; } - getStackCount(): integer { + getStackCount(): number { return this.stackCount + this.virtualStackCount; } - abstract getMaxStackCount(scene: BattleScene, forThreshold?: boolean): integer; + abstract getMaxStackCount(scene: BattleScene, forThreshold?: boolean): number; isIconVisible(scene: BattleScene): boolean { return true; @@ -247,25 +259,26 @@ export abstract class ConsumableModifier extends Modifier { add(_modifiers: Modifier[]): boolean { return true; } - - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 1 && args[0] instanceof BattleScene; - } } export class AddPokeballModifier extends ConsumableModifier { private pokeballType: PokeballType; - private count: integer; + private count: number; - constructor(type: ModifierType, pokeballType: PokeballType, count: integer) { + constructor(type: ModifierType, pokeballType: PokeballType, count: number) { super(type); this.pokeballType = pokeballType; this.count = count; } - apply(args: any[]): boolean { - const pokeballCounts = (args[0] as BattleScene).pokeballCounts; + /** + * Applies {@linkcode AddPokeballModifier} + * @param battleScene {@linkcode BattleScene} + * @returns always `true` + */ + override apply(battleScene: BattleScene): boolean { + const pokeballCounts = battleScene.pokeballCounts; pokeballCounts[this.pokeballType] = Math.min(pokeballCounts[this.pokeballType] + this.count, MAX_PER_TYPE_POKEBALLS); return true; @@ -274,17 +287,22 @@ export class AddPokeballModifier extends ConsumableModifier { export class AddVoucherModifier extends ConsumableModifier { private voucherType: VoucherType; - private count: integer; + private count: number; - constructor(type: ModifierType, voucherType: VoucherType, count: integer) { + constructor(type: ModifierType, voucherType: VoucherType, count: number) { super(type); this.voucherType = voucherType; this.count = count; } - apply(args: any[]): boolean { - const voucherCounts = (args[0] as BattleScene).gameData.voucherCounts; + /** + * Applies {@linkcode AddVoucherModifier} + * @param battleScene {@linkcode BattleScene} + * @returns always `true` + */ + override apply(battleScene: BattleScene): boolean { + const voucherCounts = battleScene.gameData.voucherCounts; voucherCounts[this.voucherType] += this.count; return true; @@ -308,7 +326,7 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { /** The current amount of battles the modifier will exist for */ private battleCount: number; - constructor(type: ModifierTypes.ModifierType, maxBattles: number, battleCount?: number, stackCount?: integer) { + constructor(type: ModifierType, maxBattles: number, battleCount?: number, stackCount?: number) { super(type, stackCount); this.maxBattles = maxBattles; @@ -322,7 +340,7 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { * @param modifiers {@linkcode PersistentModifier} array of the player's modifiers * @param _virtual N/A * @param _scene N/A - * @returns true if the modifier was successfully added or applied, false otherwise + * @returns `true` if the modifier was successfully added or applied, false otherwise */ add(modifiers: PersistentModifier[], _virtual: boolean, scene: BattleScene): boolean { for (const modifier of modifiers) { @@ -342,7 +360,12 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { return true; } - lapse(_args: any[]): boolean { + /** + * Lapses the {@linkcode battleCount} by 1. + * @param _args passed arguments (not in use here) + * @returns `true` if the {@linkcode battleCount} is greater than 0 + */ + public lapse(..._args: unknown[]): boolean { this.battleCount--; return this.battleCount > 0; } @@ -354,10 +377,13 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { const hue = Math.floor(120 * (this.battleCount / this.maxBattles) + 5); // Generates the color hex code with a constant saturation and lightness but varying hue - const typeHex = Utils.hslToHex(hue, 0.50, 0.90); - const strokeHex = Utils.hslToHex(hue, 0.70, 0.30); + const typeHex = hslToHex(hue, 0.5, 0.9); + const strokeHex = hslToHex(hue, 0.7, 0.3); - const battleCountText = addTextObject(scene, 27, 0, this.battleCount.toString(), TextStyle.PARTY, { fontSize: "66px", color: typeHex }); + const battleCountText = addTextObject(scene, 27, 0, this.battleCount.toString(), TextStyle.PARTY, { + fontSize: "66px", + color: typeHex, + }); battleCountText.setShadow(0, 0); battleCountText.setStroke(strokeHex, 16); battleCountText.setOrigin(1, 0); @@ -378,6 +404,14 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { this.battleCount = this.maxBattles; } + /** + * Updates an existing modifier with a new `maxBattles` and `battleCount`. + */ + setNewBattleCount(count: number): void { + this.maxBattles = count; + this.battleCount = count; + } + getMaxBattles(): number { return this.maxBattles; } @@ -399,7 +433,9 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { * @see {@linkcode apply} */ export class DoubleBattleChanceBoosterModifier extends LapsingPersistentModifier { - constructor(type: ModifierType, maxBattles:number, battleCount?: number, stackCount?: integer) { + public override type: DoubleBattleChanceBoosterModifierType; + + constructor(type: ModifierType, maxBattles:number, battleCount?: number, stackCount?: number) { super(type, maxBattles, battleCount, stackCount); } @@ -408,17 +444,16 @@ export class DoubleBattleChanceBoosterModifier extends LapsingPersistentModifier } clone(): DoubleBattleChanceBoosterModifier { - return new DoubleBattleChanceBoosterModifier(this.type as ModifierTypes.DoubleBattleChanceBoosterModifierType, this.getMaxBattles(), this.getBattleCount(), this.stackCount); + return new DoubleBattleChanceBoosterModifier(this.type, this.getMaxBattles(), this.getBattleCount(), this.stackCount); } /** * Increases the chance of a double battle occurring - * @param args [0] {@linkcode Utils.NumberHolder} for double battle chance - * @returns true if the modifier was applied + * @param doubleBattleChance {@linkcode NumberHolder} for double battle chance + * @returns true */ - apply(args: any[]): boolean { - const doubleBattleChance = args[0] as Utils.NumberHolder; - // This is divided because the chance is generated as a number from 0 to doubleBattleChance.value using Utils.randSeedInt + override apply(doubleBattleChance: NumberHolder): boolean { + // This is divided because the chance is generated as a number from 0 to doubleBattleChance.value using randSeedInt // A double battle will initiate if the generated number is 0 doubleBattleChance.value = doubleBattleChance.value / 4; @@ -467,21 +502,21 @@ export class TempStatStageBoosterModifier extends LapsingPersistentModifier { /** * Checks if {@linkcode args} contains the necessary elements and if the * incoming stat is matches {@linkcode stat}. - * @param args [0] {@linkcode TempBattleStat} being checked at the time - * [1] {@linkcode Utils.NumberHolder} N/A - * @returns true if the modifier can be applied, false otherwise + * @param tempBattleStat {@linkcode TempBattleStat} being affected + * @param statLevel {@linkcode NumberHolder} that holds the resulting value of the stat stage multiplier + * @returns `true` if the modifier can be applied, false otherwise */ - shouldApply(args: any[]): boolean { - return args && (args.length === 2) && TEMP_BATTLE_STATS.includes(args[0]) && (args[0] === this.stat) && (args[1] instanceof Utils.NumberHolder); + override shouldApply(tempBattleStat?: TempBattleStat, statLevel?: NumberHolder): boolean { + return !!tempBattleStat && !!statLevel && TEMP_BATTLE_STATS.includes(tempBattleStat) && (tempBattleStat === this.stat); } /** * Increases the incoming stat stage matching {@linkcode stat} by {@linkcode boost}. - * @param args [0] {@linkcode TempBattleStat} N/A - * [1] {@linkcode Utils.NumberHolder} that holds the resulting value of the stat stage multiplier + * @param _tempBattleStat {@linkcode TempBattleStat} N/A + * @param statLevel {@linkcode NumberHolder} that holds the resulting value of the stat stage multiplier */ - apply(args: any[]): boolean { - (args[1] as Utils.NumberHolder).value += this.boost; + override apply(_tempBattleStat: TempBattleStat, statLevel: NumberHolder): boolean { + statLevel.value += this.boost; return true; } } @@ -507,26 +542,26 @@ export class TempCritBoosterModifier extends LapsingPersistentModifier { /** * Checks if {@linkcode args} contains the necessary elements. - * @param args [1] {@linkcode Utils.NumberHolder} N/A - * @returns true if the critical-hit stage boost applies successfully + * @param critLevel {@linkcode NumberHolder} that holds the resulting critical-hit level + * @returns `true` if the critical-hit stage boost applies successfully */ - shouldApply(args: any[]): boolean { - return args && (args.length === 1) && (args[0] instanceof Utils.NumberHolder); + override shouldApply(critLevel?: NumberHolder): boolean { + return !!critLevel; } /** * Increases the current critical-hit stage value by 1. - * @param args [0] {@linkcode Utils.IntegerHolder} that holds the resulting critical-hit level - * @returns true if the critical-hit stage boost applies successfully + * @param critLevel {@linkcode NumberHolder} that holds the resulting critical-hit level + * @returns `true` if the critical-hit stage boost applies successfully */ - apply(args: any[]): boolean { - (args[0] as Utils.NumberHolder).value++; + override apply(critLevel: NumberHolder): boolean { + critLevel.value++; return true; } } export class MapModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -534,17 +569,17 @@ export class MapModifier extends PersistentModifier { return new MapModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { + override apply(..._args: unknown[]): boolean { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 1; } } export class MegaEvolutionAccessModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -552,17 +587,17 @@ export class MegaEvolutionAccessModifier extends PersistentModifier { return new MegaEvolutionAccessModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { + override apply(..._args: unknown[]): boolean { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 1; } } export class GigantamaxAccessModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -570,17 +605,22 @@ export class GigantamaxAccessModifier extends PersistentModifier { return new GigantamaxAccessModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { + /** + * Applies {@linkcode GigantamaxAccessModifier} + * @param _args N/A + * @returns always `true` + */ + apply(..._args: unknown[]): boolean { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 1; } } export class TerastallizeAccessModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -588,20 +628,25 @@ export class TerastallizeAccessModifier extends PersistentModifier { return new TerastallizeAccessModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { + /** + * Applies {@linkcode TerastallizeAccessModifier} + * @param _args N/A + * @returns always `true` + */ + override apply(..._args: unknown[]): boolean { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 1; } } export abstract class PokemonHeldItemModifier extends PersistentModifier { - public pokemonId: integer; + public pokemonId: number; public isTransferable: boolean = true; - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, stackCount); this.pokemonId = pokemonId; @@ -617,8 +662,21 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { return [ this.pokemonId ]; } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length !== 0 && args[0] instanceof Pokemon && (this.pokemonId === -1 || (args[0] as Pokemon).id === this.pokemonId); + /** + * Applies the {@linkcode PokemonHeldItemModifier} to the given {@linkcode Pokemon}. + * @param pokemon The {@linkcode Pokemon} that holds the held item + * @param args additional parameters + */ + abstract override apply(pokemon: Pokemon, ...args: unknown[]): boolean; + + /** + * Checks if {@linkcode PokemonHeldItemModifier} should be applied. + * @param pokemon The {@linkcode Pokemon} that holds the item + * @param _args N/A + * @returns if {@linkcode PokemonHeldItemModifier} should be applied + */ + override shouldApply(pokemon?: Pokemon, ..._args: unknown[]): boolean { + return !!pokemon && (this.pokemonId === -1 || pokemon.id === this.pokemonId); } isIconVisible(scene: BattleScene): boolean { @@ -667,7 +725,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { } //Applies to items with chance of activating secondary effects ie Kings Rock - getSecondaryChanceMultiplier(pokemon: Pokemon): integer { + getSecondaryChanceMultiplier(pokemon: Pokemon): number { // Temporary quickfix to stop game from freezing when the opponet uses u-turn while holding on to king's rock if (!pokemon.getLastXMoves(0)[0]) { return 1; @@ -682,41 +740,52 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { return 1; } - getMaxStackCount(scene: BattleScene, forThreshold?: boolean): integer { + getMaxStackCount(scene: BattleScene, forThreshold?: boolean): number { const pokemon = this.getPokemon(scene); if (!pokemon) { return 0; } if (pokemon.isPlayer() && forThreshold) { - return scene.getParty().map(p => this.getMaxHeldItemCount(p)).reduce((stackCount: integer, maxStackCount: integer) => Math.max(stackCount, maxStackCount), 0); + return scene.getParty().map(p => this.getMaxHeldItemCount(p)).reduce((stackCount: number, maxStackCount: number) => Math.max(stackCount, maxStackCount), 0); } return this.getMaxHeldItemCount(pokemon); } - abstract getMaxHeldItemCount(pokemon?: Pokemon): integer; + abstract getMaxHeldItemCount(pokemon?: Pokemon): number; } export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModifier { - protected battlesLeft: integer; + protected battlesLeft: number; public isTransferable: boolean = false; - constructor(type: ModifierTypes.ModifierType, pokemonId: integer, battlesLeft?: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, battlesLeft?: number, stackCount?: number) { super(type, pokemonId, stackCount); this.battlesLeft = battlesLeft!; // TODO: is this bang correct? } - lapse(args: any[]): boolean { + /** + * Lapse the {@linkcode battlesLeft} counter (reduce it by 1) + * @param _args arguments passed (not used here) + * @returns `true` if {@linkcode battlesLeft} is not null + */ + public lapse(..._args: unknown[]): boolean { return !!--this.battlesLeft; } - getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container { + /** + * Retrieve the {@linkcode Modifier | Modifiers} icon as a {@linkcode Phaser.GameObjects.Container | Container} + * @param scene The {@linkcode BattleScene} + * @param forSummary `true` if the icon is for the summary screen + * @returns the icon as a {@linkcode Phaser.GameObjects.Container | Container} + */ + public getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container { const container = super.getIcon(scene, forSummary); if (this.getPokemon(scene)?.isPlayer()) { - const battleCountText = addTextObject(scene, 27, 0, this.battlesLeft.toString(), TextStyle.PARTY, { fontSize: "66px", color: "#f89890" }); + const battleCountText = addTextObject(scene, 27, 0, this.battlesLeft.toString(), TextStyle.PARTY, { fontSize: "66px", color: Color.PINK }); battleCountText.setShadow(0, 0); - battleCountText.setStroke("#984038", 16); + battleCountText.setStroke(ShadowColor.RED, 16); battleCountText.setOrigin(1, 0); container.add(battleCountText); } @@ -724,7 +793,7 @@ export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModi return container; } - getBattlesLeft(): integer { + getBattlesLeft(): number { return this.battlesLeft; } @@ -734,10 +803,11 @@ export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModi } export class TerastallizeModifier extends LapsingPokemonHeldItemModifier { + public override type: TerastallizeModifierType; public teraType: Type; public isTransferable: boolean = false; - constructor(type: ModifierTypes.TerastallizeModifierType, pokemonId: integer, teraType: Type, battlesLeft?: integer, stackCount?: integer) { + constructor(type: TerastallizeModifierType, pokemonId: number, teraType: Type, battlesLeft?: number, stackCount?: number) { super(type, pokemonId, battlesLeft || 10, stackCount); this.teraType = teraType; @@ -751,15 +821,19 @@ export class TerastallizeModifier extends LapsingPokemonHeldItemModifier { } clone(): TerastallizeModifier { - return new TerastallizeModifier(this.type as ModifierTypes.TerastallizeModifierType, this.pokemonId, this.teraType, this.battlesLeft, this.stackCount); + return new TerastallizeModifier(this.type, this.pokemonId, this.teraType, this.battlesLeft, this.stackCount); } getArgs(): any[] { return [ this.pokemonId, this.teraType, this.battlesLeft ]; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; + /** + * Applies the {@linkcode TerastallizeModifier} to the specified {@linkcode Pokemon}. + * @param pokemon the {@linkcode Pokemon} to be terastallized + * @returns always `true` + */ + override apply(pokemon: Pokemon): boolean { if (pokemon.isPlayer()) { pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeTeraTrigger); pokemon.scene.validateAchv(achvs.TERASTALLIZE); @@ -771,10 +845,14 @@ export class TerastallizeModifier extends LapsingPokemonHeldItemModifier { return true; } - lapse(args: any[]): boolean { - const ret = super.lapse(args); + /** + * Triggers {@linkcode LapsingPokemonHeldItemModifier.lapse} and if it returns `0` a form change is triggered. + * @param pokemon THe {@linkcode Pokemon} to be terastallized + * @returns the result of {@linkcode LapsingPokemonHeldItemModifier.lapse} + */ + public override lapse(pokemon: Pokemon): boolean { + const ret = super.lapse(pokemon); if (!ret) { - const pokemon = args[0] as Pokemon; pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeLapseTeraTrigger); pokemon.updateSpritePipelineData(); } @@ -785,7 +863,7 @@ export class TerastallizeModifier extends LapsingPokemonHeldItemModifier { return 1.25; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 1; } } @@ -800,7 +878,7 @@ export class BaseStatModifier extends PokemonHeldItemModifier { protected stat: PermanentStat; public isTransferable: boolean = false; - constructor(type: ModifierType, pokemonId: integer, stat: PermanentStat, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stat: PermanentStat, stackCount?: number) { super(type, pokemonId, stackCount); this.stat = stat; } @@ -820,12 +898,23 @@ export class BaseStatModifier extends PokemonHeldItemModifier { return super.getArgs().concat(this.stat); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && Array.isArray(args[1]); + /** + * Checks if {@linkcode BaseStatModifier} should be applied to the specified {@linkcode Pokemon}. + * @param _pokemon the {@linkcode Pokemon} to be modified + * @param baseStats the base stats of the {@linkcode Pokemon} + * @returns `true` if the {@linkcode Pokemon} should be modified + */ + override shouldApply(_pokemon?: Pokemon, baseStats?: number[]): boolean { + return super.shouldApply(_pokemon, baseStats) && Array.isArray(baseStats); } - apply(args: any[]): boolean { - const baseStats = args[1] as number[]; + /** + * Applies the {@linkcode BaseStatModifier} to the specified {@linkcode Pokemon}. + * @param _pokemon the {@linkcode Pokemon} to be modified + * @param baseStats the base stats of the {@linkcode Pokemon} + * @returns always `true` + */ + override apply(_pokemon: Pokemon, baseStats: number[]): boolean { baseStats[this.stat] = Math.floor(baseStats[this.stat] * (1 + this.getStackCount() * 0.1)); return true; } @@ -834,17 +923,17 @@ export class BaseStatModifier extends PokemonHeldItemModifier { return 1.1; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return pokemon.ivs[this.stat]; } } export class EvoTrackerModifier extends PokemonHeldItemModifier { protected species: Species; - protected required: integer; + protected required: number; public isTransferable: boolean = false; - constructor(type: ModifierType, pokemonId: integer, species: Species, required: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, species: Species, required: number, stackCount?: number) { super(type, pokemonId, stackCount); this.species = species; this.required = required; @@ -859,10 +948,14 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { } getArgs(): any[] { - return super.getArgs().concat([this.species, this.required]); + return super.getArgs().concat([ this.species, this.required ]); } - apply(args: any[]): boolean { + /** + * Applies the {@linkcode EvoTrackerModifier} + * @returns always `true` + */ + override apply(): boolean { return true; } @@ -875,7 +968,7 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { this.stackCount = pokemon ? pokemon.evoCounter + pokemon.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - + pokemon.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length + + pokemon.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length : this.stackCount; const text = scene.add.bitmapText(10, 15, "item-count", this.stackCount.toString(), 11); @@ -888,9 +981,9 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { return text; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { this.stackCount = pokemon.evoCounter + pokemon.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - + pokemon.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier).length; + + pokemon.scene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length; return 999; } } @@ -899,10 +992,12 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier { * Currently used by Shuckle Juice item */ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { - private statModifier: integer; + public override type: PokemonBaseStatTotalModifierType; public isTransferable: boolean = false; - constructor(type: ModifierTypes.PokemonBaseStatTotalModifierType, pokemonId: number, statModifier: number, stackCount?: integer) { + private statModifier: number; + + constructor(type: PokemonBaseStatTotalModifierType, pokemonId: number, statModifier: number, stackCount?: number) { super(type, pokemonId, stackCount); this.statModifier = statModifier; } @@ -912,23 +1007,35 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { } override clone(): PersistentModifier { - return new PokemonBaseStatTotalModifier(this.type as ModifierTypes.PokemonBaseStatTotalModifierType, this.pokemonId, this.statModifier, this.stackCount); + return new PokemonBaseStatTotalModifier(this.type, this.pokemonId, this.statModifier, this.stackCount); } override getArgs(): any[] { return super.getArgs().concat(this.statModifier); } - override shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array; + /** + * Checks if {@linkcode PokemonBaseStatTotalModifier} should be applied to the specified {@linkcode Pokemon}. + * @param pokemon the {@linkcode Pokemon} to be modified + * @param baseStats the base stats of the {@linkcode Pokemon} + * @returns `true` if the {@linkcode Pokemon} should be modified + */ + override shouldApply(pokemon?: Pokemon, baseStats?: number[]): boolean { + return super.shouldApply(pokemon, baseStats) && Array.isArray(baseStats); } - override apply(args: any[]): boolean { + /** + * Applies the {@linkcode PokemonBaseStatTotalModifier} + * @param _pokemon the {@linkcode Pokemon} to be modified + * @param baseStats the base stats of the {@linkcode Pokemon} + * @returns always `true` + */ + override apply(_pokemon: Pokemon, baseStats: number[]): boolean { // Modifies the passed in baseStats[] array - args[1].forEach((v, i) => { + baseStats.forEach((v, i) => { // HP is affected by half as much as other stats const newVal = i === 0 ? Math.floor(v + this.statModifier / 2) : Math.floor(v + this.statModifier); - args[1][i] = Math.min(Math.max(newVal, 1), 999999); + baseStats[i] = Math.min(Math.max(newVal, 1), 999999); }); return true; @@ -938,7 +1045,7 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { return 1.2; } - override getMaxHeldItemCount(pokemon: Pokemon): integer { + override getMaxHeldItemCount(pokemon: Pokemon): number { return 2; } } @@ -970,16 +1077,28 @@ export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier { return [ ...super.getArgs(), this.statModifier, this.stats ]; } - override shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array; + /** + * Checks if the {@linkcode PokemonBaseStatFlatModifier} should be applied to the {@linkcode Pokemon}. + * @param pokemon The {@linkcode Pokemon} that holds the item + * @param baseStats The base stats of the {@linkcode Pokemon} + * @returns `true` if the {@linkcode PokemonBaseStatFlatModifier} should be applied + */ + override shouldApply(pokemon?: Pokemon, baseStats?: number[]): boolean { + return super.shouldApply(pokemon, baseStats) && Array.isArray(baseStats); } - override apply(args: any[]): boolean { + /** + * Applies the {@linkcode PokemonBaseStatFlatModifier} + * @param _pokemon The {@linkcode Pokemon} that holds the item + * @param baseStats The base stats of the {@linkcode Pokemon} + * @returns always `true` + */ + override apply(_pokemon: Pokemon, baseStats: number[]): boolean { // Modifies the passed in baseStats[] array by a flat value, only if the stat is specified in this.stats - args[1].forEach((v, i) => { + baseStats.forEach((v, i) => { if (this.stats.includes(i)) { const newVal = Math.floor(v + this.statModifier); - args[1][i] = Math.min(Math.max(newVal, 1), 999999); + baseStats[i] = Math.min(Math.max(newVal, 1), 999999); } }); @@ -990,7 +1109,7 @@ export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier { return 1.1; } - override getMaxHeldItemCount(pokemon: Pokemon): integer { + override getMaxHeldItemCount(pokemon: Pokemon): number { return 1; } } @@ -1001,7 +1120,7 @@ export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier { export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { public isTransferable: boolean = false; - constructor (type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor (type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -1017,15 +1136,28 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { return super.getArgs(); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 3 && args[2] instanceof Utils.IntegerHolder; + /** + * Checks if the {@linkcode PokemonIncrementingStatModifier} should be applied to the {@linkcode Pokemon}. + * @param pokemon The {@linkcode Pokemon} that holds the item + * @param stat The affected {@linkcode Stat} + * @param statHolder The {@linkcode NumberHolder} that holds the stat + * @returns `true` if the {@linkcode PokemonBaseStatFlatModifier} should be applied + */ + override shouldApply(pokemon?: Pokemon, stat?: Stat, statHolder?: NumberHolder): boolean { + return super.shouldApply(pokemon, stat, statHolder) && !!statHolder; } - apply(args: any[]): boolean { - // Modifies the passed in stat integer holder by +1 per stack for HP, +2 per stack for other stats + /** + * Applies the {@linkcode PokemonIncrementingStatModifier} + * @param _pokemon The {@linkcode Pokemon} that holds the item + * @param stat The affected {@linkcode Stat} + * @param statHolder The {@linkcode NumberHolder} that holds the stat + * @returns always `true` + */ + override apply(_pokemon: Pokemon, stat: Stat, statHolder: NumberHolder): boolean { + // Modifies the passed in stat number holder by +1 per stack for HP, +2 per stack for other stats // If the Macho Brace is at max stacks (50), adds additional 5% to total HP and 10% to other stats - const isHp = args[1] === Stat.HP; - const statHolder = args[2] as Utils.IntegerHolder; + const isHp = stat === Stat.HP; if (isHp) { statHolder.value += this.stackCount; @@ -1046,13 +1178,13 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { return 1.2; } - getMaxHeldItemCount(pokemon?: Pokemon): integer { + getMaxHeldItemCount(pokemon?: Pokemon): number { return 50; } } /** - * Modifier used for held items that apply {@linkcode Stat} boost(s) + * Modifier used for held items that Applies {@linkcode Stat} boost(s) * using a multiplier. * @extends PokemonHeldItemModifier * @see {@linkcode apply} @@ -1063,7 +1195,7 @@ export class StatBoosterModifier extends PokemonHeldItemModifier { /** The multiplier used to increase the relevant stat(s) */ protected multiplier: number; - constructor(type: ModifierType, pokemonId: integer, stats: Stat[], multiplier: number, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stats: Stat[], multiplier: number, stackCount?: number) { super(type, pokemonId, stackCount); this.stats = stats; @@ -1091,27 +1223,25 @@ export class StatBoosterModifier extends PokemonHeldItemModifier { /** * Checks if the incoming stat is listed in {@linkcode stats} - * @param args [0] {@linkcode Pokemon} N/A - * [1] {@linkcode Stat} being checked at the time - * [2] {@linkcode Utils.NumberHolder} N/A - * @returns true if the stat could be boosted, false otherwise + * @param _pokemon the {@linkcode Pokemon} that holds the item + * @param _stat the {@linkcode Stat} to be boosted + * @param statValue {@linkcode NumberHolder} that holds the resulting value of the stat + * @returns `true` if the stat could be boosted, false otherwise */ - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && this.stats.includes(args[1] as Stat); + override shouldApply(pokemon: Pokemon, stat: Stat, statValue: NumberHolder): boolean { + return super.shouldApply(pokemon, stat, statValue) && this.stats.includes(stat); } /** * Boosts the incoming stat by a {@linkcode multiplier} if the stat is listed * in {@linkcode stats}. - * @param args [0] {@linkcode Pokemon} N/A - * [1] {@linkcode Stat} N/A - * [2] {@linkcode Utils.NumberHolder} that holds the resulting value of the stat - * @returns true if the stat boost applies successfully, false otherwise + * @param _pokemon the {@linkcode Pokemon} that holds the item + * @param _stat the {@linkcode Stat} to be boosted + * @param statValue {@linkcode NumberHolder} that holds the resulting value of the stat + * @returns `true` if the stat boost applies successfully, false otherwise * @see shouldApply */ - apply(args: any[]): boolean { - const statValue = args[2] as Utils.NumberHolder; - + override apply(_pokemon: Pokemon, _stat: Stat, statValue: NumberHolder): boolean { statValue.value *= this.multiplier; return true; } @@ -1139,39 +1269,37 @@ export class EvolutionStatBoosterModifier extends StatBoosterModifier { /** * Checks if the stat boosts can apply and if the holder is not currently * Gigantamax'd. - * @param args [0] {@linkcode Pokemon} that holds the held item - * [1] {@linkcode Stat} N/A - * [2] {@linkcode Utils.NumberHolder} N/A - * @returns true if the stat boosts can be applied, false otherwise + * @param pokemon {@linkcode Pokemon} that holds the held item + * @param stat {@linkcode Stat} The {@linkcode Stat} to be boosted + * @param statValue {@linkcode NumberHolder} that holds the resulting value of the stat + * @returns `true` if the stat boosts can be applied, false otherwise */ - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && !(args[0] as Pokemon).isMax(); + override shouldApply(pokemon: Pokemon, stat: Stat, statValue: NumberHolder): boolean { + return super.shouldApply(pokemon, stat, statValue) && !pokemon.isMax(); } /** - * Boosts the incoming stat value by a {@linkcode multiplier} if the holder + * Boosts the incoming stat value by a {@linkcode EvolutionStatBoosterModifier.multiplier} if the holder * can evolve. Note that, if the holder is a fusion, they will receive * only half of the boost if either of the fused members are fully * evolved. However, if they are both unevolved, the full boost * will apply. - * @param args [0] {@linkcode Pokemon} that holds the held item - * [1] {@linkcode Stat} N/A - * [2] {@linkcode Utils.NumberHolder} that holds the resulting value of the stat - * @returns true if the stat boost applies successfully, false otherwise + * @param pokemon {@linkcode Pokemon} that holds the item + * @param _stat {@linkcode Stat} The {@linkcode Stat} to be boosted + * @param statValue{@linkcode NumberHolder} that holds the resulting value of the stat + * @returns `true` if the stat boost applies successfully, false otherwise * @see shouldApply */ - apply(args: any[]): boolean { - const holder = args[0] as Pokemon; - const statValue = args[2] as Utils.NumberHolder; - const isUnevolved = holder.getSpeciesForm(true).speciesId in pokemonEvolutions; + override apply(pokemon: Pokemon, stat: Stat, statValue: NumberHolder): boolean { + const isUnevolved = pokemon.getSpeciesForm(true).speciesId in pokemonEvolutions; - if (holder.isFusion() && (holder.getFusionSpeciesForm(true).speciesId in pokemonEvolutions) !== isUnevolved) { - // Half boost applied if holder is fused and either part of fusion is fully evolved + if (pokemon.isFusion() && (pokemon.getFusionSpeciesForm(true).speciesId in pokemonEvolutions) !== isUnevolved) { + // Half boost applied if pokemon is fused and either part of fusion is fully evolved statValue.value *= 1 + (this.multiplier - 1) / 2; return true; } else if (isUnevolved) { // Full boost applied if holder is unfused and unevolved or, if fused, both parts of fusion are unevolved - return super.apply(args); + return super.apply(pokemon, stat, statValue); } return false; @@ -1179,7 +1307,7 @@ export class EvolutionStatBoosterModifier extends StatBoosterModifier { } /** - * Modifier used for held items that apply {@linkcode Stat} boost(s) using a + * Modifier used for held items that Applies {@linkcode Stat} boost(s) using a * multiplier if the holder is of a specific {@linkcode Species}. * @extends StatBoosterModifier * @see {@linkcode apply} @@ -1188,7 +1316,7 @@ export class SpeciesStatBoosterModifier extends StatBoosterModifier { /** The species that the held item's stat boost(s) apply to */ private species: Species[]; - constructor(type: ModifierType, pokemonId: integer, stats: Stat[], multiplier: number, species: Species[], stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stats: Stat[], multiplier: number, species: Species[], stackCount?: number) { super(type, pokemonId, stats, multiplier, stackCount); this.species = species; @@ -1216,21 +1344,20 @@ export class SpeciesStatBoosterModifier extends StatBoosterModifier { /** * Checks if the incoming stat is listed in {@linkcode stats} and if the holder's {@linkcode Species} * (or its fused species) is listed in {@linkcode species}. - * @param args [0] {@linkcode Pokemon} that holds the held item - * [1] {@linkcode Stat} being checked at the time - * [2] {@linkcode Utils.NumberHolder} N/A - * @returns true if the stat could be boosted, false otherwise + * @param pokemon {@linkcode Pokemon} that holds the item + * @param stat {@linkcode Stat} being checked at the time + * @param statValue {@linkcode NumberHolder} that holds the resulting value of the stat + * @returns `true` if the stat could be boosted, false otherwise */ - shouldApply(args: any[]): boolean { - const holder = args[0] as Pokemon; - return super.shouldApply(args) && (this.species.includes(holder.getSpeciesForm(true).speciesId) || (holder.isFusion() && this.species.includes(holder.getFusionSpeciesForm(true).speciesId))); + override shouldApply(pokemon: Pokemon, stat: Stat, statValue: NumberHolder): boolean { + return super.shouldApply(pokemon, stat, statValue) && (this.species.includes(pokemon.getSpeciesForm(true).speciesId) || (pokemon.isFusion() && this.species.includes(pokemon.getFusionSpeciesForm(true).speciesId))); } /** * Checks if either parameter is included in the corresponding lists * @param speciesId {@linkcode Species} being checked * @param stat {@linkcode Stat} being checked - * @returns true if both parameters are in {@linkcode species} and {@linkcode stats} respectively, false otherwise + * @returns `true` if both parameters are in {@linkcode species} and {@linkcode stats} respectively, false otherwise */ contains(speciesId: Species, stat: Stat): boolean { return this.species.includes(speciesId) && this.stats.includes(stat); @@ -1246,7 +1373,7 @@ export class CritBoosterModifier extends PokemonHeldItemModifier { /** The amount of stages by which the held item increases the current critical-hit stage value */ protected stageIncrement: number; - constructor(type: ModifierType, pokemonId: integer, stageIncrement: number, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stageIncrement: number, stackCount?: number) { super(type, pokemonId, stackCount); this.stageIncrement = stageIncrement; @@ -1270,13 +1397,11 @@ export class CritBoosterModifier extends PokemonHeldItemModifier { /** * Increases the current critical-hit stage value by {@linkcode stageIncrement}. - * @param args [0] {@linkcode Pokemon} N/A - * [1] {@linkcode Utils.IntegerHolder} that holds the resulting critical-hit level - * @returns true if the critical-hit stage boost applies successfully, false otherwise + * @param _pokemon {@linkcode Pokemon} N/A + * @param critStage {@linkcode NumberHolder} that holds the resulting critical-hit level + * @returns always `true` */ - apply(args: any[]): boolean { - const critStage = args[1] as Utils.NumberHolder; - + override apply(_pokemon: Pokemon, critStage: NumberHolder): boolean { critStage.value += this.stageIncrement; return true; } @@ -1296,7 +1421,7 @@ export class SpeciesCritBoosterModifier extends CritBoosterModifier { /** The species that the held item's critical-hit stage boost applies to */ private species: Species[]; - constructor(type: ModifierType, pokemonId: integer, stageIncrement: number, species: Species[], stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stageIncrement: number, species: Species[], stackCount?: number) { super(type, pokemonId, stageIncrement, stackCount); this.species = species; @@ -1317,14 +1442,12 @@ export class SpeciesCritBoosterModifier extends CritBoosterModifier { /** * Checks if the holder's {@linkcode Species} (or its fused species) is listed * in {@linkcode species}. - * @param args [0] {@linkcode Pokemon} that holds the held item - * [1] {@linkcode Utils.IntegerHolder} N/A - * @returns true if the critical-hit level can be incremented, false otherwise + * @param pokemon {@linkcode Pokemon} that holds the held item + * @param critStage {@linkcode NumberHolder} that holds the resulting critical-hit level + * @returns `true` if the critical-hit level can be incremented, false otherwise */ - shouldApply(args: any[]) { - const holder = args[0] as Pokemon; - - return super.shouldApply(args) && (this.species.includes(holder.getSpeciesForm(true).speciesId) || (holder.isFusion() && this.species.includes(holder.getFusionSpeciesForm(true).speciesId))); + override shouldApply(pokemon: Pokemon, critStage: NumberHolder): boolean { + return super.shouldApply(pokemon, critStage) && (this.species.includes(pokemon.getSpeciesForm(true).speciesId) || (pokemon.isFusion() && this.species.includes(pokemon.getFusionSpeciesForm(true).speciesId))); } } @@ -1335,7 +1458,7 @@ export class AttackTypeBoosterModifier extends PokemonHeldItemModifier { public moveType: Type; private boostMultiplier: number; - constructor(type: ModifierType, pokemonId: integer, moveType: Type, boostPercent: number, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, moveType: Type, boostPercent: number, stackCount?: number) { super(type, pokemonId, stackCount); this.moveType = moveType; @@ -1359,20 +1482,27 @@ export class AttackTypeBoosterModifier extends PokemonHeldItemModifier { return super.getArgs().concat([ this.moveType, this.boostMultiplier * 100 ]); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 3 && typeof args[1] === "number" && args[2] instanceof Utils.NumberHolder; + /** + * Checks if {@linkcode AttackTypeBoosterModifier} should be applied + * @param pokemon the {@linkcode Pokemon} that holds the held item + * @param moveType the {@linkcode Type} of the move being used + * @param movePower the {@linkcode NumberHolder} that holds the power of the move + * @returns `true` if boosts should be applied to the move. + */ + override shouldApply(pokemon?: Pokemon, moveType?: Type, movePower?: NumberHolder): boolean { + return super.shouldApply(pokemon, moveType, movePower) && typeof moveType === "number" && movePower instanceof NumberHolder; } /** - * @param {Array} args Array - * - Index 0: {Pokemon} Pokemon - * - Index 1: {number} Move type - * - Index 2: {Utils.NumberHolder} Move power - * @returns {boolean} Returns true if boosts have been applied to the move. - */ - apply(args: any[]): boolean { - if (args[1] === this.moveType && (args[2] as Utils.NumberHolder).value >= 1) { - (args[2] as Utils.NumberHolder).value = Math.floor((args[2] as Utils.NumberHolder).value * (1 + (this.getStackCount() * this.boostMultiplier))); + * Applies {@linkcode AttackTypeBoosterModifier} + * @param pokemon {@linkcode Pokemon} that holds the held item + * @param moveType {@linkcode Type} of the move being used + * @param movePower {@linkcode NumberHolder} that holds the power of the move + * @returns `true` if boosts have been applied to the move. + */ + override apply(_pokemon: Pokemon, moveType: Type, movePower: NumberHolder): boolean { + if (moveType === this.moveType && movePower.value >= 1) { + (movePower as NumberHolder).value = Math.floor((movePower as NumberHolder).value * (1 + (this.getStackCount() * this.boostMultiplier))); return true; } @@ -1383,13 +1513,13 @@ export class AttackTypeBoosterModifier extends PokemonHeldItemModifier { return 1.2; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 99; } } export class SurviveDamageModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -1401,14 +1531,23 @@ export class SurviveDamageModifier extends PokemonHeldItemModifier { return new SurviveDamageModifier(this.type, this.pokemonId, this.stackCount); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.BooleanHolder; + /** + * Checks if the {@linkcode SurviveDamageModifier} should be applied + * @param pokemon the {@linkcode Pokemon} that holds the item + * @param surviveDamage {@linkcode BooleanHolder} that holds the survive damage + * @returns `true` if the {@linkcode SurviveDamageModifier} should be applied + */ + override shouldApply(pokemon?: Pokemon, surviveDamage?: BooleanHolder): boolean { + return super.shouldApply(pokemon, surviveDamage) && !!surviveDamage; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - const surviveDamage = args[1] as Utils.BooleanHolder; - + /** + * Applies {@linkcode SurviveDamageModifier} + * @param pokemon the {@linkcode Pokemon} that holds the item + * @param surviveDamage {@linkcode BooleanHolder} that holds the survive damage + * @returns `true` if the survive damage has been applied + */ + override apply(pokemon: Pokemon, surviveDamage: BooleanHolder): boolean { if (!surviveDamage.value && pokemon.randSeedInt(10) < this.getStackCount()) { surviveDamage.value = true; @@ -1419,13 +1558,13 @@ export class SurviveDamageModifier extends PokemonHeldItemModifier { return false; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 5; } } export class BypassSpeedChanceModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -1437,18 +1576,27 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier { return new BypassSpeedChanceModifier(this.type, this.pokemonId, this.stackCount); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.BooleanHolder; + /** + * Checks if {@linkcode BypassSpeedChanceModifier} should be applied + * @param pokemon the {@linkcode Pokemon} that holds the item + * @param doBypassSpeed {@linkcode BooleanHolder} that is `true` if speed should be bypassed + * @returns `true` if {@linkcode BypassSpeedChanceModifier} should be applied + */ + override shouldApply(pokemon?: Pokemon, doBypassSpeed?: BooleanHolder): boolean { + return super.shouldApply(pokemon, doBypassSpeed) && !!doBypassSpeed; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - const bypassSpeed = args[1] as Utils.BooleanHolder; - - if (!bypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) { - bypassSpeed.value = true; + /** + * Applies {@linkcode BypassSpeedChanceModifier} + * @param pokemon the {@linkcode Pokemon} that holds the item + * @param doBypassSpeed {@linkcode BooleanHolder} that is `true` if speed should be bypassed + * @returns `true` if {@linkcode BypassSpeedChanceModifier} has been applied + */ + override apply(pokemon: Pokemon, doBypassSpeed: BooleanHolder): boolean { + if (!doBypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) { + doBypassSpeed.value = true; const isCommandFight = pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT; - const hasQuickClaw = this.type instanceof ModifierTypes.PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW"; + const hasQuickClaw = this.type instanceof PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW"; if (isCommandFight && hasQuickClaw) { pokemon.scene.queueMessage(i18next.t("modifier:bypassSpeedChanceApply", { pokemonName: getPokemonNameWithAffix(pokemon), itemName: i18next.t("modifierType:ModifierType.QUICK_CLAW.name") })); @@ -1459,13 +1607,13 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier { return false; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 3; } } export class FlinchChanceModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -1477,14 +1625,23 @@ export class FlinchChanceModifier extends PokemonHeldItemModifier { return new FlinchChanceModifier(this.type, this.pokemonId, this.stackCount); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.BooleanHolder; + /** + * Checks if {@linkcode FlinchChanceModifier} should be applied + * @param pokemon the {@linkcode Pokemon} that holds the item + * @param flinched {@linkcode BooleanHolder} that is `true` if the pokemon flinched + * @returns `true` if {@linkcode FlinchChanceModifier} should be applied + */ + override shouldApply(pokemon?: Pokemon, flinched?: BooleanHolder): boolean { + return super.shouldApply(pokemon, flinched) && !!flinched; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - const flinched = args[1] as Utils.BooleanHolder; - + /** + * Applies {@linkcode FlinchChanceModifier} + * @param pokemon the {@linkcode Pokemon} that holds the item + * @param flinched {@linkcode BooleanHolder} that is `true` if the pokemon flinched + * @returns `true` if {@linkcode FlinchChanceModifier} has been applied + */ + override apply(pokemon: Pokemon, flinched: BooleanHolder): boolean { if (!flinched.value && pokemon.randSeedInt(10) < (this.getStackCount() * this.getSecondaryChanceMultiplier(pokemon))) { flinched.value = true; return true; @@ -1493,13 +1650,13 @@ export class FlinchChanceModifier extends PokemonHeldItemModifier { return false; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 3; } } export class TurnHealModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -1511,20 +1668,23 @@ export class TurnHealModifier extends PokemonHeldItemModifier { return new TurnHealModifier(this.type, this.pokemonId, this.stackCount); } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - + /** + * Applies {@linkcode TurnHealModifier} + * @param pokemon The {@linkcode Pokemon} that holds the item + * @returns `true` if the {@linkcode Pokemon} was healed + */ + override apply(pokemon: Pokemon): boolean { if (!pokemon.isFullHp()) { const scene = pokemon.scene; scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(), - Utils.toDmgValue(pokemon.getMaxHp() / 16) * this.stackCount, i18next.t("modifier:turnHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), true)); + toDmgValue(pokemon.getMaxHp() / 16) * this.stackCount, i18next.t("modifier:turnHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), true)); return true; } return false; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 4; } } @@ -1539,16 +1699,16 @@ export class TurnStatusEffectModifier extends PokemonHeldItemModifier { /** The status effect to be applied by the held item */ private effect: StatusEffect; - constructor (type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor (type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); switch (type.id) { - case "TOXIC_ORB": - this.effect = StatusEffect.TOXIC; - break; - case "FLAME_ORB": - this.effect = StatusEffect.BURN; - break; + case "TOXIC_ORB": + this.effect = StatusEffect.TOXIC; + break; + case "FLAME_ORB": + this.effect = StatusEffect.BURN; + break; } } @@ -1559,7 +1719,7 @@ export class TurnStatusEffectModifier extends PokemonHeldItemModifier { * would be the only item able to {@linkcode apply} successfully. * @override * @param modifier {@linkcode Modifier} being type tested - * @return true if {@linkcode modifier} is an instance of + * @return `true` if {@linkcode modifier} is an instance of * TurnStatusEffectModifier, false otherwise */ matchType(modifier: Modifier): boolean { @@ -1572,15 +1732,14 @@ export class TurnStatusEffectModifier extends PokemonHeldItemModifier { /** * Tries to inflicts the holder with the associated {@linkcode StatusEffect}. - * @param args [0] {@linkcode Pokemon} that holds the held item - * @returns true if the status effect was applied successfully, false if - * otherwise + * @param pokemon {@linkcode Pokemon} that holds the held item + * @returns `true` if the status effect was applied successfully */ - apply(args: any[]): boolean { - return (args[0] as Pokemon).trySetStatus(this.effect, true, undefined, undefined, this.type.name); + override apply(pokemon: Pokemon): boolean { + return pokemon.trySetStatus(this.effect, true, undefined, undefined, this.type.name); } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 1; } @@ -1590,7 +1749,7 @@ export class TurnStatusEffectModifier extends PokemonHeldItemModifier { } export class HitHealModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -1602,25 +1761,28 @@ export class HitHealModifier extends PokemonHeldItemModifier { return new HitHealModifier(this.type, this.pokemonId, this.stackCount); } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - + /** + * Applies {@linkcode HitHealModifier} + * @param pokemon The {@linkcode Pokemon} that holds the item + * @returns `true` if the {@linkcode Pokemon} was healed + */ + override apply(pokemon: Pokemon): boolean { if (pokemon.turnData.damageDealt && !pokemon.isFullHp()) { const scene = pokemon.scene; scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(), - Utils.toDmgValue(pokemon.turnData.damageDealt / 8) * this.stackCount, i18next.t("modifier:hitHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), true)); + toDmgValue(pokemon.turnData.damageDealt / 8) * this.stackCount, i18next.t("modifier:hitHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), true)); } return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 4; } } export class LevelIncrementBoosterModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -1632,12 +1794,22 @@ export class LevelIncrementBoosterModifier extends PersistentModifier { return new LevelIncrementBoosterModifier(this.type, this.stackCount); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args[0] instanceof Utils.IntegerHolder; + /** + * Checks if {@linkcode LevelIncrementBoosterModifier} should be applied + * @param count {@linkcode NumberHolder} holding the level increment count + * @returns `true` if {@linkcode LevelIncrementBoosterModifier} should be applied + */ + override shouldApply(count: NumberHolder): boolean { + return !!count; } - apply(args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value += this.getStackCount(); + /** + * Applies {@linkcode LevelIncrementBoosterModifier} + * @param count {@linkcode NumberHolder} holding the level increment count + * @returns always `true` + */ + override apply(count: NumberHolder): boolean { + count.value += this.getStackCount(); return true; } @@ -1651,7 +1823,7 @@ export class BerryModifier extends PokemonHeldItemModifier { public berryType: BerryType; public consumed: boolean; - constructor(type: ModifierType, pokemonId: integer, berryType: BerryType, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, berryType: BerryType, stackCount?: number) { super(type, pokemonId, stackCount); this.berryType = berryType; @@ -1670,14 +1842,22 @@ export class BerryModifier extends PokemonHeldItemModifier { return super.getArgs().concat(this.berryType); } - shouldApply(args: any[]): boolean { - return !this.consumed && super.shouldApply(args) && getBerryPredicate(this.berryType)(args[0] as Pokemon); + /** + * Checks if {@linkcode BerryModifier} should be applied + * @param pokemon The {@linkcode Pokemon} that holds the berry + * @returns `true` if {@linkcode BerryModifier} should be applied + */ + override shouldApply(pokemon: Pokemon): boolean { + return !this.consumed && super.shouldApply(pokemon) && getBerryPredicate(this.berryType)(pokemon); } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - - const preserve = new Utils.BooleanHolder(false); + /** + * Applies {@linkcode BerryModifier} + * @param pokemon The {@linkcode Pokemon} that holds the berry + * @returns always `true` + */ + override apply(pokemon: Pokemon): boolean { + const preserve = new BooleanHolder(false); pokemon.scene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve); getBerryEffectFunc(this.berryType)(pokemon); @@ -1688,8 +1868,8 @@ export class BerryModifier extends PokemonHeldItemModifier { return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { - if ([BerryType.LUM, BerryType.LEPPA, BerryType.SITRUS, BerryType.ENIGMA].includes(this.berryType)) { + getMaxHeldItemCount(pokemon: Pokemon): number { + if ([ BerryType.LUM, BerryType.LEPPA, BerryType.SITRUS, BerryType.ENIGMA ].includes(this.berryType)) { return 2; } return 3; @@ -1697,7 +1877,7 @@ export class BerryModifier extends PokemonHeldItemModifier { } export class PreserveBerryModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -1709,25 +1889,37 @@ export class PreserveBerryModifier extends PersistentModifier { return new PreserveBerryModifier(this.type, this.stackCount); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args[0] instanceof Pokemon && args[1] instanceof Utils.BooleanHolder; + /** + * Checks if all prequired conditions are met to apply {@linkcode PreserveBerryModifier} + * @param pokemon {@linkcode Pokemon} that holds the berry + * @param doPreserve {@linkcode BooleanHolder} that is `true` if the berry should be preserved + * @returns `true` if {@linkcode PreserveBerryModifier} should be applied + */ + override shouldApply(pokemon?: Pokemon, doPreserve?: BooleanHolder): boolean { + return !!pokemon && !!doPreserve; } - apply(args: any[]): boolean { - if (!(args[1] as Utils.BooleanHolder).value) { - (args[1] as Utils.BooleanHolder).value = (args[0] as Pokemon).randSeedInt(10) < this.getStackCount() * 3; + /** + * Applies {@linkcode PreserveBerryModifier} + * @param pokemon The {@linkcode Pokemon} that holds the berry + * @param doPreserve {@linkcode BooleanHolder} that is `true` if the berry should be preserved + * @returns always `true` + */ + override apply(pokemon: Pokemon, doPreserve: BooleanHolder): boolean { + if (!doPreserve.value) { + doPreserve.value = pokemon.randSeedInt(10) < this.getStackCount() * 3; } return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 3; } } export class PokemonInstantReviveModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -1739,17 +1931,20 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier { return new PokemonInstantReviveModifier(this.type, this.pokemonId, this.stackCount); } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - + /** + * Applies {@linkcode PokemonInstantReviveModifier} + * @param pokemon The {@linkcode Pokemon} that holds the item + * @returns always `true` + */ + override apply(pokemon: Pokemon): boolean { pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), - Utils.toDmgValue(pokemon.getMaxHp() / 2), i18next.t("modifier:pokemonInstantReviveApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), false, false, true)); + toDmgValue(pokemon.getMaxHp() / 2), i18next.t("modifier:pokemonInstantReviveApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), false, false, true)); pokemon.resetStatus(true, false, true); return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 1; } } @@ -1761,7 +1956,7 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier { * @see {@linkcode apply} */ export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -1776,11 +1971,10 @@ export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier { /** * Goes through the holder's stat stages and, if any are negative, resets that * stat stage back to 0. - * @param args [0] {@linkcode Pokemon} that holds the held item - * @returns true if any stat stages were reset, false otherwise + * @param pokemon {@linkcode Pokemon} that holds the item + * @returns `true` if any stat stages were reset, false otherwise */ - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; + override apply(pokemon: Pokemon): boolean { let statRestored = false; for (const s of BATTLE_STATS) { @@ -1796,36 +1990,49 @@ export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier { return statRestored; } - getMaxHeldItemCount(_pokemon: Pokemon): integer { + getMaxHeldItemCount(_pokemon: Pokemon): number { return 2; } } export abstract class ConsumablePokemonModifier extends ConsumableModifier { - public pokemonId: integer; + public pokemonId: number; - constructor(type: ModifierType, pokemonId: integer) { + constructor(type: ModifierType, pokemonId: number) { super(type); this.pokemonId = pokemonId; } - shouldApply(args: any[]): boolean { - return args.length !== 0 && args[0] instanceof PlayerPokemon && (this.pokemonId === -1 || (args[0] as PlayerPokemon).id === this.pokemonId); + /** + * Checks if {@linkcode ConsumablePokemonModifier} should be applied + * @param playerPokemon The {@linkcode PlayerPokemon} that consumes the item + * @param _args N/A + * @returns `true` if {@linkcode ConsumablePokemonModifier} should be applied + */ + override shouldApply(playerPokemon?: PlayerPokemon, ..._args: unknown[]): boolean { + return !!playerPokemon && (this.pokemonId === -1 || playerPokemon.id === this.pokemonId); } + /** + * Applies {@linkcode ConsumablePokemonModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that consumes the item + * @param args Additional arguments passed to {@linkcode ConsumablePokemonModifier.apply} + */ + abstract override apply(playerPokemon: PlayerPokemon, ...args: unknown[]): boolean | Promise; + getPokemon(scene: BattleScene) { return scene.getParty().find(p => p.id === this.pokemonId); } } export class PokemonHpRestoreModifier extends ConsumablePokemonModifier { - private restorePoints: integer; + private restorePoints: number; private restorePercent: number; private healStatus: boolean; public fainted: boolean; - constructor(type: ModifierType, pokemonId: integer, restorePoints: integer, restorePercent: number, healStatus: boolean, fainted?: boolean) { + constructor(type: ModifierType, pokemonId: number, restorePoints: number, restorePercent: number, healStatus: boolean, fainted?: boolean) { super(type, pokemonId); this.restorePoints = restorePoints; @@ -1834,16 +2041,27 @@ export class PokemonHpRestoreModifier extends ConsumablePokemonModifier { this.fainted = !!fainted; } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && (this.fainted || (args.length > 1 && typeof(args[1]) === "number")); + /** + * Checks if {@linkcode PokemonHpRestoreModifier} should be applied + * @param playerPokemon The {@linkcode PlayerPokemon} that consumes the item + * @param multiplier The multiplier of the hp restore + * @returns `true` if the {@linkcode PokemonHpRestoreModifier} should be applied + */ + override shouldApply(playerPokemon?: PlayerPokemon, multiplier?: number): boolean { + return super.shouldApply(playerPokemon) && (this.fainted || (!isNullOrUndefined(multiplier) && typeof(multiplier) === "number")); } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; + /** + * Applies {@linkcode PokemonHpRestoreModifier} + * @param pokemon The {@linkcode PlayerPokemon} that consumes the item + * @param multiplier The multiplier of the hp restore + * @returns `true` if hp was restored + */ + override apply(pokemon: Pokemon, multiplier: number): boolean { if (!pokemon.hp === this.fainted) { let restorePoints = this.restorePoints; if (!this.fainted) { - restorePoints = Math.floor(restorePoints * (args[1] as number)); + restorePoints = Math.floor(restorePoints * multiplier); } if (this.fainted || this.healStatus) { pokemon.resetStatus(true, true); @@ -1856,21 +2074,25 @@ export class PokemonHpRestoreModifier extends ConsumablePokemonModifier { } export class PokemonStatusHealModifier extends ConsumablePokemonModifier { - constructor(type: ModifierType, pokemonId: integer) { + constructor(type: ModifierType, pokemonId: number) { super(type, pokemonId); } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - pokemon.resetStatus(true, true); + /** + * Applies {@linkcode PokemonStatusHealModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that gets healed from the status + * @returns always `true` + */ + override apply(playerPokemon: PlayerPokemon): boolean { + playerPokemon.resetStatus(true, true); return true; } } export abstract class ConsumablePokemonMoveModifier extends ConsumablePokemonModifier { - public moveIndex: integer; + public moveIndex: number; - constructor(type: ModifierType, pokemonId: integer, moveIndex: integer) { + constructor(type: ModifierType, pokemonId: number, moveIndex: number) { super(type, pokemonId); this.moveIndex = moveIndex; @@ -1878,36 +2100,49 @@ export abstract class ConsumablePokemonMoveModifier extends ConsumablePokemonMod } export class PokemonPpRestoreModifier extends ConsumablePokemonMoveModifier { - private restorePoints: integer; + private restorePoints: number; - constructor(type: ModifierType, pokemonId: integer, moveIndex: integer, restorePoints: integer) { + constructor(type: ModifierType, pokemonId: number, moveIndex: number, restorePoints: number) { super(type, pokemonId, moveIndex); this.restorePoints = restorePoints; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - const move = pokemon.getMoveset()[this.moveIndex]!; //TODO: is the bang correct? - move.ppUsed = this.restorePoints > -1 ? Math.max(move.ppUsed - this.restorePoints, 0) : 0; + /** + * Applies {@linkcode PokemonPpRestoreModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that should get move pp restored + * @returns always `true` + */ + override apply(playerPokemon: PlayerPokemon): boolean { + const move = playerPokemon.getMoveset()[this.moveIndex]; + + if (move) { + move.ppUsed = this.restorePoints > -1 ? Math.max(move.ppUsed - this.restorePoints, 0) : 0; + } return true; } } export class PokemonAllMovePpRestoreModifier extends ConsumablePokemonModifier { - private restorePoints: integer; + private restorePoints: number; - constructor(type: ModifierType, pokemonId: integer, restorePoints: integer) { + constructor(type: ModifierType, pokemonId: number, restorePoints: number) { super(type, pokemonId); this.restorePoints = restorePoints; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - for (const move of pokemon.getMoveset()) { - move!.ppUsed = this.restorePoints > -1 ? Math.max(move!.ppUsed - this.restorePoints, 0) : 0; // TODO: are those bangs correct? + /** + * Applies {@linkcode PokemonAllMovePpRestoreModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that should get all move pp restored + * @returns always `true` + */ + override apply(playerPokemon: PlayerPokemon): boolean { + for (const move of playerPokemon.getMoveset()) { + if (move) { + move.ppUsed = this.restorePoints > -1 ? Math.max(move.ppUsed - this.restorePoints, 0) : 0; + } } return true; @@ -1915,18 +2150,25 @@ export class PokemonAllMovePpRestoreModifier extends ConsumablePokemonModifier { } export class PokemonPpUpModifier extends ConsumablePokemonMoveModifier { - private upPoints: integer; + private upPoints: number; - constructor(type: ModifierType, pokemonId: integer, moveIndex: integer, upPoints: integer) { + constructor(type: ModifierType, pokemonId: number, moveIndex: number, upPoints: number) { super(type, pokemonId, moveIndex); this.upPoints = upPoints; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - const move = pokemon.getMoveset()[this.moveIndex]!; // TODO: is the bang correct? - move.ppUp = Math.min(move.ppUp + this.upPoints, 3); + /** + * Applies {@linkcode PokemonPpUpModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that gets a pp up on move-slot {@linkcode moveIndex} + * @returns + */ + override apply(playerPokemon: PlayerPokemon): boolean { + const move = playerPokemon.getMoveset()[this.moveIndex]; + + if (move && !move.maxPpOverride) { + move.ppUp = Math.min(move.ppUp + this.upPoints, 3); + } return true; } @@ -1935,21 +2177,25 @@ export class PokemonPpUpModifier extends ConsumablePokemonMoveModifier { export class PokemonNatureChangeModifier extends ConsumablePokemonModifier { public nature: Nature; - constructor(type: ModifierType, pokemonId: integer, nature: Nature) { + constructor(type: ModifierType, pokemonId: number, nature: Nature) { super(type, pokemonId); this.nature = nature; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - pokemon.natureOverride = this.nature; - let speciesId = pokemon.species.speciesId; - pokemon.scene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1); + /** + * Applies {@linkcode PokemonNatureChangeModifier} + * @param playerPokemon {@linkcode PlayerPokemon} to apply the {@linkcode Nature} change to + * @returns + */ + override apply(playerPokemon: PlayerPokemon): boolean { + playerPokemon.customPokemonData.nature = this.nature; + let speciesId = playerPokemon.species.speciesId; + playerPokemon.scene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1); while (pokemonPrevolutions.hasOwnProperty(speciesId)) { speciesId = pokemonPrevolutions[speciesId]; - pokemon.scene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1); + playerPokemon.scene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1); } return true; @@ -1957,86 +2203,105 @@ export class PokemonNatureChangeModifier extends ConsumablePokemonModifier { } export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier { - constructor(type: ModifierType, pokemonId: integer) { + constructor(type: ModifierType, pokemonId: number) { super(type, pokemonId); } - apply(args: any[]): boolean { - const pokemon = args[0] as PlayerPokemon; - const levelCount = new Utils.IntegerHolder(1); - pokemon.scene.applyModifiers(LevelIncrementBoosterModifier, true, levelCount); + /** + * Applies {@linkcode PokemonLevelIncrementModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that should get levels incremented + * @param levelCount The amount of levels to increment + * @returns always `true` + */ + override apply(playerPokemon: PlayerPokemon, levelCount: NumberHolder = new NumberHolder(1)): boolean { + playerPokemon.scene.applyModifiers(LevelIncrementBoosterModifier, true, levelCount); - pokemon.level += levelCount.value; - if (pokemon.level <= pokemon.scene.getMaxExpLevel(true)) { - pokemon.exp = getLevelTotalExp(pokemon.level, pokemon.species.growthRate); - pokemon.levelExp = 0; + playerPokemon.level += levelCount.value; + if (playerPokemon.level <= playerPokemon.scene.getMaxExpLevel(true)) { + playerPokemon.exp = getLevelTotalExp(playerPokemon.level, playerPokemon.species.growthRate); + playerPokemon.levelExp = 0; } - pokemon.addFriendship(5); + playerPokemon.addFriendship(FRIENDSHIP_GAIN_FROM_RARE_CANDY); - pokemon.scene.unshiftPhase(new LevelUpPhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), pokemon.level - levelCount.value, pokemon.level)); + playerPokemon.scene.unshiftPhase(new LevelUpPhase(playerPokemon.scene, playerPokemon.scene.getParty().indexOf(playerPokemon), playerPokemon.level - levelCount.value, playerPokemon.level)); return true; } } export class TmModifier extends ConsumablePokemonModifier { - constructor(type: ModifierTypes.TmModifierType, pokemonId: integer) { + public override type: TmModifierType; + + constructor(type: TmModifierType, pokemonId: number) { super(type, pokemonId); } - apply(args: any[]): boolean { - const pokemon = args[0] as PlayerPokemon; + /** + * Applies {@linkcode TmModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that should learn the TM + * @returns always `true` + */ + override apply(playerPokemon: PlayerPokemon): boolean { - pokemon.scene.unshiftPhase(new LearnMovePhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), (this.type as ModifierTypes.TmModifierType).moveId, true)); + playerPokemon.scene.unshiftPhase(new LearnMovePhase(playerPokemon.scene, playerPokemon.scene.getParty().indexOf(playerPokemon), this.type.moveId, LearnMoveType.TM)); return true; } } export class RememberMoveModifier extends ConsumablePokemonModifier { - public levelMoveIndex: integer; + public levelMoveIndex: number; - constructor(type: ModifierTypes.ModifierType, pokemonId: integer, levelMoveIndex: integer) { + constructor(type: ModifierType, pokemonId: number, levelMoveIndex: number) { super(type, pokemonId); this.levelMoveIndex = levelMoveIndex; } - apply(args: any[]): boolean { - const pokemon = args[0] as PlayerPokemon; + /** + * Applies {@linkcode RememberMoveModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that should remember the move + * @returns always `true` + */ + override apply(playerPokemon: PlayerPokemon, cost?: number): boolean { - pokemon.scene.unshiftPhase(new LearnMovePhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), pokemon.getLearnableLevelMoves()[this.levelMoveIndex])); + playerPokemon.scene.unshiftPhase(new LearnMovePhase(playerPokemon.scene, playerPokemon.scene.getParty().indexOf(playerPokemon), playerPokemon.getLearnableLevelMoves()[this.levelMoveIndex], LearnMoveType.MEMORY, cost)); return true; } } export class EvolutionItemModifier extends ConsumablePokemonModifier { - constructor(type: ModifierTypes.EvolutionItemModifierType, pokemonId: integer) { + public override type: EvolutionItemModifierType; + + constructor(type: EvolutionItemModifierType, pokemonId: number) { super(type, pokemonId); } - apply(args: any[]): boolean { - const pokemon = args[0] as PlayerPokemon; - - let matchingEvolution = pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) - ? pokemonEvolutions[pokemon.species.speciesId].find(e => e.item === (this.type as ModifierTypes.EvolutionItemModifierType).evolutionItem - && (e.evoFormKey === null || (e.preFormKey || "") === pokemon.getFormKey()) - && (!e.condition || e.condition.predicate(pokemon))) + /** + * Applies {@linkcode EvolutionItemModifier} + * @param playerPokemon The {@linkcode PlayerPokemon} that should evolve via item + * @returns `true` if the evolution was successful + */ + override apply(playerPokemon: PlayerPokemon): boolean { + let matchingEvolution = pokemonEvolutions.hasOwnProperty(playerPokemon.species.speciesId) + ? pokemonEvolutions[playerPokemon.species.speciesId].find(e => e.item === this.type.evolutionItem + && (e.evoFormKey === null || (e.preFormKey || "") === playerPokemon.getFormKey()) + && (!e.condition || e.condition.predicate(playerPokemon))) : null; - if (!matchingEvolution && pokemon.isFusion()) { - matchingEvolution = pokemonEvolutions[pokemon.fusionSpecies!.speciesId].find(e => e.item === (this.type as ModifierTypes.EvolutionItemModifierType).evolutionItem // TODO: is the bang correct? - && (e.evoFormKey === null || (e.preFormKey || "") === pokemon.getFusionFormKey()) - && (!e.condition || e.condition.predicate(pokemon))); + if (!matchingEvolution && playerPokemon.isFusion()) { + matchingEvolution = pokemonEvolutions[playerPokemon.fusionSpecies!.speciesId].find(e => e.item === this.type.evolutionItem // TODO: is the bang correct? + && (e.evoFormKey === null || (e.preFormKey || "") === playerPokemon.getFusionFormKey()) + && (!e.condition || e.condition.predicate(playerPokemon))); if (matchingEvolution) { - matchingEvolution = new FusionSpeciesFormEvolution(pokemon.species.speciesId, matchingEvolution); + matchingEvolution = new FusionSpeciesFormEvolution(playerPokemon.species.speciesId, matchingEvolution); } } if (matchingEvolution) { - pokemon.scene.unshiftPhase(new EvolutionPhase(pokemon.scene, pokemon, matchingEvolution, pokemon.level - 1)); + playerPokemon.scene.unshiftPhase(new EvolutionPhase(playerPokemon.scene, playerPokemon, matchingEvolution, playerPokemon.level - 1)); return true; } @@ -2045,27 +2310,38 @@ export class EvolutionItemModifier extends ConsumablePokemonModifier { } export class FusePokemonModifier extends ConsumablePokemonModifier { - public fusePokemonId: integer; + public fusePokemonId: number; - constructor(type: ModifierType, pokemonId: integer, fusePokemonId: integer) { + constructor(type: ModifierType, pokemonId: number, fusePokemonId: number) { super(type, pokemonId); this.fusePokemonId = fusePokemonId; } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args[1] instanceof PlayerPokemon && this.fusePokemonId === (args[1] as PlayerPokemon).id; + /** + * Checks if {@linkcode FusePokemonModifier} should be applied + * @param playerPokemon {@linkcode PlayerPokemon} that should be fused + * @param playerPokemon2 {@linkcode PlayerPokemon} that should be fused with {@linkcode playerPokemon} + * @returns `true` if {@linkcode FusePokemonModifier} should be applied + */ + override shouldApply(playerPokemon?: PlayerPokemon, playerPokemon2?: PlayerPokemon): boolean { + return super.shouldApply(playerPokemon, playerPokemon2) && !!playerPokemon2 && this.fusePokemonId === playerPokemon2.id; } - apply(args: any[]): Promise { - return new Promise(resolve => { - (args[0] as PlayerPokemon).fuse(args[1] as PlayerPokemon).then(() => resolve(true)); - }); + /** + * Applies {@linkcode FusePokemonModifier} + * @param playerPokemon {@linkcode PlayerPokemon} that should be fused + * @param playerPokemon2 {@linkcode PlayerPokemon} that should be fused with {@linkcode playerPokemon} + * @returns always Promise + */ + override async apply(playerPokemon: PlayerPokemon, playerPokemon2: PlayerPokemon): Promise { + await playerPokemon.fuse(playerPokemon2); + return true; } } export class MultipleParticipantExpBonusModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2073,7 +2349,11 @@ export class MultipleParticipantExpBonusModifier extends PersistentModifier { return modifier instanceof MultipleParticipantExpBonusModifier; } - apply(_args: any[]): boolean { + /** + * Applies {@linkcode MultipleParticipantExpBonusModifier} + * @returns always `true` + */ + apply(): boolean { return true; } @@ -2081,7 +2361,7 @@ export class MultipleParticipantExpBonusModifier extends PersistentModifier { return new MultipleParticipantExpBonusModifier(this.type, this.stackCount); } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 5; } } @@ -2089,7 +2369,7 @@ export class MultipleParticipantExpBonusModifier extends PersistentModifier { export class HealingBoosterModifier extends PersistentModifier { private multiplier: number; - constructor(type: ModifierType, multiplier: number, stackCount?: integer) { + constructor(type: ModifierType, multiplier: number, stackCount?: number) { super(type, stackCount); this.multiplier = multiplier; @@ -2107,22 +2387,26 @@ export class HealingBoosterModifier extends PersistentModifier { return [ this.multiplier ]; } - apply(args: any[]): boolean { - const healingMultiplier = args[0] as Utils.IntegerHolder; + /** + * Applies {@linkcode HealingBoosterModifier} + * @param healingMultiplier the multiplier to apply to the healing + * @returns always `true` + */ + override apply(healingMultiplier: NumberHolder): boolean { healingMultiplier.value *= 1 + ((this.multiplier - 1) * this.getStackCount()); return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 5; } } export class ExpBoosterModifier extends PersistentModifier { - private boostMultiplier: integer; + private boostMultiplier: number; - constructor(type: ModifierType, boostPercent: number, stackCount?: integer) { + constructor(type: ModifierType, boostPercent: number, stackCount?: number) { super(type, stackCount); this.boostMultiplier = boostPercent * 0.01; @@ -2144,21 +2428,28 @@ export class ExpBoosterModifier extends PersistentModifier { return [ this.boostMultiplier * 100 ]; } - apply(args: any[]): boolean { - (args[0] as Utils.NumberHolder).value = Math.floor((args[0] as Utils.NumberHolder).value * (1 + (this.getStackCount() * this.boostMultiplier))); + /** + * Applies {@linkcode ExpBoosterModifier} + * @param boost {@linkcode NumberHolder} holding the boost value + * @returns always `true` + */ + override apply(boost: NumberHolder): boolean { + boost.value = Math.floor(boost.value * (1 + (this.getStackCount() * this.boostMultiplier))); return true; } - getMaxStackCount(scene: BattleScene, forThreshold?: boolean): integer { + getMaxStackCount(scene: BattleScene, forThreshold?: boolean): number { return this.boostMultiplier < 1 ? this.boostMultiplier < 0.6 ? 99 : 30 : 10; } } export class PokemonExpBoosterModifier extends PokemonHeldItemModifier { - private boostMultiplier: integer; + public override type: PokemonExpBoosterModifierType; - constructor(type: ModifierTypes.PokemonExpBoosterModifierType, pokemonId: integer, boostPercent: number, stackCount?: integer) { + private boostMultiplier: number; + + constructor(type: PokemonExpBoosterModifierType, pokemonId: number, boostPercent: number, stackCount?: number) { super(type, pokemonId, stackCount); this.boostMultiplier = boostPercent * 0.01; } @@ -2172,30 +2463,42 @@ export class PokemonExpBoosterModifier extends PokemonHeldItemModifier { } clone(): PersistentModifier { - return new PokemonExpBoosterModifier(this.type as ModifierTypes.PokemonExpBoosterModifierType, this.pokemonId, this.boostMultiplier * 100, this.stackCount); + return new PokemonExpBoosterModifier(this.type, this.pokemonId, this.boostMultiplier * 100, this.stackCount); } getArgs(): any[] { return super.getArgs().concat(this.boostMultiplier * 100); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.NumberHolder; + /** + * Checks if {@linkcode PokemonExpBoosterModifier} should be applied + * @param pokemon The {@linkcode Pokemon} to apply the exp boost to + * @param boost {@linkcode NumberHolder} holding the exp boost value + * @returns `true` if {@linkcode PokemonExpBoosterModifier} should be applied + */ + override shouldApply(pokemon: Pokemon, boost: NumberHolder): boolean { + return super.shouldApply(pokemon, boost) && !!boost; } - apply(args: any[]): boolean { - (args[1] as Utils.NumberHolder).value = Math.floor((args[1] as Utils.NumberHolder).value * (1 + (this.getStackCount() * this.boostMultiplier))); + /** + * Applies {@linkcode PokemonExpBoosterModifier} + * @param _pokemon The {@linkcode Pokemon} to apply the exp boost to + * @param boost {@linkcode NumberHolder} holding the exp boost value + * @returns always `true` + */ + override apply(_pokemon: Pokemon, boost: NumberHolder): boolean { + boost.value = Math.floor(boost.value * (1 + (this.getStackCount() * this.boostMultiplier))); return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 99; } } export class ExpShareModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2207,17 +2510,21 @@ export class ExpShareModifier extends PersistentModifier { return new ExpShareModifier(this.type, this.stackCount); } - apply(_args: any[]): boolean { + /** + * Applies {@linkcode ExpShareModifier} + * @returns always `true` + */ + override apply(): boolean { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 5; } } export class ExpBalanceModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2229,17 +2536,23 @@ export class ExpBalanceModifier extends PersistentModifier { return new ExpBalanceModifier(this.type, this.stackCount); } - apply(_args: any[]): boolean { + /** + * Applies {@linkcode ExpBalanceModifier} + * @returns always `true` + */ + override apply(): boolean { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 4; } } export class PokemonFriendshipBoosterModifier extends PokemonHeldItemModifier { - constructor(type: ModifierTypes.PokemonFriendshipBoosterModifierType, pokemonId: integer, stackCount?: integer) { + public override type: PokemonFriendshipBoosterModifierType; + + constructor(type: PokemonFriendshipBoosterModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -2248,23 +2561,28 @@ export class PokemonFriendshipBoosterModifier extends PokemonHeldItemModifier { } clone(): PersistentModifier { - return new PokemonFriendshipBoosterModifier(this.type as ModifierTypes.PokemonFriendshipBoosterModifierType, this.pokemonId, this.stackCount); + return new PokemonFriendshipBoosterModifier(this.type, this.pokemonId, this.stackCount); } - apply(args: any[]): boolean { - const friendship = args[1] as Utils.IntegerHolder; + /** + * Applies {@linkcode PokemonFriendshipBoosterModifier} + * @param _pokemon The {@linkcode Pokemon} to apply the friendship boost to + * @param friendship {@linkcode NumberHolder} holding the friendship boost value + * @returns always `true` + */ + override apply(_pokemon: Pokemon, friendship: NumberHolder): boolean { friendship.value = Math.floor(friendship.value * (1 + 0.5 * this.getStackCount())); return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 3; } } export class PokemonNatureWeightModifier extends PokemonHeldItemModifier { - constructor(type: ModifierTypes.ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -2276,8 +2594,13 @@ export class PokemonNatureWeightModifier extends PokemonHeldItemModifier { return new PokemonNatureWeightModifier(this.type, this.pokemonId, this.stackCount); } - apply(args: any[]): boolean { - const multiplier = args[1] as Utils.IntegerHolder; + /** + * Applies {@linkcode PokemonNatureWeightModifier} + * @param _pokemon The {@linkcode Pokemon} to apply the nature weight to + * @param multiplier {@linkcode NumberHolder} holding the nature weight + * @returns `true` if multiplier was applied + */ + override apply(_pokemon: Pokemon, multiplier: NumberHolder): boolean { if (multiplier.value !== 1) { multiplier.value += 0.1 * this.getStackCount() * (multiplier.value > 1 ? 1 : -1); return true; @@ -2286,15 +2609,16 @@ export class PokemonNatureWeightModifier extends PokemonHeldItemModifier { return false; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 10; } } export class PokemonMoveAccuracyBoosterModifier extends PokemonHeldItemModifier { - private accuracyAmount: integer; + public override type: PokemonMoveAccuracyBoosterModifierType; + private accuracyAmount: number; - constructor(type: ModifierTypes.PokemonMoveAccuracyBoosterModifierType, pokemonId: integer, accuracy: integer, stackCount?: integer) { + constructor(type: PokemonMoveAccuracyBoosterModifierType, pokemonId: number, accuracy: number, stackCount?: number) { super(type, pokemonId, stackCount); this.accuracyAmount = accuracy; } @@ -2308,31 +2632,44 @@ export class PokemonMoveAccuracyBoosterModifier extends PokemonHeldItemModifier } clone(): PersistentModifier { - return new PokemonMoveAccuracyBoosterModifier(this.type as ModifierTypes.PokemonMoveAccuracyBoosterModifierType, this.pokemonId, this.accuracyAmount, this.stackCount); + return new PokemonMoveAccuracyBoosterModifier(this.type, this.pokemonId, this.accuracyAmount, this.stackCount); } getArgs(): any[] { return super.getArgs().concat(this.accuracyAmount); } - shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.NumberHolder; + /** + * Checks if {@linkcode PokemonMoveAccuracyBoosterModifier} should be applied + * @param pokemon The {@linkcode Pokemon} to apply the move accuracy boost to + * @param moveAccuracy {@linkcode NumberHolder} holding the move accuracy boost + * @returns `true` if {@linkcode PokemonMoveAccuracyBoosterModifier} should be applied + */ + override shouldApply(pokemon?: Pokemon, moveAccuracy?: NumberHolder): boolean { + return super.shouldApply(pokemon, moveAccuracy) && !!moveAccuracy; } - apply(args: any[]): boolean { - const moveAccuracy = (args[1] as Utils.IntegerHolder); + /** + * Applies {@linkcode PokemonMoveAccuracyBoosterModifier} + * @param _pokemon The {@linkcode Pokemon} to apply the move accuracy boost to + * @param moveAccuracy {@linkcode NumberHolder} holding the move accuracy boost + * @returns always `true` + */ + override apply(_pokemon: Pokemon, moveAccuracy: NumberHolder): boolean { moveAccuracy.value = Math.min(moveAccuracy.value + this.accuracyAmount * this.getStackCount(), 100); return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 3; } } export class PokemonMultiHitModifier extends PokemonHeldItemModifier { - constructor(type: ModifierTypes.PokemonMultiHitModifierType, pokemonId: integer, stackCount?: integer) { + public override type: PokemonMultiHitModifierType; + + constructor(type: PokemonMultiHitModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -2341,39 +2678,46 @@ export class PokemonMultiHitModifier extends PokemonHeldItemModifier { } clone(): PersistentModifier { - return new PokemonMultiHitModifier(this.type as ModifierTypes.PokemonMultiHitModifierType, this.pokemonId, this.stackCount); + return new PokemonMultiHitModifier(this.type, this.pokemonId, this.stackCount); } - apply(args: any[]): boolean { - (args[1] as Utils.IntegerHolder).value *= (this.getStackCount() + 1); + /** + * Applies {@linkcode PokemonMultiHitModifier} + * @param _pokemon The {@linkcode Pokemon} using the move + * @param count {@linkcode NumberHolder} holding the number of items + * @param power {@linkcode NumberHolder} holding the power of the move + * @returns always `true` + */ + override apply(_pokemon: Pokemon, count: NumberHolder, power: NumberHolder): boolean { + count.value *= (this.getStackCount() + 1); - const power = args[2] as Utils.NumberHolder; switch (this.getStackCount()) { - case 1: - power.value *= 0.4; - break; - case 2: - power.value *= 0.25; - break; - case 3: - power.value *= 0.175; - break; + case 1: + power.value *= 0.4; + break; + case 2: + power.value *= 0.25; + break; + case 3: + power.value *= 0.175; + break; } return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 3; } } export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier { + public override type: FormChangeItemModifierType; public formChangeItem: FormChangeItem; public active: boolean; public isTransferable: boolean = false; - constructor(type: ModifierTypes.FormChangeItemModifierType, pokemonId: integer, formChangeItem: FormChangeItem, active: boolean, stackCount?: integer) { + constructor(type: FormChangeItemModifierType, pokemonId: number, formChangeItem: FormChangeItem, active: boolean, stackCount?: number) { super(type, pokemonId, stackCount); this.formChangeItem = formChangeItem; this.active = active; @@ -2384,17 +2728,20 @@ export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier { } clone(): PersistentModifier { - return new PokemonFormChangeItemModifier(this.type as ModifierTypes.FormChangeItemModifierType, this.pokemonId, this.formChangeItem, this.active, this.stackCount); + return new PokemonFormChangeItemModifier(this.type, this.pokemonId, this.formChangeItem, this.active, this.stackCount); } getArgs(): any[] { return super.getArgs().concat(this.formChangeItem, this.active); } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - const active = args[1] as boolean; - + /** + * Applies {@linkcode PokemonFormChangeItemModifier} + * @param pokemon The {@linkcode Pokemon} to apply the form change item to + * @param active `true` if the form change item is active + * @returns `true` if the form change item was applied + */ + override apply(pokemon: Pokemon, active: boolean): boolean { const switchActive = this.active && !active; if (switchActive) { @@ -2410,7 +2757,7 @@ export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier { return ret; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 1; } } @@ -2424,19 +2771,23 @@ export class MoneyRewardModifier extends ConsumableModifier { this.moneyMultiplier = moneyMultiplier; } - apply(args: any[]): boolean { - const scene = args[0] as BattleScene; - const moneyAmount = new Utils.IntegerHolder(scene.getWaveMoneyAmount(this.moneyMultiplier)); + /** + * Applies {@linkcode MoneyRewardModifier} + * @param battleScene The current {@linkcode BattleScene} + * @returns always `true` + */ + override apply(battleScene: BattleScene): boolean { + const moneyAmount = new NumberHolder(battleScene.getWaveMoneyAmount(this.moneyMultiplier)); - scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); + battleScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); - scene.addMoney(moneyAmount.value); + battleScene.addMoney(moneyAmount.value); - scene.getParty().map(p => { + battleScene.getParty().map(p => { if (p.species?.speciesId === Species.GIMMIGHOUL || p.fusionSpecies?.speciesId === Species.GIMMIGHOUL) { p.evoCounter ? p.evoCounter++ : p.evoCounter = 1; const modifier = getModifierType(modifierTypes.EVOLUTION_TRACKER_GIMMIGHOUL).newModifier(p) as EvoTrackerModifier; - scene.addModifier(modifier); + battleScene.addModifier(modifier); } }); @@ -2445,7 +2796,7 @@ export class MoneyRewardModifier extends ConsumableModifier { } export class MoneyMultiplierModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2457,19 +2808,24 @@ export class MoneyMultiplierModifier extends PersistentModifier { return new MoneyMultiplierModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value += Math.floor((args[0] as Utils.IntegerHolder).value * 0.2 * this.getStackCount()); + /** + * Applies {@linkcode MoneyMultiplierModifier} + * @param multiplier {@linkcode NumberHolder} holding the money multiplier value + * @returns always `true` + */ + override apply(multiplier: NumberHolder): boolean { + multiplier.value += Math.floor(multiplier.value * 0.2 * this.getStackCount()); return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 5; } } export class DamageMoneyRewardModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -2481,22 +2837,28 @@ export class DamageMoneyRewardModifier extends PokemonHeldItemModifier { return new DamageMoneyRewardModifier(this.type, this.pokemonId, this.stackCount); } - apply(args: any[]): boolean { - const scene = (args[0] as Pokemon).scene; - const moneyAmount = new Utils.IntegerHolder(Math.floor((args[1] as Utils.IntegerHolder).value * (0.5 * this.getStackCount()))); - scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); - scene.addMoney(moneyAmount.value); + /** + * Applies {@linkcode DamageMoneyRewardModifier} + * @param pokemon The {@linkcode Pokemon} attacking + * @param multiplier {@linkcode NumberHolder} holding the multiplier value + * @returns always `true` + */ + override apply(pokemon: Pokemon, multiplier: NumberHolder): boolean { + const battleScene = pokemon.scene; + const moneyAmount = new NumberHolder(Math.floor(multiplier.value * (0.5 * this.getStackCount()))); + battleScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); + battleScene.addMoney(moneyAmount.value); return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 5; } } export class MoneyInterestModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2504,15 +2866,19 @@ export class MoneyInterestModifier extends PersistentModifier { return modifier instanceof MoneyInterestModifier; } - apply(args: any[]): boolean { - const scene = args[0] as BattleScene; - const interestAmount = Math.floor(scene.money * 0.1 * this.getStackCount()); - scene.addMoney(interestAmount); + /** + * Applies {@linkcode MoneyInterestModifier} + * @param battleScene The current {@linkcode BattleScene} + * @returns always `true` + */ + override apply(battleScene: BattleScene): boolean { + const interestAmount = Math.floor(battleScene.money * 0.1 * this.getStackCount()); + battleScene.addMoney(interestAmount); const userLocale = navigator.language || "en-US"; const formattedMoneyAmount = interestAmount.toLocaleString(userLocale); const message = i18next.t("modifier:moneyInterestApply", { moneyAmount: formattedMoneyAmount, typeName: this.type.name }); - scene.queueMessage(message, undefined, true); + battleScene.queueMessage(message, undefined, true); return true; } @@ -2521,13 +2887,13 @@ export class MoneyInterestModifier extends PersistentModifier { return new MoneyInterestModifier(this.type, this.stackCount); } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 5; } } export class HiddenAbilityRateBoosterModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2539,19 +2905,24 @@ export class HiddenAbilityRateBoosterModifier extends PersistentModifier { return new HiddenAbilityRateBoosterModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value *= Math.pow(2, -1 - this.getStackCount()); + /** + * Applies {@linkcode HiddenAbilityRateBoosterModifier} + * @param boost {@linkcode NumberHolder} holding the boost value + * @returns always `true` + */ + override apply(boost: NumberHolder): boolean { + boost.value *= Math.pow(2, -1 - this.getStackCount()); return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 4; } } export class ShinyRateBoosterModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2563,19 +2934,24 @@ export class ShinyRateBoosterModifier extends PersistentModifier { return new ShinyRateBoosterModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value *= Math.pow(2, 1 + this.getStackCount()); + /** + * Applies {@linkcode ShinyRateBoosterModifier} + * @param boost {@linkcode NumberHolder} holding the boost value + * @returns always `true` + */ + override apply(boost: NumberHolder): boolean { + boost.value *= Math.pow(2, 1 + this.getStackCount()); return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 4; } } export class LockModifierTiersModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2583,7 +2959,11 @@ export class LockModifierTiersModifier extends PersistentModifier { return modifier instanceof LockModifierTiersModifier; } - apply(args: any[]): boolean { + /** + * Applies {@linkcode LockModifierTiersModifier} + * @returns always `true` + */ + override apply(): boolean { return true; } @@ -2591,7 +2971,7 @@ export class LockModifierTiersModifier extends PersistentModifier { return new LockModifierTiersModifier(this.type, this.stackCount); } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 1; } } @@ -2602,7 +2982,7 @@ export class LockModifierTiersModifier extends PersistentModifier { export class HealShopCostModifier extends PersistentModifier { public readonly shopMultiplier: number; - constructor(type: ModifierType, shopMultiplier: number, stackCount?: integer) { + constructor(type: ModifierType, shopMultiplier: number, stackCount?: number) { super(type, stackCount); this.shopMultiplier = shopMultiplier ?? 2.5; @@ -2616,8 +2996,12 @@ export class HealShopCostModifier extends PersistentModifier { return new HealShopCostModifier(this.type, this.shopMultiplier, this.stackCount); } - apply(args: any[]): boolean { - const moneyCost = args[0] as Utils.NumberHolder; + /** + * Applies {@linkcode HealShopCostModifier} + * @param cost {@linkcode NumberHolder} holding the heal shop cost + * @returns always `true` + */ + apply(moneyCost: NumberHolder): boolean { moneyCost.value = Math.floor(moneyCost.value * this.shopMultiplier); return true; @@ -2627,13 +3011,13 @@ export class HealShopCostModifier extends PersistentModifier { return super.getArgs().concat(this.shopMultiplier); } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 1; } } export class BoostBugSpawnModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2645,17 +3029,21 @@ export class BoostBugSpawnModifier extends PersistentModifier { return new BoostBugSpawnModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { + /** + * Applies {@linkcode BoostBugSpawnModifier} + * @returns always `true` + */ + override apply(): boolean { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 1; } } export class SwitchEffectTransferModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -2667,11 +3055,15 @@ export class SwitchEffectTransferModifier extends PokemonHeldItemModifier { return new SwitchEffectTransferModifier(this.type, this.pokemonId, this.stackCount); } - apply(args: any[]): boolean { + /** + * Applies {@linkcode SwitchEffectTransferModifier} + * @returns always `true` + */ + override apply(): boolean { return true; } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 1; } } @@ -2682,18 +3074,17 @@ export class SwitchEffectTransferModifier extends PokemonHeldItemModifier { * @see {@linkcode ContactHeldItemTransferChanceModifier} */ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } /** * Determines the targets to transfer items from when this applies. - * @param args\[0\] the {@linkcode Pokemon} holding this item + * @param pokemon the {@linkcode Pokemon} holding this item + * @param _args N/A * @returns the opponents of the source {@linkcode Pokemon} */ - getTargets(args: any[]): Pokemon[] { - const pokemon = args[0]; - + getTargets(pokemon?: Pokemon, ..._args: unknown[]): Pokemon[] { return pokemon instanceof Pokemon ? pokemon.getOpponents() : []; @@ -2702,12 +3093,13 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { /** * Steals an item from a set of target Pokemon. * This prioritizes high-tier held items when selecting the item to steal. - * @param args \[0\] The {@linkcode Pokemon} holding this item - * @returns true if an item was stolen; false otherwise. + * @param pokemon The {@linkcode Pokemon} holding this item + * @param target The {@linkcode Pokemon} to steal from (optional) + * @param _args N/A + * @returns `true` if an item was stolen; false otherwise. */ - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - const opponents = this.getTargets(args); + override apply(pokemon: Pokemon, target?: Pokemon, ..._args: unknown[]): boolean { + const opponents = this.getTargets(pokemon, target); if (!opponents.length) { return false; @@ -2720,9 +3112,9 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { return false; } - const poolType = pokemon.isPlayer() ? ModifierTypes.ModifierPoolType.PLAYER : pokemon.hasTrainer() ? ModifierTypes.ModifierPoolType.TRAINER : ModifierTypes.ModifierPoolType.WILD; + const poolType = pokemon.isPlayer() ? ModifierPoolType.PLAYER : pokemon.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD; - const transferredModifierTypes: ModifierTypes.ModifierType[] = []; + const transferredModifierTypes: ModifierType[] = []; const itemModifiers = pokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === targetPokemon.id && m.isTransferable, targetPokemon.isPlayer()) as PokemonHeldItemModifier[]; let highestItemTier = itemModifiers.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier!, highestTier), 0); // TODO: is this bang correct? @@ -2758,9 +3150,9 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { return !!transferredModifierTypes.length; } - abstract getTransferredItemCount(): integer; + abstract getTransferredItemCount(): number; - abstract getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierTypes.ModifierType): string; + abstract getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierType): string; } /** @@ -2770,7 +3162,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { */ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier { isTransferable: boolean = true; - constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, stackCount?: number) { super(type, pokemonId, stackCount); } @@ -2782,15 +3174,15 @@ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier { return new TurnHeldItemTransferModifier(this.type, this.pokemonId, this.stackCount); } - getTransferredItemCount(): integer { + getTransferredItemCount(): number { return this.getStackCount(); } - getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierTypes.ModifierType): string { + getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierType): string { return i18next.t("modifier:turnHeldItemTransferApply", { pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon), itemName: item.name, pokemonName: pokemon.getNameToRender(), typeName: this.type.name }); } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 1; } @@ -2806,9 +3198,9 @@ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier { * @see {@linkcode HeldItemTransferModifier} */ export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModifier { - private chance: number; + public readonly chance: number; - constructor(type: ModifierType, pokemonId: integer, chancePercent: number, stackCount?: integer) { + constructor(type: ModifierType, pokemonId: number, chancePercent: number, stackCount?: number) { super(type, pokemonId, stackCount); this.chance = chancePercent / 100; @@ -2816,16 +3208,12 @@ export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModif /** * Determines the target to steal items from when this applies. - * @param args\[0\] The {@linkcode Pokemon} holding this item - * @param args\[1\] The {@linkcode Pokemon} the holder is targeting with an attack - * @returns The target (args[1]) stored in array format for use in {@linkcode HeldItemTransferModifier.apply} + * @param _holderPokemon The {@linkcode Pokemon} holding this item + * @param targetPokemon The {@linkcode Pokemon} the holder is targeting with an attack + * @returns The target {@linkcode Pokemon} as array for further use in `apply` implementations */ - getTargets(args: any[]): Pokemon[] { - const target = args[1]; - - return target instanceof Pokemon - ? [ target ] - : []; + override getTargets(_holderPokemon: Pokemon, targetPokemon: Pokemon): Pokemon[] { + return !!targetPokemon ? [ targetPokemon ] : []; } matchType(modifier: Modifier): boolean { @@ -2840,21 +3228,21 @@ export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModif return super.getArgs().concat(this.chance * 100); } - getTransferredItemCount(): integer { + getTransferredItemCount(): number { return Phaser.Math.RND.realInRange(0, 1) < (this.chance * this.getStackCount()) ? 1 : 0; } - getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierTypes.ModifierType): string { + getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierType): string { return i18next.t("modifier:contactHeldItemTransferApply", { pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon), itemName: item.name, pokemonName: getPokemonNameWithAffix(pokemon), typeName: this.type.name }); } - getMaxHeldItemCount(pokemon: Pokemon): integer { + getMaxHeldItemCount(pokemon: Pokemon): number { return 5; } } export class IvScannerModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2866,17 +3254,21 @@ export class IvScannerModifier extends PersistentModifier { return new IvScannerModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { + /** + * Applies {@linkcode IvScannerModifier} + * @returns always `true` + */ + override apply(): boolean { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 3; } } export class ExtraModifierModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } @@ -2888,23 +3280,82 @@ export class ExtraModifierModifier extends PersistentModifier { return new ExtraModifierModifier(this.type, this.stackCount); } - apply(args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value += this.getStackCount(); + /** + * Applies {@linkcode ExtraModifierModifier} + * @param count {NumberHolder} holding the count value + * @returns always `true` + */ + override apply(count: NumberHolder): boolean { + count.value += this.getStackCount(); return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 3; } } +/** + * Modifier used for timed boosts to the player's shop item rewards. + * @extends LapsingPersistentModifier + * @see {@linkcode apply} + */ +export class TempExtraModifierModifier extends LapsingPersistentModifier { + constructor(type: ModifierType, maxBattles: number, battleCount?: number, stackCount?: number) { + super(type, maxBattles, battleCount, stackCount); + } + + /** + * Goes through existing modifiers for any that match Silver Pokeball, + * which will then add the max count of the new item to the existing count of the current item. + * If no existing Silver Pokeballs are found, will add a new one. + * @param modifiers {@linkcode PersistentModifier} array of the player's modifiers + * @param _virtual N/A + * @param scene + * @returns true if the modifier was successfully added or applied, false otherwise + */ + add(modifiers: PersistentModifier[], _virtual: boolean, scene: BattleScene): boolean { + for (const modifier of modifiers) { + if (this.match(modifier)) { + const modifierInstance = modifier as TempExtraModifierModifier; + const newBattleCount = this.getMaxBattles() + modifierInstance.getBattleCount(); + + modifierInstance.setNewBattleCount(newBattleCount); + scene.playSound("se/restore"); + return true; + } + } + + modifiers.push(this); + return true; + } + + clone() { + return new TempExtraModifierModifier(this.type, this.getMaxBattles(), this.getBattleCount(), this.stackCount); + } + + match(modifier: Modifier): boolean { + return (modifier instanceof TempExtraModifierModifier); + } + + /** + * Increases the current rewards in the battle by the `stackCount`. + * @returns `true` if the shop reward number modifier applies successfully + * @param count {@linkcode NumberHolder} that holds the resulting shop item reward count + */ + apply(count: NumberHolder): boolean { + count.value += this.getStackCount(); + return true; + } +} + export abstract class EnemyPersistentModifier extends PersistentModifier { - constructor(type: ModifierType, stackCount?: integer) { + constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 5; } } @@ -2912,25 +3363,30 @@ export abstract class EnemyPersistentModifier extends PersistentModifier { abstract class EnemyDamageMultiplierModifier extends EnemyPersistentModifier { protected damageMultiplier: number; - constructor(type: ModifierType, damageMultiplier: number, stackCount?: integer) { + constructor(type: ModifierType, damageMultiplier: number, stackCount?: number) { super(type, stackCount); this.damageMultiplier = damageMultiplier; } - apply(args: any[]): boolean { - (args[0] as Utils.NumberHolder).value = Math.floor((args[0] as Utils.NumberHolder).value * Math.pow(this.damageMultiplier, this.getStackCount())); + /** + * Applies {@linkcode EnemyDamageMultiplierModifier} + * @param multiplier {NumberHolder} holding the multiplier value + * @returns always `true` + */ + override apply(multiplier: NumberHolder): boolean { + multiplier.value = Math.floor(multiplier.value * Math.pow(this.damageMultiplier, this.getStackCount())); return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 99; } } export class EnemyDamageBoosterModifier extends EnemyDamageMultiplierModifier { - constructor(type: ModifierType, boostPercent: number, stackCount?: integer) { + constructor(type: ModifierType, boostPercent: number, stackCount?: number) { //super(type, 1 + ((boostPercent || 10) * 0.01), stackCount); super(type, 1.05, stackCount); // Hardcode multiplier temporarily } @@ -2947,13 +3403,13 @@ export class EnemyDamageBoosterModifier extends EnemyDamageMultiplierModifier { return [ (this.damageMultiplier - 1) * 100 ]; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 999; } } export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier { - constructor(type: ModifierType, reductionPercent: number, stackCount?: integer) { + constructor(type: ModifierType, reductionPercent: number, stackCount?: number) { //super(type, 1 - ((reductionPercent || 5) * 0.01), stackCount); super(type, 0.975, stackCount); // Hardcode multiplier temporarily } @@ -2970,7 +3426,7 @@ export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier { return [ (1 - this.damageMultiplier) * 100 ]; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return scene.currentBattle.waveIndex < 2000 ? super.getMaxStackCount(scene) : 999; } } @@ -2978,7 +3434,7 @@ export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier { export class EnemyTurnHealModifier extends EnemyPersistentModifier { public healPercent: number; - constructor(type: ModifierType, healPercent: number, stackCount?: integer) { + constructor(type: ModifierType, healPercent: number, stackCount?: number) { super(type, stackCount); // Hardcode temporarily @@ -2997,20 +3453,23 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier { return [ this.healPercent ]; } - apply(args: any[]): boolean { - const pokemon = args[0] as Pokemon; - - if (!pokemon.isFullHp()) { - const scene = pokemon.scene; - scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(), - Math.max(Math.floor(pokemon.getMaxHp() / (100 / this.healPercent)) * this.stackCount, 1), i18next.t("modifier:enemyTurnHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), true, false, false, false, true)); + /** + * Applies {@linkcode EnemyTurnHealModifier} + * @param enemyPokemon The {@linkcode Pokemon} to heal + * @returns `true` if the {@linkcode Pokemon} was healed + */ + override apply(enemyPokemon: Pokemon): boolean { + if (!enemyPokemon.isFullHp()) { + const scene = enemyPokemon.scene; + scene.unshiftPhase(new PokemonHealPhase(scene, enemyPokemon.getBattlerIndex(), + Math.max(Math.floor(enemyPokemon.getMaxHp() / (100 / this.healPercent)) * this.stackCount, 1), i18next.t("modifier:enemyTurnHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(enemyPokemon) }), true, false, false, false, true)); return true; } return false; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 10; } } @@ -3019,7 +3478,7 @@ export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifi public effect: StatusEffect; public chance: number; - constructor(type: ModifierType, effect: StatusEffect, chancePercent: number, stackCount?: integer) { + constructor(type: ModifierType, effect: StatusEffect, chancePercent: number, stackCount?: number) { super(type, stackCount); this.effect = effect; @@ -3039,16 +3498,20 @@ export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifi return [ this.effect, this.chance * 100 ]; } - apply(args: any[]): boolean { - const target = (args[0] as Pokemon); + /** + * Applies {@linkcode EnemyAttackStatusEffectChanceModifier} + * @param enemyPokemon {@linkcode Pokemon} to apply the status effect to + * @returns `true` if the {@linkcode Pokemon} was affected + */ + override apply(enemyPokemon: Pokemon): boolean { if (Phaser.Math.RND.realInRange(0, 1) < (this.chance * this.getStackCount())) { - return target.trySetStatus(this.effect, true); + return enemyPokemon.trySetStatus(this.effect, true); } return false; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 10; } } @@ -3056,7 +3519,7 @@ export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifi export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier { public chance: number; - constructor(type: ModifierType, chancePercent: number, stackCount?: integer) { + constructor(type: ModifierType, chancePercent: number, stackCount?: number) { super(type, stackCount); //Hardcode temporarily @@ -3075,19 +3538,23 @@ export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier return [ this.chance * 100 ]; } - apply(args: any[]): boolean { - const target = (args[0] as Pokemon); - if (target.status && Phaser.Math.RND.realInRange(0, 1) < (this.chance * this.getStackCount())) { - target.scene.queueMessage(getStatusEffectHealText(target.status.effect, getPokemonNameWithAffix(target))); - target.resetStatus(); - target.updateInfo(); + /** + * Applies {@linkcode EnemyStatusEffectHealChanceModifier} + * @param enemyPokemon The {@linkcode Pokemon} to heal + * @returns `true` if the {@linkcode Pokemon} was healed + */ + override apply(enemyPokemon: Pokemon): boolean { + if (enemyPokemon.status && Phaser.Math.RND.realInRange(0, 1) < (this.chance * this.getStackCount())) { + enemyPokemon.scene.queueMessage(getStatusEffectHealText(enemyPokemon.status.effect, getPokemonNameWithAffix(enemyPokemon))); + enemyPokemon.resetStatus(); + enemyPokemon.updateInfo(); return true; } return false; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 10; } } @@ -3095,7 +3562,7 @@ export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier export class EnemyEndureChanceModifier extends EnemyPersistentModifier { public chance: number; - constructor(type: ModifierType, chancePercent?: number, stackCount?: integer) { + constructor(type: ModifierType, chancePercent?: number, stackCount?: number) { super(type, stackCount || 10); //Hardcode temporarily @@ -3114,9 +3581,12 @@ export class EnemyEndureChanceModifier extends EnemyPersistentModifier { return [ this.chance * 100 ]; } - apply(args: any[]): boolean { - const target = (args[0] as Pokemon); - + /** + * Applies {@linkcode EnemyEndureChanceModifier} + * @param target {@linkcode Pokemon} to apply the {@linkcode BattlerTagType.ENDURING} chance to + * @returns `true` if {@linkcode Pokemon} endured + */ + override apply(target: Pokemon): boolean { if (target.battleData.endured || Phaser.Math.RND.realInRange(0, 1) >= (this.chance * this.getStackCount())) { return false; } @@ -3128,7 +3598,7 @@ export class EnemyEndureChanceModifier extends EnemyPersistentModifier { return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 10; } } @@ -3136,7 +3606,7 @@ export class EnemyEndureChanceModifier extends EnemyPersistentModifier { export class EnemyFusionChanceModifier extends EnemyPersistentModifier { private chance: number; - constructor(type: ModifierType, chancePercent: number, stackCount?: integer) { + constructor(type: ModifierType, chancePercent: number, stackCount?: number) { super(type, stackCount); this.chance = chancePercent / 100; @@ -3154,17 +3624,22 @@ export class EnemyFusionChanceModifier extends EnemyPersistentModifier { return [ this.chance * 100 ]; } - apply(args: any[]): boolean { + /** + * Applies {@linkcode EnemyFusionChanceModifier} + * @param isFusion {@linkcode BooleanHolder} that will be set to `true` if the {@linkcode EnemyPokemon} is a fusion + * @returns `true` if the {@linkcode EnemyPokemon} is a fusion + */ + override apply(isFusion: BooleanHolder): boolean { if (Phaser.Math.RND.realInRange(0, 1) >= (this.chance * this.getStackCount())) { return false; } - (args[0] as Utils.BooleanHolder).value = true; + isFusion.value = true; return true; } - getMaxStackCount(scene: BattleScene): integer { + getMaxStackCount(scene: BattleScene): number { return 10; } } @@ -3177,7 +3652,7 @@ export class EnemyFusionChanceModifier extends EnemyPersistentModifier { * @param isPlayer {@linkcode boolean} for whether the player (`true`) or enemy (`false`) is being overridden */ export function overrideModifiers(scene: BattleScene, isPlayer: boolean = true): void { - const modifiersOverride: ModifierTypes.ModifierOverride[] = isPlayer ? Overrides.STARTING_MODIFIER_OVERRIDE : Overrides.OPP_MODIFIER_OVERRIDE; + const modifiersOverride: ModifierOverride[] = isPlayer ? Overrides.STARTING_MODIFIER_OVERRIDE : Overrides.OPP_MODIFIER_OVERRIDE; if (!modifiersOverride || modifiersOverride.length === 0 || !scene) { return; } @@ -3191,8 +3666,8 @@ export function overrideModifiers(scene: BattleScene, isPlayer: boolean = true): const modifierFunc = modifierTypes[item.name]; let modifierType: ModifierType | null = modifierFunc(); - if (modifierType instanceof ModifierTypes.ModifierTypeGenerator) { - const pregenArgs = ("type" in item) && (item.type !== null) ? [item.type] : undefined; + if (modifierType instanceof ModifierTypeGenerator) { + const pregenArgs = ("type" in item) && (item.type !== null) ? [ item.type ] : undefined; modifierType = modifierType.generateType([], pregenArgs); } @@ -3218,13 +3693,13 @@ export function overrideModifiers(scene: BattleScene, isPlayer: boolean = true): * @param isPlayer {@linkcode boolean} for whether the {@linkcode pokemon} is the player's (`true`) or an enemy (`false`) */ export function overrideHeldItems(scene: BattleScene, pokemon: Pokemon, isPlayer: boolean = true): void { - const heldItemsOverride: ModifierTypes.ModifierOverride[] = isPlayer ? Overrides.STARTING_HELD_ITEMS_OVERRIDE : Overrides.OPP_HELD_ITEMS_OVERRIDE; + const heldItemsOverride: ModifierOverride[] = isPlayer ? Overrides.STARTING_HELD_ITEMS_OVERRIDE : Overrides.OPP_HELD_ITEMS_OVERRIDE; if (!heldItemsOverride || heldItemsOverride.length === 0 || !scene) { return; } if (!isPlayer) { - scene.clearEnemyHeldItemModifiers(); + scene.clearEnemyHeldItemModifiers(pokemon); } heldItemsOverride.forEach(item => { @@ -3232,8 +3707,8 @@ export function overrideHeldItems(scene: BattleScene, pokemon: Pokemon, isPlayer let modifierType: ModifierType | null = modifierFunc(); const qty = item.count || 1; - if (modifierType instanceof ModifierTypes.ModifierTypeGenerator) { - const pregenArgs = ("type" in item) && (item.type !== null) ? [item.type] : undefined; + if (modifierType instanceof ModifierTypeGenerator) { + const pregenArgs = ("type" in item) && (item.type !== null) ? [ item.type ] : undefined; modifierType = modifierType.generateType([], pregenArgs); } diff --git a/src/overrides.ts b/src/overrides.ts index 852961db8d7..6760db79205 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -75,6 +75,8 @@ class DefaultOverrides { readonly ITEM_UNLOCK_OVERRIDE: Unlockables[] = []; /** Set to `true` to show all tutorials */ readonly BYPASS_TUTORIAL_SKIP_OVERRIDE: boolean = false; + /** Set to `true` to force Paralysis and Freeze to always activate, or `false` to force them to not activate */ + readonly STATUS_ACTIVATION_OVERRIDE: boolean | null = null; // ---------------- // PLAYER OVERRIDES @@ -100,26 +102,42 @@ class DefaultOverrides { * @example SPECIES_OVERRIDE = Species.Bulbasaur; */ readonly STARTER_SPECIES_OVERRIDE: Species | number = 0; + /** + * This will force your starter to be a random fusion + */ + readonly STARTER_FUSION_OVERRIDE: boolean = false; + /** + * This will override the species of the fusion + */ + readonly STARTER_FUSION_SPECIES_OVERRIDE: Species | integer = 0; readonly ABILITY_OVERRIDE: Abilities = Abilities.NONE; readonly PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE; readonly STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE; readonly GENDER_OVERRIDE: Gender | null = null; readonly MOVESET_OVERRIDE: Moves | Array = []; - readonly SHINY_OVERRIDE: boolean = false; - readonly VARIANT_OVERRIDE: Variant = 0; + readonly SHINY_OVERRIDE: boolean | null = null; + readonly VARIANT_OVERRIDE: Variant | null = null; // -------------------------- // OPPONENT / ENEMY OVERRIDES // -------------------------- readonly OPP_SPECIES_OVERRIDE: Species | number = 0; + /** + * This will make all opponents fused Pokemon + */ + readonly OPP_FUSION_OVERRIDE: boolean = false; + /** + * This will override the species of the fusion only when the opponent is already a fusion + */ + readonly OPP_FUSION_SPECIES_OVERRIDE: Species | integer = 0; readonly OPP_LEVEL_OVERRIDE: number = 0; readonly OPP_ABILITY_OVERRIDE: Abilities = Abilities.NONE; readonly OPP_PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE; readonly OPP_STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE; readonly OPP_GENDER_OVERRIDE: Gender | null = null; readonly OPP_MOVESET_OVERRIDE: Moves | Array = []; - readonly OPP_SHINY_OVERRIDE: boolean = false; - readonly OPP_VARIANT_OVERRIDE: Variant = 0; + readonly OPP_SHINY_OVERRIDE: boolean | null = null; + readonly OPP_VARIANT_OVERRIDE: Variant | null = null; readonly OPP_IVS_OVERRIDE: number | number[] = []; readonly OPP_FORM_OVERRIDES: Partial> = {}; /** @@ -140,6 +158,7 @@ class DefaultOverrides { readonly EGG_VARIANT_OVERRIDE: VariantTier | null = null; readonly EGG_FREE_GACHA_PULLS_OVERRIDE: boolean = false; readonly EGG_GACHA_PULL_COUNT_OVERRIDE: number = 0; + readonly UNLIMITED_EGG_COUNT_OVERRIDE: boolean = false; // ------------------------- // MYSTERY ENCOUNTER OVERRIDES diff --git a/src/phase.ts b/src/phase.ts index 02939757112..5cf91f2c478 100644 --- a/src/phase.ts +++ b/src/phase.ts @@ -8,7 +8,6 @@ export class Phase { } start() { - console.log(`%cStart Phase ${this.constructor.name}`, "color:green;"); if (this.scene.abilityBar.shown) { this.scene.abilityBar.resetAutoHideTimer(); } diff --git a/src/phases/attempt-capture-phase.ts b/src/phases/attempt-capture-phase.ts index 53723526c14..3e46fc792f0 100644 --- a/src/phases/attempt-capture-phase.ts +++ b/src/phases/attempt-capture-phase.ts @@ -248,7 +248,7 @@ export class AttemptCapturePhase extends PokemonPhase { } }); }; - Promise.all([pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon)]).then(() => { + Promise.all([ pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon) ]).then(() => { if (this.scene.getParty().length === 6) { const promptRelease = () => { this.scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => { diff --git a/src/phases/attempt-run-phase.ts b/src/phases/attempt-run-phase.ts index 46d68f6005a..b4768dc9a26 100644 --- a/src/phases/attempt-run-phase.ts +++ b/src/phases/attempt-run-phase.ts @@ -10,6 +10,10 @@ import { NewBattlePhase } from "./new-battle-phase"; import { PokemonPhase } from "./pokemon-phase"; export class AttemptRunPhase extends PokemonPhase { + + /** For testing purposes: this is to force the pokemon to fail and escape */ + public forceFailEscape = false; + constructor(scene: BattleScene, fieldIndex: number) { super(scene, fieldIndex); } @@ -28,12 +32,12 @@ export class AttemptRunPhase extends PokemonPhase { applyAbAttrs(RunSuccessAbAttr, playerPokemon, null, false, escapeChance); - if (playerPokemon.randSeedInt(100) < escapeChance.value) { + if (playerPokemon.randSeedInt(100) < escapeChance.value && !this.forceFailEscape) { this.scene.playSound("se/flee"); this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500); this.scene.tweens.add({ - targets: [this.scene.arenaEnemy, enemyField].flat(), + targets: [ this.scene.arenaEnemy, enemyField ].flat(), alpha: 0, duration: 250, ease: "Sine.easeIn", @@ -51,6 +55,7 @@ export class AttemptRunPhase extends PokemonPhase { this.scene.pushPhase(new BattleEndPhase(this.scene)); this.scene.pushPhase(new NewBattlePhase(this.scene)); } else { + playerPokemon.turnData.failedRunAway = true; this.scene.queueMessage(i18next.t("battle:runAwayCannotEscape"), null, true, 500); } diff --git a/src/phases/battle-end-phase.ts b/src/phases/battle-end-phase.ts index eaa458af904..bae61aa2288 100644 --- a/src/phases/battle-end-phase.ts +++ b/src/phases/battle-end-phase.ts @@ -57,7 +57,7 @@ export class BattleEndPhase extends BattlePhase { if (m instanceof LapsingPokemonHeldItemModifier) { args.push(this.scene.getPokemonById(m.pokemonId)); } - if (!m.lapse(args)) { + if (!m.lapse(...args)) { this.scene.removeModifier(m); } } diff --git a/src/phases/battle-phase.ts b/src/phases/battle-phase.ts index b51e19bdf0e..11807fdc714 100644 --- a/src/phases/battle-phase.ts +++ b/src/phases/battle-phase.ts @@ -12,7 +12,7 @@ export class BattlePhase extends Phase { const tintSprites = this.scene.currentBattle.trainer?.getTintSprites()!; // TODO: is this bang correct? for (let i = 0; i < sprites.length; i++) { const visible = !trainerSlot || !i === (trainerSlot === TrainerSlot.TRAINER) || sprites.length < 2; - [sprites[i], tintSprites[i]].map(sprite => { + [ sprites[i], tintSprites[i] ].map(sprite => { if (visible) { sprite.x = trainerSlot || sprites.length < 2 ? 0 : i ? 16 : -16; } diff --git a/src/phases/berry-phase.ts b/src/phases/berry-phase.ts index 66ecaa6c7f8..e419aa6692d 100644 --- a/src/phases/berry-phase.ts +++ b/src/phases/berry-phase.ts @@ -15,7 +15,7 @@ export class BerryPhase extends FieldPhase { this.executeForAll((pokemon) => { const hasUsableBerry = !!this.scene.findModifier((m) => { - return m instanceof BerryModifier && m.shouldApply([pokemon]); + return m instanceof BerryModifier && m.shouldApply(pokemon); }, pokemon.isPlayer()); if (hasUsableBerry) { @@ -29,7 +29,7 @@ export class BerryPhase extends FieldPhase { new CommonAnimPhase(this.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM) ); - for (const berryModifier of this.scene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon) as BerryModifier[]) { + for (const berryModifier of this.scene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) { if (berryModifier.consumed) { if (!--berryModifier.stackCount) { this.scene.removeModifier(berryModifier); diff --git a/src/phases/check-status-effect-phase.ts b/src/phases/check-status-effect-phase.ts new file mode 100644 index 00000000000..44918b54966 --- /dev/null +++ b/src/phases/check-status-effect-phase.ts @@ -0,0 +1,23 @@ +import { PostTurnStatusEffectPhase } from "#app/phases/post-turn-status-effect-phase"; +import { Phase } from "#app/phase"; +import { BattlerIndex } from "#app/battle"; +import BattleScene from "#app/battle-scene"; + +export class CheckStatusEffectPhase extends Phase { + private order : BattlerIndex[]; + constructor(scene : BattleScene, order : BattlerIndex[]) { + super(scene); + this.scene = scene; + this.order = order; + } + + start() { + const field = this.scene.getField(); + for (const o of this.order) { + if (field[o].status && field[o].status.isPostTurn()) { + this.scene.unshiftPhase(new PostTurnStatusEffectPhase(this.scene, o)); + } + } + this.end(); + } +} diff --git a/src/phases/check-switch-phase.ts b/src/phases/check-switch-phase.ts index 8849d304435..5e459d0e6b5 100644 --- a/src/phases/check-switch-phase.ts +++ b/src/phases/check-switch-phase.ts @@ -51,7 +51,7 @@ export class CheckSwitchPhase extends BattlePhase { this.scene.ui.setMode(Mode.CONFIRM, () => { this.scene.ui.setMode(Mode.MESSAGE); this.scene.tryRemovePhase(p => p instanceof PostSummonPhase && p.player && p.fieldIndex === this.fieldIndex); - this.scene.unshiftPhase(new SwitchPhase(this.scene, SwitchType.SWITCH, this.fieldIndex, false, true)); + this.scene.unshiftPhase(new SwitchPhase(this.scene, SwitchType.INITIAL_SWITCH, this.fieldIndex, false, true)); this.end(); }, () => { this.scene.ui.setMode(Mode.MESSAGE); diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 5e5031c1d06..6d4d46c51c9 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -30,6 +30,15 @@ export class CommandPhase extends FieldPhase { start() { super.start(); + const commandUiHandler = this.scene.ui.handlers[Mode.COMMAND]; + if (commandUiHandler) { + if (this.scene.currentBattle.turn === 1 || commandUiHandler.getCursor() === Command.POKEMON) { + commandUiHandler.setCursor(Command.FIGHT); + } else { + commandUiHandler.setCursor(commandUiHandler.getCursor()); + } + } + if (this.fieldIndex) { // If we somehow are attempting to check the right pokemon but there's only one pokemon out // Switch back to the center pokemon. This can happen rarely in double battles with mid turn switching @@ -84,170 +93,170 @@ export class CommandPhase extends FieldPhase { let success: boolean; switch (command) { - case Command.FIGHT: - let useStruggle = false; - if (cursor === -1 || + case Command.FIGHT: + let useStruggle = false; + if (cursor === -1 || playerPokemon.trySelectMove(cursor, args[0] as boolean) || (useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m?.isUsable(playerPokemon)).length)) { - const moveId = !useStruggle ? cursor > -1 ? playerPokemon.getMoveset()[cursor]!.moveId : Moves.NONE : Moves.STRUGGLE; // TODO: is the bang correct? - const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args }; - const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2]; - if (!moveId) { - turnCommand.targets = [this.fieldIndex]; - } - console.log(moveTargets, getPokemonNameWithAffix(playerPokemon)); - if (moveTargets.targets.length > 1 && moveTargets.multiple) { - this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex)); - } - if (moveTargets.targets.length <= 1 || moveTargets.multiple) { + const moveId = !useStruggle ? cursor > -1 ? playerPokemon.getMoveset()[cursor]!.moveId : Moves.NONE : Moves.STRUGGLE; // TODO: is the bang correct? + const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args }; + const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2]; + if (!moveId) { + turnCommand.targets = [ this.fieldIndex ]; + } + console.log(moveTargets, getPokemonNameWithAffix(playerPokemon)); + if (moveTargets.targets.length > 1 && moveTargets.multiple) { + this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex)); + } + if (moveTargets.targets.length <= 1 || moveTargets.multiple) { turnCommand.move!.targets = moveTargets.targets; //TODO: is the bang correct here? - } else if (playerPokemon.getTag(BattlerTagType.CHARGING) && playerPokemon.getMoveQueue().length >= 1) { + } else if (playerPokemon.getTag(BattlerTagType.CHARGING) && playerPokemon.getMoveQueue().length >= 1) { turnCommand.move!.targets = playerPokemon.getMoveQueue()[0].targets; //TODO: is the bang correct here? - } else { - this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex)); - } - this.scene.currentBattle.turnCommands[this.fieldIndex] = turnCommand; - success = true; - } else if (cursor < playerPokemon.getMoveset().length) { - const move = playerPokemon.getMoveset()[cursor]!; //TODO: is this bang correct? - this.scene.ui.setMode(Mode.MESSAGE); + } else { + this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex)); + } + this.scene.currentBattle.turnCommands[this.fieldIndex] = turnCommand; + success = true; + } else if (cursor < playerPokemon.getMoveset().length) { + const move = playerPokemon.getMoveset()[cursor]!; //TODO: is this bang correct? + this.scene.ui.setMode(Mode.MESSAGE); - // Decides between a Disabled, Not Implemented, or No PP translation message - const errorMessage = - playerPokemon.isMoveRestricted(move.moveId) - ? playerPokemon.getRestrictingTag(move.moveId)!.selectionDeniedText(playerPokemon, move.moveId) + // Decides between a Disabled, Not Implemented, or No PP translation message + const errorMessage = + playerPokemon.isMoveRestricted(move.moveId, playerPokemon) + ? playerPokemon.getRestrictingTag(move.moveId, playerPokemon)!.selectionDeniedText(playerPokemon, move.moveId) : move.getName().endsWith(" (N)") ? "battle:moveNotImplemented" : "battle:moveNoPP"; - const moveName = move.getName().replace(" (N)", ""); // Trims off the indicator + const moveName = move.getName().replace(" (N)", ""); // Trims off the indicator - this.scene.ui.showText(i18next.t(errorMessage, { moveName: moveName }), null, () => { - this.scene.ui.clearText(); - this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex); - }, null, true); - } - break; - case Command.BALL: - const notInDex = (this.scene.getEnemyField().filter(p => p.isActive(true)).some(p => !p.scene.gameData.dexData[p.species.speciesId].caughtAttr) && this.scene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1); - if (this.scene.arena.biomeType === Biome.END && (!this.scene.gameMode.isClassic || this.scene.gameMode.isFreshStartChallenge() || notInDex )) { - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.showText(i18next.t("battle:noPokeballForce"), null, () => { - this.scene.ui.showText("", 0); - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - }, null, true); - } else if (this.scene.currentBattle.battleType === BattleType.TRAINER) { - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.showText(i18next.t("battle:noPokeballTrainer"), null, () => { - this.scene.ui.showText("", 0); - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - }, null, true); - } else if (this.scene.currentBattle.isBattleMysteryEncounter() && !this.scene.currentBattle.mysteryEncounter!.catchAllowed) { - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.showText(i18next.t("battle:noPokeballMysteryEncounter"), null, () => { - this.scene.ui.showText("", 0); - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - }, null, true); - } else { - const targets = this.scene.getEnemyField().filter(p => p.isActive(true)).map(p => p.getBattlerIndex()); - if (targets.length > 1) { + this.scene.ui.showText(i18next.t(errorMessage, { moveName: moveName }), null, () => { + this.scene.ui.clearText(); + this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex); + }, null, true); + } + break; + case Command.BALL: + const notInDex = (this.scene.getEnemyField().filter(p => p.isActive(true)).some(p => !p.scene.gameData.dexData[p.species.speciesId].caughtAttr) && this.scene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1); + if (this.scene.arena.biomeType === Biome.END && (!this.scene.gameMode.isClassic || this.scene.gameMode.isFreshStartChallenge() || notInDex )) { this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.showText(i18next.t("battle:noPokeballMulti"), null, () => { + this.scene.ui.showText(i18next.t("battle:noPokeballForce"), null, () => { this.scene.ui.showText("", 0); this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); }, null, true); - } else if (cursor < 5) { - const targetPokemon = this.scene.getEnemyField().find(p => p.isActive(true)); - if (targetPokemon?.isBoss() && targetPokemon?.bossSegmentIndex >= 1 && !targetPokemon?.hasAbility(Abilities.WONDER_GUARD, false, true) && cursor < PokeballType.MASTER_BALL) { + } else if (this.scene.currentBattle.battleType === BattleType.TRAINER) { + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + this.scene.ui.setMode(Mode.MESSAGE); + this.scene.ui.showText(i18next.t("battle:noPokeballTrainer"), null, () => { + this.scene.ui.showText("", 0); + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + }, null, true); + } else if (this.scene.currentBattle.isBattleMysteryEncounter() && !this.scene.currentBattle.mysteryEncounter!.catchAllowed) { + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + this.scene.ui.setMode(Mode.MESSAGE); + this.scene.ui.showText(i18next.t("battle:noPokeballMysteryEncounter"), null, () => { + this.scene.ui.showText("", 0); + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + }, null, true); + } else { + const targets = this.scene.getEnemyField().filter(p => p.isActive(true)).map(p => p.getBattlerIndex()); + if (targets.length > 1) { this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.showText(i18next.t("battle:noPokeballStrong"), null, () => { + this.scene.ui.showText(i18next.t("battle:noPokeballMulti"), null, () => { this.scene.ui.showText("", 0); this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); }, null, true); - } else { - this.scene.currentBattle.turnCommands[this.fieldIndex] = { command: Command.BALL, cursor: cursor }; + } else if (cursor < 5) { + const targetPokemon = this.scene.getEnemyField().find(p => p.isActive(true)); + if (targetPokemon?.isBoss() && targetPokemon?.bossSegmentIndex >= 1 && !targetPokemon?.hasAbility(Abilities.WONDER_GUARD, false, true) && cursor < PokeballType.MASTER_BALL) { + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + this.scene.ui.setMode(Mode.MESSAGE); + this.scene.ui.showText(i18next.t("battle:noPokeballStrong"), null, () => { + this.scene.ui.showText("", 0); + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + }, null, true); + } else { + this.scene.currentBattle.turnCommands[this.fieldIndex] = { command: Command.BALL, cursor: cursor }; this.scene.currentBattle.turnCommands[this.fieldIndex]!.targets = targets; if (this.fieldIndex) { this.scene.currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true; } success = true; + } } } - } - break; - case Command.POKEMON: - case Command.RUN: - const isSwitch = command === Command.POKEMON; - const { currentBattle, arena } = this.scene; - const mysteryEncounterFleeAllowed = currentBattle.mysteryEncounter?.fleeAllowed; - if (!isSwitch && (arena.biomeType === Biome.END || (!isNullOrUndefined(mysteryEncounterFleeAllowed) && !mysteryEncounterFleeAllowed))) { - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.showText(i18next.t("battle:noEscapeForce"), null, () => { - this.scene.ui.showText("", 0); + break; + case Command.POKEMON: + case Command.RUN: + const isSwitch = command === Command.POKEMON; + const { currentBattle, arena } = this.scene; + const mysteryEncounterFleeAllowed = currentBattle.mysteryEncounter?.fleeAllowed; + if (!isSwitch && (arena.biomeType === Biome.END || (!isNullOrUndefined(mysteryEncounterFleeAllowed) && !mysteryEncounterFleeAllowed))) { this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - }, null, true); - } else if (!isSwitch && (currentBattle.battleType === BattleType.TRAINER || currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE)) { - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.ui.showText(i18next.t("battle:noEscapeTrainer"), null, () => { - this.scene.ui.showText("", 0); - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - }, null, true); - } else { - const batonPass = isSwitch && args[0] as boolean; - const trappedAbMessages: string[] = []; - if (batonPass || !playerPokemon.isTrapped(trappedAbMessages)) { - currentBattle.turnCommands[this.fieldIndex] = isSwitch - ? { command: Command.POKEMON, cursor: cursor, args: args } - : { command: Command.RUN }; - success = true; - if (!isSwitch && this.fieldIndex) { - currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true; - } - } else if (trappedAbMessages.length > 0) { - if (!isSwitch) { - this.scene.ui.setMode(Mode.MESSAGE); - } - this.scene.ui.showText(trappedAbMessages[0], null, () => { + this.scene.ui.setMode(Mode.MESSAGE); + this.scene.ui.showText(i18next.t("battle:noEscapeForce"), null, () => { this.scene.ui.showText("", 0); - if (!isSwitch) { - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - } + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + }, null, true); + } else if (!isSwitch && (currentBattle.battleType === BattleType.TRAINER || currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE)) { + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + this.scene.ui.setMode(Mode.MESSAGE); + this.scene.ui.showText(i18next.t("battle:noEscapeTrainer"), null, () => { + this.scene.ui.showText("", 0); + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); }, null, true); } else { - const trapTag = playerPokemon.getTag(TrappedTag); - - // trapTag should be defined at this point, but just in case... - if (!trapTag) { + const batonPass = isSwitch && args[0] as boolean; + const trappedAbMessages: string[] = []; + if (batonPass || !playerPokemon.isTrapped(trappedAbMessages)) { currentBattle.turnCommands[this.fieldIndex] = isSwitch ? { command: Command.POKEMON, cursor: cursor, args: args } : { command: Command.RUN }; - break; - } - - if (!isSwitch) { - this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); - this.scene.ui.setMode(Mode.MESSAGE); - } - this.scene.ui.showText( - i18next.t("battle:noEscapePokemon", { - pokemonName: trapTag.sourceId && this.scene.getPokemonById(trapTag.sourceId) ? getPokemonNameWithAffix(this.scene.getPokemonById(trapTag.sourceId)!) : "", - moveName: trapTag.getMoveName(), - escapeVerb: isSwitch ? i18next.t("battle:escapeVerbSwitch") : i18next.t("battle:escapeVerbFlee") - }), - null, - () => { + success = true; + if (!isSwitch && this.fieldIndex) { + currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true; + } + } else if (trappedAbMessages.length > 0) { + if (!isSwitch) { + this.scene.ui.setMode(Mode.MESSAGE); + } + this.scene.ui.showText(trappedAbMessages[0], null, () => { this.scene.ui.showText("", 0); if (!isSwitch) { this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); } }, null, true); + } else { + const trapTag = playerPokemon.getTag(TrappedTag); + + // trapTag should be defined at this point, but just in case... + if (!trapTag) { + currentBattle.turnCommands[this.fieldIndex] = isSwitch + ? { command: Command.POKEMON, cursor: cursor, args: args } + : { command: Command.RUN }; + break; + } + + if (!isSwitch) { + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + this.scene.ui.setMode(Mode.MESSAGE); + } + this.scene.ui.showText( + i18next.t("battle:noEscapePokemon", { + pokemonName: trapTag.sourceId && this.scene.getPokemonById(trapTag.sourceId) ? getPokemonNameWithAffix(this.scene.getPokemonById(trapTag.sourceId)!) : "", + moveName: trapTag.getMoveName(), + escapeVerb: isSwitch ? i18next.t("battle:escapeVerbSwitch") : i18next.t("battle:escapeVerbFlee") + }), + null, + () => { + this.scene.ui.showText("", 0); + if (!isSwitch) { + this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); + } + }, null, true); + } } - } - break; + break; } if (success!) { // TODO: is the bang correct? diff --git a/src/phases/damage-phase.ts b/src/phases/damage-phase.ts index 66b11512729..44e3dfd4182 100644 --- a/src/phases/damage-phase.ts +++ b/src/phases/damage-phase.ts @@ -41,16 +41,16 @@ export class DamagePhase extends PokemonPhase { applyDamage() { switch (this.damageResult) { - case HitResult.EFFECTIVE: - this.scene.playSound("se/hit"); - break; - case HitResult.SUPER_EFFECTIVE: - case HitResult.ONE_HIT_KO: - this.scene.playSound("se/hit_strong"); - break; - case HitResult.NOT_VERY_EFFECTIVE: - this.scene.playSound("se/hit_weak"); - break; + case HitResult.EFFECTIVE: + this.scene.playSound("se/hit"); + break; + case HitResult.SUPER_EFFECTIVE: + case HitResult.ONE_HIT_KO: + this.scene.playSound("se/hit_strong"); + break; + case HitResult.NOT_VERY_EFFECTIVE: + this.scene.playSound("se/hit_weak"); + break; } if (this.amount) { diff --git a/src/phases/egg-lapse-phase.ts b/src/phases/egg-lapse-phase.ts index c251819f331..4c57be09b79 100644 --- a/src/phases/egg-lapse-phase.ts +++ b/src/phases/egg-lapse-phase.ts @@ -28,12 +28,12 @@ export class EggLapsePhase extends Phase { return Overrides.EGG_IMMEDIATE_HATCH_OVERRIDE ? true : --egg.hatchWaves < 1; }); const eggsToHatchCount: number = eggsToHatch.length; - this.eggHatchData= []; + this.eggHatchData = []; if (eggsToHatchCount > 0) { if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 1) { this.scene.ui.showText(i18next.t("battle:eggHatching"), 0, () => { - // show prompt for skip + // show prompt for skip, blocking inputs for 1 second this.scene.ui.showText(i18next.t("battle:eggSkipPrompt"), 0); this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => { this.hatchEggsSkipped(eggsToHatch); @@ -41,7 +41,8 @@ export class EggLapsePhase extends Phase { }, () => { this.hatchEggsRegular(eggsToHatch); this.end(); - } + }, + null, null, null, 1000, true ); }, 100, true); } else if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 2) { diff --git a/src/phases/egg-summary-phase.ts b/src/phases/egg-summary-phase.ts index 75c6939daf1..b673eb4887b 100644 --- a/src/phases/egg-summary-phase.ts +++ b/src/phases/egg-summary-phase.ts @@ -1,7 +1,6 @@ import BattleScene from "#app/battle-scene"; import { Phase } from "#app/phase"; import { Mode } from "#app/ui/ui"; -import EggHatchSceneHandler from "#app/ui/egg-hatch-scene-handler"; import { EggHatchData } from "#app/data/egg-hatch-data"; /** @@ -11,7 +10,6 @@ import { EggHatchData } from "#app/data/egg-hatch-data"; */ export class EggSummaryPhase extends Phase { private eggHatchData: EggHatchData[]; - private eggHatchHandler: EggHatchSceneHandler; constructor(scene: BattleScene, eggHatchData: EggHatchData[]) { super(scene); @@ -26,7 +24,6 @@ export class EggSummaryPhase extends Phase { if (i >= this.eggHatchData.length) { this.scene.ui.setModeForceTransition(Mode.EGG_HATCH_SUMMARY, this.eggHatchData).then(() => { this.scene.fadeOutBgm(undefined, false); - this.eggHatchHandler = this.scene.ui.getHandler() as EggHatchSceneHandler; }); } else { diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 798ee3dca3c..b7071c4cc6f 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -35,6 +35,7 @@ import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-d import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; import { getGoldenBugNetSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { Biome } from "#enums/biome"; +import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters"; export class EncounterPhase extends BattlePhase { private loaded: boolean; @@ -68,7 +69,7 @@ export class EncounterPhase extends BattlePhase { this.scene.executeWithSeedOffset(() => { const currentSessionEncounterType = battle.mysteryEncounterType; battle.mysteryEncounter = this.scene.getMysteryEncounter(currentSessionEncounterType); - }, battle.waveIndex << 4); + }, battle.waveIndex * 16); } const mysteryEncounter = battle.mysteryEncounter; if (mysteryEncounter) { @@ -251,6 +252,13 @@ export class EncounterPhase extends BattlePhase { this.scene.updateModifiers(true); }*/ + const { battleType, waveIndex } = this.scene.currentBattle; + if (this.scene.isMysteryEncounterValidForWave(battleType, waveIndex) && !this.scene.currentBattle.isBattleMysteryEncounter()) { + // Increment ME spawn chance if an ME could have spawned but did not + // Only do this AFTER session has been saved to avoid duplicating increments + this.scene.mysteryEncounterSaveData.encounterSpawnChance += WEIGHT_INCREMENT_ON_SPAWN_MISS; + } + for (const pokemon of this.scene.getParty()) { if (pokemon) { pokemon.resetBattleData(); @@ -259,7 +267,7 @@ export class EncounterPhase extends BattlePhase { const enemyField = this.scene.getEnemyField(); this.scene.tweens.add({ - targets: [this.scene.arenaEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.arenaPlayer, this.scene.trainer].flat(), + targets: [ this.scene.arenaEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.arenaPlayer, this.scene.trainer ].flat(), x: (_target, _key, value, fieldIndex: integer) => fieldIndex < 2 + (enemyField.length) ? value + 300 : value - 300, duration: 2000, onComplete: () => { @@ -287,7 +295,7 @@ export class EncounterPhase extends BattlePhase { const enemyField = this.scene.getEnemyField(); if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) { - return i18next.t("battle:bossAppeared", { bossName: getPokemonNameWithAffix(enemyField[0])}); + return i18next.t("battle:bossAppeared", { bossName: getPokemonNameWithAffix(enemyField[0]) }); } if (this.scene.currentBattle.battleType === BattleType.TRAINER) { @@ -436,7 +444,7 @@ export class EncounterPhase extends BattlePhase { } }); - if (![BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.scene.currentBattle.battleType)) { + if (![ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.scene.currentBattle.battleType)) { enemyField.map(p => this.scene.pushConditionalPhase(new PostSummonPhase(this.scene, p.getBattlerIndex()), () => { // if there is not a player party, we can't continue if (!this.scene.getParty()?.length) { @@ -494,31 +502,31 @@ export class EncounterPhase extends BattlePhase { tryOverrideForBattleSpec(): boolean { switch (this.scene.currentBattle.battleSpec) { - case BattleSpec.FINAL_BOSS: - const enemy = this.scene.getEnemyPokemon(); - this.scene.ui.showText(this.getEncounterMessage(), null, () => { - const localizationKey = "battleSpecDialogue:encounter"; - if (this.scene.ui.shouldSkipDialogue(localizationKey)) { + case BattleSpec.FINAL_BOSS: + const enemy = this.scene.getEnemyPokemon(); + this.scene.ui.showText(this.getEncounterMessage(), null, () => { + const localizationKey = "battleSpecDialogue:encounter"; + if (this.scene.ui.shouldSkipDialogue(localizationKey)) { // Logging mirrors logging found in dialogue-ui-handler - console.log(`Dialogue ${localizationKey} skipped`); - this.doEncounterCommon(false); - } else { - const count = 5643853 + this.scene.gameData.gameStats.classicSessionsPlayed; - // The line below checks if an English ordinal is necessary or not based on whether an entry for encounterLocalizationKey exists in the language or not. - const ordinalUsed = !i18next.exists(localizationKey, {fallbackLng: []}) || i18next.resolvedLanguage === "en" ? i18next.t("battleSpecDialogue:key", { count: count, ordinal: true }) : ""; - const cycleCount = count.toLocaleString() + ordinalUsed; - const genderIndex = this.scene.gameData.gender ?? PlayerGender.UNSET; - const genderStr = PlayerGender[genderIndex].toLowerCase(); - const encounterDialogue = i18next.t(localizationKey, { context: genderStr, cycleCount: cycleCount }); - if (!this.scene.gameData.getSeenDialogues()[localizationKey]) { - this.scene.gameData.saveSeenDialogue(localizationKey); - } - this.scene.ui.showDialogue(encounterDialogue, enemy?.species.name, null, () => { + console.log(`Dialogue ${localizationKey} skipped`); this.doEncounterCommon(false); - }); - } - }, 1500, true); - return true; + } else { + const count = 5643853 + this.scene.gameData.gameStats.classicSessionsPlayed; + // The line below checks if an English ordinal is necessary or not based on whether an entry for encounterLocalizationKey exists in the language or not. + const ordinalUsed = !i18next.exists(localizationKey, { fallbackLng: []}) || i18next.resolvedLanguage === "en" ? i18next.t("battleSpecDialogue:key", { count: count, ordinal: true }) : ""; + const cycleCount = count.toLocaleString() + ordinalUsed; + const genderIndex = this.scene.gameData.gender ?? PlayerGender.UNSET; + const genderStr = PlayerGender[genderIndex].toLowerCase(); + const encounterDialogue = i18next.t(localizationKey, { context: genderStr, cycleCount: cycleCount }); + if (!this.scene.gameData.getSeenDialogues()[localizationKey]) { + this.scene.gameData.saveSeenDialogue(localizationKey); + } + this.scene.ui.showDialogue(encounterDialogue, enemy?.species.name, null, () => { + this.doEncounterCommon(false); + }); + } + }, 1500, true); + return true; } return false; } diff --git a/src/phases/enemy-command-phase.ts b/src/phases/enemy-command-phase.ts index b4503a7b059..3647a237ef1 100644 --- a/src/phases/enemy-command-phase.ts +++ b/src/phases/enemy-command-phase.ts @@ -61,7 +61,7 @@ export class EnemyCommandPhase extends FieldPhase { const index = trainer.getNextSummonIndex(enemyPokemon.trainerSlot, partyMemberScores); battle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] = - { command: Command.POKEMON, cursor: index, args: [false], skip: this.skipTurn }; + { command: Command.POKEMON, cursor: index, args: [ false ], skip: this.skipTurn }; battle.enemySwitchCounter++; diff --git a/src/phases/faint-phase.ts b/src/phases/faint-phase.ts index ba25225f6e0..8eb84beded5 100644 --- a/src/phases/faint-phase.ts +++ b/src/phases/faint-phase.ts @@ -1,12 +1,12 @@ import BattleScene from "#app/battle-scene"; import { BattlerIndex, BattleType } from "#app/battle"; import { applyPostFaintAbAttrs, PostFaintAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr } from "#app/data/ability"; -import { BattlerTagLapseType } from "#app/data/battler-tags"; +import { BattlerTagLapseType, DestinyBondTag } from "#app/data/battler-tags"; import { battleSpecDialogue } from "#app/data/dialogue"; import { allMoves, PostVictoryStatStageChangeAttr } from "#app/data/move"; import { BattleSpec } from "#app/enums/battle-spec"; import { StatusEffect } from "#app/enums/status-effect"; -import { PokemonMove, EnemyPokemon, PlayerPokemon, HitResult } from "#app/field/pokemon"; +import Pokemon, { PokemonMove, EnemyPokemon, PlayerPokemon, HitResult } from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; import { PokemonInstantReviveModifier } from "#app/modifier/modifier"; import i18next from "i18next"; @@ -19,19 +19,40 @@ import { SwitchPhase } from "./switch-phase"; import { VictoryPhase } from "./victory-phase"; import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms"; import { SwitchType } from "#enums/switch-type"; +import { isNullOrUndefined } from "#app/utils"; +import { FRIENDSHIP_LOSS_FROM_FAINT } from "#app/data/balance/starters"; export class FaintPhase extends PokemonPhase { + /** + * Whether or not enduring (for this phase's purposes, Reviver Seed) should be prevented + */ private preventEndure: boolean; - constructor(scene: BattleScene, battlerIndex: BattlerIndex, preventEndure?: boolean) { + /** + * Destiny Bond tag belonging to the currently fainting Pokemon, if applicable + */ + private destinyTag?: DestinyBondTag; + + /** + * The source Pokemon that dealt fatal damage and should get KO'd by Destiny Bond, if applicable + */ + private source?: Pokemon; + + constructor(scene: BattleScene, battlerIndex: BattlerIndex, preventEndure: boolean = false, destinyTag?: DestinyBondTag, source?: Pokemon) { super(scene, battlerIndex); - this.preventEndure = preventEndure!; // TODO: is this bang correct? + this.preventEndure = preventEndure; + this.destinyTag = destinyTag; + this.source = source; } start() { super.start(); + if (!isNullOrUndefined(this.destinyTag) && !isNullOrUndefined(this.source)) { + this.destinyTag.lapse(this.source, BattlerTagLapseType.CUSTOM); + } + if (!this.preventEndure) { const instantReviveModifier = this.scene.applyModifier(PokemonInstantReviveModifier, this.player, this.getPokemon()) as PokemonInstantReviveModifier; @@ -44,6 +65,15 @@ export class FaintPhase extends PokemonPhase { } } + /** In case the current pokemon was just switched in, make sure it is counted as participating in the combat */ + this.scene.getPlayerField().forEach((pokemon, i) => { + if (pokemon?.isActive(true)) { + if (pokemon.isPlayer()) { + this.scene.currentBattle.addParticipant(pokemon as PlayerPokemon); + } + } + }); + if (!this.tryOverrideForBattleSpec()) { this.doFaint(); } @@ -111,7 +141,7 @@ export class FaintPhase extends PokemonPhase { } } else { this.scene.unshiftPhase(new VictoryPhase(this.scene, this.battlerIndex)); - if ([BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.scene.currentBattle.battleType)) { + if ([ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.scene.currentBattle.battleType)) { const hasReservePartyMember = !!this.scene.getEnemyParty().filter(p => p.isActive() && !p.isOnField() && p.trainerSlot === (pokemon as EnemyPokemon).trainerSlot).length; if (hasReservePartyMember) { this.scene.pushPhase(new SwitchSummonPhase(this.scene, SwitchType.SWITCH, this.fieldIndex, -1, false, false)); @@ -127,7 +157,7 @@ export class FaintPhase extends PokemonPhase { pokemon.faintCry(() => { if (pokemon instanceof PlayerPokemon) { - pokemon.addFriendship(-10); + pokemon.addFriendship(-FRIENDSHIP_LOSS_FROM_FAINT); } pokemon.hideInfo(); this.scene.playSound("se/faint"); @@ -158,19 +188,19 @@ export class FaintPhase extends PokemonPhase { tryOverrideForBattleSpec(): boolean { switch (this.scene.currentBattle.battleSpec) { - case BattleSpec.FINAL_BOSS: - if (!this.player) { - const enemy = this.getPokemon(); - if (enemy.formIndex) { - this.scene.ui.showDialogue(battleSpecDialogue[BattleSpec.FINAL_BOSS].secondStageWin, enemy.species.name, null, () => this.doFaint()); - } else { + case BattleSpec.FINAL_BOSS: + if (!this.player) { + const enemy = this.getPokemon(); + if (enemy.formIndex) { + this.scene.ui.showDialogue(battleSpecDialogue[BattleSpec.FINAL_BOSS].secondStageWin, enemy.species.name, null, () => this.doFaint()); + } else { // Final boss' HP threshold has been bypassed; cancel faint and force check for 2nd phase - enemy.hp++; - this.scene.unshiftPhase(new DamagePhase(this.scene, enemy.getBattlerIndex(), 0, HitResult.OTHER)); - this.end(); + enemy.hp++; + this.scene.unshiftPhase(new DamagePhase(this.scene, enemy.getBattlerIndex(), 0, HitResult.OTHER)); + this.end(); + } + return true; } - return true; - } } return false; diff --git a/src/phases/learn-move-phase.ts b/src/phases/learn-move-phase.ts index 5b4b16f3785..fefda384092 100644 --- a/src/phases/learn-move-phase.ts +++ b/src/phases/learn-move-phase.ts @@ -2,24 +2,37 @@ import BattleScene from "#app/battle-scene"; import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; import Move, { allMoves } from "#app/data/move"; import { SpeciesFormChangeMoveLearnedTrigger } from "#app/data/pokemon-forms"; -import { Moves } from "#app/enums/moves"; +import { Moves } from "#enums/moves"; import { getPokemonNameWithAffix } from "#app/messages"; +import Overrides from "#app/overrides"; import EvolutionSceneHandler from "#app/ui/evolution-scene-handler"; import { SummaryUiMode } from "#app/ui/summary-ui-handler"; import { Mode } from "#app/ui/ui"; import i18next from "i18next"; -import { PlayerPartyMemberPokemonPhase } from "./player-party-member-pokemon-phase"; +import { PlayerPartyMemberPokemonPhase } from "#app/phases/player-party-member-pokemon-phase"; import Pokemon from "#app/field/pokemon"; +import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; + +export enum LearnMoveType { + /** For learning a move via level-up, evolution, or other non-item-based event */ + LEARN_MOVE, + /** For learning a move via Memory Mushroom */ + MEMORY, + /** For learning a move via TM */ + TM +} export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { private moveId: Moves; private messageMode: Mode; - private fromTM: boolean; + private learnMoveType; + private cost: number; - constructor(scene: BattleScene, partyMemberIndex: integer, moveId: Moves, fromTM?: boolean) { + constructor(scene: BattleScene, partyMemberIndex: integer, moveId: Moves, learnMoveType: LearnMoveType = LearnMoveType.LEARN_MOVE, cost: number = -1) { super(scene, partyMemberIndex); this.moveId = moveId; - this.fromTM = fromTM ?? false; + this.learnMoveType = learnMoveType; + this.cost = cost; } start() { @@ -59,7 +72,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { const learnMovePrompt = i18next.t("battle:learnMovePrompt", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }); const moveLimitReached = i18next.t("battle:learnMoveLimitReached", { pokemonName: getPokemonNameWithAffix(pokemon) }); const shouldReplaceQ = i18next.t("battle:learnMoveReplaceQuestion", { moveName: move.name }); - const preQText = [learnMovePrompt, moveLimitReached].join("$"); + const preQText = [ learnMovePrompt, moveLimitReached ].join("$"); await this.scene.ui.showTextPromise(preQText); await this.scene.ui.showTextPromise(shouldReplaceQ, undefined, false); await this.scene.ui.setModeWithoutClear(Mode.CONFIRM, @@ -91,7 +104,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { return; } const forgetSuccessText = i18next.t("battle:learnMoveForgetSuccess", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: pokemon.moveset[moveIndex]!.getName() }); - const fullText = [i18next.t("battle:countdownPoof"), forgetSuccessText, i18next.t("battle:learnMoveAnd")].join("$"); + const fullText = [ i18next.t("battle:countdownPoof"), forgetSuccessText, i18next.t("battle:learnMoveAnd") ].join("$"); this.scene.ui.setMode(this.messageMode).then(() => this.learnMove(moveIndex, move, pokemon, fullText)); }); } @@ -136,22 +149,37 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { * @param Pokemon The Pokemon learning the move */ async learnMove(index: number, move: Move, pokemon: Pokemon, textMessage?: string) { - if (this.fromTM) { + if (this.learnMoveType === LearnMoveType.TM) { if (!pokemon.usedTMs) { pokemon.usedTMs = []; } pokemon.usedTMs.push(this.moveId); + this.scene.tryRemovePhase((phase) => phase instanceof SelectModifierPhase); + } else if (this.learnMoveType === LearnMoveType.MEMORY) { + if (this.cost !== -1) { + if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { + this.scene.money -= this.cost; + this.scene.updateMoneyText(); + this.scene.animateMoneyChanged(false); + } + this.scene.playSound("se/buy"); + } else { + this.scene.tryRemovePhase((phase) => phase instanceof SelectModifierPhase); + } } pokemon.setMove(index, this.moveId); initMoveAnim(this.scene, this.moveId).then(() => { - loadMoveAnimAssets(this.scene, [this.moveId], true); - this.scene.playSound("level_up_fanfare"); // Sound loaded into game as is + loadMoveAnimAssets(this.scene, [ this.moveId ], true); }); this.scene.ui.setMode(this.messageMode); const learnMoveText = i18next.t("battle:learnMove", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }); - textMessage = textMessage ? textMessage+"$"+learnMoveText : learnMoveText; - await this.scene.ui.showTextPromise(textMessage, this.messageMode === Mode.EVOLUTION_SCENE ? 1000 : undefined, true); - this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true); - this.end(); + if (textMessage) { + await this.scene.ui.showTextPromise(textMessage); + } + this.scene.playSound("level_up_fanfare"); // Sound loaded into game as is + this.scene.ui.showText(learnMoveText, null, () => { + this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true); + this.end(); + }, this.messageMode === Mode.EVOLUTION_SCENE ? 1000 : undefined, true); } } diff --git a/src/phases/level-up-phase.ts b/src/phases/level-up-phase.ts index a99e038acba..a2fa8a16533 100644 --- a/src/phases/level-up-phase.ts +++ b/src/phases/level-up-phase.ts @@ -28,7 +28,7 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase { this.scene.gameData.gameStats.highestLevel = this.level; } - this.scene.validateAchvs(LevelAchv, new Utils.IntegerHolder(this.level)); + this.scene.validateAchvs(LevelAchv, new Utils.NumberHolder(this.level)); const pokemon = this.getPokemon(); const prevStats = pokemon.stats.slice(0); diff --git a/src/phases/login-phase.ts b/src/phases/login-phase.ts index 89ced201e9e..ac1e68d1b0e 100644 --- a/src/phases/login-phase.ts +++ b/src/phases/login-phase.ts @@ -22,7 +22,7 @@ export class LoginPhase extends Phase { const hasSession = !!Utils.getCookie(Utils.sessionIdKey); - this.scene.ui.setMode(Mode.LOADING, { buttonActions: [] }); + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); Utils.executeIf(bypassLogin || hasSession, updateUserInfo).then(response => { const success = response ? response[0] : false; const statusCode = response ? response[1] : null; diff --git a/src/phases/move-anim-test-phase.ts b/src/phases/move-anim-test-phase.ts index a6ab90464b8..e4b04ce5de6 100644 --- a/src/phases/move-anim-test-phase.ts +++ b/src/phases/move-anim-test-phase.ts @@ -29,7 +29,7 @@ export class MoveAnimTestPhase extends BattlePhase { } initMoveAnim(this.scene, moveId).then(() => { - loadMoveAnimAssets(this.scene, [moveId], true) + loadMoveAnimAssets(this.scene, [ moveId ], true) .then(() => { const user = player ? this.scene.getPlayerPokemon()! : this.scene.getEnemyPokemon()!; const target = (player !== (allMoves[moveId] instanceof SelfStatusMove)) ? this.scene.getEnemyPokemon()! : this.scene.getPlayerPokemon()!; diff --git a/src/phases/move-charge-phase.ts b/src/phases/move-charge-phase.ts new file mode 100644 index 00000000000..d1dc340b81b --- /dev/null +++ b/src/phases/move-charge-phase.ts @@ -0,0 +1,84 @@ +import BattleScene from "#app/battle-scene"; +import { BattlerIndex } from "#app/battle"; +import { MoveChargeAnim } from "#app/data/battle-anims"; +import { applyMoveChargeAttrs, MoveEffectAttr, InstantChargeAttr } from "#app/data/move"; +import Pokemon, { MoveResult, PokemonMove } from "#app/field/pokemon"; +import { BooleanHolder } from "#app/utils"; +import { MovePhase } from "#app/phases/move-phase"; +import { PokemonPhase } from "#app/phases/pokemon-phase"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { MoveEndPhase } from "#app/phases/move-end-phase"; + +/** + * Phase for the "charging turn" of two-turn moves (e.g. Dig). + * @extends {@linkcode PokemonPhase} + */ +export class MoveChargePhase extends PokemonPhase { + /** The move instance that this phase applies */ + public move: PokemonMove; + /** The field index targeted by the move (Charging moves assume single target) */ + public targetIndex: BattlerIndex; + + constructor(scene: BattleScene, battlerIndex: BattlerIndex, targetIndex: BattlerIndex, move: PokemonMove) { + super(scene, battlerIndex); + this.move = move; + this.targetIndex = targetIndex; + } + + public override start() { + super.start(); + + const user = this.getUserPokemon(); + const target = this.getTargetPokemon(); + const move = this.move.getMove(); + + // If the target is somehow not defined, or the move is somehow not a ChargingMove, + // immediately end this phase. + if (!target || !(move.isChargingMove())) { + console.warn("Invalid parameters for MoveChargePhase"); + return super.end(); + } + + new MoveChargeAnim(move.chargeAnim, move.id, user).play(this.scene, false, () => { + move.showChargeText(user, target); + + applyMoveChargeAttrs(MoveEffectAttr, user, target, move).then(() => { + user.addTag(BattlerTagType.CHARGING, 1, move.id, user.id); + this.end(); + }); + }); + } + + /** Checks the move's instant charge conditions, then ends this phase. */ + public override end() { + const user = this.getUserPokemon(); + const move = this.move.getMove(); + + if (move.isChargingMove()) { + const instantCharge = new BooleanHolder(false); + + applyMoveChargeAttrs(InstantChargeAttr, user, null, move, instantCharge); + + if (instantCharge.value) { + // this MoveEndPhase will be duplicated by the queued MovePhase if not removed + this.scene.tryRemovePhase((phase) => phase instanceof MoveEndPhase && phase.getPokemon() === user); + // queue a new MovePhase for this move's attack phase + this.scene.unshiftPhase(new MovePhase(this.scene, user, [ this.targetIndex ], this.move, false)); + } else { + user.getMoveQueue().push({ move: move.id, targets: [ this.targetIndex ]}); + } + + // Add this move's charging phase to the user's move history + user.pushMoveHistory({ move: this.move.moveId, targets: [ this.targetIndex ], result: MoveResult.OTHER }); + } + super.end(); + } + + public getUserPokemon(): Pokemon { + return (this.player ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.fieldIndex]; + } + + public getTargetPokemon(): Pokemon | undefined { + return this.scene.getField(true).find((p) => this.targetIndex === p.getBattlerIndex()); + } +} diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index ca1fb87654f..2b898f7d66b 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -4,7 +4,7 @@ import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr, import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag"; import { MoveAnim } from "#app/data/battle-anims"; import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags"; -import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr } from "#app/data/move"; +import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, OneHitKOAttr, MoveEffectTrigger, MoveCategory, NoEffectAttr, HitsTagAttr, ToxicAccuracyAttr } from "#app/data/move"; import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms"; import { BattlerTagType } from "#app/enums/battler-tag-type"; import { Moves } from "#app/enums/moves"; @@ -14,6 +14,7 @@ import { PokemonMultiHitModifier, FlinchChanceModifier, EnemyAttackStatusEffectC import i18next from "i18next"; import * as Utils from "#app/utils"; import { PokemonPhase } from "./pokemon-phase"; +import { Type } from "#app/data/type"; export class MoveEffectPhase extends PokemonPhase { public move: PokemonMove; @@ -23,10 +24,10 @@ export class MoveEffectPhase extends PokemonPhase { super(scene, battlerIndex); this.move = move; /** - * In double battles, if the right Pokemon selects a spread move and the left Pokemon dies - * with no party members available to switch in, then the right Pokemon takes the index - * of the left Pokemon and gets hit unless this is checked. - */ + * In double battles, if the right Pokemon selects a spread move and the left Pokemon dies + * with no party members available to switch in, then the right Pokemon takes the index + * of the left Pokemon and gets hit unless this is checked. + */ if (targets.includes(battlerIndex) && this.move.getMove().moveTarget === MoveTarget.ALL_NEAR_OTHERS) { const i = targets.indexOf(battlerIndex); targets.splice(i, i + 1); @@ -48,9 +49,9 @@ export class MoveEffectPhase extends PokemonPhase { } /** - * Does an effect from this move override other effects on this turn? - * e.g. Charging moves (Fly, etc.) on their first turn of use. - */ + * Does an effect from this move override other effects on this turn? + * e.g. Charging moves (Fly, etc.) on their first turn of use. + */ const overridden = new Utils.BooleanHolder(false); /** The {@linkcode Move} object from {@linkcode allMoves} invoked by this phase */ const move = this.move.getMove(); @@ -65,11 +66,11 @@ export class MoveEffectPhase extends PokemonPhase { user.lapseTags(BattlerTagLapseType.MOVE_EFFECT); /** - * If this phase is for the first hit of the invoked move, - * resolve the move's total hit count. This block combines the - * effects of the move itself, Parental Bond, and Multi-Lens to do so. - */ - if (user.turnData.hitsLeft === undefined) { + * If this phase is for the first hit of the invoked move, + * resolve the move's total hit count. This block combines the + * effects of the move itself, Parental Bond, and Multi-Lens to do so. + */ + if (user.turnData.hitsLeft === -1) { const hitCount = new Utils.IntegerHolder(1); // Assume single target for multi hit applyMoveAttrs(MultiHitAttr, user, this.getTarget() ?? null, move, hitCount); @@ -85,32 +86,32 @@ export class MoveEffectPhase extends PokemonPhase { } /** - * Log to be entered into the user's move history once the move result is resolved. - * Note that `result` (a {@linkcode MoveResult}) logs whether the move was successfully - * used in the sense of "Does it have an effect on the user?". - */ + * Log to be entered into the user's move history once the move result is resolved. + * Note that `result` (a {@linkcode MoveResult}) logs whether the move was successfully + * used in the sense of "Does it have an effect on the user?". + */ const moveHistoryEntry = { move: this.move.moveId, targets: this.targets, result: MoveResult.PENDING, virtual: this.move.virtual }; /** - * Stores results of hit checks of the invoked move against all targets, organized by battler index. - * @see {@linkcode hitCheck} - */ - const targetHitChecks = Object.fromEntries(targets.map(p => [p.getBattlerIndex(), this.hitCheck(p)])); + * Stores results of hit checks of the invoked move against all targets, organized by battler index. + * @see {@linkcode hitCheck} + */ + const targetHitChecks = Object.fromEntries(targets.map(p => [ p.getBattlerIndex(), this.hitCheck(p) ])); const hasActiveTargets = targets.some(t => t.isActive(true)); - /** Check if the target is immune via ability to the attacking move */ - const isImmune = targets[0].hasAbilityWithAttr(TypeImmunityAbAttr) && (targets[0].getAbility()?.getAttrs(TypeImmunityAbAttr)?.[0]?.getImmuneType() === user.getMoveType(move)); + /** Check if the target is immune via ability to the attacking move, and NOT in semi invulnerable state */ + const isImmune = targets[0].hasAbilityWithAttr(TypeImmunityAbAttr) && (targets[0].getAbility()?.getAttrs(TypeImmunityAbAttr)?.[0]?.getImmuneType() === user.getMoveType(move)) + && !targets[0].getTag(SemiInvulnerableTag); /** - * If no targets are left for the move to hit (FAIL), or the invoked move is single-target - * (and not random target) and failed the hit check against its target (MISS), log the move - * as FAILed or MISSed (depending on the conditions above) and end this phase. - */ - + * If no targets are left for the move to hit (FAIL), or the invoked move is single-target + * (and not random target) and failed the hit check against its target (MISS), log the move + * as FAILed or MISSed (depending on the conditions above) and end this phase. + */ if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]] && !targets[0].getTag(ProtectedTag) && !isImmune)) { this.stopMultiHit(); if (hasActiveTargets) { - this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getTarget()? getPokemonNameWithAffix(this.getTarget()!) : "" })); + this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getTarget() ? getPokemonNameWithAffix(this.getTarget()!) : "" })); moveHistoryEntry.result = MoveResult.MISS; applyMoveAttrs(MissEffectAttr, user, null, move); } else { @@ -139,7 +140,7 @@ export class MoveEffectPhase extends PokemonPhase { const bypassIgnoreProtect = new Utils.BooleanHolder(false); /** If the move is not targeting a Pokemon on the user's side, try to apply conditional protection effects */ if (!this.move.getMove().isAllyTarget()) { - this.scene.arena.applyTagsForSide(ConditionalProtectTag, targetSide, hasConditionalProtectApplied, user, target, move.id, bypassIgnoreProtect); + this.scene.arena.applyTagsForSide(ConditionalProtectTag, targetSide, false, hasConditionalProtectApplied, user, target, move.id, bypassIgnoreProtect); } /** Is the target protected by Protect, etc. or a relevant conditional protection effect? */ @@ -147,13 +148,14 @@ export class MoveEffectPhase extends PokemonPhase { && (hasConditionalProtectApplied.value || (!target.findTags(t => t instanceof DamageProtectedTag).length && target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType))) || (this.move.getMove().category !== MoveCategory.STATUS && target.findTags(t => t instanceof DamageProtectedTag).find(t => target.lapseTag(t.tagType)))); - /** Is the pokemon immune due to an ablility? */ - const isImmune = target.hasAbilityWithAttr(TypeImmunityAbAttr) && (target.getAbility()?.getAttrs(TypeImmunityAbAttr)?.[0]?.getImmuneType() === user.getMoveType(move)); + /** Is the pokemon immune due to an ablility, and also not in a semi invulnerable state? */ + const isImmune = target.hasAbilityWithAttr(TypeImmunityAbAttr) && (target.getAbility()?.getAttrs(TypeImmunityAbAttr)?.[0]?.getImmuneType() === user.getMoveType(move)) + && !target.getTag(SemiInvulnerableTag); /** - * If the move missed a target, stop all future hits against that target - * and move on to the next target (if there is one). - */ + * If the move missed a target, stop all future hits against that target + * and move on to the next target (if there is one). + */ if (!isImmune && !isProtected && !targetHitChecks[target.getBattlerIndex()]) { this.stopMultiHit(target); this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) })); @@ -174,23 +176,23 @@ export class MoveEffectPhase extends PokemonPhase { } /** - * Since all fail/miss checks have applied, the move is considered successfully applied. - * It's worth noting that if the move has no effect or is protected against, this assignment - * is overwritten and the move is logged as a FAIL. - */ + * Since all fail/miss checks have applied, the move is considered successfully applied. + * It's worth noting that if the move has no effect or is protected against, this assignment + * is overwritten and the move is logged as a FAIL. + */ moveHistoryEntry.result = MoveResult.SUCCESS; /** - * Stores the result of applying the invoked move to the target. - * If the target is protected, the result is always `NO_EFFECT`. - * Otherwise, the hit result is based on type effectiveness, immunities, - * and other factors that may negate the attack or status application. - * - * Internally, the call to {@linkcode Pokemon.apply} is where damage is calculated - * (for attack moves) and the target's HP is updated. However, this isn't - * made visible to the user until the resulting {@linkcode DamagePhase} - * is invoked. - */ + * Stores the result of applying the invoked move to the target. + * If the target is protected, the result is always `NO_EFFECT`. + * Otherwise, the hit result is based on type effectiveness, immunities, + * and other factors that may negate the attack or status application. + * + * Internally, the call to {@linkcode Pokemon.apply} is where damage is calculated + * (for attack moves) and the target's HP is updated. However, this isn't + * made visible to the user until the resulting {@linkcode DamagePhase} + * is invoked. + */ const hitResult = !isProtected ? target.apply(user, move) : HitResult.NO_EFFECT; /** Does {@linkcode hitResult} indicate that damage was dealt to the target? */ @@ -208,9 +210,9 @@ export class MoveEffectPhase extends PokemonPhase { } /** - * If the move has no effect on the target (i.e. the target is protected or immune), - * change the logged move result to FAIL. - */ + * If the move has no effect on the target (i.e. the target is protected or immune), + * change the logged move result to FAIL. + */ if (hitResult === HitResult.NO_EFFECT) { moveHistoryEntry.result = MoveResult.FAIL; } @@ -219,43 +221,41 @@ export class MoveEffectPhase extends PokemonPhase { const lastHit = (user.turnData.hitsLeft === 1 || !this.getTarget()?.isActive()); /** - * If the user can change forms by using the invoked move, - * it only changes forms after the move's last hit - * (see Relic Song's interaction with Parental Bond when used by Meloetta). - */ + * If the user can change forms by using the invoked move, + * it only changes forms after the move's last hit + * (see Relic Song's interaction with Parental Bond when used by Meloetta). + */ if (lastHit) { this.scene.triggerPokemonFormChange(user, SpeciesFormChangePostMoveTrigger); } /** - * Create a Promise that applys *all* effects from the invoked move's MoveEffectAttrs. - * These are ordered by trigger type (see {@linkcode MoveEffectTrigger}), and each trigger - * type requires different conditions to be met with respect to the move's hit result. - */ + * Create a Promise that applys *all* effects from the invoked move's MoveEffectAttrs. + * These are ordered by trigger type (see {@linkcode MoveEffectTrigger}), and each trigger + * type requires different conditions to be met with respect to the move's hit result. + */ applyAttrs.push(new Promise(resolve => { // Apply all effects with PRE_MOVE triggers (if the target isn't immune to the move) applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.PRE_APPLY && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && hitResult !== HitResult.NO_EFFECT, user, target, move).then(() => { // All other effects require the move to not have failed or have been cancelled to trigger if (hitResult !== HitResult.FAIL) { - /** Are the move's effects tied to the first turn of a charge move? */ - const chargeEffect = !!move.getAttrs(ChargeAttr).find(ca => ca.usedChargeEffect(user, this.getTarget() ?? null, move)); /** - * If the invoked move's effects are meant to trigger during the move's "charge turn," - * ignore all effects after this point. - * Otherwise, apply all self-targeted POST_APPLY effects. - */ - Utils.executeIf(!chargeEffect, () => applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.POST_APPLY - && attr.selfTarget && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), user, target, move)).then(() => { + * If the invoked move's effects are meant to trigger during the move's "charge turn," + * ignore all effects after this point. + * Otherwise, apply all self-targeted POST_APPLY effects. + */ + applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.POST_APPLY + && attr.selfTarget && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), user, target, move).then(() => { // All effects past this point require the move to have hit the target if (hitResult !== HitResult.NO_EFFECT) { // Apply all non-self-targeted POST_APPLY effects applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.POST_APPLY && !(attr as MoveEffectAttr).selfTarget && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), user, target, this.move.getMove()).then(() => { /** - * If the move hit, and the target doesn't have Shield Dust, - * apply the chance to flinch the target gained from King's Rock - */ + * If the move hit, and the target doesn't have Shield Dust, + * apply the chance to flinch the target gained from King's Rock + */ if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && !move.hitsSubstitute(user, target)) { const flinched = new Utils.BooleanHolder(false); user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched); @@ -264,7 +264,7 @@ export class MoveEffectPhase extends PokemonPhase { } } // If the move was not protected against, apply all HIT effects - Utils.executeIf(!isProtected && !chargeEffect, () => applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.HIT + Utils.executeIf(!isProtected, () => applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.HIT && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && (!attr.firstTargetOnly || firstTarget), user, target, this.move.getMove()).then(() => { // Apply the target's post-defend ability effects (as long as the target is active or can otherwise apply them) return Utils.executeIf(!target.isFainted() || target.canApplyAbility(), () => applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult).then(() => { @@ -277,17 +277,15 @@ export class MoveEffectPhase extends PokemonPhase { if (!user.isPlayer() && this.move.getMove() instanceof AttackMove) { user.scene.applyShuffledModifiers(this.scene, EnemyAttackStatusEffectChanceModifier, false, target); } - target.lapseTag(BattlerTagType.BEAK_BLAST_CHARGING); - if (move.category === MoveCategory.PHYSICAL && user.isPlayer() !== target.isPlayer()) { - target.lapseTag(BattlerTagType.SHELL_TRAP); - } + target.lapseTags(BattlerTagLapseType.AFTER_HIT); + })).then(() => { // Apply the user's post-attack ability effects applyPostAttackAbAttrs(PostAttackAbAttr, user, target, this.move.getMove(), hitResult).then(() => { /** - * If the invoked move is an attack, apply the user's chance to - * steal an item from the target granted by Grip Claw - */ + * If the invoked move is an attack, apply the user's chance to + * steal an item from the target granted by Grip Claw + */ if (this.move.getMove() instanceof AttackMove) { this.scene.applyModifiers(ContactHeldItemTransferChanceModifier, this.player, user, target); } @@ -342,12 +340,12 @@ export class MoveEffectPhase extends PokemonPhase { end() { const user = this.getUserPokemon(); /** - * If this phase isn't for the invoked move's last strike, - * unshift another MoveEffectPhase for the next strike. - * Otherwise, queue a message indicating the number of times the move has struck - * (if the move has struck more than once), then apply the heal from Shell Bell - * to the user. - */ + * If this phase isn't for the invoked move's last strike, + * unshift another MoveEffectPhase for the next strike. + * Otherwise, queue a message indicating the number of times the move has struck + * (if the move has struck more than once), then apply the heal from Shell Bell + * to the user. + */ if (user) { if (user.turnData.hitsLeft && --user.turnData.hitsLeft >= 1 && this.getTarget()?.isActive()) { this.scene.unshiftPhase(this.getNewHitPhase()); @@ -375,7 +373,7 @@ export class MoveEffectPhase extends PokemonPhase { */ hitCheck(target: Pokemon): boolean { // Moves targeting the user and entry hazards can't miss - if ([MoveTarget.USER, MoveTarget.ENEMY_SIDE].includes(this.move.getMove().moveTarget)) { + if ([ MoveTarget.USER, MoveTarget.ENEMY_SIDE ].includes(this.move.getMove().moveTarget)) { return true; } @@ -403,8 +401,15 @@ export class MoveEffectPhase extends PokemonPhase { return true; } + if (target.getTag(BattlerTagType.TELEKINESIS) && !target.getTag(SemiInvulnerableTag) && !this.move.getMove().hasAttr(OneHitKOAttr)) { + return true; + } + const semiInvulnerableTag = target.getTag(SemiInvulnerableTag); - if (semiInvulnerableTag && !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)) { + if (semiInvulnerableTag + && !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType) + && !(this.move.getMove().hasAttr(ToxicAccuracyAttr) && user.isOfType(Type.POISON)) + ) { return false; } @@ -439,9 +444,9 @@ export class MoveEffectPhase extends PokemonPhase { } /** - * Removes the given {@linkcode Pokemon} from this phase's target list - * @param target {@linkcode Pokemon} the Pokemon to be removed - */ + * Removes the given {@linkcode Pokemon} from this phase's target list + * @param target {@linkcode Pokemon} the Pokemon to be removed + */ removeTarget(target: Pokemon): void { const targetIndex = this.targets.findIndex(ind => ind === target.getBattlerIndex()); if (targetIndex !== -1) { @@ -450,19 +455,19 @@ export class MoveEffectPhase extends PokemonPhase { } /** - * Prevents subsequent strikes of this phase's invoked move from occurring - * @param target {@linkcode Pokemon} if defined, only stop subsequent - * strikes against this Pokemon - */ + * Prevents subsequent strikes of this phase's invoked move from occurring + * @param target {@linkcode Pokemon} if defined, only stop subsequent + * strikes against this Pokemon + */ stopMultiHit(target?: Pokemon): void { /** If given a specific target, remove the target from subsequent strikes */ if (target) { this.removeTarget(target); } /** - * If no target specified, or the specified target was the last of this move's - * targets, completely cancel all subsequent strikes. - */ + * If no target specified, or the specified target was the last of this move's + * targets, completely cancel all subsequent strikes. + */ if (!target || this.targets.length === 0 ) { this.getUserPokemon()!.turnData.hitCount = 1; // TODO: is the bang correct here? this.getUserPokemon()!.turnData.hitsLeft = 1; // TODO: is the bang correct here? diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 0a75c32bac3..5c6c339ffa5 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -1,309 +1,498 @@ -import BattleScene from "#app/battle-scene"; import { BattlerIndex } from "#app/battle"; -import { applyAbAttrs, applyPostMoveUsedAbAttrs, applyPreAttackAbAttrs, BlockRedirectAbAttr, IncreasePpAbAttr, PokemonTypeChangeAbAttr, PostMoveUsedAbAttr, RedirectMoveAbAttr } from "#app/data/ability"; +import BattleScene from "#app/battle-scene"; +import { applyAbAttrs, applyPostMoveUsedAbAttrs, applyPreAttackAbAttrs, BlockRedirectAbAttr, IncreasePpAbAttr, PokemonTypeChangeAbAttr, PostMoveUsedAbAttr, RedirectMoveAbAttr, ReduceStatusEffectDurationAbAttr } from "#app/data/ability"; import { CommonAnim } from "#app/data/battle-anims"; import { BattlerTagLapseType, CenterOfAttentionTag } from "#app/data/battler-tags"; -import { allMoves, applyMoveAttrs, BypassRedirectAttr, BypassSleepAttr, ChargeAttr, CopyMoveAttr, HealStatusEffectAttr, MoveFlags, PreMoveMessageAttr } from "#app/data/move"; +import { allMoves, applyMoveAttrs, BypassRedirectAttr, BypassSleepAttr, CopyMoveAttr, frenzyMissFunc, HealStatusEffectAttr, MoveFlags, PreMoveMessageAttr } from "#app/data/move"; import { SpeciesFormChangePreMoveTrigger } from "#app/data/pokemon-forms"; import { getStatusEffectActivationText, getStatusEffectHealText } from "#app/data/status-effect"; import { Type } from "#app/data/type"; import { getTerrainBlockMessage } from "#app/data/weather"; -import { Abilities } from "#app/enums/abilities"; -import { BattlerTagType } from "#app/enums/battler-tag-type"; -import { Moves } from "#app/enums/moves"; -import { StatusEffect } from "#app/enums/status-effect"; import { MoveUsedEvent } from "#app/events/battle-scene"; -import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon"; +import Pokemon, { MoveResult, PokemonMove } from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; -import * as Utils from "#app/utils"; +import Overrides from "#app/overrides"; +import { BattlePhase } from "#app/phases/battle-phase"; +import { CommonAnimPhase } from "#app/phases/common-anim-phase"; +import { MoveEffectPhase } from "#app/phases/move-effect-phase"; +import { MoveEndPhase } from "#app/phases/move-end-phase"; +import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; +import { BooleanHolder, NumberHolder } from "#app/utils"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Moves } from "#enums/moves"; +import { StatusEffect } from "#enums/status-effect"; import i18next from "i18next"; -import { BattlePhase } from "./battle-phase"; -import { CommonAnimPhase } from "./common-anim-phase"; -import { MoveEffectPhase } from "./move-effect-phase"; -import { MoveEndPhase } from "./move-end-phase"; -import { ShowAbilityPhase } from "./show-ability-phase"; +import { MoveChargePhase } from "#app/phases/move-charge-phase"; export class MovePhase extends BattlePhase { - public pokemon: Pokemon; - public move: PokemonMove; - public targets: BattlerIndex[]; + protected _pokemon: Pokemon; + protected _move: PokemonMove; + protected _targets: BattlerIndex[]; protected followUp: boolean; protected ignorePp: boolean; - protected failed: boolean; - protected cancelled: boolean; + protected failed: boolean = false; + protected cancelled: boolean = false; - constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp?: boolean, ignorePp?: boolean) { + public get pokemon(): Pokemon { + return this._pokemon; + } + + protected set pokemon(pokemon: Pokemon) { + this._pokemon = pokemon; + } + + public get move(): PokemonMove { + return this._move; + } + + protected set move(move: PokemonMove) { + this._move = move; + } + + public get targets(): BattlerIndex[] { + return this._targets; + } + + protected set targets(targets: BattlerIndex[]) { + this._targets = targets; + } + + /** + * @param followUp Indicates that the move being uses is a "follow-up" - for example, a move being used by Metronome or Dancer. + * Follow-ups bypass a few failure conditions, including flinches, sleep/paralysis/freeze and volatile status checks, etc. + */ + constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp: boolean = false, ignorePp: boolean = false) { super(scene); this.pokemon = pokemon; this.targets = targets; this.move = move; - this.followUp = followUp ?? false; - this.ignorePp = ignorePp ?? false; - this.failed = false; - this.cancelled = false; + this.followUp = followUp; + this.ignorePp = ignorePp; } - canMove(ignoreDisableTags?: boolean): boolean { + /** + * Checks if the pokemon is active, if the move is usable, and that the move is targetting something. + * @param ignoreDisableTags `true` to not check if the move is disabled + * @returns `true` if all the checks pass + */ + public canMove(ignoreDisableTags: boolean = false): boolean { return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp, ignoreDisableTags) && !!this.targets.length; } /**Signifies the current move should fail but still use PP */ - fail(): void { + public fail(): void { this.failed = true; } /**Signifies the current move should cancel and retain PP */ - cancel(): void { + public cancel(): void { this.cancelled = true; } - start() { + public start(): void { super.start(); console.log(Moves[this.move.moveId]); + // Check if move is unusable (e.g. because it's out of PP due to a mid-turn Spite). if (!this.canMove(true)) { - if (this.pokemon.isActive(true) && this.move.ppUsed >= this.move.getMovePp()) { // if the move PP was reduced from Spite or otherwise, the move fails + if (this.pokemon.isActive(true) && this.move.ppUsed >= this.move.getMovePp()) { this.fail(); this.showMoveText(); this.showFailedText(); } + return this.end(); } + this.pokemon.turnData.acted = true; + + // Reset hit-related turn data when starting follow-up moves (e.g. Metronomed moves, Dancer repeats) + if (this.followUp) { + this.pokemon.turnData.hitsLeft = -1; + this.pokemon.turnData.hitCount = 0; + } + + // Check move to see if arena.ignoreAbilities should be true. if (!this.followUp) { if (this.move.getMove().checkFlag(MoveFlags.IGNORE_ABILITIES, this.pokemon, null)) { this.scene.arena.setIgnoreAbilities(true, this.pokemon.getBattlerIndex()); } + } + + this.resolveRedirectTarget(); + + this.resolveCounterAttackTarget(); + + this.resolvePreMoveStatusEffects(); + + this.lapsePreMoveAndMoveTags(); + + if (!(this.failed || this.cancelled)) { + this.resolveFinalPreMoveCancellationChecks(); + } + + if (this.cancelled || this.failed) { + this.handlePreMoveFailures(); + } else if (this.move.getMove().isChargingMove() && !this.pokemon.getTag(BattlerTagType.CHARGING)) { + this.chargeMove(); } else { - this.pokemon.turnData.hitsLeft = 0; // TODO: is `0` correct? - this.pokemon.turnData.hitCount = 0; // TODO: is `0` correct? + this.useMove(); } - // Move redirection abilities (ie. Storm Drain) only support single target moves - const moveTarget = this.targets.length === 1 - ? new Utils.IntegerHolder(this.targets[0]) - : null; - if (moveTarget) { - const oldTarget = moveTarget.value; - this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, moveTarget)); - this.pokemon.getOpponents().forEach(p => { - const redirectTag = p.getTag(CenterOfAttentionTag) as CenterOfAttentionTag; - if (redirectTag && (!redirectTag.powder || (!this.pokemon.isOfType(Type.GRASS) && !this.pokemon.hasAbility(Abilities.OVERCOAT)))) { - moveTarget.value = p.getBattlerIndex(); - } - }); - //Check if this move is immune to being redirected, and restore its target to the intended target if it is. - if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) || this.move.getMove().hasAttr(BypassRedirectAttr))) { - //If an ability prevented this move from being redirected, display its ability pop up. - if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) && !this.move.getMove().hasAttr(BypassRedirectAttr)) && oldTarget !== moveTarget.value) { - this.scene.unshiftPhase(new ShowAbilityPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr))); - } - moveTarget.value = oldTarget; - } - this.targets[0] = moveTarget.value; + this.end(); + } + + /** Check for cancellation edge cases - no targets remaining, or {@linkcode Moves.NONE} is in the queue */ + protected resolveFinalPreMoveCancellationChecks(): void { + const targets = this.getActiveTargetPokemon(); + const moveQueue = this.pokemon.getMoveQueue(); + + if (targets.length === 0 || (moveQueue.length && moveQueue[0].move === Moves.NONE)) { + this.showMoveText(); + this.showFailedText(); + this.cancel(); } + } - // Check for counterattack moves to switch target - if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) { - if (this.pokemon.turnData.attacksReceived.length) { - const attack = this.pokemon.turnData.attacksReceived[0]; - this.targets[0] = attack.sourceBattlerIndex; - - // account for metal burst and comeuppance hitting remaining targets in double battles - // counterattack will redirect to remaining ally if original attacker faints - if (this.scene.currentBattle.double && this.move.getMove().hasFlag(MoveFlags.REDIRECT_COUNTER)) { - if (this.scene.getField()[this.targets[0]].hp === 0) { - const opposingField = this.pokemon.isPlayer() ? this.scene.getEnemyField() : this.scene.getPlayerField(); - //@ts-ignore - this.targets[0] = opposingField.find(p => p.hp > 0)?.getBattlerIndex(); //TODO: fix ts-ignore - } - } - } - if (this.targets[0] === BattlerIndex.ATTACKER) { - this.fail(); // Marks the move as failed for later in doMove - this.showMoveText(); - this.showFailedText(); - } - } - - const targets = this.scene.getField(true).filter(p => { - if (this.targets.indexOf(p.getBattlerIndex()) > -1) { - return true; - } - return false; - }); - - const doMove = () => { - this.pokemon.turnData.acted = true; // Record that the move was attempted, even if it fails - - this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE); - - let ppUsed = 1; - // Filter all opponents to include only those this move is targeting - const targetedOpponents = this.pokemon.getOpponents().filter(o => this.targets.includes(o.getBattlerIndex())); - for (const opponent of targetedOpponents) { - if (this.move.ppUsed + ppUsed >= this.move.getMovePp()) { // If we're already at max PP usage, stop checking - break; - } - if (opponent.hasAbilityWithAttr(IncreasePpAbAttr)) { // Accounting for abilities like Pressure - ppUsed++; - } - } - - if (!this.followUp && this.canMove() && !this.cancelled) { - this.pokemon.lapseTags(BattlerTagLapseType.MOVE); - } - - const moveQueue = this.pokemon.getMoveQueue(); - if (this.cancelled || this.failed) { - if (this.failed) { - this.move.usePp(ppUsed); // Only use PP if the move failed - this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed)); - } - - // Record a failed move so Abilities like Truant don't trigger next turn and soft-lock - this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL }); - - this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc. - this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE); - moveQueue.shift(); // Remove the second turn of charge moves - return this.end(); - } - - this.scene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangePreMoveTrigger); - - if (this.move.moveId) { - this.showMoveText(); - } - - // This should only happen when there are no valid targets left on the field - if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || !targets.length) { - this.showFailedText(); - this.cancel(); - - // Record a failed move so Abilities like Truant don't trigger next turn and soft-lock - this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL }); - - this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc. - this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE); - - moveQueue.shift(); - return this.end(); - } - - if ((!moveQueue.length || !moveQueue.shift()?.ignorePP) && !this.ignorePp) { // using .shift here clears out two turn moves once they've been used - this.move.usePp(ppUsed); - this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed)); - } - - if (!allMoves[this.move.moveId].hasAttr(CopyMoveAttr)) { - this.scene.currentBattle.lastMove = this.move.moveId; - } - - // Assume conditions affecting targets only apply to moves with a single target - let success = this.move.getMove().applyConditions(this.pokemon, targets[0], this.move.getMove()); - const cancelled = new Utils.BooleanHolder(false); - let failedText = this.move.getMove().getFailedText(this.pokemon, targets[0], this.move.getMove(), cancelled); - if (success && this.scene.arena.isMoveWeatherCancelled(this.pokemon, this.move.getMove())) { - success = false; - } else if (success && this.scene.arena.isMoveTerrainCancelled(this.pokemon, this.targets, this.move.getMove())) { - success = false; - if (failedText === null) { - failedText = getTerrainBlockMessage(targets[0], this.scene.arena.terrain?.terrainType!); // TODO: is this bang correct? - } - } - - /** - * Trigger pokemon type change before playing the move animation - * Will still change the user's type when using Roar, Whirlwind, Trick-or-Treat, and Forest's Curse, - * regardless of whether the move successfully executes or not. - */ - if (success || [Moves.ROAR, Moves.WHIRLWIND, Moves.TRICK_OR_TREAT, Moves.FORESTS_CURSE].includes(this.move.moveId)) { - applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove()); - } - - if (success) { - this.scene.unshiftPhase(this.getEffectPhase()); - } else { - this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual }); - if (!cancelled.value) { - this.showFailedText(failedText); - } - } - // Checks if Dancer ability is triggered - if (this.move.getMove().hasFlag(MoveFlags.DANCE_MOVE) && !this.followUp) { - // Pokemon with Dancer can be on either side of the battle so we check in both cases - this.scene.getPlayerField().forEach(pokemon => { - applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets); - }); - this.scene.getEnemyField().forEach(pokemon => { - applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets); - }); - } - this.end(); - }; + public getActiveTargetPokemon(): Pokemon[] { + return this.scene.getField(true).filter(p => this.targets.includes(p.getBattlerIndex())); + } + /** + * Handles {@link StatusEffect.SLEEP Sleep}/{@link StatusEffect.PARALYSIS Paralysis}/{@link StatusEffect.FREEZE Freeze} rolls and side effects. + */ + protected resolvePreMoveStatusEffects(): void { if (!this.followUp && this.pokemon.status && !this.pokemon.status.isPostTurn()) { this.pokemon.status.incrementTurn(); let activated = false; let healed = false; switch (this.pokemon.status.effect) { - case StatusEffect.PARALYSIS: - if (!this.pokemon.randSeedInt(4)) { - activated = true; - this.cancelled = true; - } - break; - case StatusEffect.SLEEP: - applyMoveAttrs(BypassSleepAttr, this.pokemon, null, this.move.getMove()); - healed = this.pokemon.status.turnCount === this.pokemon.status.cureTurn; - activated = !healed && !this.pokemon.getTag(BattlerTagType.BYPASS_SLEEP); - this.cancelled = activated; - break; - case StatusEffect.FREEZE: - healed = !!this.move.getMove().findAttr(attr => attr instanceof HealStatusEffectAttr && attr.selfTarget && attr.isOfEffect(StatusEffect.FREEZE)) || !this.pokemon.randSeedInt(5); - activated = !healed; - this.cancelled = activated; - break; + case StatusEffect.PARALYSIS: + activated = (!this.pokemon.randSeedInt(4) || Overrides.STATUS_ACTIVATION_OVERRIDE === true) && Overrides.STATUS_ACTIVATION_OVERRIDE !== false; + break; + case StatusEffect.SLEEP: + applyMoveAttrs(BypassSleepAttr, this.pokemon, null, this.move.getMove()); + const turnsRemaining = new NumberHolder(this.pokemon.status.sleepTurnsRemaining ?? 0); + applyAbAttrs(ReduceStatusEffectDurationAbAttr, this.pokemon, null, false, this.pokemon.status.effect, turnsRemaining); + this.pokemon.status.sleepTurnsRemaining = turnsRemaining.value; + healed = this.pokemon.status.sleepTurnsRemaining <= 0; + activated = !healed && !this.pokemon.getTag(BattlerTagType.BYPASS_SLEEP); + break; + case StatusEffect.FREEZE: + healed = + !!this.move.getMove().findAttr((attr) => + attr instanceof HealStatusEffectAttr + && attr.selfTarget + && attr.isOfEffect(StatusEffect.FREEZE)) + || (!this.pokemon.randSeedInt(5) && Overrides.STATUS_ACTIVATION_OVERRIDE !== true) + || Overrides.STATUS_ACTIVATION_OVERRIDE === false; + + activated = !healed; + break; } if (activated) { + this.cancel(); this.scene.queueMessage(getStatusEffectActivationText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon))); this.scene.unshiftPhase(new CommonAnimPhase(this.scene, this.pokemon.getBattlerIndex(), undefined, CommonAnim.POISON + (this.pokemon.status.effect - 1))); - doMove(); - } else { - if (healed) { - this.scene.queueMessage(getStatusEffectHealText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon))); - this.pokemon.resetStatus(); - this.pokemon.updateInfo(); - } - doMove(); + } else if (healed) { + this.scene.queueMessage(getStatusEffectHealText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon))); + this.pokemon.resetStatus(); + this.pokemon.updateInfo(); } + } + } + + /** + * Lapse {@linkcode BattlerTagLapseType.PRE_MOVE PRE_MOVE} tags that trigger before a move is used, regardless of whether or not it failed. + * Also lapse {@linkcode BattlerTagLapseType.MOVE MOVE} tags if the move should be successful. + */ + protected lapsePreMoveAndMoveTags(): void { + this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE); + + // TODO: does this intentionally happen before the no targets/Moves.NONE on queue cancellation case is checked? + if (!this.followUp && this.canMove() && !this.cancelled) { + this.pokemon.lapseTags(BattlerTagLapseType.MOVE); + } + } + + protected useMove(): void { + const targets = this.getActiveTargetPokemon(); + const moveQueue = this.pokemon.getMoveQueue(); + + // form changes happen even before we know that the move wll execute. + this.scene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangePreMoveTrigger); + + this.showMoveText(); + + if (moveQueue.length > 0) { + // Using .shift here clears out two turn moves once they've been used + this.ignorePp = moveQueue.shift()?.ignorePP ?? false; + } + + if (this.pokemon.getTag(BattlerTagType.CHARGING)?.sourceMove === this.move.moveId) { + this.pokemon.lapseTag(BattlerTagType.CHARGING); + } + + // "commit" to using the move, deducting PP. + if (!this.ignorePp) { + const ppUsed = 1 + this.getPpIncreaseFromPressure(targets); + + this.move.usePp(ppUsed); + this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed)); + } + + // Update the battle's "last move" pointer, unless we're currently mimicking a move. + if (!allMoves[this.move.moveId].hasAttr(CopyMoveAttr)) { + this.scene.currentBattle.lastMove = this.move.moveId; + } + + /** + * Determine if the move is successful (meaning that its damage/effects can be attempted) + * by checking that all of the following are true: + * - Conditional attributes of the move are all met + * - The target's `ForceSwitchOutImmunityAbAttr` is not triggered (see {@linkcode Move.prototype.applyConditions}) + * - Weather does not block the move + * - Terrain does not block the move + * + * TODO: These steps are straightforward, but the implementation below is extremely convoluted. + */ + + const move = this.move.getMove(); + + /** + * Move conditions assume the move has a single target + * TODO: is this sustainable? + */ + const passesConditions = move.applyConditions(this.pokemon, targets[0], move); + const failedDueToWeather: boolean = this.scene.arena.isMoveWeatherCancelled(this.pokemon, move); + const failedDueToTerrain: boolean = this.scene.arena.isMoveTerrainCancelled(this.pokemon, this.targets, move); + + const success = passesConditions && !failedDueToWeather && !failedDueToTerrain; + + /** + * If the move has not failed, trigger ability-based user type changes and then execute it. + * + * Notably, Roar, Whirlwind, Trick-or-Treat, and Forest's Curse will trigger these type changes even + * if the move fails. + */ + if (success) { + applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove()); + this.scene.unshiftPhase(new MoveEffectPhase(this.scene, this.pokemon.getBattlerIndex(), this.targets, this.move)); + } else { - doMove(); + if ([ Moves.ROAR, Moves.WHIRLWIND, Moves.TRICK_OR_TREAT, Moves.FORESTS_CURSE ].includes(this.move.moveId)) { + applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove()); + } + + this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual }); + + let failedText: string | undefined; + const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new BooleanHolder(false)); + + if (failureMessage) { + failedText = failureMessage; + } else if (failedDueToTerrain) { + failedText = getTerrainBlockMessage(this.pokemon, this.scene.arena.getTerrainType()); + } + + this.showFailedText(failedText); + + // Remove the user from its semi-invulnerable state (if applicable) + this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); + } + + // Handle Dancer, which triggers immediately after a move is used (rather than waiting on `this.end()`). + // Note that the `!this.followUp` check here prevents an infinite Dancer loop. + if (this.move.getMove().hasFlag(MoveFlags.DANCE_MOVE) && !this.followUp) { + this.scene.getField(true).forEach(pokemon => { + applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets); + }); } } - getEffectPhase(): MoveEffectPhase { - return new MoveEffectPhase(this.scene, this.pokemon.getBattlerIndex(), this.targets, this.move); + /** Queues a {@linkcode MoveChargePhase} for this phase's invoked move. */ + protected chargeMove() { + const move = this.move.getMove(); + const targets = this.getActiveTargetPokemon(); + + if (move.applyConditions(this.pokemon, targets[0], move)) { + // Protean and Libero apply on the charging turn of charge moves + applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove()); + + this.showMoveText(); + this.scene.unshiftPhase(new MoveChargePhase(this.scene, this.pokemon.getBattlerIndex(), this.targets[0], this.move)); + } else { + this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual }); + + let failedText: string | undefined; + const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new BooleanHolder(false)); + + if (failureMessage) { + failedText = failureMessage; + } + + this.showMoveText(); + this.showFailedText(failedText); + + // Remove the user from its semi-invulnerable state (if applicable) + this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); + } } - showMoveText(): void { - if (this.move.getMove().hasAttr(ChargeAttr)) { - const lastMove = this.pokemon.getLastXMoves() as TurnMove[]; - if (!lastMove.length || lastMove[0].move !== this.move.getMove().id || lastMove[0].result !== MoveResult.OTHER) { - this.scene.queueMessage(i18next.t("battle:useMove", { - pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon), - moveName: this.move.getName() - }), 500); - return; + /** + * Queues a {@linkcode MoveEndPhase} if the move wasn't a {@linkcode followUp} and {@linkcode canMove()} returns `true`, + * then ends the phase. + */ + public end(): void { + if (!this.followUp && this.canMove()) { + this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex())); + } + + super.end(); + } + + /** + * Applies PP increasing abilities (currently only {@link Abilities.PRESSURE Pressure}) if they exist on the target pokemon. + * Note that targets must include only active pokemon. + * + * TODO: This hardcodes the PP increase at 1 per opponent, rather than deferring to the ability. + */ + public getPpIncreaseFromPressure(targets: Pokemon[]): number { + const foesWithPressure = this.pokemon.getOpponents().filter(o => targets.includes(o) && o.isActive(true) && o.hasAbilityWithAttr(IncreasePpAbAttr)); + return foesWithPressure.length; + } + + /** + * Modifies `this.targets` in place, based upon: + * - Move redirection abilities, effects, etc. + * - Counterattacks, which pass a special value into the `targets` constructor param (`[`{@linkcode BattlerIndex.ATTACKER}`]`). + */ + protected resolveRedirectTarget(): void { + if (this.targets.length === 1) { + const currentTarget = this.targets[0]; + const redirectTarget = new NumberHolder(currentTarget); + + // check move redirection abilities of every pokemon *except* the user. + this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, redirectTarget)); + + /** `true` if an Ability is responsible for redirecting the move to another target; `false` otherwise */ + let redirectedByAbility = (currentTarget !== redirectTarget.value); + + // check for center-of-attention tags (note that this will override redirect abilities) + this.pokemon.getOpponents().forEach(p => { + const redirectTag = p.getTag(CenterOfAttentionTag); + + // TODO: don't hardcode this interaction. + // Handle interaction between the rage powder center-of-attention tag and moves used by grass types/overcoat-havers (which are immune to RP's redirect) + if (redirectTag && (!redirectTag.powder || (!this.pokemon.isOfType(Type.GRASS) && !this.pokemon.hasAbility(Abilities.OVERCOAT)))) { + redirectTarget.value = p.getBattlerIndex(); + redirectedByAbility = false; + } + }); + + if (currentTarget !== redirectTarget.value) { + const bypassRedirectAttrs = this.move.getMove().getAttrs(BypassRedirectAttr); + bypassRedirectAttrs.forEach((attr) => { + if (!attr.abilitiesOnly || redirectedByAbility) { + redirectTarget.value = currentTarget; + } + }); + + if (this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr)) { + redirectTarget.value = currentTarget; + this.scene.unshiftPhase(new ShowAbilityPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr))); + } + + this.targets[0] = redirectTarget.value; } } + } - if (this.pokemon.getTag(BattlerTagType.RECHARGING || BattlerTagType.INTERRUPTED)) { + /** + * Counter-attacking moves pass in `[`{@linkcode BattlerIndex.ATTACKER}`]` into the constructor's `targets` param. + * This function modifies `this.targets` to reflect the actual battler index of the user's last + * attacker. + * + * If there is no last attacker, or they are no longer on the field, a message is displayed and the + * move is marked for failure. + */ + protected resolveCounterAttackTarget(): void { + if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) { + if (this.pokemon.turnData.attacksReceived.length) { + this.targets[0] = this.pokemon.turnData.attacksReceived[0].sourceBattlerIndex; + + // account for metal burst and comeuppance hitting remaining targets in double battles + // counterattack will redirect to remaining ally if original attacker faints + if (this.scene.currentBattle.double && this.move.getMove().hasFlag(MoveFlags.REDIRECT_COUNTER)) { + if (this.scene.getField()[this.targets[0]].hp === 0) { + const opposingField = this.pokemon.isPlayer() ? this.scene.getEnemyField() : this.scene.getPlayerField(); + this.targets[0] = opposingField.find(p => p.hp > 0)?.getBattlerIndex() ?? BattlerIndex.ATTACKER; + } + } + } + + if (this.targets[0] === BattlerIndex.ATTACKER) { + this.fail(); + this.showMoveText(); + this.showFailedText(); + } + } + } + + /** + * Handles the case where the move was cancelled or failed: + * - Uses PP if the move failed (not cancelled) and should use PP (failed moves are not affected by {@link Abilities.PRESSURE Pressure}) + * - Records a cancelled OR failed move in move history, so abilities like {@link Abilities.TRUANT Truant} don't trigger on the + * next turn and soft-lock. + * - Lapses `MOVE_EFFECT` tags: + * - Semi-invulnerable battler tags (Fly/Dive/etc.) are intended to lapse on move effects, but also need + * to lapse on move failure/cancellation. + * + * TODO: ...this seems weird. + * - Lapses `AFTER_MOVE` tags: + * - This handles the effects of {@link Moves.SUBSTITUTE Substitute} + * - Removes the second turn of charge moves + */ + protected handlePreMoveFailures(): void { + if (this.cancelled || this.failed) { + if (this.failed) { + const ppUsed = this.ignorePp ? 0 : 1; + + if (ppUsed) { + this.move.usePp(); + } + + this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed)); + } + + if (this.cancelled && this.pokemon.summonData?.tags?.find(t => t.tagType === BattlerTagType.FRENZY)) { + frenzyMissFunc(this.pokemon, this.move.getMove()); + } + + this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL }); + + this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); + this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE); + + this.pokemon.getMoveQueue().shift(); + } + } + + /** + * Displays the move's usage text to the player, unless it's a charge turn (ie: {@link Moves.SOLAR_BEAM Solar Beam}), + * the pokemon is on a recharge turn (ie: {@link Moves.HYPER_BEAM Hyper Beam}), or a 2-turn move was interrupted (ie: {@link Moves.FLY Fly}). + */ + protected showMoveText(): void { + if (this.move.moveId === Moves.NONE) { + return; + } + + if (this.pokemon.getTag(BattlerTagType.RECHARGING) || this.pokemon.getTag(BattlerTagType.INTERRUPTED)) { return; } @@ -311,18 +500,10 @@ export class MovePhase extends BattlePhase { pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon), moveName: this.move.getName() }), 500); - applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents().find(() => true)!, this.move.getMove()); //TODO: is the bang correct here? + applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents()[0], this.move.getMove()); } - showFailedText(failedText: string | null = null): void { - this.scene.queueMessage(failedText || i18next.t("battle:attackFailed")); - } - - end() { - if (!this.followUp && this.canMove()) { - this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex())); - } - - super.end(); + protected showFailedText(failedText?: string): void { + this.scene.queueMessage(failedText ?? i18next.t("battle:attackFailed")); } } diff --git a/src/phases/mystery-encounter-phases.ts b/src/phases/mystery-encounter-phases.ts index 0efaf1bf4ca..49e78fa5369 100644 --- a/src/phases/mystery-encounter-phases.ts +++ b/src/phases/mystery-encounter-phases.ts @@ -220,7 +220,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase { super.start(); // Lapse any residual flinches/endures but ignore all other turn-end battle tags - const includedLapseTags = [BattlerTagType.FLINCHED, BattlerTagType.ENDURING]; + const includedLapseTags = [ BattlerTagType.FLINCHED, BattlerTagType.ENDURING ]; const field = this.scene.getField(true).filter(p => p.summonData); field.forEach(pokemon => { const tags = pokemon.summonData.tags; @@ -402,7 +402,7 @@ export class MysteryEncounterBattlePhase extends Phase { } } - const availablePartyMembers = scene.getParty().filter(p => !p.isFainted()); + const availablePartyMembers = scene.getParty().filter(p => p.isAllowedInBattle()); if (!availablePartyMembers[0].isOnField()) { scene.pushPhase(new SummonPhase(scene, 0)); diff --git a/src/phases/new-biome-encounter-phase.ts b/src/phases/new-biome-encounter-phase.ts index 2a526a22ee2..eea591c3936 100644 --- a/src/phases/new-biome-encounter-phase.ts +++ b/src/phases/new-biome-encounter-phase.ts @@ -22,7 +22,7 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase { } const enemyField = this.scene.getEnemyField(); - const moveTargets: any[] = [this.scene.arenaEnemy, enemyField]; + const moveTargets: any[] = [ this.scene.arenaEnemy, enemyField ]; const mysteryEncounter = this.scene.currentBattle?.mysteryEncounter?.introVisuals; if (mysteryEncounter) { moveTargets.push(mysteryEncounter); diff --git a/src/phases/next-encounter-phase.ts b/src/phases/next-encounter-phase.ts index d63823e4167..407d7c26b5d 100644 --- a/src/phases/next-encounter-phase.ts +++ b/src/phases/next-encounter-phase.ts @@ -23,7 +23,7 @@ export class NextEncounterPhase extends EncounterPhase { this.scene.arenaNextEnemy.setVisible(true); const enemyField = this.scene.getEnemyField(); - const moveTargets: any[] = [this.scene.arenaEnemy, this.scene.arenaNextEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.lastEnemyTrainer]; + const moveTargets: any[] = [ this.scene.arenaEnemy, this.scene.arenaNextEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.lastEnemyTrainer ]; const lastEncounterVisuals = this.scene.lastMysteryEncounter?.introVisuals; if (lastEncounterVisuals) { moveTargets.push(lastEncounterVisuals); diff --git a/src/phases/obtain-status-effect-phase.ts b/src/phases/obtain-status-effect-phase.ts index bf38c432394..01384b932cb 100644 --- a/src/phases/obtain-status-effect-phase.ts +++ b/src/phases/obtain-status-effect-phase.ts @@ -6,36 +6,32 @@ import { StatusEffect } from "#app/enums/status-effect"; import Pokemon from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; import { PokemonPhase } from "./pokemon-phase"; -import { PostTurnStatusEffectPhase } from "./post-turn-status-effect-phase"; export class ObtainStatusEffectPhase extends PokemonPhase { - private statusEffect?: StatusEffect | undefined; - private cureTurn?: integer | null; + private statusEffect?: StatusEffect; + private turnsRemaining?: number; private sourceText?: string | null; private sourcePokemon?: Pokemon | null; - constructor(scene: BattleScene, battlerIndex: BattlerIndex, statusEffect?: StatusEffect, cureTurn?: integer | null, sourceText?: string | null, sourcePokemon?: Pokemon | null) { + constructor(scene: BattleScene, battlerIndex: BattlerIndex, statusEffect?: StatusEffect, turnsRemaining?: number, sourceText?: string | null, sourcePokemon?: Pokemon | null) { super(scene, battlerIndex); this.statusEffect = statusEffect; - this.cureTurn = cureTurn; + this.turnsRemaining = turnsRemaining; this.sourceText = sourceText; - this.sourcePokemon = sourcePokemon; // For tracking which Pokemon caused the status effect + this.sourcePokemon = sourcePokemon; } start() { const pokemon = this.getPokemon(); if (pokemon && !pokemon.status) { if (pokemon.trySetStatus(this.statusEffect, false, this.sourcePokemon)) { - if (this.cureTurn) { - pokemon.status!.cureTurn = this.cureTurn; // TODO: is this bang correct? + if (this.turnsRemaining) { + pokemon.status!.sleepTurnsRemaining = this.turnsRemaining; } pokemon.updateInfo(true); new CommonBattleAnim(CommonAnim.POISON + (this.statusEffect! - 1), pokemon).play(this.scene, false, () => { this.scene.queueMessage(getStatusEffectObtainText(this.statusEffect, getPokemonNameWithAffix(pokemon), this.sourceText ?? undefined)); - if (pokemon.status?.isPostTurn()) { - this.scene.pushPhase(new PostTurnStatusEffectPhase(this.scene, this.battlerIndex)); - } this.end(); }); return; diff --git a/src/phases/outdated-phase.ts b/src/phases/outdated-phase.ts deleted file mode 100644 index 4baf16d2f56..00000000000 --- a/src/phases/outdated-phase.ts +++ /dev/null @@ -1,13 +0,0 @@ -import BattleScene from "#app/battle-scene"; -import { Phase } from "#app/phase"; -import { Mode } from "#app/ui/ui"; - -export class OutdatedPhase extends Phase { - constructor(scene: BattleScene) { - super(scene); - } - - start(): void { - this.scene.ui.setMode(Mode.OUTDATED); - } -} diff --git a/src/phases/party-status-cure-phase.ts b/src/phases/party-status-cure-phase.ts deleted file mode 100644 index e4903c7fc1f..00000000000 --- a/src/phases/party-status-cure-phase.ts +++ /dev/null @@ -1,48 +0,0 @@ -import BattleScene from "#app/battle-scene"; -import { Abilities } from "#app/enums/abilities"; -import Pokemon from "#app/field/pokemon"; -import { BattlePhase } from "./battle-phase"; -import { ShowAbilityPhase } from "./show-ability-phase"; - -/** - * Cures the party of all non-volatile status conditions, shows a message - * @param {BattleScene} scene The current scene - * @param {Pokemon} user The user of the move that cures the party - * @param {string} message The message that should be displayed - * @param {Abilities} abilityCondition Pokemon with this ability will not be affected ie. Soundproof - */ -export class PartyStatusCurePhase extends BattlePhase { - private user: Pokemon; - private message: string; - private abilityCondition: Abilities; - - constructor(scene: BattleScene, user: Pokemon, message: string, abilityCondition: Abilities) { - super(scene); - - this.user = user; - this.message = message; - this.abilityCondition = abilityCondition; - } - - start() { - super.start(); - for (const pokemon of this.scene.getParty()) { - if (!pokemon.isOnField() || pokemon === this.user) { - pokemon.resetStatus(false); - pokemon.updateInfo(true); - } else { - if (!pokemon.hasAbility(this.abilityCondition)) { - pokemon.resetStatus(); - pokemon.updateInfo(true); - } else { - // Manually show ability bar, since we're not hooked into the targeting system - pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, pokemon.getPassiveAbility()?.id === this.abilityCondition)); - } - } - } - if (this.message) { - this.scene.queueMessage(this.message); - } - this.end(); - } -} diff --git a/src/phases/pokemon-anim-phase.ts b/src/phases/pokemon-anim-phase.ts index 50a62837f9c..26ae11d1026 100644 --- a/src/phases/pokemon-anim-phase.ts +++ b/src/phases/pokemon-anim-phase.ts @@ -5,7 +5,6 @@ import Pokemon from "#app/field/pokemon"; import { BattlePhase } from "#app/phases/battle-phase"; - export class PokemonAnimPhase extends BattlePhase { /** The type of animation to play in this phase */ private key: PokemonAnimType; @@ -26,20 +25,20 @@ export class PokemonAnimPhase extends BattlePhase { super.start(); switch (this.key) { - case PokemonAnimType.SUBSTITUTE_ADD: - this.doSubstituteAddAnim(); - break; - case PokemonAnimType.SUBSTITUTE_PRE_MOVE: - this.doSubstitutePreMoveAnim(); - break; - case PokemonAnimType.SUBSTITUTE_POST_MOVE: - this.doSubstitutePostMoveAnim(); - break; - case PokemonAnimType.SUBSTITUTE_REMOVE: - this.doSubstituteRemoveAnim(); - break; - default: - this.end(); + case PokemonAnimType.SUBSTITUTE_ADD: + this.doSubstituteAddAnim(); + break; + case PokemonAnimType.SUBSTITUTE_PRE_MOVE: + this.doSubstitutePreMoveAnim(); + break; + case PokemonAnimType.SUBSTITUTE_POST_MOVE: + this.doSubstitutePostMoveAnim(); + break; + case PokemonAnimType.SUBSTITUTE_REMOVE: + this.doSubstituteRemoveAnim(); + break; + default: + this.end(); } } @@ -53,7 +52,7 @@ export class PokemonAnimPhase extends BattlePhase { const sprite = this.scene.addFieldSprite( this.pokemon.x + this.pokemon.getSprite().x, this.pokemon.y + this.pokemon.getSprite().y, - `pkmn${this.pokemon.isPlayer() ? "__back": ""}__sub` + `pkmn${this.pokemon.isPlayer() ? "__back" : ""}__sub` ); sprite.setOrigin(0.5, 1); this.scene.field.add(sprite); @@ -179,7 +178,7 @@ export class PokemonAnimPhase extends BattlePhase { const sprite = this.scene.addFieldSprite( subSprite.x, subSprite.y, - `pkmn${this.pokemon.isPlayer() ? "__back": ""}__sub` + `pkmn${this.pokemon.isPlayer() ? "__back" : ""}__sub` ); sprite.setOrigin(0.5, 1); this.scene.field.add(sprite); diff --git a/src/phases/post-summon-phase.ts b/src/phases/post-summon-phase.ts index b99c0b90fd8..3db98d9926c 100644 --- a/src/phases/post-summon-phase.ts +++ b/src/phases/post-summon-phase.ts @@ -18,9 +18,9 @@ export class PostSummonPhase extends PokemonPhase { const pokemon = this.getPokemon(); if (pokemon.status?.effect === StatusEffect.TOXIC) { - pokemon.status.turnCount = 0; + pokemon.status.toxicTurnCount = 0; } - this.scene.arena.applyTags(ArenaTrapTag, pokemon); + this.scene.arena.applyTags(ArenaTrapTag, false, pokemon); // If this is mystery encounter and has post summon phase tag, apply post summon effects if (this.scene.currentBattle.isBattleMysteryEncounter() && pokemon.findTags(t => t instanceof MysteryEncounterPostSummonTag).length > 0) { diff --git a/src/phases/post-turn-status-effect-phase.ts b/src/phases/post-turn-status-effect-phase.ts index 285bbddde88..2efd992a2b5 100644 --- a/src/phases/post-turn-status-effect-phase.ts +++ b/src/phases/post-turn-status-effect-phase.ts @@ -26,16 +26,16 @@ export class PostTurnStatusEffectPhase extends PokemonPhase { this.scene.queueMessage(getStatusEffectActivationText(pokemon.status.effect, getPokemonNameWithAffix(pokemon))); const damage = new Utils.NumberHolder(0); switch (pokemon.status.effect) { - case StatusEffect.POISON: - damage.value = Math.max(pokemon.getMaxHp() >> 3, 1); - break; - case StatusEffect.TOXIC: - damage.value = Math.max(Math.floor((pokemon.getMaxHp() / 16) * pokemon.status.turnCount), 1); - break; - case StatusEffect.BURN: - damage.value = Math.max(pokemon.getMaxHp() >> 4, 1); - applyAbAttrs(ReduceBurnDamageAbAttr, pokemon, null, false, damage); - break; + case StatusEffect.POISON: + damage.value = Math.max(pokemon.getMaxHp() >> 3, 1); + break; + case StatusEffect.TOXIC: + damage.value = Math.max(Math.floor((pokemon.getMaxHp() / 16) * pokemon.status.toxicTurnCount), 1); + break; + case StatusEffect.BURN: + damage.value = Math.max(pokemon.getMaxHp() >> 4, 1); + applyAbAttrs(ReduceBurnDamageAbAttr, pokemon, null, false, damage); + break; } if (damage.value) { // Set preventEndure flag to avoid pokemon surviving thanks to focus band, sturdy, endure ... diff --git a/src/phases/select-biome-phase.ts b/src/phases/select-biome-phase.ts index 49c6c3ac3c0..817cd7bcd3d 100644 --- a/src/phases/select-biome-phase.ts +++ b/src/phases/select-biome-phase.ts @@ -45,7 +45,7 @@ export class SelectBiomePhase extends BattlePhase { let biomeChoices: Biome[] = []; this.scene.executeWithSeedOffset(() => { biomeChoices = (!Array.isArray(biomeLinks[currentBiome]) - ? [biomeLinks[currentBiome] as Biome] + ? [ biomeLinks[currentBiome] as Biome ] : biomeLinks[currentBiome] as (Biome | [Biome, integer])[]) .filter((b, i) => !Array.isArray(b) || !Utils.randSeedInt(b[1])) .map(b => Array.isArray(b) ? b[0] : b); diff --git a/src/phases/select-modifier-phase.ts b/src/phases/select-modifier-phase.ts index ba55340bd8d..e5a60692bb4 100644 --- a/src/phases/select-modifier-phase.ts +++ b/src/phases/select-modifier-phase.ts @@ -1,7 +1,7 @@ import BattleScene from "#app/battle-scene"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { regenerateModifierPoolThresholds, ModifierTypeOption, ModifierType, getPlayerShopModifierTypeOptionsForWave, PokemonModifierType, FusePokemonModifierType, PokemonMoveModifierType, TmModifierType, RememberMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, ModifierPoolType, getPlayerModifierTypeOptions } from "#app/modifier/modifier-type"; -import { ExtraModifierModifier, HealShopCostModifier, Modifier, PokemonHeldItemModifier } from "#app/modifier/modifier"; +import { ExtraModifierModifier, HealShopCostModifier, Modifier, PokemonHeldItemModifier, TempExtraModifierModifier } from "#app/modifier/modifier"; import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "#app/ui/modifier-select-ui-handler"; import PartyUiHandler, { PartyUiMode, PartyOption } from "#app/ui/party-ui-handler"; import { Mode } from "#app/ui/ui"; @@ -16,29 +16,36 @@ export class SelectModifierPhase extends BattlePhase { private rerollCount: integer; private modifierTiers?: ModifierTier[]; private customModifierSettings?: CustomModifierSettings; + private isCopy: boolean; - constructor(scene: BattleScene, rerollCount: integer = 0, modifierTiers?: ModifierTier[], customModifierSettings?: CustomModifierSettings) { + private typeOptions: ModifierTypeOption[]; + + constructor(scene: BattleScene, rerollCount: integer = 0, modifierTiers?: ModifierTier[], customModifierSettings?: CustomModifierSettings, isCopy: boolean = false) { super(scene); this.rerollCount = rerollCount; this.modifierTiers = modifierTiers; this.customModifierSettings = customModifierSettings; + this.isCopy = isCopy; } start() { super.start(); - if (!this.rerollCount) { + if (!this.rerollCount && !this.isCopy) { this.updateSeed(); - } else { + } else if (this.rerollCount) { this.scene.reroll = false; } const party = this.scene.getParty(); - regenerateModifierPoolThresholds(party, this.getPoolType(), this.rerollCount); + if (!this.isCopy) { + regenerateModifierPoolThresholds(party, this.getPoolType(), this.rerollCount); + } const modifierCount = new Utils.IntegerHolder(3); if (this.isPlayer()) { this.scene.applyModifiers(ExtraModifierModifier, true, modifierCount); + this.scene.applyModifiers(TempExtraModifierModifier, true, modifierCount); } // If custom modifiers are specified, overrides default item count @@ -54,7 +61,7 @@ export class SelectModifierPhase extends BattlePhase { } } - const typeOptions: ModifierTypeOption[] = this.getModifierTypeOptions(modifierCount.value); + this.typeOptions = this.getModifierTypeOptions(modifierCount.value); const modifierSelectCallback = (rowCursor: integer, cursor: integer) => { if (rowCursor < 0 || cursor < 0) { @@ -63,86 +70,86 @@ export class SelectModifierPhase extends BattlePhase { this.scene.ui.revertMode(); this.scene.ui.setMode(Mode.MESSAGE); super.end(); - }, () => this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers))); + }, () => this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), this.typeOptions, modifierSelectCallback, this.getRerollCost(this.scene.lockModifierTiers))); }); return false; } let modifierType: ModifierType; let cost: integer; - const rerollCost = this.getRerollCost(typeOptions, this.scene.lockModifierTiers); + const rerollCost = this.getRerollCost(this.scene.lockModifierTiers); switch (rowCursor) { - case 0: - switch (cursor) { case 0: - if (rerollCost < 0 || this.scene.money < rerollCost) { - this.scene.ui.playError(); - return false; - } else { - this.scene.reroll = true; - this.scene.unshiftPhase(new SelectModifierPhase(this.scene, this.rerollCount + 1, typeOptions.map(o => o.type?.tier).filter(t => t !== undefined) as ModifierTier[])); - this.scene.ui.clearText(); - this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end()); - if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { - this.scene.money -= rerollCost; - this.scene.updateMoneyText(); - this.scene.animateMoneyChanged(false); - } - this.scene.playSound("se/buy"); - } - break; - case 1: - this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, itemQuantity: integer, toSlotIndex: integer) => { - if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) { - const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier + switch (cursor) { + case 0: + if (rerollCost < 0 || this.scene.money < rerollCost) { + this.scene.ui.playError(); + return false; + } else { + this.scene.reroll = true; + this.scene.unshiftPhase(new SelectModifierPhase(this.scene, this.rerollCount + 1, this.typeOptions.map(o => o.type?.tier).filter(t => t !== undefined) as ModifierTier[])); + this.scene.ui.clearText(); + this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end()); + if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { + this.scene.money -= rerollCost; + this.scene.updateMoneyText(); + this.scene.animateMoneyChanged(false); + } + this.scene.playSound("se/buy"); + } + break; + case 1: + this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, itemQuantity: integer, toSlotIndex: integer) => { + if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) { + const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.isTransferable && m.pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[]; - const itemModifier = itemModifiers[itemIndex]; - this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, itemQuantity); - } else { - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers)); - } - }, PartyUiHandler.FilterItemMaxStacks); - break; - case 2: - this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.CHECK, -1, () => { - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers)); - }); - break; - case 3: - if (rerollCost < 0) { - // Reroll lock button is also disabled when reroll is disabled - this.scene.ui.playError(); - return false; + const itemModifier = itemModifiers[itemIndex]; + this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, itemQuantity); + } else { + this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), this.typeOptions, modifierSelectCallback, this.getRerollCost(this.scene.lockModifierTiers)); + } + }, PartyUiHandler.FilterItemMaxStacks); + break; + case 2: + this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.CHECK, -1, () => { + this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), this.typeOptions, modifierSelectCallback, this.getRerollCost(this.scene.lockModifierTiers)); + }); + break; + case 3: + if (rerollCost < 0) { + // Reroll lock button is also disabled when reroll is disabled + this.scene.ui.playError(); + return false; + } + this.scene.lockModifierTiers = !this.scene.lockModifierTiers; + const uiHandler = this.scene.ui.getHandler() as ModifierSelectUiHandler; + uiHandler.setRerollCost(this.getRerollCost(this.scene.lockModifierTiers)); + uiHandler.updateLockRaritiesText(); + uiHandler.updateRerollCostText(); + return false; } - this.scene.lockModifierTiers = !this.scene.lockModifierTiers; - const uiHandler = this.scene.ui.getHandler() as ModifierSelectUiHandler; - uiHandler.setRerollCost(this.getRerollCost(typeOptions, this.scene.lockModifierTiers)); - uiHandler.updateLockRaritiesText(); - uiHandler.updateRerollCostText(); - return false; - } - return true; - case 1: - if (typeOptions.length === 0) { - this.scene.ui.clearText(); - this.scene.ui.setMode(Mode.MESSAGE); - super.end(); return true; - } - if (typeOptions[cursor].type) { - modifierType = typeOptions[cursor].type; - } - break; - default: - const shopOptions = getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1)); - const shopOption = shopOptions[rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT]; - if (shopOption.type) { - modifierType = shopOption.type; - } - // Apply Black Sludge to healing item cost - const healingItemCost = new NumberHolder(shopOption.cost); - this.scene.applyModifier(HealShopCostModifier, true, healingItemCost); - cost = healingItemCost.value; - break; + case 1: + if (this.typeOptions.length === 0) { + this.scene.ui.clearText(); + this.scene.ui.setMode(Mode.MESSAGE); + super.end(); + return true; + } + if (this.typeOptions[cursor].type) { + modifierType = this.typeOptions[cursor].type; + } + break; + default: + const shopOptions = getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1)); + const shopOption = shopOptions[rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT]; + if (shopOption.type) { + modifierType = shopOption.type; + } + // Apply Black Sludge to healing item cost + const healingItemCost = new NumberHolder(shopOption.cost); + this.scene.applyModifier(HealShopCostModifier, true, healingItemCost); + cost = healingItemCost.value; + break; } if (cost! && (this.scene.money < cost) && !Overrides.WAIVE_ROLL_FEE_OVERRIDE) { // TODO: is the bang on cost correct? @@ -151,8 +158,16 @@ export class SelectModifierPhase extends BattlePhase { } const applyModifier = (modifier: Modifier, playSound: boolean = false) => { - const result = this.scene.addModifier(modifier, false, playSound); - if (cost) { + const result = this.scene.addModifier(modifier, false, playSound, undefined, undefined, cost); + // Queue a copy of this phase when applying a TM or Memory Mushroom. + // If the player selects either of these, then escapes out of consuming them, + // they are returned to a shop in the same state. + if (modifier.type instanceof RememberMoveModifierType || + modifier.type instanceof TmModifierType) { + this.scene.unshiftPhase(this.copy()); + } + + if (cost && !(modifier.type instanceof RememberMoveModifierType)) { result.then(success => { if (success) { if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { @@ -189,7 +204,7 @@ export class SelectModifierPhase extends BattlePhase { applyModifier(modifier, true); }); } else { - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers)); + this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), this.typeOptions, modifierSelectCallback, this.getRerollCost(this.scene.lockModifierTiers)); } }, modifierType.selectFilter); } else { @@ -216,7 +231,7 @@ export class SelectModifierPhase extends BattlePhase { applyModifier(modifier!, true); // TODO: is the bang correct? }); } else { - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers)); + this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), this.typeOptions, modifierSelectCallback, this.getRerollCost(this.scene.lockModifierTiers)); } }, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined, tmMoveId, isPpRestoreModifier); } @@ -226,7 +241,7 @@ export class SelectModifierPhase extends BattlePhase { return !cost!;// TODO: is the bang correct? }; - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers)); + this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), this.typeOptions, modifierSelectCallback, this.getRerollCost(this.scene.lockModifierTiers)); } updateSeed(): void { @@ -237,13 +252,13 @@ export class SelectModifierPhase extends BattlePhase { return true; } - getRerollCost(typeOptions: ModifierTypeOption[], lockRarities: boolean): number { + getRerollCost(lockRarities: boolean): number { let baseValue = 0; if (Overrides.WAIVE_ROLL_FEE_OVERRIDE) { return baseValue; } else if (lockRarities) { - const tierValues = [50, 125, 300, 750, 2000]; - for (const opt of typeOptions) { + const tierValues = [ 50, 125, 300, 750, 2000 ]; + for (const opt of this.typeOptions) { baseValue += tierValues[opt.type.tier ?? 0]; } } else { @@ -260,7 +275,13 @@ export class SelectModifierPhase extends BattlePhase { // Otherwise, continue with custom multiplier multiplier = this.customModifierSettings.rerollMultiplier; } - return Math.min(Math.ceil(this.scene.currentBattle.waveIndex / 10) * baseValue * Math.pow(2, this.rerollCount) * multiplier, Number.MAX_SAFE_INTEGER); + + const baseMultiplier = Math.min(Math.ceil(this.scene.currentBattle.waveIndex / 10) * baseValue * (2 ** this.rerollCount) * multiplier, Number.MAX_SAFE_INTEGER); + + // Apply Black Sludge to reroll cost + const modifiedRerollCost = new NumberHolder(baseMultiplier); + this.scene.applyModifier(HealShopCostModifier, true, modifiedRerollCost); + return modifiedRerollCost.value; } getPoolType(): ModifierPoolType { @@ -271,6 +292,16 @@ export class SelectModifierPhase extends BattlePhase { return getPlayerModifierTypeOptions(modifierCount, this.scene.getParty(), this.scene.lockModifierTiers ? this.modifierTiers : undefined, this.customModifierSettings); } + copy(): SelectModifierPhase { + return new SelectModifierPhase( + this.scene, + this.rerollCount, + this.modifierTiers, + { guaranteedModifierTypeOptions: this.typeOptions, rerollMultiplier: this.customModifierSettings?.rerollMultiplier, allowLuckUpgrades: false }, + true + ); + } + addModifier(modifier: Modifier): Promise { return this.scene.addModifier(modifier, false, true); } diff --git a/src/phases/select-starter-phase.ts b/src/phases/select-starter-phase.ts index cd3c112549c..1692b5f2234 100644 --- a/src/phases/select-starter-phase.ts +++ b/src/phases/select-starter-phase.ts @@ -80,7 +80,7 @@ export class SelectStarterPhase extends Phase { starterPokemon.nickname = starter.nickname; } - if (this.scene.gameMode.isSplicedOnly) { + if (this.scene.gameMode.isSplicedOnly || Overrides.STARTER_FUSION_OVERRIDE) { starterPokemon.generateFusionSpecies(true); } starterPokemon.setVisible(false); diff --git a/src/phases/stat-stage-change-phase.ts b/src/phases/stat-stage-change-phase.ts index 4418c38c849..ce6ebea2442 100644 --- a/src/phases/stat-stage-change-phase.ts +++ b/src/phases/stat-stage-change-phase.ts @@ -36,6 +36,16 @@ export class StatStageChangePhase extends PokemonPhase { } start() { + + // Check if multiple stats are being changed at the same time, then run SSCPhase for each of them + if (this.stats.length > 1) { + for (let i = 0; i < this.stats.length; i++) { + const stat = [ this.stats[i] ]; + this.scene.unshiftPhase(new StatStageChangePhase(this.scene, this.battlerIndex, this.selfTarget, stat, this.stages, this.showMessage, this.ignoreAbilities, this.canBeCopied, this.onChange)); + } + return this.end(); + } + const pokemon = this.getPokemon(); if (!pokemon.isActive(true)) { @@ -54,8 +64,8 @@ export class StatStageChangePhase extends PokemonPhase { const cancelled = new BooleanHolder(false); if (!this.selfTarget && stages.value < 0) { - // TODO: Include simulate boolean when tag applications can be simulated - this.scene.arena.applyTagsForSide(MistTag, pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY, cancelled); + // TODO: add a reference to the source of the stat change to fix Infiltrator interaction + this.scene.arena.applyTagsForSide(MistTag, pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY, false, null, cancelled); } if (!cancelled.value && !this.selfTarget && stages.value < 0) { diff --git a/src/phases/summon-phase.ts b/src/phases/summon-phase.ts index dfa374307d5..119e550293c 100644 --- a/src/phases/summon-phase.ts +++ b/src/phases/summon-phase.ts @@ -57,7 +57,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { } // Swaps the fainted Pokemon and the first non-fainted legal Pokemon in the party - [party[this.partyMemberIndex], party[legalIndex]] = [party[legalIndex], party[this.partyMemberIndex]]; + [ party[this.partyMemberIndex], party[legalIndex] ] = [ party[legalIndex], party[this.partyMemberIndex] ]; console.warn("Swapped %s %O with %s %O", getPokemonNameWithAffix(partyMember), partyMember, getPokemonNameWithAffix(party[0]), party[0]); } @@ -240,7 +240,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { pokemon.resetTurnData(); - if (!this.loaded || [BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.scene.currentBattle.battleType) || (this.scene.currentBattle.waveIndex % 10) === 1) { + if (!this.loaded || [ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.scene.currentBattle.battleType) || (this.scene.currentBattle.waveIndex % 10) === 1) { this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true); this.queuePostSummon(); } diff --git a/src/phases/switch-biome-phase.ts b/src/phases/switch-biome-phase.ts index 9cf5635a39f..80a31794209 100644 --- a/src/phases/switch-biome-phase.ts +++ b/src/phases/switch-biome-phase.ts @@ -20,7 +20,7 @@ export class SwitchBiomePhase extends BattlePhase { } this.scene.tweens.add({ - targets: [this.scene.arenaEnemy, this.scene.lastEnemyTrainer], + targets: [ this.scene.arenaEnemy, this.scene.lastEnemyTrainer ], x: "+=300", duration: 2000, onComplete: () => { @@ -38,7 +38,7 @@ export class SwitchBiomePhase extends BattlePhase { this.scene.arenaPlayerTransition.setVisible(true); this.scene.tweens.add({ - targets: [this.scene.arenaPlayer, this.scene.arenaBgTransition, this.scene.arenaPlayerTransition], + targets: [ this.scene.arenaPlayer, this.scene.arenaBgTransition, this.scene.arenaPlayerTransition ], duration: 1000, delay: 1000, ease: "Sine.easeInOut", diff --git a/src/phases/switch-summon-phase.ts b/src/phases/switch-summon-phase.ts index 07761b10d6e..c7e7bbe011e 100644 --- a/src/phases/switch-summon-phase.ts +++ b/src/phases/switch-summon-phase.ts @@ -64,9 +64,8 @@ export class SwitchSummonPhase extends SummonPhase { } const pokemon = this.getPokemon(); - - if (this.switchType === SwitchType.SWITCH) { - (this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.removeTagsBySourceId(pokemon.id)); + (this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.removeTagsBySourceId(pokemon.id)); + if (this.switchType === SwitchType.SWITCH || this.switchType === SwitchType.INITIAL_SWITCH) { const substitute = pokemon.getTag(SubstituteTag); if (substitute) { this.scene.tweens.add({ @@ -185,6 +184,11 @@ export class SwitchSummonPhase extends SummonPhase { } } + if (this.switchType !== SwitchType.INITIAL_SWITCH) { + pokemon.resetTurnData(); + pokemon.turnData.switchedInThisTurn = true; + } + this.lastPokemon?.resetSummonData(); this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true); diff --git a/src/phases/title-phase.ts b/src/phases/title-phase.ts index b23a5ec0c89..58683cf8ec8 100644 --- a/src/phases/title-phase.ts +++ b/src/phases/title-phase.ts @@ -60,7 +60,7 @@ export class TitlePhase extends Phase { const options: OptionSelectItem[] = []; if (loggedInUser && loggedInUser.lastSessionSlot > -1) { options.push({ - label: i18next.t("continue", {ns: "menu"}), + label: i18next.t("continue", { ns: "menu" }), handler: () => { this.loadSaveSlot(this.lastSessionData || !loggedInUser ? -1 : loggedInUser.lastSessionSlot); return true; @@ -196,7 +196,7 @@ export class TitlePhase extends Phase { this.scene.gameMode = getGameMode(GameModes.DAILY); this.scene.setSeed(seed); - this.scene.resetSeed(1); + this.scene.resetSeed(0); this.scene.money = this.scene.gameMode.getStartingMoney(); @@ -221,7 +221,7 @@ export class TitlePhase extends Phase { const modifiers: Modifier[] = Array(3).fill(null).map(() => modifierTypes.EXP_SHARE().withIdFromFunc(modifierTypes.EXP_SHARE).newModifier()) .concat(Array(3).fill(null).map(() => modifierTypes.GOLDEN_EXP_CHARM().withIdFromFunc(modifierTypes.GOLDEN_EXP_CHARM).newModifier())) - .concat([modifierTypes.MAP().withIdFromFunc(modifierTypes.MAP).newModifier()]) + .concat([ modifierTypes.MAP().withIdFromFunc(modifierTypes.MAP).newModifier() ]) .concat(getDailyRunStarterModifiers(party)) .filter((m) => m !== null); diff --git a/src/phases/trainer-message-test-phase.ts b/src/phases/trainer-message-test-phase.ts index 8075dd761e2..d9e58473bd5 100644 --- a/src/phases/trainer-message-test-phase.ts +++ b/src/phases/trainer-message-test-phase.ts @@ -24,7 +24,7 @@ export class TrainerMessageTestPhase extends BattlePhase { continue; } const config = trainerConfigs[type]; - [config.encounterMessages, config.femaleEncounterMessages, config.victoryMessages, config.femaleVictoryMessages, config.defeatMessages, config.femaleDefeatMessages] + [ config.encounterMessages, config.femaleEncounterMessages, config.victoryMessages, config.femaleVictoryMessages, config.defeatMessages, config.femaleDefeatMessages ] .map(messages => { if (messages?.length) { testMessages.push(...messages); diff --git a/src/phases/trainer-victory-phase.ts b/src/phases/trainer-victory-phase.ts index e925f0c47d4..dc1b962f47e 100644 --- a/src/phases/trainer-victory-phase.ts +++ b/src/phases/trainer-victory-phase.ts @@ -27,10 +27,16 @@ export class TrainerVictoryPhase extends BattlePhase { this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, modifierRewardFunc)); } + if (this.scene.eventManager.isEventActive()) { + for (const rewardFunc of this.scene.currentBattle.trainer?.config.eventRewardFuncs!) { + this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, rewardFunc)); + } + } + const trainerType = this.scene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct? if (vouchers.hasOwnProperty(TrainerType[trainerType])) { if (!this.scene.validateVoucher(vouchers[TrainerType[trainerType]]) && this.scene.currentBattle.trainer?.config.isBoss) { - this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, [modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM][vouchers[TrainerType[trainerType]].voucherType])); + this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, [ modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM ][vouchers[TrainerType[trainerType]].voucherType])); } } diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index 95d55986185..dc3ee3f660a 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -13,10 +13,10 @@ import { BerryPhase } from "./berry-phase"; import { FieldPhase } from "./field-phase"; import { MoveHeaderPhase } from "./move-header-phase"; import { MovePhase } from "./move-phase"; -import { PostTurnStatusEffectPhase } from "./post-turn-status-effect-phase"; import { SwitchSummonPhase } from "./switch-summon-phase"; import { TurnEndPhase } from "./turn-end-phase"; import { WeatherEffectPhase } from "./weather-effect-phase"; +import { CheckStatusEffectPhase } from "#app/phases/check-status-effect-phase"; import { BattlerIndex } from "#app/battle"; import { TrickRoomTag } from "#app/data/arena-tag"; import { SwitchType } from "#enums/switch-type"; @@ -45,7 +45,7 @@ export class TurnStartPhase extends FieldPhase { // Next, a check for Trick Room is applied to determine sort order. const speedReversed = new Utils.BooleanHolder(false); - this.scene.arena.applyTags(TrickRoomTag, speedReversed); + this.scene.arena.applyTags(TrickRoomTag, false, speedReversed); // Adjust the sort function based on whether Trick Room is active. orderedTargets.sort((a: Pokemon, b: Pokemon) => { @@ -152,67 +152,64 @@ export class TurnStartPhase extends FieldPhase { } switch (turnCommand?.command) { - case Command.FIGHT: - const queuedMove = turnCommand.move; - pokemon.turnData.order = orderIndex++; - if (!queuedMove) { - continue; - } - const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move) || new PokemonMove(queuedMove.move); - if (move.getMove().hasAttr(MoveHeaderAttr)) { - this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move)); - } - if (pokemon.isPlayer()) { - if (turnCommand.cursor === -1) { - this.scene.pushPhase(new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move));//TODO: is the bang correct here? - } else { - const playerPhase = new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move, false, queuedMove.ignorePP);//TODO: is the bang correct here? - this.scene.pushPhase(playerPhase); + case Command.FIGHT: + const queuedMove = turnCommand.move; + pokemon.turnData.order = orderIndex++; + if (!queuedMove) { + continue; } - } else { - this.scene.pushPhase(new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move, false, queuedMove.ignorePP));//TODO: is the bang correct here? - } - break; - case Command.BALL: - this.scene.unshiftPhase(new AttemptCapturePhase(this.scene, turnCommand.targets![0] % 2, turnCommand.cursor!));//TODO: is the bang correct here? - break; - case Command.POKEMON: - const switchType = turnCommand.args?.[0] ? SwitchType.BATON_PASS : SwitchType.SWITCH; - this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, switchType, pokemon.getFieldIndex(), turnCommand.cursor!, true, pokemon.isPlayer())); - break; - case Command.RUN: - let runningPokemon = pokemon; - if (this.scene.currentBattle.double) { - const playerActivePokemon = field.filter(pokemon => { - if (!!pokemon) { - return pokemon.isPlayer() && pokemon.isActive(); + const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move && m?.ppUsed < m?.getMovePp()) || new PokemonMove(queuedMove.move); + if (move.getMove().hasAttr(MoveHeaderAttr)) { + this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move)); + } + if (pokemon.isPlayer()) { + if (turnCommand.cursor === -1) { + this.scene.pushPhase(new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move));//TODO: is the bang correct here? } else { - return; + const playerPhase = new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move, false, queuedMove.ignorePP);//TODO: is the bang correct here? + this.scene.pushPhase(playerPhase); } - }); - // if only one pokemon is alive, use that one - if (playerActivePokemon.length > 1) { - // find which active pokemon has faster speed - const fasterPokemon = playerActivePokemon[0].getStat(Stat.SPD) > playerActivePokemon[1].getStat(Stat.SPD) ? playerActivePokemon[0] : playerActivePokemon[1]; - // check if either active pokemon has the ability "Run Away" - const hasRunAway = playerActivePokemon.find(p => p.hasAbility(Abilities.RUN_AWAY)); - runningPokemon = hasRunAway !== undefined ? hasRunAway : fasterPokemon; + } else { + this.scene.pushPhase(new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move, false, queuedMove.ignorePP));//TODO: is the bang correct here? } - } - this.scene.unshiftPhase(new AttemptRunPhase(this.scene, runningPokemon.getFieldIndex())); - break; + break; + case Command.BALL: + this.scene.unshiftPhase(new AttemptCapturePhase(this.scene, turnCommand.targets![0] % 2, turnCommand.cursor!));//TODO: is the bang correct here? + break; + case Command.POKEMON: + const switchType = turnCommand.args?.[0] ? SwitchType.BATON_PASS : SwitchType.SWITCH; + this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, switchType, pokemon.getFieldIndex(), turnCommand.cursor!, true, pokemon.isPlayer())); + break; + case Command.RUN: + let runningPokemon = pokemon; + if (this.scene.currentBattle.double) { + const playerActivePokemon = field.filter(pokemon => { + if (!!pokemon) { + return pokemon.isPlayer() && pokemon.isActive(); + } else { + return; + } + }); + // if only one pokemon is alive, use that one + if (playerActivePokemon.length > 1) { + // find which active pokemon has faster speed + const fasterPokemon = playerActivePokemon[0].getStat(Stat.SPD) > playerActivePokemon[1].getStat(Stat.SPD) ? playerActivePokemon[0] : playerActivePokemon[1]; + // check if either active pokemon has the ability "Run Away" + const hasRunAway = playerActivePokemon.find(p => p.hasAbility(Abilities.RUN_AWAY)); + runningPokemon = hasRunAway !== undefined ? hasRunAway : fasterPokemon; + } + } + this.scene.unshiftPhase(new AttemptRunPhase(this.scene, runningPokemon.getFieldIndex())); + break; } } this.scene.pushPhase(new WeatherEffectPhase(this.scene)); - - for (const o of moveOrder) { - if (field[o].status && field[o].status.isPostTurn()) { - this.scene.pushPhase(new PostTurnStatusEffectPhase(this.scene, o)); - } - } - this.scene.pushPhase(new BerryPhase(this.scene)); + + /** Add a new phase to check who should be taking status damage */ + this.scene.pushPhase(new CheckStatusEffectPhase(this.scene, moveOrder)); + this.scene.pushPhase(new TurnEndPhase(this.scene)); /** diff --git a/src/phases/victory-phase.ts b/src/phases/victory-phase.ts index e900ff97fc6..1faa31655df 100644 --- a/src/phases/victory-phase.ts +++ b/src/phases/victory-phase.ts @@ -25,12 +25,17 @@ export class VictoryPhase extends PokemonPhase { start() { super.start(); - this.scene.gameData.gameStats.pokemonDefeated++; + const isMysteryEncounter = this.scene.currentBattle.isBattleMysteryEncounter(); + + // update Pokemon defeated count except for MEs that disable it + if (!isMysteryEncounter || !this.scene.currentBattle.mysteryEncounter?.preventGameStatsUpdates) { + this.scene.gameData.gameStats.pokemonDefeated++; + } const expValue = this.getPokemon().getExpValue(); this.scene.applyPartyExp(expValue, true); - if (this.scene.currentBattle.isBattleMysteryEncounter()) { + if (isMysteryEncounter) { handleMysteryEncounterVictory(this.scene, false, this.isExpOnly); return this.end(); } diff --git a/src/phases/weather-effect-phase.ts b/src/phases/weather-effect-phase.ts index 73de44389d0..b48ee342780 100644 --- a/src/phases/weather-effect-phase.ts +++ b/src/phases/weather-effect-phase.ts @@ -44,7 +44,7 @@ export class WeatherEffectPhase extends CommonAnimPhase { return; } - const damage = Math.ceil(pokemon.getMaxHp() / 16); + const damage = Utils.toDmgValue(pokemon.getMaxHp() / 16); this.scene.queueMessage(getWeatherDamageMessage(this.weather?.weatherType!, pokemon)!); // TODO: are those bangs correct? pokemon.damageAndUpdate(damage, HitResult.EFFECTIVE, false, false, true); diff --git a/src/plugins/cache-busted-loader-plugin.ts b/src/plugins/cache-busted-loader-plugin.ts index 3ed939c49dd..344da3eaa66 100644 --- a/src/plugins/cache-busted-loader-plugin.ts +++ b/src/plugins/cache-busted-loader-plugin.ts @@ -20,7 +20,7 @@ export default class CacheBustedLoaderPlugin extends Phaser.Loader.LoaderPlugin file.forEach(item => { if (manifest) { - const timestamp = manifest[`/${item.url.replace(/\/\//g, "/")}` ]; + const timestamp = manifest[`/${item.url.replace(/\/\//g, "/")}`]; if (timestamp) { item.url += `?t=${timestamp}`; } diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index 5f7be4768a3..91a67b9414c 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -27,9 +27,9 @@ const unicodeRanges = { }; const rangesByLanguage = { - korean: [unicodeRanges.CJKCommon, unicodeRanges.hangul].join(","), - chinese: [unicodeRanges.CJKCommon, unicodeRanges.fullwidth, unicodeRanges.CJKIdeograph].join(","), - japanese: [unicodeRanges.CJKCommon, unicodeRanges.fullwidth, unicodeRanges.kana, unicodeRanges.CJKIdeograph].join(",") + korean: [ unicodeRanges.CJKCommon, unicodeRanges.hangul ].join(","), + chinese: [ unicodeRanges.CJKCommon, unicodeRanges.fullwidth, unicodeRanges.CJKIdeograph ].join(","), + japanese: [ unicodeRanges.CJKCommon, unicodeRanges.fullwidth, unicodeRanges.kana, unicodeRanges.CJKIdeograph ].join(",") }; const fonts: Array = [ @@ -81,6 +81,8 @@ const namespaceMap = { miscDialogue: "dialogue-misc", battleSpecDialogue: "dialogue-final-boss", doubleBattleDialogue: "dialogue-double-battle", + splashMessages: "splash-texts", + mysteryEncounterMessages: "mystery-encounter-texts", }; //#region Functions @@ -100,6 +102,22 @@ async function initFonts(language: string | undefined) { } } +/** + * I18n money formatter with. (useful for BBCode coloring of text)\ + * *If you don't want the BBCode tag applied, just use 'number' formatter* + * @example Input: `{{myMoneyValue, money}}` + * Output: `@[MONEY]{₽100,000,000}` + * @param amount the money amount + * @returns a money formatted string + */ +function i18nMoneyFormatter(amount: any): string { + if (isNaN(Number(amount))) { + console.warn(`i18nMoneyFormatter: value "${amount}" is not a number!`); + } + + return `@[MONEY]{${i18next.t("common:money", { amount })}}`; +} + //#region Exports /** @@ -135,7 +153,7 @@ export async function initI18n(): Promise { i18next.use(new KoreanPostpositionProcessor()); await i18next.init({ fallbackLng: "en", - supportedLngs: ["en", "es", "fr", "it", "de", "zh-CN", "zh-TW", "pt-BR", "ko", "ja", "ca-ES"], + supportedLngs: [ "en", "es", "fr", "it", "de", "zh-CN", "zh-TW", "pt-BR", "ko", "ja", "ca-ES" ], backend: { loadPath(lng: string, [ ns ]: string[]) { let fileName: string; @@ -146,7 +164,7 @@ export async function initI18n(): Promise { } else { fileName = camelCaseToKebabCase(ns); } - return `/locales/${lng}/${fileName}.json?v=${pkg.version}`; + return `./locales/${lng}/${fileName}.json?v=${pkg.version}`; }, }, defaultNS: "menu", @@ -246,27 +264,13 @@ export async function initI18n(): Promise { interpolation: { escapeValue: false, }, - postProcess: ["korean-postposition"], + postProcess: [ "korean-postposition" ], }); - // Input: {{myMoneyValue, money}} - // Output: @[MONEY]{₽100,000,000} (useful for BBCode coloring of text) - // If you don't want the BBCode tag applied, just use 'number' formatter - i18next.services.formatter?.add("money", (value, lng, options) => { - const numberFormattedString = Intl.NumberFormat(lng, options).format(value); - switch (lng) { - case "ja": - return `@[MONEY]{${numberFormattedString}}円`; - case "de": - case "es": - case "fr": - case "it": - return `@[MONEY]{${numberFormattedString} ₽}`; - default: - // English and other languages that use same format - return `@[MONEY]{₽${numberFormattedString}}`; - } - }); + + if (i18next.services.formatter) { + i18next.services.formatter.add("money", i18nMoneyFormatter); + } await initFonts(localStorage.getItem("prLang") ?? undefined); } diff --git a/src/plugins/vite/vite-minify-json-plugin.ts b/src/plugins/vite/vite-minify-json-plugin.ts index 57130669075..a638271562f 100644 --- a/src/plugins/vite/vite-minify-json-plugin.ts +++ b/src/plugins/vite/vite-minify-json-plugin.ts @@ -41,7 +41,7 @@ export function minifyJsonPlugin(basePath: string | string[], recursive?: boolea }, async closeBundle() { console.log("Minifying JSON files..."); - const basePathes = Array.isArray(basePath) ? basePath : [basePath]; + const basePathes = Array.isArray(basePath) ? basePath : [ basePath ]; basePathes.forEach((basePath) => { const baseDir = path.resolve(buildDir, basePath); diff --git a/src/scene-base.ts b/src/scene-base.ts index 298b8096e54..9af97b8e6d4 100644 --- a/src/scene-base.ts +++ b/src/scene-base.ts @@ -81,7 +81,7 @@ export class SceneBase extends Phaser.Scene { filenames = [ filenames ]; } for (const f of filenames as string[]) { - this.load.audio(folder+key, this.getCachedUrl(`audio/${folder}${f}`)); + this.load.audio(folder + key, this.getCachedUrl(`audio/${folder}${f}`)); } } diff --git a/src/system/achv.ts b/src/system/achv.ts index a355a027093..366813328e2 100644 --- a/src/system/achv.ts +++ b/src/system/achv.ts @@ -109,7 +109,7 @@ export class DamageAchv extends Achv { damageAmount: integer; constructor(localizationKey: string, name: string, damageAmount: integer, iconImage: string, score: integer) { - super(localizationKey, name, "", iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] as Utils.NumberHolder).value >= this.damageAmount); + super(localizationKey, name, "", iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.damageAmount); this.damageAmount = damageAmount; } } @@ -118,7 +118,7 @@ export class HealAchv extends Achv { healAmount: integer; constructor(localizationKey: string, name: string, healAmount: integer, iconImage: string, score: integer) { - super(localizationKey, name, "", iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] as Utils.NumberHolder).value >= this.healAmount); + super(localizationKey, name, "", iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.healAmount); this.healAmount = healAmount; } } @@ -127,7 +127,7 @@ export class LevelAchv extends Achv { level: integer; constructor(localizationKey: string, name: string, level: integer, iconImage: string, score: integer) { - super(localizationKey, name, "", iconImage, score, (scene: BattleScene, args: any[]) => (args[0] as Utils.IntegerHolder).value >= this.level); + super(localizationKey, name, "", iconImage, score, (scene: BattleScene, args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.level); this.level = level; } } @@ -156,133 +156,133 @@ export function getAchievementDescription(localizationKey: string): string { const genderStr = PlayerGender[genderIndex].toLowerCase(); switch (localizationKey) { - case "10K_MONEY": - return i18next.t("achv:MoneyAchv.description", {context: genderStr, "moneyAmount": achvs._10K_MONEY.moneyAmount.toLocaleString("en-US")}); - case "100K_MONEY": - return i18next.t("achv:MoneyAchv.description", {context: genderStr, "moneyAmount": achvs._100K_MONEY.moneyAmount.toLocaleString("en-US")}); - case "1M_MONEY": - return i18next.t("achv:MoneyAchv.description", {context: genderStr, "moneyAmount": achvs._1M_MONEY.moneyAmount.toLocaleString("en-US")}); - case "10M_MONEY": - return i18next.t("achv:MoneyAchv.description", {context: genderStr, "moneyAmount": achvs._10M_MONEY.moneyAmount.toLocaleString("en-US")}); - case "250_DMG": - return i18next.t("achv:DamageAchv.description", {context: genderStr, "damageAmount": achvs._250_DMG.damageAmount.toLocaleString("en-US")}); - case "1000_DMG": - return i18next.t("achv:DamageAchv.description", {context: genderStr, "damageAmount": achvs._1000_DMG.damageAmount.toLocaleString("en-US")}); - case "2500_DMG": - return i18next.t("achv:DamageAchv.description", {context: genderStr, "damageAmount": achvs._2500_DMG.damageAmount.toLocaleString("en-US")}); - case "10000_DMG": - return i18next.t("achv:DamageAchv.description", {context: genderStr, "damageAmount": achvs._10000_DMG.damageAmount.toLocaleString("en-US")}); - case "250_HEAL": - return i18next.t("achv:HealAchv.description", {context: genderStr, "healAmount": achvs._250_HEAL.healAmount.toLocaleString("en-US"), "HP": i18next.t(getShortenedStatKey(Stat.HP))}); - case "1000_HEAL": - return i18next.t("achv:HealAchv.description", {context: genderStr, "healAmount": achvs._1000_HEAL.healAmount.toLocaleString("en-US"), "HP": i18next.t(getShortenedStatKey(Stat.HP))}); - case "2500_HEAL": - return i18next.t("achv:HealAchv.description", {context: genderStr, "healAmount": achvs._2500_HEAL.healAmount.toLocaleString("en-US"), "HP": i18next.t(getShortenedStatKey(Stat.HP))}); - case "10000_HEAL": - return i18next.t("achv:HealAchv.description", {context: genderStr, "healAmount": achvs._10000_HEAL.healAmount.toLocaleString("en-US"), "HP": i18next.t(getShortenedStatKey(Stat.HP))}); - case "LV_100": - return i18next.t("achv:LevelAchv.description", {context: genderStr, "level": achvs.LV_100.level}); - case "LV_250": - return i18next.t("achv:LevelAchv.description", {context: genderStr, "level": achvs.LV_250.level}); - case "LV_1000": - return i18next.t("achv:LevelAchv.description", {context: genderStr, "level": achvs.LV_1000.level}); - case "10_RIBBONS": - return i18next.t("achv:RibbonAchv.description", {context: genderStr, "ribbonAmount": achvs._10_RIBBONS.ribbonAmount.toLocaleString("en-US")}); - case "25_RIBBONS": - return i18next.t("achv:RibbonAchv.description", {context: genderStr, "ribbonAmount": achvs._25_RIBBONS.ribbonAmount.toLocaleString("en-US")}); - case "50_RIBBONS": - return i18next.t("achv:RibbonAchv.description", {context: genderStr, "ribbonAmount": achvs._50_RIBBONS.ribbonAmount.toLocaleString("en-US")}); - case "75_RIBBONS": - return i18next.t("achv:RibbonAchv.description", {context: genderStr, "ribbonAmount": achvs._75_RIBBONS.ribbonAmount.toLocaleString("en-US")}); - case "100_RIBBONS": - return i18next.t("achv:RibbonAchv.description", {context: genderStr, "ribbonAmount": achvs._100_RIBBONS.ribbonAmount.toLocaleString("en-US")}); - case "TRANSFER_MAX_STAT_STAGE": - return i18next.t("achv:TRANSFER_MAX_STAT_STAGE.description", { context: genderStr }); - case "MAX_FRIENDSHIP": - return i18next.t("achv:MAX_FRIENDSHIP.description", { context: genderStr }); - case "MEGA_EVOLVE": - return i18next.t("achv:MEGA_EVOLVE.description", { context: genderStr }); - case "GIGANTAMAX": - return i18next.t("achv:GIGANTAMAX.description", { context: genderStr }); - case "TERASTALLIZE": - return i18next.t("achv:TERASTALLIZE.description", { context: genderStr }); - case "STELLAR_TERASTALLIZE": - return i18next.t("achv:STELLAR_TERASTALLIZE.description", { context: genderStr }); - case "SPLICE": - return i18next.t("achv:SPLICE.description", { context: genderStr }); - case "MINI_BLACK_HOLE": - return i18next.t("achv:MINI_BLACK_HOLE.description", { context: genderStr }); - case "CATCH_MYTHICAL": - return i18next.t("achv:CATCH_MYTHICAL.description", { context: genderStr }); - case "CATCH_SUB_LEGENDARY": - return i18next.t("achv:CATCH_SUB_LEGENDARY.description", { context: genderStr }); - case "CATCH_LEGENDARY": - return i18next.t("achv:CATCH_LEGENDARY.description", { context: genderStr }); - case "SEE_SHINY": - return i18next.t("achv:SEE_SHINY.description", { context: genderStr }); - case "SHINY_PARTY": - return i18next.t("achv:SHINY_PARTY.description", { context: genderStr }); - case "HATCH_MYTHICAL": - return i18next.t("achv:HATCH_MYTHICAL.description", { context: genderStr }); - case "HATCH_SUB_LEGENDARY": - return i18next.t("achv:HATCH_SUB_LEGENDARY.description", { context: genderStr }); - case "HATCH_LEGENDARY": - return i18next.t("achv:HATCH_LEGENDARY.description", { context: genderStr }); - case "HATCH_SHINY": - return i18next.t("achv:HATCH_SHINY.description", { context: genderStr }); - case "HIDDEN_ABILITY": - return i18next.t("achv:HIDDEN_ABILITY.description", { context: genderStr }); - case "PERFECT_IVS": - return i18next.t("achv:PERFECT_IVS.description", { context: genderStr }); - case "CLASSIC_VICTORY": - return i18next.t("achv:CLASSIC_VICTORY.description", { context: genderStr }); - case "UNEVOLVED_CLASSIC_VICTORY": - return i18next.t("achv:UNEVOLVED_CLASSIC_VICTORY.description", { context: genderStr }); - case "MONO_GEN_ONE": - return i18next.t("achv:MONO_GEN_ONE.description", { context: genderStr }); - case "MONO_GEN_TWO": - return i18next.t("achv:MONO_GEN_TWO.description", { context: genderStr }); - case "MONO_GEN_THREE": - return i18next.t("achv:MONO_GEN_THREE.description", { context: genderStr }); - case "MONO_GEN_FOUR": - return i18next.t("achv:MONO_GEN_FOUR.description", { context: genderStr }); - case "MONO_GEN_FIVE": - return i18next.t("achv:MONO_GEN_FIVE.description", { context: genderStr }); - case "MONO_GEN_SIX": - return i18next.t("achv:MONO_GEN_SIX.description", { context: genderStr }); - case "MONO_GEN_SEVEN": - return i18next.t("achv:MONO_GEN_SEVEN.description", { context: genderStr }); - case "MONO_GEN_EIGHT": - return i18next.t("achv:MONO_GEN_EIGHT.description", { context: genderStr }); - case "MONO_GEN_NINE": - return i18next.t("achv:MONO_GEN_NINE.description", { context: genderStr }); - case "MONO_NORMAL": - case "MONO_FIGHTING": - case "MONO_FLYING": - case "MONO_POISON": - case "MONO_GROUND": - case "MONO_ROCK": - case "MONO_BUG": - case "MONO_GHOST": - case "MONO_STEEL": - case "MONO_FIRE": - case "MONO_WATER": - case "MONO_GRASS": - case "MONO_ELECTRIC": - case "MONO_PSYCHIC": - case "MONO_ICE": - case "MONO_DRAGON": - case "MONO_DARK": - case "MONO_FAIRY": - return i18next.t("achv:MonoType.description", { context: genderStr, "type": i18next.t(`pokemonInfo:Type.${localizationKey.slice(5)}`) }); - case "FRESH_START": - return i18next.t("achv:FRESH_START.description", { context: genderStr }); - case "INVERSE_BATTLE": - return i18next.t("achv:INVERSE_BATTLE.description", { context: genderStr }); - case "BREEDERS_IN_SPACE": - return i18next.t("achv:BREEDERS_IN_SPACE.description", { context: genderStr }); - default: - return ""; + case "10K_MONEY": + return i18next.t("achv:MoneyAchv.description", { context: genderStr, "moneyAmount": achvs._10K_MONEY.moneyAmount.toLocaleString("en-US") }); + case "100K_MONEY": + return i18next.t("achv:MoneyAchv.description", { context: genderStr, "moneyAmount": achvs._100K_MONEY.moneyAmount.toLocaleString("en-US") }); + case "1M_MONEY": + return i18next.t("achv:MoneyAchv.description", { context: genderStr, "moneyAmount": achvs._1M_MONEY.moneyAmount.toLocaleString("en-US") }); + case "10M_MONEY": + return i18next.t("achv:MoneyAchv.description", { context: genderStr, "moneyAmount": achvs._10M_MONEY.moneyAmount.toLocaleString("en-US") }); + case "250_DMG": + return i18next.t("achv:DamageAchv.description", { context: genderStr, "damageAmount": achvs._250_DMG.damageAmount.toLocaleString("en-US") }); + case "1000_DMG": + return i18next.t("achv:DamageAchv.description", { context: genderStr, "damageAmount": achvs._1000_DMG.damageAmount.toLocaleString("en-US") }); + case "2500_DMG": + return i18next.t("achv:DamageAchv.description", { context: genderStr, "damageAmount": achvs._2500_DMG.damageAmount.toLocaleString("en-US") }); + case "10000_DMG": + return i18next.t("achv:DamageAchv.description", { context: genderStr, "damageAmount": achvs._10000_DMG.damageAmount.toLocaleString("en-US") }); + case "250_HEAL": + return i18next.t("achv:HealAchv.description", { context: genderStr, "healAmount": achvs._250_HEAL.healAmount.toLocaleString("en-US"), "HP": i18next.t(getShortenedStatKey(Stat.HP)) }); + case "1000_HEAL": + return i18next.t("achv:HealAchv.description", { context: genderStr, "healAmount": achvs._1000_HEAL.healAmount.toLocaleString("en-US"), "HP": i18next.t(getShortenedStatKey(Stat.HP)) }); + case "2500_HEAL": + return i18next.t("achv:HealAchv.description", { context: genderStr, "healAmount": achvs._2500_HEAL.healAmount.toLocaleString("en-US"), "HP": i18next.t(getShortenedStatKey(Stat.HP)) }); + case "10000_HEAL": + return i18next.t("achv:HealAchv.description", { context: genderStr, "healAmount": achvs._10000_HEAL.healAmount.toLocaleString("en-US"), "HP": i18next.t(getShortenedStatKey(Stat.HP)) }); + case "LV_100": + return i18next.t("achv:LevelAchv.description", { context: genderStr, "level": achvs.LV_100.level }); + case "LV_250": + return i18next.t("achv:LevelAchv.description", { context: genderStr, "level": achvs.LV_250.level }); + case "LV_1000": + return i18next.t("achv:LevelAchv.description", { context: genderStr, "level": achvs.LV_1000.level }); + case "10_RIBBONS": + return i18next.t("achv:RibbonAchv.description", { context: genderStr, "ribbonAmount": achvs._10_RIBBONS.ribbonAmount.toLocaleString("en-US") }); + case "25_RIBBONS": + return i18next.t("achv:RibbonAchv.description", { context: genderStr, "ribbonAmount": achvs._25_RIBBONS.ribbonAmount.toLocaleString("en-US") }); + case "50_RIBBONS": + return i18next.t("achv:RibbonAchv.description", { context: genderStr, "ribbonAmount": achvs._50_RIBBONS.ribbonAmount.toLocaleString("en-US") }); + case "75_RIBBONS": + return i18next.t("achv:RibbonAchv.description", { context: genderStr, "ribbonAmount": achvs._75_RIBBONS.ribbonAmount.toLocaleString("en-US") }); + case "100_RIBBONS": + return i18next.t("achv:RibbonAchv.description", { context: genderStr, "ribbonAmount": achvs._100_RIBBONS.ribbonAmount.toLocaleString("en-US") }); + case "TRANSFER_MAX_STAT_STAGE": + return i18next.t("achv:TRANSFER_MAX_STAT_STAGE.description", { context: genderStr }); + case "MAX_FRIENDSHIP": + return i18next.t("achv:MAX_FRIENDSHIP.description", { context: genderStr }); + case "MEGA_EVOLVE": + return i18next.t("achv:MEGA_EVOLVE.description", { context: genderStr }); + case "GIGANTAMAX": + return i18next.t("achv:GIGANTAMAX.description", { context: genderStr }); + case "TERASTALLIZE": + return i18next.t("achv:TERASTALLIZE.description", { context: genderStr }); + case "STELLAR_TERASTALLIZE": + return i18next.t("achv:STELLAR_TERASTALLIZE.description", { context: genderStr }); + case "SPLICE": + return i18next.t("achv:SPLICE.description", { context: genderStr }); + case "MINI_BLACK_HOLE": + return i18next.t("achv:MINI_BLACK_HOLE.description", { context: genderStr }); + case "CATCH_MYTHICAL": + return i18next.t("achv:CATCH_MYTHICAL.description", { context: genderStr }); + case "CATCH_SUB_LEGENDARY": + return i18next.t("achv:CATCH_SUB_LEGENDARY.description", { context: genderStr }); + case "CATCH_LEGENDARY": + return i18next.t("achv:CATCH_LEGENDARY.description", { context: genderStr }); + case "SEE_SHINY": + return i18next.t("achv:SEE_SHINY.description", { context: genderStr }); + case "SHINY_PARTY": + return i18next.t("achv:SHINY_PARTY.description", { context: genderStr }); + case "HATCH_MYTHICAL": + return i18next.t("achv:HATCH_MYTHICAL.description", { context: genderStr }); + case "HATCH_SUB_LEGENDARY": + return i18next.t("achv:HATCH_SUB_LEGENDARY.description", { context: genderStr }); + case "HATCH_LEGENDARY": + return i18next.t("achv:HATCH_LEGENDARY.description", { context: genderStr }); + case "HATCH_SHINY": + return i18next.t("achv:HATCH_SHINY.description", { context: genderStr }); + case "HIDDEN_ABILITY": + return i18next.t("achv:HIDDEN_ABILITY.description", { context: genderStr }); + case "PERFECT_IVS": + return i18next.t("achv:PERFECT_IVS.description", { context: genderStr }); + case "CLASSIC_VICTORY": + return i18next.t("achv:CLASSIC_VICTORY.description", { context: genderStr }); + case "UNEVOLVED_CLASSIC_VICTORY": + return i18next.t("achv:UNEVOLVED_CLASSIC_VICTORY.description", { context: genderStr }); + case "MONO_GEN_ONE": + return i18next.t("achv:MONO_GEN_ONE.description", { context: genderStr }); + case "MONO_GEN_TWO": + return i18next.t("achv:MONO_GEN_TWO.description", { context: genderStr }); + case "MONO_GEN_THREE": + return i18next.t("achv:MONO_GEN_THREE.description", { context: genderStr }); + case "MONO_GEN_FOUR": + return i18next.t("achv:MONO_GEN_FOUR.description", { context: genderStr }); + case "MONO_GEN_FIVE": + return i18next.t("achv:MONO_GEN_FIVE.description", { context: genderStr }); + case "MONO_GEN_SIX": + return i18next.t("achv:MONO_GEN_SIX.description", { context: genderStr }); + case "MONO_GEN_SEVEN": + return i18next.t("achv:MONO_GEN_SEVEN.description", { context: genderStr }); + case "MONO_GEN_EIGHT": + return i18next.t("achv:MONO_GEN_EIGHT.description", { context: genderStr }); + case "MONO_GEN_NINE": + return i18next.t("achv:MONO_GEN_NINE.description", { context: genderStr }); + case "MONO_NORMAL": + case "MONO_FIGHTING": + case "MONO_FLYING": + case "MONO_POISON": + case "MONO_GROUND": + case "MONO_ROCK": + case "MONO_BUG": + case "MONO_GHOST": + case "MONO_STEEL": + case "MONO_FIRE": + case "MONO_WATER": + case "MONO_GRASS": + case "MONO_ELECTRIC": + case "MONO_PSYCHIC": + case "MONO_ICE": + case "MONO_DRAGON": + case "MONO_DARK": + case "MONO_FAIRY": + return i18next.t("achv:MonoType.description", { context: genderStr, "type": i18next.t(`pokemonInfo:Type.${localizationKey.slice(5)}`) }); + case "FRESH_START": + return i18next.t("achv:FRESH_START.description", { context: genderStr }); + case "INVERSE_BATTLE": + return i18next.t("achv:INVERSE_BATTLE.description", { context: genderStr }); + case "BREEDERS_IN_SPACE": + return i18next.t("achv:BREEDERS_IN_SPACE.description", { context: genderStr }); + default: + return ""; } } diff --git a/src/system/arena-data.ts b/src/system/arena-data.ts index 5b907805372..ba37de0ed0e 100644 --- a/src/system/arena-data.ts +++ b/src/system/arena-data.ts @@ -1,5 +1,5 @@ import { Arena } from "../field/arena"; -import { ArenaTag } from "../data/arena-tag"; +import { ArenaTag, loadArenaTag } from "../data/arena-tag"; import { Biome } from "#enums/biome"; import { Weather } from "../data/weather"; import { Terrain } from "#app/data/terrain"; @@ -15,6 +15,10 @@ export default class ArenaData { this.biome = sourceArena ? sourceArena.biomeType : source.biome; this.weather = sourceArena ? sourceArena.weather : source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : null; this.terrain = sourceArena ? sourceArena.terrain : source.terrain ? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft) : null; - this.tags = sourceArena ? sourceArena.tags : []; + this.tags = []; + + if (source.tags) { + this.tags = source.tags.map(t => loadArenaTag(t)); + } } } diff --git a/src/system/egg-data.ts b/src/system/egg-data.ts index 1c9c903688a..aa06316a61f 100644 --- a/src/system/egg-data.ts +++ b/src/system/egg-data.ts @@ -41,7 +41,7 @@ export default class EggData { if (!this.species) { return new Egg({ id: this.id, hatchWaves: this.hatchWaves, sourceType: this.sourceType, timestamp: this.timestamp, tier: Math.floor(this.id / EGG_SEED) }); } else { - return new Egg({id: this.id, tier: this.tier, sourceType: this.sourceType, hatchWaves: this.hatchWaves, + return new Egg({ id: this.id, tier: this.tier, sourceType: this.sourceType, hatchWaves: this.hatchWaves, timestamp: this.timestamp, variantTier: this.variantTier, isShiny: this.isShiny, species: this.species, eggMoveIndex: this.eggMoveIndex, overrideHiddenAbility: this.overrideHiddenAbility }); } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index b597a1b9aad..c00159a7fd7 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -31,7 +31,7 @@ import { TrainerVariant } from "#app/field/trainer"; import { Variant } from "#app/data/variant"; import { setSettingGamepad, SettingGamepad, settingGamepadDefaults } from "#app/system/settings/settings-gamepad"; import { setSettingKeyboard, SettingKeyboard } from "#app/system/settings/settings-keyboard"; -import { TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; +import { TagAddedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; import * as Modifier from "#app/modifier/modifier"; import { StatusEffect } from "#app/data/status-effect"; import ChallengeData from "#app/system/challenge-data"; @@ -43,13 +43,13 @@ import { Species } from "#enums/species"; import { applyChallenges, ChallengeType } from "#app/data/challenge"; import { WeatherType } from "#enums/weather-type"; import { TerrainType } from "#app/data/terrain"; -import { OutdatedPhase } from "#app/phases/outdated-phase"; import { ReloadSessionPhase } from "#app/phases/reload-session-phase"; import { RUN_HISTORY_LIMIT } from "#app/ui/run-history-ui-handler"; -import { applySessionDataPatches, applySettingsDataPatches, applySystemDataPatches } from "#app/system/version-converter"; +import { applySessionVersionMigration, applySystemVersionMigration, applySettingsVersionMigration } from "./version_migration/version_converter"; import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api"; +import { ArenaTrapTag } from "#app/data/arena-tag"; export const defaultStarterSpecies: Species[] = [ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, @@ -67,22 +67,22 @@ const saveKey = "x0i2O7WRiANTqPmZ"; // Temporary; secure encryption is not yet n export function getDataTypeKey(dataType: GameDataType, slotId: integer = 0): string { switch (dataType) { - case GameDataType.SYSTEM: - return "data"; - case GameDataType.SESSION: - let ret = "sessionData"; - if (slotId) { - ret += slotId; - } - return ret; - case GameDataType.SETTINGS: - return "settings"; - case GameDataType.TUTORIALS: - return "tutorials"; - case GameDataType.SEEN_DIALOGUES: - return "seenDialogues"; - case GameDataType.RUN_HISTORY: - return "runHistoryData"; + case GameDataType.SYSTEM: + return "data"; + case GameDataType.SESSION: + let ret = "sessionData"; + if (slotId) { + ret += slotId; + } + return ret; + case GameDataType.SETTINGS: + return "settings"; + case GameDataType.TUTORIALS: + return "tutorials"; + case GameDataType.SEEN_DIALOGUES: + return "seenDialogues"; + case GameDataType.RUN_HISTORY: + return "runHistoryData"; } } @@ -348,8 +348,8 @@ export class GameData { [VoucherType.GOLDEN]: 0 }; this.eggs = []; - this.eggPity = [0, 0, 0, 0]; - this.unlockPity = [0, 0, 0, 0]; + this.eggPity = [ 0, 0, 0, 0 ]; + this.unlockPity = [ 0, 0, 0, 0 ]; this.initDexData(); this.initStarterData(); } @@ -402,10 +402,7 @@ export class GameData { .then(error => { this.scene.ui.savingIcon.hide(); if (error) { - if (error.startsWith("client version out of date")) { - this.scene.clearPhaseQueue(); - this.scene.unshiftPhase(new OutdatedPhase(this.scene)); - } else if (error.startsWith("session out of date")) { + if (error.startsWith("session out of date")) { this.scene.clearPhaseQueue(); this.scene.unshiftPhase(new ReloadSessionPhase(this.scene)); } @@ -481,7 +478,7 @@ export class GameData { localStorage.setItem(lsItemKey, ""); } - applySystemDataPatches(systemData); + applySystemVersionMigration(systemData); this.trainerId = systemData.trainerId; this.secretId = systemData.secretId; @@ -560,8 +557,8 @@ export class GameData { ? systemData.eggs.map(e => e.toEgg()) : []; - this.eggPity = systemData.eggPity ? systemData.eggPity.slice(0) : [0, 0, 0, 0]; - this.unlockPity = systemData.unlockPity ? systemData.unlockPity.slice(0) : [0, 0, 0, 0]; + this.eggPity = systemData.eggPity ? systemData.eggPity.slice(0) : [ 0, 0, 0, 0 ]; + this.unlockPity = systemData.unlockPity ? systemData.unlockPity.slice(0) : [ 0, 0, 0, 0 ]; this.dexData = Object.assign(this.dexData, systemData.dexData); this.consolidateDexData(this.dexData); @@ -856,7 +853,7 @@ export class GameData { const settings = JSON.parse(localStorage.getItem("settings")!); // TODO: is this bang correct? - applySettingsDataPatches(settings); + applySettingsVersionMigration(settings); for (const setting of Object.keys(settings)) { setSetting(this.scene, setting, settings[setting]); @@ -1085,8 +1082,18 @@ export class GameData { scene.arena.terrain = sessionData.arena.terrain; scene.arena.eventTarget.dispatchEvent(new TerrainChangedEvent(TerrainType.NONE, scene.arena.terrain?.terrainType!, scene.arena.terrain?.turnsLeft!)); // TODO: is this bang correct? - // TODO - //scene.arena.tags = sessionData.arena.tags; + + scene.arena.tags = sessionData.arena.tags; + if (scene.arena.tags) { + for (const tag of scene.arena.tags) { + if (tag instanceof ArenaTrapTag) { + const { tagType, side, turnCount, layers, maxLayers } = tag as ArenaTrapTag; + scene.arena.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers)); + } else { + scene.arena.eventTarget.dispatchEvent(new TagAddedEvent(tag.tagType, tag.side, tag.turnCount)); + } + } + } for (const modifierData of sessionData.modifiers) { const modifier = modifierData.toModifier(scene, Modifier[modifierData.className]); @@ -1125,10 +1132,16 @@ export class GameData { }); } + /** + * Delete the session data at the given slot when overwriting a save file + * For deleting the session of a finished run, use {@linkcode tryClearSession} + * @param slotId the slot to clear + * @returns Promise with result `true` if the session was deleted successfully, `false` otherwise + */ deleteSession(slotId: integer): Promise { return new Promise(resolve => { if (bypassLogin) { - localStorage.removeItem(`sessionData${this.scene.sessionSlotId ? this.scene.sessionSlotId : ""}_${loggedInUser?.username}`); + localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); return resolve(true); } @@ -1139,7 +1152,7 @@ export class GameData { Utils.apiFetch(`savedata/session/delete?slot=${slotId}&clientSessionId=${clientSessionId}`, true).then(response => { if (response.ok) { loggedInUser!.lastSessionSlot = -1; // TODO: is the bang correct? - localStorage.removeItem(`sessionData${this.scene.sessionSlotId ? this.scene.sessionSlotId : ""}_${loggedInUser?.username}`); + localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); resolve(true); } return response.text(); @@ -1190,27 +1203,29 @@ export class GameData { /** - * Attempt to clear session data. After session data is removed, attempt to update user info so the menu updates + * Attempt to clear session data after the end of a run + * After session data is removed, attempt to update user info so the menu updates + * To delete an unfinished run instead, use {@linkcode deleteSession} */ async tryClearSession(scene: BattleScene, slotId: integer): Promise<[success: boolean, newClear: boolean]> { - let result: [boolean, boolean] = [false, false]; + let result: [boolean, boolean] = [ false, false ]; if (bypassLogin) { localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); - result = [true, true]; + result = [ true, true ]; } else { const sessionData = this.getSessionSaveData(scene); const response = await Utils.apiPost(`savedata/session/clear?slot=${slotId}&trainerId=${this.trainerId}&secretId=${this.secretId}&clientSessionId=${clientSessionId}`, JSON.stringify(sessionData), undefined, true); if (response.ok) { loggedInUser!.lastSessionSlot = -1; // TODO: is the bang correct? - localStorage.removeItem(`sessionData${this.scene.sessionSlotId ? this.scene.sessionSlotId : ""}_${loggedInUser?.username}`); + localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); } const jsonResponse: PokerogueApiClearSessionData = await response.json(); if (!jsonResponse.error) { - result = [true, jsonResponse.success ?? false]; + result = [ true, jsonResponse.success ?? false ]; } else { if (jsonResponse && jsonResponse.error?.startsWith("session out of date")) { this.scene.clearPhaseQueue(); @@ -1218,7 +1233,7 @@ export class GameData { } console.error(jsonResponse); - result = [false, false]; + result = [ false, false ]; } } @@ -1294,7 +1309,7 @@ export class GameData { return v; }) as SessionSaveData; - applySessionDataPatches(sessionData); + applySessionVersionMigration(sessionData); return sessionData; } @@ -1335,10 +1350,7 @@ export class GameData { this.scene.ui.savingIcon.hide(); } if (error) { - if (error.startsWith("client version out of date")) { - this.scene.clearPhaseQueue(); - this.scene.unshiftPhase(new OutdatedPhase(this.scene)); - } else if (error.startsWith("session out of date")) { + if (error.startsWith("session out of date")) { this.scene.clearPhaseQueue(); this.scene.unshiftPhase(new ReloadSessionPhase(this.scene)); } @@ -1362,12 +1374,12 @@ export class GameData { const dataKey: string = `${getDataTypeKey(dataType, slotId)}_${loggedInUser?.username}`; const handleData = (dataStr: string) => { switch (dataType) { - case GameDataType.SYSTEM: - dataStr = this.convertSystemDataStr(dataStr, true); - break; + case GameDataType.SYSTEM: + dataStr = this.convertSystemDataStr(dataStr, true); + break; } const encryptedData = AES.encrypt(dataStr, saveKey); - const blob = new Blob([ encryptedData.toString() ], {type: "text/json"}); + const blob = new Blob([ encryptedData.toString() ], { type: "text/json" }); const link = document.createElement("a"); link.href = window.URL.createObjectURL(blob); link.download = `${dataKey}.prsv`; @@ -1422,28 +1434,28 @@ export class GameData { try { dataName = GameDataType[dataType].toLowerCase(); switch (dataType) { - case GameDataType.SYSTEM: - dataStr = this.convertSystemDataStr(dataStr); - const systemData = this.parseSystemData(dataStr); - valid = !!systemData.dexData && !!systemData.timestamp; - break; - case GameDataType.SESSION: - const sessionData = this.parseSessionData(dataStr); - valid = !!sessionData.party && !!sessionData.enemyParty && !!sessionData.timestamp; - break; - case GameDataType.RUN_HISTORY: - const data = JSON.parse(dataStr); - const keys = Object.keys(data); - dataName = i18next.t("menuUiHandler:RUN_HISTORY").toLowerCase(); - keys.forEach((key) => { - const entryKeys = Object.keys(data[key]); - valid = ["isFavorite", "isVictory", "entry"].every(v => entryKeys.includes(v)) && entryKeys.length === 3; - }); - break; - case GameDataType.SETTINGS: - case GameDataType.TUTORIALS: - valid = true; - break; + case GameDataType.SYSTEM: + dataStr = this.convertSystemDataStr(dataStr); + const systemData = this.parseSystemData(dataStr); + valid = !!systemData.dexData && !!systemData.timestamp; + break; + case GameDataType.SESSION: + const sessionData = this.parseSessionData(dataStr); + valid = !!sessionData.party && !!sessionData.enemyParty && !!sessionData.timestamp; + break; + case GameDataType.RUN_HISTORY: + const data = JSON.parse(dataStr); + const keys = Object.keys(data); + dataName = i18next.t("menuUiHandler:RUN_HISTORY").toLowerCase(); + keys.forEach((key) => { + const entryKeys = Object.keys(data[key]); + valid = [ "isFavorite", "isVictory", "entry" ].every(v => entryKeys.includes(v)) && entryKeys.length === 3; + }); + break; + case GameDataType.SETTINGS: + case GameDataType.TUTORIALS: + valid = true; + break; } } catch (ex) { console.error(ex); @@ -1557,6 +1569,10 @@ export class GameData { } setPokemonSeen(pokemon: Pokemon, incrementCount: boolean = true, trainer: boolean = false): void { + // Some Mystery Encounters block updates to these stats + if (this.scene.currentBattle?.isBattleMysteryEncounter() && this.scene.currentBattle.mysteryEncounter?.preventGameStatsUpdates) { + return; + } const dexEntry = this.dexData[pokemon.species.speciesId]; dexEntry.seenAttr |= pokemon.getDexAttr(); if (incrementCount) { diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 8240b6bcf84..485c1d90c1d 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -12,7 +12,7 @@ import { loadBattlerTag } from "../data/battler-tags"; import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; export default class PokemonData { public id: integer; @@ -33,7 +33,6 @@ export default class PokemonData { public stats: integer[]; public ivs: integer[]; public nature: Nature; - public natureOverride: Nature | -1; public moveset: (PokemonMove | null)[]; public status: Status | null; public friendship: integer; @@ -54,14 +53,20 @@ export default class PokemonData { public fusionVariant: Variant; public fusionGender: Gender; public fusionLuck: integer; - public fusionMysteryEncounterPokemonData: MysteryEncounterPokemonData; public boss: boolean; public bossSegments?: integer; public summonData: PokemonSummonData; + /** Data that can customize a Pokemon in non-standard ways from its Species */ - public mysteryEncounterPokemonData: MysteryEncounterPokemonData; + public customPokemonData: CustomPokemonData; + public fusionCustomPokemonData: CustomPokemonData; + + // Deprecated attributes, needed for now to allow SessionData migration (see PR#4619 comments) + public natureOverride: Nature | -1; + public mysteryEncounterPokemonData: CustomPokemonData | null; + public fusionMysteryEncounterPokemonData: CustomPokemonData | null; constructor(source: Pokemon | any, forHistory: boolean = false) { const sourcePokemon = source instanceof Pokemon ? source : null; @@ -87,7 +92,6 @@ export default class PokemonData { this.stats = source.stats; this.ivs = source.ivs; this.nature = source.nature !== undefined ? source.nature : 0 as Nature; - this.natureOverride = source.natureOverride !== undefined ? source.natureOverride : -1; this.friendship = source.friendship !== undefined ? source.friendship : getPokemonSpecies(this.species).baseFriendship; this.metLevel = source.metLevel || 5; this.metBiome = source.metBiome !== undefined ? source.metBiome : -1; @@ -107,9 +111,15 @@ export default class PokemonData { this.fusionVariant = source.fusionVariant; this.fusionGender = source.fusionGender; this.fusionLuck = source.fusionLuck !== undefined ? source.fusionLuck : (source.fusionShiny ? source.fusionVariant + 1 : 0); + this.fusionCustomPokemonData = new CustomPokemonData(source.fusionCustomPokemonData); this.usedTMs = source.usedTMs ?? []; - this.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(source.mysteryEncounterPokemonData); + this.customPokemonData = new CustomPokemonData(source.customPokemonData); + + // Deprecated, but needed for session data migration + this.natureOverride = source.natureOverride; + this.mysteryEncounterPokemonData = source.mysteryEncounterPokemonData ? new CustomPokemonData(source.mysteryEncounterPokemonData) : null; + this.fusionMysteryEncounterPokemonData = source.fusionMysteryEncounterPokemonData ? new CustomPokemonData(source.fusionMysteryEncounterPokemonData) : null; if (!forHistory) { this.boss = (source instanceof EnemyPokemon && !!source.bossSegments) || (!this.player && !!source.boss); @@ -125,10 +135,10 @@ export default class PokemonData { } } } else { - this.moveset = (source.moveset || [ new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL) ]).filter(m => m).map((m: any) => new PokemonMove(m.moveId, m.ppUsed, m.ppUp)); + this.moveset = (source.moveset || [ new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL) ]).filter(m => m).map((m: any) => new PokemonMove(m.moveId, m.ppUsed, m.ppUp, m.virtual, m.maxPpOverride)); if (!forHistory) { this.status = source.status - ? new Status(source.status.effect, source.status.turnCount, source.status.cureTurn) + ? new Status(source.status.effect, source.status.toxicTurnCount, source.status.sleepTurnsRemaining) : null; } diff --git a/src/system/settings/settings-gamepad.ts b/src/system/settings/settings-gamepad.ts index 5dd94b780a0..322b2baac9e 100644 --- a/src/system/settings/settings-gamepad.ts +++ b/src/system/settings/settings-gamepad.ts @@ -1,9 +1,9 @@ import BattleScene from "../../battle-scene"; import SettingsGamepadUiHandler from "../../ui/settings/settings-gamepad-ui-handler"; -import {Mode} from "../../ui/ui"; -import {truncateString} from "../../utils"; -import {Button} from "#enums/buttons"; -import {SettingKeyboard} from "#app/system/settings/settings-keyboard"; +import { Mode } from "../../ui/ui"; +import { truncateString } from "../../utils"; +import { Button } from "#enums/buttons"; +import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; export enum SettingGamepad { Controller = "CONTROLLER", @@ -30,25 +30,25 @@ export enum SettingGamepad { const pressAction = "Press action to assign"; export const settingGamepadOptions = { - [SettingGamepad.Controller]: ["Default", "Change"], - [SettingGamepad.Gamepad_Support]: ["Auto", "Disabled"], - [SettingGamepad.Button_Up]: [`KEY ${Button.UP.toString()}`, pressAction], - [SettingGamepad.Button_Down]: [`KEY ${Button.DOWN.toString()}`, pressAction], - [SettingGamepad.Button_Left]: [`KEY ${Button.LEFT.toString()}`, pressAction], - [SettingGamepad.Button_Right]: [`KEY ${Button.RIGHT.toString()}`, pressAction], - [SettingGamepad.Button_Action]: [`KEY ${Button.ACTION.toString()}`, pressAction], - [SettingGamepad.Button_Cancel]: [`KEY ${Button.CANCEL.toString()}`, pressAction], - [SettingGamepad.Button_Menu]: [`KEY ${Button.MENU.toString()}`, pressAction], - [SettingGamepad.Button_Stats]: [`KEY ${Button.STATS.toString()}`, pressAction], - [SettingGamepad.Button_Cycle_Form]: [`KEY ${Button.CYCLE_FORM.toString()}`, pressAction], - [SettingGamepad.Button_Cycle_Shiny]: [`KEY ${Button.CYCLE_SHINY.toString()}`, pressAction], - [SettingGamepad.Button_Cycle_Gender]: [`KEY ${Button.CYCLE_GENDER.toString()}`, pressAction], - [SettingGamepad.Button_Cycle_Ability]: [`KEY ${Button.CYCLE_ABILITY.toString()}`, pressAction], - [SettingGamepad.Button_Cycle_Nature]: [`KEY ${Button.CYCLE_NATURE.toString()}`, pressAction], - [SettingGamepad.Button_Cycle_Variant]: [`KEY ${Button.V.toString()}`, pressAction], - [SettingGamepad.Button_Speed_Up]: [`KEY ${Button.SPEED_UP.toString()}`, pressAction], - [SettingGamepad.Button_Slow_Down]: [`KEY ${Button.SLOW_DOWN.toString()}`, pressAction], - [SettingGamepad.Button_Submit]: [`KEY ${Button.SUBMIT.toString()}`, pressAction], + [SettingGamepad.Controller]: [ "Default", "Change" ], + [SettingGamepad.Gamepad_Support]: [ "Auto", "Disabled" ], + [SettingGamepad.Button_Up]: [ `KEY ${Button.UP.toString()}`, pressAction ], + [SettingGamepad.Button_Down]: [ `KEY ${Button.DOWN.toString()}`, pressAction ], + [SettingGamepad.Button_Left]: [ `KEY ${Button.LEFT.toString()}`, pressAction ], + [SettingGamepad.Button_Right]: [ `KEY ${Button.RIGHT.toString()}`, pressAction ], + [SettingGamepad.Button_Action]: [ `KEY ${Button.ACTION.toString()}`, pressAction ], + [SettingGamepad.Button_Cancel]: [ `KEY ${Button.CANCEL.toString()}`, pressAction ], + [SettingGamepad.Button_Menu]: [ `KEY ${Button.MENU.toString()}`, pressAction ], + [SettingGamepad.Button_Stats]: [ `KEY ${Button.STATS.toString()}`, pressAction ], + [SettingGamepad.Button_Cycle_Form]: [ `KEY ${Button.CYCLE_FORM.toString()}`, pressAction ], + [SettingGamepad.Button_Cycle_Shiny]: [ `KEY ${Button.CYCLE_SHINY.toString()}`, pressAction ], + [SettingGamepad.Button_Cycle_Gender]: [ `KEY ${Button.CYCLE_GENDER.toString()}`, pressAction ], + [SettingGamepad.Button_Cycle_Ability]: [ `KEY ${Button.CYCLE_ABILITY.toString()}`, pressAction ], + [SettingGamepad.Button_Cycle_Nature]: [ `KEY ${Button.CYCLE_NATURE.toString()}`, pressAction ], + [SettingGamepad.Button_Cycle_Variant]: [ `KEY ${Button.V.toString()}`, pressAction ], + [SettingGamepad.Button_Speed_Up]: [ `KEY ${Button.SPEED_UP.toString()}`, pressAction ], + [SettingGamepad.Button_Slow_Down]: [ `KEY ${Button.SLOW_DOWN.toString()}`, pressAction ], + [SettingGamepad.Button_Submit]: [ `KEY ${Button.SUBMIT.toString()}`, pressAction ], }; export const settingGamepadDefaults = { @@ -82,66 +82,66 @@ export const settingGamepadBlackList = [ export function setSettingGamepad(scene: BattleScene, setting: SettingGamepad, value: integer): boolean { switch (setting) { - case SettingGamepad.Gamepad_Support: + case SettingGamepad.Gamepad_Support: // if we change the value of the gamepad support, we call a method in the inputController to // activate or deactivate the controller listener - scene.inputController.setGamepadSupport(settingGamepadOptions[setting][value] !== "Disabled"); - break; - case SettingGamepad.Button_Action: - case SettingGamepad.Button_Cancel: - case SettingGamepad.Button_Menu: - case SettingGamepad.Button_Stats: - case SettingGamepad.Button_Cycle_Shiny: - case SettingGamepad.Button_Cycle_Form: - case SettingGamepad.Button_Cycle_Gender: - case SettingGamepad.Button_Cycle_Ability: - case SettingGamepad.Button_Cycle_Nature: - case SettingGamepad.Button_Cycle_Variant: - case SettingGamepad.Button_Speed_Up: - case SettingGamepad.Button_Slow_Down: - case SettingGamepad.Button_Submit: - if (value) { - if (scene.ui) { - const cancelHandler = (success: boolean = false) : boolean => { - scene.ui.revertMode(); - (scene.ui.getHandler() as SettingsGamepadUiHandler).updateBindings(); - return success; - }; - scene.ui.setOverlayMode(Mode.GAMEPAD_BINDING, { - target: setting, - cancelHandler: cancelHandler, - }); + scene.inputController.setGamepadSupport(settingGamepadOptions[setting][value] !== "Disabled"); + break; + case SettingGamepad.Button_Action: + case SettingGamepad.Button_Cancel: + case SettingGamepad.Button_Menu: + case SettingGamepad.Button_Stats: + case SettingGamepad.Button_Cycle_Shiny: + case SettingGamepad.Button_Cycle_Form: + case SettingGamepad.Button_Cycle_Gender: + case SettingGamepad.Button_Cycle_Ability: + case SettingGamepad.Button_Cycle_Nature: + case SettingGamepad.Button_Cycle_Variant: + case SettingGamepad.Button_Speed_Up: + case SettingGamepad.Button_Slow_Down: + case SettingGamepad.Button_Submit: + if (value) { + if (scene.ui) { + const cancelHandler = (success: boolean = false) : boolean => { + scene.ui.revertMode(); + (scene.ui.getHandler() as SettingsGamepadUiHandler).updateBindings(); + return success; + }; + scene.ui.setOverlayMode(Mode.GAMEPAD_BINDING, { + target: setting, + cancelHandler: cancelHandler, + }); + } } - } - break; - case SettingGamepad.Controller: - if (value) { - const gp = scene.inputController.getGamepadsName(); - if (scene.ui && gp) { - const cancelHandler = () => { - scene.ui.revertMode(); - (scene.ui.getHandler() as SettingsGamepadUiHandler).setOptionCursor(Object.values(SettingGamepad).indexOf(SettingGamepad.Controller), 0, true); - (scene.ui.getHandler() as SettingsGamepadUiHandler).updateBindings(); + break; + case SettingGamepad.Controller: + if (value) { + const gp = scene.inputController.getGamepadsName(); + if (scene.ui && gp) { + const cancelHandler = () => { + scene.ui.revertMode(); + (scene.ui.getHandler() as SettingsGamepadUiHandler).setOptionCursor(Object.values(SettingGamepad).indexOf(SettingGamepad.Controller), 0, true); + (scene.ui.getHandler() as SettingsGamepadUiHandler).updateBindings(); + return false; + }; + const changeGamepadHandler = (gamepad: string) => { + scene.inputController.setChosenGamepad(gamepad); + cancelHandler(); + return true; + }; + scene.ui.setOverlayMode(Mode.OPTION_SELECT, { + options: [ ...gp.map((g: string) => ({ + label: truncateString(g, 30), // Truncate the gamepad name for display + handler: () => changeGamepadHandler(g) + })), { + label: "Cancel", + handler: cancelHandler, + }] + }); return false; - }; - const changeGamepadHandler = (gamepad: string) => { - scene.inputController.setChosenGamepad(gamepad); - cancelHandler(); - return true; - }; - scene.ui.setOverlayMode(Mode.OPTION_SELECT, { - options: [...gp.map((g: string) => ({ - label: truncateString(g, 30), // Truncate the gamepad name for display - handler: () => changeGamepadHandler(g) - })), { - label: "Cancel", - handler: cancelHandler, - }] - }); - return false; + } } - } - break; + break; } return true; diff --git a/src/system/settings/settings-keyboard.ts b/src/system/settings/settings-keyboard.ts index d60af06e12b..97990f61c86 100644 --- a/src/system/settings/settings-keyboard.ts +++ b/src/system/settings/settings-keyboard.ts @@ -1,6 +1,6 @@ -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import BattleScene from "#app/battle-scene"; -import {Mode} from "#app/ui/ui"; +import { Mode } from "#app/ui/ui"; import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler"; import i18next from "i18next"; @@ -46,40 +46,40 @@ const pressAction = i18next.t("settings:pressToBind"); export const settingKeyboardOptions = { // [SettingKeyboard.Default_Layout]: ['Default'], - [SettingKeyboard.Button_Up]: [`KEY ${Button.UP.toString()}`, pressAction], - [SettingKeyboard.Button_Down]: [`KEY ${Button.DOWN.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Up]: [`KEY ${Button.UP.toString()}`, pressAction], - [SettingKeyboard.Button_Left]: [`KEY ${Button.LEFT.toString()}`, pressAction], - [SettingKeyboard.Button_Right]: [`KEY ${Button.RIGHT.toString()}`, pressAction], - [SettingKeyboard.Button_Action]: [`KEY ${Button.ACTION.toString()}`, pressAction], - [SettingKeyboard.Button_Menu]: [`KEY ${Button.MENU.toString()}`, pressAction], - [SettingKeyboard.Button_Submit]: [`KEY ${Button.SUBMIT.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Down]: [`KEY ${Button.DOWN.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Left]: [`KEY ${Button.LEFT.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Right]: [`KEY ${Button.RIGHT.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Action]: [`KEY ${Button.ACTION.toString()}`, pressAction], - [SettingKeyboard.Button_Cancel]: [`KEY ${Button.CANCEL.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Cancel]: [`KEY ${Button.CANCEL.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Menu]: [`KEY ${Button.MENU.toString()}`, pressAction], - [SettingKeyboard.Button_Stats]: [`KEY ${Button.STATS.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Stats]: [`KEY ${Button.STATS.toString()}`, pressAction], - [SettingKeyboard.Button_Cycle_Form]: [`KEY ${Button.CYCLE_FORM.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Cycle_Form]: [`KEY ${Button.CYCLE_FORM.toString()}`, pressAction], - [SettingKeyboard.Button_Cycle_Shiny]: [`KEY ${Button.CYCLE_SHINY.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Cycle_Shiny]: [`KEY ${Button.CYCLE_SHINY.toString()}`, pressAction], - [SettingKeyboard.Button_Cycle_Gender]: [`KEY ${Button.CYCLE_GENDER.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Cycle_Gender]: [`KEY ${Button.CYCLE_GENDER.toString()}`, pressAction], - [SettingKeyboard.Button_Cycle_Ability]: [`KEY ${Button.CYCLE_ABILITY.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Cycle_Ability]: [`KEY ${Button.CYCLE_ABILITY.toString()}`, pressAction], - [SettingKeyboard.Button_Cycle_Nature]: [`KEY ${Button.CYCLE_NATURE.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Cycle_Nature]: [`KEY ${Button.CYCLE_NATURE.toString()}`, pressAction], - [SettingKeyboard.Button_Cycle_Variant]: [`KEY ${Button.V.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Cycle_Variant]: [`KEY ${Button.V.toString()}`, pressAction], - [SettingKeyboard.Button_Speed_Up]: [`KEY ${Button.SPEED_UP.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Speed_Up]: [`KEY ${Button.SPEED_UP.toString()}`, pressAction], - [SettingKeyboard.Button_Slow_Down]: [`KEY ${Button.SLOW_DOWN.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Slow_Down]: [`KEY ${Button.SLOW_DOWN.toString()}`, pressAction], - [SettingKeyboard.Alt_Button_Submit]: [`KEY ${Button.SUBMIT.toString()}`, pressAction], + [SettingKeyboard.Button_Up]: [ `KEY ${Button.UP.toString()}`, pressAction ], + [SettingKeyboard.Button_Down]: [ `KEY ${Button.DOWN.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Up]: [ `KEY ${Button.UP.toString()}`, pressAction ], + [SettingKeyboard.Button_Left]: [ `KEY ${Button.LEFT.toString()}`, pressAction ], + [SettingKeyboard.Button_Right]: [ `KEY ${Button.RIGHT.toString()}`, pressAction ], + [SettingKeyboard.Button_Action]: [ `KEY ${Button.ACTION.toString()}`, pressAction ], + [SettingKeyboard.Button_Menu]: [ `KEY ${Button.MENU.toString()}`, pressAction ], + [SettingKeyboard.Button_Submit]: [ `KEY ${Button.SUBMIT.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Down]: [ `KEY ${Button.DOWN.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Left]: [ `KEY ${Button.LEFT.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Right]: [ `KEY ${Button.RIGHT.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Action]: [ `KEY ${Button.ACTION.toString()}`, pressAction ], + [SettingKeyboard.Button_Cancel]: [ `KEY ${Button.CANCEL.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Cancel]: [ `KEY ${Button.CANCEL.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Menu]: [ `KEY ${Button.MENU.toString()}`, pressAction ], + [SettingKeyboard.Button_Stats]: [ `KEY ${Button.STATS.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Stats]: [ `KEY ${Button.STATS.toString()}`, pressAction ], + [SettingKeyboard.Button_Cycle_Form]: [ `KEY ${Button.CYCLE_FORM.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Cycle_Form]: [ `KEY ${Button.CYCLE_FORM.toString()}`, pressAction ], + [SettingKeyboard.Button_Cycle_Shiny]: [ `KEY ${Button.CYCLE_SHINY.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Cycle_Shiny]: [ `KEY ${Button.CYCLE_SHINY.toString()}`, pressAction ], + [SettingKeyboard.Button_Cycle_Gender]: [ `KEY ${Button.CYCLE_GENDER.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Cycle_Gender]: [ `KEY ${Button.CYCLE_GENDER.toString()}`, pressAction ], + [SettingKeyboard.Button_Cycle_Ability]: [ `KEY ${Button.CYCLE_ABILITY.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Cycle_Ability]: [ `KEY ${Button.CYCLE_ABILITY.toString()}`, pressAction ], + [SettingKeyboard.Button_Cycle_Nature]: [ `KEY ${Button.CYCLE_NATURE.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Cycle_Nature]: [ `KEY ${Button.CYCLE_NATURE.toString()}`, pressAction ], + [SettingKeyboard.Button_Cycle_Variant]: [ `KEY ${Button.V.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Cycle_Variant]: [ `KEY ${Button.V.toString()}`, pressAction ], + [SettingKeyboard.Button_Speed_Up]: [ `KEY ${Button.SPEED_UP.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Speed_Up]: [ `KEY ${Button.SPEED_UP.toString()}`, pressAction ], + [SettingKeyboard.Button_Slow_Down]: [ `KEY ${Button.SLOW_DOWN.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Slow_Down]: [ `KEY ${Button.SLOW_DOWN.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Submit]: [ `KEY ${Button.SUBMIT.toString()}`, pressAction ], }; export const settingKeyboardDefaults = { @@ -135,53 +135,53 @@ export const settingKeyboardBlackList = [ export function setSettingKeyboard(scene: BattleScene, setting: SettingKeyboard, value: integer): boolean { switch (setting) { - case SettingKeyboard.Button_Up: - case SettingKeyboard.Button_Down: - case SettingKeyboard.Button_Left: - case SettingKeyboard.Button_Right: - case SettingKeyboard.Button_Action: - case SettingKeyboard.Button_Cancel: - case SettingKeyboard.Button_Menu: - case SettingKeyboard.Button_Stats: - case SettingKeyboard.Button_Cycle_Shiny: - case SettingKeyboard.Button_Cycle_Form: - case SettingKeyboard.Button_Cycle_Gender: - case SettingKeyboard.Button_Cycle_Ability: - case SettingKeyboard.Button_Cycle_Nature: - case SettingKeyboard.Button_Cycle_Variant: - case SettingKeyboard.Button_Speed_Up: - case SettingKeyboard.Button_Slow_Down: - case SettingKeyboard.Alt_Button_Up: - case SettingKeyboard.Alt_Button_Down: - case SettingKeyboard.Alt_Button_Left: - case SettingKeyboard.Alt_Button_Right: - case SettingKeyboard.Alt_Button_Action: - case SettingKeyboard.Alt_Button_Cancel: - case SettingKeyboard.Alt_Button_Menu: - case SettingKeyboard.Alt_Button_Stats: - case SettingKeyboard.Alt_Button_Cycle_Shiny: - case SettingKeyboard.Alt_Button_Cycle_Form: - case SettingKeyboard.Alt_Button_Cycle_Gender: - case SettingKeyboard.Alt_Button_Cycle_Ability: - case SettingKeyboard.Alt_Button_Cycle_Nature: - case SettingKeyboard.Alt_Button_Cycle_Variant: - case SettingKeyboard.Alt_Button_Speed_Up: - case SettingKeyboard.Alt_Button_Slow_Down: - case SettingKeyboard.Alt_Button_Submit: - if (value) { - if (scene.ui) { - const cancelHandler = (success: boolean = false) : boolean => { - scene.ui.revertMode(); - (scene.ui.getHandler() as SettingsKeyboardUiHandler).updateBindings(); - return success; - }; - scene.ui.setOverlayMode(Mode.KEYBOARD_BINDING, { - target: setting, - cancelHandler: cancelHandler, - }); + case SettingKeyboard.Button_Up: + case SettingKeyboard.Button_Down: + case SettingKeyboard.Button_Left: + case SettingKeyboard.Button_Right: + case SettingKeyboard.Button_Action: + case SettingKeyboard.Button_Cancel: + case SettingKeyboard.Button_Menu: + case SettingKeyboard.Button_Stats: + case SettingKeyboard.Button_Cycle_Shiny: + case SettingKeyboard.Button_Cycle_Form: + case SettingKeyboard.Button_Cycle_Gender: + case SettingKeyboard.Button_Cycle_Ability: + case SettingKeyboard.Button_Cycle_Nature: + case SettingKeyboard.Button_Cycle_Variant: + case SettingKeyboard.Button_Speed_Up: + case SettingKeyboard.Button_Slow_Down: + case SettingKeyboard.Alt_Button_Up: + case SettingKeyboard.Alt_Button_Down: + case SettingKeyboard.Alt_Button_Left: + case SettingKeyboard.Alt_Button_Right: + case SettingKeyboard.Alt_Button_Action: + case SettingKeyboard.Alt_Button_Cancel: + case SettingKeyboard.Alt_Button_Menu: + case SettingKeyboard.Alt_Button_Stats: + case SettingKeyboard.Alt_Button_Cycle_Shiny: + case SettingKeyboard.Alt_Button_Cycle_Form: + case SettingKeyboard.Alt_Button_Cycle_Gender: + case SettingKeyboard.Alt_Button_Cycle_Ability: + case SettingKeyboard.Alt_Button_Cycle_Nature: + case SettingKeyboard.Alt_Button_Cycle_Variant: + case SettingKeyboard.Alt_Button_Speed_Up: + case SettingKeyboard.Alt_Button_Slow_Down: + case SettingKeyboard.Alt_Button_Submit: + if (value) { + if (scene.ui) { + const cancelHandler = (success: boolean = false) : boolean => { + scene.ui.revertMode(); + (scene.ui.getHandler() as SettingsKeyboardUiHandler).updateBindings(); + return success; + }; + scene.ui.setOverlayMode(Mode.KEYBOARD_BINDING, { + target: setting, + cancelHandler: cancelHandler, + }); + } } - } - break; + break; // case SettingKeyboard.Default_Layout: // if (value && scene.ui) { // const cancelHandler = () => { diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 66021845c29..be440d5d93e 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -76,16 +76,16 @@ const SHOP_CURSOR_TARGET_OPTIONS: SettingOption[] = [ const shopCursorTargetIndexMap = SHOP_CURSOR_TARGET_OPTIONS.map(option => { switch (option.value) { - case "Rewards": - return ShopCursorTarget.REWARDS; - case "Shop": - return ShopCursorTarget.SHOP; - case "Reroll": - return ShopCursorTarget.REROLL; - case "Check Team": - return ShopCursorTarget.CHECK_TEAM; - default: - throw new Error(`Unknown value: ${option.value}`); + case "Rewards": + return ShopCursorTarget.REWARDS; + case "Shop": + return ShopCursorTarget.SHOP; + case "Reroll": + return ShopCursorTarget.REROLL; + case "Check Team": + return ShopCursorTarget.CHECK_TEAM; + default: + throw new Error(`Unknown value: ${option.value}`); } }); @@ -699,226 +699,226 @@ export function setSetting(scene: BattleScene, setting: string, value: integer): return false; } switch (Setting[index].key) { - case SettingKeys.Game_Speed: - scene.gameSpeed = parseFloat(Setting[index].options[value].value.replace("x", "")); - break; - case SettingKeys.Master_Volume: - scene.masterVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; - scene.updateSoundVolume(); - break; - case SettingKeys.BGM_Volume: - scene.bgmVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; - scene.updateSoundVolume(); - break; - case SettingKeys.Field_Volume: - scene.fieldVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; - scene.updateSoundVolume(); - break; - case SettingKeys.SE_Volume: - scene.seVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; - scene.updateSoundVolume(); - break; - case SettingKeys.UI_Volume: - scene.uiVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; - break; - case SettingKeys.Music_Preference: - scene.musicPreference = value; - break; - case SettingKeys.Damage_Numbers: - scene.damageNumbersMode = value; - break; - case SettingKeys.UI_Theme: - scene.uiTheme = value; - break; - case SettingKeys.Window_Type: - updateWindowType(scene, parseInt(Setting[index].options[value].value)); - break; - case SettingKeys.Tutorials: - scene.enableTutorials = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Move_Info: - scene.enableMoveInfo = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Enable_Retries: - scene.enableRetries = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Hide_IVs: - scene.hideIvs = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Skip_Seen_Dialogues: - scene.skipSeenDialogues = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Egg_Skip: - scene.eggSkipPreference = value; - break; - case SettingKeys.Battle_Style: - scene.battleStyle = value; - break; - case SettingKeys.Show_BGM_Bar: - scene.showBgmBar = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Candy_Upgrade_Notification: - if (scene.candyUpgradeNotification === value) { + case SettingKeys.Game_Speed: + scene.gameSpeed = parseFloat(Setting[index].options[value].value.replace("x", "")); break; - } - scene.candyUpgradeNotification = value; - scene.eventTarget.dispatchEvent(new CandyUpgradeNotificationChangedEvent(value)); - break; - case SettingKeys.Candy_Upgrade_Display: - scene.candyUpgradeDisplay = value; - case SettingKeys.Money_Format: - switch (Setting[index].options[value].value) { - case "Normal": - scene.moneyFormat = MoneyFormat.NORMAL; + case SettingKeys.Master_Volume: + scene.masterVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; + scene.updateSoundVolume(); break; - case "Abbreviated": - scene.moneyFormat = MoneyFormat.ABBREVIATED; + case SettingKeys.BGM_Volume: + scene.bgmVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; + scene.updateSoundVolume(); break; - } - scene.updateMoneyText(false); - break; - case SettingKeys.Sprite_Set: - scene.experimentalSprites = !!value; - if (value) { - scene.initExpSprites(); - } - break; - case SettingKeys.Move_Animations: - scene.moveAnimations = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Show_Moveset_Flyout: - scene.showMovesetFlyout = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Show_Arena_Flyout: - scene.showArenaFlyout = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Show_Time_Of_Day_Widget: - scene.showTimeOfDayWidget = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Time_Of_Day_Animation: - scene.timeOfDayAnimation = Setting[index].options[value].value === "Bounce" ? EaseType.BOUNCE : EaseType.BACK; - break; - case SettingKeys.Show_Stats_on_Level_Up: - scene.showLevelUpStats = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Shop_Cursor_Target: - const selectedValue = shopCursorTargetIndexMap[value]; - scene.shopCursorTarget = selectedValue; - break; - case SettingKeys.EXP_Gains_Speed: - scene.expGainsSpeed = value; - break; - case SettingKeys.EXP_Party_Display: - scene.expParty = value; - break; - case SettingKeys.HP_Bar_Speed: - scene.hpBarSpeed = value; - break; - case SettingKeys.Fusion_Palette_Swaps: - scene.fusionPaletteSwaps = !!value; - break; - case SettingKeys.Player_Gender: - if (scene.gameData) { - const female = Setting[index].options[value].value === "Girl"; - scene.gameData.gender = female ? PlayerGender.FEMALE : PlayerGender.MALE; - scene.trainer.setTexture(scene.trainer.texture.key.replace(female ? "m" : "f", female ? "f" : "m")); - } else { - return false; - } - break; - case SettingKeys.Touch_Controls: - scene.enableTouchControls = Setting[index].options[value].value !== "Disabled" && hasTouchscreen(); - const touchControls = document.getElementById("touchControls"); - if (touchControls) { - touchControls.classList.toggle("visible", scene.enableTouchControls); - } - break; - case SettingKeys.Vibration: - scene.enableVibration = Setting[index].options[value].value !== "Disabled" && hasTouchscreen(); - break; - case SettingKeys.Type_Hints: - scene.typeHints = Setting[index].options[value].value === "On"; - break; - case SettingKeys.Language: - if (value) { - if (scene.ui) { - const cancelHandler = () => { - scene.ui.revertMode(); - (scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(0, 0, true); - }; - const changeLocaleHandler = (locale: string): boolean => { - try { - i18next.changeLanguage(locale); - localStorage.setItem("prLang", locale); - cancelHandler(); - // Reload the whole game to apply the new locale since also some constants are translated - window.location.reload(); - return true; - } catch (error) { - console.error("Error changing locale:", error); - return false; - } - }; - scene.ui.setOverlayMode(Mode.OPTION_SELECT, { - options: [ - { - label: "English", - handler: () => changeLocaleHandler("en") - }, - { - label: "Español", - handler: () => changeLocaleHandler("es") - }, - { - label: "Italiano", - handler: () => changeLocaleHandler("it") - }, - { - label: "Français", - handler: () => changeLocaleHandler("fr") - }, - { - label: "Deutsch", - handler: () => changeLocaleHandler("de") - }, - { - label: "Português (BR)", - handler: () => changeLocaleHandler("pt-BR") - }, - { - label: "简体中文", - handler: () => changeLocaleHandler("zh-CN") - }, - { - label: "繁體中文", - handler: () => changeLocaleHandler("zh-TW") - }, - { - label: "한국어", - handler: () => changeLocaleHandler("ko") - }, - { - label: "日本語", - handler: () => changeLocaleHandler("ja") - }, - // { - // label: "Català", - // handler: () => changeLocaleHandler("ca-ES") - // }, - { - label: i18next.t("settings:back"), - handler: () => cancelHandler() - } - ], - maxOptions: 7 - }); + case SettingKeys.Field_Volume: + scene.fieldVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; + scene.updateSoundVolume(); + break; + case SettingKeys.SE_Volume: + scene.seVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; + scene.updateSoundVolume(); + break; + case SettingKeys.UI_Volume: + scene.uiVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0; + break; + case SettingKeys.Music_Preference: + scene.musicPreference = value; + break; + case SettingKeys.Damage_Numbers: + scene.damageNumbersMode = value; + break; + case SettingKeys.UI_Theme: + scene.uiTheme = value; + break; + case SettingKeys.Window_Type: + updateWindowType(scene, parseInt(Setting[index].options[value].value)); + break; + case SettingKeys.Tutorials: + scene.enableTutorials = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Move_Info: + scene.enableMoveInfo = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Enable_Retries: + scene.enableRetries = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Hide_IVs: + scene.hideIvs = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Skip_Seen_Dialogues: + scene.skipSeenDialogues = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Egg_Skip: + scene.eggSkipPreference = value; + break; + case SettingKeys.Battle_Style: + scene.battleStyle = value; + break; + case SettingKeys.Show_BGM_Bar: + scene.showBgmBar = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Candy_Upgrade_Notification: + if (scene.candyUpgradeNotification === value) { + break; + } + scene.candyUpgradeNotification = value; + scene.eventTarget.dispatchEvent(new CandyUpgradeNotificationChangedEvent(value)); + break; + case SettingKeys.Candy_Upgrade_Display: + scene.candyUpgradeDisplay = value; + case SettingKeys.Money_Format: + switch (Setting[index].options[value].value) { + case "Normal": + scene.moneyFormat = MoneyFormat.NORMAL; + break; + case "Abbreviated": + scene.moneyFormat = MoneyFormat.ABBREVIATED; + break; + } + scene.updateMoneyText(false); + break; + case SettingKeys.Sprite_Set: + scene.experimentalSprites = !!value; + if (value) { + scene.initExpSprites(); + } + break; + case SettingKeys.Move_Animations: + scene.moveAnimations = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Show_Moveset_Flyout: + scene.showMovesetFlyout = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Show_Arena_Flyout: + scene.showArenaFlyout = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Show_Time_Of_Day_Widget: + scene.showTimeOfDayWidget = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Time_Of_Day_Animation: + scene.timeOfDayAnimation = Setting[index].options[value].value === "Bounce" ? EaseType.BOUNCE : EaseType.BACK; + break; + case SettingKeys.Show_Stats_on_Level_Up: + scene.showLevelUpStats = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Shop_Cursor_Target: + const selectedValue = shopCursorTargetIndexMap[value]; + scene.shopCursorTarget = selectedValue; + break; + case SettingKeys.EXP_Gains_Speed: + scene.expGainsSpeed = value; + break; + case SettingKeys.EXP_Party_Display: + scene.expParty = value; + break; + case SettingKeys.HP_Bar_Speed: + scene.hpBarSpeed = value; + break; + case SettingKeys.Fusion_Palette_Swaps: + scene.fusionPaletteSwaps = !!value; + break; + case SettingKeys.Player_Gender: + if (scene.gameData) { + const female = Setting[index].options[value].value === "Girl"; + scene.gameData.gender = female ? PlayerGender.FEMALE : PlayerGender.MALE; + scene.trainer.setTexture(scene.trainer.texture.key.replace(female ? "m" : "f", female ? "f" : "m")); + } else { return false; } - } - break; - case SettingKeys.Shop_Overlay_Opacity: - scene.updateShopOverlayOpacity(parseInt(Setting[index].options[value].value) * .01); - break; + break; + case SettingKeys.Touch_Controls: + scene.enableTouchControls = Setting[index].options[value].value !== "Disabled" && hasTouchscreen(); + const touchControls = document.getElementById("touchControls"); + if (touchControls) { + touchControls.classList.toggle("visible", scene.enableTouchControls); + } + break; + case SettingKeys.Vibration: + scene.enableVibration = Setting[index].options[value].value !== "Disabled" && hasTouchscreen(); + break; + case SettingKeys.Type_Hints: + scene.typeHints = Setting[index].options[value].value === "On"; + break; + case SettingKeys.Language: + if (value) { + if (scene.ui) { + const cancelHandler = () => { + scene.ui.revertMode(); + (scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(0, 0, true); + }; + const changeLocaleHandler = (locale: string): boolean => { + try { + i18next.changeLanguage(locale); + localStorage.setItem("prLang", locale); + cancelHandler(); + // Reload the whole game to apply the new locale since also some constants are translated + window.location.reload(); + return true; + } catch (error) { + console.error("Error changing locale:", error); + return false; + } + }; + scene.ui.setOverlayMode(Mode.OPTION_SELECT, { + options: [ + { + label: "English", + handler: () => changeLocaleHandler("en") + }, + { + label: "Español", + handler: () => changeLocaleHandler("es") + }, + { + label: "Italiano", + handler: () => changeLocaleHandler("it") + }, + { + label: "Français", + handler: () => changeLocaleHandler("fr") + }, + { + label: "Deutsch", + handler: () => changeLocaleHandler("de") + }, + { + label: "Português (BR)", + handler: () => changeLocaleHandler("pt-BR") + }, + { + label: "简体中文", + handler: () => changeLocaleHandler("zh-CN") + }, + { + label: "繁體中文", + handler: () => changeLocaleHandler("zh-TW") + }, + { + label: "한국어", + handler: () => changeLocaleHandler("ko") + }, + { + label: "日本語", + handler: () => changeLocaleHandler("ja") + }, + // { + // label: "Català", + // handler: () => changeLocaleHandler("ca-ES") + // }, + { + label: i18next.t("settings:back"), + handler: () => cancelHandler() + } + ], + maxOptions: 7 + }); + return false; + } + } + break; + case SettingKeys.Shop_Overlay_Opacity: + scene.updateShopOverlayOpacity(parseInt(Setting[index].options[value].value) * .01); + break; } return true; diff --git a/src/system/unlockables.ts b/src/system/unlockables.ts index 983909373fd..0a666e2c755 100644 --- a/src/system/unlockables.ts +++ b/src/system/unlockables.ts @@ -10,13 +10,13 @@ export enum Unlockables { export function getUnlockableName(unlockable: Unlockables) { switch (unlockable) { - case Unlockables.ENDLESS_MODE: - return `${GameMode.getModeName(GameModes.ENDLESS)} Mode`; - case Unlockables.MINI_BLACK_HOLE: - return i18next.t("modifierType:ModifierType.MINI_BLACK_HOLE.name"); - case Unlockables.SPLICED_ENDLESS_MODE: - return `${GameMode.getModeName(GameModes.SPLICED_ENDLESS)} Mode`; - case Unlockables.EVIOLITE: - return i18next.t("modifierType:ModifierType.EVIOLITE.name"); + case Unlockables.ENDLESS_MODE: + return `${GameMode.getModeName(GameModes.ENDLESS)} Mode`; + case Unlockables.MINI_BLACK_HOLE: + return i18next.t("modifierType:ModifierType.MINI_BLACK_HOLE.name"); + case Unlockables.SPLICED_ENDLESS_MODE: + return `${GameMode.getModeName(GameModes.SPLICED_ENDLESS)} Mode`; + case Unlockables.EVIOLITE: + return i18next.t("modifierType:ModifierType.EVIOLITE.name"); } } diff --git a/src/system/version-converter.ts b/src/system/version-converter.ts deleted file mode 100644 index 3a4416a975e..00000000000 --- a/src/system/version-converter.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { allSpecies } from "#app/data/pokemon-species"; -import { AbilityAttr, defaultStarterSpecies, DexAttr, SessionSaveData, SystemSaveData } from "./game-data"; -import { SettingKeys } from "./settings/settings"; - -const LATEST_VERSION = "1.0.5"; - -export function applySessionDataPatches(data: SessionSaveData) { - const curVersion = data.gameVersion; - - // Always sanitize money as a safeguard - data.money = Math.floor(data.money); - - if (curVersion !== LATEST_VERSION) { - switch (curVersion) { - case "1.0.0": - case "1.0.1": - case "1.0.2": - case "1.0.3": - case "1.0.4": - // --- PATCHES --- - - // Fix Battle Items, Vitamins, and Lures - data.modifiers.forEach((m) => { - if (m.className === "PokemonBaseStatModifier") { - m.className = "BaseStatModifier"; - } else if (m.className === "PokemonResetNegativeStatStageModifier") { - m.className = "ResetNegativeStatStageModifier"; - } else if (m.className === "TempBattleStatBoosterModifier") { - // Dire Hit no longer a part of the TempBattleStatBoosterModifierTypeGenerator - if (m.typeId !== "DIRE_HIT") { - m.className = "TempStatStageBoosterModifier"; - m.typeId = "TEMP_STAT_STAGE_BOOSTER"; - - // Migration from TempBattleStat to Stat - const newStat = m.typePregenArgs[0] + 1; - m.typePregenArgs[0] = newStat; - - // From [ stat, battlesLeft ] to [ stat, maxBattles, battleCount ] - m.args = [ newStat, 5, m.args[1] ]; - } else { - m.className = "TempCritBoosterModifier"; - m.typePregenArgs = []; - - // From [ stat, battlesLeft ] to [ maxBattles, battleCount ] - m.args = [ 5, m.args[1] ]; - } - - } else if (m.className === "DoubleBattleChanceBoosterModifier" && m.args.length === 1) { - let maxBattles: number; - switch (m.typeId) { - case "MAX_LURE": - maxBattles = 30; - break; - case "SUPER_LURE": - maxBattles = 15; - break; - default: - maxBattles = 10; - break; - } - - // From [ battlesLeft ] to [ maxBattles, battleCount ] - m.args = [ maxBattles, m.args[0] ]; - } - }); - - data.enemyModifiers.forEach((m) => { - if (m.className === "PokemonBaseStatModifier") { - m.className = "BaseStatModifier"; - } else if (m.className === "PokemonResetNegativeStatStageModifier") { - m.className = "ResetNegativeStatStageModifier"; - } - }); - } - - data.gameVersion = LATEST_VERSION; - } -} - -export function applySystemDataPatches(data: SystemSaveData) { - const curVersion = data.gameVersion; - if (curVersion !== LATEST_VERSION) { - switch (curVersion) { - case "1.0.0": - case "1.0.1": - case "1.0.2": - case "1.0.3": - case "1.0.4": - // --- LEGACY PATCHES --- - if (data.starterData && data.dexData) { - // Migrate ability starter data if empty for caught species - Object.keys(data.starterData).forEach(sd => { - if (data.dexData[sd]?.caughtAttr && (data.starterData[sd] && !data.starterData[sd].abilityAttr)) { - data.starterData[sd].abilityAttr = 1; - } - }); - } - - // Fix Legendary Stats - if (data.gameStats && (data.gameStats.legendaryPokemonCaught !== undefined && data.gameStats.subLegendaryPokemonCaught === undefined)) { - data.gameStats.subLegendaryPokemonSeen = 0; - data.gameStats.subLegendaryPokemonCaught = 0; - data.gameStats.subLegendaryPokemonHatched = 0; - allSpecies.filter(s => s.subLegendary).forEach(s => { - const dexEntry = data.dexData[s.speciesId]; - data.gameStats.subLegendaryPokemonSeen += dexEntry.seenCount; - data.gameStats.legendaryPokemonSeen = Math.max(data.gameStats.legendaryPokemonSeen - dexEntry.seenCount, 0); - data.gameStats.subLegendaryPokemonCaught += dexEntry.caughtCount; - data.gameStats.legendaryPokemonCaught = Math.max(data.gameStats.legendaryPokemonCaught - dexEntry.caughtCount, 0); - data.gameStats.subLegendaryPokemonHatched += dexEntry.hatchedCount; - data.gameStats.legendaryPokemonHatched = Math.max(data.gameStats.legendaryPokemonHatched - dexEntry.hatchedCount, 0); - }); - data.gameStats.subLegendaryPokemonSeen = Math.max(data.gameStats.subLegendaryPokemonSeen, data.gameStats.subLegendaryPokemonCaught); - data.gameStats.legendaryPokemonSeen = Math.max(data.gameStats.legendaryPokemonSeen, data.gameStats.legendaryPokemonCaught); - data.gameStats.mythicalPokemonSeen = Math.max(data.gameStats.mythicalPokemonSeen, data.gameStats.mythicalPokemonCaught); - } - - // --- PATCHES --- - - // Fix Starter Data - if (data.starterData && data.dexData) { - for (const starterId of defaultStarterSpecies) { - if (data.starterData[starterId]?.abilityAttr) { - data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1; - } - if (data.dexData[starterId]?.caughtAttr) { - data.dexData[starterId].caughtAttr |= DexAttr.FEMALE; - } - } - } - } - - data.gameVersion = LATEST_VERSION; - } -} - -export function applySettingsDataPatches(settings: Object) { - const curVersion = settings.hasOwnProperty("gameVersion") ? settings["gameVersion"] : "1.0.0"; - if (curVersion !== LATEST_VERSION) { - switch (curVersion) { - case "1.0.0": - case "1.0.1": - case "1.0.2": - case "1.0.3": - case "1.0.4": - // --- PATCHES --- - - // Fix Reward Cursor Target - if (settings.hasOwnProperty("REROLL_TARGET") && !settings.hasOwnProperty(SettingKeys.Shop_Cursor_Target)) { - settings[SettingKeys.Shop_Cursor_Target] = settings["REROLL_TARGET"]; - delete settings["REROLL_TARGET"]; - localStorage.setItem("settings", JSON.stringify(settings)); - } - } - // Note that the current game version will be written at `saveSettings` - } -} diff --git a/src/system/version_migration/version_converter.ts b/src/system/version_migration/version_converter.ts new file mode 100644 index 00000000000..e96afb5cbd4 --- /dev/null +++ b/src/system/version_migration/version_converter.ts @@ -0,0 +1,197 @@ +import { SessionSaveData, SystemSaveData } from "../game-data"; +import { version } from "../../../package.json"; + +// --- v1.0.4 (and below) PATCHES --- // +import * as v1_0_4 from "./versions/v1_0_4"; + +// --- v1.1.0 PATCHES --- // +import * as v1_1_0 from "./versions/v1_1_0"; + +const LATEST_VERSION = version.split(".").map(value => parseInt(value)); + +/** + * Converts incoming {@linkcode SystemSaveData} that has a version below the + * current version number listed in `package.json`. + * + * Note that no transforms act on the {@linkcode data} if its version matches + * the current version or if there are no migrations made between its version up + * to the current version. + * @param data {@linkcode SystemSaveData} + * @see {@link SystemVersionConverter} + */ +export function applySystemVersionMigration(data: SystemSaveData) { + const curVersion = data.gameVersion.split(".").map(value => parseInt(value)); + + if (!curVersion.every((value, index) => value === LATEST_VERSION[index])) { + const converter = new SystemVersionConverter(); + converter.applyStaticPreprocessors(data); + converter.applyMigration(data, curVersion); + } +} + +/** + * Converts incoming {@linkcode SessionSavaData} that has a version below the + * current version number listed in `package.json`. + * + * Note that no transforms act on the {@linkcode data} if its version matches + * the current version or if there are no migrations made between its version up + * to the current version. + * @param data {@linkcode SessionSaveData} + * @see {@link SessionVersionConverter} + */ +export function applySessionVersionMigration(data: SessionSaveData) { + const curVersion = data.gameVersion.split(".").map(value => parseInt(value)); + + if (!curVersion.every((value, index) => value === LATEST_VERSION[index])) { + const converter = new SessionVersionConverter(); + converter.applyStaticPreprocessors(data); + converter.applyMigration(data, curVersion); + } +} + +/** + * Converts incoming settings data that has a version below the + * current version number listed in `package.json`. + * + * Note that no transforms act on the {@linkcode data} if its version matches + * the current version or if there are no migrations made between its version up + * to the current version. + * @param data Settings data object + * @see {@link SettingsVersionConverter} + */ +export function applySettingsVersionMigration(data: Object) { + const gameVersion: string = data.hasOwnProperty("gameVersion") ? data["gameVersion"] : "1.0.0"; + const curVersion = gameVersion.split(".").map(value => parseInt(value)); + + if (!curVersion.every((value, index) => value === LATEST_VERSION[index])) { + const converter = new SettingsVersionConverter(); + converter.applyStaticPreprocessors(data); + converter.applyMigration(data, curVersion); + } +} + +/** + * Abstract class encapsulating the logic for migrating data from a given version up to + * the current version listed in `package.json`. + * + * Note that, for any version converter, the corresponding `applyMigration` + * function would only need to be changed once when the first migration for a + * given version is introduced. Similarly, a version file (within the `versions` + * folder) would only need to be created for a version once with the appropriate + * array nomenclature. + */ +abstract class VersionConverter { + /** + * Iterates through an array of designated migration functions that are each + * called one by one to transform the data. + * @param data The data to be operated on + * @param migrationArr An array of functions that will transform the incoming data + */ + callMigrators(data: any, migrationArr: readonly any[]) { + for (const migrate of migrationArr) { + migrate(data); + } + } + + /** + * Applies any version-agnostic data sanitation as defined within the function + * body. + * @param data The data to be operated on + */ + applyStaticPreprocessors(_data: any): void { + } + + /** + * Uses the current version the incoming data to determine the starting point + * of the migration which will cascade up to the latest version, calling the + * necessary migration functions in the process. + * @param data The data to be operated on + * @param curVersion [0] Current major version + * [1] Current minor version + * [2] Current patch version + */ + abstract applyMigration(data: any, curVersion: number[]): void; +} + +/** + * Class encapsulating the logic for migrating {@linkcode SessionSaveData} from + * a given version up to the current version listed in `package.json`. + * @extends VersionConverter + */ +class SessionVersionConverter extends VersionConverter { + override applyStaticPreprocessors(data: SessionSaveData): void { + // Always sanitize money as a safeguard + data.money = Math.floor(data.money); + } + + override applyMigration(data: SessionSaveData, curVersion: number[]): void { + const [ curMajor, curMinor, curPatch ] = curVersion; + + if (curMajor === 1) { + if (curMinor === 0) { + if (curPatch <= 4) { + console.log("Applying v1.0.4 session data migration!"); + this.callMigrators(data, v1_0_4.sessionMigrators); + } + } + if (curMinor <= 1) { + console.log("Applying v1.1.0 session data migration!"); + this.callMigrators(data, v1_1_0.sessionMigrators); + } + } + + console.log(`Session data successfully migrated to v${version}!`); + } +} + +/** + * Class encapsulating the logic for migrating {@linkcode SystemSaveData} from + * a given version up to the current version listed in `package.json`. + * @extends VersionConverter + */ +class SystemVersionConverter extends VersionConverter { + override applyMigration(data: SystemSaveData, curVersion: number[]): void { + const [ curMajor, curMinor, curPatch ] = curVersion; + + if (curMajor === 1) { + if (curMinor === 0) { + if (curPatch <= 4) { + console.log("Applying v1.0.4 system data migraton!"); + this.callMigrators(data, v1_0_4.systemMigrators); + } + } + if (curMinor <= 1) { + console.log("Applying v1.1.0 system data migraton!"); + this.callMigrators(data, v1_1_0.systemMigrators); + } + } + + console.log(`System data successfully migrated to v${version}!`); + } +} + +/** + * Class encapsulating the logic for migrating settings data from + * a given version up to the current version listed in `package.json`. + * @extends VersionConverter + */ +class SettingsVersionConverter extends VersionConverter { + override applyMigration(data: Object, curVersion: number[]): void { + const [ curMajor, curMinor, curPatch ] = curVersion; + + if (curMajor === 1) { + if (curMinor === 0) { + if (curPatch <= 4) { + console.log("Applying v1.0.4 settings data migraton!"); + this.callMigrators(data, v1_0_4.settingsMigrators); + } + } + if (curMinor <= 1) { + console.log("Applying v1.1.0 settings data migraton!"); + this.callMigrators(data, v1_1_0.settingsMigrators); + } + } + + console.log(`System data successfully migrated to v${version}!`); + } +} diff --git a/src/system/version_migration/versions/v1_0_4.ts b/src/system/version_migration/versions/v1_0_4.ts new file mode 100644 index 00000000000..f16b6bcb6bb --- /dev/null +++ b/src/system/version_migration/versions/v1_0_4.ts @@ -0,0 +1,135 @@ +import { SettingKeys } from "../../settings/settings"; +import { AbilityAttr, defaultStarterSpecies, DexAttr, SystemSaveData, SessionSaveData } from "../../game-data"; +import { allSpecies } from "../../../data/pokemon-species"; + +export const systemMigrators = [ + /** + * Migrate ability starter data if empty for caught species. + * @param data {@linkcode SystemSaveData} + */ + function migrateAbilityData(data: SystemSaveData) { + if (data.starterData && data.dexData) { + Object.keys(data.starterData).forEach(sd => { + if (data.dexData[sd]?.caughtAttr && (data.starterData[sd] && !data.starterData[sd].abilityAttr)) { + data.starterData[sd].abilityAttr = 1; + } + }); + } + }, + + /** + * Populate legendary Pokémon statistics if they are missing. + * @param data {@linkcode SystemSaveData} + */ + function fixLegendaryStats(data: SystemSaveData) { + if (data.gameStats && (data.gameStats.legendaryPokemonCaught !== undefined && data.gameStats.subLegendaryPokemonCaught === undefined)) { + data.gameStats.subLegendaryPokemonSeen = 0; + data.gameStats.subLegendaryPokemonCaught = 0; + data.gameStats.subLegendaryPokemonHatched = 0; + allSpecies.filter(s => s.subLegendary).forEach(s => { + const dexEntry = data.dexData[s.speciesId]; + data.gameStats.subLegendaryPokemonSeen += dexEntry.seenCount; + data.gameStats.legendaryPokemonSeen = Math.max(data.gameStats.legendaryPokemonSeen - dexEntry.seenCount, 0); + data.gameStats.subLegendaryPokemonCaught += dexEntry.caughtCount; + data.gameStats.legendaryPokemonCaught = Math.max(data.gameStats.legendaryPokemonCaught - dexEntry.caughtCount, 0); + data.gameStats.subLegendaryPokemonHatched += dexEntry.hatchedCount; + data.gameStats.legendaryPokemonHatched = Math.max(data.gameStats.legendaryPokemonHatched - dexEntry.hatchedCount, 0); + }); + data.gameStats.subLegendaryPokemonSeen = Math.max(data.gameStats.subLegendaryPokemonSeen, data.gameStats.subLegendaryPokemonCaught); + data.gameStats.legendaryPokemonSeen = Math.max(data.gameStats.legendaryPokemonSeen, data.gameStats.legendaryPokemonCaught); + data.gameStats.mythicalPokemonSeen = Math.max(data.gameStats.mythicalPokemonSeen, data.gameStats.mythicalPokemonCaught); + } + }, + + /** + * Unlock all starters' first ability and female gender option. + * @param data {@linkcode SystemSaveData} + */ + function fixStarterData(data: SystemSaveData) { + for (const starterId of defaultStarterSpecies) { + if (data.starterData[starterId]?.abilityAttr) { + data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1; + } + if (data.dexData[starterId]?.caughtAttr) { + data.dexData[starterId].caughtAttr |= DexAttr.FEMALE; + } + } + } +] as const; + +export const settingsMigrators = [ + /** + * Migrate from "REROLL_TARGET" property to {@linkcode + * SettingKeys.Shop_Cursor_Target}. + * @param data the `settings` object + */ + function fixRerollTarget(data: Object) { + if (data.hasOwnProperty("REROLL_TARGET") && !data.hasOwnProperty(SettingKeys.Shop_Cursor_Target)) { + data[SettingKeys.Shop_Cursor_Target] = data["REROLL_TARGET"]; + delete data["REROLL_TARGET"]; + localStorage.setItem("settings", JSON.stringify(data)); + } + } +] as const; + +export const sessionMigrators = [ + /** + * Converts old lapsing modifiers (battle items, lures, and Dire Hit) and + * other miscellaneous modifiers (vitamins, White Herb) to any new class + * names and/or change in reload arguments. + * @param data {@linkcode SessionSaveData} + */ + function migrateModifiers(data: SessionSaveData) { + data.modifiers.forEach((m) => { + if (m.className === "PokemonBaseStatModifier") { + m.className = "BaseStatModifier"; + } else if (m.className === "PokemonResetNegativeStatStageModifier") { + m.className = "ResetNegativeStatStageModifier"; + } else if (m.className === "TempBattleStatBoosterModifier") { + const maxBattles = 5; + // Dire Hit no longer a part of the TempBattleStatBoosterModifierTypeGenerator + if (m.typeId !== "DIRE_HIT") { + m.className = "TempStatStageBoosterModifier"; + m.typeId = "TEMP_STAT_STAGE_BOOSTER"; + + // Migration from TempBattleStat to Stat + const newStat = m.typePregenArgs[0] + 1; + m.typePregenArgs[0] = newStat; + + // From [ stat, battlesLeft ] to [ stat, maxBattles, battleCount ] + m.args = [ newStat, maxBattles, Math.min(m.args[1], maxBattles) ]; + } else { + m.className = "TempCritBoosterModifier"; + m.typePregenArgs = []; + + // From [ stat, battlesLeft ] to [ maxBattles, battleCount ] + m.args = [ maxBattles, Math.min(m.args[1], maxBattles) ]; + } + } else if (m.className === "DoubleBattleChanceBoosterModifier" && m.args.length === 1) { + let maxBattles: number; + switch (m.typeId) { + case "MAX_LURE": + maxBattles = 30; + break; + case "SUPER_LURE": + maxBattles = 15; + break; + default: + maxBattles = 10; + break; + } + + // From [ battlesLeft ] to [ maxBattles, battleCount ] + m.args = [ maxBattles, Math.min(m.args[0], maxBattles) ]; + } + }); + + data.enemyModifiers.forEach((m) => { + if (m.className === "PokemonBaseStatModifier") { + m.className = "BaseStatModifier"; + } else if (m.className === "PokemonResetNegativeStatStageModifier") { + m.className = "ResetNegativeStatStageModifier"; + } + }); + } +] as const; diff --git a/src/system/version_migration/versions/v1_1_0.ts b/src/system/version_migration/versions/v1_1_0.ts new file mode 100644 index 00000000000..aac554c4531 --- /dev/null +++ b/src/system/version_migration/versions/v1_1_0.ts @@ -0,0 +1,32 @@ +import { SessionSaveData } from "../../game-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; + +export const systemMigrators = [] as const; + +export const settingsMigrators = [] as const; + +export const sessionMigrators = [ + /** + * Converts old Pokemon natureOverride and mysteryEncounterData + * to use the new conjoined {@linkcode Pokemon.customPokemonData} structure instead. + * @param data {@linkcode SessionSaveData} + */ + function migrateCustomPokemonDataAndNatureOverrides(data: SessionSaveData) { + // Fix Pokemon nature overrides and custom data migration + data.party.forEach(pokemon => { + if (pokemon["mysteryEncounterPokemonData"]) { + pokemon.customPokemonData = new CustomPokemonData(pokemon["mysteryEncounterPokemonData"]); + pokemon["mysteryEncounterPokemonData"] = null; + } + if (pokemon["fusionMysteryEncounterPokemonData"]) { + pokemon.fusionCustomPokemonData = new CustomPokemonData(pokemon["fusionMysteryEncounterPokemonData"]); + pokemon["fusionMysteryEncounterPokemonData"] = null; + } + pokemon.customPokemonData = pokemon.customPokemonData ?? new CustomPokemonData(); + if (pokemon["natureOverride"] && pokemon["natureOverride"] >= 0) { + pokemon.customPokemonData.nature = pokemon["natureOverride"]; + pokemon["natureOverride"] = -1; + } + }); + } +] as const; diff --git a/src/system/voucher.ts b/src/system/voucher.ts index 06edfe5c6a6..b38fd528c9f 100644 --- a/src/system/voucher.ts +++ b/src/system/voucher.ts @@ -45,41 +45,41 @@ export class Voucher { getTier(): AchvTier { switch (this.voucherType) { - case VoucherType.REGULAR: - return AchvTier.COMMON; - case VoucherType.PLUS: - return AchvTier.GREAT; - case VoucherType.PREMIUM: - return AchvTier.ULTRA; - case VoucherType.GOLDEN: - return AchvTier.ROGUE; + case VoucherType.REGULAR: + return AchvTier.COMMON; + case VoucherType.PLUS: + return AchvTier.GREAT; + case VoucherType.PREMIUM: + return AchvTier.ULTRA; + case VoucherType.GOLDEN: + return AchvTier.ROGUE; } } } export function getVoucherTypeName(voucherType: VoucherType): string { switch (voucherType) { - case VoucherType.REGULAR: - return i18next.t("voucher:eggVoucher"); - case VoucherType.PLUS: - return i18next.t("voucher:eggVoucherPlus"); - case VoucherType.PREMIUM: - return i18next.t("voucher:eggVoucherPremium"); - case VoucherType.GOLDEN: - return i18next.t("voucher:eggVoucherGold"); + case VoucherType.REGULAR: + return i18next.t("voucher:eggVoucher"); + case VoucherType.PLUS: + return i18next.t("voucher:eggVoucherPlus"); + case VoucherType.PREMIUM: + return i18next.t("voucher:eggVoucherPremium"); + case VoucherType.GOLDEN: + return i18next.t("voucher:eggVoucherGold"); } } export function getVoucherTypeIcon(voucherType: VoucherType): string { switch (voucherType) { - case VoucherType.REGULAR: - return "coupon"; - case VoucherType.PLUS: - return "pair_of_tickets"; - case VoucherType.PREMIUM: - return "mystic_ticket"; - case VoucherType.GOLDEN: - return "golden_mystic_ticket"; + case VoucherType.REGULAR: + return "coupon"; + case VoucherType.PLUS: + return "pair_of_tickets"; + case VoucherType.PREMIUM: + return "mystic_ticket"; + case VoucherType.GOLDEN: + return "golden_mystic_ticket"; } } @@ -90,7 +90,7 @@ export interface Vouchers { export const vouchers: Vouchers = {}; export function initVouchers() { - for (const achv of [achvs.CLASSIC_VICTORY]) { + for (const achv of [ achvs.CLASSIC_VICTORY ]) { const voucherType = achv.score >= 150 ? VoucherType.GOLDEN : achv.score >= 100 diff --git a/src/test/abilities/ability_duplication.test.ts b/src/test/abilities/ability_duplication.test.ts new file mode 100644 index 00000000000..f9122b3259c --- /dev/null +++ b/src/test/abilities/ability_duplication.test.ts @@ -0,0 +1,58 @@ +import { Stat } from "#app/enums/stat"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest"; + +describe("Ability Duplication", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.SPLASH ]) + .battleType("single") + .ability(Abilities.HUGE_POWER) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("huge power should only be applied once if both normal and passive", async () => { + game.override.passiveAbility(Abilities.HUGE_POWER); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const [ magikarp ] = game.scene.getPlayerField(); + const magikarpAttack = magikarp.getEffectiveStat(Stat.ATK); + + magikarp.summonData.abilitySuppressed = true; + + expect(magikarp.getEffectiveStat(Stat.ATK)).toBe(magikarpAttack / 2); + }); + + it("huge power should stack with pure power", async () => { + game.override.passiveAbility(Abilities.PURE_POWER); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const [ magikarp ] = game.scene.getPlayerField(); + const magikarpAttack = magikarp.getEffectiveStat(Stat.ATK); + + magikarp.summonData.abilitySuppressed = true; + + expect(magikarp.getEffectiveStat(Stat.ATK)).toBe(magikarpAttack / 4); + }); +}); diff --git a/src/test/abilities/ability_timing.test.ts b/src/test/abilities/ability_timing.test.ts index 16437df06c9..e3264c2c1a8 100644 --- a/src/test/abilities/ability_timing.test.ts +++ b/src/test/abilities/ability_timing.test.ts @@ -1,13 +1,13 @@ import { BattleStyle } from "#app/enums/battle-style"; import { CommandPhase } from "#app/phases/command-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase"; -import i18next, { initI18n } from "#app/plugins/i18n"; +import i18next from "#app/plugins/i18n"; import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Ability Timing", () => { @@ -32,13 +32,12 @@ describe("Ability Timing", () => { .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.INTIMIDATE) .ability(Abilities.BALL_FETCH); + vi.spyOn(i18next, "t"); }); it("should trigger after switch check", async () => { - initI18n(); - i18next.changeLanguage("en"); game.settings.battleStyle = BattleStyle.SWITCH; - await game.classicMode.runToSummon([Species.EEVEE, Species.FEEBAS]); + await game.classicMode.runToSummon([ Species.EEVEE, Species.FEEBAS ]); game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { game.setMode(Mode.MESSAGE); @@ -46,7 +45,6 @@ describe("Ability Timing", () => { }, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase)); await game.phaseInterceptor.to("MessagePhase"); - const message = game.textInterceptor.getLatestMessage(); - expect(message).toContain("battle:statFell"); + expect(i18next.t).toHaveBeenCalledWith("battle:statFell", expect.objectContaining({ count: 1 })); }, 5000); }); diff --git a/src/test/abilities/aroma_veil.test.ts b/src/test/abilities/aroma_veil.test.ts index b70308a5d60..4284eb43a75 100644 --- a/src/test/abilities/aroma_veil.test.ts +++ b/src/test/abilities/aroma_veil.test.ts @@ -27,14 +27,14 @@ describe("Moves - Aroma Veil", () => { game.override .battleType("double") .enemyAbility(Abilities.BALL_FETCH) - .enemyMoveset([Moves.HEAL_BLOCK, Moves.IMPRISON, Moves.SPLASH]) + .enemyMoveset([ Moves.HEAL_BLOCK, Moves.IMPRISON, Moves.SPLASH ]) .enemySpecies(Species.SHUCKLE) .ability(Abilities.AROMA_VEIL) - .moveset([Moves.GROWL]); + .moveset([ Moves.GROWL ]); }); it("Aroma Veil protects the Pokemon's side against most Move Restriction Battler Tags", async () => { - await game.classicMode.startBattle([Species.REGIELEKI, Species.BULBASAUR]); + await game.classicMode.startBattle([ Species.REGIELEKI, Species.BULBASAUR ]); const party = game.scene.getParty()! as PlayerPokemon[]; @@ -48,7 +48,7 @@ describe("Moves - Aroma Veil", () => { }); it("Aroma Veil does not protect against Imprison", async () => { - await game.classicMode.startBattle([Species.REGIELEKI, Species.BULBASAUR]); + await game.classicMode.startBattle([ Species.REGIELEKI, Species.BULBASAUR ]); const party = game.scene.getParty()! as PlayerPokemon[]; diff --git a/src/test/abilities/aura_break.test.ts b/src/test/abilities/aura_break.test.ts index 422ac5178c1..137688d1f22 100644 --- a/src/test/abilities/aura_break.test.ts +++ b/src/test/abilities/aura_break.test.ts @@ -25,7 +25,7 @@ describe("Abilities - Aura Break", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("single"); - game.override.moveset([Moves.MOONBLAST, Moves.DARK_PULSE, Moves.MOONBLAST, Moves.DARK_PULSE]); + game.override.moveset([ Moves.MOONBLAST, Moves.DARK_PULSE, Moves.MOONBLAST, Moves.DARK_PULSE ]); game.override.enemyMoveset(Moves.SPLASH); game.override.enemyAbility(Abilities.AURA_BREAK); game.override.enemySpecies(Species.SHUCKLE); @@ -38,7 +38,7 @@ describe("Abilities - Aura Break", () => { game.override.ability(Abilities.FAIRY_AURA); vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); game.move.select(Moves.MOONBLAST); await game.phaseInterceptor.to("MoveEffectPhase"); @@ -52,7 +52,7 @@ describe("Abilities - Aura Break", () => { game.override.ability(Abilities.DARK_AURA); vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); game.move.select(Moves.DARK_PULSE); await game.phaseInterceptor.to("MoveEffectPhase"); @@ -66,7 +66,7 @@ describe("Abilities - Aura Break", () => { game.override.ability(Abilities.BALL_FETCH); vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); game.move.select(Moves.MOONBLAST); await game.phaseInterceptor.to("MoveEffectPhase"); diff --git a/src/test/abilities/battery.test.ts b/src/test/abilities/battery.test.ts index cd02ed0c4eb..8abeca287f7 100644 --- a/src/test/abilities/battery.test.ts +++ b/src/test/abilities/battery.test.ts @@ -29,7 +29,7 @@ describe("Abilities - Battery", () => { game.override.battleType("double"); game.override.enemySpecies(Species.SHUCKLE); game.override.enemyAbility(Abilities.BALL_FETCH); - game.override.moveset([Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM]); + game.override.moveset([ Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM ]); game.override.enemyMoveset(Moves.SPLASH); }); @@ -39,7 +39,7 @@ describe("Abilities - Battery", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.PIKACHU, Species.CHARJABUG]); + await game.startBattle([ Species.PIKACHU, Species.CHARJABUG ]); game.move.select(Moves.DAZZLING_GLEAM); game.move.select(Moves.SPLASH, 1); @@ -54,7 +54,7 @@ describe("Abilities - Battery", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.PIKACHU, Species.CHARJABUG]); + await game.startBattle([ Species.PIKACHU, Species.CHARJABUG ]); game.move.select(Moves.BREAKING_SWIPE); game.move.select(Moves.SPLASH, 1); @@ -69,7 +69,7 @@ describe("Abilities - Battery", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.CHARJABUG, Species.PIKACHU]); + await game.startBattle([ Species.CHARJABUG, Species.PIKACHU ]); game.move.select(Moves.DAZZLING_GLEAM); game.move.select(Moves.SPLASH, 1); diff --git a/src/test/abilities/battle_bond.test.ts b/src/test/abilities/battle_bond.test.ts index 4882001cc8d..283fb0d0f14 100644 --- a/src/test/abilities/battle_bond.test.ts +++ b/src/test/abilities/battle_bond.test.ts @@ -1,18 +1,19 @@ +import { allMoves, MultiHitAttr, MultiHitType } from "#app/data/move"; import { Status, StatusEffect } from "#app/data/status-effect"; -import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; -import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; -import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Abilities - BATTLE BOND", () => { let phaserGame: Phaser.Game; let game: GameManager; + const baseForm = 1; + const ashForm = 2; + beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, @@ -25,40 +26,68 @@ describe("Abilities - BATTLE BOND", () => { beforeEach(() => { game = new GameManager(phaserGame); - const moveToUse = Moves.SPLASH; - game.override.battleType("single"); - game.override.ability(Abilities.BATTLE_BOND); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single") + .startingWave(4) // Leads to arena reset on Wave 5 trainer battle + .ability(Abilities.BATTLE_BOND) + .starterForms({ [Species.GRENINJA]: ashForm, }) + .moveset([ Moves.SPLASH, Moves.WATER_SHURIKEN ]) + .enemySpecies(Species.BULBASAUR) + .enemyMoveset(Moves.SPLASH) + .startingLevel(100) // Avoid levelling up + .enemyLevel(1000); // Avoid opponent dying before `doKillOpponents()` }); - test( - "check if fainted pokemon switches to base form on arena reset", - async () => { - const baseForm = 1; - const ashForm = 2; - game.override.startingWave(4); - game.override.starterForms({ - [Species.GRENINJA]: ashForm, - }); + it("check if fainted pokemon switches to base form on arena reset", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP, Species.GRENINJA ]); - await game.startBattle([Species.MAGIKARP, Species.GRENINJA]); + const greninja = game.scene.getParty()[1]; + expect(greninja.formIndex).toBe(ashForm); - const greninja = game.scene.getParty().find((p) => p.species.speciesId === Species.GRENINJA); - expect(greninja).toBeDefined(); - expect(greninja!.formIndex).toBe(ashForm); + greninja.hp = 0; + greninja.status = new Status(StatusEffect.FAINT); + expect(greninja.isFainted()).toBe(true); - greninja!.hp = 0; - greninja!.status = new Status(StatusEffect.FAINT); - expect(greninja!.isFainted()).toBe(true); + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.phaseInterceptor.to("TurnEndPhase"); + game.doSelectModifier(); + await game.phaseInterceptor.to("QuietFormChangePhase"); - game.move.select(Moves.SPLASH); - await game.doKillOpponents(); - await game.phaseInterceptor.to(TurnEndPhase); - game.doSelectModifier(); - await game.phaseInterceptor.to(QuietFormChangePhase); + expect(greninja.formIndex).toBe(baseForm); + }); - expect(greninja!.formIndex).toBe(baseForm); - }, - ); + it("should not keep buffing Water Shuriken after Greninja switches to base form", async () => { + await game.classicMode.startBattle([ Species.GRENINJA ]); + + const waterShuriken = allMoves[Moves.WATER_SHURIKEN]; + vi.spyOn(waterShuriken, "calculateBattlePower"); + + let actualMultiHitType: MultiHitType | null = null; + const multiHitAttr = waterShuriken.getAttrs(MultiHitAttr)[0]; + vi.spyOn(multiHitAttr, "getHitCount").mockImplementation(() => { + actualMultiHitType = multiHitAttr.getMultiHitType(); + return 3; + }); + + // Wave 4: Use Water Shuriken in Ash form + let expectedBattlePower = 20; + let expectedMultiHitType = MultiHitType._3; + + game.move.select(Moves.WATER_SHURIKEN); + await game.phaseInterceptor.to("BerryPhase", false); + expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower); + expect(actualMultiHitType).toBe(expectedMultiHitType); + + await game.doKillOpponents(); + await game.toNextWave(); + + // Wave 5: Use Water Shuriken in base form + expectedBattlePower = 15; + expectedMultiHitType = MultiHitType._2_TO_5; + + game.move.select(Moves.WATER_SHURIKEN); + await game.phaseInterceptor.to("BerryPhase", false); + expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower); + expect(actualMultiHitType).toBe(expectedMultiHitType); + }); }); diff --git a/src/test/abilities/beast_boost.test.ts b/src/test/abilities/beast_boost.test.ts index 26bae7b8838..de31b979e32 100644 --- a/src/test/abilities/beast_boost.test.ts +++ b/src/test/abilities/beast_boost.test.ts @@ -34,7 +34,7 @@ describe("Abilities - Beast Boost", () => { }); it("should prefer highest stat to boost its corresponding stat stage by 1 when winning a battle", async() => { - await game.classicMode.startBattle([Species.SLOWBRO]); + await game.classicMode.startBattle([ Species.SLOWBRO ]); const playerPokemon = game.scene.getPlayerPokemon()!; // Set the pokemon's highest stat to DEF, so it should be picked by Beast Boost @@ -50,9 +50,9 @@ describe("Abilities - Beast Boost", () => { }, 20000); it("should use in-battle overriden stats when determining the stat stage to raise by 1", async() => { - game.override.enemyMoveset([Moves.GUARD_SPLIT]); + game.override.enemyMoveset([ Moves.GUARD_SPLIT ]); - await game.classicMode.startBattle([Species.SLOWBRO]); + await game.classicMode.startBattle([ Species.SLOWBRO ]); const playerPokemon = game.scene.getPlayerPokemon()!; // If the opponent uses Guard Split, the pokemon's second highest stat (SPATK) should be chosen @@ -70,7 +70,7 @@ describe("Abilities - Beast Boost", () => { it("should have order preference in case of stat ties", async() => { // Order preference follows the order of EFFECTIVE_STAT - await game.classicMode.startBattle([Species.SLOWBRO]); + await game.classicMode.startBattle([ Species.SLOWBRO ]); const playerPokemon = game.scene.getPlayerPokemon()!; diff --git a/src/test/abilities/competitive.test.ts b/src/test/abilities/competitive.test.ts new file mode 100644 index 00000000000..ecb276a1b8d --- /dev/null +++ b/src/test/abilities/competitive.test.ts @@ -0,0 +1,72 @@ +import { Stat } from "#enums/stat"; +import { TurnInitPhase } from "#app/phases/turn-init-phase"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Abilities - Competitive", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override.battleType("single") + .enemySpecies(Species.BEEDRILL) + .enemyMoveset(Moves.TICKLE) + .startingLevel(1) + .moveset([ Moves.SPLASH, Moves.CLOSE_COMBAT ]) + .ability(Abilities.COMPETITIVE); + }); + + it("lower atk and def by 1 via tickle, then increase spatk by 4 via competitive", async () => { + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(4); + }); + + it("lowering your own stats should not trigger competitive", async () => { + game.override.enemyMoveset(Moves.SPLASH); + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.CLOSE_COMBAT); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0); + }); + + it("white herb should remove only the negative effects", async () => { + game.override.startingHeldItems([{ name: "WHITE_HERB" }]); + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(4); + }); +}); diff --git a/src/test/abilities/contrary.test.ts b/src/test/abilities/contrary.test.ts index 5221e821e70..c838a5a098e 100644 --- a/src/test/abilities/contrary.test.ts +++ b/src/test/abilities/contrary.test.ts @@ -44,8 +44,8 @@ describe("Abilities - Contrary", () => { it("should apply positive effects", async () => { game.override .enemyPassiveAbility(Abilities.CLEAR_BODY) - .moveset([Moves.TAIL_WHIP]); - await game.classicMode.startBattle([Species.SLOWBRO]); + .moveset([ Moves.TAIL_WHIP ]); + await game.classicMode.startBattle([ Species.SLOWBRO ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -60,9 +60,9 @@ describe("Abilities - Contrary", () => { it("should block negative effects", async () => { game.override .enemyPassiveAbility(Abilities.CLEAR_BODY) - .enemyMoveset([Moves.HOWL, Moves.HOWL, Moves.HOWL, Moves.HOWL]) - .moveset([Moves.SPLASH]); - await game.classicMode.startBattle([Species.SLOWBRO]); + .enemyMoveset([ Moves.HOWL, Moves.HOWL, Moves.HOWL, Moves.HOWL ]) + .moveset([ Moves.SPLASH ]); + await game.classicMode.startBattle([ Species.SLOWBRO ]); const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/abilities/costar.test.ts b/src/test/abilities/costar.test.ts index 2fd1cb26408..3be29ea2dcf 100644 --- a/src/test/abilities/costar.test.ts +++ b/src/test/abilities/costar.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Abilities - COSTAR", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -28,7 +27,7 @@ describe("Abilities - COSTAR", () => { game = new GameManager(phaserGame); game.override.battleType("double"); game.override.ability(Abilities.COSTAR); - game.override.moveset([Moves.SPLASH, Moves.NASTY_PLOT]); + game.override.moveset([ Moves.SPLASH, Moves.NASTY_PLOT ]); game.override.enemyMoveset(Moves.SPLASH); }); @@ -38,9 +37,9 @@ describe("Abilities - COSTAR", () => { async () => { game.override.enemyAbility(Abilities.BALL_FETCH); - await game.startBattle([Species.MAGIKARP, Species.MAGIKARP, Species.FLAMIGO]); + await game.startBattle([ Species.MAGIKARP, Species.MAGIKARP, Species.FLAMIGO ]); - let [leftPokemon, rightPokemon] = game.scene.getPlayerField(); + let [ leftPokemon, rightPokemon ] = game.scene.getPlayerField(); game.move.select(Moves.NASTY_PLOT); await game.phaseInterceptor.to(CommandPhase); @@ -55,7 +54,7 @@ describe("Abilities - COSTAR", () => { game.doSwitchPokemon(2); await game.phaseInterceptor.to(MessagePhase); - [leftPokemon, rightPokemon] = game.scene.getPlayerField(); + [ leftPokemon, rightPokemon ] = game.scene.getPlayerField(); expect(leftPokemon.getStatStage(Stat.SPATK)).toBe(2); expect(rightPokemon.getStatStage(Stat.SPATK)).toBe(2); }, @@ -66,9 +65,9 @@ describe("Abilities - COSTAR", () => { async () => { game.override.enemyAbility(Abilities.INTIMIDATE); - await game.startBattle([Species.MAGIKARP, Species.MAGIKARP, Species.FLAMIGO]); + await game.startBattle([ Species.MAGIKARP, Species.MAGIKARP, Species.FLAMIGO ]); - let [leftPokemon, rightPokemon] = game.scene.getPlayerField(); + let [ leftPokemon, rightPokemon ] = game.scene.getPlayerField(); expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2); expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2); @@ -78,7 +77,7 @@ describe("Abilities - COSTAR", () => { game.doSwitchPokemon(2); await game.phaseInterceptor.to(MessagePhase); - [leftPokemon, rightPokemon] = game.scene.getPlayerField(); + [ leftPokemon, rightPokemon ] = game.scene.getPlayerField(); expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2); expect(rightPokemon.getStatStage(Stat.ATK)).toBe(-2); }, diff --git a/src/test/abilities/dancer.test.ts b/src/test/abilities/dancer.test.ts index 7564a254dbe..8fa3d444f37 100644 --- a/src/test/abilities/dancer.test.ts +++ b/src/test/abilities/dancer.test.ts @@ -8,7 +8,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Abilities - Dancer", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -27,22 +26,22 @@ describe("Abilities - Dancer", () => { game = new GameManager(phaserGame); game.override .battleType("double") - .moveset([Moves.SWORDS_DANCE, Moves.SPLASH]) + .moveset([ Moves.SWORDS_DANCE, Moves.SPLASH ]) .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.DANCER) - .enemyMoveset([Moves.VICTORY_DANCE]); + .enemyMoveset([ Moves.VICTORY_DANCE ]); }); // Reference Link: https://bulbapedia.bulbagarden.net/wiki/Dancer_(Ability) it("triggers when dance moves are used, doesn't consume extra PP", async () => { - await game.classicMode.startBattle([Species.ORICORIO, Species.FEEBAS]); + await game.classicMode.startBattle([ Species.ORICORIO, Species.FEEBAS ]); - const [oricorio] = game.scene.getPlayerField(); + const [ oricorio ] = game.scene.getPlayerField(); game.move.select(Moves.SPLASH); game.move.select(Moves.SWORDS_DANCE, 1); - await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("MovePhase"); // immediately copies ally move await game.phaseInterceptor.to("MovePhase", false); diff --git a/src/test/abilities/defiant.test.ts b/src/test/abilities/defiant.test.ts new file mode 100644 index 00000000000..aa8d250dad7 --- /dev/null +++ b/src/test/abilities/defiant.test.ts @@ -0,0 +1,70 @@ +import { Stat } from "#enums/stat"; +import { TurnInitPhase } from "#app/phases/turn-init-phase"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Abilities - Defiant", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override.battleType("single") + .enemySpecies(Species.BEEDRILL) + .enemyMoveset(Moves.TICKLE) + .startingLevel(1) + .moveset([ Moves.SPLASH, Moves.CLOSE_COMBAT ]) + .ability(Abilities.DEFIANT); + }); + + it("lower atk and def by 1 via tickle, then increase atk by 4 via defiant", async () => { + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1); + }); + + it("lowering your own stats should not trigger defiant", async () => { + game.override.enemyMoveset(Moves.SPLASH); + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.CLOSE_COMBAT); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0); + }); + + it("white herb should remove only the negative effects", async () => { + game.override.startingHeldItems([{ name: "WHITE_HERB" }]); + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0); + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3); + }); +}); diff --git a/src/test/abilities/disguise.test.ts b/src/test/abilities/disguise.test.ts index 0268a738c0e..0241aa4b9ea 100644 --- a/src/test/abilities/disguise.test.ts +++ b/src/test/abilities/disguise.test.ts @@ -1,14 +1,14 @@ +import { BattlerIndex } from "#app/battle"; +import { StatusEffect } from "#app/data/status-effect"; import { toDmgValue } from "#app/utils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { StatusEffect } from "#app/data/status-effect"; import { Stat } from "#enums/stat"; import GameManager from "#test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Abilities - Disguise", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -32,7 +32,7 @@ describe("Abilities - Disguise", () => { .enemySpecies(Species.MIMIKYU) .enemyMoveset(Moves.SPLASH) .starterSpecies(Species.REGIELEKI) - .moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]); + .moveset([ Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH ]); }); it("takes no damage from attacking move and transforms to Busted form, takes 1/8 max HP damage from the disguise breaking", async () => { @@ -107,7 +107,7 @@ describe("Abilities - Disguise", () => { }); it("persists form change when switched out", async () => { - game.override.enemyMoveset([Moves.SHADOW_SNEAK]); + game.override.enemyMoveset([ Moves.SHADOW_SNEAK ]); game.override.starterSpecies(0); await game.classicMode.startBattle([ Species.MIMIKYU, Species.FURRET ]); @@ -193,7 +193,7 @@ describe("Abilities - Disguise", () => { }); it("doesn't faint twice when fainting due to Disguise break damage, nor prevent faint from Disguise break damage if using Endure", async () => { - game.override.enemyMoveset([Moves.ENDURE]); + game.override.enemyMoveset([ Moves.ENDURE ]); await game.classicMode.startBattle(); const mimikyu = game.scene.getEnemyPokemon()!; @@ -208,7 +208,7 @@ describe("Abilities - Disguise", () => { it("activates when Aerilate circumvents immunity to the move's base type", async () => { game.override.ability(Abilities.AERILATE); - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); await game.classicMode.startBattle(); @@ -223,4 +223,17 @@ describe("Abilities - Disguise", () => { expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.hp).toBe(maxHp - disguiseDamage); }); + + it("doesn't trigger if user is behind a substitute", async () => { + game.override + .enemyMoveset(Moves.SUBSTITUTE) + .moveset(Moves.POWER_TRIP); + await game.classicMode.startBattle(); + + game.move.select(Moves.POWER_TRIP); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextTurn(); + + expect(game.scene.getEnemyPokemon()!.formIndex).toBe(disguisedForm); + }); }); diff --git a/src/test/abilities/dry_skin.test.ts b/src/test/abilities/dry_skin.test.ts index a97914660bc..314564df15c 100644 --- a/src/test/abilities/dry_skin.test.ts +++ b/src/test/abilities/dry_skin.test.ts @@ -28,7 +28,7 @@ describe("Abilities - Dry Skin", () => { .enemyMoveset(Moves.SPLASH) .enemySpecies(Species.CHARMANDER) .ability(Abilities.BALL_FETCH) - .moveset([Moves.SUNNY_DAY, Moves.RAIN_DANCE, Moves.SPLASH, Moves.WATER_GUN]) + .moveset([ Moves.SUNNY_DAY, Moves.RAIN_DANCE, Moves.SPLASH, Moves.WATER_GUN ]) .starterSpecies(Species.CHANDELURE); }); @@ -69,7 +69,7 @@ describe("Abilities - Dry Skin", () => { }); it("opposing fire attacks do 25% more damage", async () => { - game.override.moveset([Moves.FLAMETHROWER]); + game.override.moveset([ Moves.FLAMETHROWER ]); await game.classicMode.startBattle(); const enemy = game.scene.getEnemyPokemon()!; @@ -105,7 +105,7 @@ describe("Abilities - Dry Skin", () => { }); it("opposing water attacks do not heal if they were protected from", async () => { - game.override.enemyMoveset([Moves.PROTECT]); + game.override.enemyMoveset([ Moves.PROTECT ]); await game.classicMode.startBattle(); @@ -119,7 +119,7 @@ describe("Abilities - Dry Skin", () => { }); it("multi-strike water attacks only heal once", async () => { - game.override.moveset([Moves.WATER_GUN, Moves.WATER_SHURIKEN]); + game.override.moveset([ Moves.WATER_GUN, Moves.WATER_SHURIKEN ]); await game.classicMode.startBattle(); diff --git a/src/test/abilities/early_bird.test.ts b/src/test/abilities/early_bird.test.ts new file mode 100644 index 00000000000..a69290fa1e4 --- /dev/null +++ b/src/test/abilities/early_bird.test.ts @@ -0,0 +1,93 @@ +import { Status } from "#app/data/status-effect"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { StatusEffect } from "#enums/status-effect"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Abilities - Early Bird", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.REST, Moves.BELLY_DRUM, Moves.SPLASH ]) + .ability(Abilities.EARLY_BIRD) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("reduces Rest's sleep time to 1 turn", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const player = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.BELLY_DRUM); + await game.toNextTurn(); + game.move.select(Moves.REST); + await game.toNextTurn(); + + expect(player.status?.effect).toBe(StatusEffect.SLEEP); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status?.effect).toBe(StatusEffect.SLEEP); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status?.effect).toBeUndefined(); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + }); + + it("reduces 3-turn sleep to 1 turn", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const player = game.scene.getPlayerPokemon()!; + player.status = new Status(StatusEffect.SLEEP, 0, 4); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status?.effect).toBe(StatusEffect.SLEEP); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status?.effect).toBeUndefined(); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + }); + + it("reduces 1-turn sleep to 0 turns", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const player = game.scene.getPlayerPokemon()!; + player.status = new Status(StatusEffect.SLEEP, 0, 2); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status?.effect).toBeUndefined(); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + }); +}); diff --git a/src/test/abilities/flash_fire.test.ts b/src/test/abilities/flash_fire.test.ts index 9c78de99575..f03e1689649 100644 --- a/src/test/abilities/flash_fire.test.ts +++ b/src/test/abilities/flash_fire.test.ts @@ -37,8 +37,8 @@ describe("Abilities - Flash Fire", () => { it("immune to Fire-type moves", async () => { - game.override.enemyMoveset([Moves.EMBER]).moveset(Moves.SPLASH); - await game.classicMode.startBattle([Species.BLISSEY]); + game.override.enemyMoveset([ Moves.EMBER ]).moveset(Moves.SPLASH); + await game.classicMode.startBattle([ Species.BLISSEY ]); const blissey = game.scene.getPlayerPokemon()!; @@ -48,8 +48,8 @@ describe("Abilities - Flash Fire", () => { }, 20000); it("not activate if the Pokémon is protected from the Fire-type move", async () => { - game.override.enemyMoveset([Moves.EMBER]).moveset([Moves.PROTECT]); - await game.classicMode.startBattle([Species.BLISSEY]); + game.override.enemyMoveset([ Moves.EMBER ]).moveset([ Moves.PROTECT ]); + await game.classicMode.startBattle([ Species.BLISSEY ]); const blissey = game.scene.getPlayerPokemon()!; @@ -59,8 +59,8 @@ describe("Abilities - Flash Fire", () => { }, 20000); it("activated by Will-O-Wisp", async () => { - game.override.enemyMoveset([Moves.WILL_O_WISP]).moveset(Moves.SPLASH); - await game.classicMode.startBattle([Species.BLISSEY]); + game.override.enemyMoveset([ Moves.WILL_O_WISP ]).moveset(Moves.SPLASH); + await game.classicMode.startBattle([ Species.BLISSEY ]); const blissey = game.scene.getPlayerPokemon()!; @@ -74,9 +74,9 @@ describe("Abilities - Flash Fire", () => { }, 20000); it("activated after being frozen", async () => { - game.override.enemyMoveset([Moves.EMBER]).moveset(Moves.SPLASH); + game.override.enemyMoveset([ Moves.EMBER ]).moveset(Moves.SPLASH); game.override.statusEffect(StatusEffect.FREEZE); - await game.classicMode.startBattle([Species.BLISSEY]); + await game.classicMode.startBattle([ Species.BLISSEY ]); const blissey = game.scene.getPlayerPokemon()!; @@ -87,12 +87,12 @@ describe("Abilities - Flash Fire", () => { }, 20000); it("not passing with baton pass", async () => { - game.override.enemyMoveset([Moves.EMBER]).moveset([Moves.BATON_PASS]); - await game.classicMode.startBattle([Species.BLISSEY, Species.CHANSEY]); + game.override.enemyMoveset([ Moves.EMBER ]).moveset([ Moves.BATON_PASS ]); + await game.classicMode.startBattle([ Species.BLISSEY, Species.CHANSEY ]); // ensure use baton pass after enemy moved game.move.select(Moves.BATON_PASS); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); game.doSelectPartyPokemon(1); @@ -103,16 +103,16 @@ describe("Abilities - Flash Fire", () => { }, 20000); it("boosts Fire-type move when the ability is activated", async () => { - game.override.enemyMoveset([Moves.FIRE_PLEDGE]).moveset([Moves.EMBER, Moves.SPLASH]); + game.override.enemyMoveset([ Moves.FIRE_PLEDGE ]).moveset([ Moves.EMBER, Moves.SPLASH ]); game.override.enemyAbility(Abilities.FLASH_FIRE).ability(Abilities.NONE); - await game.classicMode.startBattle([Species.BLISSEY]); + await game.classicMode.startBattle([ Species.BLISSEY ]); const blissey = game.scene.getPlayerPokemon()!; const initialHP = 1000; blissey.hp = initialHP; // first turn game.move.select(Moves.EMBER); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to(TurnEndPhase); const originalDmg = initialHP - blissey.hp; @@ -131,7 +131,7 @@ describe("Abilities - Flash Fire", () => { game.override.moveset(Moves.FIRE_PLEDGE).enemyMoveset(Moves.EMBER); game.override.enemyAbility(Abilities.NONE).ability(Abilities.FLASH_FIRE); game.override.enemySpecies(Species.BLISSEY); - await game.classicMode.startBattle([Species.RATTATA]); + await game.classicMode.startBattle([ Species.RATTATA ]); const blissey = game.scene.getEnemyPokemon()!; const initialHP = 1000; @@ -139,7 +139,7 @@ describe("Abilities - Flash Fire", () => { // first turn game.move.select(Moves.FIRE_PLEDGE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); await game.move.forceMiss(); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/abilities/flower_gift.test.ts b/src/test/abilities/flower_gift.test.ts index 256b61c6fea..04ada598f22 100644 --- a/src/test/abilities/flower_gift.test.ts +++ b/src/test/abilities/flower_gift.test.ts @@ -21,7 +21,7 @@ describe("Abilities - Flower Gift", () => { */ const testRevertFormAgainstAbility = async (game: GameManager, ability: Abilities) => { game.override.starterForms({ [Species.CASTFORM]: SUNSHINE_FORM }).enemyAbility(ability); - await game.classicMode.startBattle([Species.CASTFORM]); + await game.classicMode.startBattle([ Species.CASTFORM ]); game.move.select(Moves.SPLASH); @@ -41,7 +41,7 @@ describe("Abilities - Flower Gift", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.SPLASH, Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.SKILL_SWAP]) + .moveset([ Moves.SPLASH, Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.SKILL_SWAP ]) .enemySpecies(Species.MAGIKARP) .enemyMoveset(Moves.SPLASH) .enemyAbility(Abilities.BALL_FETCH); @@ -50,7 +50,7 @@ describe("Abilities - Flower Gift", () => { // TODO: Uncomment expect statements when the ability is implemented - currently does not increase stats of allies it("increases the ATK and SPDEF stat stages of the Pokémon with this Ability and its allies by 1.5× during Harsh Sunlight", async () => { game.override.battleType("double"); - await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.CHERRIM, Species.MAGIKARP ]); const [ cherrim ] = game.scene.getPlayerField(); const cherrimAtkStat = cherrim.getEffectiveStat(Stat.ATK); @@ -62,7 +62,7 @@ describe("Abilities - Flower Gift", () => { game.move.select(Moves.SUNNY_DAY, 0); game.move.select(Moves.SPLASH, 1); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("TurnEndPhase"); expect(cherrim.formIndex).toBe(SUNSHINE_FORM); @@ -74,7 +74,7 @@ describe("Abilities - Flower Gift", () => { it("changes the Pokemon's form during Harsh Sunlight", async () => { game.override.weather(WeatherType.HARSH_SUN); - await game.classicMode.startBattle([Species.CHERRIM]); + await game.classicMode.startBattle([ Species.CHERRIM ]); const cherrim = game.scene.getPlayerPokemon()!; expect(cherrim.formIndex).toBe(SUNSHINE_FORM); @@ -91,9 +91,9 @@ describe("Abilities - Flower Gift", () => { }); it("reverts to Overcast Form when the Pokémon loses Flower Gift, changes form under Harsh Sunlight/Sunny when it regains it", async () => { - game.override.enemyMoveset([Moves.SKILL_SWAP]).weather(WeatherType.HARSH_SUN); + game.override.enemyMoveset([ Moves.SKILL_SWAP ]).weather(WeatherType.HARSH_SUN); - await game.classicMode.startBattle([Species.CHERRIM]); + await game.classicMode.startBattle([ Species.CHERRIM ]); const cherrim = game.scene.getPlayerPokemon()!; @@ -110,16 +110,16 @@ describe("Abilities - Flower Gift", () => { }); it("reverts to Overcast Form when the Flower Gift is suppressed, changes form under Harsh Sunlight/Sunny when it regains it", async () => { - game.override.enemyMoveset([Moves.GASTRO_ACID]).weather(WeatherType.HARSH_SUN); + game.override.enemyMoveset([ Moves.GASTRO_ACID ]).weather(WeatherType.HARSH_SUN); - await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.CHERRIM, Species.MAGIKARP ]); const cherrim = game.scene.getPlayerPokemon()!; expect(cherrim.formIndex).toBe(SUNSHINE_FORM); game.move.select(Moves.SPLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); expect(cherrim.summonData.abilitySuppressed).toBe(true); @@ -140,7 +140,7 @@ describe("Abilities - Flower Gift", () => { it("should be in Overcast Form after the user is switched out", async () => { game.override.weather(WeatherType.SUNNY); - await game.classicMode.startBattle([Species.CASTFORM, Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.CASTFORM, Species.MAGIKARP ]); const cherrim = game.scene.getPlayerPokemon()!; expect(cherrim.formIndex).toBe(SUNSHINE_FORM); diff --git a/src/test/abilities/forecast.test.ts b/src/test/abilities/forecast.test.ts index c1eb3600b8b..6da31307789 100644 --- a/src/test/abilities/forecast.test.ts +++ b/src/test/abilities/forecast.test.ts @@ -30,7 +30,7 @@ describe("Abilities - Forecast", () => { */ const testWeatherFormChange = async (game: GameManager, weather: WeatherType, form: number, initialForm?: number) => { game.override.weather(weather).starterForms({ [Species.CASTFORM]: initialForm }); - await game.startBattle([Species.CASTFORM]); + await game.startBattle([ Species.CASTFORM ]); game.move.select(Moves.SPLASH); @@ -44,7 +44,7 @@ describe("Abilities - Forecast", () => { */ const testRevertFormAgainstAbility = async (game: GameManager, ability: Abilities) => { game.override.starterForms({ [Species.CASTFORM]: SUNNY_FORM }).enemyAbility(ability); - await game.startBattle([Species.CASTFORM]); + await game.startBattle([ Species.CASTFORM ]); game.move.select(Moves.SPLASH); @@ -64,7 +64,7 @@ describe("Abilities - Forecast", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.SPLASH, Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.TACKLE]) + .moveset([ Moves.SPLASH, Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.TACKLE ]) .enemySpecies(Species.MAGIKARP) .enemyMoveset(Moves.SPLASH) .enemyAbility(Abilities.BALL_FETCH); @@ -72,14 +72,14 @@ describe("Abilities - Forecast", () => { it("changes form based on weather", async () => { game.override - .moveset([Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.SNOWSCAPE, Moves.SPLASH]) + .moveset([ Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.SNOWSCAPE, Moves.SPLASH ]) .battleType("double") .starterForms({ [Species.KYOGRE]: 1, [Species.GROUDON]: 1, [Species.RAYQUAZA]: 1 }); - await game.startBattle([Species.CASTFORM, Species.FEEBAS, Species.KYOGRE, Species.GROUDON, Species.RAYQUAZA, Species.ALTARIA]); + await game.startBattle([ Species.CASTFORM, Species.FEEBAS, Species.KYOGRE, Species.GROUDON, Species.RAYQUAZA, Species.ALTARIA ]); vi.spyOn(game.scene.getParty()[5], "getAbility").mockReturnValue(allAbilities[Abilities.CLOUD_NINE]); @@ -107,7 +107,7 @@ describe("Abilities - Forecast", () => { expect(castform.formIndex).toBe(SNOWY_FORM); - game.override.moveset([Moves.HAIL, Moves.SANDSTORM, Moves.SNOWSCAPE, Moves.SPLASH]); + game.override.moveset([ Moves.HAIL, Moves.SANDSTORM, Moves.SNOWSCAPE, Moves.SPLASH ]); game.move.select(Moves.SANDSTORM); game.move.select(Moves.SPLASH, 1); @@ -190,7 +190,7 @@ describe("Abilities - Forecast", () => { it("has no effect on Pokémon other than Castform", async () => { game.override.enemyAbility(Abilities.FORECAST).enemySpecies(Species.SHUCKLE); - await game.startBattle([Species.CASTFORM]); + await game.startBattle([ Species.CASTFORM ]); game.move.select(Moves.RAIN_DANCE); await game.phaseInterceptor.to(TurnEndPhase); @@ -200,8 +200,8 @@ describe("Abilities - Forecast", () => { }); it("reverts to Normal Form when Castform loses Forecast, changes form to match the weather when it regains it", async () => { - game.override.moveset([Moves.SKILL_SWAP, Moves.WORRY_SEED, Moves.SPLASH]).weather(WeatherType.RAIN).battleType("double"); - await game.startBattle([Species.CASTFORM, Species.FEEBAS]); + game.override.moveset([ Moves.SKILL_SWAP, Moves.WORRY_SEED, Moves.SPLASH ]).weather(WeatherType.RAIN).battleType("double"); + await game.startBattle([ Species.CASTFORM, Species.FEEBAS ]); const castform = game.scene.getPlayerField()[0]; @@ -209,7 +209,7 @@ describe("Abilities - Forecast", () => { game.move.select(Moves.SKILL_SWAP, 0, BattlerIndex.PLAYER_2); game.move.select(Moves.SKILL_SWAP, 1, BattlerIndex.PLAYER); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(castform.formIndex).toBe(NORMAL_FORM); @@ -221,22 +221,22 @@ describe("Abilities - Forecast", () => { game.move.select(Moves.SPLASH); game.move.select(Moves.WORRY_SEED, 1, BattlerIndex.PLAYER); - await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(castform.formIndex).toBe(NORMAL_FORM); }); it("reverts to Normal Form when Forecast is suppressed, changes form to match the weather when it regains it", async () => { - game.override.enemyMoveset([Moves.GASTRO_ACID]).weather(WeatherType.RAIN); - await game.startBattle([Species.CASTFORM, Species.PIKACHU]); + game.override.enemyMoveset([ Moves.GASTRO_ACID ]).weather(WeatherType.RAIN); + await game.startBattle([ Species.CASTFORM, Species.PIKACHU ]); const castform = game.scene.getPlayerPokemon()!; expect(castform.formIndex).toBe(RAINY_FORM); // First turn - Forecast is suppressed game.move.select(Moves.SPLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.move.forceHit(); await game.phaseInterceptor.to(TurnEndPhase); @@ -259,8 +259,8 @@ describe("Abilities - Forecast", () => { }); it("does not change Castform's form until after Stealth Rock deals damage", async () => { - game.override.weather(WeatherType.RAIN).enemyMoveset([Moves.STEALTH_ROCK]); - await game.startBattle([Species.PIKACHU, Species.CASTFORM]); + game.override.weather(WeatherType.RAIN).enemyMoveset([ Moves.STEALTH_ROCK ]); + await game.startBattle([ Species.PIKACHU, Species.CASTFORM ]); // First turn - set up stealth rock game.move.select(Moves.SPLASH); @@ -284,7 +284,7 @@ describe("Abilities - Forecast", () => { it("should be in Normal Form after the user is switched out", async () => { game.override.weather(WeatherType.RAIN); - await game.startBattle([Species.CASTFORM, Species.MAGIKARP]); + await game.startBattle([ Species.CASTFORM, Species.MAGIKARP ]); const castform = game.scene.getPlayerPokemon()!; expect(castform.formIndex).toBe(RAINY_FORM); diff --git a/src/test/abilities/friend_guard.test.ts b/src/test/abilities/friend_guard.test.ts new file mode 100644 index 00000000000..4ce64468c43 --- /dev/null +++ b/src/test/abilities/friend_guard.test.ts @@ -0,0 +1,120 @@ +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Abilities } from "#enums/abilities"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { BattlerIndex } from "#app/battle"; +import { allAbilities } from "#app/data/ability"; +import { allMoves, MoveCategory } from "#app/data/move"; + +describe("Moves - Friend Guard", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleType("double") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset([ Moves.TACKLE, Moves.SPLASH, Moves.DRAGON_RAGE ]) + .enemySpecies(Species.SHUCKLE) + .moveset([ Moves.SPLASH ]) + .startingLevel(100); + }); + + it("should reduce damage that other allied Pokémon receive from attacks (from any Pokémon) by 25%", async () => { + await game.classicMode.startBattle([ Species.BULBASAUR, Species.CHARMANDER ]); + const [ player1, player2 ] = game.scene.getPlayerField(); + const spy = vi.spyOn(player1, "getAttackDamage"); + + const enemy1 = game.scene.getEnemyField()[0]; + + game.move.select(Moves.SPLASH); + game.move.select(Moves.SPLASH, 1); + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + // Get the last return value from `getAttackDamage` + const turn1Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; + // Making sure the test is controlled; turn 1 damage is equal to base damage (after rounding) + expect(turn1Damage).toBe(Math.floor(player1.getBaseDamage(enemy1, allMoves[Moves.TACKLE], MoveCategory.PHYSICAL))); + + vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[Abilities.FRIEND_GUARD]); + + game.move.select(Moves.SPLASH); + game.move.select(Moves.SPLASH, 1); + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + // Get the last return value from `getAttackDamage` + const turn2Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; + // With the ally's Friend Guard, damage should have been reduced from base damage by 25% + expect(turn2Damage).toBe(Math.floor(player1.getBaseDamage(enemy1, allMoves[Moves.TACKLE], MoveCategory.PHYSICAL) * 0.75)); + }); + + it("should NOT reduce damage to pokemon with friend guard", async () => { + await game.classicMode.startBattle([ Species.BULBASAUR, Species.CHARMANDER ]); + + const player2 = game.scene.getPlayerField()[1]; + const spy = vi.spyOn(player2, "getAttackDamage"); + + game.move.select(Moves.SPLASH); + game.move.select(Moves.SPLASH, 1); + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + const turn1Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; + + vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[Abilities.FRIEND_GUARD]); + + game.move.select(Moves.SPLASH); + game.move.select(Moves.SPLASH, 1); + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + const turn2Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; + expect(turn2Damage).toBe(turn1Damage); + }); + + it("should NOT reduce damage from fixed damage attacks", async () => { + await game.classicMode.startBattle([ Species.BULBASAUR, Species.CHARMANDER ]); + + const [ player1, player2 ] = game.scene.getPlayerField(); + const spy = vi.spyOn(player1, "getAttackDamage"); + + game.move.select(Moves.SPLASH); + game.move.select(Moves.SPLASH, 1); + await game.forceEnemyMove(Moves.DRAGON_RAGE, BattlerIndex.PLAYER); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + const turn1Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; + expect(turn1Damage).toBe(40); + + vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[Abilities.FRIEND_GUARD]); + + game.move.select(Moves.SPLASH); + game.move.select(Moves.SPLASH, 1); + await game.forceEnemyMove(Moves.DRAGON_RAGE, BattlerIndex.PLAYER); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + const turn2Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; + expect(turn2Damage).toBe(40); + }); +}); diff --git a/src/test/abilities/galvanize.test.ts b/src/test/abilities/galvanize.test.ts index 1b7dde9ba60..438f166174d 100644 --- a/src/test/abilities/galvanize.test.ts +++ b/src/test/abilities/galvanize.test.ts @@ -10,7 +10,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; - describe("Abilities - Galvanize", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -32,7 +31,7 @@ describe("Abilities - Galvanize", () => { .battleType("single") .startingLevel(100) .ability(Abilities.GALVANIZE) - .moveset([Moves.TACKLE, Moves.REVELATION_DANCE, Moves.FURY_SWIPES]) + .moveset([ Moves.TACKLE, Moves.REVELATION_DANCE, Moves.FURY_SWIPES ]) .enemySpecies(Species.DUSCLOPS) .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) @@ -86,7 +85,7 @@ describe("Abilities - Galvanize", () => { it("should not change the type of variable-type moves", async () => { game.override.enemySpecies(Species.MIGHTYENA); - await game.startBattle([Species.ESPEON]); + await game.startBattle([ Species.ESPEON ]); const playerPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(playerPokemon, "getMoveType"); @@ -112,7 +111,7 @@ describe("Abilities - Galvanize", () => { vi.spyOn(enemyPokemon, "apply"); game.move.select(Moves.FURY_SWIPES); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.move.forceHit(); await game.phaseInterceptor.to("MoveEffectPhase"); diff --git a/src/test/abilities/gorilla_tactics.test.ts b/src/test/abilities/gorilla_tactics.test.ts index 5e92950526e..8aee365eb8f 100644 --- a/src/test/abilities/gorilla_tactics.test.ts +++ b/src/test/abilities/gorilla_tactics.test.ts @@ -25,15 +25,15 @@ describe("Abilities - Gorilla Tactics", () => { game.override .battleType("single") .enemyAbility(Abilities.BALL_FETCH) - .enemyMoveset([Moves.SPLASH, Moves.DISABLE]) + .enemyMoveset([ Moves.SPLASH, Moves.DISABLE ]) .enemySpecies(Species.MAGIKARP) .enemyLevel(30) - .moveset([Moves.SPLASH, Moves.TACKLE, Moves.GROWL]) + .moveset([ Moves.SPLASH, Moves.TACKLE, Moves.GROWL ]) .ability(Abilities.GORILLA_TACTICS); }); it("boosts the Pokémon's Attack by 50%, but limits the Pokémon to using only one move", async () => { - await game.classicMode.startBattle([Species.GALAR_DARMANITAN]); + await game.classicMode.startBattle([ Species.GALAR_DARMANITAN ]); const darmanitan = game.scene.getPlayerPokemon()!; const initialAtkStat = darmanitan.getStat(Stat.ATK); @@ -50,7 +50,7 @@ describe("Abilities - Gorilla Tactics", () => { }); it("should struggle if the only usable move is disabled", async () => { - await game.classicMode.startBattle([Species.GALAR_DARMANITAN]); + await game.classicMode.startBattle([ Species.GALAR_DARMANITAN ]); const darmanitan = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -64,7 +64,7 @@ describe("Abilities - Gorilla Tactics", () => { game.move.select(Moves.GROWL); await game.forceEnemyMove(Moves.DISABLE); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); expect(enemy.getStatStage(Stat.ATK)).toBe(-1); // Only the effect of the first Growl should be applied @@ -73,7 +73,7 @@ describe("Abilities - Gorilla Tactics", () => { await game.toNextTurn(); game.move.select(Moves.TACKLE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(darmanitan.hp).toBeLessThan(darmanitan.getMaxHp()); diff --git a/src/test/abilities/gulp_missile.test.ts b/src/test/abilities/gulp_missile.test.ts index d981f009974..01b68d0c89d 100644 --- a/src/test/abilities/gulp_missile.test.ts +++ b/src/test/abilities/gulp_missile.test.ts @@ -1,13 +1,14 @@ -import { BattlerTagType } from "#enums/battler-tag-type"; -import { StatusEffect } from "#enums/status-effect"; +import { BattlerIndex } from "#app/battle"; import Pokemon from "#app/field/pokemon"; -import GameManager from "#test/utils/gameManager"; import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; +import { StatusEffect } from "#enums/status-effect"; +import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { Stat } from "#enums/stat"; describe("Abilities - Gulp Missile", () => { let phaserGame: Phaser.Game; @@ -40,8 +41,9 @@ describe("Abilities - Gulp Missile", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override + .disableCrits() .battleType("single") - .moveset([Moves.SURF, Moves.DIVE, Moves.SPLASH]) + .moveset([ Moves.SURF, Moves.DIVE, Moves.SPLASH, Moves.SUBSTITUTE ]) .enemySpecies(Species.SNORLAX) .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) @@ -49,7 +51,7 @@ describe("Abilities - Gulp Missile", () => { }); it("changes to Gulping Form if HP is over half when Surf or Dive is used", async () => { - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; game.move.select(Moves.DIVE); @@ -63,7 +65,7 @@ describe("Abilities - Gulp Missile", () => { }); it("changes to Gorging Form if HP is under half when Surf or Dive is used", async () => { - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.49); @@ -77,7 +79,7 @@ describe("Abilities - Gulp Missile", () => { }); it("changes to base form when switched out after Surf or Dive is used", async () => { - await game.classicMode.startBattle([Species.CRAMORANT, Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.CRAMORANT, Species.MAGIKARP ]); const cramorant = game.scene.getPlayerPokemon()!; game.move.select(Moves.SURF); @@ -92,7 +94,7 @@ describe("Abilities - Gulp Missile", () => { }); it("changes form during Dive's charge turn", async () => { - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; game.move.select(Moves.DIVE); @@ -104,7 +106,7 @@ describe("Abilities - Gulp Missile", () => { it("deals 1/4 of the attacker's maximum HP when hit by a damaging attack", async () => { game.override.enemyMoveset(Moves.TACKLE); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const enemy = game.scene.getEnemyPokemon()!; vi.spyOn(enemy, "damageAndUpdate"); @@ -117,7 +119,7 @@ describe("Abilities - Gulp Missile", () => { it("does not have any effect when hit by non-damaging attack", async () => { game.override.enemyMoveset(Moves.TAIL_WHIP); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.55); @@ -136,7 +138,7 @@ describe("Abilities - Gulp Missile", () => { it("lowers attacker's DEF stat stage by 1 when hit in Gulping form", async () => { game.override.enemyMoveset(Moves.TACKLE); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -160,7 +162,7 @@ describe("Abilities - Gulp Missile", () => { it("paralyzes the enemy when hit in Gorging form", async () => { game.override.enemyMoveset(Moves.TACKLE); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -184,7 +186,7 @@ describe("Abilities - Gulp Missile", () => { it("does not activate the ability when underwater", async () => { game.override.enemyMoveset(Moves.SURF); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; @@ -197,7 +199,7 @@ describe("Abilities - Gulp Missile", () => { it("prevents effect damage but inflicts secondary effect on attacker with Magic Guard", async () => { game.override.enemyMoveset(Moves.TACKLE).enemyAbility(Abilities.MAGIC_GUARD); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -221,7 +223,7 @@ describe("Abilities - Gulp Missile", () => { it("activates on faint", async () => { game.override.enemyMoveset(Moves.THUNDERBOLT); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; @@ -234,10 +236,29 @@ describe("Abilities - Gulp Missile", () => { expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.DEF)).toBe(-1); }); + it("doesn't trigger if user is behind a substitute", async () => { + game.override + .enemyAbility(Abilities.STURDY) + .enemyMoveset([ Moves.SPLASH, Moves.POWER_TRIP ]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); + + game.move.select(Moves.SURF); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM); + + game.move.select(Moves.SUBSTITUTE); + await game.forceEnemyMove(Moves.POWER_TRIP); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.toNextTurn(); + + expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM); + }); it("cannot be suppressed", async () => { game.override.enemyMoveset(Moves.GASTRO_ACID); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.55); @@ -257,7 +278,7 @@ describe("Abilities - Gulp Missile", () => { it("cannot be swapped with another ability", async () => { game.override.enemyMoveset(Moves.SKILL_SWAP); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); const cramorant = game.scene.getPlayerPokemon()!; vi.spyOn(cramorant, "getHpRatio").mockReturnValue(.55); @@ -278,7 +299,7 @@ describe("Abilities - Gulp Missile", () => { it("cannot be copied", async () => { game.override.enemyAbility(Abilities.TRACE); - await game.classicMode.startBattle([Species.CRAMORANT]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); game.move.select(Moves.SPLASH); await game.phaseInterceptor.to("TurnStartPhase"); diff --git a/src/test/abilities/heatproof.test.ts b/src/test/abilities/heatproof.test.ts index 61c406201bd..bf4e99ce467 100644 --- a/src/test/abilities/heatproof.test.ts +++ b/src/test/abilities/heatproof.test.ts @@ -33,7 +33,7 @@ describe("Abilities - Heatproof", () => { .enemyLevel(100) .starterSpecies(Species.CHANDELURE) .ability(Abilities.BALL_FETCH) - .moveset([Moves.FLAMETHROWER, Moves.SPLASH]) + .moveset([ Moves.FLAMETHROWER, Moves.SPLASH ]) .startingLevel(100); }); diff --git a/src/test/abilities/hustle.test.ts b/src/test/abilities/hustle.test.ts index 29cbfdc1a5d..c4c4818040d 100644 --- a/src/test/abilities/hustle.test.ts +++ b/src/test/abilities/hustle.test.ts @@ -34,7 +34,7 @@ describe("Abilities - Hustle", () => { }); it("increases the user's Attack stat by 50%", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pikachu = game.scene.getPlayerPokemon()!; const atk = pikachu.stats[Stat.ATK]; @@ -48,7 +48,7 @@ describe("Abilities - Hustle", () => { }); it("lowers the accuracy of the user's physical moves by 20%", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pikachu = game.scene.getPlayerPokemon()!; vi.spyOn(pikachu, "getAccuracyMultiplier"); @@ -60,7 +60,7 @@ describe("Abilities - Hustle", () => { }); it("does not affect non-physical moves", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pikachu = game.scene.getPlayerPokemon()!; const spatk = pikachu.stats[Stat.SPATK]; @@ -78,7 +78,7 @@ describe("Abilities - Hustle", () => { game.override.startingLevel(100); game.override.enemyLevel(30); - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pikachu = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/abilities/hyper_cutter.test.ts b/src/test/abilities/hyper_cutter.test.ts index ec947add939..e51fef6bd49 100644 --- a/src/test/abilities/hyper_cutter.test.ts +++ b/src/test/abilities/hyper_cutter.test.ts @@ -24,7 +24,7 @@ describe("Abilities - Hyper Cutter", () => { game = new GameManager(phaserGame); game.override .battleType("single") - .moveset([Moves.SAND_ATTACK, Moves.NOBLE_ROAR, Moves.DEFOG, Moves.OCTOLOCK]) + .moveset([ Moves.SAND_ATTACK, Moves.NOBLE_ROAR, Moves.DEFOG, Moves.OCTOLOCK ]) .ability(Abilities.BALL_FETCH) .enemySpecies(Species.SHUCKLE) .enemyAbility(Abilities.HYPER_CUTTER) @@ -46,11 +46,11 @@ describe("Abilities - Hyper Cutter", () => { await game.toNextTurn(); game.move.select(Moves.SAND_ATTACK); await game.toNextTurn(); - game.override.moveset([Moves.STRING_SHOT]); + game.override.moveset([ Moves.STRING_SHOT ]); game.move.select(Moves.STRING_SHOT); await game.toNextTurn(); expect(enemy.getStatStage(Stat.ATK)).toEqual(0); - [Stat.ACC, Stat.DEF, Stat.EVA, Stat.SPATK, Stat.SPDEF, Stat.SPD].forEach((stat: number) => expect(enemy.getStatStage(stat)).toBeLessThan(0)); + [ Stat.ACC, Stat.DEF, Stat.EVA, Stat.SPATK, Stat.SPDEF, Stat.SPD ].forEach((stat: number) => expect(enemy.getStatStage(stat)).toBeLessThan(0)); }); }); diff --git a/src/test/abilities/ice_face.test.ts b/src/test/abilities/ice_face.test.ts index fbc660c27c2..1c7f7bd6093 100644 --- a/src/test/abilities/ice_face.test.ts +++ b/src/test/abilities/ice_face.test.ts @@ -1,3 +1,4 @@ +import { BattlerIndex } from "#app/battle"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { MoveEndPhase } from "#app/phases/move-end-phase"; import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; @@ -32,11 +33,11 @@ describe("Abilities - Ice Face", () => { game.override.battleType("single"); game.override.enemySpecies(Species.EISCUE); game.override.enemyAbility(Abilities.ICE_FACE); - game.override.moveset([Moves.TACKLE, Moves.ICE_BEAM, Moves.TOXIC_THREAD, Moves.HAIL]); + game.override.moveset([ Moves.TACKLE, Moves.ICE_BEAM, Moves.TOXIC_THREAD, Moves.HAIL ]); }); it("takes no damage from physical move and transforms to Noice", async () => { - await game.startBattle([Species.HITMONLEE]); + await game.classicMode.startBattle([ Species.HITMONLEE ]); game.move.select(Moves.TACKLE); @@ -50,9 +51,9 @@ describe("Abilities - Ice Face", () => { }); it("takes no damage from the first hit of multihit physical move and transforms to Noice", async () => { - game.override.moveset([Moves.SURGING_STRIKES]); + game.override.moveset([ Moves.SURGING_STRIKES ]); game.override.enemyLevel(1); - await game.startBattle([Species.HITMONLEE]); + await game.classicMode.startBattle([ Species.HITMONLEE ]); game.move.select(Moves.SURGING_STRIKES); @@ -78,7 +79,7 @@ describe("Abilities - Ice Face", () => { }); it("takes damage from special moves", async () => { - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.ICE_BEAM); @@ -92,7 +93,7 @@ describe("Abilities - Ice Face", () => { }); it("takes effects from status moves", async () => { - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.TOXIC_THREAD); @@ -105,10 +106,10 @@ describe("Abilities - Ice Face", () => { }); it("transforms to Ice Face when Hail or Snow starts", async () => { - game.override.moveset([Moves.QUICK_ATTACK]); - game.override.enemyMoveset([Moves.HAIL, Moves.HAIL, Moves.HAIL, Moves.HAIL]); + game.override.moveset([ Moves.QUICK_ATTACK ]); + game.override.enemyMoveset([ Moves.HAIL, Moves.HAIL, Moves.HAIL, Moves.HAIL ]); - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.QUICK_ATTACK); @@ -127,10 +128,10 @@ describe("Abilities - Ice Face", () => { }); it("transforms to Ice Face when summoned on arena with active Snow or Hail", async () => { - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); - game.override.moveset([Moves.SNOWSCAPE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); + game.override.moveset([ Moves.SNOWSCAPE ]); - await game.startBattle([Species.EISCUE, Species.NINJASK]); + await game.classicMode.startBattle([ Species.EISCUE, Species.NINJASK ]); game.move.select(Moves.SNOWSCAPE); @@ -155,9 +156,9 @@ describe("Abilities - Ice Face", () => { it("will not revert to its Ice Face if there is already Hail when it changes into Noice", async () => { game.override.enemySpecies(Species.SHUCKLE); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); - await game.startBattle([Species.EISCUE]); + await game.classicMode.startBattle([ Species.EISCUE ]); game.move.select(Moves.HAIL); const eiscue = game.scene.getPlayerPokemon()!; @@ -174,9 +175,9 @@ describe("Abilities - Ice Face", () => { }); it("persists form change when switched out", async () => { - game.override.enemyMoveset([Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK]); + game.override.enemyMoveset([ Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK ]); - await game.startBattle([Species.EISCUE, Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.EISCUE, Species.MAGIKARP ]); game.move.select(Moves.ICE_BEAM); @@ -205,7 +206,7 @@ describe("Abilities - Ice Face", () => { [Species.EISCUE]: noiceForm, }); - await game.startBattle([Species.EISCUE]); + await game.classicMode.startBattle([ Species.EISCUE ]); const eiscue = game.scene.getPlayerPokemon()!; @@ -222,10 +223,23 @@ describe("Abilities - Ice Face", () => { expect(eiscue.getTag(BattlerTagType.ICE_FACE)).not.toBe(undefined); }); - it("cannot be suppressed", async () => { - game.override.moveset([Moves.GASTRO_ACID]); + it("doesn't trigger if user is behind a substitute", async () => { + game.override + .enemyMoveset(Moves.SUBSTITUTE) + .moveset(Moves.POWER_TRIP); + await game.classicMode.startBattle(); - await game.startBattle([Species.MAGIKARP]); + game.move.select(Moves.POWER_TRIP); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextTurn(); + + expect(game.scene.getEnemyPokemon()!.formIndex).toBe(icefaceForm); + }); + + it("cannot be suppressed", async () => { + game.override.moveset([ Moves.GASTRO_ACID ]); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.GASTRO_ACID); @@ -239,9 +253,9 @@ describe("Abilities - Ice Face", () => { }); it("cannot be swapped with another ability", async () => { - game.override.moveset([Moves.SKILL_SWAP]); + game.override.moveset([ Moves.SKILL_SWAP ]); - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.SKILL_SWAP); @@ -257,7 +271,7 @@ describe("Abilities - Ice Face", () => { it("cannot be copied", async () => { game.override.ability(Abilities.TRACE); - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.SIMPLE_BEAM); diff --git a/src/test/abilities/imposter.test.ts b/src/test/abilities/imposter.test.ts index 27673564aaa..3445b3b322c 100644 --- a/src/test/abilities/imposter.test.ts +++ b/src/test/abilities/imposter.test.ts @@ -36,9 +36,7 @@ describe("Abilities - Imposter", () => { }); it("should copy species, ability, gender, all stats except HP, all stat stages, moveset, and types of target", async () => { - await game.startBattle([ - Species.DITTO - ]); + await game.classicMode.startBattle([ Species.DITTO ]); game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); @@ -62,25 +60,24 @@ describe("Abilities - Imposter", () => { const playerMoveset = player.getMoveset(); const enemyMoveset = player.getMoveset(); + expect(playerMoveset.length).toBe(enemyMoveset.length); for (let i = 0; i < playerMoveset.length && i < enemyMoveset.length; i++) { - // TODO: Checks for 5 PP should be done here when that gets addressed expect(playerMoveset[i]?.moveId).toBe(enemyMoveset[i]?.moveId); } const playerTypes = player.getTypes(); const enemyTypes = enemy.getTypes(); + expect(playerTypes.length).toBe(enemyTypes.length); for (let i = 0; i < playerTypes.length && i < enemyTypes.length; i++) { expect(playerTypes[i]).toBe(enemyTypes[i]); } - }, 20000); + }); it("should copy in-battle overridden stats", async () => { - game.override.enemyMoveset([Moves.POWER_SPLIT]); + game.override.enemyMoveset([ Moves.POWER_SPLIT ]); - await game.startBattle([ - Species.DITTO - ]); + await game.classicMode.startBattle([ Species.DITTO ]); const player = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -97,4 +94,26 @@ describe("Abilities - Imposter", () => { expect(player.getStat(Stat.SPATK, false)).toBe(avgSpAtk); expect(enemy.getStat(Stat.SPATK, false)).toBe(avgSpAtk); }); + + it("should set each move's pp to a maximum of 5", async () => { + game.override.enemyMoveset([ Moves.SWORDS_DANCE, Moves.GROWL, Moves.SKETCH, Moves.RECOVER ]); + + await game.classicMode.startBattle([ Species.DITTO ]); + const player = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.TACKLE); + await game.phaseInterceptor.to(TurnEndPhase); + + player.getMoveset().forEach(move => { + // Should set correct maximum PP without touching `ppUp` + if (move) { + if (move.moveId === Moves.SKETCH) { + expect(move.getMovePp()).toBe(1); + } else { + expect(move.getMovePp()).toBe(5); + } + expect(move.ppUp).toBe(0); + } + }); + }); }); diff --git a/src/test/abilities/infiltrator.test.ts b/src/test/abilities/infiltrator.test.ts new file mode 100644 index 00000000000..01c5cef7796 --- /dev/null +++ b/src/test/abilities/infiltrator.test.ts @@ -0,0 +1,107 @@ +import { ArenaTagSide } from "#app/data/arena-tag"; +import { allMoves } from "#app/data/move"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Stat } from "#enums/stat"; +import { StatusEffect } from "#enums/status-effect"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Abilities - Infiltrator", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.TACKLE, Moves.WATER_GUN, Moves.SPORE, Moves.BABY_DOLL_EYES ]) + .ability(Abilities.INFILTRATOR) + .battleType("single") + .disableCrits() + .enemySpecies(Species.SNORLAX) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .startingLevel(100) + .enemyLevel(100); + }); + + it.each([ + { effectName: "Light Screen", tagType: ArenaTagType.LIGHT_SCREEN, move: Moves.WATER_GUN }, + { effectName: "Reflect", tagType: ArenaTagType.REFLECT, move: Moves.TACKLE }, + { effectName: "Aurora Veil", tagType: ArenaTagType.AURORA_VEIL, move: Moves.TACKLE } + ])("should bypass the target's $effectName", async ({ tagType, move }) => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + const preScreenDmg = enemy.getAttackDamage(player, allMoves[move]).damage; + + game.scene.arena.addTag(tagType, 1, Moves.NONE, enemy.id, ArenaTagSide.ENEMY, true); + + const postScreenDmg = enemy.getAttackDamage(player, allMoves[move]).damage; + + expect(postScreenDmg).toBe(preScreenDmg); + expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.INFILTRATOR); + }); + + it("should bypass the target's Safeguard", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + game.scene.arena.addTag(ArenaTagType.SAFEGUARD, 1, Moves.NONE, enemy.id, ArenaTagSide.ENEMY, true); + + game.move.select(Moves.SPORE); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemy.status?.effect).toBe(StatusEffect.SLEEP); + expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.INFILTRATOR); + }); + + // TODO: fix this interaction to pass this test + it.skip("should bypass the target's Mist", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + game.scene.arena.addTag(ArenaTagType.MIST, 1, Moves.NONE, enemy.id, ArenaTagSide.ENEMY, true); + + game.move.select(Moves.BABY_DOLL_EYES); + + await game.phaseInterceptor.to("MoveEndPhase"); + expect(enemy.getStatStage(Stat.ATK)).toBe(-1); + expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.INFILTRATOR); + }); + + it("should bypass the target's Substitute", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + enemy.addTag(BattlerTagType.SUBSTITUTE, 1, Moves.NONE, enemy.id); + + game.move.select(Moves.BABY_DOLL_EYES); + + await game.phaseInterceptor.to("MoveEndPhase"); + expect(enemy.getStatStage(Stat.ATK)).toBe(-1); + expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.INFILTRATOR); + }); +}); diff --git a/src/test/abilities/intimidate.test.ts b/src/test/abilities/intimidate.test.ts index d4c097022df..d5a37d06593 100644 --- a/src/test/abilities/intimidate.test.ts +++ b/src/test/abilities/intimidate.test.ts @@ -34,7 +34,7 @@ describe("Abilities - Intimidate", () => { }); it("should lower ATK stat stage by 1 of enemy Pokemon on entry and player switch", async () => { - await game.classicMode.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); + await game.classicMode.runToSummon([ Species.MIGHTYENA, Species.POOCHYENA ]); game.onNextPrompt( "CheckSwitchPhase", Mode.CONFIRM, @@ -66,7 +66,7 @@ describe("Abilities - Intimidate", () => { it("should lower ATK stat stage by 1 for every enemy Pokemon in a double battle on entry", async () => { game.override.battleType("double") .startingWave(3); - await game.classicMode.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); + await game.classicMode.runToSummon([ Species.MIGHTYENA, Species.POOCHYENA ]); game.onNextPrompt( "CheckSwitchPhase", Mode.CONFIRM, @@ -89,7 +89,7 @@ describe("Abilities - Intimidate", () => { it("should not activate again if there is no switch or new entry", async () => { game.override.startingWave(2); - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); await game.classicMode.startBattle([ Species.MIGHTYENA, Species.POOCHYENA ]); const playerPokemon = game.scene.getPlayerPokemon()!; @@ -106,8 +106,8 @@ describe("Abilities - Intimidate", () => { }, 20000); it("should lower ATK stat stage by 1 for every switch", async () => { - game.override.moveset([Moves.SPLASH]) - .enemyMoveset([Moves.VOLT_SWITCH]) + game.override.moveset([ Moves.SPLASH ]) + .enemyMoveset([ Moves.VOLT_SWITCH ]) .startingWave(5); await game.classicMode.startBattle([ Species.MIGHTYENA, Species.POOCHYENA ]); diff --git a/src/test/abilities/libero.test.ts b/src/test/abilities/libero.test.ts index f429d9ffc72..aac1cb16d97 100644 --- a/src/test/abilities/libero.test.ts +++ b/src/test/abilities/libero.test.ts @@ -13,7 +13,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; - describe("Abilities - Libero", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -34,15 +33,15 @@ describe("Abilities - Libero", () => { game.override.ability(Abilities.LIBERO); game.override.startingLevel(100); game.override.enemySpecies(Species.RATTATA); - game.override.enemyMoveset([Moves.ENDURE, Moves.ENDURE, Moves.ENDURE, Moves.ENDURE]); + game.override.enemyMoveset([ Moves.ENDURE, Moves.ENDURE, Moves.ENDURE, Moves.ENDURE ]); }); test( "ability applies and changes a pokemon's type", async () => { - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -57,9 +56,9 @@ describe("Abilities - Libero", () => { test.skip( "ability applies only once per switch in", async () => { - game.override.moveset([Moves.SPLASH, Moves.AGILITY]); + game.override.moveset([ Moves.SPLASH, Moves.AGILITY ]); - await game.startBattle([Species.MAGIKARP, Species.BULBASAUR]); + await game.startBattle([ Species.MAGIKARP, Species.BULBASAUR ]); let leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -96,9 +95,9 @@ describe("Abilities - Libero", () => { test( "ability applies correctly even if the pokemon's move has a variable type", async () => { - game.override.moveset([Moves.WEATHER_BALL]); + game.override.moveset([ Moves.WEATHER_BALL ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -118,10 +117,10 @@ describe("Abilities - Libero", () => { test( "ability applies correctly even if the type has changed by another ability", async () => { - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.passiveAbility(Abilities.REFRIGERATE); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -140,9 +139,9 @@ describe("Abilities - Libero", () => { test( "ability applies correctly even if the pokemon's move calls another move", async () => { - game.override.moveset([Moves.NATURE_POWER]); + game.override.moveset([ Moves.NATURE_POWER ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -158,9 +157,9 @@ describe("Abilities - Libero", () => { test( "ability applies correctly even if the pokemon's move is delayed / charging", async () => { - game.override.moveset([Moves.DIG]); + game.override.moveset([ Moves.DIG ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -175,10 +174,10 @@ describe("Abilities - Libero", () => { test( "ability applies correctly even if the pokemon's move misses", async () => { - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemyMoveset(Moves.SPLASH); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -196,10 +195,10 @@ describe("Abilities - Libero", () => { test( "ability applies correctly even if the pokemon's move is protected against", async () => { - game.override.moveset([Moves.TACKLE]); - game.override.enemyMoveset([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); + game.override.moveset([ Moves.TACKLE ]); + game.override.enemyMoveset([ Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -214,10 +213,10 @@ describe("Abilities - Libero", () => { test( "ability applies correctly even if the pokemon's move fails because of type immunity", async () => { - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemySpecies(Species.GASTLY); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -232,14 +231,14 @@ describe("Abilities - Libero", () => { test( "ability is not applied if pokemon's type is the same as the move's type", async () => { - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); - leadPokemon.summonData.types = [allMoves[Moves.SPLASH].type]; + leadPokemon.summonData.types = [ allMoves[Moves.SPLASH].type ]; game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); @@ -250,9 +249,9 @@ describe("Abilities - Libero", () => { test( "ability is not applied if pokemon is terastallized", async () => { - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -269,9 +268,9 @@ describe("Abilities - Libero", () => { test( "ability is not applied if pokemon uses struggle", async () => { - game.override.moveset([Moves.STRUGGLE]); + game.override.moveset([ Moves.STRUGGLE ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -286,9 +285,9 @@ describe("Abilities - Libero", () => { test( "ability is not applied if the pokemon's move fails", async () => { - game.override.moveset([Moves.BURN_UP]); + game.override.moveset([ Moves.BURN_UP ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -303,10 +302,10 @@ describe("Abilities - Libero", () => { test( "ability applies correctly even if the pokemon's Trick-or-Treat fails", async () => { - game.override.moveset([Moves.TRICK_OR_TREAT]); + game.override.moveset([ Moves.TRICK_OR_TREAT ]); game.override.enemySpecies(Species.GASTLY); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -321,9 +320,9 @@ describe("Abilities - Libero", () => { test( "ability applies correctly and the pokemon curses itself", async () => { - game.override.moveset([Moves.CURSE]); + game.override.moveset([ Moves.CURSE ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); diff --git a/src/test/abilities/magic_guard.test.ts b/src/test/abilities/magic_guard.test.ts index dd8b83f7601..8075eac66f2 100644 --- a/src/test/abilities/magic_guard.test.ts +++ b/src/test/abilities/magic_guard.test.ts @@ -30,7 +30,7 @@ describe("Abilities - Magic Guard", () => { /** Player Pokemon overrides */ game.override.ability(Abilities.MAGIC_GUARD); - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); game.override.startingLevel(100); /** Enemy Pokemon overrides */ @@ -47,7 +47,7 @@ describe("Abilities - Magic Guard", () => { async () => { game.override.weather(WeatherType.SANDSTORM); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -74,7 +74,7 @@ describe("Abilities - Magic Guard", () => { //Toxic keeps track of the turn counters -> important that Magic Guard keeps track of post-Toxic turns game.override.statusEffect(StatusEffect.POISON); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -95,10 +95,10 @@ describe("Abilities - Magic Guard", () => { it( "ability effect should not persist when the ability is replaced", async () => { - game.override.enemyMoveset([Moves.WORRY_SEED, Moves.WORRY_SEED, Moves.WORRY_SEED, Moves.WORRY_SEED]); + game.override.enemyMoveset([ Moves.WORRY_SEED, Moves.WORRY_SEED, Moves.WORRY_SEED, Moves.WORRY_SEED ]); game.override.statusEffect(StatusEffect.POISON); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -120,7 +120,7 @@ describe("Abilities - Magic Guard", () => { game.override.enemyStatusEffect(StatusEffect.BURN); game.override.enemyAbility(Abilities.MAGIC_GUARD); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.SPLASH); @@ -144,13 +144,13 @@ describe("Abilities - Magic Guard", () => { game.override.enemyStatusEffect(StatusEffect.TOXIC); game.override.enemyAbility(Abilities.MAGIC_GUARD); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.SPLASH); const enemyPokemon = game.scene.getEnemyPokemon()!; - const toxicStartCounter = enemyPokemon.status!.turnCount; + const toxicStartCounter = enemyPokemon.status!.toxicTurnCount; //should be 0 await game.phaseInterceptor.to(TurnEndPhase); @@ -162,7 +162,7 @@ describe("Abilities - Magic Guard", () => { * - The enemy Pokemon's hypothetical CatchRateMultiplier should be 1.5 */ expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); - expect(enemyPokemon.status!.turnCount).toBeGreaterThan(toxicStartCounter); + expect(enemyPokemon.status!.toxicTurnCount).toBeGreaterThan(toxicStartCounter); expect(getStatusEffectCatchRateMultiplier(enemyPokemon.status!.effect)).toBe(1.5); } ); @@ -173,7 +173,7 @@ describe("Abilities - Magic Guard", () => { const newTag = getArenaTag(ArenaTagType.SPIKES, 5, Moves.SPIKES, 0, 0, ArenaTagSide.BOTH)!; game.scene.arena.tags.push(newTag); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; game.move.select(Moves.SPLASH); @@ -199,7 +199,7 @@ describe("Abilities - Magic Guard", () => { game.scene.arena.tags.push(playerTag); game.scene.arena.tags.push(enemyTag); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; game.move.select(Moves.SPLASH); @@ -223,8 +223,8 @@ describe("Abilities - Magic Guard", () => { it("Magic Guard prevents against damage from volatile status effects", async () => { - await game.startBattle([Species.DUSKULL]); - game.override.moveset([Moves.CURSE]); + await game.startBattle([ Species.DUSKULL ]); + game.override.moveset([ Moves.CURSE ]); game.override.enemyAbility(Abilities.MAGIC_GUARD); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -248,8 +248,8 @@ describe("Abilities - Magic Guard", () => { ); it("Magic Guard prevents crash damage", async () => { - game.override.moveset([Moves.HIGH_JUMP_KICK]); - await game.startBattle([Species.MAGIKARP]); + game.override.moveset([ Moves.HIGH_JUMP_KICK ]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -267,8 +267,8 @@ describe("Abilities - Magic Guard", () => { ); it("Magic Guard prevents damage from recoil", async () => { - game.override.moveset([Moves.TAKE_DOWN]); - await game.startBattle([Species.MAGIKARP]); + game.override.moveset([ Moves.TAKE_DOWN ]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -285,8 +285,8 @@ describe("Abilities - Magic Guard", () => { ); it("Magic Guard does not prevent damage from Struggle's recoil", async () => { - game.override.moveset([Moves.STRUGGLE]); - await game.startBattle([Species.MAGIKARP]); + game.override.moveset([ Moves.STRUGGLE ]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -304,8 +304,8 @@ describe("Abilities - Magic Guard", () => { //This tests different move attributes than the recoil tests above it("Magic Guard prevents self-damage from attacking moves", async () => { - game.override.moveset([Moves.STEEL_BEAM]); - await game.startBattle([Species.MAGIKARP]); + game.override.moveset([ Moves.STEEL_BEAM ]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -332,8 +332,8 @@ describe("Abilities - Magic Guard", () => { */ it("Magic Guard does not prevent self-damage from non-attacking moves", async () => { - game.override.moveset([Moves.BELLY_DRUM]); - await game.startBattle([Species.MAGIKARP]); + game.override.moveset([ Moves.BELLY_DRUM ]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -353,10 +353,10 @@ describe("Abilities - Magic Guard", () => { //Tests the ability Bad Dreams game.override.statusEffect(StatusEffect.SLEEP); //enemy pokemon is given Spore just in case player pokemon somehow awakens during test - game.override.enemyMoveset([Moves.SPORE, Moves.SPORE, Moves.SPORE, Moves.SPORE]); + game.override.enemyMoveset([ Moves.SPORE, Moves.SPORE, Moves.SPORE, Moves.SPORE ]); game.override.enemyAbility(Abilities.BAD_DREAMS); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -376,10 +376,10 @@ describe("Abilities - Magic Guard", () => { it("Magic Guard prevents damage from abilities with PostFaintContactDamageAbAttr", async () => { //Tests the abilities Innards Out/Aftermath - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemyAbility(Abilities.AFTERMATH); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -401,10 +401,10 @@ describe("Abilities - Magic Guard", () => { it("Magic Guard prevents damage from abilities with PostDefendContactDamageAbAttr", async () => { //Tests the abilities Iron Barbs/Rough Skin - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemyAbility(Abilities.IRON_BARBS); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -425,10 +425,10 @@ describe("Abilities - Magic Guard", () => { it("Magic Guard prevents damage from abilities with ReverseDrainAbAttr", async () => { //Tests the ability Liquid Ooze - game.override.moveset([Moves.ABSORB]); + game.override.moveset([ Moves.ABSORB ]); game.override.enemyAbility(Abilities.LIQUID_OOZE); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -452,7 +452,7 @@ describe("Abilities - Magic Guard", () => { game.override.passiveAbility(Abilities.SOLAR_POWER); game.override.weather(WeatherType.SUNNY); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/abilities/mimicry.test.ts b/src/test/abilities/mimicry.test.ts new file mode 100644 index 00000000000..4e62ddc0b76 --- /dev/null +++ b/src/test/abilities/mimicry.test.ts @@ -0,0 +1,91 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Type } from "#app/data/type"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Abilities - Mimicry", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.SPLASH ]) + .ability(Abilities.MIMICRY) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyMoveset(Moves.SPLASH); + }); + + it("Mimicry activates after the Pokémon with Mimicry is switched in while terrain is present, or whenever there is a change in terrain", async () => { + game.override.enemyAbility(Abilities.MISTY_SURGE); + await game.classicMode.startBattle([ Species.FEEBAS, Species.ABRA ]); + + const [ playerPokemon1, playerPokemon2 ] = game.scene.getParty(); + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(playerPokemon1.getTypes().includes(Type.FAIRY)).toBe(true); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + expect(playerPokemon2.getTypes().includes(Type.FAIRY)).toBe(true); + }); + + it("Pokemon should revert back to its original, root type once terrain ends", async () => { + game.override + .moveset([ Moves.SPLASH, Moves.TRANSFORM ]) + .enemyAbility(Abilities.MIMICRY) + .enemyMoveset([ Moves.SPLASH, Moves.PSYCHIC_TERRAIN ]); + await game.classicMode.startBattle([ Species.REGIELEKI ]); + + const playerPokemon = game.scene.getPlayerPokemon(); + game.move.select(Moves.TRANSFORM); + await game.forceEnemyMove(Moves.PSYCHIC_TERRAIN); + await game.toNextTurn(); + expect(playerPokemon?.getTypes().includes(Type.PSYCHIC)).toBe(true); + + if (game.scene.arena.terrain) { + game.scene.arena.terrain.turnsLeft = 1; + } + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + expect(playerPokemon?.getTypes().includes(Type.ELECTRIC)).toBe(true); + }); + + it("If the Pokemon is under the effect of a type-adding move and an equivalent terrain activates, the move's effect disappears", async () => { + game.override + .enemyMoveset([ Moves.FORESTS_CURSE, Moves.GRASSY_TERRAIN ]); + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const playerPokemon = game.scene.getPlayerPokemon(); + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.FORESTS_CURSE); + await game.toNextTurn(); + + expect(playerPokemon?.summonData.addedType).toBe(Type.GRASS); + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.GRASSY_TERRAIN); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(playerPokemon?.summonData.addedType).toBeNull(); + expect(playerPokemon?.getTypes().includes(Type.GRASS)).toBe(true); + }); +}); diff --git a/src/test/abilities/mycelium_might.test.ts b/src/test/abilities/mycelium_might.test.ts index d8947935880..0c8e7b5a703 100644 --- a/src/test/abilities/mycelium_might.test.ts +++ b/src/test/abilities/mycelium_might.test.ts @@ -28,9 +28,9 @@ describe("Abilities - Mycelium Might", () => { game.override.disableCrits(); game.override.enemySpecies(Species.SHUCKLE); game.override.enemyAbility(Abilities.CLEAR_BODY); - game.override.enemyMoveset([Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK]); + game.override.enemyMoveset([ Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK ]); game.override.ability(Abilities.MYCELIUM_MIGHT); - game.override.moveset([Moves.QUICK_ATTACK, Moves.BABY_DOLL_EYES]); + game.override.moveset([ Moves.QUICK_ATTACK, Moves.BABY_DOLL_EYES ]); }); /** @@ -41,7 +41,7 @@ describe("Abilities - Mycelium Might", () => { **/ it("will move last in its priority bracket and ignore protective abilities", async () => { - await game.startBattle([Species.REGIELEKI]); + await game.startBattle([ Species.REGIELEKI ]); const enemyPokemon = game.scene.getEnemyPokemon(); const playerIndex = game.scene.getPlayerPokemon()?.getBattlerIndex(); @@ -55,8 +55,8 @@ describe("Abilities - Mycelium Might", () => { const commandOrder = phase.getCommandOrder(); // The opponent Pokemon (without Mycelium Might) goes first despite having lower speed than the player Pokemon. // The player Pokemon (with Mycelium Might) goes last despite having higher speed than the opponent. - expect(speedOrder).toEqual([playerIndex, enemyIndex]); - expect(commandOrder).toEqual([enemyIndex, playerIndex]); + expect(speedOrder).toEqual([ playerIndex, enemyIndex ]); + expect(commandOrder).toEqual([ enemyIndex, playerIndex ]); await game.phaseInterceptor.to(TurnEndPhase); // Despite the opponent's ability (Clear Body), its ATK stat stage is still reduced. @@ -64,8 +64,8 @@ describe("Abilities - Mycelium Might", () => { }, 20000); it("will still go first if a status move that is in a higher priority bracket than the opponent's move is used", async () => { - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); - await game.startBattle([Species.REGIELEKI]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); + await game.startBattle([ Species.REGIELEKI ]); const enemyPokemon = game.scene.getEnemyPokemon(); const playerIndex = game.scene.getPlayerPokemon()?.getBattlerIndex(); @@ -79,15 +79,15 @@ describe("Abilities - Mycelium Might", () => { const commandOrder = phase.getCommandOrder(); // The player Pokemon (with M.M.) goes first because its move is still within a higher priority bracket than its opponent. // The enemy Pokemon goes second because its move is in a lower priority bracket. - expect(speedOrder).toEqual([playerIndex, enemyIndex]); - expect(commandOrder).toEqual([playerIndex, enemyIndex]); + expect(speedOrder).toEqual([ playerIndex, enemyIndex ]); + expect(commandOrder).toEqual([ playerIndex, enemyIndex ]); await game.phaseInterceptor.to(TurnEndPhase); // Despite the opponent's ability (Clear Body), its ATK stat stage is still reduced. expect(enemyPokemon?.getStatStage(Stat.ATK)).toBe(-1); }, 20000); it("will not affect non-status moves", async () => { - await game.startBattle([Species.REGIELEKI]); + await game.startBattle([ Species.REGIELEKI ]); const playerIndex = game.scene.getPlayerPokemon()!.getBattlerIndex(); const enemyIndex = game.scene.getEnemyPokemon()!.getBattlerIndex(); @@ -101,7 +101,7 @@ describe("Abilities - Mycelium Might", () => { // The player Pokemon (with M.M.) goes first because it has a higher speed and did not use a status move. // The enemy Pokemon (without M.M.) goes second because its speed is lower. // This means that the commandOrder should be identical to the speedOrder - expect(speedOrder).toEqual([playerIndex, enemyIndex]); - expect(commandOrder).toEqual([playerIndex, enemyIndex]); + expect(speedOrder).toEqual([ playerIndex, enemyIndex ]); + expect(commandOrder).toEqual([ playerIndex, enemyIndex ]); }, 20000); }); diff --git a/src/test/abilities/parental_bond.test.ts b/src/test/abilities/parental_bond.test.ts index 22c9d8028be..993a5eb8344 100644 --- a/src/test/abilities/parental_bond.test.ts +++ b/src/test/abilities/parental_bond.test.ts @@ -11,7 +11,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Abilities - Parental Bond", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -41,9 +40,9 @@ describe("Abilities - Parental Bond", () => { it( "should add second strike to attack move", async () => { - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -68,10 +67,10 @@ describe("Abilities - Parental Bond", () => { it( "should apply secondary effects to both strikes", async () => { - game.override.moveset([Moves.POWER_UP_PUNCH]); + game.override.moveset([ Moves.POWER_UP_PUNCH ]); game.override.enemySpecies(Species.AMOONGUSS); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -87,9 +86,9 @@ describe("Abilities - Parental Bond", () => { it( "should not apply to Status moves", async () => { - game.override.moveset([Moves.BABY_DOLL_EYES]); + game.override.moveset([ Moves.BABY_DOLL_EYES ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -104,9 +103,9 @@ describe("Abilities - Parental Bond", () => { it( "should not apply to multi-hit moves", async () => { - game.override.moveset([Moves.DOUBLE_HIT]); + game.override.moveset([ Moves.DOUBLE_HIT ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -122,9 +121,9 @@ describe("Abilities - Parental Bond", () => { it( "should not apply to self-sacrifice moves", async () => { - game.override.moveset([Moves.SELF_DESTRUCT]); + game.override.moveset([ Moves.SELF_DESTRUCT ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -139,9 +138,9 @@ describe("Abilities - Parental Bond", () => { it( "should not apply to Rollout", async () => { - game.override.moveset([Moves.ROLLOUT]); + game.override.moveset([ Moves.ROLLOUT ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -157,9 +156,9 @@ describe("Abilities - Parental Bond", () => { it( "should not apply multiplier to fixed-damage moves", async () => { - game.override.moveset([Moves.DRAGON_RAGE]); + game.override.moveset([ Moves.DRAGON_RAGE ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -173,10 +172,10 @@ describe("Abilities - Parental Bond", () => { it( "should not apply multiplier to counter moves", async () => { - game.override.moveset([Moves.COUNTER]); - game.override.enemyMoveset([Moves.TACKLE]); + game.override.moveset([ Moves.COUNTER ]); + game.override.enemyMoveset([ Moves.TACKLE ]); - await game.classicMode.startBattle([Species.SHUCKLE]); + await game.classicMode.startBattle([ Species.SHUCKLE ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -196,10 +195,10 @@ describe("Abilities - Parental Bond", () => { "should not apply to multi-target moves", async () => { game.override.battleType("double"); - game.override.moveset([Moves.EARTHQUAKE]); + game.override.moveset([ Moves.EARTHQUAKE ]); game.override.passiveAbility(Abilities.LEVITATE); - await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); + await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); const playerPokemon = game.scene.getPlayerField(); @@ -215,9 +214,9 @@ describe("Abilities - Parental Bond", () => { it( "should apply to multi-target moves when hitting only one target", async () => { - game.override.moveset([Moves.EARTHQUAKE]); + game.override.moveset([ Moves.EARTHQUAKE ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -231,9 +230,9 @@ describe("Abilities - Parental Bond", () => { it( "should only trigger post-target move effects once", async () => { - game.override.moveset([Moves.MIND_BLOWN]); + game.override.moveset([ Moves.MIND_BLOWN ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -253,9 +252,9 @@ describe("Abilities - Parental Bond", () => { it( "Burn Up only removes type after the second strike", async () => { - game.override.moveset([Moves.BURN_UP]); + game.override.moveset([ Moves.BURN_UP ]); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -277,10 +276,10 @@ describe("Abilities - Parental Bond", () => { it( "Moves boosted by this ability and Multi-Lens should strike 4 times", async () => { - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -295,10 +294,10 @@ describe("Abilities - Parental Bond", () => { it( "Super Fang boosted by this ability and Multi-Lens should strike twice", async () => { - game.override.moveset([Moves.SUPER_FANG]); + game.override.moveset([ Moves.SUPER_FANG ]); game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -319,10 +318,10 @@ describe("Abilities - Parental Bond", () => { it( "Seismic Toss boosted by this ability and Multi-Lens should strike twice", async () => { - game.override.moveset([Moves.SEISMIC_TOSS]); + game.override.moveset([ Moves.SEISMIC_TOSS ]); game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -345,9 +344,9 @@ describe("Abilities - Parental Bond", () => { it( "Hyper Beam boosted by this ability should strike twice, then recharge", async () => { - game.override.moveset([Moves.HYPER_BEAM]); + game.override.moveset([ Moves.HYPER_BEAM ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -368,9 +367,9 @@ describe("Abilities - Parental Bond", () => { it( "Anchor Shot boosted by this ability should only trap the target after the second hit", async () => { - game.override.moveset([Moves.ANCHOR_SHOT]); + game.override.moveset([ Moves.ANCHOR_SHOT ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -395,9 +394,9 @@ describe("Abilities - Parental Bond", () => { it( "Smack Down boosted by this ability should only ground the target after the second hit", async () => { - game.override.moveset([Moves.SMACK_DOWN]); + game.override.moveset([ Moves.SMACK_DOWN ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -419,9 +418,9 @@ describe("Abilities - Parental Bond", () => { it( "U-turn boosted by this ability should strike twice before forcing a switch", async () => { - game.override.moveset([Moves.U_TURN]); + game.override.moveset([ Moves.U_TURN ]); - await game.classicMode.startBattle([Species.MAGIKARP, Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.MAGIKARP, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -439,9 +438,9 @@ describe("Abilities - Parental Bond", () => { it( "Wake-Up Slap boosted by this ability should only wake up the target after the second hit", async () => { - game.override.moveset([Moves.WAKE_UP_SLAP]).enemyStatusEffect(StatusEffect.SLEEP); + game.override.moveset([ Moves.WAKE_UP_SLAP ]).enemyStatusEffect(StatusEffect.SLEEP); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -463,10 +462,10 @@ describe("Abilities - Parental Bond", () => { it( "should not cause user to hit into King's Shield more than once", async () => { - game.override.moveset([Moves.TACKLE]); - game.override.enemyMoveset([Moves.KINGS_SHIELD]); + game.override.moveset([ Moves.TACKLE ]); + game.override.enemyMoveset([ Moves.KINGS_SHIELD ]); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -481,10 +480,10 @@ describe("Abilities - Parental Bond", () => { it( "should not cause user to hit into Storm Drain more than once", async () => { - game.override.moveset([Moves.WATER_GUN]); + game.override.moveset([ Moves.WATER_GUN ]); game.override.enemyAbility(Abilities.STORM_DRAIN); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -500,11 +499,11 @@ describe("Abilities - Parental Bond", () => { "should not apply to multi-target moves with Multi-Lens", async () => { game.override.battleType("double"); - game.override.moveset([Moves.EARTHQUAKE, Moves.SPLASH]); + game.override.moveset([ Moves.EARTHQUAKE, Moves.SPLASH ]); game.override.passiveAbility(Abilities.LEVITATE); game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); + await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); const enemyPokemon = game.scene.getEnemyField(); diff --git a/src/test/abilities/pastel_veil.test.ts b/src/test/abilities/pastel_veil.test.ts index 31490aab143..660ff2616e9 100644 --- a/src/test/abilities/pastel_veil.test.ts +++ b/src/test/abilities/pastel_veil.test.ts @@ -27,14 +27,14 @@ describe("Abilities - Pastel Veil", () => { game = new GameManager(phaserGame); game.override .battleType("double") - .moveset([Moves.TOXIC_THREAD, Moves.SPLASH]) + .moveset([ Moves.TOXIC_THREAD, Moves.SPLASH ]) .enemyAbility(Abilities.BALL_FETCH) .enemySpecies(Species.SUNKERN) .enemyMoveset(Moves.SPLASH); }); it("prevents the user and its allies from being afflicted by poison", async () => { - await game.startBattle([Species.MAGIKARP, Species.GALAR_PONYTA]); + await game.startBattle([ Species.MAGIKARP, Species.GALAR_PONYTA ]); const ponyta = game.scene.getPlayerField()[1]; const magikarp = game.scene.getPlayerField()[0]; ponyta.abilityIndex = 1; @@ -50,7 +50,7 @@ describe("Abilities - Pastel Veil", () => { }); it("it heals the poisoned status condition of allies if user is sent out into battle", async () => { - await game.startBattle([Species.MAGIKARP, Species.FEEBAS, Species.GALAR_PONYTA]); + await game.startBattle([ Species.MAGIKARP, Species.FEEBAS, Species.GALAR_PONYTA ]); const ponyta = game.scene.getParty()[2]; const magikarp = game.scene.getPlayerField()[0]; ponyta.abilityIndex = 1; diff --git a/src/test/abilities/power_construct.test.ts b/src/test/abilities/power_construct.test.ts index 94cee82fb4a..1a9e7d4818a 100644 --- a/src/test/abilities/power_construct.test.ts +++ b/src/test/abilities/power_construct.test.ts @@ -8,7 +8,6 @@ import GameManager from "#test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Abilities - POWER CONSTRUCT", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -28,12 +27,12 @@ describe("Abilities - POWER CONSTRUCT", () => { const moveToUse = Moves.SPLASH; game.override.battleType("single"); game.override.ability(Abilities.POWER_CONSTRUCT); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); test( - "check if fainted pokemon switches to base form on arena reset", + "check if fainted 50% Power Construct Pokemon switches to base form on arena reset", async () => { const baseForm = 2, completeForm = 4; @@ -42,7 +41,37 @@ describe("Abilities - POWER CONSTRUCT", () => { [Species.ZYGARDE]: completeForm, }); - await game.startBattle([Species.MAGIKARP, Species.ZYGARDE]); + await game.classicMode.startBattle([ Species.MAGIKARP, Species.ZYGARDE ]); + + const zygarde = game.scene.getParty().find((p) => p.species.speciesId === Species.ZYGARDE); + expect(zygarde).not.toBe(undefined); + expect(zygarde!.formIndex).toBe(completeForm); + + zygarde!.hp = 0; + zygarde!.status = new Status(StatusEffect.FAINT); + expect(zygarde!.isFainted()).toBe(true); + + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.phaseInterceptor.to(TurnEndPhase); + game.doSelectModifier(); + await game.phaseInterceptor.to(QuietFormChangePhase); + + expect(zygarde!.formIndex).toBe(baseForm); + }, + ); + + test( + "check if fainted 10% Power Construct Pokemon switches to base form on arena reset", + async () => { + const baseForm = 3, + completeForm = 5; + game.override.startingWave(4); + game.override.starterForms({ + [Species.ZYGARDE]: completeForm, + }); + + await game.classicMode.startBattle([ Species.MAGIKARP, Species.ZYGARDE ]); const zygarde = game.scene.getParty().find((p) => p.species.speciesId === Species.ZYGARDE); expect(zygarde).not.toBe(undefined); diff --git a/src/test/abilities/power_spot.test.ts b/src/test/abilities/power_spot.test.ts index 6d349a1a3f9..a566c2277c3 100644 --- a/src/test/abilities/power_spot.test.ts +++ b/src/test/abilities/power_spot.test.ts @@ -27,7 +27,7 @@ describe("Abilities - Power Spot", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("double"); - game.override.moveset([Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM]); + game.override.moveset([ Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM ]); game.override.enemyMoveset(Moves.SPLASH); game.override.enemySpecies(Species.SHUCKLE); game.override.enemyAbility(Abilities.BALL_FETCH); @@ -39,7 +39,7 @@ describe("Abilities - Power Spot", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.REGIELEKI, Species.STONJOURNER]); + await game.startBattle([ Species.REGIELEKI, Species.STONJOURNER ]); game.move.select(Moves.DAZZLING_GLEAM); game.move.select(Moves.SPLASH, 1); await game.phaseInterceptor.to(MoveEffectPhase); @@ -53,7 +53,7 @@ describe("Abilities - Power Spot", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.REGIELEKI, Species.STONJOURNER]); + await game.startBattle([ Species.REGIELEKI, Species.STONJOURNER ]); game.move.select(Moves.BREAKING_SWIPE); game.move.select(Moves.SPLASH, 1); await game.phaseInterceptor.to(MoveEffectPhase); @@ -67,7 +67,7 @@ describe("Abilities - Power Spot", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.STONJOURNER, Species.REGIELEKI]); + await game.startBattle([ Species.STONJOURNER, Species.REGIELEKI ]); game.move.select(Moves.BREAKING_SWIPE); game.move.select(Moves.SPLASH, 1); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/abilities/protean.test.ts b/src/test/abilities/protean.test.ts index 8479a293722..5f86ec4c6e6 100644 --- a/src/test/abilities/protean.test.ts +++ b/src/test/abilities/protean.test.ts @@ -13,7 +13,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; - describe("Abilities - Protean", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -34,15 +33,15 @@ describe("Abilities - Protean", () => { game.override.ability(Abilities.PROTEAN); game.override.startingLevel(100); game.override.enemySpecies(Species.RATTATA); - game.override.enemyMoveset([Moves.ENDURE, Moves.ENDURE, Moves.ENDURE, Moves.ENDURE]); + game.override.enemyMoveset([ Moves.ENDURE, Moves.ENDURE, Moves.ENDURE, Moves.ENDURE ]); }); test( "ability applies and changes a pokemon's type", async () => { - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -57,9 +56,9 @@ describe("Abilities - Protean", () => { test.skip( "ability applies only once per switch in", async () => { - game.override.moveset([Moves.SPLASH, Moves.AGILITY]); + game.override.moveset([ Moves.SPLASH, Moves.AGILITY ]); - await game.startBattle([Species.MAGIKARP, Species.BULBASAUR]); + await game.startBattle([ Species.MAGIKARP, Species.BULBASAUR ]); let leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -96,9 +95,9 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move has a variable type", async () => { - game.override.moveset([Moves.WEATHER_BALL]); + game.override.moveset([ Moves.WEATHER_BALL ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -118,10 +117,10 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the type has changed by another ability", async () => { - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.passiveAbility(Abilities.REFRIGERATE); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -140,9 +139,9 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move calls another move", async () => { - game.override.moveset([Moves.NATURE_POWER]); + game.override.moveset([ Moves.NATURE_POWER ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -158,9 +157,9 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move is delayed / charging", async () => { - game.override.moveset([Moves.DIG]); + game.override.moveset([ Moves.DIG ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -175,10 +174,10 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move misses", async () => { - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemyMoveset(Moves.SPLASH); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -196,10 +195,10 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move is protected against", async () => { - game.override.moveset([Moves.TACKLE]); - game.override.enemyMoveset([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); + game.override.moveset([ Moves.TACKLE ]); + game.override.enemyMoveset([ Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -214,10 +213,10 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move fails because of type immunity", async () => { - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemySpecies(Species.GASTLY); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -232,14 +231,14 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon's type is the same as the move's type", async () => { - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); - leadPokemon.summonData.types = [allMoves[Moves.SPLASH].type]; + leadPokemon.summonData.types = [ allMoves[Moves.SPLASH].type ]; game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); @@ -250,9 +249,9 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon is terastallized", async () => { - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -269,9 +268,9 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon uses struggle", async () => { - game.override.moveset([Moves.STRUGGLE]); + game.override.moveset([ Moves.STRUGGLE ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -286,9 +285,9 @@ describe("Abilities - Protean", () => { test( "ability is not applied if the pokemon's move fails", async () => { - game.override.moveset([Moves.BURN_UP]); + game.override.moveset([ Moves.BURN_UP ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -303,10 +302,10 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's Trick-or-Treat fails", async () => { - game.override.moveset([Moves.TRICK_OR_TREAT]); + game.override.moveset([ Moves.TRICK_OR_TREAT ]); game.override.enemySpecies(Species.GASTLY); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); @@ -321,9 +320,9 @@ describe("Abilities - Protean", () => { test( "ability applies correctly and the pokemon curses itself", async () => { - game.override.moveset([Moves.CURSE]); + game.override.moveset([ Moves.CURSE ]); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); diff --git a/src/test/abilities/quick_draw.test.ts b/src/test/abilities/quick_draw.test.ts index dbed6c822c4..4979152f4d6 100644 --- a/src/test/abilities/quick_draw.test.ts +++ b/src/test/abilities/quick_draw.test.ts @@ -27,12 +27,12 @@ describe("Abilities - Quick Draw", () => { game.override.starterSpecies(Species.MAGIKARP); game.override.ability(Abilities.QUICK_DRAW); - game.override.moveset([Moves.TACKLE, Moves.TAIL_WHIP]); + game.override.moveset([ Moves.TACKLE, Moves.TAIL_WHIP ]); game.override.enemyLevel(100); game.override.enemySpecies(Species.MAGIKARP); game.override.enemyAbility(Abilities.BALL_FETCH); - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); vi.spyOn(allAbilities[Abilities.QUICK_DRAW].getAttrs(BypassSpeedChanceAbAttr)[0], "chance", "get").mockReturnValue(100); }); @@ -75,7 +75,7 @@ describe("Abilities - Quick Draw", () => { ); test("does not increase priority", async () => { - game.override.enemyMoveset([Moves.EXTREME_SPEED]); + game.override.enemyMoveset([ Moves.EXTREME_SPEED ]); await game.startBattle(); diff --git a/src/test/abilities/sand_spit.test.ts b/src/test/abilities/sand_spit.test.ts index add13ede296..1c21cff3c14 100644 --- a/src/test/abilities/sand_spit.test.ts +++ b/src/test/abilities/sand_spit.test.ts @@ -31,11 +31,11 @@ describe("Abilities - Sand Spit", () => { game.override.starterSpecies(Species.SILICOBRA); game.override.ability(Abilities.SAND_SPIT); - game.override.moveset([Moves.SPLASH, Moves.COIL]); + game.override.moveset([ Moves.SPLASH, Moves.COIL ]); }); it("should trigger when hit with damaging move", async () => { - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); await game.startBattle(); game.move.select(Moves.SPLASH); @@ -45,7 +45,7 @@ describe("Abilities - Sand Spit", () => { }, 20000); it("should not trigger when targetted with status moves", async () => { - game.override.enemyMoveset([Moves.GROWL]); + game.override.enemyMoveset([ Moves.GROWL ]); await game.startBattle(); game.move.select(Moves.COIL); diff --git a/src/test/abilities/sand_veil.test.ts b/src/test/abilities/sand_veil.test.ts index 201d8d89600..c62357f17af 100644 --- a/src/test/abilities/sand_veil.test.ts +++ b/src/test/abilities/sand_veil.test.ts @@ -12,7 +12,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; - describe("Abilities - Sand Veil", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -29,10 +28,10 @@ describe("Abilities - Sand Veil", () => { beforeEach(() => { game = new GameManager(phaserGame); - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); game.override.enemySpecies(Species.MEOWSCARADA); game.override.enemyAbility(Abilities.INSOMNIA); - game.override.enemyMoveset([Moves.TWISTER, Moves.TWISTER, Moves.TWISTER, Moves.TWISTER]); + game.override.enemyMoveset([ Moves.TWISTER, Moves.TWISTER, Moves.TWISTER, Moves.TWISTER ]); game.override.startingLevel(100); game.override.enemyLevel(100); game.override @@ -43,7 +42,7 @@ describe("Abilities - Sand Veil", () => { test( "ability should increase the evasiveness of the source", async () => { - await game.startBattle([Species.SNORLAX, Species.BLISSEY]); + await game.startBattle([ Species.SNORLAX, Species.BLISSEY ]); const leadPokemon = game.scene.getPlayerField(); diff --git a/src/test/abilities/sap_sipper.test.ts b/src/test/abilities/sap_sipper.test.ts index b73bc3d9e27..a4ce0c1b8f6 100644 --- a/src/test/abilities/sap_sipper.test.ts +++ b/src/test/abilities/sap_sipper.test.ts @@ -148,8 +148,8 @@ describe("Abilities - Sap Sipper", () => { const moveToUse = Moves.METRONOME; const enemyAbility = Abilities.SAP_SIPPER; - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE ]); game.override.enemySpecies(Species.RATTATA); game.override.enemyAbility(enemyAbility); diff --git a/src/test/abilities/schooling.test.ts b/src/test/abilities/schooling.test.ts index 4c5a66a41b7..aacc7bbd4c2 100644 --- a/src/test/abilities/schooling.test.ts +++ b/src/test/abilities/schooling.test.ts @@ -8,7 +8,6 @@ import GameManager from "#test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Abilities - SCHOOLING", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -28,8 +27,8 @@ describe("Abilities - SCHOOLING", () => { const moveToUse = Moves.SPLASH; game.override.battleType("single"); game.override.ability(Abilities.SCHOOLING); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); test( @@ -42,7 +41,7 @@ describe("Abilities - SCHOOLING", () => { [Species.WISHIWASHI]: schoolForm, }); - await game.startBattle([Species.MAGIKARP, Species.WISHIWASHI]); + await game.startBattle([ Species.MAGIKARP, Species.WISHIWASHI ]); const wishiwashi = game.scene.getParty().find((p) => p.species.speciesId === Species.WISHIWASHI)!; expect(wishiwashi).not.toBe(undefined); diff --git a/src/test/abilities/screen_cleaner.test.ts b/src/test/abilities/screen_cleaner.test.ts index 3c0d12a06ea..c036aa90a77 100644 --- a/src/test/abilities/screen_cleaner.test.ts +++ b/src/test/abilities/screen_cleaner.test.ts @@ -30,10 +30,10 @@ describe("Abilities - Screen Cleaner", () => { }); it("removes Aurora Veil", async () => { - game.override.moveset([Moves.HAIL]); - game.override.enemyMoveset([Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL]); + game.override.moveset([ Moves.HAIL ]); + game.override.enemyMoveset([ Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL ]); - await game.startBattle([Species.MAGIKARP, Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP, Species.MAGIKARP ]); game.move.select(Moves.HAIL); await game.phaseInterceptor.to(TurnEndPhase); @@ -48,9 +48,9 @@ describe("Abilities - Screen Cleaner", () => { }); it("removes Light Screen", async () => { - game.override.enemyMoveset([Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN]); + game.override.enemyMoveset([ Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN ]); - await game.startBattle([Species.MAGIKARP, Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP, Species.MAGIKARP ]); game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); @@ -65,9 +65,9 @@ describe("Abilities - Screen Cleaner", () => { }); it("removes Reflect", async () => { - game.override.enemyMoveset([Moves.REFLECT, Moves.REFLECT, Moves.REFLECT, Moves.REFLECT]); + game.override.enemyMoveset([ Moves.REFLECT, Moves.REFLECT, Moves.REFLECT, Moves.REFLECT ]); - await game.startBattle([Species.MAGIKARP, Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP, Species.MAGIKARP ]); game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/abilities/serene_grace.test.ts b/src/test/abilities/serene_grace.test.ts index e06288b9de9..3155594c81d 100644 --- a/src/test/abilities/serene_grace.test.ts +++ b/src/test/abilities/serene_grace.test.ts @@ -27,12 +27,12 @@ describe("Abilities - Serene Grace", () => { beforeEach(() => { game = new GameManager(phaserGame); - const movesToUse = [Moves.AIR_SLASH, Moves.TACKLE]; + const movesToUse = [ Moves.AIR_SLASH, Moves.TACKLE ]; game.override.battleType("single"); game.override.enemySpecies(Species.ONIX); game.override.startingLevel(100); game.override.moveset(movesToUse); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); it("Move chance without Serene Grace", async () => { @@ -47,7 +47,7 @@ describe("Abilities - Serene Grace", () => { game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); // Check chance of Air Slash without Serene Grace @@ -74,7 +74,7 @@ describe("Abilities - Serene Grace", () => { game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); // Check chance of Air Slash with Serene Grace diff --git a/src/test/abilities/sheer_force.test.ts b/src/test/abilities/sheer_force.test.ts index 69b47e1eaae..a2600476d6d 100644 --- a/src/test/abilities/sheer_force.test.ts +++ b/src/test/abilities/sheer_force.test.ts @@ -9,6 +9,7 @@ import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { allMoves } from "#app/data/move"; describe("Abilities - Sheer Force", () => { @@ -27,12 +28,12 @@ describe("Abilities - Sheer Force", () => { beforeEach(() => { game = new GameManager(phaserGame); - const movesToUse = [Moves.AIR_SLASH, Moves.BIND, Moves.CRUSH_CLAW, Moves.TACKLE]; + const movesToUse = [ Moves.AIR_SLASH, Moves.BIND, Moves.CRUSH_CLAW, Moves.TACKLE ]; game.override.battleType("single"); game.override.enemySpecies(Species.ONIX); game.override.startingLevel(100); game.override.moveset(movesToUse); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); it("Sheer Force", async () => { @@ -48,7 +49,7 @@ describe("Abilities - Sheer Force", () => { game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); const phase = game.scene.getCurrentPhase() as MoveEffectPhase; @@ -81,7 +82,7 @@ describe("Abilities - Sheer Force", () => { game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); const phase = game.scene.getCurrentPhase() as MoveEffectPhase; @@ -114,7 +115,7 @@ describe("Abilities - Sheer Force", () => { game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); const phase = game.scene.getCurrentPhase() as MoveEffectPhase; @@ -149,7 +150,7 @@ describe("Abilities - Sheer Force", () => { game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); const phase = game.scene.getCurrentPhase() as MoveEffectPhase; @@ -174,5 +175,31 @@ describe("Abilities - Sheer Force", () => { }, 20000); + it("Two Pokemon with abilities disabled by Sheer Force hitting each other should not cause a crash", async () => { + const moveToUse = Moves.CRUNCH; + game.override.enemyAbility(Abilities.COLOR_CHANGE) + .ability(Abilities.COLOR_CHANGE) + .moveset(moveToUse) + .enemyMoveset(moveToUse); + + await game.classicMode.startBattle([ + Species.PIDGEOT + ]); + + const pidgeot = game.scene.getParty()[0]; + const onix = game.scene.getEnemyParty()[0]; + + pidgeot.stats[Stat.DEF] = 10000; + onix.stats[Stat.DEF] = 10000; + + game.move.select(moveToUse); + await game.toNextTurn(); + + // Check that both Pokemon's Color Change activated + const expectedTypes = [ allMoves[moveToUse].type ]; + expect(pidgeot.getTypes()).toStrictEqual(expectedTypes); + expect(onix.getTypes()).toStrictEqual(expectedTypes); + }); + //TODO King's Rock Interaction Unit Test }); diff --git a/src/test/abilities/shield_dust.test.ts b/src/test/abilities/shield_dust.test.ts index 8a0b769827d..0f831fcf3fa 100644 --- a/src/test/abilities/shield_dust.test.ts +++ b/src/test/abilities/shield_dust.test.ts @@ -27,13 +27,13 @@ describe("Abilities - Shield Dust", () => { beforeEach(() => { game = new GameManager(phaserGame); - const movesToUse = [Moves.AIR_SLASH]; + const movesToUse = [ Moves.AIR_SLASH ]; game.override.battleType("single"); game.override.enemySpecies(Species.ONIX); game.override.enemyAbility(Abilities.SHIELD_DUST); game.override.startingLevel(100); game.override.moveset(movesToUse); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); it("Shield Dust", async () => { @@ -48,7 +48,7 @@ describe("Abilities - Shield Dust", () => { game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); // Shield Dust negates secondary effect diff --git a/src/test/abilities/shields_down.test.ts b/src/test/abilities/shields_down.test.ts index 411c23fc652..d3d72ac80a5 100644 --- a/src/test/abilities/shields_down.test.ts +++ b/src/test/abilities/shields_down.test.ts @@ -8,7 +8,6 @@ import GameManager from "#test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Abilities - SHIELDS DOWN", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -28,8 +27,8 @@ describe("Abilities - SHIELDS DOWN", () => { const moveToUse = Moves.SPLASH; game.override.battleType("single"); game.override.ability(Abilities.SHIELDS_DOWN); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); test( @@ -42,7 +41,7 @@ describe("Abilities - SHIELDS DOWN", () => { [Species.MINIOR]: coreForm, }); - await game.startBattle([Species.MAGIKARP, Species.MINIOR]); + await game.startBattle([ Species.MAGIKARP, Species.MINIOR ]); const minior = game.scene.getParty().find((p) => p.species.speciesId === Species.MINIOR)!; expect(minior).not.toBe(undefined); diff --git a/src/test/abilities/speed_boost.test.ts b/src/test/abilities/speed_boost.test.ts new file mode 100644 index 00000000000..dd2e83aaa88 --- /dev/null +++ b/src/test/abilities/speed_boost.test.ts @@ -0,0 +1,125 @@ +import { Stat } from "#enums/stat"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { CommandPhase } from "#app/phases/command-phase"; +import { Command } from "#app/ui/command-ui-handler"; +import { AttemptRunPhase } from "#app/phases/attempt-run-phase"; + +describe("Abilities - Speed Boost", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override + .battleType("single") + .enemySpecies(Species.DRAGAPULT) + .ability(Abilities.SPEED_BOOST) + .enemyMoveset(Moves.SPLASH) + .moveset([ Moves.SPLASH, Moves.U_TURN ]); + }); + + it("should increase speed by 1 stage at end of turn", + async () => { + await game.classicMode.startBattle(); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(1); + }); + + it("should not trigger this turn if pokemon was switched into combat via attack, but the turn after", + async () => { + await game.classicMode.startBattle([ + Species.SHUCKLE, + Species.NINJASK + ]); + + game.move.select(Moves.U_TURN); + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + const playerPokemon = game.scene.getPlayerPokemon()!; + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(0); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(1); + }); + + it("checking back to back swtiches", + async () => { + await game.classicMode.startBattle([ + Species.SHUCKLE, + Species.NINJASK + ]); + + game.move.select(Moves.U_TURN); + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + let playerPokemon = game.scene.getPlayerPokemon()!; + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(0); + + game.move.select(Moves.U_TURN); + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + playerPokemon = game.scene.getPlayerPokemon()!; + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(0); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(1); + }); + + it("should not trigger this turn if pokemon was switched into combat via normal switch, but the turn after", + async () => { + await game.classicMode.startBattle([ + Species.SHUCKLE, + Species.NINJASK + ]); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + const playerPokemon = game.scene.getPlayerPokemon()!; + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(0); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(1); + }); + + it("should not trigger if pokemon fails to escape", + async () => { + await game.classicMode.startBattle([ Species.SHUCKLE ]); + + const commandPhase = game.scene.getCurrentPhase() as CommandPhase; + commandPhase.handleCommand(Command.RUN, 0); + const runPhase = game.scene.getCurrentPhase() as AttemptRunPhase; + runPhase.forceFailEscape = true; + await game.phaseInterceptor.to(AttemptRunPhase); + await game.toNextTurn(); + + const playerPokemon = game.scene.getPlayerPokemon()!; + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(0); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(1); + }); +}); diff --git a/src/test/abilities/stall.test.ts b/src/test/abilities/stall.test.ts index 7baf7c846f0..b51c56dbe1f 100644 --- a/src/test/abilities/stall.test.ts +++ b/src/test/abilities/stall.test.ts @@ -26,8 +26,8 @@ describe("Abilities - Stall", () => { game.override.disableCrits(); game.override.enemySpecies(Species.REGIELEKI); game.override.enemyAbility(Abilities.STALL); - game.override.enemyMoveset([Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK]); - game.override.moveset([Moves.QUICK_ATTACK, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK ]); + game.override.moveset([ Moves.QUICK_ATTACK, Moves.TACKLE ]); }); /** @@ -37,7 +37,7 @@ describe("Abilities - Stall", () => { **/ it("Pokemon with Stall should move last in its priority bracket regardless of speed", async () => { - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); const playerIndex = game.scene.getPlayerPokemon()!.getBattlerIndex(); const enemyIndex = game.scene.getEnemyPokemon()!.getBattlerIndex(); @@ -50,12 +50,12 @@ describe("Abilities - Stall", () => { const commandOrder = phase.getCommandOrder(); // The player Pokemon (without Stall) goes first despite having lower speed than the opponent. // The opponent Pokemon (with Stall) goes last despite having higher speed than the player Pokemon. - expect(speedOrder).toEqual([enemyIndex, playerIndex]); - expect(commandOrder).toEqual([playerIndex, enemyIndex]); + expect(speedOrder).toEqual([ enemyIndex, playerIndex ]); + expect(commandOrder).toEqual([ playerIndex, enemyIndex ]); }, 20000); it("Pokemon with Stall will go first if a move that is in a higher priority bracket than the opponent's move is used", async () => { - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); const playerIndex = game.scene.getPlayerPokemon()!.getBattlerIndex(); const enemyIndex = game.scene.getEnemyPokemon()!.getBattlerIndex(); @@ -68,13 +68,13 @@ describe("Abilities - Stall", () => { const commandOrder = phase.getCommandOrder(); // The opponent Pokemon (with Stall) goes first because its move is still within a higher priority bracket than its opponent. // The player Pokemon goes second because its move is in a lower priority bracket. - expect(speedOrder).toEqual([enemyIndex, playerIndex]); - expect(commandOrder).toEqual([enemyIndex, playerIndex]); + expect(speedOrder).toEqual([ enemyIndex, playerIndex ]); + expect(commandOrder).toEqual([ enemyIndex, playerIndex ]); }, 20000); it("If both Pokemon have stall and use the same move, speed is used to determine who goes first.", async () => { game.override.ability(Abilities.STALL); - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); const playerIndex = game.scene.getPlayerPokemon()!.getBattlerIndex(); const enemyIndex = game.scene.getEnemyPokemon()!.getBattlerIndex(); @@ -88,7 +88,7 @@ describe("Abilities - Stall", () => { // The opponent Pokemon (with Stall) goes first because it has a higher speed. // The player Pokemon (with Stall) goes second because its speed is lower. - expect(speedOrder).toEqual([enemyIndex, playerIndex]); - expect(commandOrder).toEqual([enemyIndex, playerIndex]); + expect(speedOrder).toEqual([ enemyIndex, playerIndex ]); + expect(commandOrder).toEqual([ enemyIndex, playerIndex ]); }, 20000); }); diff --git a/src/test/abilities/steely_spirit.test.ts b/src/test/abilities/steely_spirit.test.ts index 7b5879555be..61e76989060 100644 --- a/src/test/abilities/steely_spirit.test.ts +++ b/src/test/abilities/steely_spirit.test.ts @@ -29,13 +29,13 @@ describe("Abilities - Steely Spirit", () => { game.override.battleType("double"); game.override.enemySpecies(Species.SHUCKLE); game.override.enemyAbility(Abilities.BALL_FETCH); - game.override.moveset([Moves.IRON_HEAD, Moves.SPLASH]); + game.override.moveset([ Moves.IRON_HEAD, Moves.SPLASH ]); game.override.enemyMoveset(Moves.SPLASH); vi.spyOn(allMoves[moveToCheck], "calculateBattlePower"); }); it("increases Steel-type moves' power used by the user and its allies by 50%", async () => { - await game.classicMode.startBattle([Species.PIKACHU, Species.SHUCKLE]); + await game.classicMode.startBattle([ Species.PIKACHU, Species.SHUCKLE ]); const boostSource = game.scene.getPlayerField()[1]; const enemyToCheck = game.scene.getEnemyPokemon()!; @@ -51,7 +51,7 @@ describe("Abilities - Steely Spirit", () => { }); it("stacks if multiple users with this ability are on the field.", async () => { - await game.classicMode.startBattle([Species.PIKACHU, Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU, Species.PIKACHU ]); const enemyToCheck = game.scene.getEnemyPokemon()!; game.scene.getPlayerField().forEach(p => { @@ -68,7 +68,7 @@ describe("Abilities - Steely Spirit", () => { }); it("does not take effect when suppressed", async () => { - await game.classicMode.startBattle([Species.PIKACHU, Species.SHUCKLE]); + await game.classicMode.startBattle([ Species.PIKACHU, Species.SHUCKLE ]); const boostSource = game.scene.getPlayerField()[1]; const enemyToCheck = game.scene.getEnemyPokemon()!; @@ -90,12 +90,12 @@ describe("Abilities - Steely Spirit", () => { it("affects variable-type moves if their resolved type is Steel", async () => { game.override .ability(Abilities.STEELY_SPIRIT) - .moveset([Moves.REVELATION_DANCE]); + .moveset([ Moves.REVELATION_DANCE ]); const revelationDance = allMoves[Moves.REVELATION_DANCE]; vi.spyOn(revelationDance, "calculateBattlePower"); - await game.classicMode.startBattle([Species.KLINKLANG]); + await game.classicMode.startBattle([ Species.KLINKLANG ]); game.move.select(Moves.REVELATION_DANCE); diff --git a/src/test/abilities/sturdy.test.ts b/src/test/abilities/sturdy.test.ts index c329d0830d3..49384e69f83 100644 --- a/src/test/abilities/sturdy.test.ts +++ b/src/test/abilities/sturdy.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Abilities - Sturdy", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,7 +29,7 @@ describe("Abilities - Sturdy", () => { game.override.starterSpecies(Species.LUCARIO); game.override.startingLevel(100); - game.override.moveset([Moves.CLOSE_COMBAT, Moves.FISSURE]); + game.override.moveset([ Moves.CLOSE_COMBAT, Moves.FISSURE ]); game.override.enemySpecies(Species.ARON); game.override.enemyLevel(5); diff --git a/src/test/abilities/sweet_veil.test.ts b/src/test/abilities/sweet_veil.test.ts index c2946443245..ef66cb1c68a 100644 --- a/src/test/abilities/sweet_veil.test.ts +++ b/src/test/abilities/sweet_veil.test.ts @@ -26,14 +26,14 @@ describe("Abilities - Sweet Veil", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("double"); - game.override.moveset([Moves.SPLASH, Moves.REST, Moves.YAWN]); + game.override.moveset([ Moves.SPLASH, Moves.REST, Moves.YAWN ]); game.override.enemySpecies(Species.MAGIKARP); game.override.enemyAbility(Abilities.BALL_FETCH); - game.override.enemyMoveset([Moves.POWDER, Moves.POWDER, Moves.POWDER, Moves.POWDER]); + game.override.enemyMoveset([ Moves.POWDER, Moves.POWDER, Moves.POWDER, Moves.POWDER ]); }); it("prevents the user and its allies from falling asleep", async () => { - await game.startBattle([Species.SWIRLIX, Species.MAGIKARP]); + await game.startBattle([ Species.SWIRLIX, Species.MAGIKARP ]); game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH, 1); @@ -45,7 +45,7 @@ describe("Abilities - Sweet Veil", () => { it("causes Rest to fail when used by the user or its allies", async () => { game.override.enemyMoveset(Moves.SPLASH); - await game.startBattle([Species.SWIRLIX, Species.MAGIKARP]); + await game.startBattle([ Species.SWIRLIX, Species.MAGIKARP ]); game.move.select(Moves.SPLASH); game.move.select(Moves.REST, 1); @@ -56,8 +56,8 @@ describe("Abilities - Sweet Veil", () => { }); it("causes Yawn to fail if used on the user or its allies", async () => { - game.override.enemyMoveset([Moves.YAWN, Moves.YAWN, Moves.YAWN, Moves.YAWN]); - await game.startBattle([Species.SWIRLIX, Species.MAGIKARP]); + game.override.enemyMoveset([ Moves.YAWN, Moves.YAWN, Moves.YAWN, Moves.YAWN ]); + await game.startBattle([ Species.SWIRLIX, Species.MAGIKARP ]); game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH, 1); @@ -73,7 +73,7 @@ describe("Abilities - Sweet Veil", () => { game.override.startingLevel(5); game.override.enemyMoveset(Moves.SPLASH); - await game.startBattle([Species.SHUCKLE, Species.SHUCKLE, Species.SWIRLIX]); + await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE, Species.SWIRLIX ]); game.move.select(Moves.SPLASH); game.move.select(Moves.YAWN, 1, BattlerIndex.PLAYER); diff --git a/src/test/abilities/synchronize.test.ts b/src/test/abilities/synchronize.test.ts index 6e0aa46763f..cdd2834f588 100644 --- a/src/test/abilities/synchronize.test.ts +++ b/src/test/abilities/synchronize.test.ts @@ -28,12 +28,12 @@ describe("Abilities - Synchronize", () => { .startingLevel(100) .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.SYNCHRONIZE) - .moveset([Moves.SPLASH, Moves.THUNDER_WAVE, Moves.SPORE, Moves.PSYCHO_SHIFT]) + .moveset([ Moves.SPLASH, Moves.THUNDER_WAVE, Moves.SPORE, Moves.PSYCHO_SHIFT ]) .ability(Abilities.NO_GUARD); }, 20000); it("does not trigger when no status is applied by opponent Pokemon", async () => { - await game.classicMode.startBattle([Species.FEEBAS]); + await game.classicMode.startBattle([ Species.FEEBAS ]); game.move.select(Moves.SPLASH); await game.phaseInterceptor.to("BerryPhase"); @@ -43,7 +43,7 @@ describe("Abilities - Synchronize", () => { }, 20000); it("sets the status of the source pokemon to Paralysis when paralyzed by it", async () => { - await game.classicMode.startBattle([Species.FEEBAS]); + await game.classicMode.startBattle([ Species.FEEBAS ]); game.move.select(Moves.THUNDER_WAVE); await game.phaseInterceptor.to("BerryPhase"); @@ -71,7 +71,7 @@ describe("Abilities - Synchronize", () => { .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Array(4).fill(Moves.TOXIC_SPIKES)); - await game.classicMode.startBattle([Species.FEEBAS, Species.MILOTIC]); + await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]); game.move.select(Moves.SPLASH); await game.toNextTurn(); @@ -85,7 +85,7 @@ describe("Abilities - Synchronize", () => { }, 20000); it("shows ability even if it fails to set the status of the opponent Pokemon", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); game.move.select(Moves.THUNDER_WAVE); await game.phaseInterceptor.to("BerryPhase"); diff --git a/src/test/abilities/tera_shell.test.ts b/src/test/abilities/tera_shell.test.ts index 9995f7c34c3..01382d0fd9a 100644 --- a/src/test/abilities/tera_shell.test.ts +++ b/src/test/abilities/tera_shell.test.ts @@ -26,10 +26,10 @@ describe("Abilities - Tera Shell", () => { game.override .battleType("single") .ability(Abilities.TERA_SHELL) - .moveset([Moves.SPLASH]) + .moveset([ Moves.SPLASH ]) .enemySpecies(Species.SNORLAX) .enemyAbility(Abilities.INSOMNIA) - .enemyMoveset([Moves.MACH_PUNCH]) + .enemyMoveset([ Moves.MACH_PUNCH ]) .startingLevel(100) .enemyLevel(100); }); @@ -37,7 +37,7 @@ describe("Abilities - Tera Shell", () => { it( "should change the effectiveness of non-resisted attacks when the source is at full HP", async () => { - await game.classicMode.startBattle([Species.SNORLAX]); + await game.classicMode.startBattle([ Species.SNORLAX ]); const playerPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(playerPokemon, "getMoveEffectiveness"); @@ -59,9 +59,9 @@ describe("Abilities - Tera Shell", () => { it( "should not override type immunities", async () => { - game.override.enemyMoveset([Moves.SHADOW_SNEAK]); + game.override.enemyMoveset([ Moves.SHADOW_SNEAK ]); - await game.classicMode.startBattle([Species.SNORLAX]); + await game.classicMode.startBattle([ Species.SNORLAX ]); const playerPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(playerPokemon, "getMoveEffectiveness"); @@ -76,9 +76,9 @@ describe("Abilities - Tera Shell", () => { it( "should not override type multipliers less than 0.5x", async () => { - game.override.enemyMoveset([Moves.QUICK_ATTACK]); + game.override.enemyMoveset([ Moves.QUICK_ATTACK ]); - await game.classicMode.startBattle([Species.AGGRON]); + await game.classicMode.startBattle([ Species.AGGRON ]); const playerPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(playerPokemon, "getMoveEffectiveness"); @@ -93,9 +93,9 @@ describe("Abilities - Tera Shell", () => { it( "should not affect the effectiveness of fixed-damage moves", async () => { - game.override.enemyMoveset([Moves.DRAGON_RAGE]); + game.override.enemyMoveset([ Moves.DRAGON_RAGE ]); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(playerPokemon, "apply"); @@ -111,16 +111,16 @@ describe("Abilities - Tera Shell", () => { it( "should change the effectiveness of all strikes of a multi-strike move", async () => { - game.override.enemyMoveset([Moves.DOUBLE_HIT]); + game.override.enemyMoveset([ Moves.DOUBLE_HIT ]); - await game.classicMode.startBattle([Species.SNORLAX]); + await game.classicMode.startBattle([ Species.SNORLAX ]); const playerPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(playerPokemon, "apply"); game.move.select(Moves.SPLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.move.forceHit(); for (let i = 0; i < 2; i++) { await game.phaseInterceptor.to("MoveEffectPhase"); diff --git a/src/test/abilities/unseen_fist.test.ts b/src/test/abilities/unseen_fist.test.ts index 0f285abd98f..f8fa8a723fe 100644 --- a/src/test/abilities/unseen_fist.test.ts +++ b/src/test/abilities/unseen_fist.test.ts @@ -9,7 +9,6 @@ import { BattlerTagType } from "#app/enums/battler-tag-type"; import { BerryPhase } from "#app/phases/berry-phase"; - describe("Abilities - Unseen Fist", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -29,7 +28,7 @@ describe("Abilities - Unseen Fist", () => { game.override.battleType("single"); game.override.starterSpecies(Species.URSHIFU); game.override.enemySpecies(Species.SNORLAX); - game.override.enemyMoveset([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); + game.override.enemyMoveset([ Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT ]); game.override.startingLevel(100); game.override.enemyLevel(100); }); @@ -66,7 +65,7 @@ describe("Abilities - Unseen Fist", () => { "should cause a contact move to ignore Protect, but not Substitute", async () => { game.override.enemyLevel(1); - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); await game.startBattle(); @@ -84,8 +83,8 @@ describe("Abilities - Unseen Fist", () => { }); async function testUnseenFistHitResult(game: GameManager, attackMove: Moves, protectMove: Moves, shouldSucceed: boolean = true): Promise { - game.override.moveset([attackMove]); - game.override.enemyMoveset([protectMove, protectMove, protectMove, protectMove]); + game.override.moveset([ attackMove ]); + game.override.enemyMoveset([ protectMove, protectMove, protectMove, protectMove ]); await game.startBattle(); diff --git a/src/test/abilities/volt_absorb.test.ts b/src/test/abilities/volt_absorb.test.ts index 9bd5de7df57..4fee7653b99 100644 --- a/src/test/abilities/volt_absorb.test.ts +++ b/src/test/abilities/volt_absorb.test.ts @@ -34,9 +34,9 @@ describe("Abilities - Volt Absorb", () => { const moveToUse = Moves.CHARGE; const ability = Abilities.VOLT_ABSORB; - game.override.moveset([moveToUse]); + game.override.moveset([ moveToUse ]); game.override.ability(ability); - game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemyMoveset([ Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE ]); game.override.enemySpecies(Species.DUSKULL); game.override.enemyAbility(Abilities.BALL_FETCH); @@ -52,6 +52,7 @@ describe("Abilities - Volt Absorb", () => { expect(playerPokemon.getTag(BattlerTagType.CHARGED)).toBeDefined(); expect(game.phaseInterceptor.log).not.toContain("ShowAbilityPhase"); }); + it("should activate regardless of accuracy checks", async () => { game.override.moveset(Moves.THUNDERBOLT); game.override.enemyMoveset(Moves.SPLASH); @@ -64,11 +65,29 @@ describe("Abilities - Volt Absorb", () => { game.move.select(Moves.THUNDERBOLT); enemyPokemon.hp = enemyPokemon.hp - 1; - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("MoveEffectPhase"); await game.move.forceMiss(); await game.phaseInterceptor.to("BerryPhase", false); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); }); + + it("regardless of accuracy should not trigger on pokemon in semi invulnerable state", async () => { + game.override.moveset(Moves.THUNDERBOLT); + game.override.enemyMoveset(Moves.DIVE); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.VOLT_ABSORB); + + await game.classicMode.startBattle(); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.THUNDERBOLT); + enemyPokemon.hp = enemyPokemon.hp - 1; + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + }); }); diff --git a/src/test/abilities/wind_power.test.ts b/src/test/abilities/wind_power.test.ts index 12b8d2f2299..538b65f898b 100644 --- a/src/test/abilities/wind_power.test.ts +++ b/src/test/abilities/wind_power.test.ts @@ -26,12 +26,12 @@ describe("Abilities - Wind Power", () => { game.override.battleType("single"); game.override.enemySpecies(Species.SHIFTRY); game.override.enemyAbility(Abilities.WIND_POWER); - game.override.moveset([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]); + game.override.moveset([ Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM ]); game.override.enemyMoveset(Moves.SPLASH); }); it("it becomes charged when hit by wind moves", async () => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const shiftry = game.scene.getEnemyPokemon()!; expect(shiftry.getTag(BattlerTagType.CHARGED)).toBeUndefined(); @@ -46,7 +46,7 @@ describe("Abilities - Wind Power", () => { game.override.ability(Abilities.WIND_POWER); game.override.enemySpecies(Species.MAGIKARP); - await game.startBattle([Species.SHIFTRY]); + await game.startBattle([ Species.SHIFTRY ]); const shiftry = game.scene.getPlayerPokemon()!; expect(shiftry.getTag(BattlerTagType.CHARGED)).toBeUndefined(); @@ -61,7 +61,7 @@ describe("Abilities - Wind Power", () => { game.override.enemySpecies(Species.MAGIKARP); game.override.ability(Abilities.WIND_POWER); - await game.startBattle([Species.SHIFTRY]); + await game.startBattle([ Species.SHIFTRY ]); const magikarp = game.scene.getEnemyPokemon()!; const shiftry = game.scene.getPlayerPokemon()!; @@ -79,7 +79,7 @@ describe("Abilities - Wind Power", () => { it("does not interact with Sandstorm", async () => { game.override.enemySpecies(Species.MAGIKARP); - await game.startBattle([Species.SHIFTRY]); + await game.startBattle([ Species.SHIFTRY ]); const shiftry = game.scene.getPlayerPokemon()!; expect(shiftry.getTag(BattlerTagType.CHARGED)).toBeUndefined(); diff --git a/src/test/abilities/wind_rider.test.ts b/src/test/abilities/wind_rider.test.ts index c917f56e101..cd7094fb0a9 100644 --- a/src/test/abilities/wind_rider.test.ts +++ b/src/test/abilities/wind_rider.test.ts @@ -26,7 +26,7 @@ describe("Abilities - Wind Rider", () => { .battleType("single") .enemySpecies(Species.SHIFTRY) .enemyAbility(Abilities.WIND_RIDER) - .moveset([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]) + .moveset([ Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM ]) .enemyMoveset(Moves.SPLASH); }); @@ -49,7 +49,7 @@ describe("Abilities - Wind Rider", () => { .enemySpecies(Species.MAGIKARP) .ability(Abilities.WIND_RIDER); - await game.classicMode.startBattle([Species.SHIFTRY]); + await game.classicMode.startBattle([ Species.SHIFTRY ]); const shiftry = game.scene.getPlayerPokemon()!; expect(shiftry.getStatStage(Stat.ATK)).toBe(0); @@ -66,7 +66,7 @@ describe("Abilities - Wind Rider", () => { .enemySpecies(Species.MAGIKARP) .ability(Abilities.WIND_RIDER); - await game.classicMode.startBattle([Species.SHIFTRY]); + await game.classicMode.startBattle([ Species.SHIFTRY ]); const magikarp = game.scene.getEnemyPokemon()!; const shiftry = game.scene.getPlayerPokemon()!; @@ -86,7 +86,7 @@ describe("Abilities - Wind Rider", () => { .enemySpecies(Species.MAGIKARP) .ability(Abilities.WIND_RIDER); - await game.classicMode.startBattle([Species.SHIFTRY]); + await game.classicMode.startBattle([ Species.SHIFTRY ]); const magikarp = game.scene.getEnemyPokemon()!; const shiftry = game.scene.getPlayerPokemon()!; @@ -104,7 +104,7 @@ describe("Abilities - Wind Rider", () => { it("does not interact with Sandstorm", async () => { game.override.enemySpecies(Species.MAGIKARP); - await game.classicMode.startBattle([Species.SHIFTRY]); + await game.classicMode.startBattle([ Species.SHIFTRY ]); const shiftry = game.scene.getPlayerPokemon()!; expect(shiftry.getStatStage(Stat.ATK)).toBe(0); diff --git a/src/test/abilities/wonder_skin.test.ts b/src/test/abilities/wonder_skin.test.ts index 6ef985fbd42..6b25701e36a 100644 --- a/src/test/abilities/wonder_skin.test.ts +++ b/src/test/abilities/wonder_skin.test.ts @@ -25,7 +25,7 @@ describe("Abilities - Wonder Skin", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("single"); - game.override.moveset([Moves.TACKLE, Moves.CHARM]); + game.override.moveset([ Moves.TACKLE, Moves.CHARM ]); game.override.ability(Abilities.BALL_FETCH); game.override.enemySpecies(Species.SHUCKLE); game.override.enemyAbility(Abilities.WONDER_SKIN); @@ -37,7 +37,7 @@ describe("Abilities - Wonder Skin", () => { vi.spyOn(moveToCheck, "calculateBattleAccuracy"); - await game.startBattle([Species.PIKACHU]); + await game.startBattle([ Species.PIKACHU ]); game.move.select(Moves.CHARM); await game.phaseInterceptor.to(MoveEffectPhase); @@ -49,14 +49,14 @@ describe("Abilities - Wonder Skin", () => { vi.spyOn(moveToCheck, "calculateBattleAccuracy"); - await game.startBattle([Species.PIKACHU]); + await game.startBattle([ Species.PIKACHU ]); game.move.select(Moves.TACKLE); await game.phaseInterceptor.to(MoveEffectPhase); expect(moveToCheck.calculateBattleAccuracy).toHaveReturnedWith(100); }); - const bypassAbilities = [Abilities.MOLD_BREAKER, Abilities.TERAVOLT, Abilities.TURBOBLAZE]; + const bypassAbilities = [ Abilities.MOLD_BREAKER, Abilities.TERAVOLT, Abilities.TURBOBLAZE ]; bypassAbilities.forEach(ability => { it(`does not affect pokemon with ${allAbilities[ability].name}`, async () => { @@ -65,7 +65,7 @@ describe("Abilities - Wonder Skin", () => { game.override.ability(ability); vi.spyOn(moveToCheck, "calculateBattleAccuracy"); - await game.startBattle([Species.PIKACHU]); + await game.startBattle([ Species.PIKACHU ]); game.move.select(Moves.CHARM); await game.phaseInterceptor.to(MoveEffectPhase); diff --git a/src/test/abilities/zen_mode.test.ts b/src/test/abilities/zen_mode.test.ts index b4c60aa7a7f..2601954a9a4 100644 --- a/src/test/abilities/zen_mode.test.ts +++ b/src/test/abilities/zen_mode.test.ts @@ -21,7 +21,6 @@ import { Status, StatusEffect } from "#app/data/status-effect"; import { SwitchType } from "#enums/switch-type"; - describe("Abilities - ZEN MODE", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -44,22 +43,22 @@ describe("Abilities - ZEN MODE", () => { game.override.enemyAbility(Abilities.HYDRATION); game.override.ability(Abilities.ZEN_MODE); game.override.startingLevel(100); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); test( "not enough damage to change form", async () => { const moveToUse = Moves.SPLASH; - await game.startBattle([Species.DARMANITAN]); + await game.startBattle([ Species.DARMANITAN ]); game.scene.getParty()[0].stats[Stat.HP] = 100; game.scene.getParty()[0].hp = 100; expect(game.scene.getParty()[0].formIndex).toBe(0); game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to(DamagePhase, false); // await game.phaseInterceptor.runFrom(DamagePhase).to(DamagePhase, false); const damagePhase = game.scene.getCurrentPhase() as DamagePhase; @@ -74,14 +73,14 @@ describe("Abilities - ZEN MODE", () => { "enough damage to change form", async () => { const moveToUse = Moves.SPLASH; - await game.startBattle([Species.DARMANITAN]); + await game.startBattle([ Species.DARMANITAN ]); game.scene.getParty()[0].stats[Stat.HP] = 1000; game.scene.getParty()[0].hp = 100; expect(game.scene.getParty()[0].formIndex).toBe(0); game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to(QuietFormChangePhase); await game.phaseInterceptor.to(TurnInitPhase, false); expect(game.scene.getParty()[0].hp).not.toBe(100); @@ -93,14 +92,14 @@ describe("Abilities - ZEN MODE", () => { "kill pokemon while on zen mode", async () => { const moveToUse = Moves.SPLASH; - await game.startBattle([Species.DARMANITAN, Species.CHARIZARD]); + await game.startBattle([ Species.DARMANITAN, Species.CHARIZARD ]); game.scene.getParty()[0].stats[Stat.HP] = 1000; game.scene.getParty()[0].hp = 100; expect(game.scene.getParty()[0].formIndex).toBe(0); game.move.select(moveToUse); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to(DamagePhase, false); // await game.phaseInterceptor.runFrom(DamagePhase).to(DamagePhase, false); const damagePhase = game.scene.getCurrentPhase() as DamagePhase; @@ -136,7 +135,7 @@ describe("Abilities - ZEN MODE", () => { [Species.DARMANITAN]: zenForm, }); - await game.startBattle([Species.MAGIKARP, Species.DARMANITAN]); + await game.startBattle([ Species.MAGIKARP, Species.DARMANITAN ]); const darmanitan = game.scene.getParty().find((p) => p.species.speciesId === Species.DARMANITAN)!; expect(darmanitan).not.toBe(undefined); diff --git a/src/test/abilities/zero_to_hero.test.ts b/src/test/abilities/zero_to_hero.test.ts index a7f7c970218..48a451e99a2 100644 --- a/src/test/abilities/zero_to_hero.test.ts +++ b/src/test/abilities/zero_to_hero.test.ts @@ -8,7 +8,6 @@ import GameManager from "#test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Abilities - ZERO TO HERO", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -40,7 +39,7 @@ describe("Abilities - ZERO TO HERO", () => { [Species.PALAFIN]: heroForm, }); - await game.startBattle([Species.FEEBAS, Species.PALAFIN, Species.PALAFIN]); + await game.startBattle([ Species.FEEBAS, Species.PALAFIN, Species.PALAFIN ]); const palafin1 = game.scene.getParty()[1]; const palafin2 = game.scene.getParty()[2]; @@ -62,7 +61,7 @@ describe("Abilities - ZERO TO HERO", () => { }); it("should swap to Hero form when switching out during a battle", async () => { - await game.startBattle([Species.PALAFIN, Species.FEEBAS]); + await game.startBattle([ Species.PALAFIN, Species.FEEBAS ]); const palafin = game.scene.getPlayerPokemon()!; expect(palafin.formIndex).toBe(baseForm); @@ -73,7 +72,7 @@ describe("Abilities - ZERO TO HERO", () => { }); it("should not swap to Hero form if switching due to faint", async () => { - await game.startBattle([Species.PALAFIN, Species.FEEBAS]); + await game.startBattle([ Species.PALAFIN, Species.FEEBAS ]); const palafin = game.scene.getPlayerPokemon()!; expect(palafin.formIndex).toBe(baseForm); @@ -90,7 +89,7 @@ describe("Abilities - ZERO TO HERO", () => { [Species.PALAFIN]: heroForm, }); - await game.startBattle([Species.PALAFIN, Species.FEEBAS]); + await game.startBattle([ Species.PALAFIN, Species.FEEBAS ]); const palafin = game.scene.getPlayerPokemon()!; expect(palafin.formIndex).toBe(heroForm); diff --git a/src/test/account.test.ts b/src/test/account.test.ts index eb6002f3cf2..8c36f2cd953 100644 --- a/src/test/account.test.ts +++ b/src/test/account.test.ts @@ -17,7 +17,7 @@ describe("account", () => { it("should set loggedInUser! to Guest if bypassLogin is true", async () => { vi.spyOn(battleScene, "bypassLogin", "get").mockReturnValue(true); - const [success, status] = await updateUserInfo(); + const [ success, status ] = await updateUserInfo(); expect(success).toBe(true); expect(status).toBe(200); @@ -39,7 +39,7 @@ describe("account", () => { ) ); - const [success, status] = await updateUserInfo(); + const [ success, status ] = await updateUserInfo(); expect(success).toBe(true); expect(status).toBe(200); @@ -53,7 +53,7 @@ describe("account", () => { new Response(null, { status: 401 }) ); - const [success, status] = await updateUserInfo(); + const [ success, status ] = await updateUserInfo(); expect(success).toBe(false); expect(status).toBe(401); @@ -64,7 +64,7 @@ describe("account", () => { vi.spyOn(battleScene, "bypassLogin", "get").mockReturnValue(false); vi.spyOn(utils, "apiFetch").mockRejectedValue(new Error("Api failed!")); - const [success, status] = await updateUserInfo(); + const [ success, status ] = await updateUserInfo(); expect(success).toBe(false); expect(status).toBe(500); diff --git a/src/test/achievements/achievement.test.ts b/src/test/achievements/achievement.test.ts index 24d00a3e77b..a3669c60463 100644 --- a/src/test/achievements/achievement.test.ts +++ b/src/test/achievements/achievement.test.ts @@ -61,8 +61,8 @@ describe("Achv", () => { const conditionFunc = vi.fn((scene: BattleScene, args: any[]) => args[0] === 10); const achv = new Achv("", "Test Achievement", "Test Description", "test_icon", 10, conditionFunc); - expect(achv.validate(new BattleScene(), [5])).toBe(false); - expect(achv.validate(new BattleScene(), [10])).toBe(true); + expect(achv.validate(new BattleScene(), [ 5 ])).toBe(false); + expect(achv.validate(new BattleScene(), [ 10 ])).toBe(true); expect(conditionFunc).toHaveBeenCalledTimes(2); }); }); @@ -141,10 +141,10 @@ describe("DamageAchv", () => { const scene = new BattleScene(); const numberHolder = new NumberHolder(200); - expect(damageAchv.validate(scene, [numberHolder])).toBe(false); + expect(damageAchv.validate(scene, [ numberHolder ])).toBe(false); numberHolder.value = 300; - expect(damageAchv.validate(scene, [numberHolder])).toBe(true); + expect(damageAchv.validate(scene, [ numberHolder ])).toBe(true); }); }); @@ -160,10 +160,10 @@ describe("HealAchv", () => { const scene = new BattleScene(); const numberHolder = new NumberHolder(200); - expect(healAchv.validate(scene, [numberHolder])).toBe(false); + expect(healAchv.validate(scene, [ numberHolder ])).toBe(false); numberHolder.value = 300; - expect(healAchv.validate(scene, [numberHolder])).toBe(true); + expect(healAchv.validate(scene, [ numberHolder ])).toBe(true); }); }); @@ -179,10 +179,10 @@ describe("LevelAchv", () => { const scene = new BattleScene(); const integerHolder = new IntegerHolder(50); - expect(levelAchv.validate(scene, [integerHolder])).toBe(false); + expect(levelAchv.validate(scene, [ integerHolder ])).toBe(false); integerHolder.value = 150; - expect(levelAchv.validate(scene, [integerHolder])).toBe(true); + expect(levelAchv.validate(scene, [ integerHolder ])).toBe(true); }); }); @@ -198,7 +198,7 @@ describe("ModifierAchv", () => { const scene = new BattleScene(); const modifier = new TurnHeldItemTransferModifier(null!, 3, 1); - expect(modifierAchv.validate(scene, [modifier])).toBe(true); + expect(modifierAchv.validate(scene, [ modifier ])).toBe(true); }); }); diff --git a/src/test/arena/arena_gravity.test.ts b/src/test/arena/arena_gravity.test.ts index 47b8bf4cf70..13e9c23a35c 100644 --- a/src/test/arena/arena_gravity.test.ts +++ b/src/test/arena/arena_gravity.test.ts @@ -1,8 +1,8 @@ +import { BattlerIndex } from "#app/battle"; import { allMoves } from "#app/data/move"; -import { Abilities } from "#app/enums/abilities"; -import { ArenaTagType } from "#app/enums/arena-tag-type"; -import { MoveEffectPhase } from "#app/phases/move-effect-phase"; -import { TurnEndPhase } from "#app/phases/turn-end-phase"; +import { Abilities } from "#enums/abilities"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { BattlerTagType } from "#enums/battler-tag-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; @@ -27,11 +27,12 @@ describe("Arena - Gravity", () => { game = new GameManager(phaserGame); game.override .battleType("single") - .moveset([Moves.TACKLE, Moves.GRAVITY, Moves.FISSURE]) + .moveset([ Moves.TACKLE, Moves.GRAVITY, Moves.FISSURE ]) .ability(Abilities.UNNERVE) .enemyAbility(Abilities.BALL_FETCH) .enemySpecies(Species.SHUCKLE) - .enemyMoveset(Moves.SPLASH); + .enemyMoveset(Moves.SPLASH) + .enemyLevel(5); }); // Reference: https://bulbapedia.bulbagarden.net/wiki/Gravity_(move) @@ -42,102 +43,121 @@ describe("Arena - Gravity", () => { vi.spyOn(moveToCheck, "calculateBattleAccuracy"); // Setup Gravity on first turn - await game.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); game.move.select(Moves.GRAVITY); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); // Use non-OHKO move on second turn await game.toNextTurn(); game.move.select(Moves.TACKLE); - await game.phaseInterceptor.to(MoveEffectPhase); + await game.phaseInterceptor.to("MoveEffectPhase"); - expect(moveToCheck.calculateBattleAccuracy).toHaveReturnedWith(100 * 1.67); + expect(moveToCheck.calculateBattleAccuracy).toHaveLastReturnedWith(100 * 1.67); }); it("OHKO move accuracy is not affected", async () => { - game.override.startingLevel(5); - game.override.enemyLevel(5); - /** See Fissure {@link https://bulbapedia.bulbagarden.net/wiki/Fissure_(move)} */ const moveToCheck = allMoves[Moves.FISSURE]; vi.spyOn(moveToCheck, "calculateBattleAccuracy"); // Setup Gravity on first turn - await game.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); game.move.select(Moves.GRAVITY); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); // Use OHKO move on second turn await game.toNextTurn(); game.move.select(Moves.FISSURE); - await game.phaseInterceptor.to(MoveEffectPhase); + await game.phaseInterceptor.to("MoveEffectPhase"); - expect(moveToCheck.calculateBattleAccuracy).toHaveReturnedWith(30); + expect(moveToCheck.calculateBattleAccuracy).toHaveLastReturnedWith(30); }); describe("Against flying types", () => { it("can be hit by ground-type moves now", async () => { game.override - .startingLevel(5) - .enemyLevel(5) .enemySpecies(Species.PIDGEOT) - .moveset([Moves.GRAVITY, Moves.EARTHQUAKE]); + .moveset([ Moves.GRAVITY, Moves.EARTHQUAKE ]); - await game.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pidgeot = game.scene.getEnemyPokemon()!; vi.spyOn(pidgeot, "getAttackTypeEffectiveness"); // Try earthquake on 1st turn (fails!); game.move.select(Moves.EARTHQUAKE); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); - expect(pidgeot.getAttackTypeEffectiveness).toHaveReturnedWith(0); + expect(pidgeot.getAttackTypeEffectiveness).toHaveLastReturnedWith(0); // Setup Gravity on 2nd turn await game.toNextTurn(); game.move.select(Moves.GRAVITY); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); // Use ground move on 3rd turn await game.toNextTurn(); game.move.select(Moves.EARTHQUAKE); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); - expect(pidgeot.getAttackTypeEffectiveness).toHaveReturnedWith(1); + expect(pidgeot.getAttackTypeEffectiveness).toHaveLastReturnedWith(1); }); it("keeps super-effective moves super-effective after using gravity", async () => { game.override - .startingLevel(5) - .enemyLevel(5) .enemySpecies(Species.PIDGEOT) - .moveset([Moves.GRAVITY, Moves.THUNDERBOLT]); + .moveset([ Moves.GRAVITY, Moves.THUNDERBOLT ]); - await game.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pidgeot = game.scene.getEnemyPokemon()!; vi.spyOn(pidgeot, "getAttackTypeEffectiveness"); // Setup Gravity on 1st turn game.move.select(Moves.GRAVITY); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); // Use electric move on 2nd turn await game.toNextTurn(); game.move.select(Moves.THUNDERBOLT); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); - expect(pidgeot.getAttackTypeEffectiveness).toHaveReturnedWith(2); + expect(pidgeot.getAttackTypeEffectiveness).toHaveLastReturnedWith(2); }); }); + + it("cancels Fly if its user is semi-invulnerable", async () => { + game.override + .enemySpecies(Species.SNORLAX) + .enemyMoveset(Moves.FLY) + .moveset([ Moves.GRAVITY, Moves.SPLASH ]); + + await game.classicMode.startBattle([ Species.CHARIZARD ]); + + const charizard = game.scene.getPlayerPokemon()!; + const snorlax = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.SPLASH); + + await game.toNextTurn(); + expect(snorlax.getTag(BattlerTagType.FLYING)).toBeDefined(); + + game.move.select(Moves.GRAVITY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to("MoveEffectPhase"); + expect(snorlax.getTag(BattlerTagType.INTERRUPTED)).toBeDefined(); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(charizard.hp).toBe(charizard.getMaxHp()); + }); }); diff --git a/src/test/arena/grassy_terrain.test.ts b/src/test/arena/grassy_terrain.test.ts index 01bbc778ded..ead4467925b 100644 --- a/src/test/arena/grassy_terrain.test.ts +++ b/src/test/arena/grassy_terrain.test.ts @@ -28,12 +28,12 @@ describe("Arena - Grassy Terrain", () => { .enemySpecies(Species.SHUCKLE) .enemyAbility(Abilities.STURDY) .enemyMoveset(Moves.FLY) - .moveset([Moves.GRASSY_TERRAIN, Moves.EARTHQUAKE]) + .moveset([ Moves.GRASSY_TERRAIN, Moves.EARTHQUAKE ]) .ability(Abilities.NO_GUARD); }); it("halves the damage of Earthquake", async () => { - await game.classicMode.startBattle([Species.TAUROS]); + await game.classicMode.startBattle([ Species.TAUROS ]); const eq = allMoves[Moves.EARTHQUAKE]; vi.spyOn(eq, "calculateBattlePower"); @@ -53,7 +53,7 @@ describe("Arena - Grassy Terrain", () => { }); it("Does not halve the damage of Earthquake if opponent is not grounded", async () => { - await game.classicMode.startBattle([Species.NINJASK]); + await game.classicMode.startBattle([ Species.NINJASK ]); const eq = allMoves[Moves.EARTHQUAKE]; vi.spyOn(eq, "calculateBattlePower"); diff --git a/src/test/arena/weather_fog.test.ts b/src/test/arena/weather_fog.test.ts index b47145e8dd0..db591dda2b8 100644 --- a/src/test/arena/weather_fog.test.ts +++ b/src/test/arena/weather_fog.test.ts @@ -27,11 +27,11 @@ describe("Weather - Fog", () => { game.override .weather(WeatherType.FOG) .battleType("single"); - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.ability(Abilities.BALL_FETCH); game.override.enemyAbility(Abilities.BALL_FETCH); game.override.enemySpecies(Species.MAGIKARP); - game.override.enemyMoveset([Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH ]); }); it("move accuracy is multiplied by 90%", async () => { @@ -39,7 +39,7 @@ describe("Weather - Fog", () => { vi.spyOn(moveToCheck, "calculateBattleAccuracy"); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.TACKLE); await game.phaseInterceptor.to(MoveEffectPhase); diff --git a/src/test/arena/weather_hail.test.ts b/src/test/arena/weather_hail.test.ts index 31d20be2ded..b8f4276a3d9 100644 --- a/src/test/arena/weather_hail.test.ts +++ b/src/test/arena/weather_hail.test.ts @@ -31,24 +31,24 @@ describe("Weather - Hail", () => { }); it("inflicts damage equal to 1/16 of Pokemon's max HP at turn end", async () => { - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.SPLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); game.scene.getField(true).forEach(pokemon => { - expect(pokemon.hp).toBeLessThan(pokemon.getMaxHp() - Math.floor(pokemon.getMaxHp() / 16)); + expect(pokemon.hp).toBe(pokemon.getMaxHp() - Math.max(Math.floor(pokemon.getMaxHp() / 16), 1)); }); }); it("does not inflict damage to a Pokemon that is underwater (Dive) or underground (Dig)", async () => { - game.override.moveset([Moves.DIG]); - await game.classicMode.startBattle([Species.MAGIKARP]); + game.override.moveset([ Moves.DIG ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.DIG); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); @@ -56,6 +56,20 @@ describe("Weather - Hail", () => { const enemyPokemon = game.scene.getEnemyPokemon()!; expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); - expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp() - Math.floor(enemyPokemon.getMaxHp() / 16)); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - Math.max(Math.floor(enemyPokemon.getMaxHp() / 16), 1)); + }); + + it("does not inflict damage to Ice type Pokemon", async () => { + await game.classicMode.startBattle([ Species.CLOYSTER ]); + + game.move.select(Moves.SPLASH); + + await game.phaseInterceptor.to("TurnEndPhase"); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - Math.max(Math.floor(enemyPokemon.getMaxHp() / 16), 1)); }); }); diff --git a/src/test/arena/weather_sandstorm.test.ts b/src/test/arena/weather_sandstorm.test.ts index 91188de6985..09d0c1d2b77 100644 --- a/src/test/arena/weather_sandstorm.test.ts +++ b/src/test/arena/weather_sandstorm.test.ts @@ -1,4 +1,6 @@ import { WeatherType } from "#app/data/weather"; +import { Abilities } from "#app/enums/abilities"; +import { Stat } from "#app/enums/stat"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; @@ -30,20 +32,20 @@ describe("Weather - Sandstorm", () => { }); it("inflicts damage equal to 1/16 of Pokemon's max HP at turn end", async () => { - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.SPLASH); await game.phaseInterceptor.to("TurnEndPhase"); game.scene.getField(true).forEach(pokemon => { - expect(pokemon.hp).toBeLessThan(pokemon.getMaxHp() - Math.floor(pokemon.getMaxHp() / 16)); + expect(pokemon.hp).toBe(pokemon.getMaxHp() - Math.max(Math.floor(pokemon.getMaxHp() / 16), 1)); }); }); it("does not inflict damage to a Pokemon that is underwater (Dive) or underground (Dig)", async () => { - game.override.moveset([Moves.DIVE]); - await game.classicMode.startBattle([Species.MAGIKARP]); + game.override.moveset([ Moves.DIVE ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.DIVE); @@ -53,6 +55,37 @@ describe("Weather - Sandstorm", () => { const enemyPokemon = game.scene.getEnemyPokemon()!; expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); - expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp() - Math.floor(enemyPokemon.getMaxHp() / 16)); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - Math.max(Math.floor(enemyPokemon.getMaxHp() / 16), 1)); + }); + + it("does not inflict damage to Rock, Ground and Steel type Pokemon", async () => { + game.override + .battleType("double") + .enemySpecies(Species.SANDSHREW) + .ability(Abilities.BALL_FETCH) + .enemyAbility(Abilities.BALL_FETCH); + + await game.classicMode.startBattle([ Species.ROCKRUFF, Species.KLINK ]); + + game.move.select(Moves.SPLASH, 0); + game.move.select(Moves.SPLASH, 1); + + await game.phaseInterceptor.to("TurnEndPhase"); + + game.scene.getField(true).forEach(pokemon => { + expect(pokemon.hp).toBe(pokemon.getMaxHp()); + }); + }); + + it("increases Rock type Pokemon Sp.Def by 50%", async () => { + await game.classicMode.startBattle([ Species.ROCKRUFF ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerSpdef = playerPokemon.getStat(Stat.SPDEF); + expect(playerPokemon.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(playerSpdef * 1.5)); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + const enemySpdef = enemyPokemon.getStat(Stat.SPDEF); + expect(enemyPokemon.getEffectiveStat(Stat.SPDEF)).toBe(enemySpdef); }); }); diff --git a/src/test/arena/weather_strong_winds.test.ts b/src/test/arena/weather_strong_winds.test.ts index 5ce0e61e647..557de93d644 100644 --- a/src/test/arena/weather_strong_winds.test.ts +++ b/src/test/arena/weather_strong_winds.test.ts @@ -28,13 +28,13 @@ describe("Weather - Strong Winds", () => { game.override.startingLevel(10); game.override.enemySpecies(Species.TAILLOW); game.override.enemyAbility(Abilities.DELTA_STREAM); - game.override.moveset([Moves.THUNDERBOLT, Moves.ICE_BEAM, Moves.ROCK_SLIDE]); + game.override.moveset([ Moves.THUNDERBOLT, Moves.ICE_BEAM, Moves.ROCK_SLIDE ]); }); it("electric type move is not very effective on Rayquaza", async () => { game.override.enemySpecies(Species.RAYQUAZA); - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pikachu = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -45,7 +45,7 @@ describe("Weather - Strong Winds", () => { }); it("electric type move is neutral for flying type pokemon", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pikachu = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -56,7 +56,7 @@ describe("Weather - Strong Winds", () => { }); it("ice type move is neutral for flying type pokemon", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pikachu = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -67,7 +67,7 @@ describe("Weather - Strong Winds", () => { }); it("rock type move is neutral for flying type pokemon", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const pikachu = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -80,7 +80,7 @@ describe("Weather - Strong Winds", () => { it("weather goes away when last trainer pokemon dies to indirect damage", async () => { game.override.enemyStatusEffect(StatusEffect.POISON); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const enemy = game.scene.getEnemyPokemon()!; enemy.hp = 1; diff --git a/src/test/battle/battle-order.test.ts b/src/test/battle/battle-order.test.ts index e19168962dc..d4e9950dec9 100644 --- a/src/test/battle/battle-order.test.ts +++ b/src/test/battle/battle-order.test.ts @@ -28,7 +28,7 @@ describe("Battle order", () => { game.override.enemySpecies(Species.MEWTWO); game.override.enemyAbility(Abilities.INSOMNIA); game.override.ability(Abilities.INSOMNIA); - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); }); it("opponent faster than player 50 vs 150", async () => { @@ -38,8 +38,8 @@ describe("Battle order", () => { const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; - vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 50]); // set playerPokemon's speed to 50 - vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set enemyPokemon's speed to 150 + vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 50 ]); // set playerPokemon's speed to 50 + vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 150 ]); // set enemyPokemon's speed to 150 game.move.select(Moves.TACKLE); await game.phaseInterceptor.run(EnemyCommandPhase); @@ -59,8 +59,8 @@ describe("Battle order", () => { const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; - vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set playerPokemon's speed to 150 - vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 50]); // set enemyPokemon's speed to 50 + vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 150 ]); // set playerPokemon's speed to 150 + vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 50 ]); // set enemyPokemon's speed to 50 game.move.select(Moves.TACKLE); await game.phaseInterceptor.run(EnemyCommandPhase); @@ -83,8 +83,8 @@ describe("Battle order", () => { const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); - playerPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 50])); // set both playerPokemons' speed to 50 - enemyPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150])); // set both enemyPokemons' speed to 150 + playerPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 50 ])); // set both playerPokemons' speed to 50 + enemyPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 150 ])); // set both enemyPokemons' speed to 150 const playerIndices = playerPokemon.map(p => p?.getBattlerIndex()); const enemyIndices = enemyPokemon.map(p => p?.getBattlerIndex()); @@ -109,9 +109,9 @@ describe("Battle order", () => { const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); - playerPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 100])); //set both playerPokemons' speed to 100 - vi.spyOn(enemyPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 100]); // set enemyPokemon's speed to 100 - vi.spyOn(enemyPokemon[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set enemyPokemon's speed to 150 + playerPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 100 ])); //set both playerPokemons' speed to 100 + vi.spyOn(enemyPokemon[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 100 ]); // set enemyPokemon's speed to 100 + vi.spyOn(enemyPokemon[1], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 150 ]); // set enemyPokemon's speed to 150 const playerIndices = playerPokemon.map(p => p?.getBattlerIndex()); const enemyIndices = enemyPokemon.map(p => p?.getBattlerIndex()); @@ -136,10 +136,10 @@ describe("Battle order", () => { const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); - vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 100]); // set one playerPokemon's speed to 100 - vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set other playerPokemon's speed to 150 - vi.spyOn(enemyPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 100]); // set one enemyPokemon's speed to 100 - vi.spyOn(enemyPokemon[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set other enemyPokemon's speed to 150 + vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 100 ]); // set one playerPokemon's speed to 100 + vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 150 ]); // set other playerPokemon's speed to 150 + vi.spyOn(enemyPokemon[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 100 ]); // set one enemyPokemon's speed to 100 + vi.spyOn(enemyPokemon[1], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, 150 ]); // set other enemyPokemon's speed to 150 const playerIndices = playerPokemon.map(p => p?.getBattlerIndex()); const enemyIndices = enemyPokemon.map(p => p?.getBattlerIndex()); diff --git a/src/test/battle/battle.test.ts b/src/test/battle/battle.test.ts index 554692374d2..eed76397f85 100644 --- a/src/test/battle/battle.test.ts +++ b/src/test/battle/battle.test.ts @@ -99,9 +99,9 @@ describe("Test Battle Phase", () => { game.override .startingWave(3) .battleType("single"); - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemyAbility(Abilities.HYDRATION); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); await game.startBattle(); game.move.select(Moves.TACKLE); await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(SelectModifierPhase, false); @@ -112,9 +112,9 @@ describe("Test Battle Phase", () => { game.override.enemySpecies(Species.RATTATA); game.override.startingLevel(5); game.override.startingWave(3); - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemyAbility(Abilities.HYDRATION); - game.override.enemyMoveset([Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP]); + game.override.enemyMoveset([ Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP ]); game.override.battleType("single"); await game.startBattle(); game.move.select(Moves.TACKLE); @@ -259,8 +259,8 @@ describe("Test Battle Phase", () => { game.override.ability(Abilities.ZEN_MODE); game.override.startingLevel(2000); game.override.startingWave(3); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); await game.startBattle([ Species.DARMANITAN, Species.CHARIZARD, @@ -282,8 +282,8 @@ describe("Test Battle Phase", () => { game.override.ability(Abilities.ZEN_MODE); game.override.startingLevel(2000); game.override.startingWave(3); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); await game.startBattle(); const turn = game.scene.currentBattle.turn; game.move.select(moveToUse); @@ -302,8 +302,8 @@ describe("Test Battle Phase", () => { .startingLevel(2000) .startingWave(3) .startingBiome(Biome.LAKE) - .moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + .moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); await game.classicMode.startBattle(); const waveIndex = game.scene.currentBattle.waveIndex; game.move.select(moveToUse); @@ -323,7 +323,7 @@ describe("Test Battle Phase", () => { .enemySpecies(Species.RATTATA) .startingWave(1) .startingLevel(100) - .moveset([moveToUse]) + .moveset([ moveToUse ]) .enemyMoveset(Moves.SPLASH) .startingHeldItems([{ name: "TEMP_STAT_STAGE_BOOSTER", type: Stat.ACC }]); diff --git a/src/test/battle/damage_calculation.test.ts b/src/test/battle/damage_calculation.test.ts index a348df6c085..e6ecbe4646f 100644 --- a/src/test/battle/damage_calculation.test.ts +++ b/src/test/battle/damage_calculation.test.ts @@ -31,11 +31,11 @@ describe("Battle Mechanics - Damage Calculation", () => { .startingLevel(100) .enemyLevel(100) .disableCrits() - .moveset([Moves.TACKLE, Moves.DRAGON_RAGE, Moves.FISSURE, Moves.JUMP_KICK]); + .moveset([ Moves.TACKLE, Moves.DRAGON_RAGE, Moves.FISSURE, Moves.JUMP_KICK ]); }); it("Tackle deals expected base damage", async () => { - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(playerPokemon, "getEffectiveStat").mockReturnValue(80); @@ -53,7 +53,7 @@ describe("Battle Mechanics - Damage Calculation", () => { .startingLevel(1) .enemySpecies(Species.AGGRON); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const aggron = game.scene.getEnemyPokemon()!; @@ -70,7 +70,7 @@ describe("Battle Mechanics - Damage Calculation", () => { .enemySpecies(Species.DRAGONITE) .enemyAbility(Abilities.MULTISCALE); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const magikarp = game.scene.getPlayerPokemon()!; const dragonite = game.scene.getEnemyPokemon()!; @@ -83,7 +83,7 @@ describe("Battle Mechanics - Damage Calculation", () => { .enemySpecies(Species.AGGRON) .enemyAbility(Abilities.MULTISCALE); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const magikarp = game.scene.getPlayerPokemon()!; const aggron = game.scene.getEnemyPokemon()!; @@ -96,7 +96,7 @@ describe("Battle Mechanics - Damage Calculation", () => { .enemySpecies(Species.GASTLY) .ability(Abilities.WONDER_GUARD); - await game.classicMode.startBattle([Species.SHEDINJA]); + await game.classicMode.startBattle([ Species.SHEDINJA ]); const shedinja = game.scene.getPlayerPokemon()!; @@ -115,7 +115,7 @@ describe("Battle Mechanics - Damage Calculation", () => { .enemySpecies(Species.CHARIZARD) .enemyAbility(Abilities.BLAZE); - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const charizard = game.scene.getEnemyPokemon()!; diff --git a/src/test/battle/error-handling.test.ts b/src/test/battle/error-handling.test.ts index da5cc4d1969..208463e7064 100644 --- a/src/test/battle/error-handling.test.ts +++ b/src/test/battle/error-handling.test.ts @@ -30,8 +30,8 @@ describe("Error Handling", () => { game.override.enemyAbility(Abilities.HYDRATION); game.override.ability(Abilities.ZEN_MODE); game.override.startingLevel(2000); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); it.skip("to next turn", async () => { diff --git a/src/test/battle/inverse_battle.test.ts b/src/test/battle/inverse_battle.test.ts index 01a0348e730..110f92d15b7 100644 --- a/src/test/battle/inverse_battle.test.ts +++ b/src/test/battle/inverse_battle.test.ts @@ -11,7 +11,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; - describe("Inverse Battle", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -42,7 +41,7 @@ describe("Inverse Battle", () => { it("Immune types are 2x effective - Thunderbolt against Ground Type", async () => { game.override - .moveset([Moves.THUNDERBOLT]) + .moveset([ Moves.THUNDERBOLT ]) .enemySpecies(Species.SANDSHREW); @@ -52,7 +51,7 @@ describe("Inverse Battle", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.THUNDERBOLT); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); @@ -60,7 +59,7 @@ describe("Inverse Battle", () => { it("2x effective types are 0.5x effective - Thunderbolt against Flying Type", async () => { game.override - .moveset([Moves.THUNDERBOLT]) + .moveset([ Moves.THUNDERBOLT ]) .enemySpecies(Species.PIDGEY); await game.challengeMode.startBattle(); @@ -69,7 +68,7 @@ describe("Inverse Battle", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.THUNDERBOLT); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(0.5); @@ -77,7 +76,7 @@ describe("Inverse Battle", () => { it("0.5x effective types are 2x effective - Thunderbolt against Electric Type", async () => { game.override - .moveset([Moves.THUNDERBOLT]) + .moveset([ Moves.THUNDERBOLT ]) .enemySpecies(Species.CHIKORITA); await game.challengeMode.startBattle(); @@ -86,7 +85,7 @@ describe("Inverse Battle", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.THUNDERBOLT); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); @@ -114,7 +113,7 @@ describe("Inverse Battle", () => { it("Freeze Dry is 2x effective against Water Type like other Ice type Move - Freeze Dry against Squirtle", async () => { game.override - .moveset([Moves.FREEZE_DRY]) + .moveset([ Moves.FREEZE_DRY ]) .enemySpecies(Species.SQUIRTLE); await game.challengeMode.startBattle(); @@ -123,7 +122,7 @@ describe("Inverse Battle", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FREEZE_DRY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); @@ -131,7 +130,7 @@ describe("Inverse Battle", () => { it("Water Absorb should heal against water moves - Water Absorb against Water gun", async () => { game.override - .moveset([Moves.WATER_GUN]) + .moveset([ Moves.WATER_GUN ]) .enemyAbility(Abilities.WATER_ABSORB); await game.challengeMode.startBattle(); @@ -139,7 +138,7 @@ describe("Inverse Battle", () => { const enemy = game.scene.getEnemyPokemon()!; enemy.hp = enemy.getMaxHp() - 1; game.move.select(Moves.WATER_GUN); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.hp).toBe(enemy.getMaxHp()); @@ -147,7 +146,7 @@ describe("Inverse Battle", () => { it("Fire type does not get burned - Will-O-Wisp against Charmander", async () => { game.override - .moveset([Moves.WILL_O_WISP]) + .moveset([ Moves.WILL_O_WISP ]) .enemySpecies(Species.CHARMANDER); await game.challengeMode.startBattle(); @@ -155,7 +154,7 @@ describe("Inverse Battle", () => { const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.WILL_O_WISP); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.move.forceHit(); await game.phaseInterceptor.to("MoveEndPhase"); @@ -164,7 +163,7 @@ describe("Inverse Battle", () => { it("Electric type does not get paralyzed - Nuzzle against Pikachu", async () => { game.override - .moveset([Moves.NUZZLE]) + .moveset([ Moves.NUZZLE ]) .enemySpecies(Species.PIKACHU) .enemyLevel(50); @@ -173,7 +172,7 @@ describe("Inverse Battle", () => { const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.NUZZLE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.status?.effect).not.toBe(StatusEffect.PARALYSIS); @@ -181,7 +180,7 @@ describe("Inverse Battle", () => { it("Ground type is not immune to Thunder Wave - Thunder Wave against Sandshrew", async () => { game.override - .moveset([Moves.THUNDER_WAVE]) + .moveset([ Moves.THUNDER_WAVE ]) .enemySpecies(Species.SANDSHREW); await game.challengeMode.startBattle(); @@ -189,7 +188,7 @@ describe("Inverse Battle", () => { const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.THUNDER_WAVE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.move.forceHit(); await game.phaseInterceptor.to("MoveEndPhase"); @@ -199,7 +198,7 @@ describe("Inverse Battle", () => { it("Anticipation should trigger on 2x effective moves - Anticipation against Thunderbolt", async () => { game.override - .moveset([Moves.THUNDERBOLT]) + .moveset([ Moves.THUNDERBOLT ]) .enemySpecies(Species.SANDSHREW) .enemyAbility(Abilities.ANTICIPATION); @@ -210,15 +209,15 @@ describe("Inverse Battle", () => { it("Conversion 2 should change the type to the resistive type - Conversion 2 against Dragonite", async () => { game.override - .moveset([Moves.CONVERSION_2]) - .enemyMoveset([Moves.DRAGON_CLAW, Moves.DRAGON_CLAW, Moves.DRAGON_CLAW, Moves.DRAGON_CLAW]); + .moveset([ Moves.CONVERSION_2 ]) + .enemyMoveset([ Moves.DRAGON_CLAW, Moves.DRAGON_CLAW, Moves.DRAGON_CLAW, Moves.DRAGON_CLAW ]); await game.challengeMode.startBattle(); const player = game.scene.getPlayerPokemon()!; game.move.select(Moves.CONVERSION_2); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); @@ -227,7 +226,7 @@ describe("Inverse Battle", () => { it("Flying Press should be 0.25x effective against Grass + Dark Type - Flying Press against Meowscarada", async () => { game.override - .moveset([Moves.FLYING_PRESS]) + .moveset([ Moves.FLYING_PRESS ]) .enemySpecies(Species.MEOWSCARADA); await game.challengeMode.startBattle(); @@ -236,7 +235,7 @@ describe("Inverse Battle", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FLYING_PRESS); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(0.25); @@ -244,7 +243,7 @@ describe("Inverse Battle", () => { it("Scrappy ability has no effect - Tackle against Ghost Type still 2x effective with Scrappy", async () => { game.override - .moveset([Moves.TACKLE]) + .moveset([ Moves.TACKLE ]) .ability(Abilities.SCRAPPY) .enemySpecies(Species.GASTLY); @@ -254,7 +253,7 @@ describe("Inverse Battle", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.TACKLE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); @@ -262,7 +261,7 @@ describe("Inverse Battle", () => { it("FORESIGHT has no effect - Tackle against Ghost Type still 2x effective with Foresight", async () => { game.override - .moveset([Moves.FORESIGHT, Moves.TACKLE]) + .moveset([ Moves.FORESIGHT, Moves.TACKLE ]) .enemySpecies(Species.GASTLY); await game.challengeMode.startBattle(); @@ -271,11 +270,11 @@ describe("Inverse Battle", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FORESIGHT); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); game.move.select(Moves.TACKLE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); diff --git a/src/test/battle/special_battle.test.ts b/src/test/battle/special_battle.test.ts index 1d319bea372..af9e3dddbec 100644 --- a/src/test/battle/special_battle.test.ts +++ b/src/test/battle/special_battle.test.ts @@ -25,10 +25,10 @@ describe("Test Battle Phase", () => { game = new GameManager(phaserGame); game.override.enemySpecies(Species.RATTATA); game.override.startingLevel(2000); - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); game.override.enemyAbility(Abilities.HYDRATION); game.override.ability(Abilities.HYDRATION); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); it("startBattle 2vs1 boss", async() => { diff --git a/src/test/battlerTags/stockpiling.test.ts b/src/test/battlerTags/stockpiling.test.ts index ae2528e7b5f..dab189853c5 100644 --- a/src/test/battlerTags/stockpiling.test.ts +++ b/src/test/battlerTags/stockpiling.test.ts @@ -27,7 +27,7 @@ describe("BattlerTag - StockpilingTag", () => { expect((phase as StatStageChangePhase)["stages"]).toEqual(1); expect((phase as StatStageChangePhase)["stats"]).toEqual(expect.arrayContaining([ Stat.DEF, Stat.SPDEF ])); - (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [Stat.DEF, Stat.SPDEF], [1, 1]); + (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.DEF, Stat.SPDEF ], [ 1, 1 ]); }); subject.onAdd(mockPokemon); @@ -52,9 +52,9 @@ describe("BattlerTag - StockpilingTag", () => { vi.spyOn(mockPokemon.scene, "unshiftPhase").mockImplementation(phase => { expect(phase).toBeInstanceOf(StatStageChangePhase); expect((phase as StatStageChangePhase)["stages"]).toEqual(1); - expect((phase as StatStageChangePhase)["stats"]).toEqual(expect.arrayContaining([Stat.DEF, Stat.SPDEF])); + expect((phase as StatStageChangePhase)["stats"]).toEqual(expect.arrayContaining([ Stat.DEF, Stat.SPDEF ])); - (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.DEF, Stat.SPDEF ], [1, 1]); + (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.DEF, Stat.SPDEF ], [ 1, 1 ]); }); subject.onAdd(mockPokemon); @@ -79,7 +79,7 @@ describe("BattlerTag - StockpilingTag", () => { expect((phase as StatStageChangePhase)["stages"]).toEqual(1); expect((phase as StatStageChangePhase)["stats"]).toEqual(expect.arrayContaining([ Stat.DEF, Stat.SPDEF ])); - (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.DEF, Stat.SPDEF ], [1, 1]); + (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.DEF, Stat.SPDEF ], [ 1, 1 ]); }); subject.onOverlap(mockPokemon); @@ -109,7 +109,7 @@ describe("BattlerTag - StockpilingTag", () => { expect((phase as StatStageChangePhase)["stats"]).toEqual(expect.arrayContaining([ Stat.DEF, Stat.SPDEF ])); // def doesn't change - (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.SPDEF ], [1]); + (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.SPDEF ], [ 1 ]); }); subject.onAdd(mockPokemon); @@ -121,7 +121,7 @@ describe("BattlerTag - StockpilingTag", () => { expect((phase as StatStageChangePhase)["stats"]).toEqual(expect.arrayContaining([ Stat.DEF, Stat.SPDEF ])); // def doesn't change - (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.SPDEF ], [1]); + (phase as StatStageChangePhase)["onChange"]!(mockPokemon, [ Stat.SPDEF ], [ 1 ]); }); subject.onOverlap(mockPokemon); @@ -145,13 +145,13 @@ describe("BattlerTag - StockpilingTag", () => { // fourth stack should not be applied subject.onOverlap(mockPokemon); expect(subject.stockpiledCount).toBe(3); - expect(subject.statChangeCounts).toMatchObject({ [ Stat.DEF ]: 0, [Stat.SPDEF]: 2 }); + expect(subject.statChangeCounts).toMatchObject({ [Stat.DEF]: 0, [Stat.SPDEF]: 2 }); // removing tag should reverse stat changes vi.spyOn(mockPokemon.scene, "unshiftPhase").mockImplementationOnce(phase => { expect(phase).toBeInstanceOf(StatStageChangePhase); expect((phase as StatStageChangePhase)["stages"]).toEqual(-2); - expect((phase as StatStageChangePhase)["stats"]).toEqual(expect.arrayContaining([Stat.SPDEF])); + expect((phase as StatStageChangePhase)["stats"]).toEqual(expect.arrayContaining([ Stat.SPDEF ])); }); subject.onRemove(mockPokemon); diff --git a/src/test/battlerTags/substitute.test.ts b/src/test/battlerTags/substitute.test.ts index 0802b549823..af0aa63af89 100644 --- a/src/test/battlerTags/substitute.test.ts +++ b/src/test/battlerTags/substitute.test.ts @@ -122,8 +122,8 @@ describe("BattlerTag - SubstituteTag", () => { scene: new BattleScene(), hp: 101, id: 0, - turnData: {acted: true} as PokemonTurnData, - getLastXMoves: vi.fn().mockReturnValue([{move: Moves.TACKLE, result: MoveResult.SUCCESS} as TurnMove]) as Pokemon["getLastXMoves"], + turnData: { acted: true } as PokemonTurnData, + getLastXMoves: vi.fn().mockReturnValue([ { move: Moves.TACKLE, result: MoveResult.SUCCESS } as TurnMove ]) as Pokemon["getLastXMoves"], } as Pokemon; vi.spyOn(messages, "getPokemonNameWithAffix").mockReturnValue(""); diff --git a/src/test/boss-pokemon.test.ts b/src/test/boss-pokemon.test.ts index e316cac0cf6..840b65f3cc6 100644 --- a/src/test/boss-pokemon.test.ts +++ b/src/test/boss-pokemon.test.ts @@ -33,7 +33,7 @@ describe("Boss Pokemon / Shields", () => { .enemyMoveset(Moves.SPLASH) .enemyHeldItems([]) .startingLevel(1000) - .moveset([Moves.FALSE_SWIPE, Moves.SUPER_FANG, Moves.SPLASH, Moves.PSYCHIC]) + .moveset([ Moves.FALSE_SWIPE, Moves.SUPER_FANG, Moves.SPLASH, Moves.PSYCHIC ]) .ability(Abilities.NO_GUARD); }); @@ -172,7 +172,7 @@ describe("Boss Pokemon / Shields", () => { game.move.select(Moves.SPLASH); await game.toNextTurn(); // All broken shields give +1 stat boost, except the last two that gives +2 - totalStatStages += i >= shieldsToBreak -1? 2 : 1; + totalStatStages += i >= shieldsToBreak - 1 ? 2 : 1; expect(getTotalStatStageBoosts(boss1)).toBe(totalStatStages); } diff --git a/src/test/daily_mode.test.ts b/src/test/daily_mode.test.ts index 58692330272..100cf07f9c0 100644 --- a/src/test/daily_mode.test.ts +++ b/src/test/daily_mode.test.ts @@ -5,6 +5,7 @@ import { Moves } from "#app/enums/moves"; import { Biome } from "#app/enums/biome"; import { Mode } from "#app/ui/ui"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; +import { Species } from "#enums/species"; //const TIMEOUT = 20 * 1000; @@ -53,12 +54,11 @@ describe("Shop modifications", async () => { game.override .startingWave(9) - .startingBiome(Biome.ICE_CAVE) // Will lead to Snowy Forest with randomly generated weather + .startingBiome(Biome.ICE_CAVE) .battleType("single") .startingLevel(100) // Avoid levelling up - .enemyLevel(1000) // Avoid opponent dying before game.doKillOpponents() .disableTrainerWaves() - .moveset([Moves.KOWTOW_CLEAVE]) + .moveset([ Moves.SPLASH ]) .enemyMoveset(Moves.SPLASH); game.modifiers .addCheck("EVIOLITE") @@ -71,9 +71,8 @@ describe("Shop modifications", async () => { }); it("should not have Eviolite and Mini Black Hole available in Classic if not unlocked", async () => { - await game.classicMode.startBattle(); - game.move.select(Moves.KOWTOW_CLEAVE); - await game.phaseInterceptor.to("DamagePhase"); + await game.classicMode.startBattle([ Species.BULBASAUR ]); + game.move.select(Moves.SPLASH); await game.doKillOpponents(); await game.phaseInterceptor.to("BattleEndPhase"); game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => { @@ -86,8 +85,7 @@ describe("Shop modifications", async () => { it("should have Eviolite and Mini Black Hole available in Daily", async () => { await game.dailyMode.startBattle(); - game.move.select(Moves.KOWTOW_CLEAVE); - await game.phaseInterceptor.to("DamagePhase"); + game.move.select(Moves.SPLASH); await game.doKillOpponents(); await game.phaseInterceptor.to("BattleEndPhase"); game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => { diff --git a/src/test/data/splash_messages.test.ts b/src/test/data/splash_messages.test.ts index 7e07b9a6e77..b9ed5b9d365 100644 --- a/src/test/data/splash_messages.test.ts +++ b/src/test/data/splash_messages.test.ts @@ -51,8 +51,8 @@ function testSeason(startDate: Date, endDate: Date, prefix: string) { const afterDate = new Date(endDate); afterDate.setDate(endDate.getDate() + 1); - const dates: Date[] = [beforeDate, startDate, endDate, afterDate]; - const [before, start, end, after] = dates.map((date) => { + const dates: Date[] = [ beforeDate, startDate, endDate, afterDate ]; + const [ before, start, end, after ] = dates.map((date) => { vi.setSystemTime(date); console.log("System time set to", date); const count = getSplashMessages().filter(filterFn).length; diff --git a/src/test/data/status-effect.test.ts b/src/test/data/status-effect.test.ts index bca3bd21c70..1b1a97fc51f 100644 --- a/src/test/data/status-effect.test.ts +++ b/src/test/data/status-effect.test.ts @@ -1,4 +1,5 @@ import { + Status, StatusEffect, getStatusEffectActivationText, getStatusEffectDescriptor, @@ -6,14 +7,19 @@ import { getStatusEffectObtainText, getStatusEffectOverlapText, } from "#app/data/status-effect"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; import { mockI18next } from "#test/utils/testUtils"; import i18next from "i18next"; -import { afterEach, beforeAll, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const pokemonName = "PKM"; const sourceText = "SOURCE"; -describe("status-effect", () => { +describe("Status Effect Messages", () => { beforeAll(() => { i18next.init(); }); @@ -299,3 +305,99 @@ describe("status-effect", () => { vi.resetAllMocks(); }); }); + +describe("Status Effects", () => { + describe("Paralysis", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override + .enemySpecies(Species.MAGIKARP) + .enemyMoveset(Moves.SPLASH) + .enemyAbility(Abilities.BALL_FETCH) + .moveset([ Moves.QUICK_ATTACK ]) + .ability(Abilities.BALL_FETCH) + .statusEffect(StatusEffect.PARALYSIS); + }); + + it("causes the pokemon's move to fail when activated", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + game.move.select(Moves.QUICK_ATTACK); + await game.move.forceStatusActivation(true); + await game.toNextTurn(); + + expect(game.scene.getEnemyPokemon()!.isFullHp()).toBe(true); + expect(game.scene.getPlayerPokemon()!.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + }); + }); + + describe("Sleep", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.SPLASH ]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should last the appropriate number of turns", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const player = game.scene.getPlayerPokemon()!; + player.status = new Status(StatusEffect.SLEEP, 0, 4); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status.effect).toBe(StatusEffect.SLEEP); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status.effect).toBe(StatusEffect.SLEEP); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status.effect).toBe(StatusEffect.SLEEP); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(player.status?.effect).toBeUndefined(); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + }); + }); +}); diff --git a/src/test/eggs/egg.test.ts b/src/test/eggs/egg.test.ts index 053ff8f1112..aebb196ff5e 100644 --- a/src/test/eggs/egg.test.ts +++ b/src/test/eggs/egg.test.ts @@ -1,4 +1,7 @@ -import { Egg, getLegendaryGachaSpeciesForTimestamp } from "#app/data/egg"; +import { speciesEggTiers } from "#app/data/balance/species-egg-tiers"; +import { speciesStarterCosts } from "#app/data/balance/starters"; +import { Egg, getLegendaryGachaSpeciesForTimestamp, getValidLegendaryGachaSpecies } from "#app/data/egg"; +import { allSpecies } from "#app/data/pokemon-species"; import { EggSourceType } from "#app/enums/egg-source-types"; import { EggTier } from "#app/enums/egg-type"; import { VariantTier } from "#app/enums/variant-tier"; @@ -55,7 +58,7 @@ describe("Egg Generation Tests", () => { let gachaSpeciesCount = 0; for (let i = 0; i < EGG_HATCH_COUNT; i++) { - const result = new Egg({ scene, timestamp, sourceType: EggSourceType.GACHA_LEGENDARY, tier: EggTier.MASTER }).generatePlayerPokemon(scene).species.speciesId; + const result = new Egg({ scene, timestamp, sourceType: EggSourceType.GACHA_LEGENDARY, tier: EggTier.LEGENDARY }).generatePlayerPokemon(scene).species.speciesId; if (result === expectedSpecies) { gachaSpeciesCount++; } @@ -64,6 +67,12 @@ describe("Egg Generation Tests", () => { expect(gachaSpeciesCount).toBeGreaterThan(0.4 * EGG_HATCH_COUNT); expect(gachaSpeciesCount).toBeLessThan(0.6 * EGG_HATCH_COUNT); }); + it("should never be allowed to generate Eternatus via the legendary gacha", () => { + const validLegendaryGachaSpecies = getValidLegendaryGachaSpecies(); + expect(validLegendaryGachaSpecies.every(s => speciesEggTiers[s] === EggTier.LEGENDARY)).toBe(true); + expect(validLegendaryGachaSpecies.every(s => allSpecies[s].isObtainable())).toBe(true); + expect(validLegendaryGachaSpecies.includes(Species.ETERNATUS)).toBe(false); + }); it("should hatch an Arceus. Set from species", () => { const scene = game.scene; const expectedSpecies = Species.ARCEUS; @@ -82,7 +91,7 @@ describe("Egg Generation Tests", () => { }); it("should return an rare tier egg", () => { const scene = game.scene; - const expectedTier = EggTier.GREAT; + const expectedTier = EggTier.RARE; const result = new Egg({ scene, tier: expectedTier }).tier; @@ -90,7 +99,7 @@ describe("Egg Generation Tests", () => { }); it("should return an epic tier egg", () => { const scene = game.scene; - const expectedTier = EggTier.ULTRA; + const expectedTier = EggTier.EPIC; const result = new Egg({ scene, tier: expectedTier }).tier; @@ -98,7 +107,7 @@ describe("Egg Generation Tests", () => { }); it("should return an legendary tier egg", () => { const scene = game.scene; - const expectedTier = EggTier.MASTER; + const expectedTier = EggTier.LEGENDARY; const result = new Egg({ scene, tier: expectedTier }).tier; @@ -200,7 +209,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const expectedEggTier = EggTier.COMMON; - const result = new Egg({ scene, tier: EggTier.MASTER, species: Species.BULBASAUR }).tier; + const result = new Egg({ scene, tier: EggTier.LEGENDARY, species: Species.BULBASAUR }).tier; expect(result).toBe(expectedEggTier); }); @@ -208,7 +217,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const expectedHatchWaves = 10; - const result = new Egg({ scene, tier: EggTier.MASTER, species: Species.BULBASAUR }).hatchWaves; + const result = new Egg({ scene, tier: EggTier.LEGENDARY, species: Species.BULBASAUR }).hatchWaves; expect(result).toBe(expectedHatchWaves); }); @@ -229,7 +238,7 @@ describe("Egg Generation Tests", () => { const result = new EggData(legacyEgg).toEgg(); - expect(result.tier).toBe(EggTier.GREAT); + expect(result.tier).toBe(EggTier.RARE); expect(result.id).toBe(legacyEgg.id); expect(result.timestamp).toBe(legacyEgg.timestamp); expect(result.hatchWaves).toBe(legacyEgg.hatchWaves); @@ -237,23 +246,23 @@ describe("Egg Generation Tests", () => { }); it("should increase egg pity", () => { const scene = game.scene; - const startPityValues = [...scene.gameData.eggPity]; + const startPityValues = [ ...scene.gameData.eggPity ]; new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.COMMON }); - expect(scene.gameData.eggPity[EggTier.GREAT]).toBe(startPityValues[EggTier.GREAT] + 1); - expect(scene.gameData.eggPity[EggTier.ULTRA]).toBe(startPityValues[EggTier.ULTRA] + 1); - expect(scene.gameData.eggPity[EggTier.MASTER]).toBe(startPityValues[EggTier.MASTER] + 1); + expect(scene.gameData.eggPity[EggTier.RARE]).toBe(startPityValues[EggTier.RARE] + 1); + expect(scene.gameData.eggPity[EggTier.EPIC]).toBe(startPityValues[EggTier.EPIC] + 1); + expect(scene.gameData.eggPity[EggTier.LEGENDARY]).toBe(startPityValues[EggTier.LEGENDARY] + 1); }); it("should increase legendary egg pity by two", () => { const scene = game.scene; - const startPityValues = [...scene.gameData.eggPity]; + const startPityValues = [ ...scene.gameData.eggPity ]; new Egg({ scene, sourceType: EggSourceType.GACHA_LEGENDARY, pulled: true, tier: EggTier.COMMON }); - expect(scene.gameData.eggPity[EggTier.GREAT]).toBe(startPityValues[EggTier.GREAT] + 1); - expect(scene.gameData.eggPity[EggTier.ULTRA]).toBe(startPityValues[EggTier.ULTRA] + 1); - expect(scene.gameData.eggPity[EggTier.MASTER]).toBe(startPityValues[EggTier.MASTER] + 2); + expect(scene.gameData.eggPity[EggTier.RARE]).toBe(startPityValues[EggTier.RARE] + 1); + expect(scene.gameData.eggPity[EggTier.EPIC]).toBe(startPityValues[EggTier.EPIC] + 1); + expect(scene.gameData.eggPity[EggTier.LEGENDARY]).toBe(startPityValues[EggTier.LEGENDARY] + 2); }); it("should not increase manaphy egg count if bulbasaurs are pulled", () => { const scene = game.scene; @@ -277,7 +286,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const startingRareEggsPulled = scene.gameData.gameStats.rareEggsPulled; - new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.GREAT }); + new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.RARE }); expect(scene.gameData.gameStats.rareEggsPulled).toBe(startingRareEggsPulled + 1); }); @@ -285,7 +294,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const startingEpicEggsPulled = scene.gameData.gameStats.epicEggsPulled; - new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.ULTRA }); + new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.EPIC }); expect(scene.gameData.gameStats.epicEggsPulled).toBe(startingEpicEggsPulled + 1); }); @@ -293,7 +302,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const startingLegendaryEggsPulled = scene.gameData.gameStats.legendaryEggsPulled; - new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.MASTER }); + new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.LEGENDARY }); expect(scene.gameData.gameStats.legendaryEggsPulled).toBe(startingLegendaryEggsPulled + 1); }); @@ -301,8 +310,8 @@ describe("Egg Generation Tests", () => { vi.spyOn(Utils, "randInt").mockReturnValue(1); const scene = game.scene; - const expectedTier1 = EggTier.MASTER; - const expectedTier2 = EggTier.ULTRA; + const expectedTier1 = EggTier.LEGENDARY; + const expectedTier2 = EggTier.EPIC; const result1 = new Egg({ scene, sourceType: EggSourceType.GACHA_LEGENDARY, pulled: true }).tier; const result2 = new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true }).tier; @@ -323,7 +332,7 @@ describe("Egg Generation Tests", () => { scene.setSeed("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); scene.resetSeed(); - const firstEgg = new Egg({scene, sourceType: EggSourceType.GACHA_SHINY, tier: EggTier.COMMON}); + const firstEgg = new Egg({ scene, sourceType: EggSourceType.GACHA_SHINY, tier: EggTier.COMMON }); const firstHatch = firstEgg.generatePlayerPokemon(scene); let diffEggMove = false; let diffSpecies = false; @@ -334,7 +343,7 @@ describe("Egg Generation Tests", () => { scene.setSeed("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); scene.resetSeed(); // Make sure that eggs are unpredictable even if using same seed - const newEgg = new Egg({scene, sourceType: EggSourceType.GACHA_SHINY, tier: EggTier.COMMON}); + const newEgg = new Egg({ scene, sourceType: EggSourceType.GACHA_SHINY, tier: EggTier.COMMON }); const newHatch = newEgg.generatePlayerPokemon(scene); diffEggMove = diffEggMove || (newEgg.eggMoveIndex !== firstEgg.eggMoveIndex); diffSpecies = diffSpecies || (newHatch.species.speciesId !== firstHatch.species.speciesId); @@ -353,7 +362,7 @@ describe("Egg Generation Tests", () => { scene.setSeed("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); scene.resetSeed(); - const firstEgg = new Egg({scene, species: Species.BULBASAUR}); + const firstEgg = new Egg({ scene, species: Species.BULBASAUR }); const firstHatch = firstEgg.generatePlayerPokemon(scene); let diffEggMove = false; let diffSpecies = false; @@ -363,7 +372,7 @@ describe("Egg Generation Tests", () => { scene.setSeed("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); scene.resetSeed(); // Make sure that eggs are unpredictable even if using same seed - const newEgg = new Egg({scene, species: Species.BULBASAUR}); + const newEgg = new Egg({ scene, species: Species.BULBASAUR }); const newHatch = newEgg.generatePlayerPokemon(scene); diffEggMove = diffEggMove || (newEgg.eggMoveIndex !== firstEgg.eggMoveIndex); diffSpecies = diffSpecies || (newHatch.species.speciesId !== firstHatch.species.speciesId); @@ -376,4 +385,23 @@ describe("Egg Generation Tests", () => { expect(diffShiny).toBe(true); expect(diffAbility).toBe(true); }); + + // For now, we are using this test to detect oversights in egg tiers. + // Delete this test if the balance team rebalances species costs independently of egg tiers. + it("should have correct egg tiers based on species costs", () => { + const getExpectedEggTier = (starterCost) => + starterCost <= 3 ? EggTier.COMMON + : starterCost <= 5 ? EggTier.RARE + : starterCost <= 7 ? EggTier.EPIC + : EggTier.LEGENDARY; + + allSpecies.forEach(pokemonSpecies => { + const rootSpecies = pokemonSpecies.getRootSpeciesId(); + const speciesCost = speciesStarterCosts[rootSpecies]; + const expectedEggTier = getExpectedEggTier(speciesCost); + const actualEggTier = speciesEggTiers[rootSpecies]; + + expect(actualEggTier).toBe(expectedEggTier); + }); + }); }); diff --git a/src/test/eggs/manaphy-egg.test.ts b/src/test/eggs/manaphy-egg.test.ts index 257bf330bb8..3b2c40ae84a 100644 --- a/src/test/eggs/manaphy-egg.test.ts +++ b/src/test/eggs/manaphy-egg.test.ts @@ -60,8 +60,8 @@ describe("Manaphy Eggs", () => { } expect(manaphyCount + phioneCount).toBe(EGG_HATCH_COUNT); - expect(manaphyCount).toBe(1/8 * EGG_HATCH_COUNT); - expect(rareEggMoveCount).toBe(1/12 * EGG_HATCH_COUNT); + expect(manaphyCount).toBe(1 / 8 * EGG_HATCH_COUNT); + expect(rareEggMoveCount).toBe(1 / 12 * EGG_HATCH_COUNT); }); it("should have correct Manaphy rates and Rare Egg Move rates, from Phione species eggs", () => { @@ -86,8 +86,8 @@ describe("Manaphy Eggs", () => { } expect(manaphyCount + phioneCount).toBe(EGG_HATCH_COUNT); - expect(manaphyCount).toBe(1/8 * EGG_HATCH_COUNT); - expect(rareEggMoveCount).toBe(1/6 * EGG_HATCH_COUNT); + expect(manaphyCount).toBe(1 / 8 * EGG_HATCH_COUNT); + expect(rareEggMoveCount).toBe(1 / 6 * EGG_HATCH_COUNT); }); it("should have correct Manaphy rates and Rare Egg Move rates, from Manaphy species eggs", () => { @@ -113,6 +113,6 @@ describe("Manaphy Eggs", () => { expect(phioneCount).toBe(0); expect(manaphyCount).toBe(EGG_HATCH_COUNT); - expect(rareEggMoveCount).toBe(1/6 * EGG_HATCH_COUNT); + expect(rareEggMoveCount).toBe(1 / 6 * EGG_HATCH_COUNT); }); }); diff --git a/src/test/endless_boss.test.ts b/src/test/endless_boss.test.ts index 8a564695e42..c9f3afc3936 100644 --- a/src/test/endless_boss.test.ts +++ b/src/test/endless_boss.test.ts @@ -32,7 +32,7 @@ describe("Endless Boss", () => { it(`should spawn a minor boss every ${EndlessBossWave.Minor} waves in END biome in Endless`, async () => { game.override.startingWave(EndlessBossWave.Minor); - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.ENDLESS); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.ENDLESS); expect(game.scene.currentBattle.waveIndex).toBe(EndlessBossWave.Minor); expect(game.scene.arena.biomeType).toBe(Biome.END); @@ -44,7 +44,7 @@ describe("Endless Boss", () => { it(`should spawn a major boss every ${EndlessBossWave.Major} waves in END biome in Endless`, async () => { game.override.startingWave(EndlessBossWave.Major); - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.ENDLESS); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.ENDLESS); expect(game.scene.currentBattle.waveIndex).toBe(EndlessBossWave.Major); expect(game.scene.arena.biomeType).toBe(Biome.END); @@ -56,7 +56,7 @@ describe("Endless Boss", () => { it(`should spawn a minor boss every ${EndlessBossWave.Minor} waves in END biome in Spliced Endless`, async () => { game.override.startingWave(EndlessBossWave.Minor); - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.SPLICED_ENDLESS); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.SPLICED_ENDLESS); expect(game.scene.currentBattle.waveIndex).toBe(EndlessBossWave.Minor); expect(game.scene.arena.biomeType).toBe(Biome.END); @@ -68,7 +68,7 @@ describe("Endless Boss", () => { it(`should spawn a major boss every ${EndlessBossWave.Major} waves in END biome in Spliced Endless`, async () => { game.override.startingWave(EndlessBossWave.Major); - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.SPLICED_ENDLESS); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.SPLICED_ENDLESS); expect(game.scene.currentBattle.waveIndex).toBe(EndlessBossWave.Major); expect(game.scene.arena.biomeType).toBe(Biome.END); @@ -80,7 +80,7 @@ describe("Endless Boss", () => { it(`should NOT spawn major or minor boss outside wave ${EndlessBossWave.Minor}s in END biome`, async () => { game.override.startingWave(EndlessBossWave.Minor - 1); - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.ENDLESS); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.ENDLESS); expect(game.scene.currentBattle.waveIndex).not.toBe(EndlessBossWave.Minor); expect(game.scene.getEnemyPokemon()!.species.speciesId).not.toBe(Species.ETERNATUS); diff --git a/src/test/enemy_command.test.ts b/src/test/enemy_command.test.ts index 53cddc86efb..49419f5b34d 100644 --- a/src/test/enemy_command.test.ts +++ b/src/test/enemy_command.test.ts @@ -23,7 +23,7 @@ function getEnemyMoveChoices(pokemon: EnemyPokemon, moveChoices: MoveChoiceSet): moveChoices[queuedMove.move]++; } - for (const [moveId, count] of Object.entries(moveChoices)) { + for (const [ moveId, count ] of Object.entries(moveChoices)) { console.log(`Move: ${allMoves[moveId].name} Count: ${count} (${count / NUM_TRIALS * 100}%)`); } } @@ -55,11 +55,11 @@ describe("Enemy Commands - Move Selection", () => { async () => { game.override .enemySpecies(Species.ETERNATUS) - .enemyMoveset([Moves.ETERNABEAM, Moves.SLUDGE_BOMB, Moves.DRAGON_DANCE, Moves.COSMIC_POWER]) + .enemyMoveset([ Moves.ETERNABEAM, Moves.SLUDGE_BOMB, Moves.DRAGON_DANCE, Moves.COSMIC_POWER ]) .startingLevel(1) .enemyLevel(100); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const enemyPokemon = game.scene.getEnemyPokemon()!; enemyPokemon.aiType = AiType.SMART_RANDOM; @@ -82,11 +82,11 @@ describe("Enemy Commands - Move Selection", () => { async () => { game.override .enemySpecies(Species.KANGASKHAN) - .enemyMoveset([Moves.LAST_RESORT, Moves.GIGA_IMPACT, Moves.SPLASH, Moves.SWORDS_DANCE]) + .enemyMoveset([ Moves.LAST_RESORT, Moves.GIGA_IMPACT, Moves.SPLASH, Moves.SWORDS_DANCE ]) .startingLevel(1) .enemyLevel(100); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const enemyPokemon = game.scene.getEnemyPokemon()!; enemyPokemon.aiType = AiType.SMART_RANDOM; diff --git a/src/test/escape-calculations.test.ts b/src/test/escape-calculations.test.ts index ecf22fc74aa..cc18fd78066 100644 --- a/src/test/escape-calculations.test.ts +++ b/src/test/escape-calculations.test.ts @@ -32,13 +32,13 @@ describe("Escape chance calculations", () => { }); it("single non-boss opponent", async () => { - await game.classicMode.startBattle([Species.BULBASAUR]); + await game.classicMode.startBattle([ Species.BULBASAUR ]); const playerPokemon = game.scene.getPlayerField(); const enemyField = game.scene.getEnemyField(); const enemySpeed = 100; // set enemyPokemon's speed to 100 - vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemySpeed]); + vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, enemySpeed ]); const commandPhase = game.scene.getCurrentPhase() as CommandPhase; commandPhase.handleCommand(Command.RUN, 0); @@ -79,7 +79,7 @@ describe("Escape chance calculations", () => { // sets the number of escape attempts to the required amount game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts; // set playerPokemon's speed to a multiple of the enemySpeed - vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, escapeChances[i].pokemonSpeedRatio * enemySpeed]); + vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, escapeChances[i].pokemonSpeedRatio * enemySpeed ]); phase.attemptRunAway(playerPokemon, enemyField, escapePercentage); expect(escapePercentage.value).toBe(escapeChances[i].expectedEscapeChance); } @@ -87,7 +87,7 @@ describe("Escape chance calculations", () => { it("double non-boss opponent", async () => { game.override.battleType("double"); - await game.classicMode.startBattle([Species.BULBASAUR, Species.ABOMASNOW]); + await game.classicMode.startBattle([ Species.BULBASAUR, Species.ABOMASNOW ]); const playerPokemon = game.scene.getPlayerField(); const enemyField = game.scene.getEnemyField(); @@ -98,9 +98,9 @@ describe("Escape chance calculations", () => { // this is used to find the ratio of the player's first pokemon const playerASpeedPercentage = 0.4; // set enemyAPokemon's speed to 70 - vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemyASpeed]); + vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, enemyASpeed ]); // set enemyBPokemon's speed to 30 - vi.spyOn(enemyField[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemyBSpeed]); + vi.spyOn(enemyField[1], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, enemyBSpeed ]); const commandPhase = game.scene.getCurrentPhase() as CommandPhase; commandPhase.handleCommand(Command.RUN, 0); @@ -141,9 +141,9 @@ describe("Escape chance calculations", () => { // sets the number of escape attempts to the required amount game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts; // set the first playerPokemon's speed to a multiple of the enemySpeed - vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, Math.floor(escapeChances[i].pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage)]); + vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, Math.floor(escapeChances[i].pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage) ]); // set the second playerPokemon's speed to the remaining value of speed - vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, escapeChances[i].pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5]]); + vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, escapeChances[i].pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5] ]); phase.attemptRunAway(playerPokemon, enemyField, escapePercentage); // checks to make sure the escape values are the same expect(escapePercentage.value).toBe(escapeChances[i].expectedEscapeChance); @@ -154,13 +154,13 @@ describe("Escape chance calculations", () => { it("single boss opponent", async () => { game.override.startingWave(10); - await game.classicMode.startBattle([Species.BULBASAUR]); + await game.classicMode.startBattle([ Species.BULBASAUR ]); const playerPokemon = game.scene.getPlayerField()!; const enemyField = game.scene.getEnemyField()!; const enemySpeed = 100; // set enemyPokemon's speed to 100 - vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemySpeed]); + vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, enemySpeed ]); const commandPhase = game.scene.getCurrentPhase() as CommandPhase; commandPhase.handleCommand(Command.RUN, 0); @@ -215,7 +215,7 @@ describe("Escape chance calculations", () => { // sets the number of escape attempts to the required amount game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts; // set playerPokemon's speed to a multiple of the enemySpeed - vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, escapeChances[i].pokemonSpeedRatio * enemySpeed]); + vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, escapeChances[i].pokemonSpeedRatio * enemySpeed ]); phase.attemptRunAway(playerPokemon, enemyField, escapePercentage); expect(escapePercentage.value).toBe(escapeChances[i].expectedEscapeChance); } @@ -224,7 +224,7 @@ describe("Escape chance calculations", () => { it("double boss opponent", async () => { game.override.battleType("double"); game.override.startingWave(10); - await game.classicMode.startBattle([Species.BULBASAUR, Species.ABOMASNOW]); + await game.classicMode.startBattle([ Species.BULBASAUR, Species.ABOMASNOW ]); const playerPokemon = game.scene.getPlayerField(); const enemyField = game.scene.getEnemyField(); @@ -235,9 +235,9 @@ describe("Escape chance calculations", () => { // this is used to find the ratio of the player's first pokemon const playerASpeedPercentage = 0.8; // set enemyAPokemon's speed to 70 - vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemyASpeed]); + vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, enemyASpeed ]); // set enemyBPokemon's speed to 30 - vi.spyOn(enemyField[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemyBSpeed]); + vi.spyOn(enemyField[1], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, enemyBSpeed ]); const commandPhase = game.scene.getCurrentPhase() as CommandPhase; commandPhase.handleCommand(Command.RUN, 0); @@ -290,9 +290,9 @@ describe("Escape chance calculations", () => { // sets the number of escape attempts to the required amount game.scene.currentBattle.escapeAttempts = escapeChances[i].escapeAttempts; // set the first playerPokemon's speed to a multiple of the enemySpeed - vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, Math.floor(escapeChances[i].pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage)]); + vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, Math.floor(escapeChances[i].pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage) ]); // set the second playerPokemon's speed to the remaining value of speed - vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, escapeChances[i].pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5]]); + vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([ 20, 20, 20, 20, 20, escapeChances[i].pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5] ]); phase.attemptRunAway(playerPokemon, enemyField, escapePercentage); // checks to make sure the escape values are the same expect(escapePercentage.value).toBe(escapeChances[i].expectedEscapeChance); diff --git a/src/test/evolution.test.ts b/src/test/evolution.test.ts index 1a5a2be996f..b94d45d6537 100644 --- a/src/test/evolution.test.ts +++ b/src/test/evolution.test.ts @@ -33,7 +33,7 @@ describe("Evolution", () => { }); it("should keep hidden ability after evolving", async () => { - await game.classicMode.runToSummon([Species.EEVEE, Species.TRAPINCH]); + await game.classicMode.runToSummon([ Species.EEVEE, Species.TRAPINCH ]); const eevee = game.scene.getParty()[0]; const trapinch = game.scene.getParty()[1]; @@ -48,7 +48,7 @@ describe("Evolution", () => { }); it("should keep same ability slot after evolving", async () => { - await game.classicMode.runToSummon([Species.BULBASAUR, Species.CHARMANDER]); + await game.classicMode.runToSummon([ Species.BULBASAUR, Species.CHARMANDER ]); const bulbasaur = game.scene.getParty()[0]; const charmander = game.scene.getParty()[1]; @@ -63,7 +63,7 @@ describe("Evolution", () => { }); it("should handle illegal abilityIndex values", async () => { - await game.classicMode.runToSummon([Species.SQUIRTLE]); + await game.classicMode.runToSummon([ Species.SQUIRTLE ]); const squirtle = game.scene.getPlayerPokemon()!; squirtle.abilityIndex = 5; @@ -73,7 +73,7 @@ describe("Evolution", () => { }); it("should handle nincada's unique evolution", async () => { - await game.classicMode.runToSummon([Species.NINCADA]); + await game.classicMode.runToSummon([ Species.NINCADA ]); const nincada = game.scene.getPlayerPokemon()!; nincada.abilityIndex = 2; @@ -95,14 +95,14 @@ describe("Evolution", () => { }); it("should increase both HP and max HP when evolving", async () => { - game.override.moveset([Moves.SURF]) + game.override.moveset([ Moves.SURF ]) .enemySpecies(Species.GOLEM) .enemyMoveset(Moves.SPLASH) .startingWave(21) .startingLevel(16) .enemyLevel(50); - await game.startBattle([Species.TOTODILE]); + await game.startBattle([ Species.TOTODILE ]); const totodile = game.scene.getPlayerPokemon()!; const hpBefore = totodile.hp; @@ -122,14 +122,14 @@ describe("Evolution", () => { }); it("should not fully heal HP when evolving", async () => { - game.override.moveset([Moves.SURF]) + game.override.moveset([ Moves.SURF ]) .enemySpecies(Species.GOLEM) .enemyMoveset(Moves.SPLASH) .startingWave(21) .startingLevel(13) .enemyLevel(30); - await game.startBattle([Species.CYNDAQUIL]); + await game.startBattle([ Species.CYNDAQUIL ]); const cyndaquil = game.scene.getPlayerPokemon()!; cyndaquil.hp = Math.floor(cyndaquil.getMaxHp() / 2); @@ -162,7 +162,7 @@ describe("Evolution", () => { * If the value is 0, it's a 3 family maushold, whereas if the value is * 1, 2 or 3, it's a 4 family maushold */ - await game.startBattle([Species.TANDEMAUS]); // starts us off with a tandemaus + await game.startBattle([ Species.TANDEMAUS ]); // starts us off with a tandemaus const playerPokemon = game.scene.getPlayerPokemon()!; playerPokemon.level = 25; // tandemaus evolves at level 25 vi.spyOn(Utils, "randSeedInt").mockReturnValue(0); // setting the random generator to be 0 to force a three family maushold diff --git a/src/test/field/pokemon.test.ts b/src/test/field/pokemon.test.ts index 225f302ff0c..aeaecab5874 100644 --- a/src/test/field/pokemon.test.ts +++ b/src/test/field/pokemon.test.ts @@ -24,7 +24,7 @@ describe("Spec - Pokemon", () => { }); it("should not crash when trying to set status of undefined", async () => { - await game.classicMode.runToSummon([Species.ABRA]); + await game.classicMode.runToSummon([ Species.ABRA ]); const pkm = game.scene.getPlayerPokemon()!; expect(pkm).toBeDefined(); @@ -37,7 +37,7 @@ describe("Spec - Pokemon", () => { beforeEach(async () => { game.override.enemySpecies(Species.ZUBAT); - await game.classicMode.runToSummon([Species.ABRA, Species.ABRA, Species.ABRA, Species.ABRA, Species.ABRA]); // 5 Abra, only 1 slot left + await game.classicMode.runToSummon([ Species.ABRA, Species.ABRA, Species.ABRA, Species.ABRA, Species.ABRA ]); // 5 Abra, only 1 slot left scene = game.scene; }); @@ -68,7 +68,7 @@ describe("Spec - Pokemon", () => { it("should not share tms between different forms", async () => { game.override.starterForms({ [Species.ROTOM]: 4 }); - await game.classicMode.startBattle([Species.ROTOM]); + await game.classicMode.startBattle([ Species.ROTOM ]); const fanRotom = game.scene.getPlayerPokemon()!; diff --git a/src/test/final_boss.test.ts b/src/test/final_boss.test.ts index fee4dc6c8f6..de2cddff944 100644 --- a/src/test/final_boss.test.ts +++ b/src/test/final_boss.test.ts @@ -38,7 +38,7 @@ describe("Final Boss", () => { }); it("should spawn Eternatus on wave 200 in END biome", async () => { - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.CLASSIC); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.CLASSIC); expect(game.scene.currentBattle.waveIndex).toBe(FinalWave.Classic); expect(game.scene.arena.biomeType).toBe(Biome.END); @@ -47,7 +47,7 @@ describe("Final Boss", () => { it("should NOT spawn Eternatus before wave 200 in END biome", async () => { game.override.startingWave(FinalWave.Classic - 1); - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.CLASSIC); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.CLASSIC); expect(game.scene.currentBattle.waveIndex).not.toBe(FinalWave.Classic); expect(game.scene.arena.biomeType).toBe(Biome.END); @@ -56,7 +56,7 @@ describe("Final Boss", () => { it("should NOT spawn Eternatus outside of END biome", async () => { game.override.startingBiome(Biome.FOREST); - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.CLASSIC); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.CLASSIC); expect(game.scene.currentBattle.waveIndex).toBe(FinalWave.Classic); expect(game.scene.arena.biomeType).not.toBe(Biome.END); @@ -64,7 +64,7 @@ describe("Final Boss", () => { }); it("should not have passive enabled on Eternatus", async () => { - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.CLASSIC); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.CLASSIC); const eternatus = game.scene.getEnemyPokemon()!; expect(eternatus.species.speciesId).toBe(Species.ETERNATUS); @@ -72,7 +72,7 @@ describe("Final Boss", () => { }); it("should change form on direct hit down to last boss fragment", async () => { - await game.runToFinalBossEncounter([Species.KYUREM], GameModes.CLASSIC); + await game.runToFinalBossEncounter([ Species.KYUREM ], GameModes.CLASSIC); await game.phaseInterceptor.to("CommandPhase"); // Eternatus phase 1 @@ -101,7 +101,7 @@ describe("Final Boss", () => { it("should change form on status damage down to last boss fragment", async () => { game.override.ability(Abilities.NO_GUARD); - await game.runToFinalBossEncounter([Species.BIDOOF], GameModes.CLASSIC); + await game.runToFinalBossEncounter([ Species.BIDOOF ], GameModes.CLASSIC); await game.phaseInterceptor.to("CommandPhase"); // Eternatus phase 1 diff --git a/src/test/internals.test.ts b/src/test/internals.test.ts index 3c76b40e901..ce2cd55dbc6 100644 --- a/src/test/internals.test.ts +++ b/src/test/internals.test.ts @@ -23,7 +23,7 @@ describe("Internals", () => { }); it("should provide Eevee with 3 defined abilities", async () => { - await game.classicMode.runToSummon([Species.EEVEE]); + await game.classicMode.runToSummon([ Species.EEVEE ]); const eevee = game.scene.getPlayerPokemon()!; expect(eevee.getSpeciesForm().getAbilityCount()).toBe(3); @@ -34,7 +34,7 @@ describe("Internals", () => { }); it("should set Eeeve abilityIndex between 0-2", async () => { - await game.classicMode.runToSummon([Species.EEVEE]); + await game.classicMode.runToSummon([ Species.EEVEE ]); const eevee = game.scene.getPlayerPokemon()!; expect(eevee.abilityIndex).toBeGreaterThanOrEqual(0); diff --git a/src/test/items/exp_booster.test.ts b/src/test/items/exp_booster.test.ts index 9a7464e4866..36107329706 100644 --- a/src/test/items/exp_booster.test.ts +++ b/src/test/items/exp_booster.test.ts @@ -28,7 +28,7 @@ describe("EXP Modifier Items", () => { }); it("EXP booster items stack multiplicatively", async() => { - game.override.startingHeldItems([{name: "LUCKY_EGG", count: 3}, {name: "GOLDEN_EGG"}]); + game.override.startingHeldItems([{ name: "LUCKY_EGG", count: 3 }, { name: "GOLDEN_EGG" }]); await game.startBattle(); const partyMember = game.scene.getPlayerPokemon()!; diff --git a/src/test/items/grip_claw.test.ts b/src/test/items/grip_claw.test.ts index 29d39cabc3e..2909549af87 100644 --- a/src/test/items/grip_claw.test.ts +++ b/src/test/items/grip_claw.test.ts @@ -1,16 +1,14 @@ import { BattlerIndex } from "#app/battle"; -import { allMoves } from "#app/data/move"; -import { Abilities } from "#app/enums/abilities"; -import { BerryType } from "#app/enums/berry-type"; -import { Moves } from "#app/enums/moves"; -import { Species } from "#app/enums/species"; -import { MoveEndPhase } from "#app/phases/move-end-phase"; +import Pokemon from "#app/field/pokemon"; +import { ContactHeldItemTransferChanceModifier } from "#app/modifier/modifier"; +import { Abilities } from "#enums/abilities"; +import { BerryType } from "#enums/berry-type"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import Phase from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -// 20 seconds - describe("Items - Grip Claw", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,39 +28,85 @@ describe("Items - Grip Claw", () => { game.override .battleType("double") - .moveset([Moves.POPULATION_BOMB, Moves.SPLASH]) + .moveset([ Moves.TACKLE, Moves.SPLASH, Moves.ATTRACT ]) .startingHeldItems([ - { name: "GRIP_CLAW", count: 5 }, // TODO: Find a way to mock the steal chance of grip claw - { name: "MULTI_LENS", count: 3 }, + { name: "GRIP_CLAW", count: 1 }, ]) .enemySpecies(Species.SNORLAX) - .ability(Abilities.KLUTZ) + .enemyAbility(Abilities.UNNERVE) + .ability(Abilities.UNNERVE) .enemyMoveset(Moves.SPLASH) .enemyHeldItems([ { name: "BERRY", type: BerryType.SITRUS, count: 2 }, { name: "BERRY", type: BerryType.LUM, count: 2 }, ]) - .startingLevel(100) .enemyLevel(100); - vi.spyOn(allMoves[Moves.POPULATION_BOMB], "accuracy", "get").mockReturnValue(100); }); - it( - "should only steal items from the attack target", - async () => { - await game.startBattle([Species.PANSEAR, Species.ROWLET]); + it("should steal items on contact and only from the attack target", async () => { + await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]); - const enemyPokemon = game.scene.getEnemyField(); + const [ playerPokemon, ] = game.scene.getPlayerField(); - const enemyHeldItemCt = enemyPokemon.map(p => p.getHeldItems.length); + const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier; + vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100); - game.move.select(Moves.POPULATION_BOMB, 0, BattlerIndex.ENEMY); - game.move.select(Moves.SPLASH, 1); + const enemyPokemon = game.scene.getEnemyField(); - await game.phaseInterceptor.to(MoveEndPhase, false); + const playerHeldItemCount = getHeldItemCount(playerPokemon); + const enemy1HeldItemCount = getHeldItemCount(enemyPokemon[0]); + const enemy2HeldItemCount = getHeldItemCount(enemyPokemon[1]); + expect(enemy2HeldItemCount).toBeGreaterThan(0); - expect(enemyPokemon[1].getHeldItems.length).toBe(enemyHeldItemCt[1]); - } - ); + game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY_2); + game.move.select(Moves.SPLASH, 1); + + await game.phaseInterceptor.to("BerryPhase", false); + + const playerHeldItemCountAfter = getHeldItemCount(playerPokemon); + const enemy1HeldItemCountsAfter = getHeldItemCount(enemyPokemon[0]); + const enemy2HeldItemCountsAfter = getHeldItemCount(enemyPokemon[1]); + + expect(playerHeldItemCountAfter).toBe(playerHeldItemCount + 1); + expect(enemy1HeldItemCountsAfter).toBe(enemy1HeldItemCount); + expect(enemy2HeldItemCountsAfter).toBe(enemy2HeldItemCount - 1); + }); + + it("should not steal items when using a targetted, non attack move", async () => { + await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]); + + const [ playerPokemon, ] = game.scene.getPlayerField(); + + const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier; + vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100); + + const enemyPokemon = game.scene.getEnemyField(); + + const playerHeldItemCount = getHeldItemCount(playerPokemon); + const enemy1HeldItemCount = getHeldItemCount(enemyPokemon[0]); + const enemy2HeldItemCount = getHeldItemCount(enemyPokemon[1]); + expect(enemy2HeldItemCount).toBeGreaterThan(0); + + game.move.select(Moves.ATTRACT, 0, BattlerIndex.ENEMY_2); + game.move.select(Moves.SPLASH, 1); + + await game.phaseInterceptor.to("BerryPhase", false); + + const playerHeldItemCountAfter = getHeldItemCount(playerPokemon); + const enemy1HeldItemCountsAfter = getHeldItemCount(enemyPokemon[0]); + const enemy2HeldItemCountsAfter = getHeldItemCount(enemyPokemon[1]); + + expect(playerHeldItemCountAfter).toBe(playerHeldItemCount); + expect(enemy1HeldItemCountsAfter).toBe(enemy1HeldItemCount); + expect(enemy2HeldItemCountsAfter).toBe(enemy2HeldItemCount); + }); }); + +/* + * Gets the total number of items a Pokemon holds + */ +function getHeldItemCount(pokemon: Pokemon) { + return pokemon.getHeldItems().reduce((currentTotal, item) => currentTotal + item.getStackCount(), 0); +} + diff --git a/src/test/items/leek.test.ts b/src/test/items/leek.test.ts index af20516ef83..e27462a9265 100644 --- a/src/test/items/leek.test.ts +++ b/src/test/items/leek.test.ts @@ -25,7 +25,7 @@ describe("Items - Leek", () => { game.override .enemySpecies(Species.MAGIKARP) - .enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]) + .enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]) .startingHeldItems([{ name: "LEEK" }]) .moveset([ Moves.TACKLE ]) .disableCrits() @@ -82,7 +82,7 @@ describe("Items - Leek", () => { it("should raise CRIT stage by 2 when held by FARFETCHD line fused with Pokemon", async () => { // Randomly choose from the Farfetch'd line - const species = [Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD]; + const species = [ Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD ]; await game.startBattle([ species[Utils.randInt(species.length)], @@ -113,7 +113,7 @@ describe("Items - Leek", () => { it("should raise CRIT stage by 2 when held by Pokemon fused with FARFETCHD line", async () => { // Randomly choose from the Farfetch'd line - const species = [Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD]; + const species = [ Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD ]; await game.startBattle([ Species.PIKACHU, diff --git a/src/test/items/leftovers.test.ts b/src/test/items/leftovers.test.ts index 8e548542436..cfbf7c2f734 100644 --- a/src/test/items/leftovers.test.ts +++ b/src/test/items/leftovers.test.ts @@ -27,15 +27,15 @@ describe("Items - Leftovers", () => { game.override.battleType("single"); game.override.startingLevel(2000); game.override.ability(Abilities.UNNERVE); - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); game.override.enemySpecies(Species.SHUCKLE); game.override.enemyAbility(Abilities.UNNERVE); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); game.override.startingHeldItems([{ name: "LEFTOVERS", count: 1 }]); }); it("leftovers works", async () => { - await game.startBattle([Species.ARCANINE]); + await game.startBattle([ Species.ARCANINE ]); // Make sure leftovers are there expect(game.scene.modifiers[0].type.id).toBe("LEFTOVERS"); diff --git a/src/test/items/light_ball.test.ts b/src/test/items/light_ball.test.ts index 673348e7b7a..78375487f3b 100644 --- a/src/test/items/light_ball.test.ts +++ b/src/test/items/light_ball.test.ts @@ -83,7 +83,7 @@ describe("Items - Light Ball", () => { expect(spAtkValue.value / spAtkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["LIGHT_BALL"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "LIGHT_BALL" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPATK, spAtkValue); @@ -122,7 +122,7 @@ describe("Items - Light Ball", () => { expect(spAtkValue.value / spAtkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["LIGHT_BALL"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "LIGHT_BALL" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPATK, spAtkValue); @@ -161,7 +161,7 @@ describe("Items - Light Ball", () => { expect(spAtkValue.value / spAtkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["LIGHT_BALL"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "LIGHT_BALL" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPATK, spAtkValue); @@ -189,7 +189,7 @@ describe("Items - Light Ball", () => { expect(spAtkValue.value / spAtkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["LIGHT_BALL"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "LIGHT_BALL" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPATK, spAtkValue); diff --git a/src/test/items/lock_capsule.test.ts b/src/test/items/lock_capsule.test.ts index bc4ca1cb014..0b6534b5eaf 100644 --- a/src/test/items/lock_capsule.test.ts +++ b/src/test/items/lock_capsule.test.ts @@ -1,7 +1,8 @@ import { Abilities } from "#app/enums/abilities"; import { Moves } from "#app/enums/moves"; -import { ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type"; +import { ModifierTier } from "#app/modifier/modifier-tier"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; +import { Mode } from "#app/ui/ui"; import GameManager from "#test/utils/gameManager"; import Phase from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -26,21 +27,22 @@ describe("Items - Lock Capsule", () => { game.override .battleType("single") .startingLevel(200) - .moveset([Moves.SURF]) + .moveset([ Moves.SURF ]) .enemyAbility(Abilities.BALL_FETCH) .startingModifier([{ name: "LOCK_CAPSULE" }]); }); it("doesn't set the cost of common tier items to 0", async () => { - await game.startBattle(); + await game.classicMode.startBattle(); + game.scene.overridePhase(new SelectModifierPhase(game.scene, 0, undefined, { guaranteedModifierTiers: [ ModifierTier.COMMON, ModifierTier.COMMON, ModifierTier.COMMON ], fillRemaining: false })); - game.move.select(Moves.SURF); - await game.phaseInterceptor.to(SelectModifierPhase, false); + game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => { + const selectModifierPhase = game.scene.getCurrentPhase() as SelectModifierPhase; + const rerollCost = selectModifierPhase.getRerollCost(true); + expect(rerollCost).toBe(150); + }); - const rewards = game.scene.getCurrentPhase() as SelectModifierPhase; - const potion = new ModifierTypeOption(modifierTypes.POTION(), 0, 40); // Common tier item - const rerollCost = rewards.getRerollCost([potion, potion, potion], true); - - expect(rerollCost).toBe(150); + game.doSelectModifier(); + await game.phaseInterceptor.to("SelectModifierPhase"); }, 20000); }); diff --git a/src/test/items/metal_powder.test.ts b/src/test/items/metal_powder.test.ts index 0206fd1f471..c577182f350 100644 --- a/src/test/items/metal_powder.test.ts +++ b/src/test/items/metal_powder.test.ts @@ -79,7 +79,7 @@ describe("Items - Metal Powder", () => { expect(defValue.value / defStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["METAL_POWDER"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "METAL_POWDER" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, defValue); expect(defValue.value / defStat).toBe(2); @@ -112,7 +112,7 @@ describe("Items - Metal Powder", () => { expect(defValue.value / defStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["METAL_POWDER"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "METAL_POWDER" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, defValue); expect(defValue.value / defStat).toBe(2); @@ -145,7 +145,7 @@ describe("Items - Metal Powder", () => { expect(defValue.value / defStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["METAL_POWDER"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "METAL_POWDER" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, defValue); expect(defValue.value / defStat).toBe(2); @@ -167,7 +167,7 @@ describe("Items - Metal Powder", () => { expect(defValue.value / defStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["METAL_POWDER"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "METAL_POWDER" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.DEF, defValue); expect(defValue.value / defStat).toBe(1); diff --git a/src/test/items/quick_powder.test.ts b/src/test/items/quick_powder.test.ts index 344b772feb4..4eb6f6fb164 100644 --- a/src/test/items/quick_powder.test.ts +++ b/src/test/items/quick_powder.test.ts @@ -79,7 +79,7 @@ describe("Items - Quick Powder", () => { expect(spdValue.value / spdStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["QUICK_POWDER"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "QUICK_POWDER" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPD, spdValue); expect(spdValue.value / spdStat).toBe(2); @@ -112,7 +112,7 @@ describe("Items - Quick Powder", () => { expect(spdValue.value / spdStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["QUICK_POWDER"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "QUICK_POWDER" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPD, spdValue); expect(spdValue.value / spdStat).toBe(2); @@ -145,7 +145,7 @@ describe("Items - Quick Powder", () => { expect(spdValue.value / spdStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["QUICK_POWDER"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "QUICK_POWDER" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPD, spdValue); expect(spdValue.value / spdStat).toBe(2); @@ -167,7 +167,7 @@ describe("Items - Quick Powder", () => { expect(spdValue.value / spdStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["QUICK_POWDER"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "QUICK_POWDER" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.SPD, spdValue); expect(spdValue.value / spdStat).toBe(1); diff --git a/src/test/items/thick_club.test.ts b/src/test/items/thick_club.test.ts index bcb6b371264..74158089c77 100644 --- a/src/test/items/thick_club.test.ts +++ b/src/test/items/thick_club.test.ts @@ -79,7 +79,7 @@ describe("Items - Thick Club", () => { expect(atkValue.value / atkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["THICK_CLUB"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "THICK_CLUB" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); expect(atkValue.value / atkStat).toBe(2); @@ -101,7 +101,7 @@ describe("Items - Thick Club", () => { expect(atkValue.value / atkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["THICK_CLUB"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "THICK_CLUB" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); expect(atkValue.value / atkStat).toBe(2); @@ -123,7 +123,7 @@ describe("Items - Thick Club", () => { expect(atkValue.value / atkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["THICK_CLUB"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "THICK_CLUB" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); expect(atkValue.value / atkStat).toBe(2); @@ -160,7 +160,7 @@ describe("Items - Thick Club", () => { expect(atkValue.value / atkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["THICK_CLUB"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "THICK_CLUB" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); expect(atkValue.value / atkStat).toBe(2); @@ -197,7 +197,7 @@ describe("Items - Thick Club", () => { expect(atkValue.value / atkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["THICK_CLUB"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "THICK_CLUB" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); expect(atkValue.value / atkStat).toBe(2); @@ -219,7 +219,7 @@ describe("Items - Thick Club", () => { expect(atkValue.value / atkStat).toBe(1); // Giving Eviolite to party member and testing if it applies - partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], ["THICK_CLUB"])!.newModifier(partyMember), true); + partyMember.scene.addModifier(modifierTypes.SPECIES_STAT_BOOSTER().generateType([], [ "THICK_CLUB" ])!.newModifier(partyMember), true); partyMember.scene.applyModifiers(SpeciesStatBoosterModifier, true, partyMember, Stat.ATK, atkValue); expect(atkValue.value / atkStat).toBe(1); diff --git a/src/test/items/toxic_orb.test.ts b/src/test/items/toxic_orb.test.ts index 66806083f6f..583e302126c 100644 --- a/src/test/items/toxic_orb.test.ts +++ b/src/test/items/toxic_orb.test.ts @@ -1,15 +1,11 @@ import { StatusEffect } from "#app/data/status-effect"; -import { EnemyCommandPhase } from "#app/phases/enemy-command-phase"; -import { MessagePhase } from "#app/phases/message-phase"; -import { TurnEndPhase } from "#app/phases/turn-end-phase"; -import i18next, { initI18n } from "#app/plugins/i18n"; +import i18next from "#app/plugins/i18n"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Items - Toxic orb", () => { let phaserGame: Phaser.Game; @@ -27,41 +23,33 @@ describe("Items - Toxic orb", () => { beforeEach(() => { game = new GameManager(phaserGame); - const moveToUse = Moves.GROWTH; - const oppMoveToUse = Moves.TACKLE; - game.override.battleType("single"); - game.override.enemySpecies(Species.RATTATA); - game.override.ability(Abilities.INSOMNIA); - game.override.enemyAbility(Abilities.INSOMNIA); - game.override.startingLevel(2000); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([oppMoveToUse, oppMoveToUse, oppMoveToUse, oppMoveToUse]); - game.override.startingHeldItems([{ - name: "TOXIC_ORB", - }]); + game.override + .battleType("single") + .enemySpecies(Species.MAGIKARP) + .ability(Abilities.BALL_FETCH) + .enemyAbility(Abilities.BALL_FETCH) + .moveset(Moves.SPLASH) + .enemyMoveset(Moves.SPLASH) + .startingHeldItems([{ + name: "TOXIC_ORB", + }]); + + vi.spyOn(i18next, "t"); }); - it("TOXIC ORB", async () => { - initI18n(); - i18next.changeLanguage("en"); - const moveToUse = Moves.GROWTH; - await game.startBattle([ - Species.MIGHTYENA, - Species.MIGHTYENA, - ]); - expect(game.scene.modifiers[0].type.id).toBe("TOXIC_ORB"); + it("should badly poison the holder", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); - game.move.select(moveToUse); + const player = game.scene.getPlayerPokemon()!; + expect(player.getHeldItems()[0].type.id).toBe("TOXIC_ORB"); - // will run the 13 phase from enemyCommandPhase to TurnEndPhase - await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnEndPhase); - // Toxic orb should trigger here - await game.phaseInterceptor.run(MessagePhase); - const message = game.textInterceptor.getLatestMessage(); - expect(message).toContain("statusEffect:toxic.obtainSource"); - await game.phaseInterceptor.run(MessagePhase); - const message2 = game.textInterceptor.getLatestMessage(); - expect(message2).toBe("statusEffect:toxic.activation"); - expect(game.scene.getParty()[0].status!.effect).toBe(StatusEffect.TOXIC); - }, 20000); + game.move.select(Moves.SPLASH); + + await game.phaseInterceptor.to("TurnEndPhase"); + await game.phaseInterceptor.to("MessagePhase"); + expect(i18next.t).toHaveBeenCalledWith("statusEffect:toxic.obtainSource", expect.anything()); + + expect(player.status?.effect).toBe(StatusEffect.TOXIC); + expect(player.status?.toxicTurnCount).toBe(0); + }); }); diff --git a/src/test/misc.test.ts b/src/test/misc.test.ts index 1052a282a64..3335c4c5523 100644 --- a/src/test/misc.test.ts +++ b/src/test/misc.test.ts @@ -64,7 +64,7 @@ describe("Test misc", () => { it("testing wait phase queue", async () => { const fakeScene = { - phaseQueue: [1, 2, 3] // Initially not empty + phaseQueue: [ 1, 2, 3 ] // Initially not empty }; setTimeout(() => { fakeScene.phaseQueue = []; diff --git a/src/test/moves/after_you.test.ts b/src/test/moves/after_you.test.ts index 025b4804bf1..99f383194aa 100644 --- a/src/test/moves/after_you.test.ts +++ b/src/test/moves/after_you.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - After You", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -33,11 +32,11 @@ describe("Moves - After You", () => { .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) .ability(Abilities.BALL_FETCH) - .moveset([Moves.AFTER_YOU, Moves.SPLASH]); + .moveset([ Moves.AFTER_YOU, Moves.SPLASH ]); }); it("makes the target move immediately after the user", async () => { - await game.classicMode.startBattle([Species.REGIELEKI, Species.SHUCKLE]); + await game.classicMode.startBattle([ Species.REGIELEKI, Species.SHUCKLE ]); game.move.select(Moves.AFTER_YOU, 0, BattlerIndex.PLAYER_2); game.move.select(Moves.SPLASH, 1); @@ -51,7 +50,7 @@ describe("Moves - After You", () => { it("fails if target already moved", async () => { game.override.enemySpecies(Species.SHUCKLE); - await game.classicMode.startBattle([Species.REGIELEKI, Species.PIKACHU]); + await game.classicMode.startBattle([ Species.REGIELEKI, Species.PIKACHU ]); game.move.select(Moves.SPLASH); game.move.select(Moves.AFTER_YOU, 1, BattlerIndex.PLAYER); diff --git a/src/test/moves/alluring_voice.test.ts b/src/test/moves/alluring_voice.test.ts index 3e86b46aa69..2980f102735 100644 --- a/src/test/moves/alluring_voice.test.ts +++ b/src/test/moves/alluring_voice.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - Alluring Voice", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -31,12 +30,12 @@ describe("Moves - Alluring Voice", () => { .disableCrits() .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.ICE_SCALES) - .enemyMoveset([Moves.HOWL]) + .enemyMoveset([ Moves.HOWL ]) .startingLevel(10) .enemyLevel(10) .starterSpecies(Species.FEEBAS) .ability(Abilities.BALL_FETCH) - .moveset([Moves.ALLURING_VOICE]); + .moveset([ Moves.ALLURING_VOICE ]); }); @@ -46,7 +45,7 @@ describe("Moves - Alluring Voice", () => { const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.ALLURING_VOICE); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to(BerryPhase); expect(enemy.getTag(BattlerTagType.CONFUSED)?.tagType).toBe("CONFUSED"); diff --git a/src/test/moves/aromatherapy.test.ts b/src/test/moves/aromatherapy.test.ts new file mode 100644 index 00000000000..f547ed0e54c --- /dev/null +++ b/src/test/moves/aromatherapy.test.ts @@ -0,0 +1,101 @@ +import { StatusEffect } from "#app/enums/status-effect"; +import { CommandPhase } from "#app/phases/command-phase"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Aromatherapy", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.AROMATHERAPY, Moves.SPLASH ]) + .statusEffect(StatusEffect.BURN) + .battleType("double") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should cure status effect of the user, its ally, and all party pokemon", async () => { + await game.classicMode.startBattle([ Species.RATTATA, Species.RATTATA, Species.RATTATA ]); + const [ leftPlayer, rightPlayer, partyPokemon ] = game.scene.getParty(); + + vi.spyOn(leftPlayer, "resetStatus"); + vi.spyOn(rightPlayer, "resetStatus"); + vi.spyOn(partyPokemon, "resetStatus"); + + game.move.select(Moves.AROMATHERAPY, 0); + await game.phaseInterceptor.to(CommandPhase); + game.move.select(Moves.SPLASH, 1); + await game.toNextTurn(); + + expect(leftPlayer.resetStatus).toHaveBeenCalledOnce(); + expect(rightPlayer.resetStatus).toHaveBeenCalledOnce(); + expect(partyPokemon.resetStatus).toHaveBeenCalledOnce(); + + expect(leftPlayer.status?.effect).toBeUndefined(); + expect(rightPlayer.status?.effect).toBeUndefined(); + expect(partyPokemon.status?.effect).toBeUndefined(); + }); + + it("should not cure status effect of the target/target's allies", async () => { + game.override.enemyStatusEffect(StatusEffect.BURN); + await game.classicMode.startBattle([ Species.RATTATA, Species.RATTATA ]); + const [ leftOpp, rightOpp ] = game.scene.getEnemyField(); + + vi.spyOn(leftOpp, "resetStatus"); + vi.spyOn(rightOpp, "resetStatus"); + + game.move.select(Moves.AROMATHERAPY, 0); + await game.phaseInterceptor.to(CommandPhase); + game.move.select(Moves.SPLASH, 1); + await game.toNextTurn(); + + expect(leftOpp.resetStatus).toHaveBeenCalledTimes(0); + expect(rightOpp.resetStatus).toHaveBeenCalledTimes(0); + + expect(leftOpp.status?.effect).toBeTruthy(); + expect(rightOpp.status?.effect).toBeTruthy(); + + expect(leftOpp.status?.effect).toBe(StatusEffect.BURN); + expect(rightOpp.status?.effect).toBe(StatusEffect.BURN); + }); + + it("should not cure status effect of allies ON FIELD with Sap Sipper, should still cure allies in party", async () => { + game.override.ability(Abilities.SAP_SIPPER); + await game.classicMode.startBattle([ Species.RATTATA, Species.RATTATA, Species.RATTATA ]); + const [ leftPlayer, rightPlayer, partyPokemon ] = game.scene.getParty(); + + vi.spyOn(leftPlayer, "resetStatus"); + vi.spyOn(rightPlayer, "resetStatus"); + vi.spyOn(partyPokemon, "resetStatus"); + + game.move.select(Moves.AROMATHERAPY, 0); + await game.phaseInterceptor.to(CommandPhase); + game.move.select(Moves.SPLASH, 1); + await game.toNextTurn(); + + expect(leftPlayer.resetStatus).toHaveBeenCalledOnce(); + expect(rightPlayer.resetStatus).toHaveBeenCalledTimes(0); + expect(partyPokemon.resetStatus).toHaveBeenCalledOnce(); + + expect(leftPlayer.status?.effect).toBeUndefined(); + expect(rightPlayer.status?.effect).toBe(StatusEffect.BURN); + expect(partyPokemon.status?.effect).toBeUndefined(); + }); +}); diff --git a/src/test/moves/astonish.test.ts b/src/test/moves/astonish.test.ts index 694ad85803b..d94e50fc9f9 100644 --- a/src/test/moves/astonish.test.ts +++ b/src/test/moves/astonish.test.ts @@ -12,7 +12,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; - describe("Moves - Astonish", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,10 +29,10 @@ describe("Moves - Astonish", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("single"); - game.override.moveset([Moves.ASTONISH, Moves.SPLASH]); + game.override.moveset([ Moves.ASTONISH, Moves.SPLASH ]); game.override.enemySpecies(Species.BLASTOISE); game.override.enemyAbility(Abilities.INSOMNIA); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); game.override.startingLevel(100); game.override.enemyLevel(100); @@ -43,7 +42,7 @@ describe("Moves - Astonish", () => { test( "move effect should cancel the target's move on the turn it applies", async () => { - await game.startBattle([Species.MEOWSCARADA]); + await game.startBattle([ Species.MEOWSCARADA ]); const leadPokemon = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/aurora_veil.test.ts b/src/test/moves/aurora_veil.test.ts index fec280debf4..e68117a2f59 100644 --- a/src/test/moves/aurora_veil.test.ts +++ b/src/test/moves/aurora_veil.test.ts @@ -33,17 +33,17 @@ describe("Moves - Aurora Veil", () => { game = new GameManager(phaserGame); game.override.battleType("single"); game.override.ability(Abilities.NONE); - game.override.moveset([Moves.ABSORB, Moves.ROCK_SLIDE, Moves.TACKLE]); + game.override.moveset([ Moves.ABSORB, Moves.ROCK_SLIDE, Moves.TACKLE ]); game.override.enemyLevel(100); game.override.enemySpecies(Species.MAGIKARP); - game.override.enemyMoveset([Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL]); + game.override.enemyMoveset([ Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL ]); game.override.disableCrits(); game.override.weather(WeatherType.HAIL); }); it("reduces damage of physical attacks by half in a single battle", async () => { const moveToUse = Moves.TACKLE; - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); game.move.select(moveToUse); @@ -57,7 +57,7 @@ describe("Moves - Aurora Veil", () => { game.override.battleType("double"); const moveToUse = Moves.ROCK_SLIDE; - await game.startBattle([Species.SHUCKLE, Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]); game.move.select(moveToUse); game.move.select(moveToUse, 1); @@ -70,7 +70,7 @@ describe("Moves - Aurora Veil", () => { it("reduces damage of special attacks by half in a single battle", async () => { const moveToUse = Moves.ABSORB; - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); game.move.select(moveToUse); @@ -85,7 +85,7 @@ describe("Moves - Aurora Veil", () => { game.override.battleType("double"); const moveToUse = Moves.DAZZLING_GLEAM; - await game.startBattle([Species.SHUCKLE, Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]); game.move.select(moveToUse); game.move.select(moveToUse, 1); @@ -111,7 +111,7 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) = const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; if (defender.scene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side)) { - defender.scene.arena.applyTagsForSide(ArenaTagType.AURORA_VEIL, side, move.category, defender.scene.currentBattle.double, multiplierHolder); + defender.scene.arena.applyTagsForSide(ArenaTagType.AURORA_VEIL, side, false, attacker, move.category, multiplierHolder); } return move.power * multiplierHolder.value; diff --git a/src/test/moves/autotomize.test.ts b/src/test/moves/autotomize.test.ts index 329b92b38fe..e15642b7ce5 100644 --- a/src/test/moves/autotomize.test.ts +++ b/src/test/moves/autotomize.test.ts @@ -23,7 +23,7 @@ describe("Moves - Autotomize", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.AUTOTOMIZE, Moves.KINGS_SHIELD, Moves.FALSE_SWIPE]) + .moveset([ Moves.AUTOTOMIZE, Moves.KINGS_SHIELD, Moves.FALSE_SWIPE ]) .battleType("single") .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH); @@ -35,7 +35,7 @@ describe("Moves - Autotomize", () => { const twoAutotomizeDracozoltWeight = 0.1; const threeAutotomizeDracozoltWeight = 0.1; - await game.classicMode.startBattle([Species.DRACOZOLT]); + await game.classicMode.startBattle([ Species.DRACOZOLT ]); const playerPokemon = game.scene.getPlayerPokemon()!; expect(playerPokemon.getWeight()).toBe(baseDracozoltWeight); game.move.select(Moves.AUTOTOMIZE); @@ -56,7 +56,7 @@ describe("Moves - Autotomize", () => { const baseAegislashWeight = 53; const autotomizeAegislashWeight = 0.1; - await game.classicMode.startBattle([Species.AEGISLASH]); + await game.classicMode.startBattle([ Species.AEGISLASH ]); const playerPokemon = game.scene.getPlayerPokemon()!; expect(playerPokemon.getWeight()).toBe(baseAegislashWeight); @@ -88,7 +88,7 @@ describe("Moves - Autotomize", () => { const baseLightGroudonWeight = 475; const autotomizeLightGroudonWeight = 425; game.override.ability(Abilities.LIGHT_METAL); - await game.classicMode.startBattle([Species.GROUDON]); + await game.classicMode.startBattle([ Species.GROUDON ]); const playerPokemon = game.scene.getPlayerPokemon()!; expect(playerPokemon.getWeight()).toBe(baseLightGroudonWeight); game.move.select(Moves.AUTOTOMIZE); diff --git a/src/test/moves/baddy_bad.test.ts b/src/test/moves/baddy_bad.test.ts index 87a7e9e049d..1be25704393 100644 --- a/src/test/moves/baddy_bad.test.ts +++ b/src/test/moves/baddy_bad.test.ts @@ -21,7 +21,7 @@ describe("Moves - Baddy Bad", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.SPLASH]) + .moveset([ Moves.SPLASH ]) .battleType("single") .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.BALL_FETCH) @@ -31,7 +31,7 @@ describe("Moves - Baddy Bad", () => { it("should not activate Reflect if the move fails due to Protect", async () => { game.override.enemyMoveset(Moves.PROTECT); - await game.classicMode.startBattle([Species.FEEBAS]); + await game.classicMode.startBattle([ Species.FEEBAS ]); game.move.select(Moves.BADDY_BAD); await game.phaseInterceptor.to("BerryPhase"); diff --git a/src/test/moves/baneful_bunker.test.ts b/src/test/moves/baneful_bunker.test.ts index 5f63e3b4313..a0fc0f21ee2 100644 --- a/src/test/moves/baneful_bunker.test.ts +++ b/src/test/moves/baneful_bunker.test.ts @@ -8,7 +8,6 @@ import { BattlerIndex } from "#app/battle"; import { StatusEffect } from "#app/enums/status-effect"; - describe("Moves - Baneful Bunker", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -40,13 +39,13 @@ describe("Moves - Baneful Bunker", () => { test( "should protect the user and poison attackers that make contact", async () => { - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.SLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("BerryPhase", false); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeTruthy(); @@ -55,13 +54,13 @@ describe("Moves - Baneful Bunker", () => { test( "should protect the user and poison attackers that make contact, regardless of accuracy checks", async () => { - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.SLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("MoveEffectPhase"); await game.move.forceMiss(); @@ -75,13 +74,13 @@ describe("Moves - Baneful Bunker", () => { "should not poison attackers that don't make contact", async () => { game.override.moveset(Moves.FLASH_CANNON); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.FLASH_CANNON); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("MoveEffectPhase"); await game.move.forceMiss(); diff --git a/src/test/moves/baton_pass.test.ts b/src/test/moves/baton_pass.test.ts index 5643efceae2..9d4a9358715 100644 --- a/src/test/moves/baton_pass.test.ts +++ b/src/test/moves/baton_pass.test.ts @@ -28,15 +28,15 @@ describe("Moves - Baton Pass", () => { .battleType("single") .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.BALL_FETCH) - .moveset([Moves.BATON_PASS, Moves.NASTY_PLOT, Moves.SPLASH]) + .moveset([ Moves.BATON_PASS, Moves.NASTY_PLOT, Moves.SPLASH ]) .ability(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) .disableCrits(); }); - it("transfers all stat stages when player uses it", async() => { + it("transfers all stat stages when player uses it", async () => { // arrange - await game.classicMode.startBattle([Species.RAICHU, Species.SHUCKLE]); + await game.classicMode.startBattle([ Species.RAICHU, Species.SHUCKLE ]); // round 1 - buff game.move.select(Moves.NASTY_PLOT); @@ -61,8 +61,8 @@ describe("Moves - Baton Pass", () => { // arrange game.override .startingWave(5) - .enemyMoveset(new Array(4).fill([Moves.NASTY_PLOT])); - await game.classicMode.startBattle([Species.RAICHU, Species.SHUCKLE]); + .enemyMoveset(new Array(4).fill([ Moves.NASTY_PLOT ])); + await game.classicMode.startBattle([ Species.RAICHU, Species.SHUCKLE ]); // round 1 - ai buffs game.move.select(Moves.SPLASH); @@ -70,7 +70,7 @@ describe("Moves - Baton Pass", () => { // round 2 - baton pass game.scene.getEnemyPokemon()!.hp = 100; - game.override.enemyMoveset([Moves.BATON_PASS]); + game.override.enemyMoveset([ Moves.BATON_PASS ]); // Force moveset to update mid-battle // TODO: replace with enemy ai control function when it's added game.scene.getEnemyParty()[0].getMoveset(); @@ -91,14 +91,14 @@ describe("Moves - Baton Pass", () => { ]); }, 20000); - it("doesn't transfer effects that aren't transferrable", async() => { - game.override.enemyMoveset([Moves.SALT_CURE]); - await game.classicMode.startBattle([Species.PIKACHU, Species.FEEBAS]); + it("doesn't transfer effects that aren't transferrable", async () => { + game.override.enemyMoveset([ Moves.SALT_CURE ]); + await game.classicMode.startBattle([ Species.PIKACHU, Species.FEEBAS ]); - const [player1, player2] = game.scene.getParty(); + const [ player1, player2 ] = game.scene.getParty(); game.move.select(Moves.BATON_PASS); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(player1.findTag((t) => t.tagType === BattlerTagType.SALT_CURED)).toBeTruthy(); game.doSelectPartyPokemon(1); @@ -106,4 +106,28 @@ describe("Moves - Baton Pass", () => { expect(player2.findTag((t) => t.tagType === BattlerTagType.SALT_CURED)).toBeUndefined(); }, 20000); + + it("doesn't allow binding effects from the user to persist", async () => { + game.override.moveset([ Moves.FIRE_SPIN, Moves.BATON_PASS ]); + + await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); + + const enemy = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.FIRE_SPIN); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.move.forceHit(); + + await game.toNextTurn(); + + expect(enemy.getTag(BattlerTagType.FIRE_SPIN)).toBeDefined(); + + game.move.select(Moves.BATON_PASS); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + + expect(enemy.getTag(BattlerTagType.FIRE_SPIN)).toBeUndefined(); + }); }); diff --git a/src/test/moves/beak_blast.test.ts b/src/test/moves/beak_blast.test.ts index 3f4fe1d1d11..0c1e7bbeed9 100644 --- a/src/test/moves/beak_blast.test.ts +++ b/src/test/moves/beak_blast.test.ts @@ -11,7 +11,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - Beak Blast", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -31,10 +30,10 @@ describe("Moves - Beak Blast", () => { game.override .battleType("single") .ability(Abilities.UNNERVE) - .moveset([Moves.BEAK_BLAST]) + .moveset([ Moves.BEAK_BLAST ]) .enemySpecies(Species.SNORLAX) .enemyAbility(Abilities.INSOMNIA) - .enemyMoveset([Moves.TACKLE]) + .enemyMoveset([ Moves.TACKLE ]) .startingLevel(100) .enemyLevel(100); }); @@ -42,7 +41,7 @@ describe("Moves - Beak Blast", () => { it( "should add a charge effect that burns attackers on contact", async () => { - await game.startBattle([Species.BLASTOISE]); + await game.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -62,7 +61,7 @@ describe("Moves - Beak Blast", () => { async () => { game.override.statusEffect(StatusEffect.SLEEP); - await game.startBattle([Species.BLASTOISE]); + await game.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -80,9 +79,9 @@ describe("Moves - Beak Blast", () => { it( "should not burn attackers that don't make contact", async () => { - game.override.enemyMoveset([Moves.WATER_GUN]); + game.override.enemyMoveset([ Moves.WATER_GUN ]); - await game.startBattle([Species.BLASTOISE]); + await game.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -102,7 +101,7 @@ describe("Moves - Beak Blast", () => { async () => { game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - await game.startBattle([Species.BLASTOISE]); + await game.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -116,9 +115,9 @@ describe("Moves - Beak Blast", () => { it( "should be blocked by Protect", async () => { - game.override.enemyMoveset([Moves.PROTECT]); + game.override.enemyMoveset([ Moves.PROTECT ]); - await game.startBattle([Species.BLASTOISE]); + await game.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/beat_up.test.ts b/src/test/moves/beat_up.test.ts index 51ec768084c..e51ac6ea452 100644 --- a/src/test/moves/beat_up.test.ts +++ b/src/test/moves/beat_up.test.ts @@ -27,17 +27,17 @@ describe("Moves - Beat Up", () => { game.override.enemySpecies(Species.SNORLAX); game.override.enemyLevel(100); - game.override.enemyMoveset([Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH ]); game.override.enemyAbility(Abilities.INSOMNIA); game.override.startingLevel(100); - game.override.moveset([Moves.BEAT_UP]); + game.override.moveset([ Moves.BEAT_UP ]); }); it( "should hit once for each healthy player Pokemon", async () => { - await game.startBattle([Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE]); + await game.startBattle([ Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -61,7 +61,7 @@ describe("Moves - Beat Up", () => { it( "should not count player Pokemon with status effects towards hit count", async () => { - await game.startBattle([Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE]); + await game.startBattle([ Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE ]); const playerPokemon = game.scene.getPlayerPokemon()!; @@ -79,7 +79,7 @@ describe("Moves - Beat Up", () => { "should hit twice for each player Pokemon if the user has Multi-Lens", async () => { game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - await game.startBattle([Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE]); + await game.startBattle([ Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/belly_drum.test.ts b/src/test/moves/belly_drum.test.ts index 494272089e2..0bed1248e7e 100644 --- a/src/test/moves/belly_drum.test.ts +++ b/src/test/moves/belly_drum.test.ts @@ -35,7 +35,7 @@ describe("Moves - BELLY DRUM", () => { .enemySpecies(Species.SNORLAX) .startingLevel(100) .enemyLevel(100) - .moveset([Moves.BELLY_DRUM]) + .moveset([ Moves.BELLY_DRUM ]) .enemyMoveset(Moves.SPLASH) .enemyAbility(Abilities.BALL_FETCH); }); @@ -44,7 +44,7 @@ describe("Moves - BELLY DRUM", () => { test("raises the user's ATK stat stage to its max, at the cost of 1/2 of its maximum HP", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = toDmgValue(leadPokemon.getMaxHp() / RATIO); @@ -59,7 +59,7 @@ describe("Moves - BELLY DRUM", () => { test("will still take effect if an uninvolved stat stage is at max", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = toDmgValue(leadPokemon.getMaxHp() / RATIO); @@ -79,7 +79,7 @@ describe("Moves - BELLY DRUM", () => { test("fails if the pokemon's ATK stat stage is at its maximum", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -95,7 +95,7 @@ describe("Moves - BELLY DRUM", () => { test("fails if the user's health is less than 1/2", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = toDmgValue(leadPokemon.getMaxHp() / RATIO); diff --git a/src/test/moves/burning_jealousy.test.ts b/src/test/moves/burning_jealousy.test.ts index d6ebbf30bb1..fe2735cfa96 100644 --- a/src/test/moves/burning_jealousy.test.ts +++ b/src/test/moves/burning_jealousy.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; - describe("Moves - Burning Jealousy", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -31,12 +30,12 @@ describe("Moves - Burning Jealousy", () => { .disableCrits() .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.ICE_SCALES) - .enemyMoveset([Moves.HOWL]) + .enemyMoveset([ Moves.HOWL ]) .startingLevel(10) .enemyLevel(10) .starterSpecies(Species.FEEBAS) .ability(Abilities.BALL_FETCH) - .moveset([Moves.BURNING_JEALOUSY, Moves.GROWL]); + .moveset([ Moves.BURNING_JEALOUSY, Moves.GROWL ]); }); @@ -46,7 +45,7 @@ describe("Moves - Burning Jealousy", () => { const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.BURNING_JEALOUSY); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("BerryPhase"); expect(enemy.status?.effect).toBe(StatusEffect.BURN); @@ -56,13 +55,13 @@ describe("Moves - Burning Jealousy", () => { game.override .starterSpecies(0) .battleType("double"); - await game.classicMode.startBattle([Species.FEEBAS, Species.ABRA]); + await game.classicMode.startBattle([ Species.FEEBAS, Species.ABRA ]); const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.BURNING_JEALOUSY); game.move.select(Moves.GROWL, 1); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("BerryPhase"); expect(enemy.status?.effect).toBe(StatusEffect.BURN); diff --git a/src/test/moves/ceaseless_edge.test.ts b/src/test/moves/ceaseless_edge.test.ts index e98fe462c62..88c8c8cf011 100644 --- a/src/test/moves/ceaseless_edge.test.ts +++ b/src/test/moves/ceaseless_edge.test.ts @@ -11,7 +11,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; - describe("Moves - Ceaseless Edge", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -34,8 +33,8 @@ describe("Moves - Ceaseless Edge", () => { game.override.enemyPassiveAbility(Abilities.RUN_AWAY); game.override.startingLevel(100); game.override.enemyLevel(100); - game.override.moveset([Moves.CEASELESS_EDGE, Moves.SPLASH, Moves.ROAR]); - game.override.enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.moveset([ Moves.CEASELESS_EDGE, Moves.SPLASH, Moves.ROAR ]); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); vi.spyOn(allMoves[Moves.CEASELESS_EDGE], "accuracy", "get").mockReturnValue(100); }); @@ -43,7 +42,7 @@ describe("Moves - Ceaseless Edge", () => { test( "move should hit and apply spikes", async () => { - await game.startBattle([Species.ILLUMISE]); + await game.startBattle([ Species.ILLUMISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -68,7 +67,7 @@ describe("Moves - Ceaseless Edge", () => { "move should hit twice with multi lens and apply two layers of spikes", async () => { game.override.startingHeldItems([{ name: "MULTI_LENS" }]); - await game.startBattle([Species.ILLUMISE]); + await game.startBattle([ Species.ILLUMISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -95,7 +94,7 @@ describe("Moves - Ceaseless Edge", () => { game.override.startingHeldItems([{ name: "MULTI_LENS" }]); game.override.startingWave(5); - await game.startBattle([Species.ILLUMISE]); + await game.startBattle([ Species.ILLUMISE ]); game.move.select(Moves.CEASELESS_EDGE); await game.phaseInterceptor.to(MoveEffectPhase, false); diff --git a/src/test/moves/chilly_reception.test.ts b/src/test/moves/chilly_reception.test.ts index 6c8e8172670..664ca242b20 100644 --- a/src/test/moves/chilly_reception.test.ts +++ b/src/test/moves/chilly_reception.test.ts @@ -24,7 +24,7 @@ describe("Moves - Chilly Reception", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("single") - .moveset([Moves.CHILLY_RECEPTION, Moves.SNOWSCAPE]) + .moveset([ Moves.CHILLY_RECEPTION, Moves.SNOWSCAPE ]) .enemyMoveset(Array(4).fill(Moves.SPLASH)) .enemyAbility(Abilities.NONE) .ability(Abilities.NONE); @@ -32,7 +32,7 @@ describe("Moves - Chilly Reception", () => { }); it("should still change the weather if user can't switch out", async () => { - await game.classicMode.startBattle([Species.SLOWKING]); + await game.classicMode.startBattle([ Species.SLOWKING ]); game.move.select(Moves.CHILLY_RECEPTION); @@ -41,7 +41,7 @@ describe("Moves - Chilly Reception", () => { }); it("should switch out even if it's snowing", async () => { - await game.classicMode.startBattle([Species.SLOWKING, Species.MEOWTH]); + await game.classicMode.startBattle([ Species.SLOWKING, Species.MEOWTH ]); // first turn set up snow with snowscape, try chilly reception on second turn game.move.select(Moves.SNOWSCAPE); await game.phaseInterceptor.to("BerryPhase", false); @@ -58,7 +58,7 @@ describe("Moves - Chilly Reception", () => { it("happy case - switch out and weather changes", async () => { - await game.classicMode.startBattle([Species.SLOWKING, Species.MEOWTH]); + await game.classicMode.startBattle([ Species.SLOWKING, Species.MEOWTH ]); game.move.select(Moves.CHILLY_RECEPTION); game.doSelectPartyPokemon(1); @@ -71,11 +71,11 @@ describe("Moves - Chilly Reception", () => { // enemy uses another move and weather doesn't change it("check case - enemy not selecting chilly reception doesn't change weather ", async () => { game.override.battleType("single") - .enemyMoveset([Moves.CHILLY_RECEPTION, Moves.TACKLE]) + .enemyMoveset([ Moves.CHILLY_RECEPTION, Moves.TACKLE ]) .enemyAbility(Abilities.NONE) .moveset(Array(4).fill(Moves.SPLASH)); - await game.classicMode.startBattle([Species.SLOWKING, Species.MEOWTH]); + await game.classicMode.startBattle([ Species.SLOWKING, Species.MEOWTH ]); game.move.select(Moves.SPLASH); await game.forceEnemyMove(Moves.TACKLE); @@ -90,9 +90,9 @@ describe("Moves - Chilly Reception", () => { .enemyMoveset(Array(4).fill(Moves.CHILLY_RECEPTION)) .enemyAbility(Abilities.NONE) .enemySpecies(Species.MAGIKARP) - .moveset([Moves.SPLASH, Moves.THUNDERBOLT]); + .moveset([ Moves.SPLASH, Moves.THUNDERBOLT ]); - await game.classicMode.startBattle([Species.JOLTEON]); + await game.classicMode.startBattle([ Species.JOLTEON ]); const RIVAL_MAGIKARP1 = game.scene.getEnemyPokemon()?.id; game.move.select(Moves.SPLASH); diff --git a/src/test/moves/chloroblast.test.ts b/src/test/moves/chloroblast.test.ts new file mode 100644 index 00000000000..5e55bf46958 --- /dev/null +++ b/src/test/moves/chloroblast.test.ts @@ -0,0 +1,42 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Chloroblast", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.CHLOROBLAST ]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.PROTECT); + }); + + it("should not deal recoil damage if the opponent uses protect", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + game.move.select(Moves.CHLOROBLAST); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.getPlayerPokemon()!.isFullHp()).toBe(true); + }); +}); diff --git a/src/test/moves/clangorous_soul.test.ts b/src/test/moves/clangorous_soul.test.ts index 8f0bfb2549f..52e980cc4fa 100644 --- a/src/test/moves/clangorous_soul.test.ts +++ b/src/test/moves/clangorous_soul.test.ts @@ -32,7 +32,7 @@ describe("Moves - Clangorous Soul", () => { game.override.enemySpecies(Species.SNORLAX); game.override.startingLevel(100); game.override.enemyLevel(100); - game.override.moveset([Moves.CLANGOROUS_SOUL]); + game.override.moveset([ Moves.CLANGOROUS_SOUL ]); game.override.enemyMoveset(Moves.SPLASH); }); @@ -40,7 +40,7 @@ describe("Moves - Clangorous Soul", () => { it("raises the user's ATK, DEF, SPATK, SPDEF, and SPD stat stages by 1 each at the cost of 1/3 of its maximum HP", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); @@ -59,7 +59,7 @@ describe("Moves - Clangorous Soul", () => { it("will still take effect if one or more of the involved stat stages are not at max", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); @@ -84,7 +84,7 @@ describe("Moves - Clangorous Soul", () => { it("fails if all stat stages involved are at max", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -108,7 +108,7 @@ describe("Moves - Clangorous Soul", () => { it("fails if the user's health is less than 1/3", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); diff --git a/src/test/moves/crafty_shield.test.ts b/src/test/moves/crafty_shield.test.ts index 63399c3a86a..93dd4a02538 100644 --- a/src/test/moves/crafty_shield.test.ts +++ b/src/test/moves/crafty_shield.test.ts @@ -10,7 +10,6 @@ import { BerryPhase } from "#app/phases/berry-phase"; import { CommandPhase } from "#app/phases/command-phase"; - describe("Moves - Crafty Shield", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,10 +29,10 @@ describe("Moves - Crafty Shield", () => { game.override.battleType("double"); - game.override.moveset([Moves.CRAFTY_SHIELD, Moves.SPLASH, Moves.SWORDS_DANCE]); + game.override.moveset([ Moves.CRAFTY_SHIELD, Moves.SPLASH, Moves.SWORDS_DANCE ]); game.override.enemySpecies(Species.SNORLAX); - game.override.enemyMoveset([Moves.GROWL]); + game.override.enemyMoveset([ Moves.GROWL ]); game.override.enemyAbility(Abilities.INSOMNIA); game.override.startingLevel(100); @@ -43,7 +42,7 @@ describe("Moves - Crafty Shield", () => { test( "should protect the user and allies from status moves", async () => { - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); @@ -62,9 +61,9 @@ describe("Moves - Crafty Shield", () => { test( "should not protect the user and allies from attack moves", async () => { - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); @@ -84,9 +83,9 @@ describe("Moves - Crafty Shield", () => { "should protect the user and allies from moves that ignore other protection", async () => { game.override.enemySpecies(Species.DUSCLOPS); - game.override.enemyMoveset([Moves.CURSE]); + game.override.enemyMoveset([ Moves.CURSE ]); - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); @@ -105,7 +104,7 @@ describe("Moves - Crafty Shield", () => { test( "should not block allies' self-targeted moves", async () => { - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); diff --git a/src/test/moves/destiny_bond.test.ts b/src/test/moves/destiny_bond.test.ts new file mode 100644 index 00000000000..4b4c8782862 --- /dev/null +++ b/src/test/moves/destiny_bond.test.ts @@ -0,0 +1,255 @@ +import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag"; +import { allMoves } from "#app/data/move"; +import { Abilities } from "#enums/abilities"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { BattlerIndex } from "#app/battle"; +import { StatusEffect } from "#enums/status-effect"; +import { PokemonInstantReviveModifier } from "#app/modifier/modifier"; + + +describe("Moves - Destiny Bond", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + const defaultParty = [ Species.BULBASAUR, Species.SQUIRTLE ]; + const enemyFirst = [ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]; + const playerFirst = [ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.battleType("single") + .ability(Abilities.UNNERVE) // Pre-emptively prevent flakiness from opponent berries + .enemySpecies(Species.RATTATA) + .enemyAbility(Abilities.RUN_AWAY) + .startingLevel(100) // Make sure tested moves KO + .enemyLevel(5) + .enemyMoveset(Moves.DESTINY_BOND); + }); + + it("should KO the opponent on the same turn", async () => { + const moveToUse = Moves.TACKLE; + + game.override.moveset(moveToUse); + await game.classicMode.startBattle(defaultParty); + + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon(); + + game.move.select(moveToUse); + await game.setTurnOrder(enemyFirst); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon?.isFainted()).toBe(true); + expect(playerPokemon?.isFainted()).toBe(true); + }); + + it("should KO the opponent on the next turn", async () => { + const moveToUse = Moves.TACKLE; + + game.override.moveset([ Moves.SPLASH, moveToUse ]); + await game.classicMode.startBattle(defaultParty); + + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon(); + + // Turn 1: Enemy uses Destiny Bond and doesn't faint + game.move.select(Moves.SPLASH); + await game.setTurnOrder(playerFirst); + await game.toNextTurn(); + + expect(enemyPokemon?.isFainted()).toBe(false); + expect(playerPokemon?.isFainted()).toBe(false); + + // Turn 2: Player KO's the enemy before the enemy's turn + game.move.select(moveToUse); + await game.setTurnOrder(playerFirst); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon?.isFainted()).toBe(true); + expect(playerPokemon?.isFainted()).toBe(true); + }); + + it("should fail if used twice in a row", async () => { + const moveToUse = Moves.TACKLE; + + game.override.moveset([ Moves.SPLASH, moveToUse ]); + await game.classicMode.startBattle(defaultParty); + + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon(); + + // Turn 1: Enemy uses Destiny Bond and doesn't faint + game.move.select(Moves.SPLASH); + await game.setTurnOrder(enemyFirst); + await game.toNextTurn(); + + expect(enemyPokemon?.isFainted()).toBe(false); + expect(playerPokemon?.isFainted()).toBe(false); + + // Turn 2: Enemy should fail Destiny Bond then get KO'd + game.move.select(moveToUse); + await game.setTurnOrder(enemyFirst); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon?.isFainted()).toBe(true); + expect(playerPokemon?.isFainted()).toBe(false); + }); + + it("should not KO the opponent if the user dies to weather", async () => { + // Opponent will be reduced to 1 HP by False Swipe, then faint to Sandstorm + const moveToUse = Moves.FALSE_SWIPE; + + game.override.moveset(moveToUse) + .ability(Abilities.SAND_STREAM); + await game.classicMode.startBattle(defaultParty); + + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon(); + + game.move.select(moveToUse); + await game.setTurnOrder(enemyFirst); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon?.isFainted()).toBe(true); + expect(playerPokemon?.isFainted()).toBe(false); + }); + + it("should not KO the opponent if the user had another turn", async () => { + const moveToUse = Moves.TACKLE; + + game.override.moveset([ Moves.SPORE, moveToUse ]); + await game.classicMode.startBattle(defaultParty); + + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon(); + + // Turn 1: Enemy uses Destiny Bond and doesn't faint + game.move.select(Moves.SPORE); + await game.setTurnOrder(enemyFirst); + await game.toNextTurn(); + + expect(enemyPokemon?.isFainted()).toBe(false); + expect(playerPokemon?.isFainted()).toBe(false); + expect(enemyPokemon?.status?.effect).toBe(StatusEffect.SLEEP); + + // Turn 2: Enemy should skip a turn due to sleep, then get KO'd + game.move.select(moveToUse); + await game.setTurnOrder(enemyFirst); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon?.isFainted()).toBe(true); + expect(playerPokemon?.isFainted()).toBe(false); + }); + + it("should not KO an ally", async () => { + game.override.moveset([ Moves.DESTINY_BOND, Moves.CRUNCH ]) + .battleType("double"); + await game.classicMode.startBattle([ Species.SHEDINJA, Species.BULBASAUR, Species.SQUIRTLE ]); + + const enemyPokemon0 = game.scene.getEnemyField()[0]; + const enemyPokemon1 = game.scene.getEnemyField()[1]; + const playerPokemon0 = game.scene.getPlayerField()[0]; + const playerPokemon1 = game.scene.getPlayerField()[1]; + + // Shedinja uses Destiny Bond, then ally Bulbasaur KO's Shedinja with Crunch + game.move.select(Moves.DESTINY_BOND, 0); + game.move.select(Moves.CRUNCH, 1, BattlerIndex.PLAYER); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon0?.isFainted()).toBe(false); + expect(enemyPokemon1?.isFainted()).toBe(false); + expect(playerPokemon0?.isFainted()).toBe(true); + expect(playerPokemon1?.isFainted()).toBe(false); + }); + + it("should not cause a crash if the user is KO'd by Ceaseless Edge", async () => { + const moveToUse = Moves.CEASELESS_EDGE; + vi.spyOn(allMoves[moveToUse], "accuracy", "get").mockReturnValue(100); + + game.override.moveset(moveToUse); + await game.classicMode.startBattle(defaultParty); + + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon(); + + game.move.select(moveToUse); + await game.setTurnOrder(enemyFirst); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon?.isFainted()).toBe(true); + expect(playerPokemon?.isFainted()).toBe(true); + + // Ceaseless Edge spikes effect should still activate + const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; + expect(tagAfter.tagType).toBe(ArenaTagType.SPIKES); + expect(tagAfter.layers).toBe(1); + }); + + it("should not cause a crash if the user is KO'd by Pledge moves", async () => { + game.override.moveset([ Moves.GRASS_PLEDGE, Moves.WATER_PLEDGE ]) + .battleType("double"); + await game.classicMode.startBattle(defaultParty); + + const enemyPokemon0 = game.scene.getEnemyField()[0]; + const enemyPokemon1 = game.scene.getEnemyField()[1]; + const playerPokemon0 = game.scene.getPlayerField()[0]; + const playerPokemon1 = game.scene.getPlayerField()[1]; + + game.move.select(Moves.GRASS_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.WATER_PLEDGE, 1, BattlerIndex.ENEMY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2 ]); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon0?.isFainted()).toBe(true); + expect(enemyPokemon1?.isFainted()).toBe(false); + expect(playerPokemon0?.isFainted()).toBe(false); + expect(playerPokemon1?.isFainted()).toBe(true); + + // Pledge secondary effect should still activate + const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.GRASS_WATER_PLEDGE, ArenaTagSide.ENEMY) as ArenaTrapTag; + expect(tagAfter.tagType).toBe(ArenaTagType.GRASS_WATER_PLEDGE); + }); + + /** + * In particular, this should prevent something like + * {@link https://github.com/pagefaultgames/pokerogue/issues/4219} + * from occurring with fainting by KO'ing a Destiny Bond user with U-Turn. + */ + it("should not allow the opponent to revive via Reviver Seed", async () => { + const moveToUse = Moves.TACKLE; + + game.override.moveset(moveToUse) + .startingHeldItems([{ name: "REVIVER_SEED" }]); + await game.classicMode.startBattle(defaultParty); + + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon(); + + game.move.select(moveToUse); + await game.setTurnOrder(enemyFirst); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemyPokemon?.isFainted()).toBe(true); + expect(playerPokemon?.isFainted()).toBe(true); + + // Check that the Tackle user's Reviver Seed did not activate + const revSeeds = game.scene.getModifiers(PokemonInstantReviveModifier).filter(m => m.pokemonId === playerPokemon?.id); + expect(revSeeds.length).toBe(1); + }); +}); diff --git a/src/test/moves/diamond_storm.test.ts b/src/test/moves/diamond_storm.test.ts new file mode 100644 index 00000000000..6e5be2a790d --- /dev/null +++ b/src/test/moves/diamond_storm.test.ts @@ -0,0 +1,46 @@ +import { allMoves } from "#app/data/move"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Moves - Diamond Storm", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.DIAMOND_STORM ]) + .battleType("single") + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should only increase defense once even if hitting 2 pokemon", async () => { + game.override.battleType("double"); + const diamondStorm = allMoves[Moves.DIAMOND_STORM]; + vi.spyOn(diamondStorm, "chance", "get").mockReturnValue(100); + vi.spyOn(diamondStorm, "accuracy", "get").mockReturnValue(100); + await game.classicMode.startBattle([ Species.FEEBAS ]); + + game.move.select(Moves.DIAMOND_STORM); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.getPlayerPokemon()!.getStatStage(Stat.DEF)).toBe(2); + }); +}); diff --git a/src/test/moves/dig.test.ts b/src/test/moves/dig.test.ts new file mode 100644 index 00000000000..4c6b5d3b75d --- /dev/null +++ b/src/test/moves/dig.test.ts @@ -0,0 +1,114 @@ +import { BattlerIndex } from "#app/battle"; +import { allMoves } from "#app/data/move"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { StatusEffect } from "#enums/status-effect"; +import { MoveResult } from "#app/field/pokemon"; +import { describe, beforeAll, afterEach, beforeEach, it, expect } from "vitest"; +import GameManager from "#test/utils/gameManager"; + +describe("Moves - Dig", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset(Moves.DIG) + .battleType("single") + .startingLevel(100) + .enemySpecies(Species.SNORLAX) + .enemyLevel(100) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.TACKLE); + }); + + it("should make the user semi-invulnerable, then attack over 2 turns", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.DIG); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.UNDERGROUND)).toBeDefined(); + expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.MISS); + expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveQueue()[0].move).toBe(Moves.DIG); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.UNDERGROUND)).toBeUndefined(); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveHistory()).toHaveLength(2); + + const playerDig = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.DIG); + expect(playerDig?.ppUsed).toBe(1); + }); + + it("should not allow the user to evade attacks from Pokemon with No Guard", async () => { + game.override.enemyAbility(Abilities.NO_GUARD); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.DIG); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); + expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + }); + + it("should not expend PP when the attack phase is cancelled", async () => { + game.override + .enemyAbility(Abilities.NO_GUARD) + .enemyMoveset(Moves.SPORE); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.DIG); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.UNDERGROUND)).toBeUndefined(); + expect(playerPokemon.status?.effect).toBe(StatusEffect.SLEEP); + + const playerDig = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.DIG); + expect(playerDig?.ppUsed).toBe(0); + }); + + it("should cause the user to take double damage from Earthquake", async () => { + await game.classicMode.startBattle([ Species.DONDOZO ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + const preDigEarthquakeDmg = playerPokemon.getAttackDamage(enemyPokemon, allMoves[Moves.EARTHQUAKE]).damage; + + game.move.select(Moves.DIG); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to("MoveEffectPhase"); + + const postDigEarthquakeDmg = playerPokemon.getAttackDamage(enemyPokemon, allMoves[Moves.EARTHQUAKE]).damage; + // these hopefully get avoid rounding errors :shrug: + expect(postDigEarthquakeDmg).toBeGreaterThanOrEqual(2 * preDigEarthquakeDmg); + expect(postDigEarthquakeDmg).toBeLessThan(2 * (preDigEarthquakeDmg + 1)); + }); +}); diff --git a/src/test/moves/disable.test.ts b/src/test/moves/disable.test.ts index a35d294e91f..3748598fa90 100644 --- a/src/test/moves/disable.test.ts +++ b/src/test/moves/disable.test.ts @@ -26,7 +26,7 @@ describe("Moves - Disable", () => { .battleType("single") .ability(Abilities.BALL_FETCH) .enemyAbility(Abilities.BALL_FETCH) - .moveset([Moves.DISABLE, Moves.SPLASH]) + .moveset([ Moves.DISABLE, Moves.SPLASH ]) .enemyMoveset(Moves.SPLASH) .starterSpecies(Species.PIKACHU) .enemySpecies(Species.SHUCKLE); @@ -38,7 +38,7 @@ describe("Moves - Disable", () => { const enemyMon = game.scene.getEnemyPokemon()!; game.move.select(Moves.DISABLE); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); expect(enemyMon.getMoveHistory()).toHaveLength(1); @@ -52,7 +52,7 @@ describe("Moves - Disable", () => { const enemyMon = game.scene.getEnemyPokemon()!; game.move.select(Moves.DISABLE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.toNextTurn(); expect(playerMon.getMoveHistory()[0]).toMatchObject({ move: Moves.DISABLE, result: MoveResult.FAIL }); @@ -65,7 +65,7 @@ describe("Moves - Disable", () => { const enemyMon = game.scene.getEnemyPokemon()!; game.move.select(Moves.DISABLE); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); game.move.select(Moves.SPLASH); @@ -78,14 +78,14 @@ describe("Moves - Disable", () => { }, 20000); it("cannot disable STRUGGLE", async() => { - game.override.enemyMoveset([Moves.STRUGGLE]); + game.override.enemyMoveset([ Moves.STRUGGLE ]); await game.classicMode.startBattle(); const playerMon = game.scene.getPlayerPokemon()!; const enemyMon = game.scene.getEnemyPokemon()!; game.move.select(Moves.DISABLE); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); expect(playerMon.getLastXMoves()[0].result).toBe(MoveResult.FAIL); @@ -103,7 +103,7 @@ describe("Moves - Disable", () => { // Both mons just used Splash last turn; now have player use Disable. game.move.select(Moves.DISABLE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.toNextTurn(); const enemyHistory = enemyMon.getMoveHistory(); @@ -113,13 +113,13 @@ describe("Moves - Disable", () => { }, 20000); it("disables NATURE POWER, not the move invoked by it", async() => { - game.override.enemyMoveset([Moves.NATURE_POWER]); + game.override.enemyMoveset([ Moves.NATURE_POWER ]); await game.classicMode.startBattle(); const enemyMon = game.scene.getEnemyPokemon()!; game.move.select(Moves.DISABLE); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); expect(enemyMon.isMoveRestricted(Moves.NATURE_POWER)).toBe(true); diff --git a/src/test/moves/dive.test.ts b/src/test/moves/dive.test.ts new file mode 100644 index 00000000000..b60416d7740 --- /dev/null +++ b/src/test/moves/dive.test.ts @@ -0,0 +1,137 @@ +import { BattlerTagType } from "#enums/battler-tag-type"; +import { StatusEffect } from "#enums/status-effect"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest"; +import { WeatherType } from "#enums/weather-type"; + +describe("Moves - Dive", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset(Moves.DIVE) + .battleType("single") + .startingLevel(100) + .enemySpecies(Species.SNORLAX) + .enemyLevel(100) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.TACKLE); + }); + + it("should make the user semi-invulnerable, then attack over 2 turns", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.DIVE); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.UNDERWATER)).toBeDefined(); + expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.MISS); + expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveQueue()[0].move).toBe(Moves.DIVE); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.UNDERWATER)).toBeUndefined(); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveHistory()).toHaveLength(2); + + const playerDive = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.DIVE); + expect(playerDive?.ppUsed).toBe(1); + }); + + it("should not allow the user to evade attacks from Pokemon with No Guard", async () => { + game.override.enemyAbility(Abilities.NO_GUARD); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.DIVE); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); + expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + }); + + it("should not expend PP when the attack phase is cancelled", async () => { + game.override + .enemyAbility(Abilities.NO_GUARD) + .enemyMoveset(Moves.SPORE); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.DIVE); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.UNDERWATER)).toBeUndefined(); + expect(playerPokemon.status?.effect).toBe(StatusEffect.SLEEP); + + const playerDive = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.DIVE); + expect(playerDive?.ppUsed).toBe(0); + }); + + it("should trigger on-contact post-defend ability effects", async () => { + game.override + .enemyAbility(Abilities.ROUGH_SKIN) + .enemyMoveset(Moves.SPLASH); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.DIVE); + + await game.phaseInterceptor.to("TurnEndPhase"); + + await game.phaseInterceptor.to("MoveEndPhase"); + expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); + expect(enemyPokemon.battleData.abilitiesApplied[0]).toBe(Abilities.ROUGH_SKIN); + }); + + it("should cancel attack after Harsh Sunlight is set", async () => { + game.override.enemyMoveset(Moves.SPLASH); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.DIVE); + + await game.phaseInterceptor.to("TurnEndPhase"); + await game.phaseInterceptor.to("TurnStartPhase", false); + game.scene.arena.trySetWeather(WeatherType.HARSH_SUN, false); + + await game.phaseInterceptor.to("MoveEndPhase"); + expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(playerPokemon.getTag(BattlerTagType.UNDERWATER)).toBeUndefined(); + + const playerDive = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.DIVE); + expect(playerDive?.ppUsed).toBe(1); + }); +}); diff --git a/src/test/moves/double_team.test.ts b/src/test/moves/double_team.test.ts index fa224c8df9e..62848553e06 100644 --- a/src/test/moves/double_team.test.ts +++ b/src/test/moves/double_team.test.ts @@ -24,16 +24,16 @@ describe("Moves - Double Team", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("single"); - game.override.moveset([Moves.DOUBLE_TEAM]); + game.override.moveset([ Moves.DOUBLE_TEAM ]); game.override.disableCrits(); game.override.ability(Abilities.BALL_FETCH); game.override.enemySpecies(Species.SHUCKLE); game.override.enemyAbility(Abilities.BALL_FETCH); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); }); it("raises the user's EVA stat stage by 1", async () => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const ally = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/dragon_cheer.test.ts b/src/test/moves/dragon_cheer.test.ts index beaf6ddb520..37b74d44360 100644 --- a/src/test/moves/dragon_cheer.test.ts +++ b/src/test/moves/dragon_cheer.test.ts @@ -27,11 +27,11 @@ describe("Moves - Dragon Cheer", () => { .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) .enemyLevel(20) - .moveset([Moves.DRAGON_CHEER, Moves.TACKLE, Moves.SPLASH]); + .moveset([ Moves.DRAGON_CHEER, Moves.TACKLE, Moves.SPLASH ]); }); it("increases the user's allies' critical hit ratio by one stage", async () => { - await game.classicMode.startBattle([Species.DRAGONAIR, Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.DRAGONAIR, Species.MAGIKARP ]); const enemy = game.scene.getEnemyField()[0]; @@ -40,7 +40,7 @@ describe("Moves - Dragon Cheer", () => { game.move.select(Moves.DRAGON_CHEER, 0); game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); // After Tackle await game.phaseInterceptor.to("TurnEndPhase"); @@ -48,7 +48,7 @@ describe("Moves - Dragon Cheer", () => { }); it("increases the user's Dragon-type allies' critical hit ratio by two stages", async () => { - await game.classicMode.startBattle([Species.MAGIKARP, Species.DRAGONAIR]); + await game.classicMode.startBattle([ Species.MAGIKARP, Species.DRAGONAIR ]); const enemy = game.scene.getEnemyField()[0]; @@ -57,7 +57,7 @@ describe("Moves - Dragon Cheer", () => { game.move.select(Moves.DRAGON_CHEER, 0); game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); // After Tackle await game.phaseInterceptor.to("TurnEndPhase"); @@ -65,7 +65,7 @@ describe("Moves - Dragon Cheer", () => { }); it("applies the effect based on the allies' type upon use of the move, and do not change if the allies' type changes later in battle", async () => { - await game.classicMode.startBattle([Species.DRAGONAIR, Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.DRAGONAIR, Species.MAGIKARP ]); const magikarp = game.scene.getPlayerField()[1]; const enemy = game.scene.getEnemyField()[0]; @@ -75,7 +75,7 @@ describe("Moves - Dragon Cheer", () => { game.move.select(Moves.DRAGON_CHEER, 0); game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); // After Tackle await game.phaseInterceptor.to("TurnEndPhase"); @@ -84,13 +84,13 @@ describe("Moves - Dragon Cheer", () => { await game.toNextTurn(); // Change Magikarp's type to Dragon - vi.spyOn(magikarp, "getTypes").mockReturnValue([Type.DRAGON]); - expect(magikarp.getTypes()).toEqual([Type.DRAGON]); + vi.spyOn(magikarp, "getTypes").mockReturnValue([ Type.DRAGON ]); + expect(magikarp.getTypes()).toEqual([ Type.DRAGON ]); game.move.select(Moves.SPLASH, 0); game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY); - await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.getCritStage).toHaveReturnedWith(1); // getCritStage is called on defender diff --git a/src/test/moves/dragon_rage.test.ts b/src/test/moves/dragon_rage.test.ts index cab8c3f808b..dcbed7107e6 100644 --- a/src/test/moves/dragon_rage.test.ts +++ b/src/test/moves/dragon_rage.test.ts @@ -35,7 +35,7 @@ describe("Moves - Dragon Rage", () => { game.override.battleType("single"); game.override.starterSpecies(Species.SNORLAX); - game.override.moveset([Moves.DRAGON_RAGE]); + game.override.moveset([ Moves.DRAGON_RAGE ]); game.override.ability(Abilities.BALL_FETCH); game.override.passiveAbility(Abilities.BALL_FETCH); game.override.startingLevel(100); @@ -58,7 +58,7 @@ describe("Moves - Dragon Rage", () => { it("ignores weaknesses", async () => { game.override.disableCrits(); - vi.spyOn(enemyPokemon, "getTypes").mockReturnValue([Type.DRAGON]); + vi.spyOn(enemyPokemon, "getTypes").mockReturnValue([ Type.DRAGON ]); game.move.select(Moves.DRAGON_RAGE); await game.phaseInterceptor.to(TurnEndPhase); @@ -68,7 +68,7 @@ describe("Moves - Dragon Rage", () => { it("ignores resistances", async () => { game.override.disableCrits(); - vi.spyOn(enemyPokemon, "getTypes").mockReturnValue([Type.STEEL]); + vi.spyOn(enemyPokemon, "getTypes").mockReturnValue([ Type.STEEL ]); game.move.select(Moves.DRAGON_RAGE); await game.phaseInterceptor.to(TurnEndPhase); @@ -88,7 +88,7 @@ describe("Moves - Dragon Rage", () => { it("ignores stab", async () => { game.override.disableCrits(); - vi.spyOn(partyPokemon, "getTypes").mockReturnValue([Type.DRAGON]); + vi.spyOn(partyPokemon, "getTypes").mockReturnValue([ Type.DRAGON ]); game.move.select(Moves.DRAGON_RAGE); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/moves/dragon_tail.test.ts b/src/test/moves/dragon_tail.test.ts index dd7193dc97f..cf801eb42c1 100644 --- a/src/test/moves/dragon_tail.test.ts +++ b/src/test/moves/dragon_tail.test.ts @@ -24,7 +24,7 @@ describe("Moves - Dragon Tail", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("single") - .moveset([Moves.DRAGON_TAIL, Moves.SPLASH, Moves.FLAMETHROWER]) + .moveset([ Moves.DRAGON_TAIL, Moves.SPLASH, Moves.FLAMETHROWER ]) .enemySpecies(Species.WAILORD) .enemyMoveset(Moves.SPLASH) .startingLevel(5) @@ -34,7 +34,7 @@ describe("Moves - Dragon Tail", () => { }); it("should cause opponent to flee, and not crash", async () => { - await game.classicMode.startBattle([Species.DRATINI]); + await game.classicMode.startBattle([ Species.DRATINI ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -52,7 +52,7 @@ describe("Moves - Dragon Tail", () => { it("should cause opponent to flee, display ability, and not crash", async () => { game.override.enemyAbility(Abilities.ROUGH_SKIN); - await game.classicMode.startBattle([Species.DRATINI]); + await game.classicMode.startBattle([ Species.DRATINI ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -71,7 +71,7 @@ describe("Moves - Dragon Tail", () => { game.override .battleType("double").enemyMoveset(Moves.SPLASH) .enemyAbility(Abilities.ROUGH_SKIN); - await game.classicMode.startBattle([Species.DRATINI, Species.DRATINI, Species.WAILORD, Species.WAILORD]); + await game.classicMode.startBattle([ Species.DRATINI, Species.DRATINI, Species.WAILORD, Species.WAILORD ]); const leadPokemon = game.scene.getParty()[0]!; @@ -103,7 +103,7 @@ describe("Moves - Dragon Tail", () => { .battleType("double") .enemyMoveset(Moves.SPLASH) .enemyAbility(Abilities.ROUGH_SKIN); - await game.classicMode.startBattle([Species.DRATINI, Species.DRATINI, Species.WAILORD, Species.WAILORD]); + await game.classicMode.startBattle([ Species.DRATINI, Species.DRATINI, Species.WAILORD, Species.WAILORD ]); const leadPokemon = game.scene.getParty()[0]!; const secPokemon = game.scene.getParty()[1]!; @@ -130,7 +130,7 @@ describe("Moves - Dragon Tail", () => { it("doesn't switch out if the target has suction cups", async () => { game.override.enemyAbility(Abilities.SUCTION_CUPS); - await game.classicMode.startBattle([Species.REGIELEKI]); + await game.classicMode.startBattle([ Species.REGIELEKI ]); const enemy = game.scene.getEnemyPokemon()!; @@ -139,4 +139,58 @@ describe("Moves - Dragon Tail", () => { expect(enemy.isFullHp()).toBe(false); }); + + it("should force a switch upon fainting an opponent normally", async () => { + game.override.startingWave(5) + .startingLevel(1000); // To make sure Dragon Tail KO's the opponent + await game.classicMode.startBattle([ Species.DRATINI ]); + + game.move.select(Moves.DRAGON_TAIL); + + await game.toNextTurn(); + + // Make sure the enemy switched to a healthy Pokemon + const enemy = game.scene.getEnemyPokemon()!; + expect(enemy).toBeDefined(); + expect(enemy.isFullHp()).toBe(true); + + // Make sure the enemy has a fainted Pokemon in their party and not on the field + const faintedEnemy = game.scene.getEnemyParty().find(p => !p.isAllowedInBattle()); + expect(faintedEnemy).toBeDefined(); + expect(game.scene.getEnemyField().length).toBe(1); + }); + + it("should not cause a softlock when activating an opponent trainer's reviver seed", async () => { + game.override.startingWave(5) + .enemyHeldItems([{ name: "REVIVER_SEED" }]) + .startingLevel(1000); // To make sure Dragon Tail KO's the opponent + await game.classicMode.startBattle([ Species.DRATINI ]); + + game.move.select(Moves.DRAGON_TAIL); + + await game.toNextTurn(); + + // Make sure the enemy field is not empty and has a revived Pokemon + const enemy = game.scene.getEnemyPokemon()!; + expect(enemy).toBeDefined(); + expect(enemy.hp).toBe(Math.floor(enemy.getMaxHp() / 2)); + expect(game.scene.getEnemyField().length).toBe(1); + }); + + it("should not cause a softlock when activating a player's reviver seed", async () => { + game.override.startingHeldItems([{ name: "REVIVER_SEED" }]) + .enemyMoveset(Moves.DRAGON_TAIL) + .enemyLevel(1000); // To make sure Dragon Tail KO's the player + await game.classicMode.startBattle([ Species.DRATINI, Species.BULBASAUR ]); + + game.move.select(Moves.SPLASH); + + await game.toNextTurn(); + + // Make sure the player's field is not empty and has a revived Pokemon + const dratini = game.scene.getPlayerPokemon()!; + expect(dratini).toBeDefined(); + expect(dratini.hp).toBe(Math.floor(dratini.getMaxHp() / 2)); + expect(game.scene.getPlayerField().length).toBe(1); + }); }); diff --git a/src/test/moves/dynamax_cannon.test.ts b/src/test/moves/dynamax_cannon.test.ts index 6ac0befdb36..9dd48d3c94c 100644 --- a/src/test/moves/dynamax_cannon.test.ts +++ b/src/test/moves/dynamax_cannon.test.ts @@ -27,7 +27,7 @@ describe("Moves - Dynamax Cannon", () => { beforeEach(() => { game = new GameManager(phaserGame); - game.override.moveset([dynamaxCannon.id]); + game.override.moveset([ dynamaxCannon.id ]); game.override.startingLevel(200); // Note that, for Waves 1-10, the level cap is 10 @@ -36,7 +36,7 @@ describe("Moves - Dynamax Cannon", () => { game.override.disableCrits(); game.override.enemySpecies(Species.MAGIKARP); - game.override.enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); vi.spyOn(dynamaxCannon, "calculateBattlePower"); }); @@ -161,7 +161,7 @@ describe("Moves - Dynamax Cannon", () => { ]); game.move.select(dynamaxCannon.id); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(dynamaxCannon.id); diff --git a/src/test/moves/electrify.test.ts b/src/test/moves/electrify.test.ts new file mode 100644 index 00000000000..5d15a825688 --- /dev/null +++ b/src/test/moves/electrify.test.ts @@ -0,0 +1,69 @@ +import { BattlerIndex } from "#app/battle"; +import { Type } from "#app/data/type"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Electrify", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset(Moves.ELECTRIFY) + .battleType("single") + .startingLevel(100) + .enemySpecies(Species.SNORLAX) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.TACKLE) + .enemyLevel(100); + }); + + it("should convert attacks to Electric type", async () => { + await game.classicMode.startBattle([ Species.EXCADRILL ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + vi.spyOn(enemyPokemon, "getMoveType"); + + game.move.select(Moves.ELECTRIFY); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); + expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); + }); + + it("should override type changes from abilities", async () => { + game.override.enemyAbility(Abilities.PIXILATE); + + await game.classicMode.startBattle([ Species.EXCADRILL ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getPlayerPokemon()!; + vi.spyOn(enemyPokemon, "getMoveType"); + + game.move.select(Moves.ELECTRIFY); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); + expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); + }); +}); diff --git a/src/test/moves/electro_shot.test.ts b/src/test/moves/electro_shot.test.ts new file mode 100644 index 00000000000..1373b4941eb --- /dev/null +++ b/src/test/moves/electro_shot.test.ts @@ -0,0 +1,104 @@ +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Stat } from "#enums/stat"; +import { WeatherType } from "#enums/weather-type"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest"; + +describe("Moves - Electro Shot", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset(Moves.ELECTRO_SHOT) + .battleType("single") + .startingLevel(100) + .enemySpecies(Species.SNORLAX) + .enemyLevel(100) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should increase the user's Sp. Atk on the first turn, then attack on the second turn", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.ELECTRO_SHOT); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.CHARGING)).toBeDefined(); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.OTHER); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(1); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.CHARGING)).toBeUndefined(); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveHistory()).toHaveLength(2); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(1); + expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + + const playerElectroShot = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.ELECTRO_SHOT); + expect(playerElectroShot?.ppUsed).toBe(1); + }); + + it.each([ + { weatherType: WeatherType.RAIN, name: "Rain" }, + { weatherType: WeatherType.HEAVY_RAIN, name: "Heavy Rain" } + ])("should fully resolve in one turn if $name is active", async ({ weatherType }) => { + game.override.weather(weatherType); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.ELECTRO_SHOT); + + await game.phaseInterceptor.to("MoveEffectPhase", false); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(1); + + await game.phaseInterceptor.to("MoveEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.CHARGING)).toBeUndefined(); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveHistory()).toHaveLength(2); + expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + + const playerElectroShot = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.ELECTRO_SHOT); + expect(playerElectroShot?.ppUsed).toBe(1); + }); + + it("should only increase Sp. Atk once with Multi-Lens", async () => { + game.override + .weather(WeatherType.RAIN) + .startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.ELECTRO_SHOT); + + await game.phaseInterceptor.to("MoveEndPhase"); + expect(playerPokemon.turnData.hitCount).toBe(2); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(1); + }); +}); diff --git a/src/test/moves/fake_out.test.ts b/src/test/moves/fake_out.test.ts index e306ab12a3f..f20b6db3a13 100644 --- a/src/test/moves/fake_out.test.ts +++ b/src/test/moves/fake_out.test.ts @@ -23,7 +23,7 @@ describe("Moves - Fake Out", () => { game.override .battleType("single") .enemySpecies(Species.CORVIKNIGHT) - .moveset([Moves.FAKE_OUT, Moves.SPLASH]) + .moveset([ Moves.FAKE_OUT, Moves.SPLASH ]) .enemyMoveset(Moves.SPLASH) .enemyLevel(10) .startingLevel(10) // prevent LevelUpPhase from happening @@ -31,7 +31,7 @@ describe("Moves - Fake Out", () => { }); it("can only be used on the first turn a pokemon is sent out in a battle", async() => { - await game.classicMode.startBattle([Species.FEEBAS]); + await game.classicMode.startBattle([ Species.FEEBAS ]); const enemy = game.scene.getEnemyPokemon()!; @@ -49,7 +49,7 @@ describe("Moves - Fake Out", () => { // This is a PokeRogue buff to Fake Out it("can be used at the start of every wave even if the pokemon wasn't recalled", async() => { - await game.classicMode.startBattle([Species.FEEBAS]); + await game.classicMode.startBattle([ Species.FEEBAS ]); const enemy = game.scene.getEnemyPokemon()!; enemy.damageAndUpdate(enemy.getMaxHp() - 1); @@ -65,7 +65,7 @@ describe("Moves - Fake Out", () => { it("can be used again if recalled and sent back out", async() => { game.override.startingWave(4); - await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); const enemy1 = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/fillet_away.test.ts b/src/test/moves/fillet_away.test.ts index d8dd74a259c..aa3243270cb 100644 --- a/src/test/moves/fillet_away.test.ts +++ b/src/test/moves/fillet_away.test.ts @@ -33,7 +33,7 @@ describe("Moves - FILLET AWAY", () => { game.override.enemySpecies(Species.SNORLAX); game.override.startingLevel(100); game.override.enemyLevel(100); - game.override.moveset([Moves.FILLET_AWAY]); + game.override.moveset([ Moves.FILLET_AWAY ]); game.override.enemyMoveset(Moves.SPLASH); }); @@ -41,7 +41,7 @@ describe("Moves - FILLET AWAY", () => { test("raises the user's ATK, SPATK, and SPD stat stages by 2 each, at the cost of 1/2 of its maximum HP", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = toDmgValue(leadPokemon.getMaxHp() / RATIO); @@ -58,7 +58,7 @@ describe("Moves - FILLET AWAY", () => { test("still takes effect if one or more of the involved stat stages are not at max", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = toDmgValue(leadPokemon.getMaxHp() / RATIO); @@ -79,7 +79,7 @@ describe("Moves - FILLET AWAY", () => { test("fails if all stat stages involved are at max", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -99,7 +99,7 @@ describe("Moves - FILLET AWAY", () => { test("fails if the user's health is less than 1/2", async() => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const hpLost = toDmgValue(leadPokemon.getMaxHp() / RATIO); diff --git a/src/test/moves/fissure.test.ts b/src/test/moves/fissure.test.ts index 8689ce4079e..16c3faa6827 100644 --- a/src/test/moves/fissure.test.ts +++ b/src/test/moves/fissure.test.ts @@ -32,7 +32,7 @@ describe("Moves - Fissure", () => { game.override.disableCrits(); game.override.starterSpecies(Species.SNORLAX); - game.override.moveset([Moves.FISSURE]); + game.override.moveset([ Moves.FISSURE ]); game.override.passiveAbility(Abilities.BALL_FETCH); game.override.startingLevel(100); diff --git a/src/test/moves/flame_burst.test.ts b/src/test/moves/flame_burst.test.ts index b2858af2b24..feedee3b7bc 100644 --- a/src/test/moves/flame_burst.test.ts +++ b/src/test/moves/flame_burst.test.ts @@ -36,18 +36,18 @@ describe("Moves - Flame Burst", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("double"); - game.override.moveset([Moves.FLAME_BURST, Moves.SPLASH]); + game.override.moveset([ Moves.FLAME_BURST, Moves.SPLASH ]); game.override.disableCrits(); game.override.ability(Abilities.UNNERVE); game.override.startingWave(4); game.override.enemySpecies(Species.SHUCKLE); game.override.enemyAbility(Abilities.BALL_FETCH); - game.override.enemyMoveset([Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH ]); }); it("inflicts damage to the target's ally equal to 1/16 of its max HP", async () => { - await game.startBattle([Species.PIKACHU, Species.PIKACHU]); - const [leftEnemy, rightEnemy] = game.scene.getEnemyField(); + await game.startBattle([ Species.PIKACHU, Species.PIKACHU ]); + const [ leftEnemy, rightEnemy ] = game.scene.getEnemyField(); game.move.select(Moves.FLAME_BURST, 0, leftEnemy.getBattlerIndex()); game.move.select(Moves.SPLASH, 1); @@ -60,8 +60,8 @@ describe("Moves - Flame Burst", () => { it("does not inflict damage to the target's ally if the target was not affected by Flame Burst", async () => { game.override.enemyAbility(Abilities.FLASH_FIRE); - await game.startBattle([Species.PIKACHU, Species.PIKACHU]); - const [leftEnemy, rightEnemy] = game.scene.getEnemyField(); + await game.startBattle([ Species.PIKACHU, Species.PIKACHU ]); + const [ leftEnemy, rightEnemy ] = game.scene.getEnemyField(); game.move.select(Moves.FLAME_BURST, 0, leftEnemy.getBattlerIndex()); game.move.select(Moves.SPLASH, 1); @@ -72,8 +72,8 @@ describe("Moves - Flame Burst", () => { }); it("does not interact with the target ally's abilities", async () => { - await game.startBattle([Species.PIKACHU, Species.PIKACHU]); - const [leftEnemy, rightEnemy] = game.scene.getEnemyField(); + await game.startBattle([ Species.PIKACHU, Species.PIKACHU ]); + const [ leftEnemy, rightEnemy ] = game.scene.getEnemyField(); vi.spyOn(rightEnemy, "getAbility").mockReturnValue(allAbilities[Abilities.FLASH_FIRE]); @@ -86,8 +86,8 @@ describe("Moves - Flame Burst", () => { }); it("effect damage is prevented by Magic Guard", async () => { - await game.startBattle([Species.PIKACHU, Species.PIKACHU]); - const [leftEnemy, rightEnemy] = game.scene.getEnemyField(); + await game.startBattle([ Species.PIKACHU, Species.PIKACHU ]); + const [ leftEnemy, rightEnemy ] = game.scene.getEnemyField(); vi.spyOn(rightEnemy, "getAbility").mockReturnValue(allAbilities[Abilities.MAGIC_GUARD]); diff --git a/src/test/moves/flower_shield.test.ts b/src/test/moves/flower_shield.test.ts index f5fe8d532cc..1a5cd326fd8 100644 --- a/src/test/moves/flower_shield.test.ts +++ b/src/test/moves/flower_shield.test.ts @@ -29,14 +29,14 @@ describe("Moves - Flower Shield", () => { game.override.ability(Abilities.NONE); game.override.enemyAbility(Abilities.NONE); game.override.battleType("single"); - game.override.moveset([Moves.FLOWER_SHIELD, Moves.SPLASH]); + game.override.moveset([ Moves.FLOWER_SHIELD, Moves.SPLASH ]); game.override.enemyMoveset(Moves.SPLASH); }); it("raises DEF stat stage by 1 for all Grass-type Pokemon on the field by one stage - single battle", async () => { game.override.enemySpecies(Species.CHERRIM); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const cherrim = game.scene.getEnemyPokemon()!; const magikarp = game.scene.getPlayerPokemon()!; @@ -53,7 +53,7 @@ describe("Moves - Flower Shield", () => { it("raises DEF stat stage by 1 for all Grass-type Pokemon on the field by one stage - double battle", async () => { game.override.enemySpecies(Species.MAGIKARP).startingBiome(Biome.GRASS).battleType("double"); - await game.startBattle([Species.CHERRIM, Species.MAGIKARP]); + await game.startBattle([ Species.CHERRIM, Species.MAGIKARP ]); const field = game.scene.getField(true); const grassPokemons = field.filter(p => p.getTypes().includes(Type.GRASS)); @@ -75,10 +75,10 @@ describe("Moves - Flower Shield", () => { */ it("does not raise DEF stat stage for a Pokemon in semi-vulnerable state", async () => { game.override.enemySpecies(Species.PARAS); - game.override.enemyMoveset([Moves.DIG, Moves.DIG, Moves.DIG, Moves.DIG]); + game.override.enemyMoveset([ Moves.DIG, Moves.DIG, Moves.DIG, Moves.DIG ]); game.override.enemyLevel(50); - await game.startBattle([Species.CHERRIM]); + await game.startBattle([ Species.CHERRIM ]); const paras = game.scene.getEnemyPokemon()!; const cherrim = game.scene.getPlayerPokemon()!; @@ -97,7 +97,7 @@ describe("Moves - Flower Shield", () => { it("does nothing if there are no Grass-type Pokemon on the field", async () => { game.override.enemySpecies(Species.MAGIKARP); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const enemy = game.scene.getEnemyPokemon()!; const ally = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/fly.test.ts b/src/test/moves/fly.test.ts new file mode 100644 index 00000000000..6ae758fe3dc --- /dev/null +++ b/src/test/moves/fly.test.ts @@ -0,0 +1,122 @@ +import { BattlerTagType } from "#enums/battler-tag-type"; +import { StatusEffect } from "#enums/status-effect"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; +import { BattlerIndex } from "#app/battle"; +import { allMoves } from "#app/data/move"; + +describe("Moves - Fly", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset(Moves.FLY) + .battleType("single") + .startingLevel(100) + .enemySpecies(Species.SNORLAX) + .enemyLevel(100) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.TACKLE); + + vi.spyOn(allMoves[Moves.FLY], "accuracy", "get").mockReturnValue(100); + }); + + it("should make the user semi-invulnerable, then attack over 2 turns", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.FLY); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.FLYING)).toBeDefined(); + expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.MISS); + expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveQueue()[0].move).toBe(Moves.FLY); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.FLYING)).toBeUndefined(); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveHistory()).toHaveLength(2); + + const playerFly = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.FLY); + expect(playerFly?.ppUsed).toBe(1); + }); + + it("should not allow the user to evade attacks from Pokemon with No Guard", async () => { + game.override.enemyAbility(Abilities.NO_GUARD); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.FLY); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); + expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + }); + + it("should not expend PP when the attack phase is cancelled", async () => { + game.override + .enemyAbility(Abilities.NO_GUARD) + .enemyMoveset(Moves.SPORE); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.FLY); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.FLYING)).toBeUndefined(); + expect(playerPokemon.status?.effect).toBe(StatusEffect.SLEEP); + + const playerFly = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.FLY); + expect(playerFly?.ppUsed).toBe(0); + }); + + it("should be cancelled when another Pokemon uses Gravity", async () => { + game.override.enemyMoveset([ Moves.SPLASH, Moves.GRAVITY ]); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.FLY); + + await game.forceEnemyMove(Moves.SPLASH); + + await game.toNextTurn(); + await game.forceEnemyMove(Moves.GRAVITY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + + const playerFly = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.FLY); + expect(playerFly?.ppUsed).toBe(0); + }); +}); diff --git a/src/test/moves/focus_punch.test.ts b/src/test/moves/focus_punch.test.ts index b839c228b68..386eb2537ee 100644 --- a/src/test/moves/focus_punch.test.ts +++ b/src/test/moves/focus_punch.test.ts @@ -11,7 +11,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - Focus Punch", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -31,7 +30,7 @@ describe("Moves - Focus Punch", () => { game.override .battleType("single") .ability(Abilities.UNNERVE) - .moveset([Moves.FOCUS_PUNCH]) + .moveset([ Moves.FOCUS_PUNCH ]) .enemySpecies(Species.GROUDON) .enemyAbility(Abilities.INSOMNIA) .enemyMoveset(Moves.SPLASH) @@ -42,7 +41,7 @@ describe("Moves - Focus Punch", () => { it( "should deal damage at the end of turn if uninterrupted", async () => { - await game.startBattle([Species.CHARIZARD]); + await game.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -67,9 +66,9 @@ describe("Moves - Focus Punch", () => { it( "should fail if the user is hit", async () => { - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); - await game.startBattle([Species.CHARIZARD]); + await game.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -94,9 +93,9 @@ describe("Moves - Focus Punch", () => { it( "should be cancelled if the user falls asleep mid-turn", async () => { - game.override.enemyMoveset([Moves.SPORE]); + game.override.enemyMoveset([ Moves.SPORE ]); - await game.startBattle([Species.CHARIZARD]); + await game.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -120,7 +119,7 @@ describe("Moves - Focus Punch", () => { /** Guarantee a Trainer battle with multiple enemy Pokemon */ game.override.startingWave(25); - await game.startBattle([Species.CHARIZARD]); + await game.startBattle([ Species.CHARIZARD ]); game.forceEnemyToSwitch(); game.move.select(Moves.FOCUS_PUNCH); diff --git a/src/test/moves/follow_me.test.ts b/src/test/moves/follow_me.test.ts index 28fb1045a8c..fba7937f812 100644 --- a/src/test/moves/follow_me.test.ts +++ b/src/test/moves/follow_me.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Moves - Follow Me", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -32,14 +31,14 @@ describe("Moves - Follow Me", () => { game.override.enemySpecies(Species.SNORLAX); game.override.startingLevel(100); game.override.enemyLevel(100); - game.override.moveset([Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK]); - game.override.enemyMoveset([Moves.TACKLE, Moves.FOLLOW_ME, Moves.SPLASH]); + game.override.moveset([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); + game.override.enemyMoveset([ Moves.TACKLE, Moves.FOLLOW_ME, Moves.SPLASH ]); }); test( "move should redirect enemy attacks to the user", async () => { - await game.classicMode.startBattle([Species.AMOONGUSS, Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerField(); @@ -60,7 +59,7 @@ describe("Moves - Follow Me", () => { test( "move should redirect enemy attacks to the first ally that uses it", async () => { - await game.classicMode.startBattle([Species.AMOONGUSS, Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerField(); @@ -84,9 +83,9 @@ describe("Moves - Follow Me", () => { "move effect should be bypassed by Stalwart", async () => { game.override.ability(Abilities.STALWART); - game.override.moveset([Moves.QUICK_ATTACK]); + game.override.moveset([ Moves.QUICK_ATTACK ]); - await game.classicMode.startBattle([Species.AMOONGUSS, Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); const enemyPokemon = game.scene.getEnemyField(); @@ -108,9 +107,9 @@ describe("Moves - Follow Me", () => { test( "move effect should be bypassed by Snipe Shot", async () => { - game.override.moveset([Moves.SNIPE_SHOT]); + game.override.moveset([ Moves.SNIPE_SHOT ]); - await game.classicMode.startBattle([Species.AMOONGUSS, Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); const enemyPokemon = game.scene.getEnemyField(); diff --git a/src/test/moves/foresight.test.ts b/src/test/moves/foresight.test.ts index d58097691fd..1195cd0b71b 100644 --- a/src/test/moves/foresight.test.ts +++ b/src/test/moves/foresight.test.ts @@ -27,7 +27,7 @@ describe("Moves - Foresight", () => { .enemyMoveset(Moves.SPLASH) .enemyLevel(5) .starterSpecies(Species.MAGIKARP) - .moveset([Moves.FORESIGHT, Moves.QUICK_ATTACK, Moves.MACH_PUNCH]); + .moveset([ Moves.FORESIGHT, Moves.QUICK_ATTACK, Moves.MACH_PUNCH ]); }); it("should allow Normal and Fighting moves to hit Ghost types", async () => { @@ -54,7 +54,7 @@ describe("Moves - Foresight", () => { }); it("should ignore target's evasiveness boosts", async () => { - game.override.enemyMoveset([Moves.MINIMIZE]); + game.override.enemyMoveset([ Moves.MINIMIZE ]); await game.startBattle(); const pokemon = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/forests_curse.test.ts b/src/test/moves/forests_curse.test.ts new file mode 100644 index 00000000000..c49bdab5255 --- /dev/null +++ b/src/test/moves/forests_curse.test.ts @@ -0,0 +1,47 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Type } from "#app/data/type"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Forest's Curse", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.FORESTS_CURSE, Moves.TRICK_OR_TREAT ]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("will replace the added type from Trick Or Treat", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const enemyPokemon = game.scene.getEnemyPokemon(); + game.move.select(Moves.TRICK_OR_TREAT); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyPokemon!.summonData.addedType).toBe(Type.GHOST); + + game.move.select(Moves.FORESTS_CURSE); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyPokemon?.summonData.addedType).toBe(Type.GRASS); + }); +}); diff --git a/src/test/moves/freeze_dry.test.ts b/src/test/moves/freeze_dry.test.ts index b901f04e6a1..c09d12fa597 100644 --- a/src/test/moves/freeze_dry.test.ts +++ b/src/test/moves/freeze_dry.test.ts @@ -28,7 +28,7 @@ describe("Moves - Freeze-Dry", () => { .enemyMoveset(Moves.SPLASH) .starterSpecies(Species.FEEBAS) .ability(Abilities.BALL_FETCH) - .moveset([Moves.FREEZE_DRY]); + .moveset([ Moves.FREEZE_DRY ]); }); it("should deal 2x damage to pure water types", async () => { @@ -38,7 +38,7 @@ describe("Moves - Freeze-Dry", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FREEZE_DRY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); @@ -52,7 +52,7 @@ describe("Moves - Freeze-Dry", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FREEZE_DRY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); @@ -66,7 +66,7 @@ describe("Moves - Freeze-Dry", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FREEZE_DRY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(1); @@ -81,7 +81,7 @@ describe("Moves - Freeze-Dry", () => { vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FREEZE_DRY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); @@ -89,14 +89,14 @@ describe("Moves - Freeze-Dry", () => { // enable once Electrify is implemented (and the interaction is fixed, as above) it.todo("should deal 2x damage to water types under Electrify", async () => { - game.override.enemyMoveset([Moves.ELECTRIFY]); + game.override.enemyMoveset([ Moves.ELECTRIFY ]); await game.classicMode.startBattle(); const enemy = game.scene.getEnemyPokemon()!; vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FREEZE_DRY); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("BerryPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); diff --git a/src/test/moves/freezy_frost.test.ts b/src/test/moves/freezy_frost.test.ts index ad5163dae48..09d7779474f 100644 --- a/src/test/moves/freezy_frost.test.ts +++ b/src/test/moves/freezy_frost.test.ts @@ -33,7 +33,7 @@ describe("Moves - Freezy Frost", () => { .moveset([ Moves.FREEZY_FROST, Moves.HOWL, Moves.SPLASH ]) .ability(Abilities.BALL_FETCH); - vi.spyOn(allMoves[ Moves.FREEZY_FROST ], "accuracy", "get").mockReturnValue(100); + vi.spyOn(allMoves[Moves.FREEZY_FROST], "accuracy", "get").mockReturnValue(100); }); it( diff --git a/src/test/moves/fusion_bolt.test.ts b/src/test/moves/fusion_bolt.test.ts index db31863ad03..4e35b939abf 100644 --- a/src/test/moves/fusion_bolt.test.ts +++ b/src/test/moves/fusion_bolt.test.ts @@ -23,12 +23,12 @@ describe("Moves - Fusion Bolt", () => { beforeEach(() => { game = new GameManager(phaserGame); - game.override.moveset([fusionBolt]); + game.override.moveset([ fusionBolt ]); game.override.startingLevel(1); game.override.enemySpecies(Species.RESHIRAM); game.override.enemyAbility(Abilities.ROUGH_SKIN); - game.override.enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); game.override.battleType("single"); game.override.startingWave(97); diff --git a/src/test/moves/fusion_flare.test.ts b/src/test/moves/fusion_flare.test.ts index 0a8f6f9115d..162cefcfb1e 100644 --- a/src/test/moves/fusion_flare.test.ts +++ b/src/test/moves/fusion_flare.test.ts @@ -24,11 +24,11 @@ describe("Moves - Fusion Flare", () => { beforeEach(() => { game = new GameManager(phaserGame); - game.override.moveset([fusionFlare]); + game.override.moveset([ fusionFlare ]); game.override.startingLevel(1); game.override.enemySpecies(Species.RATTATA); - game.override.enemyMoveset([Moves.REST, Moves.REST, Moves.REST, Moves.REST]); + game.override.enemyMoveset([ Moves.REST, Moves.REST, Moves.REST, Moves.REST ]); game.override.battleType("single"); game.override.startingWave(97); diff --git a/src/test/moves/fusion_flare_bolt.test.ts b/src/test/moves/fusion_flare_bolt.test.ts index a8372fcaaab..0d9b9898276 100644 --- a/src/test/moves/fusion_flare_bolt.test.ts +++ b/src/test/moves/fusion_flare_bolt.test.ts @@ -30,11 +30,11 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { beforeEach(() => { game = new GameManager(phaserGame); - game.override.moveset([fusionFlare.id, fusionBolt.id]); + game.override.moveset([ fusionFlare.id, fusionBolt.id ]); game.override.startingLevel(1); game.override.enemySpecies(Species.RESHIRAM); - game.override.enemyMoveset([Moves.REST, Moves.REST, Moves.REST, Moves.REST]); + game.override.enemyMoveset([ Moves.REST, Moves.REST, Moves.REST, Moves.REST ]); game.override.battleType("double"); game.override.startingWave(97); @@ -54,7 +54,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY); // Force user party to act before enemy party - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); @@ -77,7 +77,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.move.select(fusionFlare.id, 1, BattlerIndex.ENEMY); // Force user party to act before enemy party - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); @@ -100,7 +100,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.move.select(fusionBolt.id, 1, BattlerIndex.PLAYER); // Force first enemy to act (and fail) in between party - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); @@ -119,7 +119,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { }, 20000); it("FUSION_FLARE should not double power of subsequent FUSION_BOLT if a move succeeded in between", async () => { - game.override.enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); await game.startBattle([ Species.ZEKROM, Species.ZEKROM @@ -129,7 +129,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY); // Force first enemy to act in between party - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); @@ -156,7 +156,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.move.select(fusionFlare.id, 1, BattlerIndex.PLAYER); // Force user party to act before enemy party - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); @@ -170,7 +170,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { }, 20000); it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves", async () => { - game.override.enemyMoveset([fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id]); + game.override.enemyMoveset([ fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id ]); await game.startBattle([ Species.ZEKROM, Species.ZEKROM @@ -186,12 +186,12 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { // Mock stats by replacing entries in copy with desired values for specific stats const stats = { enemy: [ - [...enemyParty[0].stats], - [...enemyParty[1].stats], + [ ...enemyParty[0].stats ], + [ ...enemyParty[1].stats ], ], player: [ - [...party[0].stats], - [...party[1].stats], + [ ...party[0].stats ], + [ ...party[1].stats ], ] }; @@ -205,7 +205,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY); // Force first enemy to act in between party - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); @@ -229,7 +229,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { }, 20000); it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves if moves are aimed at allies", async () => { - game.override.enemyMoveset([fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id]); + game.override.enemyMoveset([ fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id ]); await game.startBattle([ Species.ZEKROM, Species.ZEKROM @@ -245,12 +245,12 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { // Mock stats by replacing entries in copy with desired values for specific stats const stats = { enemy: [ - [...enemyParty[0].stats], - [...enemyParty[1].stats], + [ ...enemyParty[0].stats ], + [ ...enemyParty[1].stats ], ], player: [ - [...party[0].stats], - [...party[1].stats], + [ ...party[0].stats ], + [ ...party[1].stats ], ] }; @@ -264,7 +264,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { game.move.select(fusionBolt.id, 1, BattlerIndex.PLAYER); // Force first enemy to act in between party - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); diff --git a/src/test/moves/gastro_acid.test.ts b/src/test/moves/gastro_acid.test.ts index 60b2bd80c05..fdd75b90b13 100644 --- a/src/test/moves/gastro_acid.test.ts +++ b/src/test/moves/gastro_acid.test.ts @@ -7,7 +7,6 @@ import GameManager from "#test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - Gastro Acid", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -28,7 +27,7 @@ describe("Moves - Gastro Acid", () => { game.override.startingLevel(1); game.override.enemyLevel(100); game.override.ability(Abilities.NONE); - game.override.moveset([Moves.GASTRO_ACID, Moves.WATER_GUN, Moves.SPLASH, Moves.CORE_ENFORCER]); + game.override.moveset([ Moves.GASTRO_ACID, Moves.WATER_GUN, Moves.SPLASH, Moves.CORE_ENFORCER ]); game.override.enemySpecies(Species.BIDOOF); game.override.enemyMoveset(Moves.SPLASH); game.override.enemyAbility(Abilities.WATER_ABSORB); @@ -69,7 +68,7 @@ describe("Moves - Gastro Acid", () => { game.move.select(Moves.CORE_ENFORCER); // Force player to be slower to enable Core Enforcer to proc its suppression effect - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnInitPhase"); diff --git a/src/test/moves/geomancy.test.ts b/src/test/moves/geomancy.test.ts new file mode 100644 index 00000000000..6e2f40b9144 --- /dev/null +++ b/src/test/moves/geomancy.test.ts @@ -0,0 +1,78 @@ +import { EffectiveStat, Stat } from "#enums/stat"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest"; + +describe("Moves - Geomancy", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset(Moves.GEOMANCY) + .battleType("single") + .startingLevel(100) + .enemySpecies(Species.SNORLAX) + .enemyLevel(100) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should boost the user's stats on the second turn of use", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const player = game.scene.getPlayerPokemon()!; + const affectedStats: EffectiveStat[] = [ Stat.SPATK, Stat.SPDEF, Stat.SPD ]; + + game.move.select(Moves.GEOMANCY); + + await game.phaseInterceptor.to("TurnEndPhase"); + affectedStats.forEach((stat) => expect(player.getStatStage(stat)).toBe(0)); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.OTHER); + + await game.phaseInterceptor.to("TurnEndPhase"); + affectedStats.forEach((stat) => expect(player.getStatStage(stat)).toBe(2)); + expect(player.getMoveHistory()).toHaveLength(2); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + + const playerGeomancy = player.getMoveset().find((mv) => mv && mv.moveId === Moves.GEOMANCY); + expect(playerGeomancy?.ppUsed).toBe(1); + }); + + it("should execute over 2 turns between waves", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const player = game.scene.getPlayerPokemon()!; + const affectedStats: EffectiveStat[] = [ Stat.SPATK, Stat.SPDEF, Stat.SPD ]; + + game.move.select(Moves.GEOMANCY); + + await game.phaseInterceptor.to("MoveEndPhase", false); + await game.doKillOpponents(); + + await game.toNextWave(); + + await game.phaseInterceptor.to("TurnEndPhase"); + affectedStats.forEach((stat) => expect(player.getStatStage(stat)).toBe(2)); + expect(player.getMoveHistory()).toHaveLength(2); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + + const playerGeomancy = player.getMoveset().find((mv) => mv && mv.moveId === Moves.GEOMANCY); + expect(playerGeomancy?.ppUsed).toBe(1); + }); +}); diff --git a/src/test/moves/gigaton_hammer.test.ts b/src/test/moves/gigaton_hammer.test.ts index b0ab06fdeb5..f54700fe660 100644 --- a/src/test/moves/gigaton_hammer.test.ts +++ b/src/test/moves/gigaton_hammer.test.ts @@ -25,7 +25,7 @@ describe("Moves - Gigaton Hammer", () => { .battleType("single") .enemySpecies(Species.MAGIKARP) .starterSpecies(Species.FEEBAS) - .moveset([Moves.GIGATON_HAMMER]) + .moveset([ Moves.GIGATON_HAMMER ]) .startingLevel(10) .enemyLevel(100) .enemyMoveset(Moves.SPLASH) @@ -38,7 +38,7 @@ describe("Moves - Gigaton Hammer", () => { const enemy1 = game.scene.getEnemyPokemon()!; game.move.select(Moves.GIGATON_HAMMER); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy1.hp).toBeLessThan(enemy1.getMaxHp()); @@ -61,7 +61,7 @@ describe("Moves - Gigaton Hammer", () => { const enemy1 = game.scene.getEnemyPokemon()!; game.move.select(Moves.GIGATON_HAMMER); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy1.hp).toBeLessThan(enemy1.getMaxHp()); diff --git a/src/test/moves/glaive_rush.test.ts b/src/test/moves/glaive_rush.test.ts index 1a524b4aef6..b36c3e20c7a 100644 --- a/src/test/moves/glaive_rush.test.ts +++ b/src/test/moves/glaive_rush.test.ts @@ -7,7 +7,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - Glaive Rush", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -29,10 +28,10 @@ describe("Moves - Glaive Rush", () => { .disableCrits() .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.BALL_FETCH) - .enemyMoveset([Moves.GLAIVE_RUSH]) + .enemyMoveset([ Moves.GLAIVE_RUSH ]) .starterSpecies(Species.KLINK) .ability(Abilities.BALL_FETCH) - .moveset([Moves.SHADOW_SNEAK, Moves.AVALANCHE, Moves.SPLASH, Moves.GLAIVE_RUSH]); + .moveset([ Moves.SHADOW_SNEAK, Moves.AVALANCHE, Moves.SPLASH, Moves.GLAIVE_RUSH ]); }); it("takes double damage from attacks", async () => { @@ -67,7 +66,7 @@ describe("Moves - Glaive Rush", () => { it("interacts properly with multi-lens", async () => { game.override .startingHeldItems([{ name: "MULTI_LENS", count: 2 }]) - .enemyMoveset([Moves.AVALANCHE]); + .enemyMoveset([ Moves.AVALANCHE ]); await game.classicMode.startBattle(); const player = game.scene.getPlayerPokemon()!; @@ -88,7 +87,7 @@ describe("Moves - Glaive Rush", () => { }); it("secondary effects only last until next move", async () => { - game.override.enemyMoveset([Moves.SHADOW_SNEAK]); + game.override.enemyMoveset([ Moves.SHADOW_SNEAK ]); await game.classicMode.startBattle(); const player = game.scene.getPlayerPokemon()!; @@ -115,9 +114,9 @@ describe("Moves - Glaive Rush", () => { it("secondary effects are removed upon switching", async () => { game.override - .enemyMoveset([Moves.SHADOW_SNEAK]) + .enemyMoveset([ Moves.SHADOW_SNEAK ]) .starterSpecies(0); - await game.classicMode.startBattle([Species.KLINK, Species.FEEBAS]); + await game.classicMode.startBattle([ Species.KLINK, Species.FEEBAS ]); const player = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -138,7 +137,7 @@ describe("Moves - Glaive Rush", () => { }); it("secondary effects don't activate if move fails", async () => { - game.override.moveset([Moves.SHADOW_SNEAK, Moves.PROTECT, Moves.SPLASH, Moves.GLAIVE_RUSH]); + game.override.moveset([ Moves.SHADOW_SNEAK, Moves.PROTECT, Moves.SPLASH, Moves.GLAIVE_RUSH ]); await game.classicMode.startBattle(); const player = game.scene.getPlayerPokemon()!; @@ -152,7 +151,7 @@ describe("Moves - Glaive Rush", () => { game.move.select(Moves.SHADOW_SNEAK); await game.phaseInterceptor.to("TurnEndPhase"); - game.override.enemyMoveset([Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH ]); const damagedHP1 = 1000 - enemy.hp; enemy.hp = 1000; diff --git a/src/test/moves/guard_split.test.ts b/src/test/moves/guard_split.test.ts index 36be82ba5e4..519f347b920 100644 --- a/src/test/moves/guard_split.test.ts +++ b/src/test/moves/guard_split.test.ts @@ -55,7 +55,7 @@ describe("Moves - Guard Split", () => { }, 20000); it("should be idempotent", async () => { - game.override.enemyMoveset([Moves.GUARD_SPLIT]); + game.override.enemyMoveset([ Moves.GUARD_SPLIT ]); await game.startBattle([ Species.INDEEDEE ]); diff --git a/src/test/moves/hard_press.test.ts b/src/test/moves/hard_press.test.ts index 5d2e4e5b145..0fa4181491c 100644 --- a/src/test/moves/hard_press.test.ts +++ b/src/test/moves/hard_press.test.ts @@ -30,12 +30,12 @@ describe("Moves - Hard Press", () => { game.override.enemySpecies(Species.MUNCHLAX); game.override.enemyAbility(Abilities.BALL_FETCH); game.override.enemyMoveset(Moves.SPLASH); - game.override.moveset([Moves.HARD_PRESS]); + game.override.moveset([ Moves.HARD_PRESS ]); vi.spyOn(moveToCheck, "calculateBattlePower"); }); it("should return 100 power if target HP ratio is at 100%", async () => { - await game.startBattle([Species.PIKACHU]); + await game.startBattle([ Species.PIKACHU ]); game.move.select(Moves.HARD_PRESS); await game.phaseInterceptor.to(MoveEffectPhase); @@ -44,7 +44,7 @@ describe("Moves - Hard Press", () => { }); it("should return 50 power if target HP ratio is at 50%", async () => { - await game.startBattle([Species.PIKACHU]); + await game.startBattle([ Species.PIKACHU ]); const targetHpRatio = .5; const enemy = game.scene.getEnemyPokemon()!; @@ -57,7 +57,7 @@ describe("Moves - Hard Press", () => { }); it("should return 1 power if target HP ratio is at 1%", async () => { - await game.startBattle([Species.PIKACHU]); + await game.startBattle([ Species.PIKACHU ]); const targetHpRatio = .01; const enemy = game.scene.getEnemyPokemon()!; @@ -70,7 +70,7 @@ describe("Moves - Hard Press", () => { }); it("should return 1 power if target HP ratio is less than 1%", async () => { - await game.startBattle([Species.PIKACHU]); + await game.startBattle([ Species.PIKACHU ]); const targetHpRatio = .005; const enemy = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/haze.test.ts b/src/test/moves/haze.test.ts index e5474801899..30aab8bd98c 100644 --- a/src/test/moves/haze.test.ts +++ b/src/test/moves/haze.test.ts @@ -31,12 +31,12 @@ describe("Moves - Haze", () => { game.override.enemyAbility(Abilities.NONE); game.override.startingLevel(100); - game.override.moveset([Moves.HAZE, Moves.SWORDS_DANCE, Moves.CHARM, Moves.SPLASH]); + game.override.moveset([ Moves.HAZE, Moves.SWORDS_DANCE, Moves.CHARM, Moves.SPLASH ]); game.override.ability(Abilities.NONE); }); it("should reset all stat changes of all Pokemon on field", async () => { - await game.startBattle([Species.RATTATA]); + await game.startBattle([ Species.RATTATA ]); const user = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/heal_bell.test.ts b/src/test/moves/heal_bell.test.ts new file mode 100644 index 00000000000..e4a019d9c0e --- /dev/null +++ b/src/test/moves/heal_bell.test.ts @@ -0,0 +1,101 @@ +import { StatusEffect } from "#app/enums/status-effect"; +import { CommandPhase } from "#app/phases/command-phase"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Heal Bell", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.HEAL_BELL, Moves.SPLASH ]) + .statusEffect(StatusEffect.BURN) + .battleType("double") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should cure status effect of the user, its ally, and all party pokemon", async () => { + await game.classicMode.startBattle([ Species.RATTATA, Species.RATTATA, Species.RATTATA ]); + const [ leftPlayer, rightPlayer, partyPokemon ] = game.scene.getParty(); + + vi.spyOn(leftPlayer, "resetStatus"); + vi.spyOn(rightPlayer, "resetStatus"); + vi.spyOn(partyPokemon, "resetStatus"); + + game.move.select(Moves.HEAL_BELL, 0); + await game.phaseInterceptor.to(CommandPhase); + game.move.select(Moves.SPLASH, 1); + await game.toNextTurn(); + + expect(leftPlayer.resetStatus).toHaveBeenCalledOnce(); + expect(rightPlayer.resetStatus).toHaveBeenCalledOnce(); + expect(partyPokemon.resetStatus).toHaveBeenCalledOnce(); + + expect(leftPlayer.status?.effect).toBeUndefined(); + expect(rightPlayer.status?.effect).toBeUndefined(); + expect(partyPokemon.status?.effect).toBeUndefined(); + }); + + it("should not cure status effect of the target/target's allies", async () => { + game.override.enemyStatusEffect(StatusEffect.BURN); + await game.classicMode.startBattle([ Species.RATTATA, Species.RATTATA ]); + const [ leftOpp, rightOpp ] = game.scene.getEnemyField(); + + vi.spyOn(leftOpp, "resetStatus"); + vi.spyOn(rightOpp, "resetStatus"); + + game.move.select(Moves.HEAL_BELL, 0); + await game.phaseInterceptor.to(CommandPhase); + game.move.select(Moves.SPLASH, 1); + await game.toNextTurn(); + + expect(leftOpp.resetStatus).toHaveBeenCalledTimes(0); + expect(rightOpp.resetStatus).toHaveBeenCalledTimes(0); + + expect(leftOpp.status?.effect).toBeTruthy(); + expect(rightOpp.status?.effect).toBeTruthy(); + + expect(leftOpp.status?.effect).toBe(StatusEffect.BURN); + expect(rightOpp.status?.effect).toBe(StatusEffect.BURN); + }); + + it("should not cure status effect of allies ON FIELD with Soundproof, should still cure allies in party", async () => { + game.override.ability(Abilities.SOUNDPROOF); + await game.classicMode.startBattle([ Species.RATTATA, Species.RATTATA, Species.RATTATA ]); + const [ leftPlayer, rightPlayer, partyPokemon ] = game.scene.getParty(); + + vi.spyOn(leftPlayer, "resetStatus"); + vi.spyOn(rightPlayer, "resetStatus"); + vi.spyOn(partyPokemon, "resetStatus"); + + game.move.select(Moves.HEAL_BELL, 0); + await game.phaseInterceptor.to(CommandPhase); + game.move.select(Moves.SPLASH, 1); + await game.toNextTurn(); + + expect(leftPlayer.resetStatus).toHaveBeenCalledOnce(); + expect(rightPlayer.resetStatus).toHaveBeenCalledTimes(0); + expect(partyPokemon.resetStatus).toHaveBeenCalledOnce(); + + expect(leftPlayer.status?.effect).toBeUndefined(); + expect(rightPlayer.status?.effect).toBe(StatusEffect.BURN); + expect(partyPokemon.status?.effect).toBeUndefined(); + }); +}); diff --git a/src/test/moves/heal_block.test.ts b/src/test/moves/heal_block.test.ts index 14662ac3fce..252533215a8 100644 --- a/src/test/moves/heal_block.test.ts +++ b/src/test/moves/heal_block.test.ts @@ -28,7 +28,7 @@ describe("Moves - Heal Block", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.ABSORB, Moves.WISH, Moves.SPLASH, Moves.AQUA_RING]) + .moveset([ Moves.ABSORB, Moves.WISH, Moves.SPLASH, Moves.AQUA_RING ]) .enemyMoveset(Moves.HEAL_BLOCK) .ability(Abilities.NO_GUARD) .enemyAbility(Abilities.BALL_FETCH) @@ -38,7 +38,7 @@ describe("Moves - Heal Block", () => { it("shouldn't stop damage from HP-drain attacks, just HP restoration", async() => { - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const player = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -46,7 +46,7 @@ describe("Moves - Heal Block", () => { player.damageAndUpdate(enemy.getMaxHp() - 1); game.move.select(Moves.ABSORB); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); expect(player.hp).toBe(1); @@ -56,13 +56,13 @@ describe("Moves - Heal Block", () => { it("shouldn't stop Liquid Ooze from dealing damage", async() => { game.override.enemyAbility(Abilities.LIQUID_OOZE); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const player = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.ABSORB); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); expect(player.isFullHp()).toBe(false); @@ -70,7 +70,7 @@ describe("Moves - Heal Block", () => { }); it("should stop delayed heals, such as from Wish", async() => { - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const player = game.scene.getPlayerPokemon()!; @@ -91,7 +91,7 @@ describe("Moves - Heal Block", () => { it("should prevent Grassy Terrain from restoring HP", async() => { game.override.enemyAbility(Abilities.GRASSY_SURGE); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const player = game.scene.getPlayerPokemon()!; @@ -104,7 +104,7 @@ describe("Moves - Heal Block", () => { }); it("should prevent healing from heal-over-time moves", async() => { - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const player = game.scene.getPlayerPokemon()!; @@ -122,7 +122,7 @@ describe("Moves - Heal Block", () => { .weather(WeatherType.RAIN) .ability(Abilities.RAIN_DISH); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const player = game.scene.getPlayerPokemon()!; @@ -135,9 +135,9 @@ describe("Moves - Heal Block", () => { }); it("should stop healing from items", async() => { - game.override.startingHeldItems([{name: "LEFTOVERS"}]); + game.override.startingHeldItems([{ name: "LEFTOVERS" }]); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const player = game.scene.getPlayerPokemon()!; player.damageAndUpdate(player.getMaxHp() - 1); diff --git a/src/test/moves/hyper_beam.test.ts b/src/test/moves/hyper_beam.test.ts index a6a471569ed..af8440a0911 100644 --- a/src/test/moves/hyper_beam.test.ts +++ b/src/test/moves/hyper_beam.test.ts @@ -30,17 +30,17 @@ describe("Moves - Hyper Beam", () => { game.override.ability(Abilities.BALL_FETCH); game.override.enemySpecies(Species.SNORLAX); game.override.enemyAbility(Abilities.BALL_FETCH); - game.override.enemyMoveset([Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH ]); game.override.enemyLevel(100); - game.override.moveset([Moves.HYPER_BEAM, Moves.TACKLE]); + game.override.moveset([ Moves.HYPER_BEAM, Moves.TACKLE ]); vi.spyOn(allMoves[Moves.HYPER_BEAM], "accuracy", "get").mockReturnValue(100); }); it( "should force the user to recharge on the next turn (and only that turn)", async () => { - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/imprison.test.ts b/src/test/moves/imprison.test.ts index abb4b3cac6c..f10e20dab63 100644 --- a/src/test/moves/imprison.test.ts +++ b/src/test/moves/imprison.test.ts @@ -25,13 +25,13 @@ describe("Moves - Imprison", () => { game.override .battleType("single") .enemyAbility(Abilities.BALL_FETCH) - .enemyMoveset([Moves.IMPRISON, Moves.SPLASH, Moves.GROWL]) + .enemyMoveset([ Moves.IMPRISON, Moves.SPLASH, Moves.GROWL ]) .enemySpecies(Species.SHUCKLE) - .moveset([Moves.TRANSFORM, Moves.SPLASH]); + .moveset([ Moves.TRANSFORM, Moves.SPLASH ]); }); it("Pokemon under Imprison cannot use shared moves", async () => { - await game.classicMode.startBattle([Species.REGIELEKI]); + await game.classicMode.startBattle([ Species.REGIELEKI ]); const playerPokemon = game.scene.getPlayerPokemon()!; @@ -55,7 +55,7 @@ describe("Moves - Imprison", () => { }); it("Imprison applies to Pokemon switched into Battle", async () => { - await game.classicMode.startBattle([Species.REGIELEKI, Species.BULBASAUR]); + await game.classicMode.startBattle([ Species.REGIELEKI, Species.BULBASAUR ]); const playerPokemon1 = game.scene.getPlayerPokemon()!; @@ -78,8 +78,8 @@ describe("Moves - Imprison", () => { }); it("The effects of Imprison only end when the source is no longer active", async () => { - game.override.moveset([Moves.SPLASH, Moves.IMPRISON]); - await game.classicMode.startBattle([Species.REGIELEKI, Species.BULBASAUR]); + game.override.moveset([ Moves.SPLASH, Moves.IMPRISON ]); + await game.classicMode.startBattle([ Species.REGIELEKI, Species.BULBASAUR ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/jaw_lock.test.ts b/src/test/moves/jaw_lock.test.ts index 3398ec00b3b..30dbcac64a8 100644 --- a/src/test/moves/jaw_lock.test.ts +++ b/src/test/moves/jaw_lock.test.ts @@ -12,7 +12,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - Jaw Lock", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -35,7 +34,7 @@ describe("Moves - Jaw Lock", () => { .enemySpecies(Species.SNORLAX) .enemyAbility(Abilities.INSOMNIA) .enemyMoveset(Moves.SPLASH) - .moveset([Moves.JAW_LOCK, Moves.SPLASH]) + .moveset([ Moves.JAW_LOCK, Moves.SPLASH ]) .startingLevel(100) .enemyLevel(100) .disableCrits(); @@ -44,13 +43,13 @@ describe("Moves - Jaw Lock", () => { it( "should trap the move's user and target", async () => { - await game.startBattle([Species.BULBASAUR]); + await game.startBattle([ Species.BULBASAUR ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.JAW_LOCK); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); @@ -68,13 +67,13 @@ describe("Moves - Jaw Lock", () => { "should not trap either pokemon if the target faints", async () => { game.override.enemyLevel(1); - await game.startBattle([Species.BULBASAUR]); + await game.startBattle([ Species.BULBASAUR ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.JAW_LOCK); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase, false); @@ -96,13 +95,13 @@ describe("Moves - Jaw Lock", () => { it( "should only trap the user until the target faints", async () => { - await game.startBattle([Species.BULBASAUR]); + await game.startBattle([ Species.BULBASAUR ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.JAW_LOCK); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); @@ -122,14 +121,14 @@ describe("Moves - Jaw Lock", () => { async () => { game.override.battleType("double"); - await game.startBattle([Species.CHARMANDER, Species.BULBASAUR]); + await game.startBattle([ Species.CHARMANDER, Species.BULBASAUR ]); const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); game.move.select(Moves.JAW_LOCK, 0, BattlerIndex.ENEMY); game.move.select(Moves.SPLASH, 1); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to(MoveEffectPhase); @@ -152,9 +151,9 @@ describe("Moves - Jaw Lock", () => { it( "should not trap either pokemon if the target is protected", async () => { - game.override.enemyMoveset([Moves.PROTECT]); + game.override.enemyMoveset([ Moves.PROTECT ]); - await game.startBattle([Species.BULBASAUR]); + await game.startBattle([ Species.BULBASAUR ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/lash_out.test.ts b/src/test/moves/lash_out.test.ts index 7a8ab6c5bb6..014c0ae8fe5 100644 --- a/src/test/moves/lash_out.test.ts +++ b/src/test/moves/lash_out.test.ts @@ -8,7 +8,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; - describe("Moves - Lash Out", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,12 +29,12 @@ describe("Moves - Lash Out", () => { .disableCrits() .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.FUR_COAT) - .enemyMoveset([Moves.GROWL]) + .enemyMoveset([ Moves.GROWL ]) .startingLevel(10) .enemyLevel(10) .starterSpecies(Species.FEEBAS) .ability(Abilities.BALL_FETCH) - .moveset([Moves.LASH_OUT]); + .moveset([ Moves.LASH_OUT ]); }); @@ -44,7 +43,7 @@ describe("Moves - Lash Out", () => { await game.classicMode.startBattle(); game.move.select(Moves.LASH_OUT); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("BerryPhase"); expect(allMoves[Moves.LASH_OUT].calculateBattlePower).toHaveReturnedWith(150); diff --git a/src/test/moves/light_screen.test.ts b/src/test/moves/light_screen.test.ts index e94dc4a299e..af14d9273e6 100644 --- a/src/test/moves/light_screen.test.ts +++ b/src/test/moves/light_screen.test.ts @@ -32,16 +32,16 @@ describe("Moves - Light Screen", () => { game = new GameManager(phaserGame); game.override.battleType("single"); game.override.ability(Abilities.NONE); - game.override.moveset([Moves.ABSORB, Moves.DAZZLING_GLEAM, Moves.TACKLE]); + game.override.moveset([ Moves.ABSORB, Moves.DAZZLING_GLEAM, Moves.TACKLE ]); game.override.enemyLevel(100); game.override.enemySpecies(Species.MAGIKARP); - game.override.enemyMoveset([Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN]); + game.override.enemyMoveset([ Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN ]); game.override.disableCrits(); }); it("reduces damage of special attacks by half in a single battle", async () => { const moveToUse = Moves.ABSORB; - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); game.move.select(moveToUse); @@ -56,7 +56,7 @@ describe("Moves - Light Screen", () => { game.override.battleType("double"); const moveToUse = Moves.DAZZLING_GLEAM; - await game.startBattle([Species.SHUCKLE, Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]); game.move.select(moveToUse); game.move.select(moveToUse, 1); @@ -69,7 +69,7 @@ describe("Moves - Light Screen", () => { it("does not affect physical attacks", async () => { const moveToUse = Moves.TACKLE; - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); game.move.select(moveToUse); @@ -94,7 +94,7 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) = const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; if (defender.scene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side)) { - defender.scene.arena.applyTagsForSide(ArenaTagType.LIGHT_SCREEN, side, move.category, defender.scene.currentBattle.double, multiplierHolder); + defender.scene.arena.applyTagsForSide(ArenaTagType.LIGHT_SCREEN, side, false, attacker, move.category, multiplierHolder); } return move.power * multiplierHolder.value; diff --git a/src/test/moves/lucky_chant.test.ts b/src/test/moves/lucky_chant.test.ts index 77ea751aee1..02e9dd24465 100644 --- a/src/test/moves/lucky_chant.test.ts +++ b/src/test/moves/lucky_chant.test.ts @@ -8,7 +8,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import GameManager from "../utils/gameManager"; - describe("Moves - Lucky Chant", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -28,10 +27,10 @@ describe("Moves - Lucky Chant", () => { game.override .battleType("single") - .moveset([Moves.LUCKY_CHANT, Moves.SPLASH, Moves.FOLLOW_ME]) + .moveset([ Moves.LUCKY_CHANT, Moves.SPLASH, Moves.FOLLOW_ME ]) .enemySpecies(Species.SNORLAX) .enemyAbility(Abilities.INSOMNIA) - .enemyMoveset([Moves.FLOWER_TRICK]) + .enemyMoveset([ Moves.FLOWER_TRICK ]) .startingLevel(100) .enemyLevel(100); }); @@ -39,7 +38,7 @@ describe("Moves - Lucky Chant", () => { it( "should prevent critical hits from moves", async () => { - await game.startBattle([Species.CHARIZARD]); + await game.startBattle([ Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerPokemon()!; @@ -63,7 +62,7 @@ describe("Moves - Lucky Chant", () => { async () => { game.override.battleType("double"); - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerField(); @@ -87,9 +86,9 @@ describe("Moves - Lucky Chant", () => { it( "should prevent critical hits from field effects", async () => { - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); - await game.startBattle([Species.CHARIZARD]); + await game.startBattle([ Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/lunar_blessing.test.ts b/src/test/moves/lunar_blessing.test.ts index 6a104762f4d..52c41a30e11 100644 --- a/src/test/moves/lunar_blessing.test.ts +++ b/src/test/moves/lunar_blessing.test.ts @@ -28,13 +28,13 @@ describe("Moves - Lunar Blessing", () => { game.override.enemyMoveset(Moves.SPLASH); game.override.enemyAbility(Abilities.BALL_FETCH); - game.override.moveset([Moves.LUNAR_BLESSING, Moves.SPLASH]); + game.override.moveset([ Moves.LUNAR_BLESSING, Moves.SPLASH ]); game.override.ability(Abilities.BALL_FETCH); }); it("should restore 25% HP of the user and its ally", async () => { - await game.startBattle([Species.RATTATA, Species.RATTATA]); - const [leftPlayer, rightPlayer] = game.scene.getPlayerField(); + await game.startBattle([ Species.RATTATA, Species.RATTATA ]); + const [ leftPlayer, rightPlayer ] = game.scene.getPlayerField(); vi.spyOn(leftPlayer, "getMaxHp").mockReturnValue(100); vi.spyOn(rightPlayer, "getMaxHp").mockReturnValue(100); @@ -62,8 +62,8 @@ describe("Moves - Lunar Blessing", () => { it("should cure status effect of the user and its ally", async () => { game.override.statusEffect(StatusEffect.BURN); - await game.startBattle([Species.RATTATA, Species.RATTATA]); - const [leftPlayer, rightPlayer] = game.scene.getPlayerField(); + await game.startBattle([ Species.RATTATA, Species.RATTATA ]); + const [ leftPlayer, rightPlayer ] = game.scene.getPlayerField(); vi.spyOn(leftPlayer, "resetStatus"); vi.spyOn(rightPlayer, "resetStatus"); diff --git a/src/test/moves/magnet_rise.test.ts b/src/test/moves/magnet_rise.test.ts index 9037e377090..0afcad67ea3 100644 --- a/src/test/moves/magnet_rise.test.ts +++ b/src/test/moves/magnet_rise.test.ts @@ -26,10 +26,10 @@ describe("Moves - Magnet Rise", () => { game.override.battleType("single"); game.override.starterSpecies(Species.MAGNEZONE); game.override.enemySpecies(Species.RATTATA); - game.override.enemyMoveset([Moves.DRILL_RUN, Moves.DRILL_RUN, Moves.DRILL_RUN, Moves.DRILL_RUN]); + game.override.enemyMoveset([ Moves.DRILL_RUN, Moves.DRILL_RUN, Moves.DRILL_RUN, Moves.DRILL_RUN ]); game.override.disableCrits(); game.override.enemyLevel(1); - game.override.moveset([moveToUse, Moves.SPLASH, Moves.GRAVITY, Moves.BATON_PASS]); + game.override.moveset([ moveToUse, Moves.SPLASH, Moves.GRAVITY, Moves.BATON_PASS ]); }); it("MAGNET RISE", async () => { diff --git a/src/test/moves/make_it_rain.test.ts b/src/test/moves/make_it_rain.test.ts index 2b28a958ff0..08021227e9c 100644 --- a/src/test/moves/make_it_rain.test.ts +++ b/src/test/moves/make_it_rain.test.ts @@ -9,7 +9,6 @@ import { MoveEndPhase } from "#app/phases/move-end-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; - describe("Moves - Make It Rain", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -27,7 +26,7 @@ describe("Moves - Make It Rain", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("double"); - game.override.moveset([Moves.MAKE_IT_RAIN, Moves.SPLASH]); + game.override.moveset([ Moves.MAKE_IT_RAIN, Moves.SPLASH ]); game.override.enemySpecies(Species.SNORLAX); game.override.enemyAbility(Abilities.INSOMNIA); game.override.enemyMoveset(Moves.SPLASH); @@ -36,7 +35,7 @@ describe("Moves - Make It Rain", () => { }); it("should only lower SPATK stat stage by 1 once in a double battle", async () => { - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerPokemon()!; @@ -52,7 +51,7 @@ describe("Moves - Make It Rain", () => { game.override.enemyLevel(1); // ensures the enemy will faint game.override.battleType("single"); - await game.startBattle([Species.CHARIZARD]); + await game.startBattle([ Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -68,7 +67,7 @@ describe("Moves - Make It Rain", () => { it("should reduce Sp. Atk. once after KOing two enemies", async () => { game.override.enemyLevel(1); // ensures the enemy will faint - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyField(); @@ -83,7 +82,7 @@ describe("Moves - Make It Rain", () => { }); it("should lower SPATK stat stage by 1 if it only hits the second target", async () => { - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/mat_block.test.ts b/src/test/moves/mat_block.test.ts index 0746f9bcfa9..a4d9177cbdc 100644 --- a/src/test/moves/mat_block.test.ts +++ b/src/test/moves/mat_block.test.ts @@ -10,7 +10,6 @@ import { CommandPhase } from "#app/phases/command-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase"; - describe("Moves - Mat Block", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,10 +29,10 @@ describe("Moves - Mat Block", () => { game.override.battleType("double"); - game.override.moveset([Moves.MAT_BLOCK, Moves.SPLASH]); + game.override.moveset([ Moves.MAT_BLOCK, Moves.SPLASH ]); game.override.enemySpecies(Species.SNORLAX); - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); game.override.enemyAbility(Abilities.INSOMNIA); game.override.startingLevel(100); @@ -43,7 +42,7 @@ describe("Moves - Mat Block", () => { test( "should protect the user and allies from attack moves", async () => { - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); @@ -62,9 +61,9 @@ describe("Moves - Mat Block", () => { test( "should not protect the user and allies from status moves", async () => { - game.override.enemyMoveset([Moves.GROWL]); + game.override.enemyMoveset([ Moves.GROWL ]); - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); @@ -83,7 +82,7 @@ describe("Moves - Mat Block", () => { test( "should fail when used after the first turn", async () => { - await game.startBattle([Species.BLASTOISE, Species.CHARIZARD]); + await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerField(); diff --git a/src/test/moves/metal_burst.test.ts b/src/test/moves/metal_burst.test.ts new file mode 100644 index 00000000000..3b32dd322a3 --- /dev/null +++ b/src/test/moves/metal_burst.test.ts @@ -0,0 +1,80 @@ +import { BattlerIndex } from "#app/battle"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Metal Burst", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.METAL_BURST, Moves.FISSURE, Moves.PRECIPICE_BLADES ]) + .ability(Abilities.PURE_POWER) + .startingLevel(10) + .battleType("double") + .disableCrits() + .enemySpecies(Species.PICHU) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.TACKLE); + }); + + it("should redirect target if intended target faints", async () => { + await game.classicMode.startBattle([ Species.FEEBAS, Species.FEEBAS ]); + + const [ , enemy2 ] = game.scene.getEnemyField(); + + game.move.select(Moves.METAL_BURST); + game.move.select(Moves.FISSURE, 1, BattlerIndex.ENEMY); + + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2); + + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to("MoveEndPhase"); + await game.move.forceHit(); + await game.phaseInterceptor.to("MoveEndPhase"); + await game.phaseInterceptor.to("MoveEndPhase"); + + expect(enemy2.isFullHp()).toBe(false); + }); + + it("should not crash if both opponents faint before the move is used", async () => { + await game.classicMode.startBattle([ Species.FEEBAS, Species.ARCEUS ]); + + const [ enemy1, enemy2 ] = game.scene.getEnemyField(); + + game.move.select(Moves.METAL_BURST); + game.move.select(Moves.PRECIPICE_BLADES, 1); + + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); + await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2); + + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to("MoveEndPhase"); + await game.move.forceHit(); + await game.phaseInterceptor.to("MoveEndPhase"); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy1.isFainted()).toBe(true); + expect(enemy2.isFainted()).toBe(true); + expect(game.scene.getPlayerField()[0].getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + }); +}); diff --git a/src/test/moves/miracle_eye.test.ts b/src/test/moves/miracle_eye.test.ts index 0528b509c82..70f487de942 100644 --- a/src/test/moves/miracle_eye.test.ts +++ b/src/test/moves/miracle_eye.test.ts @@ -28,7 +28,7 @@ describe("Moves - Miracle Eye", () => { .enemyMoveset(Moves.SPLASH) .enemyLevel(5) .starterSpecies(Species.MAGIKARP) - .moveset([Moves.MIRACLE_EYE, Moves.CONFUSION]); + .moveset([ Moves.MIRACLE_EYE, Moves.CONFUSION ]); }); it("should allow Psychic moves to hit Dark types", async () => { @@ -43,7 +43,7 @@ describe("Moves - Miracle Eye", () => { game.move.select(Moves.MIRACLE_EYE); await game.toNextTurn(); game.move.select(Moves.CONFUSION); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); diff --git a/src/test/moves/mist.test.ts b/src/test/moves/mist.test.ts new file mode 100644 index 00000000000..cd338f79412 --- /dev/null +++ b/src/test/moves/mist.test.ts @@ -0,0 +1,49 @@ +import { Stat } from "#enums/stat"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Mist", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.MIST, Moves.SPLASH ]) + .ability(Abilities.BALL_FETCH) + .battleType("double") + .disableCrits() + .enemySpecies(Species.SNORLAX) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.GROWL); + }); + + it("should prevent the user's side from having stats lowered", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); + + const playerPokemon = game.scene.getPlayerField(); + + game.move.select(Moves.MIST, 0); + game.move.select(Moves.SPLASH, 1); + + await game.phaseInterceptor.to("BerryPhase"); + + playerPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(0)); + }); + + it.todo("should be ignored by opponents with Infiltrator"); +}); diff --git a/src/test/moves/multi_target.test.ts b/src/test/moves/multi_target.test.ts index cd69482bd8e..b6836b1dcb9 100644 --- a/src/test/moves/multi_target.test.ts +++ b/src/test/moves/multi_target.test.ts @@ -8,7 +8,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Multi-target damage reduction", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -33,18 +32,18 @@ describe("Multi-target damage reduction", () => { .enemySpecies(Species.POLIWAG) .enemyMoveset(Moves.SPLASH) .enemyAbility(Abilities.BALL_FETCH) - .moveset([Moves.TACKLE, Moves.DAZZLING_GLEAM, Moves.EARTHQUAKE, Moves.SPLASH]) + .moveset([ Moves.TACKLE, Moves.DAZZLING_GLEAM, Moves.EARTHQUAKE, Moves.SPLASH ]) .ability(Abilities.BALL_FETCH); }); it("should reduce d.gleam damage when multiple enemies but not tackle", async () => { - await game.startBattle([Species.MAGIKARP, Species.FEEBAS]); + await game.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); - const [enemy1, enemy2] = game.scene.getEnemyField(); + const [ enemy1, enemy2 ] = game.scene.getEnemyField(); game.move.select(Moves.DAZZLING_GLEAM); game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("MoveEndPhase"); const gleam1 = enemy1.getMaxHp() - enemy1.hp; @@ -60,7 +59,7 @@ describe("Multi-target damage reduction", () => { game.move.select(Moves.DAZZLING_GLEAM); game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); @@ -78,14 +77,14 @@ describe("Multi-target damage reduction", () => { }); it("should reduce earthquake when more than one pokemon other than user is not fainted", async () => { - await game.startBattle([Species.MAGIKARP, Species.FEEBAS]); + await game.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); const player2 = game.scene.getParty()[1]; - const [enemy1, enemy2] = game.scene.getEnemyField(); + const [ enemy1, enemy2 ] = game.scene.getEnemyField(); game.move.select(Moves.EARTHQUAKE); game.move.select(Moves.SPLASH, 1); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("MoveEndPhase"); @@ -100,7 +99,7 @@ describe("Multi-target damage reduction", () => { game.move.select(Moves.EARTHQUAKE); game.move.select(Moves.SPLASH, 1); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); @@ -118,7 +117,7 @@ describe("Multi-target damage reduction", () => { await game.toNextTurn(); game.move.select(Moves.EARTHQUAKE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); diff --git a/src/test/moves/nightmare.test.ts b/src/test/moves/nightmare.test.ts new file mode 100644 index 00000000000..f4c485ff1b4 --- /dev/null +++ b/src/test/moves/nightmare.test.ts @@ -0,0 +1,52 @@ +import { StatusEffect } from "#app/data/status-effect"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Nightmare", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override.battleType("single") + .enemySpecies(Species.RATTATA) + .enemyMoveset(Moves.SPLASH) + .enemyAbility(Abilities.BALL_FETCH) + .enemyStatusEffect(StatusEffect.SLEEP) + .startingLevel(5) + .moveset([ Moves.NIGHTMARE, Moves.SPLASH ]); + }); + + it("lowers enemy hp by 1/4 each turn while asleep", async () => { + await game.classicMode.startBattle([ Species.HYPNO ]); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + const enemyMaxHP = enemyPokemon.hp; + + game.move.select(Moves.NIGHTMARE); + await game.toNextTurn(); + + expect(enemyPokemon.hp).toBe(enemyMaxHP - Math.floor(enemyMaxHP / 4)); + + // take a second turn to make sure damage occurs again + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(enemyPokemon.hp).toBe(enemyMaxHP - Math.floor(enemyMaxHP / 4) - Math.floor(enemyMaxHP / 4)); + }); +}); diff --git a/src/test/moves/obstruct.test.ts b/src/test/moves/obstruct.test.ts index 43706a5a1d6..1649c199e32 100644 --- a/src/test/moves/obstruct.test.ts +++ b/src/test/moves/obstruct.test.ts @@ -1,6 +1,7 @@ -import { Moves } from "#app/enums/moves"; -import { Stat } from "#app/enums/stat"; import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -22,13 +23,15 @@ describe("Moves - Obstruct", () => { game = new GameManager(phaserGame); game.override .battleType("single") + .enemySpecies(Species.MAGIKARP) + .enemyMoveset(Moves.TACKLE) .enemyAbility(Abilities.BALL_FETCH) .ability(Abilities.BALL_FETCH) - .moveset([Moves.OBSTRUCT]); + .moveset([ Moves.OBSTRUCT ]) + .starterSpecies(Species.FEEBAS); }); it("protects from contact damaging moves and lowers the opponent's defense by 2 stages", async () => { - game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH)); await game.classicMode.startBattle(); game.move.select(Moves.OBSTRUCT); @@ -42,7 +45,6 @@ describe("Moves - Obstruct", () => { }); it("bypasses accuracy checks when applying protection and defense reduction", async () => { - game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH)); await game.classicMode.startBattle(); game.move.select(Moves.OBSTRUCT); @@ -59,7 +61,7 @@ describe("Moves - Obstruct", () => { ); it("protects from non-contact damaging moves and doesn't lower the opponent's defense by 2 stages", async () => { - game.override.enemyMoveset(Array(4).fill(Moves.WATER_GUN)); + game.override.enemyMoveset(Moves.WATER_GUN); await game.classicMode.startBattle(); game.move.select(Moves.OBSTRUCT); @@ -73,7 +75,7 @@ describe("Moves - Obstruct", () => { }); it("doesn't protect from status moves", async () => { - game.override.enemyMoveset(Array(4).fill(Moves.GROWL)); + game.override.enemyMoveset(Moves.GROWL); await game.classicMode.startBattle(); game.move.select(Moves.OBSTRUCT); @@ -83,4 +85,14 @@ describe("Moves - Obstruct", () => { expect(player.getStatStage(Stat.ATK)).toBe(-1); }); + + it("doesn't reduce the stats of an opponent with Clear Body/etc", async () => { + game.override.enemyAbility(Abilities.CLEAR_BODY); + await game.classicMode.startBattle(); + + game.move.select(Moves.OBSTRUCT); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.DEF)).toBe(0); + }); }); diff --git a/src/test/moves/parting_shot.test.ts b/src/test/moves/parting_shot.test.ts index fa328e15a32..e5a2fc38b94 100644 --- a/src/test/moves/parting_shot.test.ts +++ b/src/test/moves/parting_shot.test.ts @@ -11,7 +11,6 @@ import { MessagePhase } from "#app/phases/message-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase"; - describe("Moves - Parting Shot", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -29,7 +28,7 @@ describe("Moves - Parting Shot", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("single"); - game.override.moveset([Moves.PARTING_SHOT, Moves.SPLASH]); + game.override.moveset([ Moves.PARTING_SHOT, Moves.SPLASH ]); game.override.enemyMoveset(Moves.SPLASH); game.override.startingLevel(5); game.override.enemyLevel(5); @@ -42,7 +41,7 @@ describe("Moves - Parting Shot", () => { game.override .enemySpecies(Species.POOCHYENA) .ability(Abilities.PRANKSTER); - await game.startBattle([Species.MURKROW, Species.MEOWTH]); + await game.startBattle([ Species.MURKROW, Species.MEOWTH ]); const enemyPokemon = game.scene.getEnemyPokemon()!; expect(enemyPokemon).toBeDefined(); @@ -62,7 +61,7 @@ describe("Moves - Parting Shot", () => { game.override .enemySpecies(Species.GHOLDENGO) .enemyAbility(Abilities.GOOD_AS_GOLD); - await game.startBattle([Species.MURKROW, Species.MEOWTH]); + await game.startBattle([ Species.MURKROW, Species.MEOWTH ]); const enemyPokemon = game.scene.getEnemyPokemon()!; expect(enemyPokemon).toBeDefined(); @@ -79,8 +78,8 @@ describe("Moves - Parting Shot", () => { it.skip( // TODO: fix this bug to pass the test! "Parting shot should fail if target is -6/-6 de-buffed", async () => { - game.override.moveset([Moves.PARTING_SHOT, Moves.MEMENTO, Moves.SPLASH]); - await game.startBattle([Species.MEOWTH, Species.MEOWTH, Species.MEOWTH, Species.MURKROW, Species.ABRA]); + game.override.moveset([ Moves.PARTING_SHOT, Moves.MEMENTO, Moves.SPLASH ]); + await game.startBattle([ Species.MEOWTH, Species.MEOWTH, Species.MEOWTH, Species.MURKROW, Species.ABRA ]); // use Memento 3 times to debuff enemy game.move.select(Moves.MEMENTO); @@ -124,8 +123,8 @@ describe("Moves - Parting Shot", () => { game.override .enemySpecies(Species.ALTARIA) .enemyAbility(Abilities.NONE) - .enemyMoveset([Moves.MIST]); - await game.startBattle([Species.SNORLAX, Species.MEOWTH]); + .enemyMoveset([ Moves.MIST ]); + await game.startBattle([ Species.SNORLAX, Species.MEOWTH ]); const enemyPokemon = game.scene.getEnemyPokemon()!; expect(enemyPokemon).toBeDefined(); @@ -145,7 +144,7 @@ describe("Moves - Parting Shot", () => { game.override .enemySpecies(Species.TENTACOOL) .enemyAbility(Abilities.CLEAR_BODY); - await game.startBattle([Species.SNORLAX, Species.MEOWTH]); + await game.startBattle([ Species.SNORLAX, Species.MEOWTH ]); const enemyPokemon = game.scene.getEnemyPokemon()!; expect(enemyPokemon).toBeDefined(); @@ -162,7 +161,7 @@ describe("Moves - Parting Shot", () => { it.skip( // TODO: fix this bug to pass the test! "Parting shot should de-buff and not fail if no party available to switch - party size 1", async () => { - await game.startBattle([Species.MURKROW]); + await game.startBattle([ Species.MURKROW ]); const enemyPokemon = game.scene.getEnemyPokemon()!; expect(enemyPokemon).toBeDefined(); @@ -179,7 +178,7 @@ describe("Moves - Parting Shot", () => { it.skip( // TODO: fix this bug to pass the test! "Parting shot regularly not fail if no party available to switch - party fainted", async () => { - await game.startBattle([Species.MURKROW, Species.MEOWTH]); + await game.startBattle([ Species.MURKROW, Species.MEOWTH ]); game.move.select(Moves.SPLASH); // intentionally kill party pokemon, switch to second slot (now 1 party mon is fainted) diff --git a/src/test/moves/plasma_fists.test.ts b/src/test/moves/plasma_fists.test.ts index a9bd7660dfd..24210cd47fa 100644 --- a/src/test/moves/plasma_fists.test.ts +++ b/src/test/moves/plasma_fists.test.ts @@ -24,7 +24,7 @@ describe("Moves - Plasma Fists", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.PLASMA_FISTS, Moves.TACKLE]) + .moveset([ Moves.PLASMA_FISTS, Moves.TACKLE ]) .battleType("double") .startingLevel(100) .enemySpecies(Species.DUSCLOPS) @@ -34,7 +34,7 @@ describe("Moves - Plasma Fists", () => { }); it("should convert all subsequent Normal-type attacks to Electric-type", async () => { - await game.classicMode.startBattle([Species.DUSCLOPS, Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.DUSCLOPS, Species.BLASTOISE ]); const field = game.scene.getField(true); field.forEach(p => vi.spyOn(p, "getMoveType")); @@ -45,7 +45,7 @@ describe("Moves - Plasma Fists", () => { await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); await game.forceEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("BerryPhase", false); @@ -60,7 +60,7 @@ describe("Moves - Plasma Fists", () => { .battleType("single") .enemyAbility(Abilities.PIXILATE); - await game.classicMode.startBattle([Species.ONIX]); + await game.classicMode.startBattle([ Species.ONIX ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -68,7 +68,7 @@ describe("Moves - Plasma Fists", () => { game.move.select(Moves.PLASMA_FISTS); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("BerryPhase", false); expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.FAIRY); @@ -81,7 +81,7 @@ describe("Moves - Plasma Fists", () => { .enemyAbility(Abilities.NORMALIZE) .enemyMoveset(Moves.WATER_GUN); - await game.classicMode.startBattle([Species.DUSCLOPS]); + await game.classicMode.startBattle([ Species.DUSCLOPS ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -89,7 +89,7 @@ describe("Moves - Plasma Fists", () => { game.move.select(Moves.PLASMA_FISTS); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("BerryPhase", false); expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); diff --git a/src/test/moves/pledge_moves.test.ts b/src/test/moves/pledge_moves.test.ts new file mode 100644 index 00000000000..93fcf57cc60 --- /dev/null +++ b/src/test/moves/pledge_moves.test.ts @@ -0,0 +1,337 @@ +import { BattlerIndex } from "#app/battle"; +import { allAbilities } from "#app/data/ability"; +import { ArenaTagSide } from "#app/data/arena-tag"; +import { allMoves, FlinchAttr } from "#app/data/move"; +import { Type } from "#app/data/type"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { Stat } from "#enums/stat"; +import { toDmgValue } from "#app/utils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Pledge Moves", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleType("double") + .startingLevel(100) + .moveset([ Moves.FIRE_PLEDGE, Moves.GRASS_PLEDGE, Moves.WATER_PLEDGE, Moves.SPLASH ]) + .enemySpecies(Species.SNORLAX) + .enemyLevel(100) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it( + "Fire Pledge - should be an 80-power Fire-type attack outside of combination", + async () => { + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); + + const firePledge = allMoves[Moves.FIRE_PLEDGE]; + vi.spyOn(firePledge, "calculateBattlePower"); + + const playerPokemon = game.scene.getPlayerField(); + vi.spyOn(playerPokemon[0], "getMoveType"); + + game.move.select(Moves.FIRE_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.SPLASH, 1); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + await game.phaseInterceptor.to("MoveEndPhase", false); + + expect(firePledge.calculateBattlePower).toHaveLastReturnedWith(80); + expect(playerPokemon[0].getMoveType).toHaveLastReturnedWith(Type.FIRE); + } + ); + + it( + "Fire Pledge - should not combine with an ally using Fire Pledge", + async () => { + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); + + const firePledge = allMoves[Moves.FIRE_PLEDGE]; + vi.spyOn(firePledge, "calculateBattlePower"); + + const playerPokemon = game.scene.getPlayerField(); + playerPokemon.forEach(p => vi.spyOn(p, "getMoveType")); + + const enemyPokemon = game.scene.getEnemyField(); + + game.move.select(Moves.FIRE_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.FIRE_PLEDGE, 0, BattlerIndex.ENEMY_2); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to("MoveEndPhase"); + expect(firePledge.calculateBattlePower).toHaveLastReturnedWith(80); + expect(playerPokemon[0].getMoveType).toHaveLastReturnedWith(Type.FIRE); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(firePledge.calculateBattlePower).toHaveLastReturnedWith(80); + expect(playerPokemon[1].getMoveType).toHaveLastReturnedWith(Type.FIRE); + + enemyPokemon.forEach(p => expect(p.hp).toBeLessThan(p.getMaxHp())); + } + ); + + it( + "Fire Pledge - should not combine with an enemy's Pledge move", + async () => { + game.override + .battleType("single") + .enemyMoveset(Moves.GRASS_PLEDGE); + + await game.classicMode.startBattle([ Species.CHARIZARD ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.FIRE_PLEDGE); + + await game.toNextTurn(); + + // Neither Pokemon should defer their move's effects as they would + // if they combined moves, so both should be damaged. + expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(game.scene.arena.getTag(ArenaTagType.FIRE_GRASS_PLEDGE)).toBeUndefined(); + } + ); + + it( + "Grass Pledge - should combine with Fire Pledge to form a 150-power Fire-type attack that creates a 'sea of fire'", + async () => { + await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); + + const grassPledge = allMoves[Moves.GRASS_PLEDGE]; + vi.spyOn(grassPledge, "calculateBattlePower"); + + const playerPokemon = game.scene.getPlayerField(); + const enemyPokemon = game.scene.getEnemyField(); + + vi.spyOn(playerPokemon[1], "getMoveType"); + const baseDmgMock = vi.spyOn(enemyPokemon[0], "getBaseDamage"); + + game.move.select(Moves.FIRE_PLEDGE, 0, BattlerIndex.ENEMY_2); + game.move.select(Moves.GRASS_PLEDGE, 1, BattlerIndex.ENEMY); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + // advance to the end of PLAYER_2's move this turn + for (let i = 0; i < 2; i++) { + await game.phaseInterceptor.to("MoveEndPhase"); + } + expect(playerPokemon[1].getMoveType).toHaveLastReturnedWith(Type.FIRE); + expect(grassPledge.calculateBattlePower).toHaveLastReturnedWith(150); + + const baseDmg = baseDmgMock.mock.results[baseDmgMock.mock.results.length - 1].value; + expect(enemyPokemon[0].getMaxHp() - enemyPokemon[0].hp).toBe(toDmgValue(baseDmg * 1.5)); + expect(enemyPokemon[1].hp).toBe(enemyPokemon[1].getMaxHp()); // PLAYER should not have attacked + expect(game.scene.arena.getTagOnSide(ArenaTagType.FIRE_GRASS_PLEDGE, ArenaTagSide.ENEMY)).toBeDefined(); + + const enemyStartingHp = enemyPokemon.map(p => p.hp); + await game.toNextTurn(); + enemyPokemon.forEach((p, i) => expect(enemyStartingHp[i] - p.hp).toBe(toDmgValue(p.getMaxHp() / 8))); + } + ); + + it( + "Fire Pledge - should combine with Water Pledge to form a 150-power Water-type attack that creates a 'rainbow'", + async () => { + game.override.moveset([ Moves.FIRE_PLEDGE, Moves.WATER_PLEDGE, Moves.FIERY_DANCE, Moves.SPLASH ]); + + await game.classicMode.startBattle([ Species.BLASTOISE, Species.VENUSAUR ]); + + const firePledge = allMoves[Moves.FIRE_PLEDGE]; + vi.spyOn(firePledge, "calculateBattlePower"); + + const playerPokemon = game.scene.getPlayerField(); + const enemyPokemon = game.scene.getEnemyField(); + + vi.spyOn(playerPokemon[1], "getMoveType"); + + game.move.select(Moves.WATER_PLEDGE, 0, BattlerIndex.ENEMY_2); + game.move.select(Moves.FIRE_PLEDGE, 1, BattlerIndex.ENEMY); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + // advance to the end of PLAYER_2's move this turn + for (let i = 0; i < 2; i++) { + await game.phaseInterceptor.to("MoveEndPhase"); + } + expect(playerPokemon[1].getMoveType).toHaveLastReturnedWith(Type.WATER); + expect(firePledge.calculateBattlePower).toHaveLastReturnedWith(150); + expect(enemyPokemon[1].hp).toBe(enemyPokemon[1].getMaxHp()); // PLAYER should not have attacked + expect(game.scene.arena.getTagOnSide(ArenaTagType.WATER_FIRE_PLEDGE, ArenaTagSide.PLAYER)).toBeDefined(); + + await game.toNextTurn(); + + game.move.select(Moves.FIERY_DANCE, 0, BattlerIndex.ENEMY_2); + game.move.select(Moves.SPLASH, 1); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + await game.phaseInterceptor.to("MoveEndPhase"); + + // Rainbow effect should increase Fiery Dance's chance of raising Sp. Atk to 100% + expect(playerPokemon[0].getStatStage(Stat.SPATK)).toBe(1); + } + ); + + it( + "Water Pledge - should combine with Grass Pledge to form a 150-power Grass-type attack that creates a 'swamp'", + async () => { + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); + + const waterPledge = allMoves[Moves.WATER_PLEDGE]; + vi.spyOn(waterPledge, "calculateBattlePower"); + + const playerPokemon = game.scene.getPlayerField(); + const enemyPokemon = game.scene.getEnemyField(); + const enemyStartingSpd = enemyPokemon.map(p => p.getEffectiveStat(Stat.SPD)); + + vi.spyOn(playerPokemon[1], "getMoveType"); + + game.move.select(Moves.GRASS_PLEDGE, 0, BattlerIndex.ENEMY_2); + game.move.select(Moves.WATER_PLEDGE, 1, BattlerIndex.ENEMY); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + // advance to the end of PLAYER_2's move this turn + for (let i = 0; i < 2; i++) { + await game.phaseInterceptor.to("MoveEndPhase"); + } + + expect(playerPokemon[1].getMoveType).toHaveLastReturnedWith(Type.GRASS); + expect(waterPledge.calculateBattlePower).toHaveLastReturnedWith(150); + expect(enemyPokemon[1].hp).toBe(enemyPokemon[1].getMaxHp()); + + expect(game.scene.arena.getTagOnSide(ArenaTagType.GRASS_WATER_PLEDGE, ArenaTagSide.ENEMY)).toBeDefined(); + enemyPokemon.forEach((p, i) => expect(p.getEffectiveStat(Stat.SPD)).toBe(Math.floor(enemyStartingSpd[i] / 4))); + } + ); + + it( + "Pledge Moves - should alter turn order when used in combination", + async () => { + await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); + + const enemyPokemon = game.scene.getEnemyField(); + + game.move.select(Moves.WATER_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.FIRE_PLEDGE, 1, BattlerIndex.ENEMY_2); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2 ]); + // PLAYER_2 should act with a combined move immediately after PLAYER as the second move in the turn + for (let i = 0; i < 2; i++) { + await game.phaseInterceptor.to("MoveEndPhase"); + } + expect(enemyPokemon[0].hp).toBe(enemyPokemon[0].getMaxHp()); + expect(enemyPokemon[1].hp).toBeLessThan(enemyPokemon[1].getMaxHp()); + } + ); + + it( + "Pledge Moves - 'rainbow' effect should not stack with Serene Grace when applied to flinching moves", + async () => { + game.override + .ability(Abilities.SERENE_GRACE) + .moveset([ Moves.FIRE_PLEDGE, Moves.WATER_PLEDGE, Moves.IRON_HEAD, Moves.SPLASH ]); + + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); + + const ironHeadFlinchAttr = allMoves[Moves.IRON_HEAD].getAttrs(FlinchAttr)[0]; + vi.spyOn(ironHeadFlinchAttr, "getMoveChance"); + + game.move.select(Moves.WATER_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.FIRE_PLEDGE, 1, BattlerIndex.ENEMY_2); + + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.scene.arena.getTagOnSide(ArenaTagType.WATER_FIRE_PLEDGE, ArenaTagSide.PLAYER)).toBeDefined(); + + game.move.select(Moves.IRON_HEAD, 0, BattlerIndex.ENEMY); + game.move.select(Moves.SPLASH, 1); + + await game.phaseInterceptor.to("BerryPhase", false); + + expect(ironHeadFlinchAttr.getMoveChance).toHaveLastReturnedWith(60); + } + ); + + it( + "Pledge Moves - should have no effect when the second ally's move is cancelled", + async () => { + game.override + .enemyMoveset([ Moves.SPLASH, Moves.SPORE ]); + + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); + + const enemyPokemon = game.scene.getEnemyField(); + + game.move.select(Moves.FIRE_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.GRASS_PLEDGE, 1, BattlerIndex.ENEMY_2); + + await game.forceEnemyMove(Moves.SPORE, BattlerIndex.PLAYER_2); + await game.forceEnemyMove(Moves.SPLASH); + + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to("BerryPhase", false); + + enemyPokemon.forEach((p) => expect(p.hp).toBe(p.getMaxHp())); + } + ); + + it( + "Pledge Moves - should ignore redirection from another Pokemon's Storm Drain", + async () => { + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); + + const enemyPokemon = game.scene.getEnemyField(); + vi.spyOn(enemyPokemon[1], "getAbility").mockReturnValue(allAbilities[Abilities.STORM_DRAIN]); + + game.move.select(Moves.WATER_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.SPLASH, 1); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to("MoveEndPhase", false); + + expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp()); + expect(enemyPokemon[1].getStatStage(Stat.SPATK)).toBe(0); + } + ); + + it( + "Pledge Moves - should not ignore redirection from another Pokemon's Follow Me", + async () => { + game.override.enemyMoveset([ Moves.FOLLOW_ME, Moves.SPLASH ]); + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); + + game.move.select(Moves.WATER_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.SPLASH, 1); + + await game.forceEnemyMove(Moves.SPLASH); + await game.forceEnemyMove(Moves.FOLLOW_ME); + + await game.phaseInterceptor.to("BerryPhase", false); + + const enemyPokemon = game.scene.getEnemyField(); + expect(enemyPokemon[0].hp).toBe(enemyPokemon[0].getMaxHp()); + expect(enemyPokemon[1].hp).toBeLessThan(enemyPokemon[1].getMaxHp()); + } + ); +}); diff --git a/src/test/moves/power_shift.test.ts b/src/test/moves/power_shift.test.ts index f39759f278b..e389f77bedf 100644 --- a/src/test/moves/power_shift.test.ts +++ b/src/test/moves/power_shift.test.ts @@ -22,7 +22,7 @@ describe("Moves - Power Shift", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.POWER_SHIFT, Moves.BULK_UP]) + .moveset([ Moves.POWER_SHIFT, Moves.BULK_UP ]) .battleType("single") .ability(Abilities.BALL_FETCH) .enemyAbility(Abilities.BALL_FETCH) @@ -30,7 +30,7 @@ describe("Moves - Power Shift", () => { }); it("switches the user's raw Attack stat with its raw Defense stat", async () => { - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const playerPokemon = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/power_split.test.ts b/src/test/moves/power_split.test.ts index aaf34541567..914fa86e491 100644 --- a/src/test/moves/power_split.test.ts +++ b/src/test/moves/power_split.test.ts @@ -55,7 +55,7 @@ describe("Moves - Power Split", () => { }, 20000); it("should be idempotent", async () => { - game.override.enemyMoveset([Moves.POWER_SPLIT]); + game.override.enemyMoveset([ Moves.POWER_SPLIT ]); await game.startBattle([ Species.INDEEDEE ]); diff --git a/src/test/moves/power_trick.test.ts b/src/test/moves/power_trick.test.ts new file mode 100644 index 00000000000..a064a43dec4 --- /dev/null +++ b/src/test/moves/power_trick.test.ts @@ -0,0 +1,113 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#app/test/utils/gameManager"; +import { Moves } from "#enums/moves"; +import { Stat } from "#enums/stat"; +import { Species } from "#enums/species"; +import { TurnEndPhase } from "#app/phases/turn-end-phase"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; + +describe("Moves - Power Trick", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleType("single") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .enemySpecies(Species.MEW) + .enemyLevel(200) + .moveset([ Moves.POWER_TRICK ]) + .ability(Abilities.BALL_FETCH); + }); + + it("swaps the user's ATK and DEF stats", async () => { + await game.classicMode.startBattle([ Species.SHUCKLE ]); + + const player = game.scene.getPlayerPokemon()!; + const baseATK = player.getStat(Stat.ATK, false); + const baseDEF = player.getStat(Stat.DEF, false); + + game.move.select(Moves.POWER_TRICK); + + await game.phaseInterceptor.to(TurnEndPhase); + + expect(player.getStat(Stat.ATK, false)).toBe(baseDEF); + expect(player.getStat(Stat.DEF, false)).toBe(baseATK); + expect(player.getTag(BattlerTagType.POWER_TRICK)).toBeDefined(); + }); + + it("resets initial ATK and DEF stat swap when used consecutively", async () => { + await game.classicMode.startBattle([ Species.SHUCKLE ]); + + const player = game.scene.getPlayerPokemon()!; + const baseATK = player.getStat(Stat.ATK, false); + const baseDEF = player.getStat(Stat.DEF, false); + + game.move.select(Moves.POWER_TRICK); + + await game.phaseInterceptor.to(TurnEndPhase); + + game.move.select(Moves.POWER_TRICK); + + await game.phaseInterceptor.to(TurnEndPhase); + + expect(player.getStat(Stat.ATK, false)).toBe(baseATK); + expect(player.getStat(Stat.DEF, false)).toBe(baseDEF); + expect(player.getTag(BattlerTagType.POWER_TRICK)).toBeUndefined(); + }); + + it("should pass effect when using BATON_PASS", async () => { + await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]); + await game.override.moveset([ Moves.POWER_TRICK, Moves.BATON_PASS ]); + + const player = game.scene.getPlayerPokemon()!; + player.addTag(BattlerTagType.POWER_TRICK); + + game.move.select(Moves.BATON_PASS); + game.doSelectPartyPokemon(1); + + await game.phaseInterceptor.to(TurnEndPhase); + + const switchedPlayer = game.scene.getPlayerPokemon()!; + const baseATK = switchedPlayer.getStat(Stat.ATK); + const baseDEF = switchedPlayer.getStat(Stat.DEF); + + expect(switchedPlayer.getStat(Stat.ATK, false)).toBe(baseDEF); + expect(switchedPlayer.getStat(Stat.DEF, false)).toBe(baseATK); + expect(switchedPlayer.getTag(BattlerTagType.POWER_TRICK)).toBeDefined(); + }); + + it("should remove effect after using Transform", async () => { + await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]); + await game.override.moveset([ Moves.POWER_TRICK, Moves.TRANSFORM ]); + + const player = game.scene.getPlayerPokemon()!; + player.addTag(BattlerTagType.POWER_TRICK); + + game.move.select(Moves.TRANSFORM); + + await game.phaseInterceptor.to(TurnEndPhase); + + const enemy = game.scene.getEnemyPokemon()!; + const baseATK = enemy.getStat(Stat.ATK); + const baseDEF = enemy.getStat(Stat.DEF); + + expect(player.getStat(Stat.ATK, false)).toBe(baseATK); + expect(player.getStat(Stat.DEF, false)).toBe(baseDEF); + expect(player.getTag(BattlerTagType.POWER_TRICK)).toBeUndefined(); + }); +}); diff --git a/src/test/moves/protect.test.ts b/src/test/moves/protect.test.ts index dcf4211ac7f..e639969ddf0 100644 --- a/src/test/moves/protect.test.ts +++ b/src/test/moves/protect.test.ts @@ -11,7 +11,6 @@ import { BattlerIndex } from "#app/battle"; import { MoveResult } from "#app/field/pokemon"; - describe("Moves - Protect", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -31,11 +30,11 @@ describe("Moves - Protect", () => { game.override.battleType("single"); - game.override.moveset([Moves.PROTECT]); + game.override.moveset([ Moves.PROTECT ]); game.override.enemySpecies(Species.SNORLAX); game.override.enemyAbility(Abilities.INSOMNIA); - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); game.override.startingLevel(100); game.override.enemyLevel(100); @@ -44,7 +43,7 @@ describe("Moves - Protect", () => { test( "should protect the user from attacks", async () => { - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -59,10 +58,10 @@ describe("Moves - Protect", () => { test( "should prevent secondary effects from the opponent's attack", async () => { - game.override.enemyMoveset([Moves.CEASELESS_EDGE]); + game.override.enemyMoveset([ Moves.CEASELESS_EDGE ]); vi.spyOn(allMoves[Moves.CEASELESS_EDGE], "accuracy", "get").mockReturnValue(100); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -78,9 +77,9 @@ describe("Moves - Protect", () => { test( "should protect the user from status moves", async () => { - game.override.enemyMoveset([Moves.CHARM]); + game.override.enemyMoveset([ Moves.CHARM ]); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -95,9 +94,9 @@ describe("Moves - Protect", () => { test( "should stop subsequent hits of a multi-hit move", async () => { - game.override.enemyMoveset([Moves.TACHYON_CUTTER]); + game.override.enemyMoveset([ Moves.TACHYON_CUTTER ]); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -114,16 +113,16 @@ describe("Moves - Protect", () => { test( "should fail if the user is the last to move in the turn", async () => { - game.override.enemyMoveset([Moves.PROTECT]); + game.override.enemyMoveset([ Moves.PROTECT ]); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.PROTECT); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("BerryPhase", false); diff --git a/src/test/moves/purify.test.ts b/src/test/moves/purify.test.ts index 3ba9dfcbb65..3b07eafd75a 100644 --- a/src/test/moves/purify.test.ts +++ b/src/test/moves/purify.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Moves - Purify", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,11 +29,11 @@ describe("Moves - Purify", () => { game.override.starterSpecies(Species.PYUKUMUKU); game.override.startingLevel(10); - game.override.moveset([Moves.PURIFY, Moves.SIZZLY_SLIDE]); + game.override.moveset([ Moves.PURIFY, Moves.SIZZLY_SLIDE ]); game.override.enemySpecies(Species.MAGIKARP); game.override.enemyLevel(10); - game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemyMoveset([ Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE ]); }); test( @@ -49,7 +48,7 @@ describe("Moves - Purify", () => { enemyPokemon.status = new Status(StatusEffect.BURN); game.move.select(Moves.PURIFY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEndPhase); expect(enemyPokemon.status).toBeNull(); @@ -68,7 +67,7 @@ describe("Moves - Purify", () => { const playerInitialHp = playerPokemon.hp; game.move.select(Moves.PURIFY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEndPhase); expect(playerPokemon.hp).toBe(playerInitialHp); diff --git a/src/test/moves/quick_guard.test.ts b/src/test/moves/quick_guard.test.ts index e03beeac06a..7bda71782aa 100644 --- a/src/test/moves/quick_guard.test.ts +++ b/src/test/moves/quick_guard.test.ts @@ -9,7 +9,6 @@ import { BattlerIndex } from "#app/battle"; import { MoveResult } from "#app/field/pokemon"; - describe("Moves - Quick Guard", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -29,10 +28,10 @@ describe("Moves - Quick Guard", () => { game.override.battleType("double"); - game.override.moveset([Moves.QUICK_GUARD, Moves.SPLASH, Moves.FOLLOW_ME]); + game.override.moveset([ Moves.QUICK_GUARD, Moves.SPLASH, Moves.FOLLOW_ME ]); game.override.enemySpecies(Species.SNORLAX); - game.override.enemyMoveset([Moves.QUICK_ATTACK]); + game.override.enemyMoveset([ Moves.QUICK_ATTACK ]); game.override.enemyAbility(Abilities.INSOMNIA); game.override.startingLevel(100); @@ -42,7 +41,7 @@ describe("Moves - Quick Guard", () => { test( "should protect the user and allies from priority moves", async () => { - await game.classicMode.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerField(); @@ -59,9 +58,9 @@ describe("Moves - Quick Guard", () => { "should protect the user and allies from Prankster-boosted moves", async () => { game.override.enemyAbility(Abilities.PRANKSTER); - game.override.enemyMoveset([Moves.GROWL]); + game.override.enemyMoveset([ Moves.GROWL ]); - await game.classicMode.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerField(); @@ -77,9 +76,9 @@ describe("Moves - Quick Guard", () => { test( "should stop subsequent hits of a multi-hit priority move", async () => { - game.override.enemyMoveset([Moves.WATER_SHURIKEN]); + game.override.enemyMoveset([ Moves.WATER_SHURIKEN ]); - await game.classicMode.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); @@ -98,16 +97,16 @@ describe("Moves - Quick Guard", () => { "should fail if the user is the last to move in the turn", async () => { game.override.battleType("single"); - game.override.enemyMoveset([Moves.QUICK_GUARD]); + game.override.enemyMoveset([ Moves.QUICK_GUARD ]); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.QUICK_GUARD); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("BerryPhase", false); diff --git a/src/test/moves/rage_powder.test.ts b/src/test/moves/rage_powder.test.ts index bb31a1f2194..1b73a7f0f5f 100644 --- a/src/test/moves/rage_powder.test.ts +++ b/src/test/moves/rage_powder.test.ts @@ -7,7 +7,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Moves - Rage Powder", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -28,14 +27,14 @@ describe("Moves - Rage Powder", () => { game.override.enemySpecies(Species.SNORLAX); game.override.startingLevel(100); game.override.enemyLevel(100); - game.override.moveset([Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK]); - game.override.enemyMoveset([Moves.RAGE_POWDER, Moves.TACKLE, Moves.SPLASH]); + game.override.moveset([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); + game.override.enemyMoveset([ Moves.RAGE_POWDER, Moves.TACKLE, Moves.SPLASH ]); }); test( "move effect should be bypassed by Grass type", async () => { - await game.classicMode.startBattle([Species.AMOONGUSS, Species.VENUSAUR]); + await game.classicMode.startBattle([ Species.AMOONGUSS, Species.VENUSAUR ]); const enemyPokemon = game.scene.getEnemyField(); @@ -59,7 +58,7 @@ describe("Moves - Rage Powder", () => { game.override.ability(Abilities.OVERCOAT); // Test with two non-Grass type player Pokemon - await game.classicMode.startBattle([Species.BLASTOISE, Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); const enemyPokemon = game.scene.getEnemyField(); diff --git a/src/test/moves/reflect.test.ts b/src/test/moves/reflect.test.ts index 9780ede3c55..3bf415ea75c 100644 --- a/src/test/moves/reflect.test.ts +++ b/src/test/moves/reflect.test.ts @@ -32,16 +32,16 @@ describe("Moves - Reflect", () => { game = new GameManager(phaserGame); game.override.battleType("single"); game.override.ability(Abilities.NONE); - game.override.moveset([Moves.ABSORB, Moves.ROCK_SLIDE, Moves.TACKLE]); + game.override.moveset([ Moves.ABSORB, Moves.ROCK_SLIDE, Moves.TACKLE ]); game.override.enemyLevel(100); game.override.enemySpecies(Species.MAGIKARP); - game.override.enemyMoveset([Moves.REFLECT, Moves.REFLECT, Moves.REFLECT, Moves.REFLECT]); + game.override.enemyMoveset([ Moves.REFLECT, Moves.REFLECT, Moves.REFLECT, Moves.REFLECT ]); game.override.disableCrits(); }); it("reduces damage of physical attacks by half in a single battle", async () => { const moveToUse = Moves.TACKLE; - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); game.move.select(moveToUse); @@ -55,7 +55,7 @@ describe("Moves - Reflect", () => { game.override.battleType("double"); const moveToUse = Moves.ROCK_SLIDE; - await game.startBattle([Species.SHUCKLE, Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]); game.move.select(moveToUse); game.move.select(moveToUse, 1); @@ -68,7 +68,7 @@ describe("Moves - Reflect", () => { it("does not affect special attacks", async () => { const moveToUse = Moves.ABSORB; - await game.startBattle([Species.SHUCKLE]); + await game.startBattle([ Species.SHUCKLE ]); game.move.select(moveToUse); @@ -94,7 +94,7 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) = const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; if (defender.scene.arena.getTagOnSide(ArenaTagType.REFLECT, side)) { - defender.scene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, move.category, defender.scene.currentBattle.double, multiplierHolder); + defender.scene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, false, attacker, move.category, multiplierHolder); } return move.power * multiplierHolder.value; diff --git a/src/test/moves/reflect_type.test.ts b/src/test/moves/reflect_type.test.ts new file mode 100644 index 00000000000..0e47d4b00fc --- /dev/null +++ b/src/test/moves/reflect_type.test.ts @@ -0,0 +1,59 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Type } from "#app/data/type"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Reflect Type", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemyAbility(Abilities.BALL_FETCH); + }); + + it("will make the user Normal/Grass if targetting a typeless Pokemon affected by Forest's Curse", async () => { + game.override + .moveset([ Moves.FORESTS_CURSE, Moves.REFLECT_TYPE ]) + .startingLevel(60) + .enemySpecies(Species.CHARMANDER) + .enemyMoveset([ Moves.BURN_UP, Moves.SPLASH ]); + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.BURN_UP); + await game.toNextTurn(); + + game.move.select(Moves.FORESTS_CURSE); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + expect(enemyPokemon?.getTypes().includes(Type.UNKNOWN)).toBe(true); + expect(enemyPokemon?.getTypes().includes(Type.GRASS)).toBe(true); + + game.move.select(Moves.REFLECT_TYPE); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon?.getTypes()[0]).toBe(Type.NORMAL); + expect(playerPokemon?.getTypes().includes(Type.GRASS)).toBe(true); + }); +}); diff --git a/src/test/moves/relic_song.test.ts b/src/test/moves/relic_song.test.ts index 67fc557a318..eb877b6054d 100644 --- a/src/test/moves/relic_song.test.ts +++ b/src/test/moves/relic_song.test.ts @@ -23,7 +23,7 @@ describe("Moves - Relic Song", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.RELIC_SONG, Moves.SPLASH]) + .moveset([ Moves.RELIC_SONG, Moves.SPLASH ]) .battleType("single") .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) @@ -32,7 +32,7 @@ describe("Moves - Relic Song", () => { }); it("swaps Meloetta's form between Aria and Pirouette", async () => { - await game.classicMode.startBattle([Species.MELOETTA]); + await game.classicMode.startBattle([ Species.MELOETTA ]); const meloetta = game.scene.getPlayerPokemon()!; @@ -49,7 +49,7 @@ describe("Moves - Relic Song", () => { it("doesn't swap Meloetta's form during a mono-type challenge", async () => { game.challengeMode.addChallenge(Challenges.SINGLE_TYPE, Type.PSYCHIC + 1, 0); - await game.challengeMode.startBattle([Species.MELOETTA]); + await game.challengeMode.startBattle([ Species.MELOETTA ]); const meloetta = game.scene.getPlayerPokemon()!; @@ -64,9 +64,9 @@ describe("Moves - Relic Song", () => { it("doesn't swap Meloetta's form during biome change (arena reset)", async () => { game.override - .starterForms({[Species.MELOETTA]: 1}) + .starterForms({ [Species.MELOETTA]: 1 }) .startingWave(10); - await game.classicMode.startBattle([Species.MELOETTA]); + await game.classicMode.startBattle([ Species.MELOETTA ]); const meloetta = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/retaliate.test.ts b/src/test/moves/retaliate.test.ts index 62965fffba6..e00b9da6010 100644 --- a/src/test/moves/retaliate.test.ts +++ b/src/test/moves/retaliate.test.ts @@ -26,16 +26,16 @@ describe("Moves - Retaliate", () => { game.override .battleType("single") .enemySpecies(Species.SNORLAX) - .enemyMoveset([Moves.RETALIATE, Moves.RETALIATE, Moves.RETALIATE, Moves.RETALIATE]) + .enemyMoveset([ Moves.RETALIATE, Moves.RETALIATE, Moves.RETALIATE, Moves.RETALIATE ]) .enemyLevel(100) - .moveset([Moves.RETALIATE, Moves.SPLASH]) + .moveset([ Moves.RETALIATE, Moves.SPLASH ]) .startingLevel(80) .disableCrits(); }); it("increases power if ally died previous turn", async () => { vi.spyOn(retaliate, "calculateBattlePower"); - await game.startBattle([Species.ABRA, Species.COBALION]); + await game.startBattle([ Species.ABRA, Species.COBALION ]); game.move.select(Moves.RETALIATE); await game.phaseInterceptor.to("TurnEndPhase"); expect(retaliate.calculateBattlePower).toHaveLastReturnedWith(70); diff --git a/src/test/moves/rollout.test.ts b/src/test/moves/rollout.test.ts index c08535a61df..4a14b100f6d 100644 --- a/src/test/moves/rollout.test.ts +++ b/src/test/moves/rollout.test.ts @@ -35,7 +35,7 @@ describe("Moves - Rollout", () => { }); it("should double it's dmg on sequential uses but reset after 5", async () => { - game.override.moveset([Moves.ROLLOUT]); + game.override.moveset([ Moves.ROLLOUT ]); vi.spyOn(allMoves[Moves.ROLLOUT], "accuracy", "get").mockReturnValue(100); //always hit const variance = 5; @@ -45,10 +45,10 @@ describe("Moves - Rollout", () => { await game.startBattle(); const playerPkm = game.scene.getParty()[0]; - vi.spyOn(playerPkm, "stats", "get").mockReturnValue([500000, 1, 1, 1, 1, 1]); // HP, ATK, DEF, SPATK, SPDEF, SPD + vi.spyOn(playerPkm, "stats", "get").mockReturnValue([ 500000, 1, 1, 1, 1, 1 ]); // HP, ATK, DEF, SPATK, SPDEF, SPD const enemyPkm = game.scene.getEnemyParty()[0]; - vi.spyOn(enemyPkm, "stats", "get").mockReturnValue([500000, 1, 1, 1, 1, 1]); // HP, ATK, DEF, SPATK, SPDEF, SPD + vi.spyOn(enemyPkm, "stats", "get").mockReturnValue([ 500000, 1, 1, 1, 1, 1 ]); // HP, ATK, DEF, SPATK, SPDEF, SPD vi.spyOn(enemyPkm, "getHeldItems").mockReturnValue([]); //no berries enemyPkm.hp = enemyPkm.getMaxHp(); @@ -62,7 +62,7 @@ describe("Moves - Rollout", () => { previousHp = enemyPkm.hp; } - const [turn1Dmg, turn2Dmg, turn3Dmg, turn4Dmg, turn5Dmg, turn6Dmg] = dmgHistory; + const [ turn1Dmg, turn2Dmg, turn3Dmg, turn4Dmg, turn5Dmg, turn6Dmg ] = dmgHistory; expect(turn2Dmg).toBeGreaterThanOrEqual(turn1Dmg * 2 - variance); expect(turn2Dmg).toBeLessThanOrEqual(turn1Dmg * 2 + variance); diff --git a/src/test/moves/roost.test.ts b/src/test/moves/roost.test.ts index a1c473c0632..e595f879844 100644 --- a/src/test/moves/roost.test.ts +++ b/src/test/moves/roost.test.ts @@ -10,7 +10,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Moves - Roost", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -32,7 +31,7 @@ describe("Moves - Roost", () => { game.override.startingLevel(100); game.override.enemyLevel(100); game.override.enemyMoveset(Moves.EARTHQUAKE); - game.override.moveset([Moves.ROOST, Moves.BURN_UP, Moves.DOUBLE_SHOCK]); + game.override.moveset([ Moves.ROOST, Moves.BURN_UP, Moves.DOUBLE_SHOCK ]); }); /** @@ -51,11 +50,11 @@ describe("Moves - Roost", () => { test( "Non flying type uses roost -> no type change, took damage", async () => { - await game.classicMode.startBattle([Species.DUNSPARCE]); + await game.classicMode.startBattle([ Species.DUNSPARCE ]); const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemonStartingHP = playerPokemon.hp; game.move.select(Moves.ROOST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); // Should only be normal type, and NOT flying type @@ -78,11 +77,11 @@ describe("Moves - Roost", () => { test( "Pure flying type -> becomes normal after roost and takes damage from ground moves -> regains flying", async () => { - await game.classicMode.startBattle([Species.TORNADUS]); + await game.classicMode.startBattle([ Species.TORNADUS ]); const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemonStartingHP = playerPokemon.hp; game.move.select(Moves.ROOST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); // Should only be normal type, and NOT flying type @@ -106,11 +105,11 @@ describe("Moves - Roost", () => { test( "Dual X/flying type -> becomes type X after roost and takes damage from ground moves -> regains flying", async () => { - await game.classicMode.startBattle([Species.HAWLUCHA]); + await game.classicMode.startBattle([ Species.HAWLUCHA ]); const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemonStartingHP = playerPokemon.hp; game.move.select(Moves.ROOST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); // Should only be pure fighting type and grounded @@ -135,11 +134,11 @@ describe("Moves - Roost", () => { "Pokemon with levitate after using roost should lose flying type but still be unaffected by ground moves", async () => { game.override.starterForms({ [Species.ROTOM]: 4 }); - await game.classicMode.startBattle([Species.ROTOM]); + await game.classicMode.startBattle([ Species.ROTOM ]); const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemonStartingHP = playerPokemon.hp; game.move.select(Moves.ROOST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); // Should only be pure eletric type and grounded @@ -163,11 +162,11 @@ describe("Moves - Roost", () => { test( "A fire/flying type that uses burn up, then roost should be typeless until end of turn", async () => { - await game.classicMode.startBattle([Species.MOLTRES]); + await game.classicMode.startBattle([ Species.MOLTRES ]); const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemonStartingHP = playerPokemon.hp; game.move.select(Moves.BURN_UP); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); // Should only be pure flying type after burn up @@ -177,7 +176,7 @@ describe("Moves - Roost", () => { await game.phaseInterceptor.to(TurnEndPhase); game.move.select(Moves.ROOST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); // Should only be typeless type after roost and is grounded @@ -203,11 +202,11 @@ describe("Moves - Roost", () => { "An electric/flying type that uses double shock, then roost should be typeless until end of turn", async () => { game.override.enemySpecies(Species.ZEKROM); - await game.classicMode.startBattle([Species.ZAPDOS]); + await game.classicMode.startBattle([ Species.ZAPDOS ]); const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemonStartingHP = playerPokemon.hp; game.move.select(Moves.DOUBLE_SHOCK); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); // Should only be pure flying type after burn up @@ -217,7 +216,7 @@ describe("Moves - Roost", () => { await game.phaseInterceptor.to(TurnEndPhase); game.move.select(Moves.ROOST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to(MoveEffectPhase); // Should only be typeless type after roost and is grounded @@ -242,8 +241,8 @@ describe("Moves - Roost", () => { test( "Dual Type Pokemon afflicted with Forests Curse/Trick or Treat and post roost will become dual type and then become 3 type at end of turn", async () => { - game.override.enemyMoveset([Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT]); - await game.classicMode.startBattle([Species.MOLTRES]); + game.override.enemyMoveset([ Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT ]); + await game.classicMode.startBattle([ Species.MOLTRES ]); const playerPokemon = game.scene.getPlayerPokemon()!; game.move.select(Moves.ROOST); await game.phaseInterceptor.to(MoveEffectPhase); diff --git a/src/test/moves/safeguard.test.ts b/src/test/moves/safeguard.test.ts index b21698d0298..6505162fd04 100644 --- a/src/test/moves/safeguard.test.ts +++ b/src/test/moves/safeguard.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; - describe("Moves - Safeguard", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -29,12 +28,12 @@ describe("Moves - Safeguard", () => { game.override .battleType("single") .enemySpecies(Species.DRATINI) - .enemyMoveset([Moves.SAFEGUARD]) + .enemyMoveset([ Moves.SAFEGUARD ]) .enemyAbility(Abilities.BALL_FETCH) .enemyLevel(5) .starterSpecies(Species.DRATINI) - .moveset([Moves.NUZZLE, Moves.SPORE, Moves.YAWN, Moves.SPLASH]) - .ability(Abilities.BALL_FETCH); + .moveset([ Moves.NUZZLE, Moves.SPORE, Moves.YAWN, Moves.SPLASH ]) + .ability(Abilities.UNNERVE); // Stop wild Pokemon from potentially eating Lum Berry }); it("protects from damaging moves with additional effects", async () => { @@ -42,7 +41,7 @@ describe("Moves - Safeguard", () => { const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.NUZZLE); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); expect(enemy.status).toBeUndefined(); @@ -53,19 +52,19 @@ describe("Moves - Safeguard", () => { const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.SPORE); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); expect(enemyPokemon.status).toBeUndefined(); }); it("protects from confusion", async () => { - game.override.moveset([Moves.CONFUSE_RAY]); + game.override.moveset([ Moves.CONFUSE_RAY ]); await game.classicMode.startBattle(); const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.CONFUSE_RAY); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); expect(enemyPokemon.summonData.tags).toEqual([]); @@ -79,7 +78,7 @@ describe("Moves - Safeguard", () => { game.move.select(Moves.SPORE, 0, BattlerIndex.ENEMY_2); game.move.select(Moves.NUZZLE, 1, BattlerIndex.ENEMY_2); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2 ]); await game.phaseInterceptor.to("BerryPhase"); @@ -94,7 +93,7 @@ describe("Moves - Safeguard", () => { const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.YAWN); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); expect(enemyPokemon.summonData.tags).toEqual([]); @@ -105,7 +104,7 @@ describe("Moves - Safeguard", () => { const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.YAWN); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.toNextTurn(); game.move.select(Moves.SPLASH); @@ -115,18 +114,18 @@ describe("Moves - Safeguard", () => { }); it("doesn't protect from self-inflicted via Rest or Flame Orb", async () => { - game.override.enemyHeldItems([{name: "FLAME_ORB"}]); + game.override.enemyHeldItems([{ name: "FLAME_ORB" }]); await game.classicMode.startBattle(); const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.SPLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); enemyPokemon.damageAndUpdate(1); expect(enemyPokemon.status?.effect).toEqual(StatusEffect.BURN); - game.override.enemyMoveset([Moves.REST]); + game.override.enemyMoveset([ Moves.REST ]); // Force the moveset to update mid-battle // TODO: Remove after enemy AI rework is in enemyPokemon.getMoveset(); @@ -144,9 +143,9 @@ describe("Moves - Safeguard", () => { const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.SPLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextTurn(); - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); game.move.select(Moves.SPLASH); await game.toNextTurn(); diff --git a/src/test/moves/scale_shot.test.ts b/src/test/moves/scale_shot.test.ts new file mode 100644 index 00000000000..e4d768fa13a --- /dev/null +++ b/src/test/moves/scale_shot.test.ts @@ -0,0 +1,85 @@ +import { BattlerIndex } from "#app/battle"; +import { allMoves } from "#app/data/move"; +import { DamagePhase } from "#app/phases/damage-phase"; +import { MoveEffectPhase } from "#app/phases/move-effect-phase"; +import { MoveEndPhase } from "#app/phases/move-end-phase"; +import { TurnEndPhase } from "#app/phases/turn-end-phase"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Scale Shot", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.SCALE_SHOT ]) + .battleType("single") + .disableCrits() + .ability(Abilities.NO_GUARD) + .passiveAbility(Abilities.SKILL_LINK) + .enemyMoveset(Moves.SPLASH) + .enemyLevel(3); + }); + + it("applies stat changes after last hit", async () => { + game.override.enemySpecies(Species.FORRETRESS); + + await game.classicMode.startBattle([ Species.MINCCINO ]); + const minccino = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SCALE_SHOT); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to(MoveEffectPhase); + await game.phaseInterceptor.to(DamagePhase); + + //check that stats haven't changed after one or two hits have occurred + await game.phaseInterceptor.to(MoveEffectPhase); + expect(minccino.getStatStage(Stat.DEF)).toBe(0); + expect(minccino.getStatStage(Stat.SPD)).toBe(0); + + //check that stats changed on last hit + await game.phaseInterceptor.to(MoveEndPhase); + expect(minccino.getStatStage(Stat.DEF)).toBe(-1); + expect(minccino.getStatStage(Stat.SPD)).toBe(1); + }); + + it("unaffected by sheer force", async () => { + const moveToCheck = allMoves[Moves.SCALE_SHOT]; + const basePower = moveToCheck.power; + + game.override.enemySpecies(Species.WOBBUFFET); + + vi.spyOn(moveToCheck, "calculateBattlePower"); + + await game.classicMode.startBattle([ Species.MINCCINO ]); + const minccino = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.SCALE_SHOT); + await game.phaseInterceptor.to(TurnEndPhase); + + //effect not nullified by sheer force + expect(minccino.getStatStage(Stat.DEF)).toBe(-1); + expect(minccino.getStatStage(Stat.SPD)).toBe(1); + + //power not boosted by sheer force + expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower); + }); +}); diff --git a/src/test/moves/secret_power.test.ts b/src/test/moves/secret_power.test.ts new file mode 100644 index 00000000000..ff0b5ae8c24 --- /dev/null +++ b/src/test/moves/secret_power.test.ts @@ -0,0 +1,89 @@ +import { Abilities } from "#enums/abilities"; +import { Biome } from "#enums/biome"; +import { Moves } from "#enums/moves"; +import { Stat } from "#enums/stat"; +import { allMoves, SecretPowerAttr } from "#app/data/move"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { StatusEffect } from "#enums/status-effect"; +import { BattlerIndex } from "#app/battle"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { ArenaTagSide } from "#app/data/arena-tag"; + +describe("Moves - Secret Power", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.SECRET_POWER ]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyLevel(60) + .enemyAbility(Abilities.BALL_FETCH); + }); + + it("Secret Power checks for an active terrain first then looks at the biome for its secondary effect", async () => { + game.override + .startingBiome(Biome.VOLCANO) + .enemyMoveset([ Moves.SPLASH, Moves.MISTY_TERRAIN ]); + vi.spyOn(allMoves[Moves.SECRET_POWER], "chance", "get").mockReturnValue(100); + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + + // No Terrain + Biome.VOLCANO --> Burn + game.move.select(Moves.SECRET_POWER); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyPokemon.status?.effect).toBe(StatusEffect.BURN); + + // Misty Terrain --> SpAtk -1 + game.move.select(Moves.SECRET_POWER); + await game.forceEnemyMove(Moves.MISTY_TERRAIN); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-1); + }); + + it("the 'rainbow' effect of fire+water pledge does not double the chance of secret power's secondary effect", + async () => { + game.override + .moveset([ Moves.FIRE_PLEDGE, Moves.WATER_PLEDGE, Moves.SECRET_POWER, Moves.SPLASH ]) + .enemyMoveset([ Moves.SPLASH ]) + .battleType("double"); + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); + + const secretPowerAttr = allMoves[Moves.SECRET_POWER].getAttrs(SecretPowerAttr)[0]; + vi.spyOn(secretPowerAttr, "getMoveChance"); + + game.move.select(Moves.WATER_PLEDGE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.FIRE_PLEDGE, 1, BattlerIndex.ENEMY_2); + + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.scene.arena.getTagOnSide(ArenaTagType.WATER_FIRE_PLEDGE, ArenaTagSide.PLAYER)).toBeDefined(); + + game.move.select(Moves.SECRET_POWER, 0, BattlerIndex.ENEMY); + game.move.select(Moves.SPLASH, 1); + + await game.phaseInterceptor.to("BerryPhase", false); + + expect(secretPowerAttr.getMoveChance).toHaveLastReturnedWith(30); + } + ); +}); diff --git a/src/test/moves/shed_tail.test.ts b/src/test/moves/shed_tail.test.ts index a976a614792..c4df6c574cb 100644 --- a/src/test/moves/shed_tail.test.ts +++ b/src/test/moves/shed_tail.test.ts @@ -23,7 +23,7 @@ describe("Moves - Shed Tail", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.SHED_TAIL]) + .moveset([ Moves.SHED_TAIL ]) .battleType("single") .enemySpecies(Species.SNORLAX) .enemyAbility(Abilities.BALL_FETCH) @@ -31,7 +31,7 @@ describe("Moves - Shed Tail", () => { }); it("transfers a Substitute doll to the switched in Pokemon", async () => { - await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); + await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); const magikarp = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/shell_side_arm.test.ts b/src/test/moves/shell_side_arm.test.ts index 643313f1eae..9646d27f17e 100644 --- a/src/test/moves/shell_side_arm.test.ts +++ b/src/test/moves/shell_side_arm.test.ts @@ -26,7 +26,7 @@ describe("Moves - Shell Side Arm", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.SHELL_SIDE_ARM]) + .moveset([ Moves.SHELL_SIDE_ARM ]) .battleType("single") .startingLevel(100) .enemyLevel(100) @@ -37,7 +37,7 @@ describe("Moves - Shell Side Arm", () => { it("becomes a physical attack if forecasted to deal more damage as physical", async () => { game.override.enemySpecies(Species.SNORLAX); - await game.classicMode.startBattle([Species.RAMPARDOS]); + await game.classicMode.startBattle([ Species.RAMPARDOS ]); vi.spyOn(shellSideArmAttr, "apply"); @@ -50,7 +50,7 @@ describe("Moves - Shell Side Arm", () => { it("remains a special attack if forecasted to deal more damage as special", async () => { game.override.enemySpecies(Species.SLOWBRO); - await game.classicMode.startBattle([Species.XURKITREE]); + await game.classicMode.startBattle([ Species.XURKITREE ]); vi.spyOn(shellSideArmAttr, "apply"); @@ -65,12 +65,12 @@ describe("Moves - Shell Side Arm", () => { .enemySpecies(Species.SNORLAX) .enemyMoveset(Moves.COTTON_GUARD); - await game.classicMode.startBattle([Species.MANAPHY]); + await game.classicMode.startBattle([ Species.MANAPHY ]); vi.spyOn(shellSideArmAttr, "apply"); game.move.select(Moves.SHELL_SIDE_ARM); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("BerryPhase", false); expect(shellSideArmAttr.apply).toHaveLastReturnedWith(false); diff --git a/src/test/moves/shell_trap.test.ts b/src/test/moves/shell_trap.test.ts index 1dae00e24a5..04d3cf998b1 100644 --- a/src/test/moves/shell_trap.test.ts +++ b/src/test/moves/shell_trap.test.ts @@ -11,7 +11,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; - describe("Moves - Shell Trap", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,9 +29,9 @@ describe("Moves - Shell Trap", () => { game = new GameManager(phaserGame); game.override .battleType("double") - .moveset([Moves.SHELL_TRAP, Moves.SPLASH, Moves.BULLDOZE]) + .moveset([ Moves.SHELL_TRAP, Moves.SPLASH, Moves.BULLDOZE ]) .enemySpecies(Species.SNORLAX) - .enemyMoveset([Moves.RAZOR_LEAF]) + .enemyMoveset([ Moves.RAZOR_LEAF ]) .startingLevel(100) .enemyLevel(100); @@ -42,7 +41,7 @@ describe("Moves - Shell Trap", () => { it( "should activate after the user is hit by a physical attack", async () => { - await game.startBattle([Species.CHARIZARD, Species.TURTONATOR]); + await game.startBattle([ Species.CHARIZARD, Species.TURTONATOR ]); const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); @@ -50,7 +49,7 @@ describe("Moves - Shell Trap", () => { game.move.select(Moves.SPLASH); game.move.select(Moves.SHELL_TRAP, 1); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2 ]); await game.phaseInterceptor.to(MoveEndPhase); @@ -66,9 +65,9 @@ describe("Moves - Shell Trap", () => { it( "should fail if the user is only hit by special attacks", async () => { - game.override.enemyMoveset([Moves.SWIFT]); + game.override.enemyMoveset([ Moves.SWIFT ]); - await game.startBattle([Species.CHARIZARD, Species.TURTONATOR]); + await game.startBattle([ Species.CHARIZARD, Species.TURTONATOR ]); const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); @@ -76,7 +75,7 @@ describe("Moves - Shell Trap", () => { game.move.select(Moves.SPLASH); game.move.select(Moves.SHELL_TRAP, 1); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2 ]); await game.phaseInterceptor.to(MoveEndPhase); @@ -94,7 +93,7 @@ describe("Moves - Shell Trap", () => { async () => { game.override.enemyMoveset(Moves.SPLASH); - await game.startBattle([Species.CHARIZARD, Species.TURTONATOR]); + await game.startBattle([ Species.CHARIZARD, Species.TURTONATOR ]); const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); @@ -102,7 +101,7 @@ describe("Moves - Shell Trap", () => { game.move.select(Moves.SPLASH); game.move.select(Moves.SHELL_TRAP, 1); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2 ]); await game.phaseInterceptor.to(MoveEndPhase); @@ -120,7 +119,7 @@ describe("Moves - Shell Trap", () => { async () => { game.override.enemyMoveset(Moves.SPLASH); - await game.startBattle([Species.BLASTOISE, Species.CHARIZARD]); + await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); @@ -147,7 +146,7 @@ describe("Moves - Shell Trap", () => { game.override.battleType("single"); vi.spyOn(allMoves[Moves.RAZOR_LEAF], "priority", "get").mockReturnValue(-4); - await game.startBattle([Species.CHARIZARD]); + await game.startBattle([ Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/sketch.test.ts b/src/test/moves/sketch.test.ts new file mode 100644 index 00000000000..2e3eb97a76c --- /dev/null +++ b/src/test/moves/sketch.test.ts @@ -0,0 +1,53 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { MoveResult } from "#app/field/pokemon"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Sketch", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.SHUCKLE) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("Sketch should not fail even if a previous Sketch failed to retrieve a valid move and ran out of PP", async () => { + game.override.moveset([ Moves.SKETCH, Moves.SKETCH ]); + + await game.classicMode.startBattle([ Species.REGIELEKI ]); + const playerPokemon = game.scene.getPlayerPokemon(); + + game.move.select(Moves.SKETCH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon?.getLastXMoves()[0].result).toBe(MoveResult.FAIL); + const moveSlot0 = playerPokemon?.getMoveset()[0]; + expect(moveSlot0?.moveId).toBe(Moves.SKETCH); + expect(moveSlot0?.getPpRatio()).toBe(0); + + await game.toNextTurn(); + game.move.select(Moves.SKETCH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon?.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS); + // Can't verify if the player Pokemon's moveset was successfully changed because of overrides. + }); +}); diff --git a/src/test/moves/solar_beam.test.ts b/src/test/moves/solar_beam.test.ts new file mode 100644 index 00000000000..ebec338932a --- /dev/null +++ b/src/test/moves/solar_beam.test.ts @@ -0,0 +1,102 @@ +import { allMoves } from "#app/data/move"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { WeatherType } from "#enums/weather-type"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Solar Beam", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset(Moves.SOLAR_BEAM) + .battleType("single") + .startingLevel(100) + .enemySpecies(Species.SNORLAX) + .enemyLevel(100) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should deal damage in two turns if no weather is active", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.SOLAR_BEAM); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.CHARGING)).toBeDefined(); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.OTHER); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.CHARGING)).toBeUndefined(); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveHistory()).toHaveLength(2); + expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + + const playerSolarBeam = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.SOLAR_BEAM); + expect(playerSolarBeam?.ppUsed).toBe(1); + }); + + it.each([ + { weatherType: WeatherType.SUNNY, name: "Sun" }, + { weatherType: WeatherType.HARSH_SUN, name: "Harsh Sun" } + ])("should deal damage in one turn if $name is active", async ({ weatherType }) => { + game.override.weather(weatherType); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.SOLAR_BEAM); + + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getTag(BattlerTagType.CHARGING)).toBeUndefined(); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(playerPokemon.getMoveHistory()).toHaveLength(2); + expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); + + const playerSolarBeam = playerPokemon.getMoveset().find(mv => mv && mv.moveId === Moves.SOLAR_BEAM); + expect(playerSolarBeam?.ppUsed).toBe(1); + }); + + it.each([ + { weatherType: WeatherType.RAIN, name: "Rain" }, + { weatherType: WeatherType.HEAVY_RAIN, name: "Heavy Rain" } + ])("should have its power halved in $name", async ({ weatherType }) => { + game.override.weather(weatherType); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const solarBeam = allMoves[Moves.SOLAR_BEAM]; + + vi.spyOn(solarBeam, "calculateBattlePower"); + + game.move.select(Moves.SOLAR_BEAM); + + await game.phaseInterceptor.to("TurnEndPhase"); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(solarBeam.calculateBattlePower).toHaveLastReturnedWith(60); + }); +}); diff --git a/src/test/moves/sparkly_swirl.test.ts b/src/test/moves/sparkly_swirl.test.ts new file mode 100644 index 00000000000..8449f2785f8 --- /dev/null +++ b/src/test/moves/sparkly_swirl.test.ts @@ -0,0 +1,86 @@ +import { allMoves } from "#app/data/move"; +import { StatusEffect } from "#app/enums/status-effect"; +import { CommandPhase } from "#app/phases/command-phase"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Moves - Sparkly Swirl", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ type: Phaser.HEADLESS }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .enemySpecies(Species.SHUCKLE) + .enemyLevel(100) + .enemyMoveset(Moves.SPLASH) + .enemyAbility(Abilities.BALL_FETCH) + .moveset([ Moves.SPARKLY_SWIRL, Moves.SPLASH ]) + .ability(Abilities.BALL_FETCH); + + vi.spyOn(allMoves[Moves.SPARKLY_SWIRL], "accuracy", "get").mockReturnValue(100); + }); + + it("should cure status effect of the user, its ally, and all party pokemon", async () => { + game.override + .battleType("double") + .statusEffect(StatusEffect.BURN); + await game.classicMode.startBattle([ Species.RATTATA, Species.RATTATA, Species.RATTATA ]); + const [ leftPlayer, rightPlayer, partyPokemon ] = game.scene.getParty(); + const leftOpp = game.scene.getEnemyPokemon()!; + + vi.spyOn(leftPlayer, "resetStatus"); + vi.spyOn(rightPlayer, "resetStatus"); + vi.spyOn(partyPokemon, "resetStatus"); + + game.move.select(Moves.SPARKLY_SWIRL, 0, leftOpp.getBattlerIndex()); + await game.phaseInterceptor.to(CommandPhase); + game.move.select(Moves.SPLASH, 1); + await game.toNextTurn(); + + expect(leftPlayer.resetStatus).toHaveBeenCalledOnce(); + expect(rightPlayer.resetStatus).toHaveBeenCalledOnce(); + expect(partyPokemon.resetStatus).toHaveBeenCalledOnce(); + + expect(leftPlayer.status?.effect).toBeUndefined(); + expect(rightPlayer.status?.effect).toBeUndefined(); + expect(partyPokemon.status?.effect).toBeUndefined(); + }); + + it("should not cure status effect of the target/target's allies", async () => { + game.override + .battleType("double") + .enemyStatusEffect(StatusEffect.BURN); + await game.classicMode.startBattle([ Species.RATTATA, Species.RATTATA ]); + const [ leftOpp, rightOpp ] = game.scene.getEnemyField(); + + vi.spyOn(leftOpp, "resetStatus"); + vi.spyOn(rightOpp, "resetStatus"); + + game.move.select(Moves.SPARKLY_SWIRL, 0, leftOpp.getBattlerIndex()); + await game.phaseInterceptor.to(CommandPhase); + game.move.select(Moves.SPLASH, 1); + await game.toNextTurn(); + + expect(leftOpp.resetStatus).toHaveBeenCalledTimes(0); + expect(rightOpp.resetStatus).toHaveBeenCalledTimes(0); + + expect(leftOpp.status?.effect).toBeTruthy(); + expect(rightOpp.status?.effect).toBeTruthy(); + + expect(leftOpp.status?.effect).toBe(StatusEffect.BURN); + expect(rightOpp.status?.effect).toBe(StatusEffect.BURN); + }); +}); diff --git a/src/test/moves/spikes.test.ts b/src/test/moves/spikes.test.ts index aa59912d802..1dd13f8f65e 100644 --- a/src/test/moves/spikes.test.ts +++ b/src/test/moves/spikes.test.ts @@ -28,11 +28,11 @@ describe("Moves - Spikes", () => { .enemyAbility(Abilities.BALL_FETCH) .ability(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) - .moveset([Moves.SPIKES, Moves.SPLASH, Moves.ROAR]); + .moveset([ Moves.SPIKES, Moves.SPLASH, Moves.ROAR ]); }); it("should not damage the team that set them", async () => { - await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); + await game.startBattle([ Species.MIGHTYENA, Species.POOCHYENA ]); game.move.select(Moves.SPIKES); await game.toNextTurn(); @@ -52,7 +52,7 @@ describe("Moves - Spikes", () => { it("should damage opposing pokemon that are forced to switch in", async () => { game.override.startingWave(5); - await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); + await game.startBattle([ Species.MIGHTYENA, Species.POOCHYENA ]); game.move.select(Moves.SPIKES); await game.toNextTurn(); @@ -66,7 +66,7 @@ describe("Moves - Spikes", () => { it("should damage opposing pokemon that choose to switch in", async () => { game.override.startingWave(5); - await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); + await game.startBattle([ Species.MIGHTYENA, Species.POOCHYENA ]); game.move.select(Moves.SPIKES); await game.toNextTurn(); diff --git a/src/test/moves/spit_up.test.ts b/src/test/moves/spit_up.test.ts index 412360c2664..8e418858e8d 100644 --- a/src/test/moves/spit_up.test.ts +++ b/src/test/moves/spit_up.test.ts @@ -47,7 +47,7 @@ describe("Moves - Spit Up", () => { const stacksToSetup = 1; const expectedPower = 100; - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; pokemon.addTag(BattlerTagType.STOCKPILING); @@ -69,7 +69,7 @@ describe("Moves - Spit Up", () => { const stacksToSetup = 2; const expectedPower = 200; - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; pokemon.addTag(BattlerTagType.STOCKPILING); @@ -92,7 +92,7 @@ describe("Moves - Spit Up", () => { const stacksToSetup = 3; const expectedPower = 300; - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; pokemon.addTag(BattlerTagType.STOCKPILING); @@ -114,7 +114,7 @@ describe("Moves - Spit Up", () => { }); it("fails without stacks", async () => { - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; @@ -131,7 +131,7 @@ describe("Moves - Spit Up", () => { describe("restores stat boosts granted by stacks", () => { it("decreases stats based on stored values (both boosts equal)", async () => { - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; pokemon.addTag(BattlerTagType.STOCKPILING); @@ -158,7 +158,7 @@ describe("Moves - Spit Up", () => { }); it("decreases stats based on stored values (different boosts)", async () => { - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; pokemon.addTag(BattlerTagType.STOCKPILING); diff --git a/src/test/moves/spotlight.test.ts b/src/test/moves/spotlight.test.ts index 6324c3dc6ec..095f7d80bfe 100644 --- a/src/test/moves/spotlight.test.ts +++ b/src/test/moves/spotlight.test.ts @@ -7,7 +7,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; - describe("Moves - Spotlight", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -29,14 +28,14 @@ describe("Moves - Spotlight", () => { game.override.enemySpecies(Species.SNORLAX); game.override.startingLevel(100); game.override.enemyLevel(100); - game.override.moveset([Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK]); - game.override.enemyMoveset([Moves.FOLLOW_ME, Moves.SPLASH]); + game.override.moveset([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); + game.override.enemyMoveset([ Moves.FOLLOW_ME, Moves.SPLASH ]); }); test( "move should redirect attacks to the target", async () => { - await game.classicMode.startBattle([Species.AMOONGUSS, Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); const enemyPokemon = game.scene.getEnemyField(); @@ -56,7 +55,7 @@ describe("Moves - Spotlight", () => { test( "move should cause other redirection moves to fail", async () => { - await game.classicMode.startBattle([Species.AMOONGUSS, Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); const enemyPokemon = game.scene.getEnemyField(); diff --git a/src/test/moves/steamroller.test.ts b/src/test/moves/steamroller.test.ts index cbbb3a22593..9d16643ec5d 100644 --- a/src/test/moves/steamroller.test.ts +++ b/src/test/moves/steamroller.test.ts @@ -25,12 +25,12 @@ describe("Moves - Steamroller", () => { beforeEach(() => { game = new GameManager(phaserGame); - game.override.moveset([Moves.STEAMROLLER]).battleType("single").enemyAbility(Abilities.BALL_FETCH); + game.override.moveset([ Moves.STEAMROLLER ]).battleType("single").enemyAbility(Abilities.BALL_FETCH); }); it("should always hit a minimzed target with double damage", async () => { game.override.enemySpecies(Species.DITTO).enemyMoveset(Moves.MINIMIZE); - await game.classicMode.startBattle([Species.IRON_BOULDER]); + await game.classicMode.startBattle([ Species.IRON_BOULDER ]); const ditto = game.scene.getEnemyPokemon()!; vi.spyOn(ditto, "getAttackDamage"); @@ -41,13 +41,13 @@ describe("Moves - Steamroller", () => { vi.spyOn(ironBoulder, "getAccuracyMultiplier"); // Turn 1 game.move.select(Moves.STEAMROLLER); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.toNextTurn(); // Turn 2 game.move.select(Moves.STEAMROLLER); await game.toNextTurn(); - const [dmgCalcTurn1, dmgCalcTurn2]: DamageCalculationResult[] = vi + const [ dmgCalcTurn1, dmgCalcTurn2 ]: DamageCalculationResult[] = vi .mocked(ditto.getAttackDamage) .mock.results.map((r) => r.value); diff --git a/src/test/moves/stockpile.test.ts b/src/test/moves/stockpile.test.ts index 141ce79eb33..d3239856ed7 100644 --- a/src/test/moves/stockpile.test.ts +++ b/src/test/moves/stockpile.test.ts @@ -33,12 +33,12 @@ describe("Moves - Stockpile", () => { game.override.enemyAbility(Abilities.NONE); game.override.startingLevel(2000); - game.override.moveset([Moves.STOCKPILE, Moves.SPLASH]); + game.override.moveset([ Moves.STOCKPILE, Moves.SPLASH ]); game.override.ability(Abilities.NONE); }); it("gains a stockpile stack and raises user's DEF and SPDEF stat stages by 1 on each use, fails at max stacks (3)", async () => { - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const user = game.scene.getPlayerPokemon()!; @@ -77,7 +77,7 @@ describe("Moves - Stockpile", () => { }); it("gains a stockpile stack even if user's DEF and SPDEF stat stages are at +6", async () => { - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const user = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/substitute.test.ts b/src/test/moves/substitute.test.ts index 3099446f081..92f66c967c4 100644 --- a/src/test/moves/substitute.test.ts +++ b/src/test/moves/substitute.test.ts @@ -38,7 +38,7 @@ describe("Moves - Substitute", () => { game.override .battleType("single") - .moveset([Moves.SUBSTITUTE, Moves.SWORDS_DANCE, Moves.TACKLE, Moves.SPLASH]) + .moveset([ Moves.SUBSTITUTE, Moves.SWORDS_DANCE, Moves.TACKLE, Moves.SPLASH ]) .enemySpecies(Species.SNORLAX) .enemyAbility(Abilities.INSOMNIA) .enemyMoveset(Moves.SPLASH) @@ -49,7 +49,7 @@ describe("Moves - Substitute", () => { it( "should cause the user to take damage", async () => { - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -57,7 +57,7 @@ describe("Moves - Substitute", () => { await game.phaseInterceptor.to("MoveEndPhase", false); - expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() * 3/4)); + expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() * 3 / 4)); } ); @@ -66,7 +66,7 @@ describe("Moves - Substitute", () => { async () => { game.override.enemyMoveset(Moves.TACKLE); - await game.classicMode.startBattle([Species.SKARMORY]); + await game.classicMode.startBattle([ Species.SKARMORY ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -74,7 +74,7 @@ describe("Moves - Substitute", () => { await game.phaseInterceptor.to("MoveEndPhase", false); - expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() * 3/4)); + expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() * 3 / 4)); expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeDefined(); const postSubHp = leadPokemon.hp; @@ -92,7 +92,7 @@ describe("Moves - Substitute", () => { game.override.enemyMoveset(Moves.GIGA_IMPACT); vi.spyOn(allMoves[Moves.GIGA_IMPACT], "accuracy", "get").mockReturnValue(100); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -100,7 +100,7 @@ describe("Moves - Substitute", () => { await game.phaseInterceptor.to("MoveEndPhase", false); - expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() * 3/4)); + expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() * 3 / 4)); expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeDefined(); const postSubHp = leadPokemon.hp; @@ -116,7 +116,7 @@ describe("Moves - Substitute", () => { async () => { game.override.enemyMoveset(Moves.CHARM); - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -134,7 +134,7 @@ describe("Moves - Substitute", () => { async () => { game.override.enemyMoveset(Moves.ECHOED_VOICE); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -158,7 +158,7 @@ describe("Moves - Substitute", () => { game.override.enemyMoveset(Moves.TACKLE); game.override.enemyAbility(Abilities.INFILTRATOR); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -179,7 +179,7 @@ describe("Moves - Substitute", () => { it( "shouldn't block the user's own status moves", async () => { - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -201,7 +201,7 @@ describe("Moves - Substitute", () => { async () => { game.override.moveset(Moves.LIGHT_SCREEN); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(leadPokemon, "getMoveEffectiveness"); @@ -222,7 +222,7 @@ describe("Moves - Substitute", () => { async () => { game.override.enemyMoveset(Moves.STEALTH_ROCK); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; vi.spyOn(leadPokemon, "getMoveEffectiveness"); @@ -243,7 +243,7 @@ describe("Moves - Substitute", () => { .moveset(Moves.TRICK_ROOM) .enemyMoveset(Moves.GRAVITY); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const pokemon = game.scene.getField(true); pokemon.forEach(p => { @@ -267,7 +267,7 @@ describe("Moves - Substitute", () => { game.override.enemyMoveset(Moves.FAKE_OUT); game.override.startingLevel(1); // Ensures the Substitute will break - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -288,7 +288,7 @@ describe("Moves - Substitute", () => { vi.spyOn(allMoves[Moves.SAND_TOMB], "accuracy", "get").mockReturnValue(100); game.override.enemyMoveset(Moves.SAND_TOMB); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -308,7 +308,7 @@ describe("Moves - Substitute", () => { vi.spyOn(allMoves[Moves.LIQUIDATION], "chance", "get").mockReturnValue(100); game.override.enemyMoveset(Moves.LIQUIDATION); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -327,7 +327,7 @@ describe("Moves - Substitute", () => { async () => { game.override.enemyMoveset(Moves.NUZZLE); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -345,10 +345,10 @@ describe("Moves - Substitute", () => { "should prevent the user's items from being stolen", async () => { game.override.enemyMoveset(Moves.THIEF); - vi.spyOn(allMoves[Moves.THIEF], "attrs", "get").mockReturnValue([new StealHeldItemChanceAttr(1.0)]); // give Thief 100% steal rate - game.override.startingHeldItems([{name: "BERRY", type: BerryType.SITRUS}]); + vi.spyOn(allMoves[Moves.THIEF], "attrs", "get").mockReturnValue([ new StealHeldItemChanceAttr(1.0) ]); // give Thief 100% steal rate + game.override.startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS }]); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -365,10 +365,10 @@ describe("Moves - Substitute", () => { it( "should prevent the user's items from being removed", async () => { - game.override.moveset([Moves.KNOCK_OFF]); - game.override.enemyHeldItems([{name: "BERRY", type: BerryType.SITRUS}]); + game.override.moveset([ Moves.KNOCK_OFF ]); + game.override.enemyHeldItems([{ name: "BERRY", type: BerryType.SITRUS }]); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -387,9 +387,9 @@ describe("Moves - Substitute", () => { "move effect should prevent the user's berries from being stolen and eaten", async () => { game.override.enemyMoveset(Moves.BUG_BITE); - game.override.startingHeldItems([{name: "BERRY", type: BerryType.SITRUS}]); + game.override.startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS }]); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -413,7 +413,7 @@ describe("Moves - Substitute", () => { async () => { game.override.enemyMoveset(Moves.CLEAR_SMOG); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -433,7 +433,7 @@ describe("Moves - Substitute", () => { game.override.enemyMoveset(Moves.MAGICAL_TORQUE); vi.spyOn(allMoves[Moves.MAGICAL_TORQUE], "chance", "get").mockReturnValue(100); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -451,9 +451,9 @@ describe("Moves - Substitute", () => { it( "should transfer to the switched in Pokemon when the source uses Baton Pass", async () => { - game.override.moveset([Moves.SUBSTITUTE, Moves.BATON_PASS]); + game.override.moveset([ Moves.SUBSTITUTE, Moves.BATON_PASS ]); - await game.classicMode.startBattle([Species.BLASTOISE, Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); const leadPokemon = game.scene.getPlayerPokemon()!; @@ -469,7 +469,7 @@ describe("Moves - Substitute", () => { const switchedPokemon = game.scene.getPlayerPokemon()!; const subTag = switchedPokemon.getTag(SubstituteTag)!; expect(subTag).toBeDefined(); - expect(subTag.hp).toBe(Math.floor(leadPokemon.getMaxHp() * 1/4)); + expect(subTag.hp).toBe(Math.floor(leadPokemon.getMaxHp() * 1 / 4)); } ); @@ -479,7 +479,7 @@ describe("Moves - Substitute", () => { game.override.enemyMoveset(Moves.TACKLE); game.override.ability(Abilities.ROUGH_SKIN); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -495,12 +495,12 @@ describe("Moves - Substitute", () => { "should prevent the source's Focus Punch from failing when hit", async () => { game.override.enemyMoveset(Moves.TACKLE); - game.override.moveset([Moves.FOCUS_PUNCH]); + game.override.moveset([ Moves.FOCUS_PUNCH ]); // Make Focus Punch 40 power to avoid a KO vi.spyOn(allMoves[Moves.FOCUS_PUNCH], "calculateBattlePower").mockReturnValue(40); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -520,9 +520,9 @@ describe("Moves - Substitute", () => { "should not allow Shell Trap to activate when attacked", async () => { game.override.enemyMoveset(Moves.TACKLE); - game.override.moveset([Moves.SHELL_TRAP]); + game.override.moveset([ Moves.SHELL_TRAP ]); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerPokemon()!; @@ -540,9 +540,9 @@ describe("Moves - Substitute", () => { "should not allow Beak Blast to burn opponents when hit", async () => { game.override.enemyMoveset(Moves.TACKLE); - game.override.moveset([Moves.BEAK_BLAST]); + game.override.moveset([ Moves.BEAK_BLAST ]); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -561,9 +561,9 @@ describe("Moves - Substitute", () => { "should cause incoming attacks to not activate Counter", async () => { game.override.enemyMoveset(Moves.TACKLE); - game.override.moveset([Moves.COUNTER]); + game.override.moveset([ Moves.COUNTER ]); - await game.classicMode.startBattle([Species.BLASTOISE]); + await game.classicMode.startBattle([ Species.BLASTOISE ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -584,7 +584,7 @@ describe("Moves - Substitute", () => { async () => { game.override.enemyMoveset(Moves.SAPPY_SEED); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); const playerPokemon = game.scene.getPlayerPokemon()!; @@ -592,7 +592,7 @@ describe("Moves - Substitute", () => { game.move.select(Moves.SPLASH); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); // enemy uses Sappy Seed first + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); // enemy uses Sappy Seed first await game.move.forceHit(); // forces Sappy Seed to hit await game.phaseInterceptor.to("MoveEndPhase"); diff --git a/src/test/moves/swallow.test.ts b/src/test/moves/swallow.test.ts index b8ca941d0ee..2aee4d2604a 100644 --- a/src/test/moves/swallow.test.ts +++ b/src/test/moves/swallow.test.ts @@ -33,7 +33,7 @@ describe("Moves - Swallow", () => { game.override.enemyAbility(Abilities.NONE); game.override.enemyLevel(2000); - game.override.moveset([Moves.SWALLOW, Moves.SWALLOW, Moves.SWALLOW, Moves.SWALLOW]); + game.override.moveset([ Moves.SWALLOW, Moves.SWALLOW, Moves.SWALLOW, Moves.SWALLOW ]); game.override.ability(Abilities.NONE); }); @@ -42,7 +42,7 @@ describe("Moves - Swallow", () => { const stacksToSetup = 1; const expectedHeal = 25; - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; vi.spyOn(pokemon, "getMaxHp").mockReturnValue(100); @@ -69,7 +69,7 @@ describe("Moves - Swallow", () => { const stacksToSetup = 2; const expectedHeal = 50; - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; vi.spyOn(pokemon, "getMaxHp").mockReturnValue(100); @@ -97,7 +97,7 @@ describe("Moves - Swallow", () => { const stacksToSetup = 3; const expectedHeal = 100; - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; vi.spyOn(pokemon, "getMaxHp").mockReturnValue(100); @@ -124,7 +124,7 @@ describe("Moves - Swallow", () => { }); it("fails without stacks", async () => { - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; @@ -139,7 +139,7 @@ describe("Moves - Swallow", () => { describe("restores stat stage boosts granted by stacks", () => { it("decreases stats based on stored values (both boosts equal)", async () => { - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; pokemon.addTag(BattlerTagType.STOCKPILING); @@ -164,7 +164,7 @@ describe("Moves - Swallow", () => { }); it("lower stat stages based on stored values (different boosts)", async () => { - await game.startBattle([Species.ABOMASNOW]); + await game.startBattle([ Species.ABOMASNOW ]); const pokemon = game.scene.getPlayerPokemon()!; pokemon.addTag(BattlerTagType.STOCKPILING); diff --git a/src/test/moves/syrup_bomb.test.ts b/src/test/moves/syrup_bomb.test.ts index 20cd590e457..ea2f8b6bab3 100644 --- a/src/test/moves/syrup_bomb.test.ts +++ b/src/test/moves/syrup_bomb.test.ts @@ -1,4 +1,3 @@ -import { allMoves } from "#app/data/move"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { Abilities } from "#enums/abilities"; @@ -7,7 +6,7 @@ import { Stat } from "#enums/stat"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { BattlerIndex } from "#app/battle"; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - SYRUP BOMB", () => { let phaserGame: Phaser.Game; @@ -26,26 +25,27 @@ describe("Moves - SYRUP BOMB", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .starterSpecies(Species.MAGIKARP) + .battleType("single") .enemySpecies(Species.SNORLAX) + .enemyAbility(Abilities.BALL_FETCH) + .ability(Abilities.BALL_FETCH) .startingLevel(30) .enemyLevel(100) - .moveset([Moves.SYRUP_BOMB, Moves.SPLASH]) + .moveset([ Moves.SYRUP_BOMB, Moves.SPLASH ]) .enemyMoveset(Moves.SPLASH); - vi.spyOn(allMoves[Moves.SYRUP_BOMB], "accuracy", "get").mockReturnValue(100); }); //Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/syrup_bomb_(move) it("decreases the target Pokemon's speed stat once per turn for 3 turns", async () => { - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const targetPokemon = game.scene.getEnemyPokemon()!; expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0); game.move.select(Moves.SYRUP_BOMB); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.move.forceHit(); await game.toNextTurn(); expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeDefined(); @@ -66,12 +66,12 @@ describe("Moves - SYRUP BOMB", () => { it("does not affect Pokemon with the ability Bulletproof", async () => { game.override.enemyAbility(Abilities.BULLETPROOF); - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const targetPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.SYRUP_BOMB); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.move.forceHit(); await game.toNextTurn(); expect(targetPokemon.isFullHp()).toBe(true); @@ -79,4 +79,18 @@ describe("Moves - SYRUP BOMB", () => { expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0); } ); + + it("stops lowering the target's speed if the user leaves the field", async () => { + await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]); + + game.move.select(Moves.SYRUP_BOMB); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.move.forceHit(); + await game.toNextTurn(); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.SPD)).toBe(-1); + }); }); diff --git a/src/test/moves/tackle.test.ts b/src/test/moves/tackle.test.ts index b25c7524a1a..5d5ff1a366d 100644 --- a/src/test/moves/tackle.test.ts +++ b/src/test/moves/tackle.test.ts @@ -29,8 +29,8 @@ describe("Moves - Tackle", () => { game.override.enemySpecies(Species.MAGIKARP); game.override.startingLevel(1); game.override.startingWave(97); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.GROWTH, Moves.GROWTH, Moves.GROWTH, Moves.GROWTH]); + game.override.moveset([ moveToUse ]); + game.override.enemyMoveset([ Moves.GROWTH, Moves.GROWTH, Moves.GROWTH, Moves.GROWTH ]); game.override.disableCrits(); }); diff --git a/src/test/moves/tailwind.test.ts b/src/test/moves/tailwind.test.ts index 6a08cfe802f..a26dde82824 100644 --- a/src/test/moves/tailwind.test.ts +++ b/src/test/moves/tailwind.test.ts @@ -25,12 +25,12 @@ describe("Moves - Tailwind", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("double"); - game.override.moveset([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]); + game.override.moveset([ Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM ]); game.override.enemyMoveset(Moves.SPLASH); }); it("doubles the Speed stat of the Pokemons on its side", async () => { - await game.startBattle([Species.MAGIKARP, Species.MEOWTH]); + await game.startBattle([ Species.MAGIKARP, Species.MEOWTH ]); const magikarp = game.scene.getPlayerField()[0]; const meowth = game.scene.getPlayerField()[1]; @@ -53,7 +53,7 @@ describe("Moves - Tailwind", () => { it("lasts for 4 turns", async () => { game.override.battleType("single"); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.TAILWIND); await game.toNextTurn(); @@ -76,7 +76,7 @@ describe("Moves - Tailwind", () => { it("does not affect the opposing side", async () => { game.override.battleType("single"); - await game.startBattle([Species.MAGIKARP]); + await game.startBattle([ Species.MAGIKARP ]); const ally = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; diff --git a/src/test/moves/tar_shot.test.ts b/src/test/moves/tar_shot.test.ts index 2385bd18265..4734da366e4 100644 --- a/src/test/moves/tar_shot.test.ts +++ b/src/test/moves/tar_shot.test.ts @@ -29,12 +29,12 @@ describe("Moves - Tar Shot", () => { .enemyMoveset(Moves.SPLASH) .enemySpecies(Species.TANGELA) .enemyLevel(1000) - .moveset([Moves.TAR_SHOT, Moves.FIRE_PUNCH]) + .moveset([ Moves.TAR_SHOT, Moves.FIRE_PUNCH ]) .disableCrits(); }); it("lowers the target's Speed stat by one stage and doubles the effectiveness of Fire-type moves used on the target", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const enemy = game.scene.getEnemyPokemon()!; @@ -48,14 +48,14 @@ describe("Moves - Tar Shot", () => { await game.toNextTurn(); game.move.select(Moves.FIRE_PUNCH); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); }); it("will not double the effectiveness of Fire-type moves used on a target that is already under the effect of Tar Shot (but may still lower its Speed)", async () => { - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const enemy = game.scene.getEnemyPokemon()!; @@ -76,7 +76,7 @@ describe("Moves - Tar Shot", () => { await game.toNextTurn(); game.move.select(Moves.FIRE_PUNCH); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); @@ -84,7 +84,7 @@ describe("Moves - Tar Shot", () => { it("does not double the effectiveness of Fire-type moves against a Pokémon that is Terastallized", async () => { game.override.enemyHeldItems([{ name: "TERA_SHARD", type: Type.GRASS }]).enemySpecies(Species.SPRIGATITO); - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const enemy = game.scene.getEnemyPokemon()!; @@ -98,7 +98,7 @@ describe("Moves - Tar Shot", () => { await game.toNextTurn(); game.move.select(Moves.FIRE_PUNCH); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); @@ -106,7 +106,7 @@ describe("Moves - Tar Shot", () => { it("doubles the effectiveness of Fire-type moves against a Pokémon that is already under the effects of Tar Shot before it Terastallized", async () => { game.override.enemySpecies(Species.SPRIGATITO); - await game.classicMode.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([ Species.PIKACHU ]); const enemy = game.scene.getEnemyPokemon()!; @@ -122,7 +122,7 @@ describe("Moves - Tar Shot", () => { game.override.enemyHeldItems([{ name: "TERA_SHARD", type: Type.GRASS }]); game.move.select(Moves.FIRE_PUNCH); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); diff --git a/src/test/moves/taunt.test.ts b/src/test/moves/taunt.test.ts index 50bb2fee9df..a425a048a2c 100644 --- a/src/test/moves/taunt.test.ts +++ b/src/test/moves/taunt.test.ts @@ -25,13 +25,13 @@ describe("Moves - Taunt", () => { game.override .battleType("single") .enemyAbility(Abilities.BALL_FETCH) - .enemyMoveset([Moves.TAUNT, Moves.SPLASH]) + .enemyMoveset([ Moves.TAUNT, Moves.SPLASH ]) .enemySpecies(Species.SHUCKLE) - .moveset([Moves.GROWL]); + .moveset([ Moves.GROWL ]); }); it("Pokemon should not be able to use Status Moves", async () => { - await game.classicMode.startBattle([Species.REGIELEKI]); + await game.classicMode.startBattle([ Species.REGIELEKI ]); const playerPokemon = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/telekinesis.test.ts b/src/test/moves/telekinesis.test.ts new file mode 100644 index 00000000000..76c0d001f00 --- /dev/null +++ b/src/test/moves/telekinesis.test.ts @@ -0,0 +1,124 @@ +import { BattlerTagType } from "#enums/battler-tag-type"; +import { allMoves } from "#app/data/move"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { MoveResult } from "#app/field/pokemon"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Telekinesis", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.TELEKINESIS, Moves.TACKLE, Moves.MUD_SHOT, Moves.SMACK_DOWN ]) + .battleType("single") + .enemySpecies(Species.SNORLAX) + .enemyLevel(60) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset([ Moves.SPLASH ]); + }); + + it("Telekinesis makes the affected vulnerable to most attacking moves regardless of accuracy", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + + await game.toNextTurn(); + vi.spyOn(allMoves[Moves.TACKLE], "accuracy", "get").mockReturnValue(0); + game.move.select(Moves.TACKLE); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.isFullHp()).toBe(false); + }); + + it("Telekinesis makes the affected airborne and immune to most Ground-moves", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + + await game.toNextTurn(); + vi.spyOn(allMoves[Moves.MUD_SHOT], "accuracy", "get").mockReturnValue(100); + game.move.select(Moves.MUD_SHOT); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.isFullHp()).toBe(true); + }); + + it("Telekinesis can still affect Pokemon that have been transformed into invalid Pokemon", async () => { + game.override.enemyMoveset(Moves.TRANSFORM); + await game.classicMode.startBattle([ Species.DIGLETT ]); + + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + expect(enemyOpponent.summonData.speciesForm?.speciesId).toBe(Species.DIGLETT); + }); + + it("Moves like Smack Down and 1000 Arrows remove all effects of Telekinesis from the target Pokemon", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + + await game.toNextTurn(); + game.move.select(Moves.SMACK_DOWN); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeUndefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeUndefined(); + }); + + it("Ingrain will remove the floating effect of Telekinesis, but not the 100% hit", async () => { + game.override.enemyMoveset([ Moves.SPLASH, Moves.INGRAIN ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + + await game.toNextTurn(); + vi.spyOn(allMoves[Moves.MUD_SHOT], "accuracy", "get").mockReturnValue(0); + game.move.select(Moves.MUD_SHOT); + await game.forceEnemyMove(Moves.INGRAIN); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.INGRAIN)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeUndefined(); + expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS); + }); +}); diff --git a/src/test/moves/tera_blast.test.ts b/src/test/moves/tera_blast.test.ts index 55d61496297..0ce8a552105 100644 --- a/src/test/moves/tera_blast.test.ts +++ b/src/test/moves/tera_blast.test.ts @@ -32,7 +32,7 @@ describe("Moves - Tera Blast", () => { .battleType("single") .disableCrits() .starterSpecies(Species.FEEBAS) - .moveset([Moves.TERA_BLAST]) + .moveset([ Moves.TERA_BLAST ]) .ability(Abilities.BALL_FETCH) .startingHeldItems([{ name: "TERA_SHARD", type: Type.FIRE }]) .enemySpecies(Species.MAGIKARP) @@ -52,7 +52,7 @@ describe("Moves - Tera Blast", () => { vi.spyOn(enemyPokemon, "apply"); game.move.select(Moves.TERA_BLAST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.SUPER_EFFECTIVE); @@ -64,7 +64,7 @@ describe("Moves - Tera Blast", () => { await game.startBattle(); game.move.select(Moves.TERA_BLAST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(100); @@ -80,7 +80,7 @@ describe("Moves - Tera Blast", () => { vi.spyOn(enemyPokemon, "isTerastallized").mockReturnValue(true); game.move.select(Moves.TERA_BLAST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.SUPER_EFFECTIVE); @@ -107,7 +107,7 @@ describe("Moves - Tera Blast", () => { const playerPokemon = game.scene.getPlayerPokemon()!; game.move.select(Moves.TERA_BLAST); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1); diff --git a/src/test/moves/tera_starstorm.test.ts b/src/test/moves/tera_starstorm.test.ts new file mode 100644 index 00000000000..f0759dd242d --- /dev/null +++ b/src/test/moves/tera_starstorm.test.ts @@ -0,0 +1,98 @@ +import { BattlerIndex } from "#app/battle"; +import { Type } from "#app/data/type"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Tera Starstorm", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.TERA_STARSTORM, Moves.SPLASH ]) + .battleType("double") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .enemyLevel(30) + .enemySpecies(Species.MAGIKARP) + .startingHeldItems([{ name: "TERA_SHARD", type: Type.FIRE }]); + }); + + it("changes type to Stellar when used by Terapagos in its Stellar Form", async () => { + game.override.battleType("single"); + await game.classicMode.startBattle([ Species.TERAPAGOS ]); + + const terapagos = game.scene.getPlayerPokemon()!; + + vi.spyOn(terapagos, "getMoveType"); + + game.move.select(Moves.TERA_STARSTORM); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(terapagos.isTerastallized()).toBe(true); + expect(terapagos.getMoveType).toHaveReturnedWith(Type.STELLAR); + }); + + it("targets both opponents in a double battle when used by Terapagos in its Stellar Form", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP, Species.TERAPAGOS ]); + + game.move.select(Moves.TERA_STARSTORM, 0, BattlerIndex.ENEMY); + game.move.select(Moves.TERA_STARSTORM, 1); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + + const enemyField = game.scene.getEnemyField(); + + // Pokemon other than Terapagos should not be affected - only hits one target + await game.phaseInterceptor.to("MoveEndPhase"); + expect(enemyField.some(pokemon => pokemon.isFullHp())).toBe(true); + + // Terapagos in Stellar Form should hit both targets + await game.phaseInterceptor.to("MoveEndPhase"); + expect(enemyField.every(pokemon => pokemon.isFullHp())).toBe(false); + }); + + it("applies the effects when Terapagos in Stellar Form is fused with another Pokemon", async () => { + await game.classicMode.startBattle([ Species.TERAPAGOS, Species.CHARMANDER, Species.MAGIKARP ]); + + const fusionedMon = game.scene.getParty()[0]; + const magikarp = game.scene.getParty()[2]; + + // Fuse party members (taken from PlayerPokemon.fuse(...) function) + fusionedMon.fusionSpecies = magikarp.species; + fusionedMon.fusionFormIndex = magikarp.formIndex; + fusionedMon.fusionAbilityIndex = magikarp.abilityIndex; + fusionedMon.fusionShiny = magikarp.shiny; + fusionedMon.fusionVariant = magikarp.variant; + fusionedMon.fusionGender = magikarp.gender; + fusionedMon.fusionLuck = magikarp.luck; + + vi.spyOn(fusionedMon, "getMoveType"); + + game.move.select(Moves.TERA_STARSTORM, 0); + game.move.select(Moves.SPLASH, 1); + await game.phaseInterceptor.to("TurnEndPhase"); + + // Fusion and terastallized + expect(fusionedMon.isFusion()).toBe(true); + expect(fusionedMon.isTerastallized()).toBe(true); + // Move effects should be applied + expect(fusionedMon.getMoveType).toHaveReturnedWith(Type.STELLAR); + expect(game.scene.getEnemyField().every(pokemon => pokemon.isFullHp())).toBe(false); + }); +}); diff --git a/src/test/moves/thousand_arrows.test.ts b/src/test/moves/thousand_arrows.test.ts index ad9281dc45e..976b4352ee4 100644 --- a/src/test/moves/thousand_arrows.test.ts +++ b/src/test/moves/thousand_arrows.test.ts @@ -9,7 +9,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - Thousand Arrows", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -30,14 +29,14 @@ describe("Moves - Thousand Arrows", () => { game.override.enemySpecies(Species.TOGETIC); game.override.startingLevel(100); game.override.enemyLevel(100); - game.override.moveset([Moves.THOUSAND_ARROWS]); - game.override.enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.moveset([ Moves.THOUSAND_ARROWS ]); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); }); it( "move should hit and ground Flying-type targets", async () => { - await game.startBattle([Species.ILLUMISE]); + await game.startBattle([ Species.ILLUMISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -60,7 +59,7 @@ describe("Moves - Thousand Arrows", () => { game.override.enemySpecies(Species.SNORLAX); game.override.enemyAbility(Abilities.LEVITATE); - await game.startBattle([Species.ILLUMISE]); + await game.startBattle([ Species.ILLUMISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -82,17 +81,17 @@ describe("Moves - Thousand Arrows", () => { async () => { game.override.enemySpecies(Species.SNORLAX); - await game.startBattle([Species.ILLUMISE]); + await game.startBattle([ Species.ILLUMISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; - enemyPokemon.addTag(BattlerTagType.MAGNET_RISEN, undefined, Moves.MAGNET_RISE); + enemyPokemon.addTag(BattlerTagType.FLOATING, undefined, Moves.MAGNET_RISE); game.move.select(Moves.THOUSAND_ARROWS); await game.phaseInterceptor.to(BerryPhase, false); - expect(enemyPokemon.getTag(BattlerTagType.MAGNET_RISEN)).toBeUndefined(); + expect(enemyPokemon.getTag(BattlerTagType.FLOATING)).toBeUndefined(); expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined(); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); } diff --git a/src/test/moves/throat_chop.test.ts b/src/test/moves/throat_chop.test.ts index 2a0ab675b25..24293f8d086 100644 --- a/src/test/moves/throat_chop.test.ts +++ b/src/test/moves/throat_chop.test.ts @@ -32,12 +32,12 @@ describe("Moves - Throat Chop", () => { }); it("prevents the target from using sound-based moves for two turns", async () => { - await game.classicMode.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const enemy = game.scene.getEnemyPokemon()!; game.move.select(Moves.GROWL); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); // First turn, move is interrupted await game.phaseInterceptor.to("TurnEndPhase"); @@ -47,7 +47,7 @@ describe("Moves - Throat Chop", () => { await game.toNextTurn(); game.move.select(Moves.GROWL); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.isFullHp()).toBe(false); diff --git a/src/test/moves/thunder_wave.test.ts b/src/test/moves/thunder_wave.test.ts index 28c5da4717b..03e9ebb94f3 100644 --- a/src/test/moves/thunder_wave.test.ts +++ b/src/test/moves/thunder_wave.test.ts @@ -8,7 +8,6 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; - describe("Moves - Thunder Wave", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -28,7 +27,7 @@ describe("Moves - Thunder Wave", () => { game.override .battleType("single") .starterSpecies(Species.PIKACHU) - .moveset([Moves.THUNDER_WAVE]) + .moveset([ Moves.THUNDER_WAVE ]) .enemyMoveset(Moves.SPLASH); }); diff --git a/src/test/moves/tidy_up.test.ts b/src/test/moves/tidy_up.test.ts index 8a3a0f3be76..255967b40ac 100644 --- a/src/test/moves/tidy_up.test.ts +++ b/src/test/moves/tidy_up.test.ts @@ -33,13 +33,13 @@ describe("Moves - Tidy Up", () => { game.override.enemyMoveset(Moves.SPLASH); game.override.starterSpecies(Species.FEEBAS); game.override.ability(Abilities.BALL_FETCH); - game.override.moveset([Moves.TIDY_UP]); + game.override.moveset([ Moves.TIDY_UP ]); game.override.startingLevel(50); }); it("spikes are cleared", async () => { - game.override.moveset([Moves.SPIKES, Moves.TIDY_UP]); - game.override.enemyMoveset([Moves.SPIKES, Moves.SPIKES, Moves.SPIKES, Moves.SPIKES]); + game.override.moveset([ Moves.SPIKES, Moves.TIDY_UP ]); + game.override.enemyMoveset([ Moves.SPIKES, Moves.SPIKES, Moves.SPIKES, Moves.SPIKES ]); await game.classicMode.startBattle(); game.move.select(Moves.SPIKES); @@ -51,8 +51,8 @@ describe("Moves - Tidy Up", () => { }, 20000); it("stealth rocks are cleared", async () => { - game.override.moveset([Moves.STEALTH_ROCK, Moves.TIDY_UP]); - game.override.enemyMoveset([Moves.STEALTH_ROCK, Moves.STEALTH_ROCK, Moves.STEALTH_ROCK, Moves.STEALTH_ROCK]); + game.override.moveset([ Moves.STEALTH_ROCK, Moves.TIDY_UP ]); + game.override.enemyMoveset([ Moves.STEALTH_ROCK, Moves.STEALTH_ROCK, Moves.STEALTH_ROCK, Moves.STEALTH_ROCK ]); await game.classicMode.startBattle(); game.move.select(Moves.STEALTH_ROCK); @@ -63,8 +63,8 @@ describe("Moves - Tidy Up", () => { }, 20000); it("toxic spikes are cleared", async () => { - game.override.moveset([Moves.TOXIC_SPIKES, Moves.TIDY_UP]); - game.override.enemyMoveset([Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES]); + game.override.moveset([ Moves.TOXIC_SPIKES, Moves.TIDY_UP ]); + game.override.enemyMoveset([ Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES ]); await game.classicMode.startBattle(); game.move.select(Moves.TOXIC_SPIKES); @@ -75,8 +75,8 @@ describe("Moves - Tidy Up", () => { }, 20000); it("sticky webs are cleared", async () => { - game.override.moveset([Moves.STICKY_WEB, Moves.TIDY_UP]); - game.override.enemyMoveset([Moves.STICKY_WEB, Moves.STICKY_WEB, Moves.STICKY_WEB, Moves.STICKY_WEB]); + game.override.moveset([ Moves.STICKY_WEB, Moves.TIDY_UP ]); + game.override.enemyMoveset([ Moves.STICKY_WEB, Moves.STICKY_WEB, Moves.STICKY_WEB, Moves.STICKY_WEB ]); await game.classicMode.startBattle(); @@ -88,8 +88,8 @@ describe("Moves - Tidy Up", () => { }, 20000); it("substitutes are cleared", async () => { - game.override.moveset([Moves.SUBSTITUTE, Moves.TIDY_UP]); - game.override.enemyMoveset([Moves.SUBSTITUTE, Moves.SUBSTITUTE, Moves.SUBSTITUTE, Moves.SUBSTITUTE]); + game.override.moveset([ Moves.SUBSTITUTE, Moves.TIDY_UP ]); + game.override.enemyMoveset([ Moves.SUBSTITUTE, Moves.SUBSTITUTE, Moves.SUBSTITUTE, Moves.SUBSTITUTE ]); await game.classicMode.startBattle(); diff --git a/src/test/moves/torment.test.ts b/src/test/moves/torment.test.ts index f725f2bc34a..b4c9a059db1 100644 --- a/src/test/moves/torment.test.ts +++ b/src/test/moves/torment.test.ts @@ -26,15 +26,15 @@ describe("Moves - Torment", () => { game.override .battleType("single") .enemyAbility(Abilities.BALL_FETCH) - .enemyMoveset([Moves.TORMENT, Moves.SPLASH]) + .enemyMoveset([ Moves.TORMENT, Moves.SPLASH ]) .enemySpecies(Species.SHUCKLE) .enemyLevel(30) - .moveset([Moves.TACKLE]) + .moveset([ Moves.TACKLE ]) .ability(Abilities.BALL_FETCH); }); it("Pokemon should not be able to use the same move consecutively", async () => { - await game.classicMode.startBattle([Species.CHANSEY]); + await game.classicMode.startBattle([ Species.CHANSEY ]); const playerPokemon = game.scene.getPlayerPokemon()!; diff --git a/src/test/moves/toxic.test.ts b/src/test/moves/toxic.test.ts new file mode 100644 index 00000000000..b146134ae51 --- /dev/null +++ b/src/test/moves/toxic.test.ts @@ -0,0 +1,89 @@ +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { StatusEffect } from "#enums/status-effect"; +import { BattlerIndex } from "#app/battle"; +import { allMoves } from "#app/data/move"; + +describe("Moves - Toxic", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleType("single") + .moveset(Moves.TOXIC) + .enemySpecies(Species.MAGIKARP) + .enemyMoveset(Moves.SPLASH); + }); + + it("should be guaranteed to hit if user is Poison-type", async () => { + vi.spyOn(allMoves[Moves.TOXIC], "accuracy", "get").mockReturnValue(0); + await game.classicMode.startBattle([ Species.TOXAPEX ]); + + game.move.select(Moves.TOXIC); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(game.scene.getEnemyPokemon()!.status?.effect).toBe(StatusEffect.TOXIC); + }); + + it("may miss if user is not Poison-type", async () => { + vi.spyOn(allMoves[Moves.TOXIC], "accuracy", "get").mockReturnValue(0); + await game.classicMode.startBattle([ Species.UMBREON ]); + + game.move.select(Moves.TOXIC); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(game.scene.getEnemyPokemon()!.status).toBeUndefined(); + }); + + it("should hit semi-invulnerable targets if user is Poison-type", async () => { + vi.spyOn(allMoves[Moves.TOXIC], "accuracy", "get").mockReturnValue(0); + game.override.enemyMoveset(Moves.FLY); + await game.classicMode.startBattle([ Species.TOXAPEX ]); + + game.move.select(Moves.TOXIC); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(game.scene.getEnemyPokemon()!.status?.effect).toBe(StatusEffect.TOXIC); + }); + + it("should miss semi-invulnerable targets if user is not Poison-type", async () => { + vi.spyOn(allMoves[Moves.TOXIC], "accuracy", "get").mockReturnValue(-1); + game.override.enemyMoveset(Moves.FLY); + await game.classicMode.startBattle([ Species.UMBREON ]); + + game.move.select(Moves.TOXIC); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(game.scene.getEnemyPokemon()!.status).toBeUndefined(); + }); + + it("moves other than Toxic should not hit semi-invulnerable targets even if user is Poison-type", async () => { + game.override.moveset(Moves.SWIFT); + game.override.enemyMoveset(Moves.FLY); + await game.classicMode.startBattle([ Species.TOXAPEX ]); + + game.move.select(Moves.SWIFT); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + }); +}); diff --git a/src/test/moves/toxic_spikes.test.ts b/src/test/moves/toxic_spikes.test.ts new file mode 100644 index 00000000000..a5c63a2652f --- /dev/null +++ b/src/test/moves/toxic_spikes.test.ts @@ -0,0 +1,139 @@ +import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag"; +import { StatusEffect } from "#app/data/status-effect"; +import { decrypt, encrypt, GameData, SessionSaveData } from "#app/system/game-data"; +import { Abilities } from "#enums/abilities"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Toxic Spikes", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleType("single") + .startingWave(5) + .enemySpecies(Species.RATTATA) + .enemyAbility(Abilities.BALL_FETCH) + .ability(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .moveset([ Moves.TOXIC_SPIKES, Moves.SPLASH, Moves.ROAR, Moves.COURT_CHANGE ]); + }); + + it("should not affect the opponent if they do not switch", async () => { + await game.classicMode.runToSummon([ Species.MIGHTYENA, Species.POOCHYENA ]); + + const enemy = game.scene.getEnemyField()[0]; + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + game.doSwitchPokemon(1); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(enemy.hp).toBe(enemy.getMaxHp()); + expect(enemy.status?.effect).toBeUndefined(); + }); + + it("should poison the opponent if they switch into 1 layer", async () => { + await game.classicMode.runToSummon([ Species.MIGHTYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.ROAR); + await game.phaseInterceptor.to("TurnEndPhase"); + + const enemy = game.scene.getEnemyField()[0]; + + expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); + expect(enemy.status?.effect).toBe(StatusEffect.POISON); + }); + + it("should badly poison the opponent if they switch into 2 layers", async () => { + await game.classicMode.runToSummon([ Species.MIGHTYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.ROAR); + await game.phaseInterceptor.to("TurnEndPhase"); + + const enemy = game.scene.getEnemyField()[0]; + expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); + expect(enemy.status?.effect).toBe(StatusEffect.TOXIC); + }); + + it("should be removed if a grounded poison pokemon switches in", async () => { + await game.classicMode.runToSummon([ Species.MUK, Species.PIDGEY ]); + + const muk = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.TOXIC_SPIKES); + await game.toNextTurn(); + // also make sure the toxic spikes are removed even if the pokemon + // that set them up is the one switching in (https://github.com/pagefaultgames/pokerogue/issues/935) + game.move.select(Moves.COURT_CHANGE); + await game.toNextTurn(); + game.doSwitchPokemon(1); + await game.toNextTurn(); + game.doSwitchPokemon(1); + await game.toNextTurn(); + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(muk.isFullHp()).toBe(true); + expect(muk.status?.effect).toBeUndefined(); + expect(game.scene.arena.tags.length).toBe(0); + }); + + it("shouldn't create multiple layers per use in doubles", async () => { + await game.classicMode.runToSummon([ Species.MIGHTYENA, Species.POOCHYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + + const arenaTags = (game.scene.arena.getTagOnSide(ArenaTagType.TOXIC_SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag); + expect(arenaTags.tagType).toBe(ArenaTagType.TOXIC_SPIKES); + expect(arenaTags.layers).toBe(1); + }); + + it("should persist through reload", async () => { + game.override.startingWave(1); + const scene = game.scene; + const gameData = new GameData(scene); + + await game.classicMode.runToSummon([ Species.MIGHTYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.phaseInterceptor.to("BattleEndPhase"); + await game.toNextWave(); + + const sessionData : SessionSaveData = gameData["getSessionSaveData"](game.scene); + localStorage.setItem("sessionTestData", encrypt(JSON.stringify(sessionData), true)); + const recoveredData : SessionSaveData = gameData.parseSessionData(decrypt(localStorage.getItem("sessionTestData")!, true)); + gameData.loadSession(game.scene, 0, recoveredData); + + expect(sessionData.arena.tags).toEqual(recoveredData.arena.tags); + localStorage.removeItem("sessionTestData"); + }); +}); diff --git a/src/test/moves/transform.test.ts b/src/test/moves/transform.test.ts index 6686f1fc73b..adb97b42af7 100644 --- a/src/test/moves/transform.test.ts +++ b/src/test/moves/transform.test.ts @@ -36,9 +36,7 @@ describe("Moves - Transform", () => { }); it("should copy species, ability, gender, all stats except HP, all stat stages, moveset, and types of target", async () => { - await game.startBattle([ - Species.DITTO - ]); + await game.classicMode.startBattle([ Species.DITTO ]); game.move.select(Moves.TRANSFORM); await game.phaseInterceptor.to(TurnEndPhase); @@ -62,25 +60,24 @@ describe("Moves - Transform", () => { const playerMoveset = player.getMoveset(); const enemyMoveset = player.getMoveset(); + expect(playerMoveset.length).toBe(enemyMoveset.length); for (let i = 0; i < playerMoveset.length && i < enemyMoveset.length; i++) { - // TODO: Checks for 5 PP should be done here when that gets addressed expect(playerMoveset[i]?.moveId).toBe(enemyMoveset[i]?.moveId); } const playerTypes = player.getTypes(); const enemyTypes = enemy.getTypes(); + expect(playerTypes.length).toBe(enemyTypes.length); for (let i = 0; i < playerTypes.length && i < enemyTypes.length; i++) { expect(playerTypes[i]).toBe(enemyTypes[i]); } - }, 20000); + }); it("should copy in-battle overridden stats", async () => { - game.override.enemyMoveset([Moves.POWER_SPLIT]); + game.override.enemyMoveset([ Moves.POWER_SPLIT ]); - await game.startBattle([ - Species.DITTO - ]); + await game.classicMode.startBattle([ Species.DITTO ]); const player = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -97,4 +94,26 @@ describe("Moves - Transform", () => { expect(player.getStat(Stat.SPATK, false)).toBe(avgSpAtk); expect(enemy.getStat(Stat.SPATK, false)).toBe(avgSpAtk); }); + + it("should set each move's pp to a maximum of 5", async () => { + game.override.enemyMoveset([ Moves.SWORDS_DANCE, Moves.GROWL, Moves.SKETCH, Moves.RECOVER ]); + + await game.classicMode.startBattle([ Species.DITTO ]); + const player = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.TRANSFORM); + await game.phaseInterceptor.to(TurnEndPhase); + + player.getMoveset().forEach(move => { + // Should set correct maximum PP without touching `ppUp` + if (move) { + if (move.moveId === Moves.SKETCH) { + expect(move.getMovePp()).toBe(1); + } else { + expect(move.getMovePp()).toBe(5); + } + expect(move.ppUp).toBe(0); + } + }); + }); }); diff --git a/src/test/moves/trick_or_treat.test.ts b/src/test/moves/trick_or_treat.test.ts new file mode 100644 index 00000000000..7ecd00ed076 --- /dev/null +++ b/src/test/moves/trick_or_treat.test.ts @@ -0,0 +1,47 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Type } from "#app/data/type"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Trick Or Treat", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.FORESTS_CURSE, Moves.TRICK_OR_TREAT ]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("will replace added type from Forest's Curse", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const enemyPokemon = game.scene.getEnemyPokemon(); + game.move.select(Moves.FORESTS_CURSE); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyPokemon!.summonData.addedType).toBe(Type.GRASS); + + game.move.select(Moves.TRICK_OR_TREAT); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyPokemon?.summonData.addedType).toBe(Type.GHOST); + }); +}); diff --git a/src/test/moves/triple_arrows.test.ts b/src/test/moves/triple_arrows.test.ts new file mode 100644 index 00000000000..98ad29997df --- /dev/null +++ b/src/test/moves/triple_arrows.test.ts @@ -0,0 +1,60 @@ +import { allMoves, FlinchAttr, StatStageChangeAttr } from "#app/data/move"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Moves - Triple Arrows", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + const tripleArrows = allMoves[Moves.TRIPLE_ARROWS]; + const flinchAttr = tripleArrows.getAttrs(FlinchAttr)[0]; + const defDropAttr = tripleArrows.getAttrs(StatStageChangeAttr)[0]; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .ability(Abilities.BALL_FETCH) + .moveset([ Moves.TRIPLE_ARROWS ]) + .battleType("single") + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.STURDY) + .enemyMoveset(Moves.SPLASH); + + vi.spyOn(flinchAttr, "getMoveChance"); + vi.spyOn(defDropAttr, "getMoveChance"); + }); + + it("has a 30% flinch chance and 50% defense drop chance", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + game.move.select(Moves.TRIPLE_ARROWS); + await game.phaseInterceptor.to("BerryPhase"); + + expect(flinchAttr.getMoveChance).toHaveReturnedWith(30); + expect(defDropAttr.getMoveChance).toHaveReturnedWith(50); + }); + + it("is affected normally by Serene Grace", async () => { + game.override.ability(Abilities.SERENE_GRACE); + await game.classicMode.startBattle([ Species.FEEBAS ]); + + game.move.select(Moves.TRIPLE_ARROWS); + await game.phaseInterceptor.to("BerryPhase"); + + expect(flinchAttr.getMoveChance).toHaveReturnedWith(60); + expect(defDropAttr.getMoveChance).toHaveReturnedWith(100); + }); +}); diff --git a/src/test/moves/u_turn.test.ts b/src/test/moves/u_turn.test.ts index c4b6ae2497f..b995c20f503 100644 --- a/src/test/moves/u_turn.test.ts +++ b/src/test/moves/u_turn.test.ts @@ -29,7 +29,7 @@ describe("Moves - U-turn", () => { .enemySpecies(Species.GENGAR) .startingLevel(90) .startingWave(97) - .moveset([Moves.U_TURN]) + .moveset([ Moves.U_TURN ]) .enemyMoveset(Moves.SPLASH) .disableCrits(); }); @@ -96,4 +96,23 @@ describe("Moves - U-turn", () => { expect(game.scene.getEnemyPokemon()!.battleData.abilityRevealed).toBe(true); // proxy for asserting ability activated expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase"); }, 20000); + + it("still forces a switch if u-turn KO's the opponent", async () => { + game.override.startingLevel(1000); // Ensure that U-Turn KO's the opponent + await game.classicMode.startBattle([ + Species.RAICHU, + Species.SHUCKLE + ]); + const enemy = game.scene.getEnemyPokemon()!; + + // KO the opponent with U-Turn + game.move.select(Moves.U_TURN); + game.doSelectPartyPokemon(1); + await game.phaseInterceptor.to(TurnEndPhase); + expect(enemy.isFainted()).toBe(true); + + // Check that U-Turn forced a switch + expect(game.phaseInterceptor.log).toContain("SwitchSummonPhase"); + expect(game.scene.getPlayerPokemon()!.species.speciesId).toBe(Species.SHUCKLE); + }); }); diff --git a/src/test/moves/whirlwind.test.ts b/src/test/moves/whirlwind.test.ts index a591a3cd6c5..c16f38111f2 100644 --- a/src/test/moves/whirlwind.test.ts +++ b/src/test/moves/whirlwind.test.ts @@ -1,12 +1,11 @@ -import { BattlerIndex } from "#app/battle"; -import { allMoves } from "#app/data/move"; import { BattlerTagType } from "#app/enums/battler-tag-type"; +import { MoveResult } from "#app/field/pokemon"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Whirlwind", () => { let phaserGame: Phaser.Game; @@ -36,18 +35,16 @@ describe("Moves - Whirlwind", () => { { move: Moves.BOUNCE, name: "Bounce" }, { move: Moves.SKY_DROP, name: "Sky Drop" }, ])("should not hit a flying target: $name (=$move)", async ({ move }) => { - game.override.moveset([move]); - await game.classicMode.startBattle([Species.STARAPTOR]); + game.override.moveset([ move ]); + await game.classicMode.startBattle([ Species.STARAPTOR ]); const staraptor = game.scene.getPlayerPokemon()!; - const whirlwind = allMoves[Moves.WHIRLWIND]; - vi.spyOn(whirlwind, "getFailedText"); game.move.select(move); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); - await game.toNextTurn(); + + await game.phaseInterceptor.to("BerryPhase", false); expect(staraptor.findTag((t) => t.tagType === BattlerTagType.FLYING)).toBeDefined(); - expect(whirlwind.getFailedText).toHaveBeenCalledOnce(); + expect(game.scene.getEnemyPokemon()!.getLastXMoves(1)[0].result).toBe(MoveResult.MISS); }); }); diff --git a/src/test/moves/wide_guard.test.ts b/src/test/moves/wide_guard.test.ts index 9ddd8905ff6..c25a700c981 100644 --- a/src/test/moves/wide_guard.test.ts +++ b/src/test/moves/wide_guard.test.ts @@ -9,7 +9,6 @@ import { BerryPhase } from "#app/phases/berry-phase"; import { CommandPhase } from "#app/phases/command-phase"; - describe("Moves - Wide Guard", () => { let phaserGame: Phaser.Game; let game: GameManager; @@ -29,10 +28,10 @@ describe("Moves - Wide Guard", () => { game.override.battleType("double"); - game.override.moveset([Moves.WIDE_GUARD, Moves.SPLASH, Moves.SURF]); + game.override.moveset([ Moves.WIDE_GUARD, Moves.SPLASH, Moves.SURF ]); game.override.enemySpecies(Species.SNORLAX); - game.override.enemyMoveset([Moves.SWIFT]); + game.override.enemyMoveset([ Moves.SWIFT ]); game.override.enemyAbility(Abilities.INSOMNIA); game.override.startingLevel(100); @@ -42,7 +41,7 @@ describe("Moves - Wide Guard", () => { test( "should protect the user and allies from multi-target attack moves", async () => { - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); @@ -61,9 +60,9 @@ describe("Moves - Wide Guard", () => { test( "should protect the user and allies from multi-target status moves", async () => { - game.override.enemyMoveset([Moves.GROWL]); + game.override.enemyMoveset([ Moves.GROWL ]); - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); @@ -82,9 +81,9 @@ describe("Moves - Wide Guard", () => { test( "should not protect the user and allies from single-target moves", async () => { - game.override.enemyMoveset([Moves.TACKLE]); + game.override.enemyMoveset([ Moves.TACKLE ]); - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); @@ -103,9 +102,9 @@ describe("Moves - Wide Guard", () => { test( "should protect the user from its ally's multi-target move", async () => { - game.override.enemyMoveset([Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH ]); - await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + await game.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); const leadPokemon = game.scene.getPlayerField(); const enemyPokemon = game.scene.getEnemyField(); diff --git a/src/test/moves/will_o_wisp.test.ts b/src/test/moves/will_o_wisp.test.ts new file mode 100644 index 00000000000..39729d331ad --- /dev/null +++ b/src/test/moves/will_o_wisp.test.ts @@ -0,0 +1,53 @@ +import { BattlerIndex } from "#app/battle"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { StatusEffect } from "#enums/status-effect"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Will-O-Wisp", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.WILL_O_WISP, Moves.SPLASH ]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should burn the opponent", async () => { + await game.classicMode.startBattle([ Species.FEEBAS ]); + + const enemy = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.WILL_O_WISP); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.move.forceHit(); + await game.toNextTurn(); + + expect(enemy.status?.effect).toBe(StatusEffect.BURN); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(enemy.status?.effect).toBe(StatusEffect.BURN); + }); +}); diff --git a/src/test/mystery-encounter/encounter-test-utils.ts b/src/test/mystery-encounter/encounter-test-utils.ts index 9fb2504c02b..f95a442d4c2 100644 --- a/src/test/mystery-encounter/encounter-test-utils.ts +++ b/src/test/mystery-encounter/encounter-test-utils.ts @@ -97,20 +97,20 @@ export async function runSelectMysteryEncounterOption(game: GameManager, optionN uiHandler.unblockInput(); // input are blocked by 1s to prevent accidental input. Tests need to handle that switch (optionNo) { - default: - case 1: + default: + case 1: // no movement needed. Default cursor position - break; - case 2: - uiHandler.processInput(Button.RIGHT); - break; - case 3: - uiHandler.processInput(Button.DOWN); - break; - case 4: - uiHandler.processInput(Button.RIGHT); - uiHandler.processInput(Button.DOWN); - break; + break; + case 2: + uiHandler.processInput(Button.RIGHT); + break; + case 3: + uiHandler.processInput(Button.DOWN); + break; + case 4: + uiHandler.processInput(Button.RIGHT); + uiHandler.processInput(Button.DOWN); + break; } if (!isNullOrUndefined(secondaryOptionSelect?.pokemonNo)) { diff --git a/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts b/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts index 6078e136ccb..7d783958422 100644 --- a/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts @@ -16,9 +16,10 @@ import { EggTier } from "#enums/egg-type"; import { CommandPhase } from "#app/phases/command-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import { PartyHealPhase } from "#app/phases/party-heal-phase"; +import i18next from "i18next"; const namespace = "mysteryEncounters/aTrainersTest"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -40,10 +41,10 @@ describe("A Trainer's Test - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.A_TRAINERS_TEST]); + biomeMap.set(biome, [ MysteryEncounterType.A_TRAINERS_TEST ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -106,7 +107,8 @@ describe("A Trainer's Test - Mystery Encounter", () => { expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(enemyField.length).toBe(1); expect(scene.currentBattle.trainer).toBeDefined(); - expect(["trainerNames:buck", "trainerNames:cheryl", "trainerNames:marley", "trainerNames:mira", "trainerNames:riley"].includes(scene.currentBattle.trainer!.config.name)).toBeTruthy(); + expect([ i18next.t("trainerNames:buck"), i18next.t("trainerNames:cheryl"), i18next.t("trainerNames:marley"), i18next.t("trainerNames:mira"), i18next.t("trainerNames:riley") ] + .map(name => name.toLowerCase()).includes(scene.currentBattle.trainer!.config.name)).toBeTruthy(); expect(enemyField[0]).toBeDefined(); }); @@ -126,7 +128,7 @@ describe("A Trainer's Test - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + 1).toBe(eggsAfter.length); const eggTier = eggsAfter[eggsAfter.length - 1].tier; - expect(eggTier === EggTier.ULTRA || eggTier === EggTier.MASTER).toBeTruthy(); + expect(eggTier === EggTier.EPIC || eggTier === EggTier.LEGENDARY).toBeTruthy(); }); }); @@ -174,7 +176,7 @@ describe("A Trainer's Test - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + 1).toBe(eggsAfter.length); const eggTier = eggsAfter[eggsAfter.length - 1].tier; - expect(eggTier).toBe(EggTier.GREAT); + expect(eggTier).toBe(EggTier.RARE); }); it("should leave encounter without battle", async () => { diff --git a/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts b/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts index 99d845c992d..a72a9fbb5a3 100644 --- a/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts @@ -16,9 +16,10 @@ import { Moves } from "#enums/moves"; import { CommandPhase } from "#app/phases/command-phase"; import { MovePhase } from "#app/phases/move-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; +import i18next from "i18next"; const namespace = "mysteryEncounters/absoluteAvarice"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.PLAINS; const defaultWave = 45; @@ -41,8 +42,8 @@ describe("Absolute Avarice - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.PLAINS, [MysteryEncounterType.ABSOLUTE_AVARICE]], - [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.PLAINS, [ MysteryEncounterType.ABSOLUTE_AVARICE ]], + [ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]) ); }); @@ -84,7 +85,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { it("should spawn if player has enough berries", async () => { game.override.mysteryEncounterTier(MysteryEncounterTier.GREAT); - game.override.startingHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}]); + game.override.startingHeldItems([{ name: "BERRY", count: 2, type: BerryType.SITRUS }, { name: "BERRY", count: 3, type: BerryType.GANLON }]); await game.runToMysteryEncounter(); @@ -92,7 +93,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { }); it("should remove all player's berries at the start of the encounter", async () => { - game.override.startingHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}]); + game.override.startingHeldItems([{ name: "BERRY", count: 2, type: BerryType.SITRUS }, { name: "BERRY", count: 3, type: BerryType.GANLON }]); await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty); @@ -128,7 +129,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(enemyField[0].species.speciesId).toBe(Species.GREEDENT); const moveset = enemyField[0].moveset.map(m => m?.moveId); expect(moveset?.length).toBe(4); - expect(moveset).toEqual([Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH]); + expect(moveset).toEqual([ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH ]); const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); expect(movePhases.length).toBe(1); @@ -146,7 +147,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { const pokemonId = partyPokemon.id; const pokemonItems = scene.findModifiers(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).pokemonId === pokemonId, true) as PokemonHeldItemModifier[]; - const revSeed = pokemonItems.find(i => i.type.name === "modifierType:ModifierType.REVIVER_SEED.name"); + const revSeed = pokemonItems.find(i => i.type.name === i18next.t("modifierType:ModifierType.REVIVER_SEED.name")); expect(revSeed).toBeDefined; expect(revSeed?.stackCount).toBe(1); } @@ -169,8 +170,8 @@ describe("Absolute Avarice - Mystery Encounter", () => { }); }); - it("Should return 3 (2/5ths floored) berries if 8 were stolen", {retry: 5}, async () => { - game.override.startingHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}, {name: "BERRY", count: 3, type: BerryType.APICOT}]); + it("Should return 3 (2/5ths floored) berries if 8 were stolen", { retry: 5 }, async () => { + game.override.startingHeldItems([{ name: "BERRY", count: 2, type: BerryType.SITRUS }, { name: "BERRY", count: 3, type: BerryType.GANLON }, { name: "BERRY", count: 3, type: BerryType.APICOT }]); await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty); @@ -185,8 +186,8 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(berryCountAfter).toBe(3); }); - it("Should return 2 (2/5ths floored) berries if 7 were stolen", {retry: 5}, async () => { - game.override.startingHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}, {name: "BERRY", count: 2, type: BerryType.APICOT}]); + it("Should return 2 (2/5ths floored) berries if 7 were stolen", { retry: 5 }, async () => { + game.override.startingHeldItems([{ name: "BERRY", count: 2, type: BerryType.SITRUS }, { name: "BERRY", count: 3, type: BerryType.GANLON }, { name: "BERRY", count: 2, type: BerryType.APICOT }]); await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty); @@ -239,7 +240,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(greedent.species.speciesId).toBe(Species.GREEDENT); const moveset = greedent.moveset.map(m => m?.moveId); expect(moveset?.length).toBe(4); - expect(moveset).toEqual([Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF]); + expect(moveset).toEqual([ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF ]); }); it("should leave encounter without battle", async () => { diff --git a/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts b/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts index 54e780aba50..0585b4ce72b 100644 --- a/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts @@ -17,10 +17,12 @@ import { getPokemonSpecies } from "#app/data/pokemon-species"; import { Moves } from "#enums/moves"; import { ShinyRateBoosterModifier } from "#app/modifier/modifier"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; +import i18next from "i18next"; +import { Abilities } from "#enums/abilities"; const namespace = "mysteryEncounters/anOfferYouCantRefuse"; /** Gyarados for Indimidate */ -const defaultParty = [Species.GYARADOS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.GYARADOS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -36,16 +38,17 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { beforeEach(async () => { game = new GameManager(phaserGame); scene = game.scene; - game.override.mysteryEncounterChance(100); - game.override.startingWave(defaultWave); - game.override.startingBiome(defaultBiome); - game.override.disableTrainerWaves(); + game.override.mysteryEncounterChance(100) + .startingWave(defaultWave) + .startingBiome(defaultBiome) + .disableTrainerWaves() + .ability(Abilities.INTIMIDATE); // Extortion ability const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE]); + biomeMap.set(biome, [ MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -93,8 +96,8 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.strongestPokemon).toBeDefined(); expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.price).toBeDefined(); - expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.option2PrimaryAbility).toBe("ability:intimidate.name"); - expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.moveOrAbility).toBe("ability:intimidate.name"); + expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.option2PrimaryAbility).toBe(i18next.t("ability:intimidate.name")); + expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.moveOrAbility).toBe(i18next.t("ability:intimidate.name")); expect(AnOfferYouCantRefuseEncounter.misc.pokemon instanceof PlayerPokemon).toBeTruthy(); expect(AnOfferYouCantRefuseEncounter.misc?.price?.toString()).toBe(AnOfferYouCantRefuseEncounter.dialogueTokens?.price); expect(onInitResult).toBe(true); @@ -194,10 +197,11 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { }); it("should award EXP to a pokemon with a move in EXTORTION_MOVES", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [Species.ABRA]); + game.override.ability(Abilities.SYNCHRONIZE); // Not an extortion ability, so we can test extortion move + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [ Species.ABRA ]); const party = scene.getParty(); const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA)!; - abra.moveset = [new PokemonMove(Moves.BEAT_UP)]; + abra.moveset = [ new PokemonMove(Moves.BEAT_UP) ]; const expBefore = abra.exp; await runMysteryEncounterToEnd(game, 2); diff --git a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts index 225c06483fa..bfa3d428bc0 100644 --- a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -20,7 +20,7 @@ import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import { Abilities } from "#enums/abilities"; const namespace = "mysteryEncounters/berriesAbound"; -const defaultParty = [Species.PYUKUMUKU, Species.MAGIKARP, Species.PIKACHU]; +const defaultParty = [ Species.PYUKUMUKU, Species.MAGIKARP, Species.PIKACHU ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -48,7 +48,7 @@ describe("Berries Abound - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.BERRIES_ABOUND]], + [ Biome.CAVE, [ MysteryEncounterType.BERRIES_ABOUND ]], ]) ); }); @@ -176,10 +176,12 @@ describe("Berries Abound - Mystery Encounter", () => { const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); + scene.getParty().forEach(pkm => { + vi.spyOn(pkm, "getStat").mockReturnValue(1); // for ease return for every stat + }); + const config = game.scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]; const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId; - // Setting enemy's level arbitrarily high to outspeed - config.pokemonConfigs![0].dataSource!.level = 1000; await runMysteryEncounterToEnd(game, 2, undefined, true); @@ -189,7 +191,7 @@ describe("Berries Abound - Mystery Encounter", () => { expect(enemyField[0].species.speciesId).toBe(speciesToSpawn); // Should be enraged - expect(enemyField[0].summonData.statStages).toEqual([0, 1, 0, 1, 1, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 0, 1, 0, 1, 1, 0, 0 ]); expect(encounterTextSpy).toHaveBeenCalledWith(expect.any(BattleScene), `${namespace}:option.2.selected_bad`); }); @@ -198,10 +200,12 @@ describe("Berries Abound - Mystery Encounter", () => { const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); + scene.getParty().forEach(pkm => { + vi.spyOn(pkm, "getStat").mockReturnValue(1); // for ease return for every stat + }); + const config = game.scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]; const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId; - // Setting enemy's level arbitrarily high to outspeed - config.pokemonConfigs![0].dataSource!.level = 1000; await runMysteryEncounterToEnd(game, 2, undefined, true); @@ -211,7 +215,7 @@ describe("Berries Abound - Mystery Encounter", () => { expect(enemyField[0].species.speciesId).toBe(speciesToSpawn); // Should be enraged - expect(enemyField[0].summonData.statStages).toEqual([1, 1, 1, 1, 1, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 1, 1, 1, 1, 1, 0, 0 ]); expect(encounterTextSpy).toHaveBeenCalledWith(expect.any(BattleScene), `${namespace}:option.2.selected_bad`); }); diff --git a/src/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts b/src/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts index bdf0dc3c307..e0f37c7e045 100644 --- a/src/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts @@ -22,7 +22,7 @@ import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; const namespace = "mysteryEncounters/bugTypeSuperfan"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.WEEDLE]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.WEEDLE ]; const defaultBiome = Biome.CAVE; const defaultWave = 24; @@ -169,7 +169,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.BUG_TYPE_SUPERFAN]], + [ Biome.CAVE, [ MysteryEncounterType.BUG_TYPE_SUPERFAN ]], ]) ); }); @@ -405,7 +405,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should NOT be selectable if the player doesn't have any Bug types", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.ABRA]); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [ Species.ABRA ]); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.getCurrentPhase(); @@ -438,7 +438,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should proceed to rewards screen with 2-3 Bug Types reward options", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL]); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [ Species.BUTTERFREE, Species.BEEDRILL ]); await runMysteryEncounterToEnd(game, 2); expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); @@ -453,7 +453,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should proceed to rewards screen with 4-5 Bug Types reward options", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL, Species.GALVANTULA, Species.VOLCARONA]); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [ Species.BUTTERFREE, Species.BEEDRILL, Species.GALVANTULA, Species.VOLCARONA ]); await runMysteryEncounterToEnd(game, 2); expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); @@ -468,7 +468,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should proceed to rewards screen with 6 Bug Types reward options (including form change item)", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL, Species.GALVANTULA, Species.VOLCARONA, Species.ANORITH, Species.GENESECT]); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [ Species.BUTTERFREE, Species.BEEDRILL, Species.GALVANTULA, Species.VOLCARONA, Species.ANORITH, Species.GENESECT ]); await runMysteryEncounterToEnd(game, 2); expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); @@ -476,10 +476,11 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; - expect(modifierSelectHandler.options.length).toEqual(3); + expect(modifierSelectHandler.options.length).toEqual(4); expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("MASTER_BALL"); - expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("MAX_LURE"); - expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toBe("FORM_CHANGE_ITEM"); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("MEGA_BRACELET"); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toBe("DYNAMAX_BAND"); + expect(modifierSelectHandler.options[3].modifierTypeOption.type.id).toBe("FORM_CHANGE_ITEM"); }); it("should leave encounter without battle", async () => { @@ -536,8 +537,8 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should remove the gifted item and proceed to rewards screen", async () => { - game.override.startingHeldItems([{name: "GRIP_CLAW", count: 1}]); - await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE]); + game.override.startingHeldItems([{ name: "GRIP_CLAW", count: 1 }]); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [ Species.BUTTERFREE ]); const gripClawCountBefore = scene.findModifier(m => m instanceof ContactHeldItemTransferChanceModifier)?.stackCount ?? 0; @@ -557,10 +558,10 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { }); it("should leave encounter without battle", async () => { - game.override.startingHeldItems([{name: "GRIP_CLAW", count: 1}]); + game.override.startingHeldItems([{ name: "GRIP_CLAW", count: 1 }]); const leaveEncounterWithoutBattleSpy = vi.spyOn(encounterPhaseUtils, "leaveEncounterWithoutBattle"); - await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE]); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [ Species.BUTTERFREE ]); await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); diff --git a/src/test/mystery-encounter/encounters/clowning-around-encounter.test.ts b/src/test/mystery-encounter/encounters/clowning-around-encounter.test.ts index 80434df2f44..82ed558e6db 100644 --- a/src/test/mystery-encounter/encounters/clowning-around-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/clowning-around-encounter.test.ts @@ -34,7 +34,7 @@ import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import { NewBattlePhase } from "#app/phases/new-battle-phase"; const namespace = "mysteryEncounters/clowningAround"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -57,7 +57,7 @@ describe("Clowning Around - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.CLOWNING_AROUND]], + [ Biome.CAVE, [ MysteryEncounterType.CLOWNING_AROUND ]], ]) ); }); @@ -114,15 +114,15 @@ describe("Clowning Around - Mystery Encounter", () => { expect(config.pokemonConfigs?.[0]).toEqual({ species: getPokemonSpecies(Species.MR_MIME), isBoss: true, - moveSet: [Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC] + moveSet: [ Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC ] }); expect(config.pokemonConfigs?.[1]).toEqual({ species: getPokemonSpecies(Species.BLACEPHALON), - mysteryEncounterPokemonData: expect.anything(), + customPokemonData: expect.anything(), isBoss: true, - moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN] + moveSet: [ Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN ] }); - expect(config.pokemonConfigs?.[1].mysteryEncounterPokemonData?.types.length).toBe(2); + expect(config.pokemonConfigs?.[1].customPokemonData?.types.length).toBe(2); expect([ Abilities.STURDY, Abilities.PICKUP, @@ -139,8 +139,8 @@ describe("Clowning Around - Mystery Encounter", () => { Abilities.MAGICIAN, Abilities.SHEER_FORCE, Abilities.PRANKSTER - ]).toContain(config.pokemonConfigs?.[1].mysteryEncounterPokemonData?.ability); - expect(ClowningAroundEncounter.misc.ability).toBe(config.pokemonConfigs?.[1].mysteryEncounterPokemonData?.ability); + ]).toContain(config.pokemonConfigs?.[1].customPokemonData?.ability); + expect(ClowningAroundEncounter.misc.ability).toBe(config.pokemonConfigs?.[1].customPokemonData?.ability); await vi.waitFor(() => expect(moveInitSpy).toHaveBeenCalled()); await vi.waitFor(() => expect(moveLoadSpy).toHaveBeenCalled()); expect(onInitResult).toBe(true); @@ -173,9 +173,9 @@ describe("Clowning Around - Mystery Encounter", () => { expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(enemyField.length).toBe(2); expect(enemyField[0].species.speciesId).toBe(Species.MR_MIME); - expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.TEETER_DANCE), new PokemonMove(Moves.ALLY_SWITCH), new PokemonMove(Moves.DAZZLING_GLEAM), new PokemonMove(Moves.PSYCHIC)]); + expect(enemyField[0].moveset).toEqual([ new PokemonMove(Moves.TEETER_DANCE), new PokemonMove(Moves.ALLY_SWITCH), new PokemonMove(Moves.DAZZLING_GLEAM), new PokemonMove(Moves.PSYCHIC) ]); expect(enemyField[1].species.speciesId).toBe(Species.BLACEPHALON); - expect(enemyField[1].moveset).toEqual([new PokemonMove(Moves.TRICK), new PokemonMove(Moves.HYPNOSIS), new PokemonMove(Moves.SHADOW_BALL), new PokemonMove(Moves.MIND_BLOWN)]); + expect(enemyField[1].moveset).toEqual([ new PokemonMove(Moves.TRICK), new PokemonMove(Moves.HYPNOSIS), new PokemonMove(Moves.SHADOW_BALL), new PokemonMove(Moves.MIND_BLOWN) ]); // Should have used moves pre-battle const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); @@ -219,7 +219,7 @@ describe("Clowning Around - Mystery Encounter", () => { await game.phaseInterceptor.to(NewBattlePhase, false); const leadPokemon = scene.getParty()[0]; - expect(leadPokemon.mysteryEncounterPokemonData?.ability).toBe(abilityToTrain); + expect(leadPokemon.customPokemonData?.ability).toBe(abilityToTrain); }); }); @@ -251,14 +251,14 @@ describe("Clowning Around - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty); // Set some moves on party for attack type booster generation - scene.getParty()[0].moveset = [new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.THIEF)]; + scene.getParty()[0].moveset = [ new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.THIEF) ]; // 2 Sitrus Berries on lead scene.modifiers = []; - let itemType = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType; + let itemType = generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType; await addItemToPokemon(scene, scene.getParty()[0], 2, itemType); // 2 Ganlon Berries on lead - itemType = generateModifierType(scene, modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType; + itemType = generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ]) as PokemonHeldItemModifierType; await addItemToPokemon(scene, scene.getParty()[0], 2, itemType); // 5 Golden Punch on lead (ultra) itemType = generateModifierType(scene, modifierTypes.GOLDEN_PUNCH) as PokemonHeldItemModifierType; @@ -333,24 +333,24 @@ describe("Clowning Around - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty); // Same type moves on lead - scene.getParty()[0].moveset = [new PokemonMove(Moves.ICE_BEAM), new PokemonMove(Moves.SURF)]; + scene.getParty()[0].moveset = [ new PokemonMove(Moves.ICE_BEAM), new PokemonMove(Moves.SURF) ]; // Different type moves on second - scene.getParty()[1].moveset = [new PokemonMove(Moves.GRASS_KNOT), new PokemonMove(Moves.ELECTRO_BALL)]; + scene.getParty()[1].moveset = [ new PokemonMove(Moves.GRASS_KNOT), new PokemonMove(Moves.ELECTRO_BALL) ]; // No moves on third scene.getParty()[2].moveset = []; await runMysteryEncounterToEnd(game, 3); - const leadTypesAfter = scene.getParty()[0].mysteryEncounterPokemonData?.types; - const secondaryTypesAfter = scene.getParty()[1].mysteryEncounterPokemonData?.types; - const thirdTypesAfter = scene.getParty()[2].mysteryEncounterPokemonData?.types; + const leadTypesAfter = scene.getParty()[0].customPokemonData?.types; + const secondaryTypesAfter = scene.getParty()[1].customPokemonData?.types; + const thirdTypesAfter = scene.getParty()[2].customPokemonData?.types; expect(leadTypesAfter.length).toBe(2); expect(leadTypesAfter[0]).toBe(Type.WATER); - expect([Type.WATER, Type.ICE].includes(leadTypesAfter[1])).toBeFalsy(); + expect([ Type.WATER, Type.ICE ].includes(leadTypesAfter[1])).toBeFalsy(); expect(secondaryTypesAfter.length).toBe(2); expect(secondaryTypesAfter[0]).toBe(Type.GHOST); - expect([Type.GHOST, Type.POISON].includes(secondaryTypesAfter[1])).toBeFalsy(); - expect([Type.GRASS, Type.ELECTRIC].includes(secondaryTypesAfter[1])).toBeTruthy(); + expect([ Type.GHOST, Type.POISON ].includes(secondaryTypesAfter[1])).toBeFalsy(); + expect([ Type.GRASS, Type.ELECTRIC ].includes(secondaryTypesAfter[1])).toBeTruthy(); expect(thirdTypesAfter.length).toBe(2); expect(thirdTypesAfter[0]).toBe(Type.PSYCHIC); expect(secondaryTypesAfter[1]).not.toBe(Type.PSYCHIC); diff --git a/src/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts b/src/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts index 107bc4f3c67..47625541160 100644 --- a/src/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts @@ -21,7 +21,7 @@ import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import { LearnMovePhase } from "#app/phases/learn-move-phase"; const namespace = "mysteryEncounters/dancingLessons"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.PLAINS; const defaultWave = 45; @@ -44,8 +44,8 @@ describe("Dancing Lessons - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.PLAINS, [MysteryEncounterType.DANCING_LESSONS]], - [Biome.SPACE, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.PLAINS, [ MysteryEncounterType.DANCING_LESSONS ]], + [ Biome.SPACE, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]) ); }); @@ -107,7 +107,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(enemyField.length).toBe(1); expect(enemyField[0].species.speciesId).toBe(Species.ORICORIO); - expect(enemyField[0].summonData.statStages).toEqual([1, 1, 1, 1, 0, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 1, 1, 1, 1, 0, 0, 0 ]); const moveset = enemyField[0].moveset.map(m => m?.moveId); expect(moveset.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy(); @@ -197,8 +197,8 @@ describe("Dancing Lessons - Mystery Encounter", () => { it("should add Oricorio to the party", async () => { await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); const partyCountBefore = scene.getParty().length; - scene.getParty()[0].moveset = [new PokemonMove(Moves.DRAGON_DANCE)]; - await runMysteryEncounterToEnd(game, 3, {pokemonNo: 1, optionNo: 1}); + scene.getParty()[0].moveset = [ new PokemonMove(Moves.DRAGON_DANCE) ]; + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); const partyCountAfter = scene.getParty().length; expect(partyCountBefore + 1).toBe(partyCountAfter); @@ -236,8 +236,8 @@ describe("Dancing Lessons - Mystery Encounter", () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); - scene.getParty()[0].moveset = [new PokemonMove(Moves.DRAGON_DANCE)]; - await runMysteryEncounterToEnd(game, 3, {pokemonNo: 1, optionNo: 1}); + scene.getParty()[0].moveset = [ new PokemonMove(Moves.DRAGON_DANCE) ]; + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); }); diff --git a/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts b/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts index e7a7c0bd50d..66d628ef82f 100644 --- a/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts @@ -18,7 +18,7 @@ import { modifierTypes } from "#app/modifier/modifier-type"; import { BerryType } from "#enums/berry-type"; const namespace = "mysteryEncounters/delibirdy"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -41,7 +41,7 @@ describe("Delibird-y - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.DELIBIRDY]], + [ Biome.CAVE, [ MysteryEncounterType.DELIBIRDY ]], ]) ); }); @@ -190,13 +190,13 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 2 Sitrus berries on party lead scene.modifiers = []; - const sitrus = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS])!; + const sitrus = generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ])!; const sitrusMod = sitrus.newModifier(scene.getParty()[0]) as BerryModifier; sitrusMod.stackCount = 2; await scene.addModifier(sitrusMod, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1 }); const sitrusAfter = scene.findModifier(m => m instanceof BerryModifier); const candyJarAfter = scene.findModifier(m => m instanceof LevelIncrementBoosterModifier); @@ -206,7 +206,7 @@ describe("Delibird-y - Mystery Encounter", () => { expect(candyJarAfter?.stackCount).toBe(1); }); - it("Should remove Reviver Seed and give the player a Healing Charm", async () => { + it("Should remove Reviver Seed and give the player a Berry Pouch", async () => { await game.runToMysteryEncounter(MysteryEncounterType.DELIBIRDY, defaultParty); // Set 1 Reviver Seed on party lead @@ -217,14 +217,14 @@ describe("Delibird-y - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1 }); const reviverSeedAfter = scene.findModifier(m => m instanceof PokemonInstantReviveModifier); - const healingCharmAfter = scene.findModifier(m => m instanceof HealingBoosterModifier); + const berryPouchAfter = scene.findModifier(m => m instanceof PreserveBerryModifier); expect(reviverSeedAfter).toBeUndefined(); - expect(healingCharmAfter).toBeDefined(); - expect(healingCharmAfter?.stackCount).toBe(1); + expect(berryPouchAfter).toBeDefined(); + expect(berryPouchAfter?.stackCount).toBe(1); }); it("Should give the player a Shell Bell if they have max stacks of Candy Jars", async () => { @@ -235,7 +235,7 @@ describe("Delibird-y - Mystery Encounter", () => { const candyJar = generateModifierType(scene, modifierTypes.CANDY_JAR)!.newModifier() as LevelIncrementBoosterModifier; candyJar.stackCount = 99; await scene.addModifier(candyJar, true, false, false, true); - const sitrus = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS])!; + const sitrus = generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ])!; // Sitrus berries on party const sitrusMod = sitrus.newModifier(scene.getParty()[0]) as BerryModifier; @@ -243,7 +243,7 @@ describe("Delibird-y - Mystery Encounter", () => { await scene.addModifier(sitrusMod, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1 }); const sitrusAfter = scene.findModifier(m => m instanceof BerryModifier); const candyJarAfter = scene.findModifier(m => m instanceof LevelIncrementBoosterModifier); @@ -256,13 +256,13 @@ describe("Delibird-y - Mystery Encounter", () => { expect(shellBellAfter?.stackCount).toBe(1); }); - it("Should give the player a Shell Bell if they have max stacks of Healing Charms", async () => { + it("Should give the player a Shell Bell if they have max stacks of Berry Pouches", async () => { await game.runToMysteryEncounter(MysteryEncounterType.DELIBIRDY, defaultParty); - // 5 Healing Charms + // 3 Berry Pouches scene.modifiers = []; - const healingCharm = generateModifierType(scene, modifierTypes.HEALING_CHARM)!.newModifier() as HealingBoosterModifier; - healingCharm.stackCount = 5; + const healingCharm = generateModifierType(scene, modifierTypes.BERRY_POUCH)!.newModifier() as PreserveBerryModifier; + healingCharm.stackCount = 3; await scene.addModifier(healingCharm, true, false, false, true); // Set 1 Reviver Seed on party lead @@ -272,15 +272,15 @@ describe("Delibird-y - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1 }); const reviverSeedAfter = scene.findModifier(m => m instanceof PokemonInstantReviveModifier); - const healingCharmAfter = scene.findModifier(m => m instanceof HealingBoosterModifier); + const healingCharmAfter = scene.findModifier(m => m instanceof PreserveBerryModifier); const shellBellAfter = scene.findModifier(m => m instanceof HitHealModifier); expect(reviverSeedAfter).toBeUndefined(); expect(healingCharmAfter).toBeDefined(); - expect(healingCharmAfter?.stackCount).toBe(5); + expect(healingCharmAfter?.stackCount).toBe(3); expect(shellBellAfter).toBeDefined(); expect(shellBellAfter?.stackCount).toBe(1); }); @@ -324,7 +324,7 @@ describe("Delibird-y - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1, optionNo: 1 }); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); }); @@ -347,7 +347,7 @@ describe("Delibird-y - Mystery Encounter", () => { }); }); - it("Should decrease held item stacks and give the player a Berry Pouch", async () => { + it("Should decrease held item stacks and give the player a Healing Charm", async () => { await game.runToMysteryEncounter(MysteryEncounterType.DELIBIRDY, defaultParty); // Set 2 Soul Dew on party lead @@ -358,17 +358,17 @@ describe("Delibird-y - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); const soulDewAfter = scene.findModifier(m => m instanceof PokemonNatureWeightModifier); - const berryPouchAfter = scene.findModifier(m => m instanceof PreserveBerryModifier); + const healingCharmAfter = scene.findModifier(m => m instanceof HealingBoosterModifier); expect(soulDewAfter?.stackCount).toBe(1); - expect(berryPouchAfter).toBeDefined(); - expect(berryPouchAfter?.stackCount).toBe(1); + expect(healingCharmAfter).toBeDefined(); + expect(healingCharmAfter?.stackCount).toBe(1); }); - it("Should remove held item and give the player a Berry Pouch", async () => { + it("Should remove held item and give the player a Healing Charm", async () => { await game.runToMysteryEncounter(MysteryEncounterType.DELIBIRDY, defaultParty); // Set 1 Soul Dew on party lead @@ -379,23 +379,23 @@ describe("Delibird-y - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); const soulDewAfter = scene.findModifier(m => m instanceof PokemonNatureWeightModifier); - const berryPouchAfter = scene.findModifier(m => m instanceof PreserveBerryModifier); + const healingCharmAfter = scene.findModifier(m => m instanceof HealingBoosterModifier); expect(soulDewAfter).toBeUndefined(); - expect(berryPouchAfter).toBeDefined(); - expect(berryPouchAfter?.stackCount).toBe(1); + expect(healingCharmAfter).toBeDefined(); + expect(healingCharmAfter?.stackCount).toBe(1); }); - it("Should give the player a Shell Bell if they have max stacks of Berry Pouches", async () => { + it("Should give the player a Shell Bell if they have max stacks of Healing Charms", async () => { await game.runToMysteryEncounter(MysteryEncounterType.DELIBIRDY, defaultParty); // 5 Healing Charms scene.modifiers = []; - const healingCharm = generateModifierType(scene, modifierTypes.BERRY_POUCH)!.newModifier() as PreserveBerryModifier; - healingCharm.stackCount = 3; + const healingCharm = generateModifierType(scene, modifierTypes.HEALING_CHARM)!.newModifier() as HealingBoosterModifier; + healingCharm.stackCount = 5; await scene.addModifier(healingCharm, true, false, false, true); // Set 1 Soul Dew on party lead @@ -405,15 +405,15 @@ describe("Delibird-y - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); const soulDewAfter = scene.findModifier(m => m instanceof PokemonNatureWeightModifier); - const berryPouchAfter = scene.findModifier(m => m instanceof PreserveBerryModifier); + const healingCharmAfter = scene.findModifier(m => m instanceof HealingBoosterModifier); const shellBellAfter = scene.findModifier(m => m instanceof HitHealModifier); expect(soulDewAfter).toBeUndefined(); - expect(berryPouchAfter).toBeDefined(); - expect(berryPouchAfter?.stackCount).toBe(3); + expect(healingCharmAfter).toBeDefined(); + expect(healingCharmAfter?.stackCount).toBe(5); expect(shellBellAfter).toBeDefined(); expect(shellBellAfter?.stackCount).toBe(1); }); @@ -458,7 +458,7 @@ describe("Delibird-y - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); }); diff --git a/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts b/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts index e36c103b57d..1869a4d3c3c 100644 --- a/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts @@ -16,7 +16,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; const namespace = "mysteryEncounters/departmentStoreSale"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.PLAINS; const defaultWave = 37; @@ -38,10 +38,10 @@ describe("Department Store Sale - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]); CIVILIZATION_ENCOUNTER_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.DEPARTMENT_STORE_SALE]); + biomeMap.set(biome, [ MysteryEncounterType.DEPARTMENT_STORE_SALE ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); diff --git a/src/test/mystery-encounter/encounters/field-trip-encounter.test.ts b/src/test/mystery-encounter/encounters/field-trip-encounter.test.ts index d8efd340b63..a6f925274c3 100644 --- a/src/test/mystery-encounter/encounters/field-trip-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/field-trip-encounter.test.ts @@ -17,7 +17,7 @@ import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import i18next from "i18next"; const namespace = "mysteryEncounters/fieldTrip"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -37,11 +37,11 @@ describe("Field Trip - Mystery Encounter", () => { game.override.startingWave(defaultWave); game.override.startingBiome(defaultBiome); game.override.disableTrainerWaves(); - game.override.moveset([Moves.TACKLE, Moves.UPROAR, Moves.SWORDS_DANCE]); + game.override.moveset([ Moves.TACKLE, Moves.UPROAR, Moves.SWORDS_DANCE ]); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.FIELD_TRIP]], + [ Biome.CAVE, [ MysteryEncounterType.FIELD_TRIP ]], ]) ); }); @@ -103,11 +103,11 @@ describe("Field Trip - Mystery Encounter", () => { expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; expect(modifierSelectHandler.options.length).toEqual(5); - expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe("modifierType:TempStatStageBoosterItem.x_attack"); - expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("modifierType:TempStatStageBoosterItem.x_defense"); - expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("modifierType:TempStatStageBoosterItem.x_speed"); - expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("modifierType:ModifierType.DIRE_HIT.name"); - expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe("modifierType:ModifierType.RARER_CANDY.name"); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe(i18next.t("modifierType:TempStatStageBoosterItem.x_attack")); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe(i18next.t("modifierType:TempStatStageBoosterItem.x_defense")); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe(i18next.t("modifierType:TempStatStageBoosterItem.x_speed")); + expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe(i18next.t("modifierType:ModifierType.DIRE_HIT.name")); + expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe(i18next.t("modifierType:ModifierType.RARER_CANDY.name")); }); it("should leave encounter without battle", async () => { @@ -150,11 +150,11 @@ describe("Field Trip - Mystery Encounter", () => { expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; expect(modifierSelectHandler.options.length).toEqual(5); - expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe("modifierType:TempStatStageBoosterItem.x_sp_atk"); - expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("modifierType:TempStatStageBoosterItem.x_sp_def"); - expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("modifierType:TempStatStageBoosterItem.x_speed"); - expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("modifierType:ModifierType.DIRE_HIT.name"); - expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe("modifierType:ModifierType.RARER_CANDY.name"); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe(i18next.t("modifierType:TempStatStageBoosterItem.x_sp_atk")); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe(i18next.t("modifierType:TempStatStageBoosterItem.x_sp_def")); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe(i18next.t("modifierType:TempStatStageBoosterItem.x_speed")); + expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe(i18next.t("modifierType:ModifierType.DIRE_HIT.name")); + expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe(i18next.t("modifierType:ModifierType.RARER_CANDY.name")); }); it("should leave encounter without battle", async () => { @@ -198,12 +198,12 @@ describe("Field Trip - Mystery Encounter", () => { expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; expect(modifierSelectHandler.options.length).toEqual(5); - expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe("modifierType:TempStatStageBoosterItem.x_accuracy"); - expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("modifierType:TempStatStageBoosterItem.x_speed"); - expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("modifierType:ModifierType.AddPokeballModifierType.name"); - expect(i18next.t).toHaveBeenCalledWith("modifierType:ModifierType.AddPokeballModifierType.name", expect.objectContaining({ modifierCount: 5 })); - expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("modifierType:ModifierType.IV_SCANNER.name"); - expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe("modifierType:ModifierType.RARER_CANDY.name"); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe(i18next.t("modifierType:TempStatStageBoosterItem.x_accuracy")); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe(i18next.t("modifierType:TempStatStageBoosterItem.x_speed")); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe(i18next.t("modifierType:ModifierType.AddPokeballModifierType.name", { modifierCount: 5, pokeballName: i18next.t("pokeball:greatBall") })); + expect(i18next.t).toHaveBeenCalledWith(("modifierType:ModifierType.AddPokeballModifierType.name"), expect.objectContaining({ modifierCount: 5 })); + expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe(i18next.t("modifierType:ModifierType.IV_SCANNER.name")); + expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe(i18next.t("modifierType:ModifierType.RARER_CANDY.name")); }); it("should leave encounter without battle", async () => { diff --git a/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts b/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts index 24c2e083a72..5a270f1cbec 100644 --- a/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts @@ -12,7 +12,7 @@ import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encount import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import { Moves } from "#enums/moves"; import BattleScene from "#app/battle-scene"; -import { PokemonHeldItemModifier } from "#app/modifier/modifier"; +import { AttackTypeBoosterModifier, PokemonHeldItemModifier } from "#app/modifier/modifier"; import { Type } from "#app/data/type"; import { Status, StatusEffect } from "#app/data/status-effect"; import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; @@ -22,10 +22,13 @@ import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; import { CommandPhase } from "#app/phases/command-phase"; import { MovePhase } from "#app/phases/move-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Abilities } from "#enums/abilities"; +import i18next from "i18next"; const namespace = "mysteryEncounters/fieryFallout"; /** Arcanine and Ninetails for 2 Fire types. Lapras, Gengar, Abra for burnable mon. */ -const defaultParty = [Species.ARCANINE, Species.NINETALES, Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.ARCANINE, Species.NINETALES, Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.VOLCANO; const defaultWave = 56; @@ -41,15 +44,16 @@ describe("Fiery Fallout - Mystery Encounter", () => { beforeEach(async () => { game = new GameManager(phaserGame); scene = game.scene; - game.override.mysteryEncounterChance(100); - game.override.startingWave(defaultWave); - game.override.startingBiome(defaultBiome); - game.override.disableTrainerWaves(); + game.override.mysteryEncounterChance(100) + .startingWave(defaultWave) + .startingBiome(defaultBiome) + .disableTrainerWaves() + .moveset([ Moves.PAYBACK, Moves.THUNDERBOLT ]); // Required for attack type booster item generation vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.VOLCANO, [MysteryEncounterType.FIERY_FALLOUT]], - [Biome.MOUNTAIN, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.VOLCANO, [ MysteryEncounterType.FIERY_FALLOUT ]], + [ Biome.MOUNTAIN, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]) ); }); @@ -108,12 +112,16 @@ describe("Fiery Fallout - Mystery Encounter", () => { { species: getPokemonSpecies(Species.VOLCARONA), isBoss: false, - gender: Gender.MALE + gender: Gender.MALE, + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], + mysteryEncounterBattleEffects: expect.any(Function) }, { species: getPokemonSpecies(Species.VOLCARONA), isBoss: false, - gender: Gender.FEMALE + gender: Gender.FEMALE, + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], + mysteryEncounterBattleEffects: expect.any(Function) } ], doubleBattle: true, @@ -156,12 +164,11 @@ describe("Fiery Fallout - Mystery Encounter", () => { expect(enemyField[0].gender).not.toEqual(enemyField[1].gender); // Should be opposite gender const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); - expect(movePhases.length).toBe(4); + expect(movePhases.length).toBe(2); expect(movePhases.filter(p => (p as MovePhase).move.moveId === Moves.FIRE_SPIN).length).toBe(2); // Fire spin used twice before battle - expect(movePhases.filter(p => (p as MovePhase).move.moveId === Moves.QUIVER_DANCE).length).toBe(2); // Quiver Dance used twice before battle }); - it("should give charcoal to lead pokemon", async () => { + it("should give attack type boosting item to lead pokemon", async () => { await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); @@ -171,8 +178,8 @@ describe("Fiery Fallout - Mystery Encounter", () => { const leadPokemonId = scene.getParty()?.[0].id; const leadPokemonItems = scene.findModifiers(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).pokemonId === leadPokemonId, true) as PokemonHeldItemModifier[]; - const charcoal = leadPokemonItems.find(i => i.type.name === "Charcoal"); - expect(charcoal).toBeDefined; + const item = leadPokemonItems.find(i => i instanceof AttackTypeBoosterModifier); + expect(item).toBeDefined; }); }); @@ -192,7 +199,7 @@ describe("Fiery Fallout - Mystery Encounter", () => { }); }); - it("should damage all non-fire party PKM by 20% and randomly burn 1", async () => { + it("should damage all non-fire party PKM by 20%, and burn + give Heatproof to a random Pokemon", async () => { await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty); const party = scene.getParty(); @@ -205,11 +212,12 @@ describe("Fiery Fallout - Mystery Encounter", () => { const burnablePokemon = party.filter((pkm) => pkm.isAllowedInBattle() && !pkm.getTypes().includes(Type.FIRE)); const notBurnablePokemon = party.filter((pkm) => !pkm.isAllowedInBattle() || pkm.getTypes().includes(Type.FIRE)); - expect(scene.currentBattle.mysteryEncounter?.dialogueTokens["burnedPokemon"]).toBe("pokemon:gengar"); + expect(scene.currentBattle.mysteryEncounter?.dialogueTokens["burnedPokemon"]).toBe(i18next.t("pokemon:gengar")); burnablePokemon.forEach((pkm) => { expect(pkm.hp, `${pkm.name} should have received 20% damage: ${pkm.hp} / ${pkm.getMaxHp()} HP`).toBe(pkm.getMaxHp() - Math.floor(pkm.getMaxHp() * 0.2)); }); - expect(burnablePokemon.some(pkm => pkm?.status?.effect === StatusEffect.BURN)).toBeTruthy(); + expect(burnablePokemon.some(pkm => pkm.status?.effect === StatusEffect.BURN)).toBeTruthy(); + expect(burnablePokemon.some(pkm => pkm.customPokemonData.ability === Abilities.HEATPROOF)); notBurnablePokemon.forEach((pkm) => expect(pkm.hp, `${pkm.name} should be full hp: ${pkm.hp} / ${pkm.getMaxHp()} HP`).toBe(pkm.getMaxHp())); }); @@ -240,17 +248,15 @@ describe("Fiery Fallout - Mystery Encounter", () => { }); }); - it("should give charcoal to lead pokemon", async () => { + it("should give attack type boosting item to lead pokemon", async () => { await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty); await runMysteryEncounterToEnd(game, 3); await game.phaseInterceptor.to(SelectModifierPhase, false); expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); - const leadPokemonId = scene.getParty()?.[0].id; - const leadPokemonItems = scene.findModifiers(m => m instanceof PokemonHeldItemModifier - && (m as PokemonHeldItemModifier).pokemonId === leadPokemonId, true) as PokemonHeldItemModifier[]; - const charcoal = leadPokemonItems.find(i => i.type.name === "Charcoal"); - expect(charcoal).toBeDefined; + const leadPokemonItems = scene.getParty()?.[0].getHeldItems() as PokemonHeldItemModifier[]; + const item = leadPokemonItems.find(i => i instanceof AttackTypeBoosterModifier); + expect(item).toBeDefined; }); it("should leave encounter without battle", async () => { @@ -263,7 +269,7 @@ describe("Fiery Fallout - Mystery Encounter", () => { }); it("should be disabled if not enough FIRE types are in party", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, [Species.MAGIKARP, Species.ARCANINE]); + await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, [ Species.MAGIKARP ]); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.getCurrentPhase(); diff --git a/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts b/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts index 20a84281530..d23e7919267 100644 --- a/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts @@ -20,7 +20,7 @@ import { CommandPhase } from "#app/phases/command-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; const namespace = "mysteryEncounters/fightOrFlight"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -43,7 +43,7 @@ describe("Fight or Flight - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.FIGHT_OR_FLIGHT]], + [ Biome.CAVE, [ MysteryEncounterType.FIGHT_OR_FLIGHT ]], ]) ); }); @@ -175,7 +175,7 @@ describe("Fight or Flight - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty); // Mock moveset - scene.getParty()[0].moveset = [new PokemonMove(Moves.KNOCK_OFF)]; + scene.getParty()[0].moveset = [ new PokemonMove(Moves.KNOCK_OFF) ]; const item = game.scene.currentBattle.mysteryEncounter!.misc; await runMysteryEncounterToEnd(game, 2); diff --git a/src/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts b/src/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts index c3fa141f65c..2f4f6bed288 100644 --- a/src/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts @@ -23,7 +23,7 @@ import { Command } from "#app/ui/command-ui-handler"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; const namespace = "mysteryEncounters/funAndGames"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -45,10 +45,10 @@ describe("Fun And Games! - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.FIGHT_OR_FLIGHT]], + [ Biome.VOLCANO, [ MysteryEncounterType.FIGHT_OR_FLIGHT ]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.FUN_AND_GAMES]); + biomeMap.set(biome, [ MysteryEncounterType.FUN_AND_GAMES ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -137,13 +137,13 @@ describe("Fun And Games! - Mystery Encounter", () => { it("should get 3 turns to attack the Wobbuffet for a reward", async () => { scene.money = 20000; - game.override.moveset([Moves.TACKLE]); + game.override.moveset([ Moves.TACKLE ]); await game.runToMysteryEncounter(MysteryEncounterType.FUN_AND_GAMES, defaultParty); await runMysteryEncounterToEnd(game, 1, { pokemonNo: 1 }, true); expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(scene.getEnemyPokemon()?.species.speciesId).toBe(Species.WOBBUFFET); - expect(scene.getEnemyPokemon()?.ivs).toEqual([0, 0, 0, 0, 0, 0]); + expect(scene.getEnemyPokemon()?.ivs).toEqual([ 0, 0, 0, 0, 0, 0 ]); expect(scene.getEnemyPokemon()?.nature).toBe(Nature.MILD); game.onNextPrompt("MessagePhase", Mode.MESSAGE, () => { @@ -192,7 +192,7 @@ describe("Fun And Games! - Mystery Encounter", () => { it("should have Wide Lens item in rewards if Wubboffet is at 15-33% HP remaining", async () => { scene.money = 20000; - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); await game.runToMysteryEncounter(MysteryEncounterType.FUN_AND_GAMES, defaultParty); await runMysteryEncounterToEnd(game, 1, { pokemonNo: 1 }, true); @@ -220,7 +220,7 @@ describe("Fun And Games! - Mystery Encounter", () => { it("should have Scope Lens item in rewards if Wubboffet is at 3-15% HP remaining", async () => { scene.money = 20000; - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); await game.runToMysteryEncounter(MysteryEncounterType.FUN_AND_GAMES, defaultParty); await runMysteryEncounterToEnd(game, 1, { pokemonNo: 1 }, true); @@ -248,7 +248,7 @@ describe("Fun And Games! - Mystery Encounter", () => { it("should have Multi Lens item in rewards if Wubboffet is at <3% HP remaining", async () => { scene.money = 20000; - game.override.moveset([Moves.SPLASH]); + game.override.moveset([ Moves.SPLASH ]); await game.runToMysteryEncounter(MysteryEncounterType.FUN_AND_GAMES, defaultParty); await runMysteryEncounterToEnd(game, 1, { pokemonNo: 1 }, true); diff --git a/src/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts b/src/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts index 17f6a74e480..b08f8008b68 100644 --- a/src/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts @@ -20,7 +20,7 @@ import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import { ModifierTier } from "#app/modifier/modifier-tier"; const namespace = "mysteryEncounters/globalTradeSystem"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -42,10 +42,10 @@ describe("Global Trade System - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]); CIVILIZATION_ENCOUNTER_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.GLOBAL_TRADE_SYSTEM]); + biomeMap.set(biome, [ MysteryEncounterType.GLOBAL_TRADE_SYSTEM ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -70,7 +70,7 @@ describe("Global Trade System - Mystery Encounter", () => { }); it("should not loop infinitely when generating trade options for extreme BST non-legendaries", async () => { - const extremeBstTeam = [Species.SLAKING, Species.WISHIWASHI, Species.SUNKERN]; + const extremeBstTeam = [ Species.SLAKING, Species.WISHIWASHI, Species.SUNKERN ]; await game.runToMysteryEncounter(MysteryEncounterType.GLOBAL_TRADE_SYSTEM, extremeBstTeam); expect(GlobalTradeSystemEncounter.encounterType).toBe(MysteryEncounterType.GLOBAL_TRADE_SYSTEM); @@ -209,7 +209,7 @@ describe("Global Trade System - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); await game.phaseInterceptor.run(SelectModifierPhase); @@ -234,7 +234,7 @@ describe("Global Trade System - Mystery Encounter", () => { await scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); - await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1}); + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); }); diff --git a/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts b/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts index bb7a74d6fd0..dec14d46cc8 100644 --- a/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts @@ -14,11 +14,12 @@ import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; import BattleScene from "#app/battle-scene"; import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; import { PartyExpPhase } from "#app/phases/party-exp-phase"; +import i18next from "i18next"; const namespace = "mysteryEncounters/lostAtSea"; /** Blastoise for surf. Pidgeot for fly. Abra for none. */ -const defaultParty = [Species.BLASTOISE, Species.PIDGEOT, Species.ABRA]; +const defaultParty = [ Species.BLASTOISE, Species.PIDGEOT, Species.ABRA ]; const defaultBiome = Biome.SEA; const defaultWave = 33; @@ -41,8 +42,8 @@ describe("Lost at Sea - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.SEA, [MysteryEncounterType.LOST_AT_SEA]], - [Biome.MOUNTAIN, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.SEA, [ MysteryEncounterType.LOST_AT_SEA ]], + [ Biome.MOUNTAIN, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]) ); }); @@ -86,8 +87,8 @@ describe("Lost at Sea - Mystery Encounter", () => { const onInitResult = onInit!(scene); expect(LostAtSeaEncounter.dialogueTokens?.damagePercentage).toBe("25"); - expect(LostAtSeaEncounter.dialogueTokens?.option1RequiredMove).toBe("move:surf.name"); - expect(LostAtSeaEncounter.dialogueTokens?.option2RequiredMove).toBe("move:fly.name"); + expect(LostAtSeaEncounter.dialogueTokens?.option1RequiredMove).toBe(i18next.t("move:surf.name")); + expect(LostAtSeaEncounter.dialogueTokens?.option2RequiredMove).toBe(i18next.t("move:fly.name")); expect(onInitResult).toBe(true); }); @@ -134,7 +135,7 @@ describe("Lost at Sea - Mystery Encounter", () => { }); it("should be disabled if no surfable PKM is in party", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, [Species.ARCANINE]); + await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, [ Species.ARCANINE ]); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.getCurrentPhase(); @@ -199,7 +200,7 @@ describe("Lost at Sea - Mystery Encounter", () => { }); it("should be disabled if no flyable PKM is in party", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, [Species.ARCANINE]); + await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, [ Species.ARCANINE ]); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.getCurrentPhase(); diff --git a/src/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts b/src/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts index b8df60b60ec..7bbc505dd8e 100644 --- a/src/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts @@ -22,7 +22,7 @@ import { CommandPhase } from "#app/phases/command-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; const namespace = "mysteryEncounters/mysteriousChallengers"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -44,10 +44,10 @@ describe("Mysterious Challengers - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.FIGHT_OR_FLIGHT]], + [ Biome.VOLCANO, [ MysteryEncounterType.FIGHT_OR_FLIGHT ]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]); + biomeMap.set(biome, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); diff --git a/src/test/mystery-encounter/encounters/part-timer-encounter.test.ts b/src/test/mystery-encounter/encounters/part-timer-encounter.test.ts index e359c4fd575..ba8ce648a3f 100644 --- a/src/test/mystery-encounter/encounters/part-timer-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/part-timer-encounter.test.ts @@ -17,7 +17,7 @@ import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; const namespace = "mysteryEncounters/partTimer"; // Pyukumuku for lowest speed, Regieleki for highest speed, Feebas for lowest "bulk", Melmetal for highest "bulk" -const defaultParty = [Species.PYUKUMUKU, Species.REGIELEKI, Species.FEEBAS, Species.MELMETAL]; +const defaultParty = [ Species.PYUKUMUKU, Species.REGIELEKI, Species.FEEBAS, Species.MELMETAL ]; const defaultBiome = Biome.PLAINS; const defaultWave = 37; @@ -39,10 +39,10 @@ describe("Part-Timer - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]); CIVILIZATION_ENCOUNTER_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.PART_TIMER]); + biomeMap.set(biome, [ MysteryEncounterType.PART_TIMER ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -122,7 +122,7 @@ describe("Part-Timer - Mystery Encounter", () => { // Override party levels to 50 so stats can be fully reflective scene.getParty().forEach(p => { p.level = 50; - p.ivs = [20, 20, 20, 20, 20, 20]; + p.ivs = [ 20, 20, 20, 20, 20, 20 ]; p.calculateStats(); }); await runMysteryEncounterToEnd(game, 1, { pokemonNo: 2 }); @@ -187,7 +187,7 @@ describe("Part-Timer - Mystery Encounter", () => { // Override party levels to 50 so stats can be fully reflective scene.getParty().forEach(p => { p.level = 50; - p.ivs = [20, 20, 20, 20, 20, 20]; + p.ivs = [ 20, 20, 20, 20, 20, 20 ]; p.calculateStats(); }); await runMysteryEncounterToEnd(game, 2, { pokemonNo: 4 }); @@ -256,7 +256,7 @@ describe("Part-Timer - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.PART_TIMER, defaultParty); // Mock moveset - scene.getParty()[0].moveset = [new PokemonMove(Moves.ATTRACT)]; + scene.getParty()[0].moveset = [ new PokemonMove(Moves.ATTRACT) ]; await runMysteryEncounterToEnd(game, 3); expect(EncounterPhaseUtils.updatePlayerMoney).toHaveBeenCalledWith(scene, scene.getWaveMoneyAmount(2.5), true, false); diff --git a/src/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts b/src/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts index b12452f0a77..02375d83b98 100644 --- a/src/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts @@ -1,28 +1,29 @@ -import * as MysteryEncounters from "#app/data/mystery-encounters/mystery-encounters"; -import { Biome } from "#app/enums/biome"; -import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; -import { Species } from "#app/enums/species"; -import GameManager from "#app/test/utils/gameManager"; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; +import { TeleportingHijinksEncounter } from "#app/data/mystery-encounters/encounters/teleporting-hijinks-encounter"; +import * as MysteryEncounters from "#app/data/mystery-encounters/mystery-encounters"; +import { Abilities } from "#enums/abilities"; +import { Biome } from "#enums/biome"; +import { MysteryEncounterType } from "#enums/mystery-encounter-type"; +import { Species } from "#enums/species"; +import { CommandPhase } from "#app/phases/command-phase"; +import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; +import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; +import GameManager from "#test/utils/gameManager"; +import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; +import { Mode } from "#app/ui/ui"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; -import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; -import { CommandPhase } from "#app/phases/command-phase"; -import { TeleportingHijinksEncounter } from "#app/data/mystery-encounters/encounters/teleporting-hijinks-encounter"; -import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; -import { Mode } from "#app/ui/ui"; -import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; -import { Abilities } from "#app/enums/abilities"; +import i18next from "i18next"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const namespace = "mysteryEncounters/teleportingHijinks"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; -const TRANSPORT_BIOMES = [Biome.SPACE, Biome.ISLAND, Biome.LABORATORY, Biome.FAIRY_CAVE, Biome.WASTELAND, Biome.DOJO]; +const TRANSPORT_BIOMES = [ Biome.SPACE, Biome.ISLAND, Biome.LABORATORY, Biome.FAIRY_CAVE, Biome.WASTELAND, Biome.DOJO ]; describe("Teleporting Hijinks - Mystery Encounter", () => { let phaserGame: Phaser.Game; @@ -47,7 +48,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.TELEPORTING_HIJINKS]], + [ Biome.CAVE, [ MysteryEncounterType.TELEPORTING_HIJINKS ]], ]) ); }); @@ -180,7 +181,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); const enemyField = scene.getEnemyField(); - expect(enemyField[0].summonData.statStages).toEqual([0, 1, 0, 1, 1, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 0, 1, 0, 1, 1, 0, 0 ]); expect(enemyField[0].isBoss()).toBe(true); }); @@ -189,7 +190,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); const enemyField = scene.getEnemyField(); - expect(enemyField[0].summonData.statStages).toEqual([1, 1, 1, 1, 1, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 1, 1, 1, 1, 1, 0, 0 ]); expect(enemyField[0].isBoss()).toBe(true); }); }); @@ -212,7 +213,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { }); it("should NOT be selectable if the player doesn't the right type pokemon", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [Species.BLASTOISE]); + await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [ Species.BLASTOISE ]); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.getCurrentPhase(); @@ -231,14 +232,14 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { }); it("should be selectable if the player has the right type pokemon", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [Species.METAGROSS]); + await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [ Species.METAGROSS ]); await runMysteryEncounterToEnd(game, 2, undefined, true); expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); }); it("should transport to a new area", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [Species.PIKACHU]); + await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [ Species.PIKACHU ]); const previousBiome = scene.arena.biomeType; @@ -249,19 +250,19 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { }); it("should start a battle against an enraged boss below wave 50", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [Species.PIKACHU]); + await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [ Species.PIKACHU ]); await runMysteryEncounterToEnd(game, 2, undefined, true); const enemyField = scene.getEnemyField(); - expect(enemyField[0].summonData.statStages).toEqual([0, 1, 0, 1, 1, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 0, 1, 0, 1, 1, 0, 0 ]); expect(enemyField[0].isBoss()).toBe(true); }); it("should start a battle against an extra enraged boss above wave 50", { retry: 5 }, async () => { game.override.startingWave(56); - await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [Species.PIKACHU]); + await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [ Species.PIKACHU ]); await runMysteryEncounterToEnd(game, 2, undefined, true); const enemyField = scene.getEnemyField(); - expect(enemyField[0].summonData.statStages).toEqual([1, 1, 1, 1, 1, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 1, 1, 1, 1, 1, 0, 0 ]); expect(enemyField[0].isBoss()).toBe(true); }); }); @@ -286,7 +287,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty); await runMysteryEncounterToEnd(game, 3, undefined, true); const enemyField = scene.getEnemyField(); - expect(enemyField[0].summonData.statStages).toEqual([0, 0, 0, 0, 0, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 0, 0, 0, 0, 0, 0, 0 ]); expect(enemyField[0].isBoss()).toBe(true); }); @@ -300,8 +301,8 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; - expect(modifierSelectHandler.options.some(opt => opt.modifierTypeOption.type.name === "modifierType:AttackTypeBoosterItem.metal_coat")).toBe(true); - expect(modifierSelectHandler.options.some(opt => opt.modifierTypeOption.type.name === "modifierType:AttackTypeBoosterItem.magnet")).toBe(true); + expect(modifierSelectHandler.options.some(opt => opt.modifierTypeOption.type.name === i18next.t("modifierType:AttackTypeBoosterItem.metal_coat"))).toBe(true); + expect(modifierSelectHandler.options.some(opt => opt.modifierTypeOption.type.name === i18next.t("modifierType:AttackTypeBoosterItem.magnet"))).toBe(true); }); }); }); diff --git a/src/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts b/src/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts index a0120522fd2..a3a43815ec6 100644 --- a/src/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts @@ -20,7 +20,7 @@ import { EggTier } from "#enums/egg-type"; import { PostMysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; const namespace = "mysteryEncounters/theExpertPokemonBreeder"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -42,10 +42,10 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.FIGHT_OR_FLIGHT]], + [ Biome.VOLCANO, [ MysteryEncounterType.FIGHT_OR_FLIGHT ]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER]); + biomeMap.set(biome, [ MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -124,10 +124,31 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { }); }); - it("should start battle against the trainer", async () => { + it("should start battle against the trainer with correctly loaded assets", async () => { await game.runToMysteryEncounter(MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER, defaultParty); + + let successfullyLoaded = false; + vi.spyOn(scene, "getEnemyParty").mockImplementation(() => { + const ace = scene.currentBattle?.enemyParty[0]; + if (ace) { + // Pretend that loading assets takes an extra 500ms + vi.spyOn(ace, "loadAssets").mockImplementation(() => new Promise(resolve => { + setTimeout(() => { + successfullyLoaded = true; + resolve(); + }, 500); + })); + } + + return scene.currentBattle?.enemyParty ?? []; + }); + await runMysteryEncounterToEnd(game, 1, undefined, true); + // Check that assets are successfully loaded + expect(successfullyLoaded).toBe(true); + + // Check usual battle stuff expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(scene.currentBattle.trainer).toBeDefined(); expect(scene.currentBattle.mysteryEncounter?.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE); @@ -155,7 +176,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + commonEggs + rareEggs).toBe(eggsAfter.length); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); - expect(eggsAfter.filter(egg => egg.tier === EggTier.GREAT).length).toBe(rareEggs); + expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); game.phaseInterceptor.superEndPhase(); await game.phaseInterceptor.to(PostMysteryEncounterPhase); @@ -182,10 +203,31 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { }); }); - it("should start battle against the trainer", async () => { + it("should start battle against the trainer with correctly loaded assets", async () => { await game.runToMysteryEncounter(MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER, defaultParty); + + let successfullyLoaded = false; + vi.spyOn(scene, "getEnemyParty").mockImplementation(() => { + const ace = scene.currentBattle?.enemyParty[0]; + if (ace) { + // Pretend that loading assets takes an extra 500ms + vi.spyOn(ace, "loadAssets").mockImplementation(() => new Promise(resolve => { + setTimeout(() => { + successfullyLoaded = true; + resolve(); + }, 500); + })); + } + + return scene.currentBattle?.enemyParty ?? []; + }); + await runMysteryEncounterToEnd(game, 2, undefined, true); + // Check that assets are successfully loaded + expect(successfullyLoaded).toBe(true); + + // Check usual battle stuff expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(scene.currentBattle.trainer).toBeDefined(); expect(scene.currentBattle.mysteryEncounter?.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE); @@ -213,7 +255,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + commonEggs + rareEggs).toBe(eggsAfter.length); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); - expect(eggsAfter.filter(egg => egg.tier === EggTier.GREAT).length).toBe(rareEggs); + expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); game.phaseInterceptor.superEndPhase(); await game.phaseInterceptor.to(PostMysteryEncounterPhase); @@ -240,10 +282,31 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { }); }); - it("should start battle against the trainer", async () => { + it("should start battle against the trainer with correctly loaded assets", async () => { await game.runToMysteryEncounter(MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER, defaultParty); + + let successfullyLoaded = false; + vi.spyOn(scene, "getEnemyParty").mockImplementation(() => { + const ace = scene.currentBattle?.enemyParty[0]; + if (ace) { + // Pretend that loading assets takes an extra 500ms + vi.spyOn(ace, "loadAssets").mockImplementation(() => new Promise(resolve => { + setTimeout(() => { + successfullyLoaded = true; + resolve(); + }, 500); + })); + } + + return scene.currentBattle?.enemyParty ?? []; + }); + await runMysteryEncounterToEnd(game, 3, undefined, true); + // Check that assets are successfully loaded + expect(successfullyLoaded).toBe(true); + + // Check usual battle stuff expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(scene.currentBattle.trainer).toBeDefined(); expect(scene.currentBattle.mysteryEncounter?.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE); @@ -271,7 +334,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + commonEggs + rareEggs).toBe(eggsAfter.length); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); - expect(eggsAfter.filter(egg => egg.tier === EggTier.GREAT).length).toBe(rareEggs); + expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); game.phaseInterceptor.superEndPhase(); await game.phaseInterceptor.to(PostMysteryEncounterPhase); diff --git a/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts b/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts index 24994b61b83..040381c4ac3 100644 --- a/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts @@ -16,7 +16,7 @@ import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; const namespace = "mysteryEncounters/thePokemonSalesman"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -38,10 +38,10 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.THE_POKEMON_SALESMAN]); + biomeMap.set(biome, [ MysteryEncounterType.THE_POKEMON_SALESMAN ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -147,8 +147,8 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { expect(scene.getParty().length).toBe(initialPartySize + 1); - const newlyPurchasedPokemon = scene.getParty().find(p => p.name === pokemonName); - expect(newlyPurchasedPokemon).toBeDefined(); + const newlyPurchasedPokemon = scene.getParty()[scene.getParty().length - 1]; + expect(newlyPurchasedPokemon.name).toBe(pokemonName); expect(newlyPurchasedPokemon!.moveset.length > 0).toBeTruthy(); }); diff --git a/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts b/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts index 3df2f35f02b..4d95ff31d36 100644 --- a/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts @@ -21,14 +21,14 @@ import { BerryModifier, PokemonBaseStatTotalModifier } from "#app/modifier/modif import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; -import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { CommandPhase } from "#app/phases/command-phase"; import { MovePhase } from "#app/phases/move-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import { Abilities } from "#app/enums/abilities"; const namespace = "mysteryEncounters/theStrongStuff"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -54,8 +54,8 @@ describe("The Strong Stuff - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.THE_STRONG_STUFF]], - [Biome.MOUNTAIN, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + [ Biome.CAVE, [ MysteryEncounterType.THE_STRONG_STUFF ]], + [ Biome.MOUNTAIN, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], ]) ); }); @@ -109,11 +109,11 @@ describe("The Strong Stuff - Mystery Encounter", () => { species: getPokemonSpecies(Species.SHUCKLE), isBoss: true, bossSegments: 5, - mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ spriteScale: 1.25 }), + customPokemonData: new CustomPokemonData({ spriteScale: 1.25 }), nature: Nature.BOLD, - moveSet: [Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER], + moveSet: [ Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER ], modifierConfigs: expect.any(Array), - tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ], mysteryEncounterBattleEffects: expect.any(Function) } ], @@ -194,7 +194,7 @@ describe("The Strong Stuff - Mystery Encounter", () => { expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(enemyField.length).toBe(1); expect(enemyField[0].species.speciesId).toBe(Species.SHUCKLE); - expect(enemyField[0].summonData.statStages).toEqual([0, 2, 0, 2, 0, 0, 0]); + expect(enemyField[0].summonData.statStages).toEqual([ 0, 2, 0, 2, 0, 0, 0 ]); const shuckleItems = enemyField[0].getHeldItems(); expect(shuckleItems.length).toBe(5); expect(shuckleItems.find(m => m instanceof BerryModifier && m.berryType === BerryType.SITRUS)?.stackCount).toBe(1); @@ -202,7 +202,7 @@ describe("The Strong Stuff - Mystery Encounter", () => { expect(shuckleItems.find(m => m instanceof BerryModifier && m.berryType === BerryType.GANLON)?.stackCount).toBe(1); expect(shuckleItems.find(m => m instanceof BerryModifier && m.berryType === BerryType.APICOT)?.stackCount).toBe(1); expect(shuckleItems.find(m => m instanceof BerryModifier && m.berryType === BerryType.LUM)?.stackCount).toBe(2); - expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.INFESTATION), new PokemonMove(Moves.SALT_CURE), new PokemonMove(Moves.GASTRO_ACID), new PokemonMove(Moves.HEAL_ORDER)]); + expect(enemyField[0].moveset).toEqual([ new PokemonMove(Moves.INFESTATION), new PokemonMove(Moves.SALT_CURE), new PokemonMove(Moves.GASTRO_ACID), new PokemonMove(Moves.HEAL_ORDER) ]); // Should have used moves pre-battle const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); diff --git a/src/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts b/src/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts index 93f01200203..2653b76ab7c 100644 --- a/src/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts @@ -27,7 +27,7 @@ import { PartyHealPhase } from "#app/phases/party-heal-phase"; import { VictoryPhase } from "#app/phases/victory-phase"; const namespace = "mysteryEncounters/theWinstrateChallenge"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -49,10 +49,10 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { game.override.disableTrainerWaves(); const biomeMap = new Map([ - [Biome.VOLCANO, [MysteryEncounterType.FIGHT_OR_FLIGHT]], + [ Biome.VOLCANO, [ MysteryEncounterType.FIGHT_OR_FLIGHT ]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.THE_WINSTRATE_CHALLENGE]); + biomeMap.set(biome, [ MysteryEncounterType.THE_WINSTRATE_CHALLENGE ]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -114,7 +114,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 0, // Soundproof nature: Nature.MODEST, - moveSet: [Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE], + moveSet: [ Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE ], modifierConfigs: expect.any(Array) }, { @@ -122,7 +122,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 2, // Gluttony nature: Nature.QUIET, - moveSet: [Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE], + moveSet: [ Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE ], modifierConfigs: expect.any(Array) }, { @@ -130,7 +130,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 2, // Tangled Feet nature: Nature.JOLLY, - moveSet: [Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF], + moveSet: [ Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF ], modifierConfigs: expect.any(Array) }, { @@ -138,7 +138,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, formIndex: 1, nature: Nature.BOLD, - moveSet: [Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT], + moveSet: [ Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT ], modifierConfigs: expect.any(Array) }, { @@ -146,7 +146,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 0, // Sheer Force nature: Nature.IMPISH, - moveSet: [Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE], + moveSet: [ Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE ], modifierConfigs: expect.any(Array) } ] @@ -159,7 +159,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, formIndex: 1, nature: Nature.IMPISH, - moveSet: [Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH], + moveSet: [ Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH ], modifierConfigs: expect.any(Array) } ] @@ -172,7 +172,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 3, // Lightning Rod nature: Nature.ADAMANT, - moveSet: [Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST], + moveSet: [ Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST ], modifierConfigs: expect.any(Array) }, { @@ -180,7 +180,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 1, // Poison Heal nature: Nature.JOLLY, - moveSet: [Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH], + moveSet: [ Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH ], modifierConfigs: expect.any(Array) }, { @@ -188,7 +188,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, formIndex: 1, nature: Nature.CALM, - moveSet: [Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT], + moveSet: [ Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT ], modifierConfigs: expect.any(Array) } ] @@ -201,7 +201,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 0, // Natural Cure nature: Nature.CALM, - moveSet: [Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER], + moveSet: [ Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER ], modifierConfigs: expect.any(Array) }, { @@ -209,7 +209,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, formIndex: 1, nature: Nature.TIMID, - moveSet: [Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP], + moveSet: [ Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP ], modifierConfigs: expect.any(Array) } ] @@ -222,7 +222,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 0, // Guts nature: Nature.ADAMANT, - moveSet: [Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK], + moveSet: [ Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK ], modifierConfigs: expect.any(Array) }, { @@ -230,7 +230,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { isBoss: false, abilityIndex: 1, // Guts nature: Nature.ADAMANT, - moveSet: [Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH], + moveSet: [ Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH ], modifierConfigs: expect.any(Array) } ] diff --git a/src/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts b/src/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts index 7e92d17ba25..8286c6a694b 100644 --- a/src/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts @@ -24,7 +24,7 @@ import { CommandPhase } from "#app/phases/command-phase"; import { MovePhase } from "#app/phases/move-phase"; const namespace = "mysteryEncounters/trashToTreasure"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -47,7 +47,7 @@ describe("Trash to Treasure - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.TRASH_TO_TREASURE]], + [ Biome.CAVE, [ MysteryEncounterType.TRASH_TO_TREASURE ]], ]) ); }); @@ -86,7 +86,7 @@ describe("Trash to Treasure - Mystery Encounter", () => { expect(TrashToTreasureEncounter.enemyPartyConfigs).toEqual([ { - levelAdditiveModifier: 1, + levelAdditiveModifier: 0.5, disableSwitch: true, pokemonConfigs: [ { @@ -94,7 +94,7 @@ describe("Trash to Treasure - Mystery Encounter", () => { isBoss: true, formIndex: 1, bossSegmentModifier: 1, - moveSet: [Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH], + moveSet: [ Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH ], } ], } @@ -175,7 +175,7 @@ describe("Trash to Treasure - Mystery Encounter", () => { expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(enemyField.length).toBe(1); expect(enemyField[0].species.speciesId).toBe(Species.GARBODOR); - expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.PAYBACK), new PokemonMove(Moves.GUNK_SHOT), new PokemonMove(Moves.STOMPING_TANTRUM), new PokemonMove(Moves.DRAIN_PUNCH)]); + expect(enemyField[0].moveset).toEqual([ new PokemonMove(Moves.PAYBACK), new PokemonMove(Moves.GUNK_SHOT), new PokemonMove(Moves.STOMPING_TANTRUM), new PokemonMove(Moves.DRAIN_PUNCH) ]); // Should have used moves pre-battle const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); diff --git a/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts b/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts index fa3c97b56ce..fa1b5ecdeb7 100644 --- a/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts @@ -27,7 +27,7 @@ import { modifierTypes } from "#app/modifier/modifier-type"; import { Abilities } from "#enums/abilities"; const namespace = "mysteryEncounters/uncommonBreed"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [ Species.LAPRAS, Species.GENGAR, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -53,7 +53,7 @@ describe("Uncommon Breed - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.UNCOMMON_BREED]], + [ Biome.CAVE, [ MysteryEncounterType.UNCOMMON_BREED ]], ]) ); }); @@ -126,7 +126,7 @@ describe("Uncommon Breed - Mystery Encounter", () => { expect(enemyField[0].species.speciesId).toBe(speciesToSpawn); const statStagePhases = unshiftPhaseSpy.mock.calls.filter(p => p[0] instanceof StatStageChangePhase)[0][0] as any; - expect(statStagePhases.stats).toEqual([Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD]); + expect(statStagePhases.stats).toEqual([ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ]); // Should have used its egg move pre-battle const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); @@ -153,7 +153,7 @@ describe("Uncommon Breed - Mystery Encounter", () => { expect(enemyField[0].species.speciesId).toBe(speciesToSpawn); const statStagePhases = unshiftPhaseSpy.mock.calls.filter(p => p[0] instanceof StatStageChangePhase)[0][0] as any; - expect(statStagePhases.stats).toEqual([Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD]); + expect(statStagePhases.stats).toEqual([ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ]); // Should have used its egg move pre-battle const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); @@ -213,11 +213,11 @@ describe("Uncommon Breed - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty); // Berries on party lead - const sitrus = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS])!; + const sitrus = generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ])!; const sitrusMod = sitrus.newModifier(scene.getParty()[0]) as BerryModifier; sitrusMod.stackCount = 2; await scene.addModifier(sitrusMod, true, false, false, true); - const ganlon = generateModifierType(scene, modifierTypes.BERRY, [BerryType.GANLON])!; + const ganlon = generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ])!; const ganlonMod = ganlon.newModifier(scene.getParty()[0]) as BerryModifier; ganlonMod.stackCount = 3; await scene.addModifier(ganlonMod, true, false, false, true); @@ -270,7 +270,7 @@ describe("Uncommon Breed - Mystery Encounter", () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty); // Mock moveset - scene.getParty()[0].moveset = [new PokemonMove(Moves.CHARM)]; + scene.getParty()[0].moveset = [ new PokemonMove(Moves.CHARM) ]; await runMysteryEncounterToEnd(game, 3); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); diff --git a/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts b/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts index fdf9634e383..c1fa6d83a18 100644 --- a/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts @@ -5,7 +5,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { Mode } from "#app/ui/ui"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; @@ -15,9 +15,11 @@ import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; import { WeirdDreamEncounter } from "#app/data/mystery-encounters/encounters/weird-dream-encounter"; import * as EncounterTransformationSequence from "#app/data/mystery-encounters/utils/encounter-transformation-sequence"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; +import { CommandPhase } from "#app/phases/command-phase"; +import { ModifierTier } from "#app/modifier/modifier-tier"; const namespace = "mysteryEncounters/weirdDream"; -const defaultParty = [Species.MAGBY, Species.HAUNTER, Species.ABRA]; +const defaultParty = [ Species.MAGBY, Species.HAUNTER, Species.ABRA ]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -41,7 +43,7 @@ describe("Weird Dream - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.CAVE, [MysteryEncounterType.WEIRD_DREAM]], + [ Biome.CAVE, [ MysteryEncounterType.WEIRD_DREAM ]], ]) ); }); @@ -70,7 +72,7 @@ describe("Weird Dream - Mystery Encounter", () => { expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`); expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}:description`); expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}:query`); - expect(WeirdDreamEncounter.options.length).toBe(2); + expect(WeirdDreamEncounter.options.length).toBe(3); }); it("should initialize fully", async () => { @@ -122,7 +124,7 @@ describe("Weird Dream - Mystery Encounter", () => { for (let i = 0; i < pokemonAfter.length; i++) { const newPokemon = pokemonAfter[i]; expect(newPokemon.getSpeciesForm().speciesId).not.toBe(pokemonPrior[i].getSpeciesForm().speciesId); - expect(newPokemon.mysteryEncounterPokemonData?.types.length).toBe(2); + expect(newPokemon.customPokemonData?.types.length).toBe(2); } const plus90To110 = bstDiff.filter(bst => bst > 80); @@ -132,7 +134,7 @@ describe("Weird Dream - Mystery Encounter", () => { expect(plus40To50.length).toBe(1); }); - it("should have 1 Memory Mushroom, 5 Rogue Balls, and 2 Mints in rewards", async () => { + it("should have 1 Memory Mushroom, 5 Rogue Balls, and 3 Mints in rewards", async () => { await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); await runMysteryEncounterToEnd(game, 1); await game.phaseInterceptor.to(SelectModifierPhase, false); @@ -141,11 +143,12 @@ describe("Weird Dream - Mystery Encounter", () => { expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; - expect(modifierSelectHandler.options.length).toEqual(4); + expect(modifierSelectHandler.options.length).toEqual(5); expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toEqual("MEMORY_MUSHROOM"); expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toEqual("ROGUE_BALL"); expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toEqual("MINT"); expect(modifierSelectHandler.options[3].modifierTypeOption.type.id).toEqual("MINT"); + expect(modifierSelectHandler.options[3].modifierTypeOption.type.id).toEqual("MINT"); }); it("should leave encounter without battle", async () => { @@ -158,7 +161,7 @@ describe("Weird Dream - Mystery Encounter", () => { }); }); - describe("Option 2 - Leave", () => { + describe("Option 2 - Battle Future Self", () => { it("should have the correct properties", () => { const option = WeirdDreamEncounter.options[1]; expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); @@ -174,17 +177,63 @@ describe("Weird Dream - Mystery Encounter", () => { }); }); - it("should reduce party levels by 12.5%", async () => { + it("should start a battle against the player's transformation team", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); + await runMysteryEncounterToEnd(game, 2, undefined, true); + + const enemyField = scene.getEnemyField(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyField.length).toBe(1); + expect(scene.getEnemyParty().length).toBe(scene.getParty().length); + }); + + it("should have 2 Rogue/2 Ultra/2 Great items in rewards", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); + await runMysteryEncounterToEnd(game, 2, undefined, true); + await skipBattleRunMysteryEncounterRewardsPhase(game); + await game.phaseInterceptor.to(SelectModifierPhase, false); + expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); + await game.phaseInterceptor.run(SelectModifierPhase); + + expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); + const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; + expect(modifierSelectHandler.options.length).toEqual(6); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.tier - modifierSelectHandler.options[0].modifierTypeOption.upgradeCount).toEqual(ModifierTier.ROGUE); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.tier - modifierSelectHandler.options[1].modifierTypeOption.upgradeCount).toEqual(ModifierTier.ROGUE); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.tier - modifierSelectHandler.options[2].modifierTypeOption.upgradeCount).toEqual(ModifierTier.ULTRA); + expect(modifierSelectHandler.options[3].modifierTypeOption.type.tier - modifierSelectHandler.options[3].modifierTypeOption.upgradeCount).toEqual(ModifierTier.ULTRA); + expect(modifierSelectHandler.options[4].modifierTypeOption.type.tier - modifierSelectHandler.options[4].modifierTypeOption.upgradeCount).toEqual(ModifierTier.GREAT); + expect(modifierSelectHandler.options[5].modifierTypeOption.type.tier - modifierSelectHandler.options[5].modifierTypeOption.upgradeCount).toEqual(ModifierTier.GREAT); + }); + }); + + describe("Option 3 - Leave", () => { + it("should have the correct properties", () => { + const option = WeirdDreamEncounter.options[2]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ + buttonLabel: `${namespace}:option.3.label`, + buttonTooltip: `${namespace}:option.3.tooltip`, + selected: [ + { + text: `${namespace}:option.3.selected`, + }, + ], + }); + }); + + it("should reduce party levels by 10%", async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); const levelsPrior = scene.getParty().map(p => p.level); - await runMysteryEncounterToEnd(game, 2); + await runMysteryEncounterToEnd(game, 3); const levelsAfter = scene.getParty().map(p => p.level); for (let i = 0; i < levelsPrior.length; i++) { - expect(Math.max(Math.ceil(0.8875 * levelsPrior[i]), 1)).toBe(levelsAfter[i]); + expect(Math.max(Math.ceil(0.9 * levelsPrior[i]), 1)).toBe(levelsAfter[i]); expect(scene.getParty()[i].levelExp).toBe(0); } @@ -195,7 +244,7 @@ describe("Weird Dream - Mystery Encounter", () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); - await runMysteryEncounterToEnd(game, 2); + await runMysteryEncounterToEnd(game, 3); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); }); diff --git a/src/test/mystery-encounter/mystery-encounter-utils.test.ts b/src/test/mystery-encounter/mystery-encounter-utils.test.ts index 7541379be07..134966a188d 100644 --- a/src/test/mystery-encounter/mystery-encounter-utils.test.ts +++ b/src/test/mystery-encounter/mystery-encounter-utils.test.ts @@ -31,7 +31,7 @@ describe("Mystery Encounter Utils", () => { beforeEach(() => { game = new GameManager(phaserGame); scene = game.scene; - initSceneWithoutEncounterPhase(game.scene, [Species.ARCEUS, Species.MANAPHY]); + initSceneWithoutEncounterPhase(game.scene, [ Species.ARCEUS, Species.MANAPHY ]); }); describe("getRandomPlayerPokemon", () => { @@ -214,7 +214,7 @@ describe("Mystery Encounter Utils", () => { }); it("gets species for a starter tier range", () => { - const result = getRandomSpeciesByStarterTier([5, 8]); + const result = getRandomSpeciesByStarterTier([ 5, 8 ]); const pokeSpecies = getPokemonSpecies(result); expect(pokeSpecies.speciesId).toBe(result); @@ -224,14 +224,14 @@ describe("Mystery Encounter Utils", () => { it("excludes species from search", () => { // Only 9 tiers are: Koraidon, Miraidon, Arceus, Rayquaza, Kyogre, Groudon, Zacian - const result = getRandomSpeciesByStarterTier(9, [Species.KORAIDON, Species.MIRAIDON, Species.ARCEUS, Species.RAYQUAZA, Species.KYOGRE, Species.GROUDON]); + const result = getRandomSpeciesByStarterTier(9, [ Species.KORAIDON, Species.MIRAIDON, Species.ARCEUS, Species.RAYQUAZA, Species.KYOGRE, Species.GROUDON ]); const pokeSpecies = getPokemonSpecies(result); expect(pokeSpecies.speciesId).toBe(Species.ZACIAN); }); it("gets species of specified types", () => { // Only 9 tiers are: Koraidon, Miraidon, Arceus, Rayquaza, Kyogre, Groudon, Zacian - const result = getRandomSpeciesByStarterTier(9, undefined, [Type.GROUND]); + const result = getRandomSpeciesByStarterTier(9, undefined, [ Type.GROUND ]); const pokeSpecies = getPokemonSpecies(result); expect(pokeSpecies.speciesId).toBe(Species.GROUDON); }); diff --git a/src/test/mystery-encounter/mystery-encounter.test.ts b/src/test/mystery-encounter/mystery-encounter.test.ts index 38c999f8aac..eaf6e04a639 100644 --- a/src/test/mystery-encounter/mystery-encounter.test.ts +++ b/src/test/mystery-encounter/mystery-encounter.test.ts @@ -29,7 +29,7 @@ describe("Mystery Encounters", () => { }); it("Spawns a mystery encounter", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]); + await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [ Species.CHARIZARD, Species.VOLCARONA ]); await game.phaseInterceptor.to(MysteryEncounterPhase, false); expect(game.scene.getCurrentPhase()!.constructor.name).toBe(MysteryEncounterPhase.name); diff --git a/src/test/phases/frenzy-move-reset.test.ts b/src/test/phases/frenzy-move-reset.test.ts new file mode 100644 index 00000000000..db9ec2bfe66 --- /dev/null +++ b/src/test/phases/frenzy-move-reset.test.ts @@ -0,0 +1,72 @@ +import { BattlerIndex } from "#app/battle"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { StatusEffect } from "#enums/status-effect"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest"; + +describe("Frenzy Move Reset", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleType("single") + .disableCrits() + .starterSpecies(Species.MAGIKARP) + .moveset(Moves.THRASH) + .statusEffect(StatusEffect.PARALYSIS) + .enemyMoveset(Moves.SPLASH) + .enemyLevel(100) + .enemySpecies(Species.SHUCKLE) + .enemyAbility(Abilities.BALL_FETCH); + }); + + /* + * Thrash (or frenzy moves in general) should not continue to run if attack fails due to paralysis + * + * This is a 3-turn Thrash test: + * 1. Thrash is selected and succeeds to hit the enemy -> Enemy Faints + * + * 2. Thrash is automatically selected but misses due to paralysis + * Note: After missing the Pokemon should stop automatically attacking + * + * 3. At the start of the 3rd turn the Player should be able to select a move/switch Pokemon/etc. + * Note: This means that BattlerTag.FRENZY is not anymore in pokemon.summonData.tags and pokemon.summonData.moveQueue is empty + * + */ + it("should cancel frenzy move if move fails turn 2", async () => { + await game.classicMode.startBattle(); + + const playerPokemon = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.THRASH); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.move.forceStatusActivation(false); + await game.toNextTurn(); + + expect(playerPokemon.summonData.moveQueue.length).toBe(2); + expect(playerPokemon.summonData.tags.some(tag => tag.tagType === BattlerTagType.FRENZY)).toBe(true); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.move.forceStatusActivation(true); + await game.toNextTurn(); + + expect(playerPokemon.summonData.moveQueue.length).toBe(0); + expect(playerPokemon.summonData.tags.some(tag => tag.tagType === BattlerTagType.FRENZY)).toBe(false); + }); +}); diff --git a/src/test/phases/learn-move-phase.test.ts b/src/test/phases/learn-move-phase.test.ts index 60cdbee8570..c4fa0e8bf45 100644 --- a/src/test/phases/learn-move-phase.test.ts +++ b/src/test/phases/learn-move-phase.test.ts @@ -25,8 +25,8 @@ describe("Learn Move Phase", () => { }); it("If Pokemon has less than 4 moves, its newest move will be added to the lowest empty index", async () => { - game.override.moveset([Moves.SPLASH]); - await game.startBattle([Species.BULBASAUR]); + game.override.moveset([ Moves.SPLASH ]); + await game.startBattle([ Species.BULBASAUR ]); const pokemon = game.scene.getPlayerPokemon()!; const newMovePos = pokemon?.getMoveset().length; game.move.select(Moves.SPLASH); diff --git a/src/test/phases/mystery-encounter-phase.test.ts b/src/test/phases/mystery-encounter-phase.test.ts index 76b0bd5a905..32e31ce1c94 100644 --- a/src/test/phases/mystery-encounter-phase.test.ts +++ b/src/test/phases/mystery-encounter-phase.test.ts @@ -1,14 +1,15 @@ -import {afterEach, beforeAll, beforeEach, expect, describe, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, expect, describe, it, vi } from "vitest"; import GameManager from "#app/test/utils/gameManager"; import Phaser from "phaser"; -import {Species} from "#enums/species"; +import { Species } from "#enums/species"; import { MysteryEncounterOptionSelectedPhase, MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; -import {Mode} from "#app/ui/ui"; -import {Button} from "#enums/buttons"; +import { Mode } from "#app/ui/ui"; +import { Button } from "#enums/buttons"; import MysteryEncounterUiHandler from "#app/ui/mystery-encounter-ui-handler"; -import {MysteryEncounterType} from "#enums/mystery-encounter-type"; +import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import MessageUiHandler from "#app/ui/message-ui-handler"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import i18next from "i18next"; describe("Mystery Encounter Phases", () => { let phaserGame: Phaser.Game; @@ -34,14 +35,14 @@ describe("Mystery Encounter Phases", () => { describe("MysteryEncounterPhase", () => { it("Runs to MysteryEncounterPhase", async() => { - await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]); + await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [ Species.CHARIZARD, Species.VOLCARONA ]); await game.phaseInterceptor.to(MysteryEncounterPhase, false); expect(game.scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name); }); it("Runs MysteryEncounterPhase", async() => { - await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]); + await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [ Species.CHARIZARD, Species.VOLCARONA ]); game.onNextPrompt("MysteryEncounterPhase", Mode.MYSTERY_ENCOUNTER, () => { // End phase early for test @@ -59,7 +60,7 @@ describe("Mystery Encounter Phases", () => { const { ui } = game.scene; vi.spyOn(ui, "showDialogue"); vi.spyOn(ui, "showText"); - await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]); + await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [ Species.CHARIZARD, Species.VOLCARONA ]); game.onNextPrompt("MysteryEncounterPhase", Mode.MESSAGE, () => { const handler = game.scene.ui.getHandler() as MessageUiHandler; @@ -78,9 +79,9 @@ describe("Mystery Encounter Phases", () => { expect(ui.getMode()).toBe(Mode.MESSAGE); expect(ui.showDialogue).toHaveBeenCalledTimes(1); expect(ui.showText).toHaveBeenCalledTimes(2); - expect(ui.showDialogue).toHaveBeenCalledWith("battle:mysteryEncounterAppeared", "???", null, expect.any(Function)); - expect(ui.showText).toHaveBeenCalledWith("mysteryEncounters/mysteriousChallengers:intro", null, expect.any(Function), 750, true); - expect(ui.showText).toHaveBeenCalledWith("mysteryEncounters/mysteriousChallengers:option.selected", null, expect.any(Function), 300, true); + expect(ui.showDialogue).toHaveBeenCalledWith(i18next.t("battle:mysteryEncounterAppeared"), "???", null, expect.any(Function)); + expect(ui.showText).toHaveBeenCalledWith(i18next.t("mysteryEncounters/mysteriousChallengers:intro"), null, expect.any(Function), 750, true); + expect(ui.showText).toHaveBeenCalledWith(i18next.t("mysteryEncounters/mysteriousChallengers:option.selected"), null, expect.any(Function), 300, true); }); }); diff --git a/src/test/phases/select-modifier-phase.test.ts b/src/test/phases/select-modifier-phase.test.ts index d946c850ae3..a945aff055b 100644 --- a/src/test/phases/select-modifier-phase.test.ts +++ b/src/test/phases/select-modifier-phase.test.ts @@ -28,7 +28,7 @@ describe("SelectModifierPhase", () => { game = new GameManager(phaserGame); scene = game.scene; - initSceneWithoutEncounterPhase(scene, [Species.ABRA, Species.VOLCARONA]); + initSceneWithoutEncounterPhase(scene, [ Species.ABRA, Species.VOLCARONA ]); }); afterEach(() => { @@ -63,11 +63,11 @@ describe("SelectModifierPhase", () => { new ModifierTypeOption(modifierTypes.REVIVE(), 0, 1000) ]; - const selectModifierPhase1 = new SelectModifierPhase(scene); - const selectModifierPhase2 = new SelectModifierPhase(scene, 0, undefined, { rerollMultiplier: 2 }); + const selectModifierPhase1 = new SelectModifierPhase(scene, 0, undefined, { guaranteedModifierTypeOptions: options }); + const selectModifierPhase2 = new SelectModifierPhase(scene, 0, undefined, { guaranteedModifierTypeOptions: options, rerollMultiplier: 2 }); - const cost1 = selectModifierPhase1.getRerollCost(options, false); - const cost2 = selectModifierPhase2.getRerollCost(options, false); + const cost1 = selectModifierPhase1.getRerollCost(false); + const cost2 = selectModifierPhase2.getRerollCost(false); expect(cost2).toEqual(cost1 * 2); }); @@ -81,7 +81,7 @@ describe("SelectModifierPhase", () => { expect(modifierSelectHandler.options.length).toEqual(3); // Simulate selecting reroll - selectModifierPhase = new SelectModifierPhase(scene, 1, [ModifierTier.COMMON, ModifierTier.COMMON, ModifierTier.COMMON]); + selectModifierPhase = new SelectModifierPhase(scene, 1, [ ModifierTier.COMMON, ModifierTier.COMMON, ModifierTier.COMMON ]); scene.unshiftPhase(selectModifierPhase); scene.ui.setMode(Mode.MESSAGE).then(() => game.endPhase()); await game.phaseInterceptor.run(SelectModifierPhase); @@ -94,7 +94,7 @@ describe("SelectModifierPhase", () => { // Just use fully random seed for this test vi.spyOn(scene, "resetSeed").mockImplementation(() => { scene.waveSeed = Utils.shiftCharCodes(scene.seed, 5); - Phaser.Math.RND.sow([scene.waveSeed]); + Phaser.Math.RND.sow([ scene.waveSeed ]); console.log("Wave Seed:", scene.waveSeed, 5); scene.rngCounter = 0; }); @@ -126,7 +126,7 @@ describe("SelectModifierPhase", () => { it("should generate custom modifiers", async () => { const customModifiers: CustomModifierSettings = { - guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_ULTRA, modifierTypes.LEFTOVERS, modifierTypes.AMULET_COIN, modifierTypes.GOLDEN_PUNCH] + guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_ULTRA, modifierTypes.LEFTOVERS, modifierTypes.AMULET_COIN, modifierTypes.GOLDEN_PUNCH ] }; const selectModifierPhase = new SelectModifierPhase(scene, 0, undefined, customModifiers); scene.pushPhase(selectModifierPhase); @@ -145,7 +145,7 @@ describe("SelectModifierPhase", () => { it("should generate custom modifier tiers that can upgrade from luck", async () => { const customModifiers: CustomModifierSettings = { - guaranteedModifierTiers: [ModifierTier.COMMON, ModifierTier.GREAT, ModifierTier.ULTRA, ModifierTier.ROGUE, ModifierTier.MASTER] + guaranteedModifierTiers: [ ModifierTier.COMMON, ModifierTier.GREAT, ModifierTier.ULTRA, ModifierTier.ROGUE, ModifierTier.MASTER ] }; const pokemon = new PlayerPokemon(scene, getPokemonSpecies(Species.BULBASAUR), 10, undefined, 0, undefined, true, 2, undefined, undefined, undefined); @@ -172,8 +172,8 @@ describe("SelectModifierPhase", () => { it("should generate custom modifiers and modifier tiers together", async () => { const customModifiers: CustomModifierSettings = { - guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_COMMON], - guaranteedModifierTiers: [ModifierTier.MASTER, ModifierTier.MASTER] + guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_COMMON ], + guaranteedModifierTiers: [ ModifierTier.MASTER, ModifierTier.MASTER ] }; const selectModifierPhase = new SelectModifierPhase(scene, 0, undefined, customModifiers); scene.pushPhase(selectModifierPhase); @@ -191,8 +191,8 @@ describe("SelectModifierPhase", () => { it("should fill remaining modifiers if fillRemaining is true with custom modifiers", async () => { const customModifiers: CustomModifierSettings = { - guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM], - guaranteedModifierTiers: [ModifierTier.MASTER], + guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM ], + guaranteedModifierTiers: [ ModifierTier.MASTER ], fillRemaining: true }; const selectModifierPhase = new SelectModifierPhase(scene, 0, undefined, customModifiers); diff --git a/src/test/reload.test.ts b/src/test/reload.test.ts index daf8e43a0cd..b15e9691ed6 100644 --- a/src/test/reload.test.ts +++ b/src/test/reload.test.ts @@ -44,15 +44,13 @@ describe("Reload", () => { .startingWave(10) .battleType("single") .startingLevel(100) // Avoid levelling up - .enemyLevel(1000) // Avoid opponent dying before game.doKillOpponents() .disableTrainerWaves() - .moveset([Moves.KOWTOW_CLEAVE]) + .moveset([ Moves.SPLASH ]) .enemyMoveset(Moves.SPLASH); await game.dailyMode.startBattle(); // Transition from Wave 10 to Wave 11 in order to trigger biome switch - game.move.select(Moves.KOWTOW_CLEAVE); - await game.phaseInterceptor.to("DamagePhase"); + game.move.select(Moves.SPLASH); await game.doKillOpponents(); game.onNextPrompt("SelectBiomePhase", Mode.OPTION_SELECT, () => { (game.scene.time as MockClock).overrideDelay = null; @@ -79,15 +77,13 @@ describe("Reload", () => { .startingBiome(Biome.ICE_CAVE) // Will lead to Snowy Forest with randomly generated weather .battleType("single") .startingLevel(100) // Avoid levelling up - .enemyLevel(1000) // Avoid opponent dying before game.doKillOpponents() .disableTrainerWaves() - .moveset([Moves.KOWTOW_CLEAVE]) + .moveset([ Moves.SPLASH ]) .enemyMoveset(Moves.SPLASH); await game.classicMode.startBattle(); // Apparently daily mode would override the biome // Transition from Wave 10 to Wave 11 in order to trigger biome switch - game.move.select(Moves.KOWTOW_CLEAVE); - await game.phaseInterceptor.to("DamagePhase"); + game.move.select(Moves.SPLASH); await game.doKillOpponents(); await game.toNextWave(); expect(game.phaseInterceptor.log).toContain("NewBiomeEncounterPhase"); @@ -161,7 +157,7 @@ describe("Reload", () => { game.override .battleType("single") .startingWave(50); - await game.runToFinalBossEncounter([Species.BULBASAUR], GameModes.DAILY); + await game.runToFinalBossEncounter([ Species.BULBASAUR ], GameModes.DAILY); const preReloadRngState = Phaser.Math.RND.state(); diff --git a/src/test/settingMenu/helpers/menuManip.ts b/src/test/settingMenu/helpers/menuManip.ts index 90b3f1e96e6..0b1f48525f1 100644 --- a/src/test/settingMenu/helpers/menuManip.ts +++ b/src/test/settingMenu/helpers/menuManip.ts @@ -72,7 +72,7 @@ export class MenuManip { const icon = getIconWithKeycode(this.config, this.keycode); const key = getKeyWithKeycode(this.config, this.keycode)!; // TODO: is this bang correct? const _keys = key.toLowerCase().split("_"); - const iconIdentifier = _keys[_keys.length-1]; + const iconIdentifier = _keys[_keys.length - 1]; expect(icon.toLowerCase().includes(iconIdentifier)).toEqual(true); return this; } diff --git a/src/test/settingMenu/rebinding_setting.test.ts b/src/test/settingMenu/rebinding_setting.test.ts index ec2343cfb41..37cf8032897 100644 --- a/src/test/settingMenu/rebinding_setting.test.ts +++ b/src/test/settingMenu/rebinding_setting.test.ts @@ -22,7 +22,7 @@ describe("Test Rebinding", () => { beforeEach(() => { config = deepCopy(cfg_keyboard_qwerty); - config.custom = {...config.default}; + config.custom = { ...config.default }; configs["default"] = config; inGame = new InGameManip(configs, config, selectedDevice); inTheSettingMenu = new MenuManip(config); diff --git a/src/test/sprites/pokemonSprite.test.ts b/src/test/sprites/pokemonSprite.test.ts index faf0626b365..c29f88d3143 100644 --- a/src/test/sprites/pokemonSprite.test.ts +++ b/src/test/sprites/pokemonSprite.test.ts @@ -70,7 +70,7 @@ describe("check if every variant's sprite are correctly set", () => { errors.push(`[${id}] missing key ${id} in masterlist for ${trimmedFilePath}`); } if (mlist[id][index] === 1 && jsonFileExists) { - const raw = fs.readFileSync(urlJsonFile, {encoding: "utf8", flag: "r"}); + const raw = fs.readFileSync(urlJsonFile, { encoding: "utf8", flag: "r" }); const data = JSON.parse(raw); const keys = Object.keys(data); if (!keys.includes(`${index}`)) { @@ -87,7 +87,7 @@ describe("check if every variant's sprite are correctly set", () => { } else if (!mlist.hasOwnProperty(name)) { errors.push(`[${name}] - missing key ${name} in masterlist for ${trimmedFilePath}`); } else { - const raw = fs.readFileSync(filePath, {encoding: "utf8", flag: "r"}); + const raw = fs.readFileSync(filePath, { encoding: "utf8", flag: "r" }); const data = JSON.parse(raw); for (const key of Object.keys(data)) { if (mlist[name][key] !== 1) { @@ -109,14 +109,14 @@ describe("check if every variant's sprite are correctly set", () => { const errors: string[] = []; for (const key of Object.keys(keys)) { const row = keys[key]; - for (const [index, elm] of row.entries()) { + for (const [ index, elm ] of row.entries()) { let url: string; if (elm === 0) { continue; } else if (elm === 1) { url = `${key}.json`; const filePath = `${dirPath}${url}`; - const raw = fs.readFileSync(filePath, {encoding: "utf8", flag: "r"}); + const raw = fs.readFileSync(filePath, { encoding: "utf8", flag: "r" }); const data = JSON.parse(raw); if (!data.hasOwnProperty(index)) { errors.push(`index: ${index} - ${filePath}`); @@ -232,7 +232,7 @@ describe("check if every variant's sprite are correctly set", () => { it("look over every file in variant back male and check if present in masterlist", () => { const dirPath = `${rootDir}back${path.sep}`; const backMaleVariant = deepCopy(backVariant); - const errors = getMissingMasterlist(backMaleVariant, dirPath, ["female"]); + const errors = getMissingMasterlist(backMaleVariant, dirPath, [ "female" ]); if (errors.length) { console.log("errors for ", dirPath, errors); } @@ -259,7 +259,7 @@ describe("check if every variant's sprite are correctly set", () => { it("look over every file in variant exp male and check if present in masterlist", () => { const dirPath = `${rootDir}exp${path.sep}`; - const errors = getMissingMasterlist(expVariant, dirPath, ["back", "female"]); + const errors = getMissingMasterlist(expVariant, dirPath, [ "back", "female" ]); if (errors.length) { console.log("errors for ", dirPath, errors); } @@ -268,7 +268,7 @@ describe("check if every variant's sprite are correctly set", () => { it("look over every file in variant root and check if present in masterlist", () => { const dirPath = `${rootDir}`; - const errors = getMissingMasterlist(masterlist, dirPath, ["back", "female", "exp", "icons"]); + const errors = getMissingMasterlist(masterlist, dirPath, [ "back", "female", "exp", "icons" ]); if (errors.length) { console.log("errors for ", dirPath, errors); } diff --git a/src/test/system/game_data.test.ts b/src/test/system/game_data.test.ts index e3550e44fff..fcb7e9067a3 100644 --- a/src/test/system/game_data.test.ts +++ b/src/test/system/game_data.test.ts @@ -11,13 +11,15 @@ import * as account from "../../account"; const apiBase = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8001"; -export const server = setupServer(); +/** We need a custom server. For some reasons I can't extend the listeners of {@linkcode global.i18nServer} with {@linkcode global.i18nServer.use} */ +const server = setupServer(); describe("System - Game Data", () => { let phaserGame: Phaser.Game; let game: GameManager; beforeAll(() => { + global.i18nServer.close(); server.listen(); phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, @@ -26,12 +28,13 @@ describe("System - Game Data", () => { afterAll(() => { server.close(); + global.i18nServer.listen(); }); beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.SPLASH]) + .moveset([ Moves.SPLASH ]) .battleType("single") .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH); @@ -46,7 +49,7 @@ describe("System - Game Data", () => { beforeEach(() => { vi.spyOn(BattleScene, "bypassLogin", "get").mockReturnValue(false); vi.spyOn(game.scene.gameData, "getSessionSaveData").mockReturnValue({} as SessionSaveData); - vi.spyOn(account, "updateUserInfo").mockImplementation(async () => [true, 1]); + vi.spyOn(account, "updateUserInfo").mockImplementation(async () => [ true, 1 ]); }); it("should return [true, true] if bypassLogin is true", async () => { @@ -54,7 +57,7 @@ describe("System - Game Data", () => { const result = await game.scene.gameData.tryClearSession(game.scene, 0); - expect(result).toEqual([true, true]); + expect(result).toEqual([ true, true ]); }); it("should return [true, true] if successful", async () => { @@ -62,7 +65,7 @@ describe("System - Game Data", () => { const result = await game.scene.gameData.tryClearSession(game.scene, 0); - expect(result).toEqual([true, true]); + expect(result).toEqual([ true, true ]); expect(account.updateUserInfo).toHaveBeenCalled(); }); @@ -71,7 +74,7 @@ describe("System - Game Data", () => { const result = await game.scene.gameData.tryClearSession(game.scene, 0); - expect(result).toEqual([true, false]); + expect(result).toEqual([ true, false ]); expect(account.updateUserInfo).toHaveBeenCalled(); }); @@ -82,7 +85,7 @@ describe("System - Game Data", () => { const result = await game.scene.gameData.tryClearSession(game.scene, 0); - expect(result).toEqual([false, false]); + expect(result).toEqual([ false, false ]); expect(account.updateUserInfo).toHaveBeenCalled(); }); }); diff --git a/src/test/ui/battle_info.test.ts b/src/test/ui/battle_info.test.ts index 4d511b75e6f..3100372f091 100644 --- a/src/test/ui/battle_info.test.ts +++ b/src/test/ui/battle_info.test.ts @@ -30,20 +30,20 @@ describe("UI - Battle Info", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.GUILLOTINE, Moves.SPLASH]) + .moveset([ Moves.GUILLOTINE, Moves.SPLASH ]) .battleType("single") .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) .enemySpecies(Species.CATERPIE); }); - it.each([ExpGainsSpeed.FAST, ExpGainsSpeed.FASTER, ExpGainsSpeed.SKIP])( + it.each([ ExpGainsSpeed.FAST, ExpGainsSpeed.FASTER, ExpGainsSpeed.SKIP ])( "should increase exp gains animation by 2^%i", async (expGainsSpeed) => { game.settings.expGainsSpeed(expGainsSpeed); vi.spyOn(Math, "pow"); - await game.classicMode.startBattle([Species.CHARIZARD]); + await game.classicMode.startBattle([ Species.CHARIZARD ]); game.move.select(Moves.SPLASH); await game.doKillOpponents(); diff --git a/src/test/ui/starter-select.test.ts b/src/test/ui/starter-select.test.ts index dd0761be392..94370ca1b74 100644 --- a/src/test/ui/starter-select.test.ts +++ b/src/test/ui/starter-select.test.ts @@ -14,6 +14,7 @@ import { Abilities } from "#enums/abilities"; import { Button } from "#enums/buttons"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; +import i18next from "i18next"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -66,11 +67,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); await new Promise((resolve) => { @@ -127,11 +128,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); await new Promise((resolve) => { @@ -191,11 +192,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); await new Promise((resolve) => { @@ -254,11 +255,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); await new Promise((resolve) => { @@ -315,11 +316,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); await new Promise((resolve) => { @@ -376,11 +377,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); await new Promise((resolve) => { @@ -436,11 +437,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); await new Promise((resolve) => { @@ -496,11 +497,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); let starterSelectUiHandler: StarterSelectUiHandler; @@ -561,11 +562,11 @@ describe("UI - Starter select", () => { resolve(); }); }); - expect(options.some(option => option.label === "starterSelectUiHandler:addToParty")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:toggleIVs")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:manageMoves")).toBe(true); - expect(options.some(option => option.label === "starterSelectUiHandler:useCandies")).toBe(true); - expect(options.some(option => option.label === "menu:cancel")).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:addToParty"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:toggleIVs"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:manageMoves"))).toBe(true); + expect(options.some(option => option.label === i18next.t("starterSelectUiHandler:useCandies"))).toBe(true); + expect(options.some(option => option.label === i18next.t("menu:cancel"))).toBe(true); optionSelectUiHandler?.processInput(Button.ACTION); let starterSelectUiHandler: StarterSelectUiHandler | undefined; diff --git a/src/test/ui/transfer-item.test.ts b/src/test/ui/transfer-item.test.ts index f7dea463574..0fbd4a52c61 100644 --- a/src/test/ui/transfer-item.test.ts +++ b/src/test/ui/transfer-item.test.ts @@ -37,11 +37,11 @@ describe("UI - Transfer Items", () => { { name: "BERRY", count: 2, type: BerryType.APICOT }, { name: "BERRY", count: 2, type: BerryType.LUM }, ]); - game.override.moveset([Moves.DRAGON_CLAW]); + game.override.moveset([ Moves.DRAGON_CLAW ]); game.override.enemySpecies(Species.MAGIKARP); - game.override.enemyMoveset([Moves.SPLASH]); + game.override.enemyMoveset([ Moves.SPLASH ]); - await game.startBattle([Species.RAYQUAZA, Species.RAYQUAZA, Species.RAYQUAZA]); + await game.startBattle([ Species.RAYQUAZA, Species.RAYQUAZA, Species.RAYQUAZA ]); game.move.select(Moves.DRAGON_CLAW); diff --git a/src/test/ui/type-hints.test.ts b/src/test/ui/type-hints.test.ts index 82209859fb0..2977262dda7 100644 --- a/src/test/ui/type-hints.test.ts +++ b/src/test/ui/type-hints.test.ts @@ -7,7 +7,8 @@ import { Mode } from "#app/ui/ui"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; -import MockText from "../utils/mocks/mocksContainer/mockText"; +import MockText from "#test/utils/mocks/mocksContainer/mockText"; +import i18next from "i18next"; describe("UI - Type Hints", () => { let phaserGame: Phaser.Game; @@ -36,10 +37,10 @@ describe("UI - Type Hints", () => { .startingWave(1) .enemySpecies(Species.FLORGES) .enemyMoveset(Moves.SPLASH) - .moveset([Moves.DRAGON_CLAW]); + .moveset([ Moves.DRAGON_CLAW ]); game.settings.typeHints(true); //activate type hints - await game.startBattle([Species.RAYQUAZA]); + await game.startBattle([ Species.RAYQUAZA ]); game.onNextPrompt("CommandPhase", Mode.COMMAND, () => { const { ui } = game.scene; @@ -53,7 +54,7 @@ describe("UI - Type Hints", () => { const movesContainer = ui.getByName(FightUiHandler.MOVES_CONTAINER_NAME); const dragonClawText = movesContainer .getAll() - .find((text) => text.text === "move:dragonClaw.name")! as unknown as MockText; + .find((text) => text.text === i18next.t("move:dragonClaw.name"))! as unknown as MockText; expect.soft(dragonClawText.color).toBe("#929292"); ui.getHandler().processInput(Button.ACTION); @@ -62,9 +63,9 @@ describe("UI - Type Hints", () => { }); it("check status move color", async () => { - game.override.enemySpecies(Species.FLORGES).moveset([Moves.GROWL]); + game.override.enemySpecies(Species.FLORGES).moveset([ Moves.GROWL ]); - await game.startBattle([Species.RAYQUAZA]); + await game.startBattle([ Species.RAYQUAZA ]); game.onNextPrompt("CommandPhase", Mode.COMMAND, () => { const { ui } = game.scene; @@ -78,7 +79,7 @@ describe("UI - Type Hints", () => { const movesContainer = ui.getByName(FightUiHandler.MOVES_CONTAINER_NAME); const growlText = movesContainer .getAll() - .find((text) => text.text === "move:growl.name")! as unknown as MockText; + .find((text) => text.text === i18next.t("move:growl.name"))! as unknown as MockText; expect.soft(growlText.color).toBe(undefined); ui.getHandler().processInput(Button.ACTION); diff --git a/src/test/utils/gameManager.ts b/src/test/utils/gameManager.ts index a2403de7e18..86c51972c8b 100644 --- a/src/test/utils/gameManager.ts +++ b/src/test/utils/gameManager.ts @@ -304,7 +304,7 @@ export default class GameManager { vi.spyOn(enemy, "getNextMove").mockReturnValueOnce({ move: moveId, targets: (target !== undefined && !legalTargets.multiple && legalTargets.targets.includes(target)) - ? [target] + ? [ target ] : enemy.getNextTargets(moveId) }); @@ -320,7 +320,7 @@ export default class GameManager { const originalMatchupScore = Trainer.prototype.getPartyMemberMatchupScores; Trainer.prototype.getPartyMemberMatchupScores = () => { Trainer.prototype.getPartyMemberMatchupScores = originalMatchupScore; - return [[1, 100], [1, 100]]; + return [[ 1, 100 ], [ 1, 100 ]]; }; } diff --git a/src/test/utils/gameManagerUtils.ts b/src/test/utils/gameManagerUtils.ts index 700d93082d8..543ee9627fe 100644 --- a/src/test/utils/gameManagerUtils.ts +++ b/src/test/utils/gameManagerUtils.ts @@ -86,7 +86,7 @@ export function waitUntil(truth) { export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: Moves) { const playerPokemon = scene.getPlayerField()[pokemonIndex]; const moveSet = playerPokemon.getMoveset(); - const index = moveSet.findIndex((m) => m?.moveId === move); + const index = moveSet.findIndex((m) => m?.moveId === move && m?.ppUsed < m?.getMovePp()); console.log(`Move position for ${Moves[move]} (=${move}):`, index); return index; } diff --git a/src/test/utils/gameWrapper.ts b/src/test/utils/gameWrapper.ts index 0ef5c4d4611..48c0007118b 100644 --- a/src/test/utils/gameWrapper.ts +++ b/src/test/utils/gameWrapper.ts @@ -23,6 +23,7 @@ import KeyboardPlugin = Phaser.Input.Keyboard.KeyboardPlugin; import GamepadPlugin = Phaser.Input.Gamepad.GamepadPlugin; import EventEmitter = Phaser.Events.EventEmitter; import UpdateList = Phaser.GameObjects.UpdateList; +import { version } from "../../../package.json"; Object.defineProperty(window, "localStorage", { value: mockLocalStorage(), @@ -101,6 +102,7 @@ export default class GameWrapper { injectMandatory() { this.game.config = { seed: ["test"], + gameVersion: version }; this.scene.game = this.game; this.game.renderer = { diff --git a/src/test/utils/helpers/challengeModeHelper.ts b/src/test/utils/helpers/challengeModeHelper.ts index 184f11f505c..5210d942d5a 100644 --- a/src/test/utils/helpers/challengeModeHelper.ts +++ b/src/test/utils/helpers/challengeModeHelper.ts @@ -38,6 +38,10 @@ export class ChallengeModeHelper extends GameManagerHelper { async runToSummon(species?: Species[]) { await this.game.runToTitle(); + if (this.game.override.disableShinies) { + this.game.override.shiny(false).enemyShiny(false); + } + this.game.onNextPrompt("TitlePhase", Mode.TITLE, () => { this.game.scene.gameMode.challenges = this.challenges; const starters = generateStarter(this.game.scene, species); @@ -47,7 +51,7 @@ export class ChallengeModeHelper extends GameManagerHelper { }); await this.game.phaseInterceptor.run(EncounterPhase); - if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0) { + if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0 && this.game.override.removeEnemyStartingItems) { this.game.removeEnemyHeldItems(); } } diff --git a/src/test/utils/helpers/classicModeHelper.ts b/src/test/utils/helpers/classicModeHelper.ts index 55e995fc9dc..80d0b86de7b 100644 --- a/src/test/utils/helpers/classicModeHelper.ts +++ b/src/test/utils/helpers/classicModeHelper.ts @@ -20,9 +20,13 @@ export class ClassicModeHelper extends GameManagerHelper { * @param species - Optional array of species to summon. * @returns A promise that resolves when the summon phase is reached. */ - async runToSummon(species?: Species[]) { + async runToSummon(species?: Species[]): Promise { await this.game.runToTitle(); + if (this.game.override.disableShinies) { + this.game.override.shiny(false).enemyShiny(false); + } + this.game.onNextPrompt("TitlePhase", Mode.TITLE, () => { this.game.scene.gameMode = getGameMode(GameModes.CLASSIC); const starters = generateStarter(this.game.scene, species); @@ -32,7 +36,7 @@ export class ClassicModeHelper extends GameManagerHelper { }); await this.game.phaseInterceptor.run(EncounterPhase); - if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0) { + if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0 && this.game.override.removeEnemyStartingItems) { this.game.removeEnemyHeldItems(); } } @@ -42,7 +46,7 @@ export class ClassicModeHelper extends GameManagerHelper { * @param species - Optional array of species to start the battle with. * @returns A promise that resolves when the battle is started. */ - async startBattle(species?: Species[]) { + async startBattle(species?: Species[]): Promise { await this.runToSummon(species); if (this.game.scene.battleStyle === BattleStyle.SWITCH) { diff --git a/src/test/utils/helpers/dailyModeHelper.ts b/src/test/utils/helpers/dailyModeHelper.ts index e40fada8ac7..813544f85df 100644 --- a/src/test/utils/helpers/dailyModeHelper.ts +++ b/src/test/utils/helpers/dailyModeHelper.ts @@ -21,6 +21,10 @@ export class DailyModeHelper extends GameManagerHelper { async runToSummon() { await this.game.runToTitle(); + if (this.game.override.disableShinies) { + this.game.override.shiny(false).enemyShiny(false); + } + this.game.onNextPrompt("TitlePhase", Mode.TITLE, () => { const titlePhase = new TitlePhase(this.game.scene); titlePhase.initDailyRun(); @@ -33,7 +37,7 @@ export class DailyModeHelper extends GameManagerHelper { await this.game.phaseInterceptor.to(EncounterPhase); - if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0) { + if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0 && this.game.override.removeEnemyStartingItems) { this.game.removeEnemyHeldItems(); } } diff --git a/src/test/utils/helpers/moveHelper.ts b/src/test/utils/helpers/moveHelper.ts index a53fa521785..73fe63395fd 100644 --- a/src/test/utils/helpers/moveHelper.ts +++ b/src/test/utils/helpers/moveHelper.ts @@ -1,34 +1,35 @@ import { BattlerIndex } from "#app/battle"; -import { Moves } from "#app/enums/moves"; +import Overrides from "#app/overrides"; import { CommandPhase } from "#app/phases/command-phase"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { Command } from "#app/ui/command-ui-handler"; import { Mode } from "#app/ui/ui"; +import { Moves } from "#enums/moves"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { GameManagerHelper } from "#test/utils/helpers/gameManagerHelper"; import { vi } from "vitest"; -import { getMovePosition } from "../gameManagerUtils"; -import { GameManagerHelper } from "./gameManagerHelper"; /** * Helper to handle a Pokemon's move */ export class MoveHelper extends GameManagerHelper { /** - * Intercepts `MoveEffectPhase` and mocks the hitCheck's - * return value to `true` {@linkcode MoveEffectPhase.hitCheck}. + * Intercepts {@linkcode MoveEffectPhase} and mocks the + * {@linkcode MoveEffectPhase.hitCheck | hitCheck}'s return value to `true`. * Used to force a move to hit. */ - async forceHit(): Promise { + public async forceHit(): Promise { await this.game.phaseInterceptor.to(MoveEffectPhase, false); vi.spyOn(this.game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck").mockReturnValue(true); } /** - * Intercepts `MoveEffectPhase` and mocks the hitCheck's - * return value to `false` {@linkcode MoveEffectPhase.hitCheck}. + * Intercepts {@linkcode MoveEffectPhase} and mocks the + * {@linkcode MoveEffectPhase.hitCheck | hitCheck}'s return value to `false`. * Used to force a move to miss. - * @param firstTargetOnly Whether the move should force miss on the first target only, in the case of multi-target moves. + * @param firstTargetOnly - Whether the move should force miss on the first target only, in the case of multi-target moves. */ - async forceMiss(firstTargetOnly: boolean = false): Promise { + public async forceMiss(firstTargetOnly: boolean = false): Promise { await this.game.phaseInterceptor.to(MoveEffectPhase, false); const hitCheck = vi.spyOn(this.game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck"); @@ -40,12 +41,12 @@ export class MoveHelper extends GameManagerHelper { } /** - * Select the move to be used by the given Pokemon(-index). Triggers during the next {@linkcode CommandPhase} - * @param move the move to use - * @param pkmIndex the pokemon index. Relevant for double-battles only (defaults to 0) - * @param targetIndex The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves, or `null` if a manual call to `selectTarget()` is required - */ - select(move: Moves, pkmIndex: 0 | 1 = 0, targetIndex?: BattlerIndex | null) { + * Select the move to be used by the given Pokemon(-index). Triggers during the next {@linkcode CommandPhase} + * @param move - the move to use + * @param pkmIndex - the pokemon index. Relevant for double-battles only (defaults to 0) + * @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves, or `null` if a manual call to `selectTarget()` is required + */ + public select(move: Moves, pkmIndex: 0 | 1 = 0, targetIndex?: BattlerIndex | null) { const movePosition = getMovePosition(this.game.scene, pkmIndex, move); this.game.onNextPrompt("CommandPhase", Mode.COMMAND, () => { @@ -59,4 +60,15 @@ export class MoveHelper extends GameManagerHelper { this.game.selectTarget(movePosition, targetIndex); } } + + /** + * Forces the Paralysis or Freeze status to activate on the next move by temporarily mocking {@linkcode Overrides.STATUS_ACTIVATION_OVERRIDE}, + * advancing to the next `MovePhase`, and then resetting the override to `null` + * @param activated - `true` to force the status to activate, `false` to force the status to not activate (will cause Freeze to heal) + */ + public async forceStatusActivation(activated: boolean): Promise { + vi.spyOn(Overrides, "STATUS_ACTIVATION_OVERRIDE", "get").mockReturnValue(activated); + await this.game.phaseInterceptor.to("MovePhase"); + vi.spyOn(Overrides, "STATUS_ACTIVATION_OVERRIDE", "get").mockReturnValue(null); + } } diff --git a/src/test/utils/helpers/overridesHelper.ts b/src/test/utils/helpers/overridesHelper.ts index 84cb1719e0b..404f5c34a26 100644 --- a/src/test/utils/helpers/overridesHelper.ts +++ b/src/test/utils/helpers/overridesHelper.ts @@ -19,12 +19,17 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; * Helper to handle overrides in tests */ export class OverridesHelper extends GameManagerHelper { + /** If `true`, removes the starting items from enemies at the start of each test; default `true` */ + public removeEnemyStartingItems: boolean = true; + /** If `true`, sets the shiny overrides to disable shinies at the start of each test; default `true` */ + public disableShinies: boolean = true; + /** * Override the starting biome * @warning Any event listeners that are attached to [NewArenaEvent](events\battle-scene.ts) may need to be handled down the line * @param biome the biome to set */ - startingBiome(biome: Biome): this { + public startingBiome(biome: Biome): this { this.game.scene.newArena(biome); this.log(`Starting biome set to ${Biome[biome]} (=${biome})!`); return this; @@ -33,9 +38,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the starting wave (index) * @param wave the wave (index) to set. Classic: `1`-`200` - * @returns this + * @returns `this` */ - startingWave(wave: number): this { + public startingWave(wave: number): this { vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(wave); this.log(`Starting wave set to ${wave}!`); return this; @@ -44,9 +49,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the player (pokemon) starting level * @param level the (pokemon) level to set - * @returns this + * @returns `this` */ - startingLevel(level: Species | number): this { + public startingLevel(level: Species | number): this { vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(level); this.log(`Player Pokemon starting level set to ${level}!`); return this; @@ -57,7 +62,7 @@ export class OverridesHelper extends GameManagerHelper { * @param value the XP multiplier to set * @returns `this` */ - xpMultiplier(value: number): this { + public xpMultiplier(value: number): this { vi.spyOn(Overrides, "XP_MULTIPLIER_OVERRIDE", "get").mockReturnValue(value); this.log(`XP Multiplier set to ${value}!`); return this; @@ -66,9 +71,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the player (pokemon) starting held items * @param items the items to hold - * @returns this + * @returns `this` */ - startingHeldItems(items: ModifierOverride[]) { + public startingHeldItems(items: ModifierOverride[]): this { vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue(items); this.log("Player Pokemon starting held items set to:", items); return this; @@ -77,23 +82,44 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the player (pokemon) {@linkcode Species | species} * @param species the (pokemon) {@linkcode Species | species} to set - * @returns this + * @returns `this` */ - starterSpecies(species: Species | number): this { + public starterSpecies(species: Species | number): this { vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(species); this.log(`Player Pokemon species set to ${Species[species]} (=${species})!`); return this; } + /** + * Override the player (pokemon) to be a random fusion + * @returns `this` + */ + public enableStarterFusion(): this { + vi.spyOn(Overrides, "STARTER_FUSION_OVERRIDE", "get").mockReturnValue(true); + this.log("Player Pokemon is a random fusion!"); + return this; + } + + /** + * Override the player (pokemon) fusion species + * @param species the fusion species to set + * @returns `this` + */ + public starterFusionSpecies(species: Species | number): this { + vi.spyOn(Overrides, "STARTER_FUSION_SPECIES_OVERRIDE", "get").mockReturnValue(species); + this.log(`Player Pokemon fusion species set to ${Species[species]} (=${species})!`); + return this; + } + /** * Override the player (pokemons) forms * @param forms the (pokemon) forms to set - * @returns this + * @returns `this` */ - starterForms(forms: Partial>): this { + public starterForms(forms: Partial>): this { vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue(forms); const formsStr = Object.entries(forms) - .map(([speciesId, formIndex]) => `${Species[speciesId]}=${formIndex}`) + .map(([ speciesId, formIndex ]) => `${Species[speciesId]}=${formIndex}`) .join(", "); this.log(`Player Pokemon form set to: ${formsStr}!`); return this; @@ -102,9 +128,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the player's starting modifiers * @param modifiers the modifiers to set - * @returns this + * @returns `this` */ - startingModifier(modifiers: ModifierOverride[]): this { + public startingModifier(modifiers: ModifierOverride[]): this { vi.spyOn(Overrides, "STARTING_MODIFIER_OVERRIDE", "get").mockReturnValue(modifiers); this.log(`Player starting modifiers set to: ${modifiers}`); return this; @@ -113,9 +139,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the player (pokemon) {@linkcode Abilities | ability} * @param ability the (pokemon) {@linkcode Abilities | ability} to set - * @returns this + * @returns `this` */ - ability(ability: Abilities): this { + public ability(ability: Abilities): this { vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(ability); this.log(`Player Pokemon ability set to ${Abilities[ability]} (=${ability})!`); return this; @@ -124,9 +150,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the player (pokemon) **passive** {@linkcode Abilities | ability} * @param passiveAbility the (pokemon) **passive** {@linkcode Abilities | ability} to set - * @returns this + * @returns `this` */ - passiveAbility(passiveAbility: Abilities): this { + public passiveAbility(passiveAbility: Abilities): this { vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(passiveAbility); this.log(`Player Pokemon PASSIVE ability set to ${Abilities[passiveAbility]} (=${passiveAbility})!`); return this; @@ -135,12 +161,12 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the player (pokemon) {@linkcode Moves | moves}set * @param moveset the {@linkcode Moves | moves}set to set - * @returns this + * @returns `this` */ - moveset(moveset: Moves | Moves[]): this { + public moveset(moveset: Moves | Moves[]): this { vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue(moveset); if (!Array.isArray(moveset)) { - moveset = [moveset]; + moveset = [ moveset ]; } const movesetStr = moveset.map((moveId) => Moves[moveId]).join(", "); this.log(`Player Pokemon moveset set to ${movesetStr} (=[${moveset.join(", ")}])!`); @@ -152,7 +178,7 @@ export class OverridesHelper extends GameManagerHelper { * @param statusEffect the {@linkcode StatusEffect | status-effect} to set * @returns */ - statusEffect(statusEffect: StatusEffect): this { + public statusEffect(statusEffect: StatusEffect): this { vi.spyOn(Overrides, "STATUS_OVERRIDE", "get").mockReturnValue(statusEffect); this.log(`Player Pokemon status-effect set to ${StatusEffect[statusEffect]} (=${statusEffect})!`); return this; @@ -160,9 +186,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override each wave to not have standard trainer battles - * @returns this + * @returns `this` */ - disableTrainerWaves(): this { + public disableTrainerWaves(): this { const realFn = getGameMode; vi.spyOn(GameMode, "getGameMode").mockImplementation((gameMode: GameModes) => { const mode = realFn(gameMode); @@ -175,9 +201,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override each wave to not have critical hits - * @returns this + * @returns `this` */ - disableCrits() { + public disableCrits(): this { vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); this.log("Critical hits are disabled!"); return this; @@ -186,9 +212,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the {@linkcode WeatherType | weather (type)} * @param type {@linkcode WeatherType | weather type} to set - * @returns this + * @returns `this` */ - weather(type: WeatherType): this { + public weather(type: WeatherType): this { vi.spyOn(Overrides, "WEATHER_OVERRIDE", "get").mockReturnValue(type); this.log(`Weather set to ${Weather[type]} (=${type})!`); return this; @@ -197,12 +223,12 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the seed * @param seed the seed to set - * @returns this + * @returns `this` */ - seed(seed: string): this { + public seed(seed: string): this { vi.spyOn(this.game.scene, "resetSeed").mockImplementation(() => { this.game.scene.waveSeed = seed; - Phaser.Math.RND.sow([seed]); + Phaser.Math.RND.sow([ seed ]); this.game.scene.rngCounter = 0; }); this.game.scene.resetSeed(); @@ -213,9 +239,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the battle type (single or double) * @param battleType battle type to set - * @returns this + * @returns `this` */ - battleType(battleType: "single" | "double" | null): this { + public battleType(battleType: "single" | "double" | null): this { vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue(battleType); this.log(`Battle type set to ${battleType} only!`); return this; @@ -224,20 +250,41 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the enemy (pokemon) {@linkcode Species | species} * @param species the (pokemon) {@linkcode Species | species} to set - * @returns this + * @returns `this` */ - enemySpecies(species: Species | number): this { + public enemySpecies(species: Species | number): this { vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(species); this.log(`Enemy Pokemon species set to ${Species[species]} (=${species})!`); return this; } + /** + * Override the enemy (pokemon) to be a random fusion + * @returns `this` + */ + public enableEnemyFusion(): this { + vi.spyOn(Overrides, "OPP_FUSION_OVERRIDE", "get").mockReturnValue(true); + this.log("Enemy Pokemon is a random fusion!"); + return this; + } + + /** + * Override the enemy (pokemon) fusion species + * @param species the fusion species to set + * @returns `this` + */ + public enemyFusionSpecies(species: Species | number): this { + vi.spyOn(Overrides, "OPP_FUSION_SPECIES_OVERRIDE", "get").mockReturnValue(species); + this.log(`Enemy Pokemon fusion species set to ${Species[species]} (=${species})!`); + return this; + } + /** * Override the enemy (pokemon) {@linkcode Abilities | ability} * @param ability the (pokemon) {@linkcode Abilities | ability} to set - * @returns this + * @returns `this` */ - enemyAbility(ability: Abilities): this { + public enemyAbility(ability: Abilities): this { vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(ability); this.log(`Enemy Pokemon ability set to ${Abilities[ability]} (=${ability})!`); return this; @@ -246,9 +293,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the enemy (pokemon) **passive** {@linkcode Abilities | ability} * @param passiveAbility the (pokemon) **passive** {@linkcode Abilities | ability} to set - * @returns this + * @returns `this` */ - enemyPassiveAbility(passiveAbility: Abilities): this { + public enemyPassiveAbility(passiveAbility: Abilities): this { vi.spyOn(Overrides, "OPP_PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(passiveAbility); this.log(`Enemy Pokemon PASSIVE ability set to ${Abilities[passiveAbility]} (=${passiveAbility})!`); return this; @@ -257,12 +304,12 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the enemy (pokemon) {@linkcode Moves | moves}set * @param moveset the {@linkcode Moves | moves}set to set - * @returns this + * @returns `this` */ - enemyMoveset(moveset: Moves | Moves[]): this { + public enemyMoveset(moveset: Moves | Moves[]): this { vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(moveset); if (!Array.isArray(moveset)) { - moveset = [moveset]; + moveset = [ moveset ]; } const movesetStr = moveset.map((moveId) => Moves[moveId]).join(", "); this.log(`Enemy Pokemon moveset set to ${movesetStr} (=[${moveset.join(", ")}])!`); @@ -272,9 +319,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the enemy (pokemon) level * @param level the level to set - * @returns this + * @returns `this` */ - enemyLevel(level: number): this { + public enemyLevel(level: number): this { vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(level); this.log(`Enemy Pokemon level set to ${level}!`); return this; @@ -285,7 +332,7 @@ export class OverridesHelper extends GameManagerHelper { * @param statusEffect the {@linkcode StatusEffect | status-effect} to set * @returns */ - enemyStatusEffect(statusEffect: StatusEffect): this { + public enemyStatusEffect(statusEffect: StatusEffect): this { vi.spyOn(Overrides, "OPP_STATUS_OVERRIDE", "get").mockReturnValue(statusEffect); this.log(`Enemy Pokemon status-effect set to ${StatusEffect[statusEffect]} (=${statusEffect})!`); return this; @@ -294,9 +341,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the enemy (pokemon) held items * @param items the items to hold - * @returns this + * @returns `this` */ - enemyHeldItems(items: ModifierOverride[]) { + public enemyHeldItems(items: ModifierOverride[]): this { vi.spyOn(Overrides, "OPP_HELD_ITEMS_OVERRIDE", "get").mockReturnValue(items); this.log("Enemy Pokemon held items set to:", items); return this; @@ -307,7 +354,7 @@ export class OverridesHelper extends GameManagerHelper { * @param unlockable The Unlockable(s) to enable. * @returns `this` */ - enableUnlockable(unlockable: Unlockables[]) { + public enableUnlockable(unlockable: Unlockables[]): this { vi.spyOn(Overrides, "ITEM_UNLOCK_OVERRIDE", "get").mockReturnValue(unlockable); this.log("Temporarily unlocked the following content: ", unlockable); return this; @@ -316,9 +363,9 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the items rolled at the end of a battle * @param items the items to be rolled - * @returns this + * @returns `this` */ - itemRewards(items: ModifierOverride[]) { + public itemRewards(items: ModifierOverride[]): this { vi.spyOn(Overrides, "ITEM_REWARD_OVERRIDE", "get").mockReturnValue(items); this.log("Item rewards set to:", items); return this; @@ -326,43 +373,87 @@ export class OverridesHelper extends GameManagerHelper { /** * Override player shininess - * @param shininess Whether the player's Pokemon should be shiny. + * @param shininess - `true` or `false` to force the player's pokemon to be shiny or not shiny, + * `null` to disable the override and re-enable RNG shinies. + * @returns `this` */ - shinyLevel(shininess: boolean): this { + public shiny(shininess: boolean | null): this { vi.spyOn(Overrides, "SHINY_OVERRIDE", "get").mockReturnValue(shininess); - this.log(`Set player Pokemon as ${shininess ? "" : "not "}shiny!`); + if (shininess === null) { + this.log("Disabled player Pokemon shiny override!"); + } else { + this.log(`Set player Pokemon to be ${shininess ? "" : "not "}shiny!`); + } return this; } + /** * Override player shiny variant - * @param variant The player's shiny variant. + * @param variant - The player's shiny variant. + * @returns `this` */ - variantLevel(variant: Variant): this { + public shinyVariant(variant: Variant): this { vi.spyOn(Overrides, "VARIANT_OVERRIDE", "get").mockReturnValue(variant); this.log(`Set player Pokemon's shiny variant to ${variant}!`); return this; } + /** + * Override enemy shininess + * @param shininess - `true` or `false` to force the enemy's pokemon to be shiny or not shiny, + * `null` to disable the override and re-enable RNG shinies. + * @param variant - (Optional) The enemy's shiny {@linkcode Variant}. + */ + enemyShiny(shininess: boolean | null, variant?: Variant): this { + vi.spyOn(Overrides, "OPP_SHINY_OVERRIDE", "get").mockReturnValue(shininess); + if (shininess === null) { + this.log("Disabled enemy Pokemon shiny override!"); + } else { + this.log(`Set enemy Pokemon to be ${shininess ? "" : "not "}shiny!`); + } + + if (variant !== undefined) { + vi.spyOn(Overrides, "OPP_VARIANT_OVERRIDE", "get").mockReturnValue(variant); + this.log(`Set enemy shiny variant to be ${variant}!`); + } + return this; + } + /** * Override the enemy (Pokemon) to have the given amount of health segments * @param healthSegments the number of segments to give - * default: 0, the health segments will be handled like in the game based on wave, level and species - * 1: the Pokemon will not be a boss - * 2+: the Pokemon will be a boss with the given number of health segments - * @returns this + * - `0` (default): the health segments will be handled like in the game based on wave, level and species + * - `1`: the Pokemon will not be a boss + * - `2`+: the Pokemon will be a boss with the given number of health segments + * @returns `this` */ - enemyHealthSegments(healthSegments: number) { + public enemyHealthSegments(healthSegments: number): this { vi.spyOn(Overrides, "OPP_HEALTH_SEGMENTS_OVERRIDE", "get").mockReturnValue(healthSegments); this.log("Enemy Pokemon health segments set to:", healthSegments); return this; } + /** + * Override statuses (Paralysis and Freeze) to always or never activate + * @param activate - `true` to force activation, `false` to force no activation, `null` to disable the override + * @returns `this` + */ + public statusActivation(activate: boolean | null): this { + vi.spyOn(Overrides, "STATUS_ACTIVATION_OVERRIDE", "get").mockReturnValue(activate); + if (activate !== null) { + this.log(`Paralysis and Freeze forced to ${activate ? "always" : "never"} activate!`); + } else { + this.log("Status activation override disabled!"); + } + return this; + } + /** * Override the encounter chance for a mystery encounter. * @param percentage the encounter chance in % - * @returns spy instance + * @returns `this` */ - mysteryEncounterChance(percentage: number) { + public mysteryEncounterChance(percentage: number): this { const maxRate: number = 256; // 100% const rate = maxRate * (percentage / 100); vi.spyOn(Overrides, "MYSTERY_ENCOUNTER_RATE_OVERRIDE", "get").mockReturnValue(rate); @@ -372,10 +463,10 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the encounter chance for a mystery encounter. - * @returns spy instance - * @param tier + * @param tier - The {@linkcode MysteryEncounterTier} to encounter + * @returns `this` */ - mysteryEncounterTier(tier: MysteryEncounterTier) { + public mysteryEncounterTier(tier: MysteryEncounterTier): this { vi.spyOn(Overrides, "MYSTERY_ENCOUNTER_TIER_OVERRIDE", "get").mockReturnValue(tier); this.log(`Mystery encounter tier set to ${tier}!`); return this; @@ -383,10 +474,10 @@ export class OverridesHelper extends GameManagerHelper { /** * Override the encounter that spawns for the scene - * @param encounterType - * @returns spy instance + * @param encounterType - The {@linkcode MysteryEncounterType} of the encounter + * @returns `this` */ - mysteryEncounter(encounterType: MysteryEncounterType) { + public mysteryEncounter(encounterType: MysteryEncounterType): this { vi.spyOn(Overrides, "MYSTERY_ENCOUNTER_OVERRIDE", "get").mockReturnValue(encounterType); this.log(`Mystery encounter override set to ${encounterType}!`); return this; diff --git a/src/test/utils/helpers/settingsHelper.ts b/src/test/utils/helpers/settingsHelper.ts index c611a705107..83baa329cec 100644 --- a/src/test/utils/helpers/settingsHelper.ts +++ b/src/test/utils/helpers/settingsHelper.ts @@ -27,7 +27,7 @@ export class SettingsHelper extends GameManagerHelper { */ typeHints(enable: boolean): void { this.game.scene.typeHints = enable; - this.log(`Type Hints ${enable? "enabled" : "disabled"}` ); + this.log(`Type Hints ${enable ? "enabled" : "disabled"}` ); } /** diff --git a/src/test/utils/inputsHandler.ts b/src/test/utils/inputsHandler.ts index 30dd101f43d..bf690d5d74c 100644 --- a/src/test/utils/inputsHandler.ts +++ b/src/test/utils/inputsHandler.ts @@ -41,18 +41,18 @@ export default class InputsHandler { pressGamepadButton(button: integer, duration: integer): Promise { return new Promise(async (resolve) => { - this.scene.input.gamepad?.emit("down", this.fakePad, {index: button}); + this.scene.input.gamepad?.emit("down", this.fakePad, { index: button }); await holdOn(duration); - this.scene.input.gamepad?.emit("up", this.fakePad, {index: button}); + this.scene.input.gamepad?.emit("up", this.fakePad, { index: button }); resolve(); }); } pressKeyboardKey(key: integer, duration: integer): Promise { return new Promise(async (resolve) => { - this.scene.input.keyboard?.emit("keydown", {keyCode: key}); + this.scene.input.keyboard?.emit("keydown", { keyCode: key }); await holdOn(duration); - this.scene.input.keyboard?.emit("keyup", {keyCode: key}); + this.scene.input.keyboard?.emit("keyup", { keyCode: key }); resolve(); }); } @@ -67,11 +67,11 @@ export default class InputsHandler { listenInputs(): void { this.events.on("input_down", (event) => { - this.log.push({type: "input_down", button: event.button}); + this.log.push({ type: "input_down", button: event.button }); }, this); this.events.on("input_up", (event) => { - this.logUp.push({type: "input_up", button: event.button}); + this.logUp.push({ type: "input_up", button: event.button }); }, this); } } @@ -82,7 +82,7 @@ class Fakepad extends Phaser.Input.Gamepad.Gamepad { constructor(pad) { //@ts-ignore - super(undefined, {...pad, buttons: pad.deviceMapping, axes: []}); //TODO: resolve ts-ignore + super(undefined, { ...pad, buttons: pad.deviceMapping, axes: []}); //TODO: resolve ts-ignore this.id = "xbox_360_fakepad"; this.index = 0; } @@ -90,7 +90,7 @@ class Fakepad extends Phaser.Input.Gamepad.Gamepad { class FakeMobile { constructor() { - const fakeMobilePage = fs.readFileSync("./src/test/utils/fakeMobile.html", {encoding: "utf8", flag: "r"}); + const fakeMobilePage = fs.readFileSync("./src/test/utils/fakeMobile.html", { encoding: "utf8", flag: "r" }); const dom = new JSDOM(fakeMobilePage); Object.defineProperty(window, "document", { value: dom.window.document, diff --git a/src/test/utils/mocks/mockClock.ts b/src/test/utils/mocks/mockClock.ts index e7501a7c99d..7fad3651010 100644 --- a/src/test/utils/mocks/mockClock.ts +++ b/src/test/utils/mocks/mockClock.ts @@ -17,7 +17,7 @@ export class MockClock extends Clock { } addEvent(config: Phaser.Time.TimerEvent | Phaser.Types.Time.TimerEventConfig): Phaser.Time.TimerEvent { - const cfg = { ...config, delay: this.overrideDelay ?? config.delay}; + const cfg = { ...config, delay: this.overrideDelay ?? config.delay }; return super.addEvent(cfg); } } diff --git a/src/test/utils/mocks/mockConsoleLog.ts b/src/test/utils/mocks/mockConsoleLog.ts index f44a0c7d6cd..9c3cbca6bb6 100644 --- a/src/test/utils/mocks/mockConsoleLog.ts +++ b/src/test/utils/mocks/mockConsoleLog.ts @@ -1,4 +1,4 @@ -const MockConsoleLog = (_logDisabled= false, _phaseText=false) => { +const MockConsoleLog = (_logDisabled = false, _phaseText = false) => { let logs: any[] = []; const logDisabled: boolean = _logDisabled; const phaseText: boolean = _phaseText; @@ -8,8 +8,8 @@ const MockConsoleLog = (_logDisabled= false, _phaseText=false) => { const originalWarn = console.warn; const notified: any[] = []; - const blacklist = ["Phaser", "variant icon does not exist", "Texture \"%s\" not found"]; - const whitelist = ["Phase"]; + const blacklist = [ "Phaser", "variant icon does not exist", "Texture \"%s\" not found" ]; + const whitelist = [ "Phase" ]; return ({ log(...args) { diff --git a/src/test/utils/mocks/mockFetch.ts b/src/test/utils/mocks/mockFetch.ts index ad3758775d1..2fa7cd198ce 100644 --- a/src/test/utils/mocks/mockFetch.ts +++ b/src/test/utils/mocks/mockFetch.ts @@ -5,12 +5,12 @@ export const MockFetch = (input, init) => { let responseText; const handlers = { - "account/info": {"username":"greenlamp", "lastSessionSlot":0}, + "account/info": { "username":"greenlamp", "lastSessionSlot":0 }, "savedata/session": {}, "savedata/system": {}, "savedata/updateall": "", "daily/rankingpagecount": { data: 0 }, - "game/titlestats": {"playerCount":0, "battleCount":5}, + "game/titlestats": { "playerCount":0, "battleCount":5 }, "daily/rankings": [], }; diff --git a/src/test/utils/mocks/mocksContainer/mockSprite.ts b/src/test/utils/mocks/mocksContainer/mockSprite.ts index a55b218d0c2..e726fec454d 100644 --- a/src/test/utils/mocks/mocksContainer/mockSprite.ts +++ b/src/test/utils/mocks/mocksContainer/mockSprite.ts @@ -212,5 +212,4 @@ export default class MockSprite implements MockGameObject { } - } diff --git a/src/test/utils/phaseInterceptor.ts b/src/test/utils/phaseInterceptor.ts index 6c4c9a6cf94..ec9309e2405 100644 --- a/src/test/utils/phaseInterceptor.ts +++ b/src/test/utils/phaseInterceptor.ts @@ -53,6 +53,7 @@ import { } from "#app/phases/mystery-encounter-phases"; import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase"; import { PartyExpPhase } from "#app/phases/party-exp-phase"; +import { ExpPhase } from "#app/phases/exp-phase"; export interface PromptHandler { phaseTarget?: string; @@ -61,7 +62,114 @@ export interface PromptHandler { expireFn?: () => void; awaitingActionInput?: boolean; } -import { ExpPhase } from "#app/phases/exp-phase"; + +type PhaseClass = + | typeof LoginPhase + | typeof TitlePhase + | typeof SelectGenderPhase + | typeof EncounterPhase + | typeof NewBiomeEncounterPhase + | typeof SelectStarterPhase + | typeof PostSummonPhase + | typeof SummonPhase + | typeof ToggleDoublePositionPhase + | typeof CheckSwitchPhase + | typeof ShowAbilityPhase + | typeof MessagePhase + | typeof TurnInitPhase + | typeof CommandPhase + | typeof EnemyCommandPhase + | typeof TurnStartPhase + | typeof MovePhase + | typeof MoveEffectPhase + | typeof DamagePhase + | typeof FaintPhase + | typeof BerryPhase + | typeof TurnEndPhase + | typeof BattleEndPhase + | typeof EggLapsePhase + | typeof SelectModifierPhase + | typeof NextEncounterPhase + | typeof NewBattlePhase + | typeof VictoryPhase + | typeof LearnMovePhase + | typeof MoveEndPhase + | typeof StatStageChangePhase + | typeof ShinySparklePhase + | typeof SelectTargetPhase + | typeof UnavailablePhase + | typeof QuietFormChangePhase + | typeof SwitchPhase + | typeof SwitchSummonPhase + | typeof PartyHealPhase + | typeof EvolutionPhase + | typeof EndEvolutionPhase + | typeof LevelCapPhase + | typeof AttemptRunPhase + | typeof SelectBiomePhase + | typeof MysteryEncounterPhase + | typeof MysteryEncounterOptionSelectedPhase + | typeof MysteryEncounterBattlePhase + | typeof MysteryEncounterRewardsPhase + | typeof PostMysteryEncounterPhase + | typeof ModifierRewardPhase + | typeof PartyExpPhase + | typeof ExpPhase; + +type PhaseString = + | "LoginPhase" + | "TitlePhase" + | "SelectGenderPhase" + | "EncounterPhase" + | "NewBiomeEncounterPhase" + | "SelectStarterPhase" + | "PostSummonPhase" + | "SummonPhase" + | "ToggleDoublePositionPhase" + | "CheckSwitchPhase" + | "ShowAbilityPhase" + | "MessagePhase" + | "TurnInitPhase" + | "CommandPhase" + | "EnemyCommandPhase" + | "TurnStartPhase" + | "MovePhase" + | "MoveEffectPhase" + | "DamagePhase" + | "FaintPhase" + | "BerryPhase" + | "TurnEndPhase" + | "BattleEndPhase" + | "EggLapsePhase" + | "SelectModifierPhase" + | "NextEncounterPhase" + | "NewBattlePhase" + | "VictoryPhase" + | "LearnMovePhase" + | "MoveEndPhase" + | "StatStageChangePhase" + | "ShinySparklePhase" + | "SelectTargetPhase" + | "UnavailablePhase" + | "QuietFormChangePhase" + | "SwitchPhase" + | "SwitchSummonPhase" + | "PartyHealPhase" + | "EvolutionPhase" + | "EndEvolutionPhase" + | "LevelCapPhase" + | "AttemptRunPhase" + | "SelectBiomePhase" + | "MysteryEncounterPhase" + | "MysteryEncounterOptionSelectedPhase" + | "MysteryEncounterBattlePhase" + | "MysteryEncounterRewardsPhase" + | "PostMysteryEncounterPhase" + | "ModifierRewardPhase" + | "PartyExpPhase" + | "ExpPhase"; + +type PhaseInterceptorPhase = PhaseClass | PhaseString; export default class PhaseInterceptor { public scene; @@ -81,57 +189,57 @@ export default class PhaseInterceptor { * List of phases with their corresponding start methods. */ private PHASES = [ - [LoginPhase, this.startPhase], - [TitlePhase, this.startPhase], - [SelectGenderPhase, this.startPhase], - [EncounterPhase, this.startPhase], - [NewBiomeEncounterPhase, this.startPhase], - [SelectStarterPhase, this.startPhase], - [PostSummonPhase, this.startPhase], - [SummonPhase, this.startPhase], - [ToggleDoublePositionPhase, this.startPhase], - [CheckSwitchPhase, this.startPhase], - [ShowAbilityPhase, this.startPhase], - [MessagePhase, this.startPhase], - [TurnInitPhase, this.startPhase], - [CommandPhase, this.startPhase], - [EnemyCommandPhase, this.startPhase], - [TurnStartPhase, this.startPhase], - [MovePhase, this.startPhase], - [MoveEffectPhase, this.startPhase], - [DamagePhase, this.startPhase], - [FaintPhase, this.startPhase], - [BerryPhase, this.startPhase], - [TurnEndPhase, this.startPhase], - [BattleEndPhase, this.startPhase], - [EggLapsePhase, this.startPhase], - [SelectModifierPhase, this.startPhase], - [NextEncounterPhase, this.startPhase], - [NewBattlePhase, this.startPhase], - [VictoryPhase, this.startPhase], - [LearnMovePhase, this.startPhase], - [MoveEndPhase, this.startPhase], - [StatStageChangePhase, this.startPhase], - [ShinySparklePhase, this.startPhase], - [SelectTargetPhase, this.startPhase], - [UnavailablePhase, this.startPhase], - [QuietFormChangePhase, this.startPhase], - [SwitchPhase, this.startPhase], - [SwitchSummonPhase, this.startPhase], - [PartyHealPhase, this.startPhase], - [EvolutionPhase, this.startPhase], - [EndEvolutionPhase, this.startPhase], - [LevelCapPhase, this.startPhase], - [AttemptRunPhase, this.startPhase], - [SelectBiomePhase, this.startPhase], - [MysteryEncounterPhase, this.startPhase], - [MysteryEncounterOptionSelectedPhase, this.startPhase], - [MysteryEncounterBattlePhase, this.startPhase], - [MysteryEncounterRewardsPhase, this.startPhase], - [PostMysteryEncounterPhase, this.startPhase], - [ModifierRewardPhase, this.startPhase], - [PartyExpPhase, this.startPhase], - [ExpPhase, this.startPhase], + [ LoginPhase, this.startPhase ], + [ TitlePhase, this.startPhase ], + [ SelectGenderPhase, this.startPhase ], + [ EncounterPhase, this.startPhase ], + [ NewBiomeEncounterPhase, this.startPhase ], + [ SelectStarterPhase, this.startPhase ], + [ PostSummonPhase, this.startPhase ], + [ SummonPhase, this.startPhase ], + [ ToggleDoublePositionPhase, this.startPhase ], + [ CheckSwitchPhase, this.startPhase ], + [ ShowAbilityPhase, this.startPhase ], + [ MessagePhase, this.startPhase ], + [ TurnInitPhase, this.startPhase ], + [ CommandPhase, this.startPhase ], + [ EnemyCommandPhase, this.startPhase ], + [ TurnStartPhase, this.startPhase ], + [ MovePhase, this.startPhase ], + [ MoveEffectPhase, this.startPhase ], + [ DamagePhase, this.startPhase ], + [ FaintPhase, this.startPhase ], + [ BerryPhase, this.startPhase ], + [ TurnEndPhase, this.startPhase ], + [ BattleEndPhase, this.startPhase ], + [ EggLapsePhase, this.startPhase ], + [ SelectModifierPhase, this.startPhase ], + [ NextEncounterPhase, this.startPhase ], + [ NewBattlePhase, this.startPhase ], + [ VictoryPhase, this.startPhase ], + [ LearnMovePhase, this.startPhase ], + [ MoveEndPhase, this.startPhase ], + [ StatStageChangePhase, this.startPhase ], + [ ShinySparklePhase, this.startPhase ], + [ SelectTargetPhase, this.startPhase ], + [ UnavailablePhase, this.startPhase ], + [ QuietFormChangePhase, this.startPhase ], + [ SwitchPhase, this.startPhase ], + [ SwitchSummonPhase, this.startPhase ], + [ PartyHealPhase, this.startPhase ], + [ EvolutionPhase, this.startPhase ], + [ EndEvolutionPhase, this.startPhase ], + [ LevelCapPhase, this.startPhase ], + [ AttemptRunPhase, this.startPhase ], + [ SelectBiomePhase, this.startPhase ], + [ MysteryEncounterPhase, this.startPhase ], + [ MysteryEncounterOptionSelectedPhase, this.startPhase ], + [ MysteryEncounterBattlePhase, this.startPhase ], + [ MysteryEncounterRewardsPhase, this.startPhase ], + [ PostMysteryEncounterPhase, this.startPhase ], + [ ModifierRewardPhase, this.startPhase ], + [ PartyExpPhase, this.startPhase ], + [ ExpPhase, this.startPhase ], ]; private endBySetMode = [ @@ -172,7 +280,7 @@ export default class PhaseInterceptor { * @param phaseFrom - The phase to start from. * @returns The instance of the PhaseInterceptor. */ - runFrom(phaseFrom) { + runFrom(phaseFrom: PhaseInterceptorPhase): PhaseInterceptor { this.phaseFrom = phaseFrom; return this; } @@ -180,9 +288,10 @@ export default class PhaseInterceptor { /** * Method to transition to a target phase. * @param phaseTo - The phase to transition to. + * @param runTarget - Whether or not to run the target phase. * @returns A promise that resolves when the transition is complete. */ - async to(phaseTo, runTarget: boolean = true): Promise { + async to(phaseTo: PhaseInterceptorPhase, runTarget: boolean = true): Promise { return new Promise(async (resolve, reject) => { ErrorInterceptor.getInstance().add(this); if (this.phaseFrom) { @@ -219,7 +328,7 @@ export default class PhaseInterceptor { * @param skipFn - Optional skip function. * @returns A promise that resolves when the phase is run. */ - run(phaseTarget, skipFn?): Promise { + run(phaseTarget: PhaseInterceptorPhase, skipFn?: (className: PhaseClass) => boolean): Promise { const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name; this.scene.moveAnimations = null; // Mandatory to avoid crash return new Promise(async (resolve, reject) => { @@ -253,7 +362,7 @@ export default class PhaseInterceptor { }); } - whenAboutToRun(phaseTarget, skipFn?): Promise { + whenAboutToRun(phaseTarget: PhaseInterceptorPhase, skipFn?: (className: PhaseClass) => boolean): Promise { const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name; this.scene.moveAnimations = null; // Mandatory to avoid crash return new Promise(async (resolve, reject) => { @@ -297,7 +406,7 @@ export default class PhaseInterceptor { this.originalSuperEnd = Phase.prototype.end; UI.prototype.setMode = (mode, ...args) => this.setMode.call(this, mode, ...args); Phase.prototype.end = () => this.superEndPhase.call(this); - for (const [phase, methodStart] of this.PHASES) { + for (const [ phase, methodStart ] of this.PHASES) { const originalStart = phase.prototype.start; this.phases[phase.name] = { start: originalStart, @@ -311,7 +420,7 @@ export default class PhaseInterceptor { * Method to start a phase and log it. * @param phase - The phase to start. */ - startPhase(phase) { + startPhase(phase: PhaseClass) { this.log.push(phase.name); const instance = this.scene.getCurrentPhase(); this.onHold.push({ @@ -340,13 +449,14 @@ export default class PhaseInterceptor { /** * m2m to set mode. - * @param phase - The phase to start. + * @param mode - The {@linkcode Mode} to set. + * @param args - Additional arguments to pass to the original method. */ - setMode(mode: Mode, ...args: any[]): Promise { + setMode(mode: Mode, ...args: unknown[]): Promise { const currentPhase = this.scene.getCurrentPhase(); const instance = this.scene.ui; console.log("setMode", `${Mode[mode]} (=${mode})`, args); - const ret = this.originalSetMode.apply(instance, [mode, ...args]); + const ret = this.originalSetMode.apply(instance, [ mode, ...args ]); if (!this.phases[currentPhase.constructor.name]) { throw new Error(`missing ${currentPhase.constructor.name} in phaseInterceptor PHASES list --- Add it to PHASES inside of /test/utils/phaseInterceptor.ts`); @@ -406,7 +516,7 @@ export default class PhaseInterceptor { * function stored in `this.phases`. Additionally, it clears the `promptInterval` and `interval`. */ restoreOg() { - for (const [phase] of this.PHASES) { + for (const [ phase ] of this.PHASES) { phase.prototype.start = this.phases[phase.name].start; } UI.prototype.setMode = this.originalSetMode; diff --git a/src/test/vitest.setup.ts b/src/test/vitest.setup.ts index 948180ca261..8438f607db2 100644 --- a/src/test/vitest.setup.ts +++ b/src/test/vitest.setup.ts @@ -4,16 +4,17 @@ import { initLoggedInUser } from "#app/account"; import { initAbilities } from "#app/data/ability"; import { initBiomes } from "#app/data/balance/biomes"; import { initEggMoves } from "#app/data/balance/egg-moves"; +import { initPokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; import { initMoves } from "#app/data/move"; import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters"; -import { initPokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; import { initPokemonForms } from "#app/data/pokemon-forms"; import { initSpecies } from "#app/data/pokemon-species"; import { initAchievements } from "#app/system/achv"; import { initVouchers } from "#app/system/voucher"; import { initStatsKeys } from "#app/ui/game-stats-ui-handler"; -import { beforeAll, vi } from "vitest"; +import { afterAll, beforeAll, vi } from "vitest"; +/** Set the timezone to UTC for tests. */ process.env.TZ = "UTC"; /** Mock the override import to always return default values, ignoring any custom overrides. */ @@ -26,26 +27,36 @@ vi.mock("#app/overrides", async (importOriginal) => { } satisfies typeof import("#app/overrides"); }); -vi.mock("i18next", () => ({ - default: { - use: () => {}, - t: (key: string) => key, - changeLanguage: () => Promise.resolve(), - init: () => Promise.resolve(), - resolvedLanguage: "en", - exists: () => true, - getDataByLanguage:() => ({ - en: { - keys: ["foo"] - }, - }), - services: { - formatter: { - add: () => {}, +/** + * This is a hacky way to mock the i18n backend requests (with the help of {@link https://mswjs.io/ | msw}). + * The reason to put it inside of a mock is to elevate it. + * This is necessary because how our code is structured. + * Do NOT try to put any of this code into external functions, it won't work as it's elevated during runtime. + */ +vi.mock("i18next", async (importOriginal) => { + console.log("Mocking i18next"); + const { setupServer } = await import("msw/node"); + const { http, HttpResponse } = await import("msw"); + + global.i18nServer = setupServer( + http.get("/locales/en/*", async (req) => { + const filename = req.params[0]; + + try { + const json = await import(`../../public/locales/en/${req.params[0]}`); + console.log("Loaded locale", filename); + return HttpResponse.json(json); + } catch (err) { + console.log(`Failed to load locale ${filename}!`, err); + return HttpResponse.json({}); } - }, - }, -})); + }) + ); + global.i18nServer.listen({ onUnhandledRequest: "error" }); + console.log("i18n MSW server listening!"); + + return await importOriginal(); +}); initVouchers(); initAchievements(); @@ -70,3 +81,8 @@ beforeAll(() => { }, }); }); + +afterAll(() => { + global.i18nServer.close(); + console.log("Closing i18n MSW server!"); +}); diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 3caa84fd39b..4c56ada1c94 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -5,13 +5,13 @@ import i18next from "i18next"; export enum EventType { SHINY, - GENERIC + NO_TIMER_DISPLAY } interface EventBanner { bannerKey?: string; - xPosition?: number; - yPosition?: number; + xOffset?: number; + yOffset?: number; scale?: number; availableLangs?: string[]; } @@ -20,21 +20,22 @@ interface TimedEvent extends EventBanner { name: string; eventType: EventType; shinyMultiplier?: number; + friendshipMultiplier?: number; startDate: Date; endDate: Date; } const timedEvents: TimedEvent[] = [ { - name: "Egg Skip Update", - eventType: EventType.GENERIC, - startDate: new Date(Date.UTC(2024, 8, 8, 0)), - endDate: new Date(Date.UTC(2024, 8, 12, 0)), - bannerKey: "egg-update", - xPosition: 19, - yPosition: 120, + name: "Halloween Update", + eventType: EventType.SHINY, + shinyMultiplier: 2, + friendshipMultiplier: 2, + startDate: new Date(Date.UTC(2024, 9, 27, 0)), + endDate: new Date(Date.UTC(2024, 10, 4, 0)), + bannerKey: "halloween2024-event-", scale: 0.21, - availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"] + availableLangs: [ "en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN" ] } ]; @@ -61,6 +62,16 @@ export class TimedEventManager { return activeEvents.length > 0; } + getFriendshipMultiplier(): number { + let multiplier = 1; + const friendshipEvents = timedEvents.filter((te) => this.isActive(te)); + friendshipEvents.forEach((fe) => { + multiplier *= fe.friendshipMultiplier ?? 1; + }); + + return multiplier; + } + getShinyMultiplier(): number { let multiplier = 1; const shinyEvents = timedEvents.filter((te) => te.eventType === EventType.SHINY && this.isActive(te)); @@ -80,42 +91,63 @@ export class TimedEventDisplay extends Phaser.GameObjects.Container { private event: TimedEvent | nil; private eventTimerText: Phaser.GameObjects.Text; private banner: Phaser.GameObjects.Image; - private bannerShadow: Phaser.GameObjects.Rectangle; + private availableWidth: number; private eventTimer: NodeJS.Timeout | null; constructor(scene: BattleScene, x: number, y: number, event?: TimedEvent) { super(scene, x, y); + this.availableWidth = scene.scaledCanvas.width; this.event = event; this.setVisible(false); } + /** + * Set the width that can be used to display the event timer and banner. By default + * these elements get centered horizontally in that space, in the bottom left of the screen + */ + setWidth(width: number) { + if (width !== this.availableWidth) { + this.availableWidth = width; + const xPosition = this.availableWidth / 2 + (this.event?.xOffset ?? 0); + if (this.banner) { + this.banner.x = xPosition; + } + if (this.eventTimerText) { + this.eventTimerText.x = xPosition; + } + } + } + setup() { const lang = i18next.resolvedLanguage; if (this.event && this.event.bannerKey) { let key = this.event.bannerKey; if (lang && this.event.availableLangs && this.event.availableLangs.length > 0) { if (this.event.availableLangs.includes(lang)) { - key += "_"+lang; + key += lang; } else { - key += "_en"; + key += "en"; } } console.log(this.event.bannerKey); - this.banner = new Phaser.GameObjects.Image(this.scene, this.event.xPosition ?? 29, this.event.yPosition ?? 64, key); + const padding = 5; + const showTimer = this.event.eventType !== EventType.NO_TIMER_DISPLAY; + const yPosition = this.scene.game.canvas.height / 6 - padding - (showTimer ? 10 : 0) - (this.event.yOffset ?? 0); + this.banner = new Phaser.GameObjects.Image(this.scene, this.availableWidth / 2, yPosition - padding, key); this.banner.setName("img-event-banner"); - this.banner.setOrigin(0.08, -0.35); + this.banner.setOrigin(0.5, 1); this.banner.setScale(this.event.scale ?? 0.18); - if (this.event.eventType !== EventType.GENERIC) { + if (showTimer) { this.eventTimerText = addTextObject( this.scene, - this.banner.x + 8, - this.banner.y + 100, + this.banner.x, + this.banner.y + 2, this.timeToGo(this.event.endDate), TextStyle.WINDOW ); this.eventTimerText.setName("text-event-timer"); this.eventTimerText.setScale(0.15); - this.eventTimerText.setOrigin(0, 0); + this.eventTimerText.setOrigin(0.5, 0); this.add(this.eventTimerText); } @@ -142,7 +174,7 @@ export class TimedEventDisplay extends Phaser.GameObjects.Container { // Utility to add leading zero function z(n) { - return (n < 10? "0" : "") + n; + return (n < 10 ? "0" : "") + n; } const now = new Date(); let diff = Math.abs(date.getTime() - now.getTime()); @@ -151,17 +183,17 @@ export class TimedEventDisplay extends Phaser.GameObjects.Container { diff = Math.abs(diff); // Get time components - const days = diff/8.64e7 | 0; - const hours = diff%8.64e7 / 3.6e6 | 0; - const mins = diff%3.6e6 / 6e4 | 0; - const secs = Math.round(diff%6e4 / 1e3); + const days = diff / 8.64e7 | 0; + const hours = diff % 8.64e7 / 3.6e6 | 0; + const mins = diff % 3.6e6 / 6e4 | 0; + const secs = Math.round(diff % 6e4 / 1e3); // Return formatted string - return "Event Ends in : " + z(days) + "d " + z(hours) + "h " + z(mins) + "m " + z(secs)+ "s"; + return "Event Ends in : " + z(days) + "d " + z(hours) + "h " + z(mins) + "m " + z(secs) + "s"; } updateCountdown() { - if (this.event && this.event.eventType !== EventType.GENERIC) { + if (this.event && this.event.eventType !== EventType.NO_TIMER_DISPLAY) { this.eventTimerText.setText(this.timeToGo(this.event.endDate)); } } diff --git a/src/touch-controls.ts b/src/touch-controls.ts index 53df545e27f..93032ce59fe 100644 --- a/src/touch-controls.ts +++ b/src/touch-controls.ts @@ -1,4 +1,4 @@ -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import EventEmitter = Phaser.Events.EventEmitter; import BattleScene from "./battle-scene"; @@ -122,20 +122,20 @@ export default class TouchControl { const button = Button[key]; switch (eventType) { - case "keydown": - this.events.emit("input_down", { - controller_type: "keyboard", - button: button, - isTouch: true - }); - break; - case "keyup": - this.events.emit("input_up", { - controller_type: "keyboard", - button: button, - isTouch: true - }); - break; + case "keydown": + this.events.emit("input_down", { + controller_type: "keyboard", + button: button, + isTouch: true + }); + break; + case "keyup": + this.events.emit("input_up", { + controller_type: "keyboard", + button: button, + isTouch: true + }); + break; } return true; } @@ -206,7 +206,7 @@ export function isMobile(): boolean { let ret = false; (function (a) { // Check the user agent string against a regex for mobile devices - if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) { + if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) { ret = true; } })(navigator.userAgent || navigator.vendor || window["opera"]); diff --git a/src/ui-inputs.ts b/src/ui-inputs.ts index b9ecb55958c..92b1653df3d 100644 --- a/src/ui-inputs.ts +++ b/src/ui-inputs.ts @@ -1,11 +1,11 @@ import Phaser from "phaser"; -import {Mode} from "./ui/ui"; -import {InputsController} from "./inputs-controller"; +import { Mode } from "./ui/ui"; +import { InputsController } from "./inputs-controller"; import MessageUiHandler from "./ui/message-ui-handler"; import StarterSelectUiHandler from "./ui/starter-select-ui-handler"; -import {Setting, SettingKeys, settingIndex} from "./system/settings/settings"; +import { Setting, SettingKeys, settingIndex } from "./system/settings/settings"; import SettingsUiHandler from "./ui/settings/settings-ui-handler"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import SettingsGamepadUiHandler from "./ui/settings/settings-gamepad-ui-handler"; import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler"; import BattleScene from "./battle-scene"; @@ -142,7 +142,7 @@ export class UiInputs { } buttonGoToFilter(button: Button): void { - const whitelist = [StarterSelectUiHandler]; + const whitelist = [ StarterSelectUiHandler ]; const uiHandler = this.scene.ui?.getHandler(); if (whitelist.some(handler => uiHandler instanceof handler)) { this.scene.ui.processInput(button); @@ -168,31 +168,31 @@ export class UiInputs { return; } switch (this.scene.ui?.getMode()) { - case Mode.MESSAGE: - const messageHandler = this.scene.ui.getHandler(); - if (!messageHandler.pendingPrompt || messageHandler.isTextAnimationInProgress()) { + case Mode.MESSAGE: + const messageHandler = this.scene.ui.getHandler(); + if (!messageHandler.pendingPrompt || messageHandler.isTextAnimationInProgress()) { + return; + } + case Mode.TITLE: + case Mode.COMMAND: + case Mode.MODIFIER_SELECT: + case Mode.MYSTERY_ENCOUNTER: + this.scene.ui.setOverlayMode(Mode.MENU); + break; + case Mode.STARTER_SELECT: + this.buttonTouch(); + break; + case Mode.MENU: + this.scene.ui.revertMode(); + this.scene.playSound("ui/select"); + break; + default: return; - } - case Mode.TITLE: - case Mode.COMMAND: - case Mode.MODIFIER_SELECT: - case Mode.MYSTERY_ENCOUNTER: - this.scene.ui.setOverlayMode(Mode.MENU); - break; - case Mode.STARTER_SELECT: - this.buttonTouch(); - break; - case Mode.MENU: - this.scene.ui.revertMode(); - this.scene.playSound("ui/select"); - break; - default: - return; } } buttonCycleOption(button: Button): void { - const whitelist = [StarterSelectUiHandler, SettingsUiHandler, RunInfoUiHandler, SettingsDisplayUiHandler, SettingsAudioUiHandler, SettingsGamepadUiHandler, SettingsKeyboardUiHandler]; + const whitelist = [ StarterSelectUiHandler, SettingsUiHandler, RunInfoUiHandler, SettingsDisplayUiHandler, SettingsAudioUiHandler, SettingsGamepadUiHandler, SettingsKeyboardUiHandler ]; const uiHandler = this.scene.ui?.getHandler(); if (whitelist.some(handler => uiHandler instanceof handler)) { this.scene.ui.processInput(button); diff --git a/src/ui/abstact-option-select-ui-handler.ts b/src/ui/abstact-option-select-ui-handler.ts index 740830595ed..01fc5b00014 100644 --- a/src/ui/abstact-option-select-ui-handler.ts +++ b/src/ui/abstact-option-select-ui-handler.ts @@ -5,7 +5,7 @@ import UiHandler from "./ui-handler"; import { addWindow } from "./ui-theme"; import * as Utils from "../utils"; import { argbFromRgba } from "@material/material-color-utilities"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; export interface OptionSelectConfig { xOffset?: number; @@ -116,7 +116,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { this.optionSelectBg.height = this.getWindowHeight(); - this.optionSelectText.setPositionRelative(this.optionSelectBg, 12+24*this.scale, 2+42*this.scale); + this.optionSelectText.setPositionRelative(this.optionSelectBg, 12 + 24 * this.scale, 2 + 42 * this.scale); options.forEach((option: OptionSelectItem, i: integer) => { if (option.item) { @@ -165,6 +165,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { if (this.config.delay) { this.blockInput = true; this.optionSelectText.setAlpha(0.5); + this.cursorObj?.setAlpha(0.8); this.scene.time.delayedCall(Utils.fixedInt(this.config.delay), () => this.unblockInput()); } @@ -221,20 +222,20 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { } } else { switch (button) { - case Button.UP: - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } else if (this.cursor === 0) { - success = this.setCursor(options.length -1); - } - break; - case Button.DOWN: - if (this.cursor < options.length - 1) { - success = this.setCursor(this.cursor + 1); - } else { - success = this.setCursor(0); - } - break; + case Button.UP: + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } else if (this.cursor === 0) { + success = this.setCursor(options.length - 1); + } + break; + case Button.DOWN: + if (this.cursor < options.length - 1) { + success = this.setCursor(this.cursor + 1); + } else { + success = this.setCursor(0); + } + break; } if (this.config?.supportHover) { // handle hover code if the element supports hover-handlers and the option has the optional hover-handler set. @@ -256,6 +257,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { this.blockInput = false; this.optionSelectText.setAlpha(1); + this.cursorObj?.setAlpha(1); } getOptionsWithScroll(): OptionSelectItem[] { @@ -335,7 +337,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { } this.cursorObj.setScale(this.scale * 6); - this.cursorObj.setPositionRelative(this.optionSelectBg, 12, 102*this.scale + this.cursor * (114 * this.scale - 3)); + this.cursorObj.setPositionRelative(this.optionSelectBg, 12, 102 * this.scale + this.cursor * (114 * this.scale - 3)); return changed; } diff --git a/src/ui/achvs-ui-handler.ts b/src/ui/achvs-ui-handler.ts index 491c4acb523..a1ced6145eb 100644 --- a/src/ui/achvs-ui-handler.ts +++ b/src/ui/achvs-ui-handler.ts @@ -40,7 +40,9 @@ export default class AchvsUiHandler extends MessageUiHandler { private iconsBg: Phaser.GameObjects.NineSlice; private icons: Phaser.GameObjects.Sprite[]; + private titleBg: Phaser.GameObjects.NineSlice; private titleText: Phaser.GameObjects.Text; + private scoreContainer: Phaser.GameObjects.Container; private scoreText: Phaser.GameObjects.Text; private unlockText: Phaser.GameObjects.Text; @@ -79,7 +81,7 @@ export default class AchvsUiHandler extends MessageUiHandler { this.headerActionButton = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "keyboard", "ACTION.png"); this.headerActionButton.setOrigin(0, 0); this.headerActionButton.setPositionRelative(this.headerBg, 236, 6); - this.headerActionText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW, {fontSize:"60px"}); + this.headerActionText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW, { fontSize:"60px" }); this.headerActionText.setOrigin(0, 0); this.headerActionText.setPositionRelative(this.headerBg, 264, 8); @@ -114,29 +116,31 @@ export default class AchvsUiHandler extends MessageUiHandler { const titleBg = addWindow(this.scene, 0, this.headerBg.height + this.iconsBg.height, 174, 24); titleBg.setOrigin(0, 0); + this.titleBg = titleBg; this.titleText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW); const textSize = languageSettings[i18next.language]?.TextSize ?? this.titleText.style.fontSize; this.titleText.setFontSize(textSize); - this.titleText.setOrigin(0, 0); const titleBgCenterX = titleBg.x + titleBg.width / 2; const titleBgCenterY = titleBg.y + titleBg.height / 2; this.titleText.setOrigin(0.5, 0.5); this.titleText.setPosition(titleBgCenterX, titleBgCenterY); - const scoreBg = addWindow(this.scene, titleBg.x + titleBg.width, titleBg.y, 46, 24); + this.scoreContainer = this.scene.add.container(titleBg.x + titleBg.width, titleBg.y); + const scoreBg = addWindow(this.scene, 0, 0, 46, 24); scoreBg.setOrigin(0, 0); + this.scoreContainer.add(scoreBg); - this.scoreText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW); - this.scoreText.setOrigin(0, 0); - this.scoreText.setPositionRelative(scoreBg, 8, 4); + this.scoreText = addTextObject(this.scene, scoreBg.width / 2, scoreBg.height / 2, "", TextStyle.WINDOW); + this.scoreText.setOrigin(0.5, 0.5); + this.scoreContainer.add(this.scoreText); - const unlockBg = addWindow(this.scene, scoreBg.x + scoreBg.width, scoreBg.y, 98, 24); + const unlockBg = addWindow(this.scene, this.scoreContainer.x + scoreBg.width, titleBg.y, 98, 24); unlockBg.setOrigin(0, 0); this.unlockText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW); - this.unlockText.setOrigin(0, 0); - this.unlockText.setPositionRelative(unlockBg, 8, 4); + this.unlockText.setOrigin(0.5, 0.5); + this.unlockText.setPositionRelative(unlockBg, unlockBg.width / 2, unlockBg.height / 2); const descriptionBg = addWindow(this.scene, 0, titleBg.y + titleBg.height, (this.scene.game.canvas.width / 6) - 2, 42); descriptionBg.setOrigin(0, 0); @@ -157,8 +161,7 @@ export default class AchvsUiHandler extends MessageUiHandler { this.mainContainer.add(this.iconsContainer); this.mainContainer.add(titleBg); this.mainContainer.add(this.titleText); - this.mainContainer.add(scoreBg); - this.mainContainer.add(this.scoreText); + this.mainContainer.add(this.scoreContainer); this.mainContainer.add(unlockBg); this.mainContainer.add(this.unlockText); this.mainContainer.add(descriptionBg); @@ -167,8 +170,6 @@ export default class AchvsUiHandler extends MessageUiHandler { ui.add(this.mainContainer); this.currentPage = Page.ACHIEVEMENTS; - this.setCursor(0); - this.setScrollCursor(0); this.mainContainer.setVisible(false); } @@ -244,51 +245,51 @@ export default class AchvsUiHandler extends MessageUiHandler { const rowIndex = Math.floor(this.cursor / this.COLS); const itemOffset = (this.scrollCursor * this.COLS); switch (button) { - case Button.UP: - if (this.cursor < this.COLS) { - if (this.scrollCursor) { - success = this.setScrollCursor(this.scrollCursor - 1); - } else { + case Button.UP: + if (this.cursor < this.COLS) { + if (this.scrollCursor) { + success = this.setScrollCursor(this.scrollCursor - 1); + } else { // Wrap around to the last row - success = this.setScrollCursor(Math.ceil(this.currentTotal / this.COLS) - this.ROWS); - let newCursorIndex = this.cursor + (this.ROWS - 1) * this.COLS; - if (newCursorIndex > this.currentTotal - this.scrollCursor * this.COLS -1) { - newCursorIndex -= this.COLS; + success = this.setScrollCursor(Math.ceil(this.currentTotal / this.COLS) - this.ROWS); + let newCursorIndex = this.cursor + (this.ROWS - 1) * this.COLS; + if (newCursorIndex > this.currentTotal - this.scrollCursor * this.COLS - 1) { + newCursorIndex -= this.COLS; + } + success = success && this.setCursor(newCursorIndex); } - success = success && this.setCursor(newCursorIndex); - } - } else { - success = this.setCursor(this.cursor - this.COLS); - } - break; - case Button.DOWN: - const canMoveDown = itemOffset + 1 < this.currentTotal; - if (rowIndex >= this.ROWS - 1) { - if (this.scrollCursor < Math.ceil(this.currentTotal / this.COLS) - this.ROWS && canMoveDown) { - // scroll down one row - success = this.setScrollCursor(this.scrollCursor + 1); } else { - // wrap back to the first row - success = this.setScrollCursor(0) && this.setCursor(this.cursor % this.COLS); + success = this.setCursor(this.cursor - this.COLS); } - } else if (canMoveDown) { - success = this.setCursor(Math.min(this.cursor + this.COLS, this.currentTotal - itemOffset - 1)); - } - break; - case Button.LEFT: - if (this.cursor % this.COLS === 0) { - success = this.setCursor(Math.min(this.cursor + this.COLS - 1, this.currentTotal - itemOffset - 1)); - } else { - success = this.setCursor(this.cursor - 1); - } - break; - case Button.RIGHT: - if ((this.cursor + 1) % this.COLS === 0 || (this.cursor + itemOffset) === (this.currentTotal - 1)) { - success = this.setCursor(this.cursor - this.cursor % this.COLS); - } else { - success = this.setCursor(this.cursor + 1); - } - break; + break; + case Button.DOWN: + const canMoveDown = itemOffset + 1 < this.currentTotal; + if (rowIndex >= this.ROWS - 1) { + if (this.scrollCursor < Math.ceil(this.currentTotal / this.COLS) - this.ROWS && canMoveDown) { + // scroll down one row + success = this.setScrollCursor(this.scrollCursor + 1); + } else { + // wrap back to the first row + success = this.setScrollCursor(0) && this.setCursor(this.cursor % this.COLS); + } + } else if (canMoveDown) { + success = this.setCursor(Math.min(this.cursor + this.COLS, this.currentTotal - itemOffset - 1)); + } + break; + case Button.LEFT: + if (this.cursor % this.COLS === 0) { + success = this.setCursor(Math.min(this.cursor + this.COLS - 1, this.currentTotal - itemOffset - 1)); + } else { + success = this.setCursor(this.cursor - 1); + } + break; + case Button.RIGHT: + if ((this.cursor + 1) % this.COLS === 0 || (this.cursor + itemOffset) === (this.currentTotal - 1)) { + success = this.setCursor(this.cursor - this.cursor % this.COLS); + } else { + success = this.setCursor(this.cursor + 1); + } + break; } } @@ -315,12 +316,22 @@ export default class AchvsUiHandler extends MessageUiHandler { if (update || pageChange) { switch (this.currentPage) { - case Page.ACHIEVEMENTS: - this.showAchv(achvs[Object.keys(achvs)[cursor + this.scrollCursor * this.COLS]]); - break; - case Page.VOUCHERS: - this.showVoucher(vouchers[Object.keys(vouchers)[cursor + this.scrollCursor * this.COLS]]); - break; + case Page.ACHIEVEMENTS: + if (pageChange) { + this.titleBg.width = 174; + this.titleText.x = this.titleBg.width / 2; + this.scoreContainer.setVisible(true); + } + this.showAchv(achvs[Object.keys(achvs)[cursor + this.scrollCursor * this.COLS]]); + break; + case Page.VOUCHERS: + if (pageChange) { + this.titleBg.width = 220; + this.titleText.x = this.titleBg.width / 2; + this.scoreContainer.setVisible(false); + } + this.showVoucher(vouchers[Object.keys(vouchers)[cursor + this.scrollCursor * this.COLS]]); + break; } } return ret; @@ -347,14 +358,14 @@ export default class AchvsUiHandler extends MessageUiHandler { } switch (this.currentPage) { - case Page.ACHIEVEMENTS: - this.updateAchvIcons(); - this.showAchv(achvs[Object.keys(achvs)[this.cursor + this.scrollCursor * this.COLS]]); - break; - case Page.VOUCHERS: - this.updateVoucherIcons(); - this.showVoucher(vouchers[Object.keys(vouchers)[this.cursor + this.scrollCursor * this.COLS]]); - break; + case Page.ACHIEVEMENTS: + this.updateAchvIcons(); + this.showAchv(achvs[Object.keys(achvs)[this.cursor + this.scrollCursor * this.COLS]]); + break; + case Page.VOUCHERS: + this.updateVoucherIcons(); + this.showVoucher(vouchers[Object.keys(vouchers)[this.cursor + this.scrollCursor * this.COLS]]); + break; } return true; } @@ -442,6 +453,7 @@ export default class AchvsUiHandler extends MessageUiHandler { this.currentPage = Page.ACHIEVEMENTS; this.mainContainer.setVisible(false); this.setScrollCursor(0); + this.setCursor(0, true); this.eraseCursor(); } diff --git a/src/ui/admin-ui-handler.ts b/src/ui/admin-ui-handler.ts index c48138853fc..6249e54d8c3 100644 --- a/src/ui/admin-ui-handler.ts +++ b/src/ui/admin-ui-handler.ts @@ -2,37 +2,83 @@ import BattleScene from "#app/battle-scene"; import { ModalConfig } from "./modal-ui-handler"; import { Mode } from "./ui"; import * as Utils from "../utils"; -import { FormModalUiHandler } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { Button } from "#app/enums/buttons"; +import { TextStyle } from "./text"; export default class AdminUiHandler extends FormModalUiHandler { + private adminMode: AdminMode; + private adminResult: AdminSearchInfo; + private config: ModalConfig; + + private readonly buttonGap = 10; + // http response from the server when a username isn't found in the server + private readonly httpUserNotFoundErrorCode: number = 404; + private readonly ERR_REQUIRED_FIELD = (field: string) => { + if (field === "username") { + return `${Utils.formatText(field)} is required`; + } else { + return `${Utils.formatText(field)} Id is required`; + } + }; + // returns a string saying whether a username has been successfully linked/unlinked to discord/google + private readonly SUCCESS_SERVICE_MODE = (service: string, mode: string) => { + return `Username and ${service} successfully ${mode.toLowerCase()}ed`; + }; + private readonly ERR_USERNAME_NOT_FOUND: string = "Username not found!"; + private readonly ERR_GENERIC_ERROR: string = "There was an error"; + constructor(scene: BattleScene, mode: Mode | null = null) { super(scene, mode); } - setup(): void { - super.setup(); - } - - getModalTitle(config?: ModalConfig): string { + override getModalTitle(): string { return "Admin panel"; } - getFields(config?: ModalConfig): string[] { - return ["Username", "Discord ID"]; + override getWidth(): number { + return this.adminMode === AdminMode.ADMIN ? 180 : 160; } - getWidth(config?: ModalConfig): number { - return 160; + override getMargin(): [number, number, number, number] { + return [ 0, 0, 0, 0 ]; } - getMargin(config?: ModalConfig): [number, number, number, number] { - return [0, 0, 48, 0]; + override getButtonLabels(): string[] { + switch (this.adminMode) { + case AdminMode.LINK: + return [ "Link Account", "Cancel" ]; + case AdminMode.SEARCH: + return [ "Find account", "Cancel" ]; + case AdminMode.ADMIN: + return [ "Back to search", "Cancel" ]; + default: + return [ "Activate ADMIN", "Cancel" ]; + } } - getButtonLabels(config?: ModalConfig): string[] { - return ["Link account", "Cancel"]; + override getInputFieldConfigs(): InputFieldConfig[] { + const inputFieldConfigs: InputFieldConfig[] = []; + switch (this.adminMode) { + case AdminMode.LINK: + inputFieldConfigs.push( { label: "Username" }); + inputFieldConfigs.push( { label: "Discord ID" }); + break; + case AdminMode.SEARCH: + inputFieldConfigs.push( { label: "Username" }); + break; + case AdminMode.ADMIN: + const adminResult = this.adminResult ?? { username: "", discordId: "", googleId: "", lastLoggedIn: "", registered: "" }; + // Discord and Google ID fields that are not empty get locked, other fields are all locked + inputFieldConfigs.push( { label: "Username", isReadOnly: true }); + inputFieldConfigs.push( { label: "Discord ID", isReadOnly: adminResult.discordId !== "" }); + inputFieldConfigs.push( { label: "Google ID", isReadOnly: adminResult.googleId !== "" }); + inputFieldConfigs.push( { label: "Last played", isReadOnly: true }); + inputFieldConfigs.push( { label: "Registered", isReadOnly: true }); + break; + } + return inputFieldConfigs; } processInput(button: Button): boolean { @@ -45,44 +91,281 @@ export default class AdminUiHandler extends FormModalUiHandler { } show(args: any[]): boolean { + this.config = args[0] as ModalConfig; // config + this.adminMode = args[1] as AdminMode; // admin mode + this.adminResult = args[2] ?? { username: "", discordId: "", googleId: "", lastLoggedIn: "", registered: "" }; // admin result, if any + const isMessageError = args[3]; // is the message shown a success or error + + const fields = this.getInputFieldConfigs(); + const hasTitle = !!this.getModalTitle(); + + this.updateFields(fields, hasTitle); + this.updateContainer(this.config); + + const labels = this.getButtonLabels(); + for (let i = 0; i < labels.length; i++) { + this.buttonLabels[i].setText(labels[i]); // sets the label text + } + + this.errorMessage.setPosition(10, (hasTitle ? 31 : 5) + 20 * (fields.length - 1) + 16 + this.getButtonTopMargin()); // sets the position of the message dynamically + if (isMessageError) { + this.errorMessage.setColor(this.getTextColor(TextStyle.SUMMARY_PINK)); + this.errorMessage.setShadowColor(this.getTextColor(TextStyle.SUMMARY_PINK, true)); + } else { + this.errorMessage.setColor(this.getTextColor(TextStyle.SUMMARY_GREEN)); + this.errorMessage.setShadowColor(this.getTextColor(TextStyle.SUMMARY_GREEN, true)); + } + if (super.show(args)) { - const config = args[0] as ModalConfig; + this.populateFields(this.adminMode, this.adminResult); const originalSubmitAction = this.submitAction; this.submitAction = (_) => { this.submitAction = originalSubmitAction; - this.scene.ui.setMode(Mode.LOADING, { buttonActions: [] }); - const onFail = error => { - this.scene.ui.setMode(Mode.ADMIN, Object.assign(config, { errorMessage: error?.trim() })); - this.scene.ui.playError(); - }; - if (!this.inputs[0].text) { - return onFail("Username is required"); + const adminSearchResult: AdminSearchInfo = this.convertInputsToAdmin(); // this converts the input texts into a single object for use later + const validFields = this.areFieldsValid(this.adminMode); + if (validFields.error) { + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); // this is here to force a loading screen to allow the admin tool to reopen again if there's an error + return this.showMessage(validFields.errorMessage ?? "", adminSearchResult, true); } - if (!this.inputs[1].text) { - return onFail("Discord Id is required"); + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); + if (this.adminMode === AdminMode.LINK) { + this.adminLinkUnlink(adminSearchResult, "discord", "Link") // calls server to link discord + .then(response => { + if (response.error) { + return this.showMessage(response.errorType, adminSearchResult, true); // error or some kind + } else { + return this.showMessage(this.SUCCESS_SERVICE_MODE("discord", "link"), adminSearchResult, false); // success + } + }); + } else if (this.adminMode === AdminMode.SEARCH) { + this.adminSearch(adminSearchResult) // admin search for username + .then(response => { + if (response.error) { + return this.showMessage(response.errorType, adminSearchResult, true); // failure + } + this.updateAdminPanelInfo(response.adminSearchResult ?? adminSearchResult); // success + }); + } else if (this.adminMode === AdminMode.ADMIN) { + this.updateAdminPanelInfo(adminSearchResult, AdminMode.SEARCH); } - Utils.apiPost("admin/account/discord-link", `username=${encodeURIComponent(this.inputs[0].text)}&discordId=${encodeURIComponent(this.inputs[1].text)}`, "application/x-www-form-urlencoded", true) - .then(response => { - if (!response.ok) { - console.error(response); - } - this.inputs[0].setText(""); - this.inputs[1].setText(""); - this.scene.ui.revertMode(); - }) - .catch((err) => { - console.error(err); - this.scene.ui.revertMode(); - }); return false; }; return true; } return false; + } + showMessage(message: string, adminResult: AdminSearchInfo, isError: boolean) { + this.scene.ui.setMode(Mode.ADMIN, Object.assign(this.config, { errorMessage: message?.trim() }), this.adminMode, adminResult, isError); + if (isError) { + this.scene.ui.playError(); + } else { + this.scene.ui.playSelect(); + } + } + + /** + * This is used to update the fields' text when loading in a new admin ui handler. It uses the {@linkcode adminResult} + * to update the input text based on the {@linkcode adminMode}. For a linking adminMode, it sets the username and discord. + * For a search adminMode, it sets the username. For an admin adminMode, it sets all the info from adminResult in the + * appropriate text boxes, and also sets the link/unlink icons for discord/google depending on the result + */ + private populateFields(adminMode: AdminMode, adminResult: AdminSearchInfo) { + switch (adminMode) { + case AdminMode.LINK: + this.inputs[0].setText(adminResult.username); + this.inputs[1].setText(adminResult.discordId); + break; + case AdminMode.SEARCH: + this.inputs[0].setText(adminResult.username); + break; + case AdminMode.ADMIN: + Object.keys(adminResult).forEach((aR, i) => { + this.inputs[i].setText(adminResult[aR]); + if (aR === "discordId" || aR === "googleId") { // this is here to add the icons for linking/unlinking of google/discord IDs + const nineSlice = this.inputContainers[i].list.find(iC => iC.type === "NineSlice"); + const img = this.scene.add.image(this.inputContainers[i].x + nineSlice!.width + this.buttonGap, this.inputContainers[i].y + (Math.floor(nineSlice!.height / 2)), adminResult[aR] === "" ? "link_icon" : "unlink_icon"); + img.setName(`adminBtn_${aR}`); + img.setOrigin(0.5, 0.5); + img.setInteractive(); + img.on("pointerdown", () => { + const service = aR.toLowerCase().replace("id", ""); // this takes our key (discordId or googleId) and removes the "Id" at the end to make it more url friendly + const mode = adminResult[aR] === "" ? "Link" : "Unlink"; // this figures out if we're linking or unlinking a service + const validFields = this.areFieldsValid(this.adminMode, service); + if (validFields.error) { + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); // this is here to force a loading screen to allow the admin tool to reopen again if there's an error + return this.showMessage(validFields.errorMessage ?? "", adminResult, true); + } + this.adminLinkUnlink(this.convertInputsToAdmin(), service, mode).then(response => { // attempts to link/unlink depending on the service + if (response.error) { + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); + return this.showMessage(response.errorType, adminResult, true); // fail + } else { // success, reload panel with new results + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); + this.adminSearch(adminResult) + .then(response => { + if (response.error) { + return this.showMessage(response.errorType, adminResult, true); + } + return this.showMessage(this.SUCCESS_SERVICE_MODE(service, mode), response.adminSearchResult ?? adminResult, false); + }); + } + }); + }); + this.addInteractionHoverEffect(img); + this.modalContainer.add(img); + } + }); + break; + } + } + + private areFieldsValid(adminMode: AdminMode, service?: string): { error: boolean; errorMessage?: string; } { + switch (adminMode) { + case AdminMode.LINK: + if (!this.inputs[0].text) { // username missing from link panel + return { + error: true, + errorMessage: this.ERR_REQUIRED_FIELD("username") + }; + } + if (!this.inputs[1].text) { // discordId missing from linking panel + return { + error: true, + errorMessage: this.ERR_REQUIRED_FIELD("discord") + }; + } + break; + case AdminMode.SEARCH: + if (!this.inputs[0].text) { // username missing from search panel + return { + error: true, + errorMessage: this.ERR_REQUIRED_FIELD("username") + }; + } + break; + case AdminMode.ADMIN: + if (!this.inputs[1].text && service === "discord") { // discordId missing from admin panel + return { + error: true, + errorMessage: this.ERR_REQUIRED_FIELD(service) + }; + } + if (!this.inputs[2].text && service === "google") { // googleId missing from admin panel + return { + error: true, + errorMessage: this.ERR_REQUIRED_FIELD(service) + }; + } + break; + } + return { + error: false + }; + } + + private convertInputsToAdmin(): AdminSearchInfo { + return { + username: this.inputs[0]?.node ? this.inputs[0].text : "", + discordId: this.inputs[1]?.node ? this.inputs[1]?.text : "", + googleId: this.inputs[2]?.node ? this.inputs[2]?.text : "", + lastLoggedIn: this.inputs[3]?.node ? this.inputs[3]?.text : "", + registered: this.inputs[4]?.node ? this.inputs[4]?.text : "" + }; + } + + private async adminSearch(adminSearchResult: AdminSearchInfo) { + try { + const adminInfo = await Utils.apiFetch(`admin/account/adminSearch?username=${encodeURIComponent(adminSearchResult.username)}`, true); + if (!adminInfo.ok) { // error - if adminInfo.status === this.httpUserNotFoundErrorCode that means the username can't be found in the db + return { adminSearchResult: adminSearchResult, error: true, errorType: adminInfo.status === this.httpUserNotFoundErrorCode ? this.ERR_USERNAME_NOT_FOUND : this.ERR_GENERIC_ERROR }; + } else { // success + const adminInfoJson: AdminSearchInfo = await adminInfo.json(); + return { adminSearchResult: adminInfoJson, error: false }; + } + } catch (err) { + console.error(err); + return { error: true, errorType: err }; + } + } + + private async adminLinkUnlink(adminSearchResult: AdminSearchInfo, service: string, mode: string) { + try { + const response = await Utils.apiPost(`admin/account/${service}${mode}`, `username=${encodeURIComponent(adminSearchResult.username)}&${service}Id=${encodeURIComponent(service === "discord" ? adminSearchResult.discordId : adminSearchResult.googleId)}`, "application/x-www-form-urlencoded", true); + if (!response.ok) { // error - if response.status === this.httpUserNotFoundErrorCode that means the username can't be found in the db + return { adminSearchResult: adminSearchResult, error: true, errorType: response.status === this.httpUserNotFoundErrorCode ? this.ERR_USERNAME_NOT_FOUND : this.ERR_GENERIC_ERROR }; + } else { // success! + return { adminSearchResult: adminSearchResult, error: false }; + } + } catch (err) { + console.error(err); + return { error: true, errorType: err }; + } + } + + private updateAdminPanelInfo(adminSearchResult: AdminSearchInfo, mode?: AdminMode) { + mode = mode ?? AdminMode.ADMIN; + this.scene.ui.setMode(Mode.ADMIN, { + buttonActions: [ + // we double revert here and below to go back 2 layers of menus + () => { + this.scene.ui.revertMode(); + this.scene.ui.revertMode(); + }, + () => { + this.scene.ui.revertMode(); + this.scene.ui.revertMode(); + } + ] + }, mode, adminSearchResult); } clear(): void { super.clear(); + + // this is used to remove the existing fields on the admin panel so they can be updated + + const itemsToRemove: string[] = [ "formLabel", "adminBtn" ]; // this is the start of the names for each element we want to remove + const removeArray: any[] = []; + const mC = this.modalContainer.list; + for (let i = mC.length - 1; i >= 0; i--) { + /* This code looks for a few things before destroying the specific field; first it looks to see if the name of the element is %like% the itemsToRemove labels + * this means that anything with, for example, "formLabel", will be true. + * It then also checks for any containers that are within this.modalContainer, and checks if any of its child elements are of type rexInputText + * and if either of these conditions are met, the element is destroyed. + */ + if (itemsToRemove.some(iTR => mC[i].name.includes(iTR)) || (mC[i].type === "Container" && (mC[i] as Phaser.GameObjects.Container).list.find(m => m.type === "rexInputText"))) { + removeArray.push(mC[i]); + } + } + + while (removeArray.length > 0) { + this.modalContainer.remove(removeArray.pop(), true); + } } } + +export enum AdminMode { + LINK, + SEARCH, + ADMIN +} + +export function getAdminModeName(adminMode: AdminMode): string { + switch (adminMode) { + case AdminMode.LINK: + return "Link"; + case AdminMode.SEARCH: + return "Search"; + default: + return ""; + } +} + +interface AdminSearchInfo { + username: string; + discordId: string; + googleId: string; + lastLoggedIn: string; + registered: string; +} diff --git a/src/ui/arena-flyout.ts b/src/ui/arena-flyout.ts index 42a2396e665..a82f97244cd 100644 --- a/src/ui/arena-flyout.ts +++ b/src/ui/arena-flyout.ts @@ -9,7 +9,7 @@ import { BattleSceneEventType, TurnEndEvent } from "../events/battle-scene"; import { ArenaTagType } from "#enums/arena-tag-type"; import TimeOfDayWidget from "./time-of-day-widget"; import * as Utils from "../utils"; -import i18next, {ParseKeys} from "i18next"; +import i18next, { ParseKeys } from "i18next"; /** Enum used to differentiate {@linkcode Arena} effects */ enum ArenaEffectType { @@ -196,7 +196,6 @@ export class ArenaFlyout extends Phaser.GameObjects.Container { } - /** Clears out the current string stored in all arena effect texts */ private clearText() { this.flyoutTextPlayer.text = ""; @@ -216,20 +215,20 @@ export class ArenaFlyout extends Phaser.GameObjects.Container { // Creates a proxy object to decide which text object needs to be updated let textObject: Phaser.GameObjects.Text; switch (fieldEffectInfo.effecType) { - case ArenaEffectType.PLAYER: - textObject = this.flyoutTextPlayer; - break; + case ArenaEffectType.PLAYER: + textObject = this.flyoutTextPlayer; + break; - case ArenaEffectType.WEATHER: - case ArenaEffectType.TERRAIN: - case ArenaEffectType.FIELD: - textObject = this.flyoutTextField; + case ArenaEffectType.WEATHER: + case ArenaEffectType.TERRAIN: + case ArenaEffectType.FIELD: + textObject = this.flyoutTextField; - break; + break; - case ArenaEffectType.ENEMY: - textObject = this.flyoutTextEnemy; - break; + case ArenaEffectType.ENEMY: + textObject = this.flyoutTextEnemy; + break; } textObject.text += fieldEffectInfo.name; @@ -254,81 +253,81 @@ export class ArenaFlyout extends Phaser.GameObjects.Container { let foundIndex: number; switch (arenaEffectChangedEvent.constructor) { - case TagAddedEvent: - const tagAddedEvent = arenaEffectChangedEvent as TagAddedEvent; - const isArenaTrapTag = this.battleScene.arena.getTag(tagAddedEvent.arenaTagType) instanceof ArenaTrapTag; - let arenaEffectType: ArenaEffectType; + case TagAddedEvent: + const tagAddedEvent = arenaEffectChangedEvent as TagAddedEvent; + const isArenaTrapTag = this.battleScene.arena.getTag(tagAddedEvent.arenaTagType) instanceof ArenaTrapTag; + let arenaEffectType: ArenaEffectType; - if (tagAddedEvent.arenaTagSide === ArenaTagSide.BOTH) { - arenaEffectType = ArenaEffectType.FIELD; - } else if (tagAddedEvent.arenaTagSide === ArenaTagSide.PLAYER) { - arenaEffectType = ArenaEffectType.PLAYER; - } else { - arenaEffectType = ArenaEffectType.ENEMY; - } - - const existingTrapTagIndex = isArenaTrapTag ? this.fieldEffectInfo.findIndex(e => tagAddedEvent.arenaTagType === e.tagType && arenaEffectType === e.effecType) : -1; - let name: string = getFieldEffectText(ArenaTagType[tagAddedEvent.arenaTagType]); - - if (isArenaTrapTag) { - if (existingTrapTagIndex !== -1) { - const layers = tagAddedEvent.arenaTagMaxLayers > 1 ? ` (${tagAddedEvent.arenaTagLayers})` : ""; - this.fieldEffectInfo[existingTrapTagIndex].name = `${name}${layers}`; - break; - } else if (tagAddedEvent.arenaTagMaxLayers > 1) { - name = `${name} (${tagAddedEvent.arenaTagLayers})`; + if (tagAddedEvent.arenaTagSide === ArenaTagSide.BOTH) { + arenaEffectType = ArenaEffectType.FIELD; + } else if (tagAddedEvent.arenaTagSide === ArenaTagSide.PLAYER) { + arenaEffectType = ArenaEffectType.PLAYER; + } else { + arenaEffectType = ArenaEffectType.ENEMY; } - } - this.fieldEffectInfo.push({ - name, - effecType: arenaEffectType, - maxDuration: tagAddedEvent.duration, - duration: tagAddedEvent.duration, - tagType: tagAddedEvent.arenaTagType - }); - break; - case TagRemovedEvent: - const tagRemovedEvent = arenaEffectChangedEvent as TagRemovedEvent; - foundIndex = this.fieldEffectInfo.findIndex(info => info.tagType === tagRemovedEvent.arenaTagType); + const existingTrapTagIndex = isArenaTrapTag ? this.fieldEffectInfo.findIndex(e => tagAddedEvent.arenaTagType === e.tagType && arenaEffectType === e.effecType) : -1; + let name: string = getFieldEffectText(ArenaTagType[tagAddedEvent.arenaTagType]); - if (foundIndex !== -1) { // If the tag was being tracked, remove it - this.fieldEffectInfo.splice(foundIndex, 1); - } - break; + if (isArenaTrapTag) { + if (existingTrapTagIndex !== -1) { + const layers = tagAddedEvent.arenaTagMaxLayers > 1 ? ` (${tagAddedEvent.arenaTagLayers})` : ""; + this.fieldEffectInfo[existingTrapTagIndex].name = `${name}${layers}`; + break; + } else if (tagAddedEvent.arenaTagMaxLayers > 1) { + name = `${name} (${tagAddedEvent.arenaTagLayers})`; + } + } - case WeatherChangedEvent: - case TerrainChangedEvent: - const fieldEffectChangedEvent = arenaEffectChangedEvent as WeatherChangedEvent | TerrainChangedEvent; + this.fieldEffectInfo.push({ + name, + effecType: arenaEffectType, + maxDuration: tagAddedEvent.duration, + duration: tagAddedEvent.duration, + tagType: tagAddedEvent.arenaTagType + }); + break; + case TagRemovedEvent: + const tagRemovedEvent = arenaEffectChangedEvent as TagRemovedEvent; + foundIndex = this.fieldEffectInfo.findIndex(info => info.tagType === tagRemovedEvent.arenaTagType); - // Stores the old Weather/Terrain name in case it's in the array already - const oldName = + if (foundIndex !== -1) { // If the tag was being tracked, remove it + this.fieldEffectInfo.splice(foundIndex, 1); + } + break; + + case WeatherChangedEvent: + case TerrainChangedEvent: + const fieldEffectChangedEvent = arenaEffectChangedEvent as WeatherChangedEvent | TerrainChangedEvent; + + // Stores the old Weather/Terrain name in case it's in the array already + const oldName = getFieldEffectText(fieldEffectChangedEvent instanceof WeatherChangedEvent ? WeatherType[fieldEffectChangedEvent.oldWeatherType] : TerrainType[fieldEffectChangedEvent.oldTerrainType]); - // Stores the new Weather/Terrain info - const newInfo = { - name: + // Stores the new Weather/Terrain info + const newInfo = { + name: getFieldEffectText(fieldEffectChangedEvent instanceof WeatherChangedEvent ? WeatherType[fieldEffectChangedEvent.newWeatherType] : TerrainType[fieldEffectChangedEvent.newTerrainType]), - effecType: fieldEffectChangedEvent instanceof WeatherChangedEvent - ? ArenaEffectType.WEATHER - : ArenaEffectType.TERRAIN, - maxDuration: fieldEffectChangedEvent.duration, - duration: fieldEffectChangedEvent.duration}; + effecType: fieldEffectChangedEvent instanceof WeatherChangedEvent + ? ArenaEffectType.WEATHER + : ArenaEffectType.TERRAIN, + maxDuration: fieldEffectChangedEvent.duration, + duration: fieldEffectChangedEvent.duration }; - foundIndex = this.fieldEffectInfo.findIndex(info => [newInfo.name, oldName].includes(info.name)); - if (foundIndex === -1) { - if (newInfo.name !== undefined) { - this.fieldEffectInfo.push(newInfo); // Adds the info to the array if it doesn't already exist and is defined + foundIndex = this.fieldEffectInfo.findIndex(info => [ newInfo.name, oldName ].includes(info.name)); + if (foundIndex === -1) { + if (newInfo.name !== undefined) { + this.fieldEffectInfo.push(newInfo); // Adds the info to the array if it doesn't already exist and is defined + } + } else if (!newInfo.name) { + this.fieldEffectInfo.splice(foundIndex, 1); // Removes the old info if the new one is undefined + } else { + this.fieldEffectInfo[foundIndex] = newInfo; // Otherwise, replace the old info } - } else if (!newInfo.name) { - this.fieldEffectInfo.splice(foundIndex, 1); // Removes the old info if the new one is undefined - } else { - this.fieldEffectInfo[foundIndex] = newInfo; // Otherwise, replace the old info - } - break; + break; } this.updateFieldText(); diff --git a/src/ui/awaitable-ui-handler.ts b/src/ui/awaitable-ui-handler.ts index c6dc717aa3a..8256f938106 100644 --- a/src/ui/awaitable-ui-handler.ts +++ b/src/ui/awaitable-ui-handler.ts @@ -1,7 +1,7 @@ import BattleScene from "../battle-scene"; import { Mode } from "./ui"; import UiHandler from "./ui-handler"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; export default abstract class AwaitableUiHandler extends UiHandler { protected awaitingActionInput: boolean; diff --git a/src/ui/ball-ui-handler.ts b/src/ui/ball-ui-handler.ts index 332fe5f65b9..9df6da36055 100644 --- a/src/ui/ball-ui-handler.ts +++ b/src/ui/ball-ui-handler.ts @@ -5,7 +5,7 @@ import { Command } from "./command-ui-handler"; import { Mode } from "./ui"; import UiHandler from "./ui-handler"; import { addWindow } from "./ui-theme"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import { CommandPhase } from "#app/phases/command-phase"; export default class BallUiHandler extends UiHandler { @@ -90,12 +90,12 @@ export default class BallUiHandler extends UiHandler { } } else { switch (button) { - case Button.UP: - success = this.setCursor(this.cursor ? this.cursor - 1 : pokeballTypeCount); - break; - case Button.DOWN: - success = this.setCursor(this.cursor < pokeballTypeCount ? this.cursor + 1 : 0); - break; + case Button.UP: + success = this.setCursor(this.cursor ? this.cursor - 1 : pokeballTypeCount); + break; + case Button.DOWN: + success = this.setCursor(this.cursor < pokeballTypeCount ? this.cursor + 1 : 0); + break; } } diff --git a/src/ui/battle-flyout.ts b/src/ui/battle-flyout.ts index fe561b76c9f..4541a2bfefa 100644 --- a/src/ui/battle-flyout.ts +++ b/src/ui/battle-flyout.ts @@ -149,7 +149,7 @@ export default class BattleFlyout extends Phaser.GameObjects.Container { if (foundInfo) { foundInfo.ppUsed = moveUsedEvent.ppUsed; } else { - this.moveInfo.push({move: moveUsedEvent.move, maxPp: moveUsedEvent.move.pp, ppUsed: moveUsedEvent.ppUsed}); + this.moveInfo.push({ move: moveUsedEvent.move, maxPp: moveUsedEvent.move.pp, ppUsed: moveUsedEvent.ppUsed }); } this.setText(); diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index b3474bed5cd..1d97998f491 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -326,7 +326,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.teraIcon.setVisible(this.lastTeraType !== Type.UNKNOWN); this.teraIcon.on("pointerover", () => { if (this.lastTeraType !== Type.UNKNOWN) { - (this.scene as BattleScene).ui.showTooltip("", i18next.t("fightUiHandler:teraHover", {type: i18next.t(`pokemonInfo:Type.${Type[this.lastTeraType]}`) })); + (this.scene as BattleScene).ui.showTooltip("", i18next.t("fightUiHandler:teraHover", { type: i18next.t(`pokemonInfo:Type.${Type[this.lastTeraType]}`) })); } }); this.teraIcon.on("pointerout", () => (this.scene as BattleScene).ui.hideTooltip()); @@ -593,7 +593,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { }; const updatePokemonHp = () => { - let duration = !instant ? Utils.clampInt(Math.abs((this.lastHp) - pokemon.hp) * 5, 250, 5000) : 0; + let duration = !instant ? Phaser.Math.Clamp(Math.abs((this.lastHp) - pokemon.hp) * 5, 250, 5000) : 0; const speed = (this.scene as BattleScene).hpBarSpeed; if (speed) { duration = speed >= 3 ? 0 : duration / Math.pow(2, speed); diff --git a/src/ui/battle-message-ui-handler.ts b/src/ui/battle-message-ui-handler.ts index c27c6974192..832d665b290 100644 --- a/src/ui/battle-message-ui-handler.ts +++ b/src/ui/battle-message-ui-handler.ts @@ -4,7 +4,7 @@ import { Mode } from "./ui"; import MessageUiHandler from "./message-ui-handler"; import { addWindow } from "./ui-theme"; import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import i18next from "i18next"; import { Stat, PERMANENT_STATS, getStatKey } from "#app/enums/stat"; @@ -55,7 +55,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler { moveDetailsWindow.setName("move-details-window"); moveDetailsWindow.setOrigin(0, 1); - this.movesWindowContainer.add([movesWindow, moveDetailsWindow]); + this.movesWindowContainer.add([ movesWindow, moveDetailsWindow ]); ui.add(this.movesWindowContainer); const messageContainer = this.scene.add.container(12, -39); @@ -113,7 +113,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler { this.levelUpStatsIncrContent = levelUpStatsIncrContent; - const levelUpStatsValuesContent = addBBCodeTextObject(this.scene, (this.scene.game.canvas.width / 6) - 7, -94, "", TextStyle.WINDOW, { maxLines: 6, lineSpacing: 5}); + const levelUpStatsValuesContent = addBBCodeTextObject(this.scene, (this.scene.game.canvas.width / 6) - 7, -94, "", TextStyle.WINDOW, { maxLines: 6, lineSpacing: 5 }); levelUpStatsValuesContent.setLineSpacing(i18next.resolvedLanguage === "ja" ? 25 : 5); levelUpStatsValuesContent.setOrigin(1, 0); levelUpStatsValuesContent.setAlign("right"); diff --git a/src/ui/bgm-bar.ts b/src/ui/bgm-bar.ts index 936ab91d8fa..616b3ff87cf 100644 --- a/src/ui/bgm-bar.ts +++ b/src/ui/bgm-bar.ts @@ -1,5 +1,5 @@ import BattleScene from "../battle-scene"; -import {addTextObject, TextStyle} from "./text"; +import { addTextObject, TextStyle } from "./text"; import i18next from "i18next"; import * as Utils from "#app/utils"; @@ -88,6 +88,6 @@ export default class BgmBar extends Phaser.GameObjects.Container { } getRealBgmName(bgmName: string): string { - return i18next.t([`bgmName:${bgmName}`, "bgmName:missing_entries"], {name: Utils.formatText(bgmName)}); + return i18next.t([ `bgmName:${bgmName}`, "bgmName:missing_entries" ], { name: Utils.formatText(bgmName) }); } } diff --git a/src/ui/challenges-select-ui-handler.ts b/src/ui/challenges-select-ui-handler.ts index 924186de789..e2547a626de 100644 --- a/src/ui/challenges-select-ui-handler.ts +++ b/src/ui/challenges-select-ui-handler.ts @@ -3,7 +3,7 @@ import { TextStyle, addTextObject } from "./text"; import { Mode } from "./ui"; import UiHandler from "./ui-handler"; import { addWindow } from "./ui-theme"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import i18next from "i18next"; import { Challenge } from "#app/data/challenge"; import * as Utils from "../utils"; @@ -110,7 +110,7 @@ export default class GameChallengesUiHandler extends UiHandler { }); this.descriptionText.setName("text-desc"); this.scene.add.existing(this.descriptionText); - this.descriptionText.setScale(1/6); + this.descriptionText.setScale(1 / 6); this.descriptionText.setShadow(4, 5, ShadowColor.ORANGE); this.descriptionText.setOrigin(0, 0); @@ -376,66 +376,66 @@ export default class GameChallengesUiHandler extends UiHandler { } else { if (this.cursorObj?.visible && !this.startCursor.visible) { switch (button) { - case Button.UP: - if (this.cursor === 0) { - if (this.scrollCursor === 0) { + case Button.UP: + if (this.cursor === 0) { + if (this.scrollCursor === 0) { // When at the top of the menu and pressing UP, move to the bottommost item. - if (this.scene.gameMode.challenges.length > rowsToDisplay) { // If there are more than 9 challenges, scroll to the bottom + if (this.scene.gameMode.challenges.length > rowsToDisplay) { // If there are more than 9 challenges, scroll to the bottom // First, set the cursor to the last visible element, preparing for the scroll to the end. - const successA = this.setCursor(rowsToDisplay - 1); - // Then, adjust the scroll to display the bottommost elements of the menu. - const successB = this.setScrollCursor(this.scene.gameMode.challenges.length - rowsToDisplay); - success = successA && successB; // success is just there to play the little validation sound effect - } else { // If there are 9 or less challenges, just move to the bottom one - success = this.setCursor(this.scene.gameMode.challenges.length - 1); + const successA = this.setCursor(rowsToDisplay - 1); + // Then, adjust the scroll to display the bottommost elements of the menu. + const successB = this.setScrollCursor(this.scene.gameMode.challenges.length - rowsToDisplay); + success = successA && successB; // success is just there to play the little validation sound effect + } else { // If there are 9 or less challenges, just move to the bottom one + success = this.setCursor(this.scene.gameMode.challenges.length - 1); + } + } else { + success = this.setScrollCursor(this.scrollCursor - 1); } } else { - success = this.setScrollCursor(this.scrollCursor - 1); + success = this.setCursor(this.cursor - 1); } - } else { - success = this.setCursor(this.cursor - 1); - } - if (success) { - this.updateText(); - } - break; - case Button.DOWN: - if (this.cursor === rowsToDisplay - 1) { - if (this.scrollCursor < this.scene.gameMode.challenges.length - rowsToDisplay) { + if (success) { + this.updateText(); + } + break; + case Button.DOWN: + if (this.cursor === rowsToDisplay - 1) { + if (this.scrollCursor < this.scene.gameMode.challenges.length - rowsToDisplay) { // When at the bottom and pressing DOWN, scroll if possible. - success = this.setScrollCursor(this.scrollCursor + 1); - } else { + success = this.setScrollCursor(this.scrollCursor + 1); + } else { // When at the bottom of a scrolling menu and pressing DOWN, move to the topmost item. // First, set the cursor to the first visible element, preparing for the scroll to the top. - const successA = this.setCursor(0); - // Then, adjust the scroll to display the topmost elements of the menu. - const successB = this.setScrollCursor(0); - success = successA && successB; // success is just there to play the little validation sound effect - } - } else if (this.scene.gameMode.challenges.length < rowsToDisplay && this.cursor === this.scene.gameMode.challenges.length - 1) { + const successA = this.setCursor(0); + // Then, adjust the scroll to display the topmost elements of the menu. + const successB = this.setScrollCursor(0); + success = successA && successB; // success is just there to play the little validation sound effect + } + } else if (this.scene.gameMode.challenges.length < rowsToDisplay && this.cursor === this.scene.gameMode.challenges.length - 1) { // When at the bottom of a non-scrolling menu and pressing DOWN, move to the topmost item. - success = this.setCursor(0); - } else { - success = this.setCursor(this.cursor + 1); - } - if (success) { - this.updateText(); - } - break; - case Button.LEFT: + success = this.setCursor(0); + } else { + success = this.setCursor(this.cursor + 1); + } + if (success) { + this.updateText(); + } + break; + case Button.LEFT: // Moves the option cursor left, if possible. - success = this.getActiveChallenge().decreaseValue(); - if (success) { - this.updateText(); - } - break; - case Button.RIGHT: + success = this.getActiveChallenge().decreaseValue(); + if (success) { + this.updateText(); + } + break; + case Button.RIGHT: // Moves the option cursor right, if possible. - success = this.getActiveChallenge().increaseValue(); - if (success) { - this.updateText(); - } - break; + success = this.getActiveChallenge().increaseValue(); + if (success) { + this.updateText(); + } + break; } } } diff --git a/src/ui/command-ui-handler.ts b/src/ui/command-ui-handler.ts index 764e71a8c3f..0f5edc28675 100644 --- a/src/ui/command-ui-handler.ts +++ b/src/ui/command-ui-handler.ts @@ -4,7 +4,7 @@ import PartyUiHandler, { PartyUiMode } from "./party-ui-handler"; import { Mode } from "./ui"; import UiHandler from "./ui-handler"; import i18next from "i18next"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import { getPokemonNameWithAffix } from "#app/messages"; import { CommandPhase } from "#app/phases/command-phase"; @@ -67,7 +67,7 @@ export default class CommandUiHandler extends UiHandler { messageHandler.commandWindow.setVisible(true); messageHandler.movesWindowContainer.setVisible(false); messageHandler.message.setWordWrapWidth(1110); - messageHandler.showText(i18next.t("commandUiHandler:actionMessage", {pokemonName: getPokemonNameWithAffix(commandPhase.getPokemon())}), 0); + messageHandler.showText(i18next.t("commandUiHandler:actionMessage", { pokemonName: getPokemonNameWithAffix(commandPhase.getPokemon()) }), 0); if (this.getCursor() === Command.POKEMON) { this.setCursor(Command.FIGHT); } else { @@ -89,54 +89,54 @@ export default class CommandUiHandler extends UiHandler { if (button === Button.ACTION) { switch (cursor) { // Fight - case Command.FIGHT: - if ((this.scene.getCurrentPhase() as CommandPhase).checkFightOverride()) { - return true; - } - ui.setMode(Mode.FIGHT, (this.scene.getCurrentPhase() as CommandPhase).getFieldIndex()); - success = true; - break; + case Command.FIGHT: + if ((this.scene.getCurrentPhase() as CommandPhase).checkFightOverride()) { + return true; + } + ui.setMode(Mode.FIGHT, (this.scene.getCurrentPhase() as CommandPhase).getFieldIndex()); + success = true; + break; // Ball - case Command.BALL: - ui.setModeWithoutClear(Mode.BALL); - success = true; - break; + case Command.BALL: + ui.setModeWithoutClear(Mode.BALL); + success = true; + break; // Pokemon - case Command.POKEMON: - ui.setMode(Mode.PARTY, PartyUiMode.SWITCH, (this.scene.getCurrentPhase() as CommandPhase).getPokemon().getFieldIndex(), null, PartyUiHandler.FilterNonFainted); - success = true; - break; + case Command.POKEMON: + ui.setMode(Mode.PARTY, PartyUiMode.SWITCH, (this.scene.getCurrentPhase() as CommandPhase).getPokemon().getFieldIndex(), null, PartyUiHandler.FilterNonFainted); + success = true; + break; // Run - case Command.RUN: - (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.RUN, 0); - success = true; - break; + case Command.RUN: + (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.RUN, 0); + success = true; + break; } } else { (this.scene.getCurrentPhase() as CommandPhase).cancel(); } } else { switch (button) { - case Button.UP: - if (cursor >= 2) { - success = this.setCursor(cursor - 2); - } - break; - case Button.DOWN: - if (cursor < 2) { - success = this.setCursor(cursor + 2); - } - break; - case Button.LEFT: - if (cursor % 2 === 1) { - success = this.setCursor(cursor - 1); - } - break; - case Button.RIGHT: - if (cursor % 2 === 0) { - success = this.setCursor(cursor + 1); - } - break; + case Button.UP: + if (cursor >= 2) { + success = this.setCursor(cursor - 2); + } + break; + case Button.DOWN: + if (cursor < 2) { + success = this.setCursor(cursor + 2); + } + break; + case Button.LEFT: + if (cursor % 2 === 1) { + success = this.setCursor(cursor - 1); + } + break; + case Button.RIGHT: + if (cursor % 2 === 0) { + success = this.setCursor(cursor + 1); + } + break; } } diff --git a/src/ui/confirm-ui-handler.ts b/src/ui/confirm-ui-handler.ts index 4a60b0c9689..2022508fc0d 100644 --- a/src/ui/confirm-ui-handler.ts +++ b/src/ui/confirm-ui-handler.ts @@ -2,7 +2,7 @@ import BattleScene from "../battle-scene"; import AbstractOptionSelectUiHandler, { OptionSelectConfig } from "./abstact-option-select-ui-handler"; import { Mode } from "./ui"; import i18next from "i18next"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler { @@ -76,7 +76,8 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler { } } ], - delay: args.length >= 6 && args[5] !== null ? args[5] as integer : 0 + delay: args.length >= 6 && args[5] !== null ? args[5] as number : 0, + noCancel: args.length >= 7 && args[6] !== null ? args[6] as boolean : false, }; super.show([ config ]); @@ -96,7 +97,7 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler { } processInput(button: Button): boolean { - if (button === Button.CANCEL && this.blockInput) { + if (button === Button.CANCEL && this.blockInput && !this.config?.noCancel) { this.unblockInput(); } diff --git a/src/ui/daily-run-scoreboard.ts b/src/ui/daily-run-scoreboard.ts index b535a94d35c..b9c1c6ea49a 100644 --- a/src/ui/daily-run-scoreboard.ts +++ b/src/ui/daily-run-scoreboard.ts @@ -142,13 +142,13 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container { entryContainer.add(scoreLabel); switch (this.category) { - case ScoreboardCategory.DAILY: - const waveLabel = addTextObject(this.scene, 68, 0, wave, TextStyle.WINDOW, { fontSize: "54px" }); - entryContainer.add(waveLabel); - break; - case ScoreboardCategory.WEEKLY: - scoreLabel.x -= 16; - break; + case ScoreboardCategory.DAILY: + const waveLabel = addTextObject(this.scene, 68, 0, wave, TextStyle.WINDOW, { fontSize: "54px" }); + entryContainer.add(waveLabel); + break; + case ScoreboardCategory.WEEKLY: + scoreLabel.x -= 16; + break; } return entryContainer; diff --git a/src/ui/dropdown.ts b/src/ui/dropdown.ts index 4e1235c211d..e16efe17036 100644 --- a/src/ui/dropdown.ts +++ b/src/ui/dropdown.ts @@ -64,7 +64,7 @@ export class DropDownOption extends Phaser.GameObjects.Container { if (Array.isArray(labels)) { this.labels = labels; } else { - this.labels = labels? [ labels ] : [ new DropDownLabel("") ]; + this.labels = labels ? [ labels ] : [ new DropDownLabel("") ]; } this.currentLabelIndex = 0; const currentLabel = this.labels[this.currentLabelIndex]; @@ -75,12 +75,12 @@ export class DropDownOption extends Phaser.GameObjects.Container { this.add(this.text); // Add to container the sprite for each label if there is one - for (let i=0; i < this.labels.length; i++) { + for (let i = 0; i < this.labels.length; i++) { const sprite = this.labels[i].sprite; if (sprite) { this.add(sprite); sprite.setOrigin(0, 0.5); - if (i!== this.currentLabelIndex) { + if (i !== this.currentLabelIndex) { sprite.setVisible(false); } } @@ -115,18 +115,18 @@ export class DropDownOption extends Phaser.GameObjects.Container { */ private updateToggleIconColor(): void { switch (this.state) { - case DropDownState.ON: - this.toggle.setTint(this.onColor); - break; - case DropDownState.OFF: - this.toggle.setTint(this.offColor); - break; - case DropDownState.EXCLUDE: - this.toggle.setTint(this.excludeColor); - break; - case DropDownState.UNLOCKABLE: - this.toggle.setTint(this.unlockableColor); - break; + case DropDownState.ON: + this.toggle.setTint(this.onColor); + break; + case DropDownState.OFF: + this.toggle.setTint(this.offColor); + break; + case DropDownState.EXCLUDE: + this.toggle.setTint(this.excludeColor); + break; + case DropDownState.UNLOCKABLE: + this.toggle.setTint(this.unlockableColor); + break; } } @@ -215,7 +215,7 @@ export class DropDownOption extends Phaser.GameObjects.Container { */ setLabelPosition(x: number, y: number) { let textX = x; - for (let i=0; i < this.labels.length; i++) { + for (let i = 0; i < this.labels.length; i++) { const label = this.labels[i]; if (label.sprite) { label.sprite.x = x; @@ -261,7 +261,7 @@ export class DropDownOption extends Phaser.GameObjects.Container { const currentText = this.text.text; for (const label of this.labels) { this.text.setText(label.text); - const spriteWidth = label.sprite? label.sprite.displayWidth + 2 : 0; + const spriteWidth = label.sprite ? label.sprite.displayWidth + 2 : 0; w = Math.max(w, this.text.displayWidth + spriteWidth); } this.text.setText(currentText); @@ -334,7 +334,7 @@ export class DropDown extends Phaser.GameObjects.Container { } getWidth(): number { - return this.window? this.window.width : this.width; + return this.window ? this.window.width : this.width; } toggleVisibility(): void { @@ -460,7 +460,7 @@ export class DropDown extends Phaser.GameObjects.Container { return this.options.filter((_, i) => i > 0).map(option => option.val); } // if nothing is selected and a single option is hovered, return that one - return [this.options[this.cursor].val]; + return [ this.options[this.cursor].val ]; } else if (this.dropDownType === DropDownType.RADIAL) { return this.options.map((option) => { return { val: option.val, state: option.state }; @@ -500,18 +500,18 @@ export class DropDown extends Phaser.GameObjects.Container { }; switch (this.dropDownType) { - case DropDownType.MULTI: - case DropDownType.RADIAL: - return compareValues(["val", "state"]); + case DropDownType.MULTI: + case DropDownType.RADIAL: + return compareValues([ "val", "state" ]); - case DropDownType.HYBRID: - return compareValues(["val", "state", "cursor"]); + case DropDownType.HYBRID: + return compareValues([ "val", "state", "cursor" ]); - case DropDownType.SINGLE: - return compareValues(["val", "state", "dir"]); + case DropDownType.SINGLE: + return compareValues([ "val", "state", "dir" ]); - default: - return false; + default: + return false; } } diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index e8753122b6d..8f977ba2ac0 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -34,6 +34,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { private cursorObj: Phaser.GameObjects.Image; private transitioning: boolean; private transitionCancelled: boolean; + private summaryFinished: boolean; private defaultText: string; private scale: number = 0.1666666667; @@ -106,7 +107,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { let pokemonIconX = -20; let pokemonIconY = 6; - if (["de", "es", "fr", "ko", "pt-BR"].includes(currentLanguage)) { + if ([ "de", "es", "fr", "ko", "pt-BR" ].includes(currentLanguage)) { gachaTextStyle = TextStyle.SMALLER_WINDOW_ALT; gachaX = 2; gachaY = 2; @@ -114,7 +115,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { let legendaryLabelX = gachaX; let legendaryLabelY = gachaY; - if (["de", "es"].includes(currentLanguage)) { + if ([ "de", "es" ].includes(currentLanguage)) { pokemonIconX = -25; pokemonIconY = 10; legendaryLabelX = -6; @@ -126,47 +127,47 @@ export default class EggGachaUiHandler extends MessageUiHandler { gachaInfoContainer.add(gachaUpLabel); switch (gachaType as GachaType) { - case GachaType.LEGENDARY: - if (["de", "es"].includes(currentLanguage)) { - gachaUpLabel.setAlign("center"); - gachaUpLabel.setY(0); - } - if (["pt-BR"].includes(currentLanguage)) { - gachaUpLabel.setX(legendaryLabelX - 2); - } else { - gachaUpLabel.setX(legendaryLabelX); - } - gachaUpLabel.setY(legendaryLabelY); + case GachaType.LEGENDARY: + if ([ "de", "es" ].includes(currentLanguage)) { + gachaUpLabel.setAlign("center"); + gachaUpLabel.setY(0); + } + if ([ "pt-BR" ].includes(currentLanguage)) { + gachaUpLabel.setX(legendaryLabelX - 2); + } else { + gachaUpLabel.setX(legendaryLabelX); + } + gachaUpLabel.setY(legendaryLabelY); - const pokemonIcon = this.scene.add.sprite(pokemonIconX, pokemonIconY, "pokemon_icons_0"); - if (["pt-BR"].includes(currentLanguage)) { - pokemonIcon.setX(pokemonIconX - 2); - } - pokemonIcon.setScale(0.5); - pokemonIcon.setOrigin(0, 0.5); + const pokemonIcon = this.scene.add.sprite(pokemonIconX, pokemonIconY, "pokemon_icons_0"); + if ([ "pt-BR" ].includes(currentLanguage)) { + pokemonIcon.setX(pokemonIconX - 2); + } + pokemonIcon.setScale(0.5); + pokemonIcon.setOrigin(0, 0.5); - gachaInfoContainer.add(pokemonIcon); - break; - case GachaType.MOVE: - if (["de", "es", "fr", "pt-BR"].includes(currentLanguage)) { - gachaUpLabel.setAlign("center"); - gachaUpLabel.setY(0); - } + gachaInfoContainer.add(pokemonIcon); + break; + case GachaType.MOVE: + if ([ "de", "es", "fr", "pt-BR" ].includes(currentLanguage)) { + gachaUpLabel.setAlign("center"); + gachaUpLabel.setY(0); + } - gachaUpLabel.setText(i18next.t("egg:moveUPGacha")); - gachaUpLabel.setX(0); - gachaUpLabel.setOrigin(0.5, 0); - break; - case GachaType.SHINY: - if (["de", "fr", "ko"].includes(currentLanguage)) { - gachaUpLabel.setAlign("center"); - gachaUpLabel.setY(0); - } + gachaUpLabel.setText(i18next.t("egg:moveUPGacha")); + gachaUpLabel.setX(0); + gachaUpLabel.setOrigin(0.5, 0); + break; + case GachaType.SHINY: + if ([ "de", "fr", "ko" ].includes(currentLanguage)) { + gachaUpLabel.setAlign("center"); + gachaUpLabel.setY(0); + } - gachaUpLabel.setText(i18next.t("egg:shinyUPGacha")); - gachaUpLabel.setX(0); - gachaUpLabel.setOrigin(0.5, 0); - break; + gachaUpLabel.setText(i18next.t("egg:shinyUPGacha")); + gachaUpLabel.setX(0); + gachaUpLabel.setOrigin(0.5, 0); + break; } const gachaKnob = this.scene.add.sprite(191, 89, "gacha_knob"); @@ -221,7 +222,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { const pullOptionsText = pullOptions.map(option =>{ const desc = option.description.split(" "); if (desc[0].length < 2) { - desc[0] += ["zh", "ko"].includes(resolvedLanguage.substring(0, 2)) ? " " : " "; + desc[0] += [ "zh", "ko" ].includes(resolvedLanguage.substring(0, 2)) ? " " : " "; } if (option.multiplier === multiplierOne) { desc[0] = " " + desc[0]; @@ -469,17 +470,22 @@ export default class EggGachaUiHandler extends MessageUiHandler { getGuaranteedEggTierFromPullCount(pullCount: number): EggTier { switch (pullCount) { - case 10: - return EggTier.GREAT; - case 25: - return EggTier.ULTRA; - default: - return EggTier.COMMON; + case 10: + return EggTier.RARE; + case 25: + return EggTier.EPIC; + default: + return EggTier.COMMON; } } showSummary(eggs: Egg[]): void { - this.transitioning = false; + // the overlay will appear faster if the egg pulling animation was skipped + const overlayEaseInDuration = this.getDelayValue(750); + + this.summaryFinished = false; + this.transitionCancelled = false; + this.setTransitioning(true); this.eggGachaSummaryContainer.setVisible(true); const eggScale = eggs.length < 20 ? 1 : 0.5; @@ -488,12 +494,14 @@ export default class EggGachaUiHandler extends MessageUiHandler { targets: this.eggGachaOverlay, alpha: 0.5, ease: "Sine.easeOut", - duration: 750, + duration: overlayEaseInDuration, onComplete: () => { const rowItems = 5; const rows = Math.ceil(eggs.length / rowItems); const cols = Math.min(eggs.length, rowItems); const height = this.eggGachaOverlay.displayHeight - this.eggGachaMessageBox.displayHeight; + + // Create sprites for each egg const eggContainers = eggs.map((egg, t) => { const col = t % rowItems; const row = Math.floor(t / rowItems); @@ -508,21 +516,31 @@ export default class EggGachaUiHandler extends MessageUiHandler { const eggText = addTextObject(this.scene, 0, 14, egg.getEggDescriptor(), TextStyle.PARTY, { align: "center" }); eggText.setOrigin(0.5, 0); - eggText.setTint(getEggTierTextTint(!egg.isManaphyEgg() ? egg.tier : EggTier.ULTRA)); + eggText.setTint(getEggTierTextTint(!egg.isManaphyEgg() ? egg.tier : EggTier.EPIC)); ret.add(eggText); this.eggGachaSummaryContainer.addAt(ret, 0); return ret; }); - eggContainers.forEach((eggContainer, e) => { - this.scene.tweens.add({ - targets: eggContainer, - delay: this.getDelayValue(e * 100), - duration: this.getDelayValue(350), - scale: eggScale, - ease: "Sine.easeOut" - }); + // If action/cancel was pressed when the overlay was easing in, show all eggs at once + // Otherwise show the eggs one by one with a small delay between each + eggContainers.forEach((eggContainer, index) => { + const delay = !this.transitionCancelled ? this.getDelayValue(index * 100) : 0; + this.scene.time.delayedCall(delay, () => + this.scene.tweens.add({ + targets: eggContainer, + duration: this.getDelayValue(350), + scale: eggScale, + ease: "Sine.easeOut", + onComplete: () => { + if (index === eggs.length - 1) { + this.setTransitioning(false); + this.summaryFinished = true; + } + } + })); + }); } }); @@ -540,6 +558,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { this.eggGachaSummaryContainer.setAlpha(1); this.eggGachaSummaryContainer.removeAll(true); this.setTransitioning(false); + this.summaryFinished = false; this.eggGachaOptionsContainer.setVisible(true); } }); @@ -548,11 +567,11 @@ export default class EggGachaUiHandler extends MessageUiHandler { updateGachaInfo(gachaType: GachaType): void { const infoContainer = this.gachaInfoContainers[gachaType]; switch (gachaType as GachaType) { - case GachaType.LEGENDARY: - const species = getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(this.scene, new Date().getTime())); - const pokemonIcon = infoContainer.getAt(1) as Phaser.GameObjects.Sprite; - pokemonIcon.setTexture(species.getIconAtlasKey(), species.getIconId(false)); - break; + case GachaType.LEGENDARY: + const species = getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(this.scene, new Date().getTime())); + const pokemonIcon = infoContainer.getAt(1) as Phaser.GameObjects.Sprite; + pokemonIcon.setTexture(species.getIconAtlasKey(), species.getIconId(false)); + break; } } @@ -613,112 +632,112 @@ export default class EggGachaUiHandler extends MessageUiHandler { } else { if (this.eggGachaSummaryContainer.visible) { - if (button === Button.ACTION || button === Button.CANCEL) { + if (this.summaryFinished && (button === Button.ACTION || button === Button.CANCEL)) { this.hideSummary(); success = true; } } else { switch (button) { - case Button.ACTION: - switch (this.cursor) { - case 0: - if (!this.scene.gameData.voucherCounts[VoucherType.REGULAR] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { - error = true; - this.showError(i18next.t("egg:notEnoughVouchers")); - } else if (this.scene.gameData.eggs.length < 99) { - if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { - this.consumeVouchers(VoucherType.REGULAR, 1); - } - this.pull(); - success = true; - } else { - error = true; - this.showError(i18next.t("egg:tooManyEggs")); - } - break; - case 2: - if (!this.scene.gameData.voucherCounts[VoucherType.PLUS] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { - error = true; - this.showError(i18next.t("egg:notEnoughVouchers")); - } else if (this.scene.gameData.eggs.length < 95) { - if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { - this.consumeVouchers(VoucherType.PLUS, 1); - } - this.pull(5); - success = true; - } else { - error = true; - this.showError(i18next.t("egg:tooManyEggs")); - } - break; - case 1: - case 3: - if ((this.cursor === 1 && this.scene.gameData.voucherCounts[VoucherType.REGULAR] < 10 && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) + case Button.ACTION: + switch (this.cursor) { + case 0: + if (!this.scene.gameData.voucherCounts[VoucherType.REGULAR] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { + error = true; + this.showError(i18next.t("egg:notEnoughVouchers")); + } else if (this.scene.gameData.eggs.length < 99 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) { + if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { + this.consumeVouchers(VoucherType.REGULAR, 1); + } + this.pull(); + success = true; + } else { + error = true; + this.showError(i18next.t("egg:tooManyEggs")); + } + break; + case 2: + if (!this.scene.gameData.voucherCounts[VoucherType.PLUS] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { + error = true; + this.showError(i18next.t("egg:notEnoughVouchers")); + } else if (this.scene.gameData.eggs.length < 95 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) { + if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { + this.consumeVouchers(VoucherType.PLUS, 1); + } + this.pull(5); + success = true; + } else { + error = true; + this.showError(i18next.t("egg:tooManyEggs")); + } + break; + case 1: + case 3: + if ((this.cursor === 1 && this.scene.gameData.voucherCounts[VoucherType.REGULAR] < 10 && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) || (this.cursor === 3 && !this.scene.gameData.voucherCounts[VoucherType.PREMIUM] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE)) { - error = true; - this.showError(i18next.t("egg:notEnoughVouchers")); - } else if (this.scene.gameData.eggs.length < 90) { - if (this.cursor === 3) { - if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { - this.consumeVouchers(VoucherType.PREMIUM, 1); + error = true; + this.showError(i18next.t("egg:notEnoughVouchers")); + } else if (this.scene.gameData.eggs.length < 90 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) { + if (this.cursor === 3) { + if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { + this.consumeVouchers(VoucherType.PREMIUM, 1); + } + } else { + if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { + this.consumeVouchers(VoucherType.REGULAR, 10); + } + } + this.pull(10); + success = true; + } else { + error = true; + this.showError(i18next.t("egg:tooManyEggs")); } - } else { - if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { - this.consumeVouchers(VoucherType.REGULAR, 10); + break; + case 4: + if (!this.scene.gameData.voucherCounts[VoucherType.GOLDEN] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { + error = true; + this.showError(i18next.t("egg:notEnoughVouchers")); + } else if (this.scene.gameData.eggs.length < 75 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) { + if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { + this.consumeVouchers(VoucherType.GOLDEN, 1); + } + this.pull(25); + success = true; + } else { + error = true; + this.showError(i18next.t("egg:tooManyEggs")); } - } - this.pull(10); - success = true; - } else { - error = true; - this.showError(i18next.t("egg:tooManyEggs")); + break; + case 5: + ui.revertMode(); + success = true; + break; } break; - case 4: - if (!this.scene.gameData.voucherCounts[VoucherType.GOLDEN] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { - error = true; - this.showError(i18next.t("egg:notEnoughVouchers")); - } else if (this.scene.gameData.eggs.length < 75) { - if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { - this.consumeVouchers(VoucherType.GOLDEN, 1); - } - this.pull(25); - success = true; - } else { - error = true; - this.showError(i18next.t("egg:tooManyEggs")); - } - break; - case 5: - ui.revertMode(); + case Button.CANCEL: + this.getUi().revertMode(); success = true; break; - } - break; - case Button.CANCEL: - this.getUi().revertMode(); - success = true; - break; - case Button.UP: - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } - break; - case Button.DOWN: - if (this.cursor < 5) { - success = this.setCursor(this.cursor + 1); - } - break; - case Button.LEFT: - if (this.gachaCursor) { - success = this.setGachaCursor(this.gachaCursor - 1); - } - break; - case Button.RIGHT: - if (this.gachaCursor < Utils.getEnumKeys(GachaType).length - 1) { - success = this.setGachaCursor(this.gachaCursor + 1); - } - break; + case Button.UP: + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } + break; + case Button.DOWN: + if (this.cursor < 5) { + success = this.setCursor(this.cursor + 1); + } + break; + case Button.LEFT: + if (this.gachaCursor) { + success = this.setGachaCursor(this.gachaCursor - 1); + } + break; + case Button.RIGHT: + if (this.gachaCursor < Utils.getEnumKeys(GachaType).length - 1) { + success = this.setGachaCursor(this.gachaCursor + 1); + } + break; } } } diff --git a/src/ui/egg-hatch-scene-handler.ts b/src/ui/egg-hatch-scene-handler.ts index 7b01ef7a3a6..1bf58a786e1 100644 --- a/src/ui/egg-hatch-scene-handler.ts +++ b/src/ui/egg-hatch-scene-handler.ts @@ -1,7 +1,7 @@ import BattleScene from "../battle-scene"; import { Mode } from "./ui"; import UiHandler from "./ui-handler"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import { EggHatchPhase } from "#app/phases/egg-hatch-phase"; export default class EggHatchSceneHandler extends UiHandler { diff --git a/src/ui/egg-list-ui-handler.ts b/src/ui/egg-list-ui-handler.ts index 0ebc0f8140e..939f95fabe6 100644 --- a/src/ui/egg-list-ui-handler.ts +++ b/src/ui/egg-list-ui-handler.ts @@ -4,7 +4,7 @@ import PokemonIconAnimHandler, { PokemonIconAnimMode } from "#app/ui/pokemon-ico import { TextStyle, addTextObject } from "#app/ui/text"; import MessageUiHandler from "#app/ui/message-ui-handler"; import { addWindow } from "#app/ui/ui-theme"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import i18next from "i18next"; import ScrollableGridUiHandler from "#app/ui/scrollable-grid-handler"; import { ScrollBar } from "#app/ui/scroll-bar"; diff --git a/src/ui/egg-summary-ui-handler.ts b/src/ui/egg-summary-ui-handler.ts index 519722b1505..da93168926e 100644 --- a/src/ui/egg-summary-ui-handler.ts +++ b/src/ui/egg-summary-ui-handler.ts @@ -42,6 +42,9 @@ export default class EggSummaryUiHandler extends MessageUiHandler { private scrollGridHandler : ScrollableGridUiHandler; private cursorObj: Phaser.GameObjects.Image; + /** used to add a delay before which it is not possible to exit the summary */ + private blockExit: boolean; + /** * Allows subscribers to listen for events * @@ -168,6 +171,13 @@ export default class EggSummaryUiHandler extends MessageUiHandler { this.setCursor(0); this.scene.playSoundWithoutBgm("evolution_fanfare"); + + // Prevent exiting the egg summary for 2 seconds if the egg hatching + // was skipped automatically and for 1 second otherwise + const exitBlockingDuration = (this.scene.eggSkipPreference === 2) ? 2000 : 1000; + this.blockExit = true; + this.scene.time.delayedCall(exitBlockingDuration, () => this.blockExit = false); + return true; } @@ -203,13 +213,17 @@ export default class EggSummaryUiHandler extends MessageUiHandler { const ui = this.getUi(); let success = false; - const error = false; + let error = false; if (button === Button.CANCEL) { - const phase = this.scene.getCurrentPhase(); - if (phase instanceof EggSummaryPhase) { - phase.end(); + if (!this.blockExit) { + const phase = this.scene.getCurrentPhase(); + if (phase instanceof EggSummaryPhase) { + phase.end(); + } + success = true; + } else { + error = true; } - success = true; } else { this.scrollGridHandler.processInput(button); } diff --git a/src/ui/evolution-scene-handler.ts b/src/ui/evolution-scene-handler.ts index 76d148d083e..a116a33f373 100644 --- a/src/ui/evolution-scene-handler.ts +++ b/src/ui/evolution-scene-handler.ts @@ -2,7 +2,7 @@ import BattleScene from "../battle-scene"; import MessageUiHandler from "./message-ui-handler"; import { TextStyle, addTextObject } from "./text"; import { Mode } from "./ui"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; export default class EvolutionSceneHandler extends MessageUiHandler { public evolutionContainer: Phaser.GameObjects.Container; diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 59d14ab3bc4..ee6641a1a27 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -7,7 +7,7 @@ import UiHandler from "./ui-handler"; import * as Utils from "../utils"; import { MoveCategory } from "#app/data/move"; import i18next from "i18next"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import Pokemon, { PokemonMove } from "#app/field/pokemon"; import { CommandPhase } from "#app/phases/command-phase"; import MoveInfoOverlay from "./move-info-overlay"; @@ -152,26 +152,26 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { } } else { switch (button) { - case Button.UP: - if (cursor >= 2) { - success = this.setCursor(cursor - 2); - } - break; - case Button.DOWN: - if (cursor < 2) { - success = this.setCursor(cursor + 2); - } - break; - case Button.LEFT: - if (cursor % 2 === 1) { - success = this.setCursor(cursor - 1); - } - break; - case Button.RIGHT: - if (cursor % 2 === 0) { - success = this.setCursor(cursor + 1); - } - break; + case Button.UP: + if (cursor >= 2) { + success = this.setCursor(cursor - 2); + } + break; + case Button.DOWN: + if (cursor < 2) { + success = this.setCursor(cursor + 2); + } + break; + case Button.LEFT: + if (cursor % 2 === 1) { + success = this.setCursor(cursor - 1); + } + break; + case Button.RIGHT: + if (cursor % 2 === 0) { + success = this.setCursor(cursor + 1); + } + break; } } @@ -188,7 +188,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { this.cursorObj?.setVisible(false); } this.scene.tweens.add({ - targets: [this.movesContainer, this.cursorObj], + targets: [ this.movesContainer, this.cursorObj ], duration: Utils.fixedInt(125), ease: "Sine.easeInOut", alpha: visible ? 0 : 1 diff --git a/src/ui/filter-bar.ts b/src/ui/filter-bar.ts index aa0f575d398..bcf7409fce0 100644 --- a/src/ui/filter-bar.ts +++ b/src/ui/filter-bar.ts @@ -104,11 +104,11 @@ export class FilterBar extends Phaser.GameObjects.Container { totalWidth += label.displayWidth + cursorOffset; }); const spacing = (this.width - totalWidth) / (this.labels.length - 1); - for (let i=0; i { - const label = addTextObject(this.scene, 10, (hasTitle ? 31 : 5) + 20 * f, field, TextStyle.TOOLTIP_CONTENT); + if (config.length >= 1) { + this.updateFields(config, hasTitle); + } - this.modalContainer.add(label); + this.errorMessage = addTextObject(this.scene, 10, (hasTitle ? 31 : 5) + 20 * (config.length - 1) + 16 + this.getButtonTopMargin(), "", TextStyle.TOOLTIP_CONTENT); + this.errorMessage.setColor(this.getTextColor(TextStyle.SUMMARY_PINK)); + this.errorMessage.setShadowColor(this.getTextColor(TextStyle.SUMMARY_PINK, true)); + this.errorMessage.setVisible(false); + this.modalContainer.add(this.errorMessage); + } + + protected updateFields(fieldsConfig: InputFieldConfig[], hasTitle: boolean) { + this.inputContainers = []; + this.inputs = []; + this.formLabels = []; + fieldsConfig.forEach((config, f) => { + const label = addTextObject(this.scene, 10, (hasTitle ? 31 : 5) + 20 * f, config.label, TextStyle.TOOLTIP_CONTENT); + label.name = "formLabel" + f; + + this.formLabels.push(label); + this.modalContainer.add(this.formLabels[this.formLabels.length - 1]); const inputContainer = this.scene.add.container(70, (hasTitle ? 28 : 2) + 20 * f); inputContainer.setVisible(false); const inputBg = addWindow(this.scene, 0, 0, 80, 16, false, false, 0, 0, WindowVariant.XTHIN); - const isPassword = field.includes(i18next.t("menu:password")) || field.includes(i18next.t("menu:confirmPassword")); - const input = addTextInputObject(this.scene, 4, -2, 440, 116, TextStyle.TOOLTIP_CONTENT, { type: isPassword ? "password" : "text", maxLength: isPassword ? 64 : 20 }); + const isPassword = config?.isPassword; + const isReadOnly = config?.isReadOnly; + const input = addTextInputObject(this.scene, 4, -2, 440, 116, TextStyle.TOOLTIP_CONTENT, { type: isPassword ? "password" : "text", maxLength: isPassword ? 64 : 20, readOnly: isReadOnly }); input.setOrigin(0, 0); inputContainer.add(inputBg); inputContainer.add(input); - this.modalContainer.add(inputContainer); this.inputContainers.push(inputContainer); + this.modalContainer.add(inputContainer); + this.inputs.push(input); }); - - this.errorMessage = addTextObject(this.scene, 10, (hasTitle ? 31 : 5) + 20 * (fields.length - 1) + 16 + this.getButtonTopMargin(), "", TextStyle.TOOLTIP_CONTENT); - this.errorMessage.setColor(this.getTextColor(TextStyle.SUMMARY_PINK)); - this.errorMessage.setShadowColor(this.getTextColor(TextStyle.SUMMARY_PINK, true)); - this.errorMessage.setVisible(false); - this.modalContainer.add(this.errorMessage); } show(args: any[]): boolean { @@ -149,3 +168,9 @@ export abstract class FormModalUiHandler extends ModalUiHandler { } } } + +export interface InputFieldConfig { + label: string, + isPassword?: boolean, + isReadOnly?: boolean +} diff --git a/src/ui/game-stats-ui-handler.ts b/src/ui/game-stats-ui-handler.ts index 69abdf85e9e..671bed29036 100644 --- a/src/ui/game-stats-ui-handler.ts +++ b/src/ui/game-stats-ui-handler.ts @@ -247,7 +247,7 @@ export default class GameStatsUiHandler extends UiHandler { const [ statsBgLeft, statsBgRight ] = new Array(2).fill(null).map((_, i) => { const width = statsBgWidth + 2; const height = Math.floor((this.scene.game.canvas.height / 6) - headerBg.height - 2); - const statsBg = addWindow(this.scene, (statsBgWidth - 2) * i, headerBg.height, width, height, false, false, i>0?-3:0, 1); + const statsBg = addWindow(this.scene, (statsBgWidth - 2) * i, headerBg.height, width, height, false, false, i > 0 ? -3 : 0, 1); statsBg.setOrigin(0, 0); return statsBg; }); @@ -276,9 +276,9 @@ export default class GameStatsUiHandler extends UiHandler { // arrows to show that we can scroll through the stats const isLegacyTheme = this.scene.uiTheme === UiTheme.LEGACY; - this.arrowDown = this.scene.add.sprite(statsBgWidth, this.scene.game.canvas.height / 6 - (isLegacyTheme? 9 : 5), "prompt"); + this.arrowDown = this.scene.add.sprite(statsBgWidth, this.scene.game.canvas.height / 6 - (isLegacyTheme ? 9 : 5), "prompt"); this.gameStatsContainer.add(this.arrowDown); - this.arrowUp = this.scene.add.sprite(statsBgWidth, headerBg.height + (isLegacyTheme? 7 : 3), "prompt"); + this.arrowUp = this.scene.add.sprite(statsBgWidth, headerBg.height + (isLegacyTheme ? 7 : 3), "prompt"); this.arrowUp.flipY = true; this.gameStatsContainer.add(this.arrowUp); @@ -351,16 +351,16 @@ export default class GameStatsUiHandler extends UiHandler { this.scene.ui.revertMode(); } else { switch (button) { - case Button.UP: - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } - break; - case Button.DOWN: - if (this.cursor < Math.ceil((Object.keys(displayStats).length - 18) / 2)) { - success = this.setCursor(this.cursor + 1); - } - break; + case Button.UP: + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } + break; + case Button.DOWN: + if (this.cursor < Math.ceil((Object.keys(displayStats).length - 18) / 2)) { + success = this.setCursor(this.cursor + 1); + } + break; } } diff --git a/src/ui/login-form-ui-handler.ts b/src/ui/login-form-ui-handler.ts index 631b2e50b02..26a2a225ec6 100644 --- a/src/ui/login-form-ui-handler.ts +++ b/src/ui/login-form-ui-handler.ts @@ -1,4 +1,4 @@ -import { FormModalUiHandler } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler"; import * as Utils from "../utils"; import { Mode } from "./ui"; @@ -17,9 +17,9 @@ interface BuildInteractableImageOpts { export default class LoginFormUiHandler extends FormModalUiHandler { private readonly ERR_USERNAME: string = "invalid username"; - private readonly ERR_PASSWORD: string = "invalid password"; - private readonly ERR_ACCOUNT_EXIST: string = "account doesn't exist"; - private readonly ERR_PASSWORD_MATCH: string = "password doesn't match"; + private readonly ERR_PASSWORD: string = "invalid password"; + private readonly ERR_ACCOUNT_EXIST: string = "account doesn't exist"; + private readonly ERR_PASSWORD_MATCH: string = "password doesn't match"; private readonly ERR_NO_SAVES: string = "No save files found"; private readonly ERR_TOO_MANY_SAVES: string = "Too many save files found"; @@ -75,10 +75,6 @@ export default class LoginFormUiHandler extends FormModalUiHandler { return i18next.t("menu:login"); } - override getFields(_config?: ModalConfig): string[] { - return [ i18next.t("menu:username"), i18next.t("menu:password") ]; - } - override getWidth(_config?: ModalConfig): number { return 160; } @@ -88,7 +84,7 @@ export default class LoginFormUiHandler extends FormModalUiHandler { } override getButtonLabels(_config?: ModalConfig): string[] { - return [ i18next.t("menu:login"), i18next.t("menu:register")]; + return [ i18next.t("menu:login"), i18next.t("menu:register") ]; } override getReadableErrorMessage(error: string): string { @@ -97,23 +93,30 @@ export default class LoginFormUiHandler extends FormModalUiHandler { error = error.slice(0, colonIndex); } switch (error) { - case this.ERR_USERNAME: - return i18next.t("menu:invalidLoginUsername"); - case this.ERR_PASSWORD: - return i18next.t("menu:invalidLoginPassword"); - case this.ERR_ACCOUNT_EXIST: - return i18next.t("menu:accountNonExistent"); - case this.ERR_PASSWORD_MATCH: - return i18next.t("menu:unmatchingPassword"); - case this.ERR_NO_SAVES: - return i18next.t("menu:noSaves"); - case this.ERR_TOO_MANY_SAVES: - return i18next.t("menu:tooManySaves"); + case this.ERR_USERNAME: + return i18next.t("menu:invalidLoginUsername"); + case this.ERR_PASSWORD: + return i18next.t("menu:invalidLoginPassword"); + case this.ERR_ACCOUNT_EXIST: + return i18next.t("menu:accountNonExistent"); + case this.ERR_PASSWORD_MATCH: + return i18next.t("menu:unmatchingPassword"); + case this.ERR_NO_SAVES: + return "P01: " + i18next.t("menu:noSaves"); + case this.ERR_TOO_MANY_SAVES: + return "P02: " + i18next.t("menu:tooManySaves"); } return super.getReadableErrorMessage(error); } + override getInputFieldConfigs(): InputFieldConfig[] { + const inputFieldConfigs: InputFieldConfig[] = []; + inputFieldConfigs.push({ label: i18next.t("menu:username") }); + inputFieldConfigs.push({ label: i18next.t("menu:password"), isPassword: true }); + return inputFieldConfigs; + } + override show(args: any[]): boolean { if (super.show(args)) { @@ -124,7 +127,7 @@ export default class LoginFormUiHandler extends FormModalUiHandler { // Prevent overlapping overrides on action modification this.submitAction = originalLoginAction; this.sanitizeInputs(); - this.scene.ui.setMode(Mode.LOADING, { buttonActions: [] }); + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); const onFail = error => { this.scene.ui.setMode(Mode.LOGIN_FORM, Object.assign(config, { errorMessage: error?.trim() })); this.scene.ui.playError(); @@ -161,19 +164,19 @@ export default class LoginFormUiHandler extends FormModalUiHandler { this.infoContainer.setVisible(false); this.setMouseCursorStyle("default"); //reset cursor - [this.discordImage, this.googleImage, this.usernameInfoImage].forEach((img) => img.off("pointerdown")); + [ this.discordImage, this.googleImage, this.usernameInfoImage ].forEach((img) => img.off("pointerdown")); } - private processExternalProvider(config: ModalConfig) : void { + private processExternalProvider(config: ModalConfig): void { this.externalPartyTitle.setText(i18next.t("menu:orUse") ?? ""); - this.externalPartyTitle.setX(20+this.externalPartyTitle.text.length); + this.externalPartyTitle.setX(20 + this.externalPartyTitle.text.length); this.externalPartyTitle.setVisible(true); this.externalPartyContainer.setPositionRelative(this.modalContainer, 175, 0); this.externalPartyContainer.setVisible(true); this.externalPartyBg.setSize(this.externalPartyTitle.text.length + 50, this.modalBg.height); this.getUi().moveTo(this.externalPartyContainer, this.getUi().length - 1); - this.googleImage.setPosition(this.externalPartyBg.width/3.1, this.externalPartyBg.height-60); - this.discordImage.setPosition(this.externalPartyBg.width/3.1, this.externalPartyBg.height-40); + this.googleImage.setPosition(this.externalPartyBg.width / 3.1, this.externalPartyBg.height - 60); + this.discordImage.setPosition(this.externalPartyBg.width / 3.1, this.externalPartyBg.height - 40); this.infoContainer.setPosition(5, -76); this.infoContainer.setVisible(true); @@ -195,7 +198,7 @@ export default class LoginFormUiHandler extends FormModalUiHandler { }); const onFail = error => { - this.scene.ui.setMode(Mode.LOADING, { buttonActions: [] }); + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); this.scene.ui.setModeForceTransition(Mode.LOGIN_FORM, Object.assign(config, { errorMessage: error?.trim() })); this.scene.ui.playError(); }; diff --git a/src/ui/menu-ui-handler.ts b/src/ui/menu-ui-handler.ts index 0af527e518f..301d54daa3a 100644 --- a/src/ui/menu-ui-handler.ts +++ b/src/ui/menu-ui-handler.ts @@ -13,6 +13,7 @@ import { GameDataType } from "#enums/game-data-type"; import BgmBar from "#app/ui/bgm-bar"; import AwaitableUiHandler from "./awaitable-ui-handler"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; +import { AdminMode, getAdminModeName } from "./admin-ui-handler"; enum MenuOptions { GAME_SETTINGS, @@ -65,8 +66,8 @@ export default class MenuUiHandler extends MessageUiHandler { super(scene, mode); this.excludedMenus = () => [ - { condition: [Mode.COMMAND, Mode.TITLE].includes(mode ?? Mode.TITLE), options: [MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] }, - { condition: bypassLogin, options: [MenuOptions.LOG_OUT] } + { condition: [ Mode.COMMAND, Mode.TITLE ].includes(mode ?? Mode.TITLE), options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST ]}, + { condition: bypassLogin, options: [ MenuOptions.LOG_OUT ]} ]; this.menuOptions = Utils.getEnumKeys(MenuOptions) @@ -80,7 +81,7 @@ export default class MenuUiHandler extends MessageUiHandler { const ui = this.getUi(); // wiki url directs based on languges available on wiki const lang = i18next.resolvedLanguage?.substring(0, 2)!; // TODO: is this bang correct? - if (["de", "fr", "ko", "zh"].includes(lang)) { + if ([ "de", "fr", "ko", "zh" ].includes(lang)) { wikiUrl = `https://wiki.pokerogue.net/${lang}:start`; } @@ -108,8 +109,8 @@ export default class MenuUiHandler extends MessageUiHandler { render() { const ui = this.getUi(); this.excludedMenus = () => [ - { condition: this.scene.getCurrentPhase() instanceof SelectModifierPhase, options: [MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] }, - { condition: bypassLogin, options: [MenuOptions.LOG_OUT] } + { condition: this.scene.getCurrentPhase() instanceof SelectModifierPhase, options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST ]}, + { condition: bypassLogin, options: [ MenuOptions.LOG_OUT ]} ]; this.menuOptions = Utils.getEnumKeys(MenuOptions) @@ -387,16 +388,41 @@ export default class MenuUiHandler extends MessageUiHandler { communityOptions.push({ label: "Admin", handler: () => { - ui.playSelect(); - ui.setOverlayMode(Mode.ADMIN, { - buttonActions: [ - () => { - ui.revertMode(); - }, - () => { - ui.revertMode(); + + const skippedAdminModes: AdminMode[] = [ AdminMode.ADMIN ]; // this is here so that we can skip the menu populating enums that aren't meant for the menu, such as the AdminMode.ADMIN + const options: OptionSelectItem[] = []; + Object.values(AdminMode).filter((v) => !isNaN(Number(v)) && !skippedAdminModes.includes(v as AdminMode)).forEach((mode) => { // this gets all the enums in a way we can use + options.push({ + label: getAdminModeName(mode as AdminMode), + handler: () => { + ui.playSelect(); + ui.setOverlayMode(Mode.ADMIN, { + buttonActions: [ + // we double revert here and below to go back 2 layers of menus + () => { + ui.revertMode(); + ui.revertMode(); + }, + () => { + ui.revertMode(); + ui.revertMode(); + } + ] + }, mode); // mode is our AdminMode enum + return true; } - ] + }); + }); + options.push({ + label: "Cancel", + handler: () => { + ui.revertMode(); + return true; + } + }); + this.scene.ui.setOverlayMode(Mode.OPTION_SELECT, { + options: options, + delay: 0 }); return true; }, @@ -468,148 +494,148 @@ export default class MenuUiHandler extends MessageUiHandler { } this.showText("", 0); switch (adjustedCursor) { - case MenuOptions.GAME_SETTINGS: - ui.setOverlayMode(Mode.SETTINGS); - success = true; - break; - case MenuOptions.ACHIEVEMENTS: - ui.setOverlayMode(Mode.ACHIEVEMENTS); - success = true; - break; - case MenuOptions.STATS: - ui.setOverlayMode(Mode.GAME_STATS); - success = true; - break; - case MenuOptions.RUN_HISTORY: - ui.setOverlayMode(Mode.RUN_HISTORY); - success = true; - break; - case MenuOptions.EGG_LIST: - if (this.scene.gameData.eggs.length) { + case MenuOptions.GAME_SETTINGS: + ui.setOverlayMode(Mode.SETTINGS); + success = true; + break; + case MenuOptions.ACHIEVEMENTS: + ui.setOverlayMode(Mode.ACHIEVEMENTS); + success = true; + break; + case MenuOptions.STATS: + ui.setOverlayMode(Mode.GAME_STATS); + success = true; + break; + case MenuOptions.RUN_HISTORY: + ui.setOverlayMode(Mode.RUN_HISTORY); + success = true; + break; + case MenuOptions.EGG_LIST: + if (this.scene.gameData.eggs.length) { + ui.revertMode(); + ui.setOverlayMode(Mode.EGG_LIST); + success = true; + } else { + ui.showText(i18next.t("menuUiHandler:noEggs"), null, () => ui.showText(""), Utils.fixedInt(1500)); + error = true; + } + break; + case MenuOptions.EGG_GACHA: ui.revertMode(); - ui.setOverlayMode(Mode.EGG_LIST); + ui.setOverlayMode(Mode.EGG_GACHA); success = true; - } else { - ui.showText(i18next.t("menuUiHandler:noEggs"), null, () => ui.showText(""), Utils.fixedInt(1500)); - error = true; - } - break; - case MenuOptions.EGG_GACHA: - ui.revertMode(); - ui.setOverlayMode(Mode.EGG_GACHA); - success = true; - break; - case MenuOptions.MANAGE_DATA: - if (!bypassLogin && !this.manageDataConfig.options.some(o => o.label === i18next.t("menuUiHandler:linkDiscord") || o.label === i18next.t("menuUiHandler:unlinkDiscord"))) { - this.manageDataConfig.options.splice(this.manageDataConfig.options.length - 1, 0, - { - label: loggedInUser?.discordId === "" ? i18next.t("menuUiHandler:linkDiscord") : i18next.t("menuUiHandler:unlinkDiscord"), - handler: () => { - if (loggedInUser?.discordId === "") { - const token = Utils.getCookie(Utils.sessionIdKey); - const redirectUri = encodeURIComponent(`${import.meta.env.VITE_SERVER_URL}/auth/discord/callback`); - const discordId = import.meta.env.VITE_DISCORD_CLIENT_ID; - const discordUrl = `https://discord.com/api/oauth2/authorize?client_id=${discordId}&redirect_uri=${redirectUri}&response_type=code&scope=identify&state=${token}&prompt=none`; - window.open(discordUrl, "_self"); - return true; - } else { - Utils.apiPost("/auth/discord/logout", undefined, undefined, true).then(res => { - if (!res.ok) { - console.error(`Unlink failed (${res.status}: ${res.statusText})`); - } - updateUserInfo().then(() => this.scene.reset(true, true)); - }); - return true; + break; + case MenuOptions.MANAGE_DATA: + if (!bypassLogin && !this.manageDataConfig.options.some(o => o.label === i18next.t("menuUiHandler:linkDiscord") || o.label === i18next.t("menuUiHandler:unlinkDiscord"))) { + this.manageDataConfig.options.splice(this.manageDataConfig.options.length - 1, 0, + { + label: loggedInUser?.discordId === "" ? i18next.t("menuUiHandler:linkDiscord") : i18next.t("menuUiHandler:unlinkDiscord"), + handler: () => { + if (loggedInUser?.discordId === "") { + const token = Utils.getCookie(Utils.sessionIdKey); + const redirectUri = encodeURIComponent(`${import.meta.env.VITE_SERVER_URL}/auth/discord/callback`); + const discordId = import.meta.env.VITE_DISCORD_CLIENT_ID; + const discordUrl = `https://discord.com/api/oauth2/authorize?client_id=${discordId}&redirect_uri=${redirectUri}&response_type=code&scope=identify&state=${token}&prompt=none`; + window.open(discordUrl, "_self"); + return true; + } else { + Utils.apiPost("/auth/discord/logout", undefined, undefined, true).then(res => { + if (!res.ok) { + console.error(`Unlink failed (${res.status}: ${res.statusText})`); + } + updateUserInfo().then(() => this.scene.reset(true, true)); + }); + return true; + } } - } - }, - { - label: loggedInUser?.googleId === "" ? i18next.t("menuUiHandler:linkGoogle") : i18next.t("menuUiHandler:unlinkGoogle"), - handler: () => { - if (loggedInUser?.googleId === "") { - const token = Utils.getCookie(Utils.sessionIdKey); - const redirectUri = encodeURIComponent(`${import.meta.env.VITE_SERVER_URL}/auth/google/callback`); - const googleId = import.meta.env.VITE_GOOGLE_CLIENT_ID; - const googleUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${googleId}&response_type=code&redirect_uri=${redirectUri}&scope=openid&state=${token}`; - window.open(googleUrl, "_self"); - return true; - } else { - Utils.apiPost("/auth/google/logout", undefined, undefined, true).then(res => { - if (!res.ok) { - console.error(`Unlink failed (${res.status}: ${res.statusText})`); - } - updateUserInfo().then(() => this.scene.reset(true, true)); - }); - return true; + }, + { + label: loggedInUser?.googleId === "" ? i18next.t("menuUiHandler:linkGoogle") : i18next.t("menuUiHandler:unlinkGoogle"), + handler: () => { + if (loggedInUser?.googleId === "") { + const token = Utils.getCookie(Utils.sessionIdKey); + const redirectUri = encodeURIComponent(`${import.meta.env.VITE_SERVER_URL}/auth/google/callback`); + const googleId = import.meta.env.VITE_GOOGLE_CLIENT_ID; + const googleUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${googleId}&response_type=code&redirect_uri=${redirectUri}&scope=openid&state=${token}`; + window.open(googleUrl, "_self"); + return true; + } else { + Utils.apiPost("/auth/google/logout", undefined, undefined, true).then(res => { + if (!res.ok) { + console.error(`Unlink failed (${res.status}: ${res.statusText})`); + } + updateUserInfo().then(() => this.scene.reset(true, true)); + }); + return true; + } } - } - }); - } - ui.setOverlayMode(Mode.MENU_OPTION_SELECT, this.manageDataConfig); - success = true; - break; - case MenuOptions.COMMUNITY: - ui.setOverlayMode(Mode.MENU_OPTION_SELECT, this.communityConfig); - success = true; - break; - case MenuOptions.SAVE_AND_QUIT: - if (this.scene.currentBattle) { + }); + } + ui.setOverlayMode(Mode.MENU_OPTION_SELECT, this.manageDataConfig); success = true; - const doSaveQuit = () => { - ui.setMode(Mode.LOADING, { - buttonActions: [], fadeOut: () => - this.scene.gameData.saveAll(this.scene, true, true, true, true).then(() => { + break; + case MenuOptions.COMMUNITY: + ui.setOverlayMode(Mode.MENU_OPTION_SELECT, this.communityConfig); + success = true; + break; + case MenuOptions.SAVE_AND_QUIT: + if (this.scene.currentBattle) { + success = true; + const doSaveQuit = () => { + ui.setMode(Mode.LOADING, { + buttonActions: [], fadeOut: () => + this.scene.gameData.saveAll(this.scene, true, true, true, true).then(() => { - this.scene.reset(true); - }) + this.scene.reset(true); + }) + }); + }; + if (this.scene.currentBattle.turn > 1) { + ui.showText(i18next.t("menuUiHandler:losingProgressionWarning"), null, () => { + if (!this.active) { + this.showText("", 0); + return; + } + ui.setOverlayMode(Mode.CONFIRM, doSaveQuit, () => { + ui.revertMode(); + this.showText("", 0); + }, false, -98); + }); + } else { + doSaveQuit(); + } + } else { + error = true; + } + break; + case MenuOptions.LOG_OUT: + success = true; + const doLogout = () => { + ui.setMode(Mode.LOADING, { + buttonActions: [], fadeOut: () => Utils.apiFetch("account/logout", true).then(res => { + if (!res.ok) { + console.error(`Log out failed (${res.status}: ${res.statusText})`); + } + Utils.removeCookie(Utils.sessionIdKey); + updateUserInfo().then(() => this.scene.reset(true, true)); + }) }); }; - if (this.scene.currentBattle.turn > 1) { + if (this.scene.currentBattle) { ui.showText(i18next.t("menuUiHandler:losingProgressionWarning"), null, () => { if (!this.active) { this.showText("", 0); return; } - ui.setOverlayMode(Mode.CONFIRM, doSaveQuit, () => { + ui.setOverlayMode(Mode.CONFIRM, doLogout, () => { ui.revertMode(); this.showText("", 0); }, false, -98); }); } else { - doSaveQuit(); + doLogout(); } - } else { - error = true; - } - break; - case MenuOptions.LOG_OUT: - success = true; - const doLogout = () => { - ui.setMode(Mode.LOADING, { - buttonActions: [], fadeOut: () => Utils.apiFetch("account/logout", true).then(res => { - if (!res.ok) { - console.error(`Log out failed (${res.status}: ${res.statusText})`); - } - Utils.removeCookie(Utils.sessionIdKey); - updateUserInfo().then(() => this.scene.reset(true, true)); - }) - }); - }; - if (this.scene.currentBattle) { - ui.showText(i18next.t("menuUiHandler:losingProgressionWarning"), null, () => { - if (!this.active) { - this.showText("", 0); - return; - } - ui.setOverlayMode(Mode.CONFIRM, doLogout, () => { - ui.revertMode(); - this.showText("", 0); - }, false, -98); - }); - } else { - doLogout(); - } - break; + break; } } else if (button === Button.CANCEL) { success = true; @@ -620,20 +646,20 @@ export default class MenuUiHandler extends MessageUiHandler { }); } else { switch (button) { - case Button.UP: - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } else { - success = this.setCursor(this.menuOptions.length - 1); - } - break; - case Button.DOWN: - if (this.cursor + 1 < this.menuOptions.length) { - success = this.setCursor(this.cursor + 1); - } else { - success = this.setCursor(0); - } - break; + case Button.UP: + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } else { + success = this.setCursor(this.menuOptions.length - 1); + } + break; + case Button.DOWN: + if (this.cursor + 1 < this.menuOptions.length) { + success = this.setCursor(this.cursor + 1); + } else { + success = this.setCursor(0); + } + break; } } diff --git a/src/ui/message-ui-handler.ts b/src/ui/message-ui-handler.ts index f1b8ed981ee..5ae4707e329 100644 --- a/src/ui/message-ui-handler.ts +++ b/src/ui/message-ui-handler.ts @@ -56,18 +56,18 @@ export default abstract class MessageUiHandler extends AwaitableUiHandler { let actionMatch: RegExpExecArray | null; while ((actionMatch = actionPattern.exec(text))) { switch (actionMatch[1]) { - case "c": - charVarMap.set(actionMatch.index, actionMatch[2]); - break; - case "d": - delayMap.set(actionMatch.index, parseInt(actionMatch[2])); - break; - case "s": - soundMap.set(actionMatch.index, actionMatch[2]); - break; - case "f": - fadeMap.set(actionMatch.index, parseInt(actionMatch[2])); - break; + case "c": + charVarMap.set(actionMatch.index, actionMatch[2]); + break; + case "d": + delayMap.set(actionMatch.index, parseInt(actionMatch[2])); + break; + case "s": + soundMap.set(actionMatch.index, actionMatch[2]); + break; + case "f": + fadeMap.set(actionMatch.index, parseInt(actionMatch[2])); + break; } text = text.slice(0, actionMatch.index) + text.slice(actionMatch.index + actionMatch[2].length + 4); } diff --git a/src/ui/modal-ui-handler.ts b/src/ui/modal-ui-handler.ts index 80a39d7bf7f..79f1e8afeed 100644 --- a/src/ui/modal-ui-handler.ts +++ b/src/ui/modal-ui-handler.ts @@ -3,7 +3,7 @@ import { TextStyle, addTextObject } from "./text"; import { Mode } from "./ui"; import UiHandler from "./ui-handler"; import { WindowVariant, addWindow } from "./ui-theme"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; export interface ModalConfig { buttonActions: Function[]; @@ -15,12 +15,14 @@ export abstract class ModalUiHandler extends UiHandler { protected titleText: Phaser.GameObjects.Text; protected buttonContainers: Phaser.GameObjects.Container[]; protected buttonBgs: Phaser.GameObjects.NineSlice[]; + protected buttonLabels: Phaser.GameObjects.Text[]; constructor(scene: BattleScene, mode: Mode | null = null) { super(scene, mode); this.buttonContainers = []; this.buttonBgs = []; + this.buttonLabels = []; } abstract getModalTitle(config?: ModalConfig): string; @@ -75,6 +77,7 @@ export abstract class ModalUiHandler extends UiHandler { const buttonContainer = this.scene.add.container(0, buttonTopMargin); + this.buttonLabels.push(buttonLabel); this.buttonBgs.push(buttonBg); this.buttonContainers.push(buttonContainer); @@ -92,7 +95,7 @@ export abstract class ModalUiHandler extends UiHandler { if (args[0].hasOwnProperty("fadeOut") && typeof args[0].fadeOut === "function") { const [ marginTop, marginRight, marginBottom, marginLeft ] = this.getMargin(); - const overlay = this.scene.add.rectangle(( this.getWidth() + marginLeft + marginRight) / 2, (this.getHeight() + marginTop + marginBottom) / 2, this.scene.game.canvas.width / 6, this.scene.game.canvas.height /6, 0); + const overlay = this.scene.add.rectangle(( this.getWidth() + marginLeft + marginRight) / 2, (this.getHeight() + marginTop + marginBottom) / 2, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6, 0); overlay.setOrigin(0.5, 0.5); overlay.setName("rect-ui-overlay-modal"); overlay.setAlpha(0); diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index a1e10d74c64..3f89ebe415f 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -16,7 +16,10 @@ import { ShopCursorTarget } from "#app/enums/shop-cursor-target"; import { IntegerHolder } from "./../utils"; import Phaser from "phaser"; -export const SHOP_OPTIONS_ROW_LIMIT = 6; +export const SHOP_OPTIONS_ROW_LIMIT = 7; +const SINGLE_SHOP_ROW_YOFFSET = 12; +const DOUBLE_SHOP_ROW_YOFFSET = 24; +const OPTION_BUTTON_YPOSITION = -62; export default class ModifierSelectUiHandler extends AwaitableUiHandler { private modifierContainer: Phaser.GameObjects.Container; @@ -68,7 +71,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.checkButtonWidth = context.measureText(i18next.t("modifierSelectUiHandler:checkTeam")).width; } - this.transferButtonContainer = this.scene.add.container((this.scene.game.canvas.width - this.checkButtonWidth) / 6 - 21, -64); + this.transferButtonContainer = this.scene.add.container((this.scene.game.canvas.width - this.checkButtonWidth) / 6 - 21, OPTION_BUTTON_YPOSITION); this.transferButtonContainer.setName("transfer-btn"); this.transferButtonContainer.setVisible(false); ui.add(this.transferButtonContainer); @@ -78,7 +81,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { transferButtonText.setOrigin(1, 0); this.transferButtonContainer.add(transferButtonText); - this.checkButtonContainer = this.scene.add.container((this.scene.game.canvas.width) / 6 - 1, -64); + this.checkButtonContainer = this.scene.add.container((this.scene.game.canvas.width) / 6 - 1, OPTION_BUTTON_YPOSITION); this.checkButtonContainer.setName("use-btn"); this.checkButtonContainer.setVisible(false); ui.add(this.checkButtonContainer); @@ -88,7 +91,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { checkButtonText.setOrigin(1, 0); this.checkButtonContainer.add(checkButtonText); - this.rerollButtonContainer = this.scene.add.container(16, -64); + this.rerollButtonContainer = this.scene.add.container(16, OPTION_BUTTON_YPOSITION); this.rerollButtonContainer.setName("reroll-brn"); this.rerollButtonContainer.setVisible(false); ui.add(this.rerollButtonContainer); @@ -104,7 +107,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.rerollCostText.setPositionRelative(rerollButtonText, rerollButtonText.displayWidth + 5, 1); this.rerollButtonContainer.add(this.rerollCostText); - this.lockRarityButtonContainer = this.scene.add.container(16, -64); + this.lockRarityButtonContainer = this.scene.add.container(16, OPTION_BUTTON_YPOSITION); this.lockRarityButtonContainer.setVisible(false); ui.add(this.lockRarityButtonContainer); @@ -191,7 +194,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { const shopTypeOptions = !removeHealShop ? getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, baseShopCost.value) : []; - const optionsYOffset = shopTypeOptions.length >= SHOP_OPTIONS_ROW_LIMIT ? -8 : -24; + const optionsYOffset = shopTypeOptions.length > SHOP_OPTIONS_ROW_LIMIT ? -SINGLE_SHOP_ROW_YOFFSET : -DOUBLE_SHOP_ROW_YOFFSET; for (let m = 0; m < typeOptions.length; m++) { const sliceWidth = (this.scene.game.canvas.width / 6) / (typeOptions.length + 2); @@ -211,8 +214,8 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { const row = m < SHOP_OPTIONS_ROW_LIMIT ? 0 : 1; const col = m < SHOP_OPTIONS_ROW_LIMIT ? m : m - SHOP_OPTIONS_ROW_LIMIT; const rowOptions = shopTypeOptions.slice(row ? SHOP_OPTIONS_ROW_LIMIT : 0, row ? undefined : SHOP_OPTIONS_ROW_LIMIT); - const sliceWidth = (this.scene.game.canvas.width / SHOP_OPTIONS_ROW_LIMIT) / (rowOptions.length + 2); - const option = new ModifierOption(this.scene, sliceWidth * (col + 1) + (sliceWidth * 0.5), ((-this.scene.game.canvas.height / 12) - (this.scene.game.canvas.height / 32) - (40 - (28 * row - 1))), shopTypeOptions[m]); + const sliceWidth = (this.scene.game.canvas.width / 6) / (rowOptions.length + 2); + const option = new ModifierOption(this.scene, sliceWidth * (col + 1) + (sliceWidth * 0.5), ((-this.scene.game.canvas.height / 12) - (this.scene.game.canvas.height / 32) - (42 - (28 * row - 1))), shopTypeOptions[m]); option.setScale(0.375); this.scene.add.existing(option); this.modifierContainer.add(option); @@ -283,7 +286,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { }); this.scene.tweens.add({ - targets: [this.rerollButtonContainer, this.lockRarityButtonContainer], + targets: [ this.rerollButtonContainer, this.lockRarityButtonContainer ], alpha: this.rerollCost < 0 ? 0.5 : 1, duration: 250 }); @@ -354,79 +357,79 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { } } else { switch (button) { - case Button.UP: - if (this.rowCursor === 0 && this.cursor === 3) { - success = this.setCursor(0); - } else if (this.rowCursor < this.shopOptionsRows.length + 1) { - success = this.setRowCursor(this.rowCursor + 1); - } - break; - case Button.DOWN: - if (this.rowCursor) { - success = this.setRowCursor(this.rowCursor - 1); - } else if (this.lockRarityButtonContainer.visible && this.cursor === 0) { - success = this.setCursor(3); - } - break; - case Button.LEFT: - if (!this.rowCursor) { - switch (this.cursor) { - case 0: - success = false; - break; - case 1: - if (this.lockRarityButtonContainer.visible) { - success = this.setCursor(3); - } else { - success = this.rerollButtonContainer.visible && this.setCursor(0); - } - break; - case 2: - if (this.transferButtonContainer.visible) { - success = this.setCursor(1); - } else if (this.rerollButtonContainer.visible) { - success = this.setCursor(0); - } else { - success = false; - } - break; + case Button.UP: + if (this.rowCursor === 0 && this.cursor === 3) { + success = this.setCursor(0); + } else if (this.rowCursor < this.shopOptionsRows.length + 1) { + success = this.setRowCursor(this.rowCursor + 1); } - } else if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } else if (this.rowCursor === 1 && this.rerollButtonContainer.visible) { - success = this.setRowCursor(0); - } - break; - case Button.RIGHT: - if (!this.rowCursor) { - switch (this.cursor) { - case 0: - if (this.transferButtonContainer.visible) { - success = this.setCursor(1); - } else { - success = this.setCursor(2); - } - break; - case 1: - success = this.setCursor(2); - break; - case 2: - success = false; - break; - case 3: - if (this.transferButtonContainer.visible) { - success = this.setCursor(1); - } else { - success = this.setCursor(2); - } - break; + break; + case Button.DOWN: + if (this.rowCursor) { + success = this.setRowCursor(this.rowCursor - 1); + } else if (this.lockRarityButtonContainer.visible && this.cursor === 0) { + success = this.setCursor(3); } - } else if (this.cursor < this.getRowItems(this.rowCursor) - 1) { - success = this.setCursor(this.cursor + 1); - } else if (this.rowCursor === 1 && this.transferButtonContainer.visible) { - success = this.setRowCursor(0); - } - break; + break; + case Button.LEFT: + if (!this.rowCursor) { + switch (this.cursor) { + case 0: + success = false; + break; + case 1: + if (this.lockRarityButtonContainer.visible) { + success = this.setCursor(3); + } else { + success = this.rerollButtonContainer.visible && this.setCursor(0); + } + break; + case 2: + if (this.transferButtonContainer.visible) { + success = this.setCursor(1); + } else if (this.rerollButtonContainer.visible) { + success = this.setCursor(0); + } else { + success = false; + } + break; + } + } else if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } else if (this.rowCursor === 1 && this.rerollButtonContainer.visible) { + success = this.setRowCursor(0); + } + break; + case Button.RIGHT: + if (!this.rowCursor) { + switch (this.cursor) { + case 0: + if (this.transferButtonContainer.visible) { + success = this.setCursor(1); + } else { + success = this.setCursor(2); + } + break; + case 1: + success = this.setCursor(2); + break; + case 2: + success = false; + break; + case 3: + if (this.transferButtonContainer.visible) { + success = this.setCursor(1); + } else { + success = this.setCursor(2); + } + break; + } + } else if (this.cursor < this.getRowItems(this.rowCursor) - 1) { + success = this.setCursor(this.cursor + 1); + } else if (this.rowCursor === 1 && this.transferButtonContainer.visible) { + success = this.setRowCursor(0); + } + break; } } @@ -456,16 +459,18 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { if (this.rowCursor === 1 && options.length === 0) { // Continue button when no shop items this.cursorObj.setScale(1.25); - this.cursorObj.setPosition((this.scene.game.canvas.width / 18) + 23, (-this.scene.game.canvas.height / 12) - (this.shopOptionsRows.length > 1 ? 6 : 22)); + this.cursorObj.setPosition((this.scene.game.canvas.width / 18) + 23, (-this.scene.game.canvas.height / 12) - (this.shopOptionsRows.length > 1 ? SINGLE_SHOP_ROW_YOFFSET - 2 : DOUBLE_SHOP_ROW_YOFFSET - 2)); ui.showText(i18next.t("modifierSelectUiHandler:continueNextWaveDescription")); return ret; } const sliceWidth = (this.scene.game.canvas.width / 6) / (options.length + 2); if (this.rowCursor < 2) { - this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 20, (-this.scene.game.canvas.height / 12) - (this.shopOptionsRows.length > 1 ? 6 : 22)); + // Cursor on free items + this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 20, (-this.scene.game.canvas.height / 12) - (this.shopOptionsRows.length > 1 ? SINGLE_SHOP_ROW_YOFFSET - 2 : DOUBLE_SHOP_ROW_YOFFSET - 2)); } else { - this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 16, (-this.scene.game.canvas.height / 12 - this.scene.game.canvas.height / 32) - (-16 + 28 * (this.rowCursor - (this.shopOptionsRows.length - 1)))); + // Cursor on paying items + this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 16, (-this.scene.game.canvas.height / 12 - this.scene.game.canvas.height / 32) - (-14 + 28 * (this.rowCursor - (this.shopOptionsRows.length - 1)))); } const type = options[this.cursor].modifierTypeOption.type; @@ -475,16 +480,16 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.moveInfoOverlay.show(allMoves[type.moveId]); } } else if (cursor === 0) { - this.cursorObj.setPosition(6, this.lockRarityButtonContainer.visible ? -72 : -60); + this.cursorObj.setPosition(6, this.lockRarityButtonContainer.visible ? OPTION_BUTTON_YPOSITION - 8 : OPTION_BUTTON_YPOSITION + 4); ui.showText(i18next.t("modifierSelectUiHandler:rerollDesc")); } else if (cursor === 1) { - this.cursorObj.setPosition((this.scene.game.canvas.width - this.transferButtonWidth - this.checkButtonWidth) / 6 - 30, -60); + this.cursorObj.setPosition((this.scene.game.canvas.width - this.transferButtonWidth - this.checkButtonWidth) / 6 - 30, OPTION_BUTTON_YPOSITION + 4); ui.showText(i18next.t("modifierSelectUiHandler:transferDesc")); } else if (cursor === 2) { - this.cursorObj.setPosition((this.scene.game.canvas.width - this.checkButtonWidth) / 6 - 10, -60); + this.cursorObj.setPosition((this.scene.game.canvas.width - this.checkButtonWidth) / 6 - 10, OPTION_BUTTON_YPOSITION + 4); ui.showText(i18next.t("modifierSelectUiHandler:checkTeamDesc")); } else { - this.cursorObj.setPosition(6, -60); + this.cursorObj.setPosition(6, OPTION_BUTTON_YPOSITION + 4); ui.showText(i18next.t("modifierSelectUiHandler:lockRaritiesDesc")); } @@ -522,12 +527,12 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { private getRowItems(rowCursor: integer): integer { switch (rowCursor) { - case 0: - return 3; - case 1: - return this.options.length; - default: - return this.shopOptionsRows[this.shopOptionsRows.length - (rowCursor - 1)].length; + case 0: + return 3; + case 1: + return this.options.length; + default: + return this.shopOptionsRows[this.shopOptionsRows.length - (rowCursor - 1)].length; } } @@ -577,6 +582,10 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.getUi().clearText(); this.eraseCursor(); + // Reset cursor positions + this.cursor = 0; + this.rowCursor = 0; + /* Multiplies the fade time duration by the speed parameter so that it is always constant, and avoids "flashbangs" at game speed x5 */ this.scene.hideShopOverlay(750 * this.scene.gameSpeed); this.scene.hideLuckText(250); diff --git a/src/ui/move-info-overlay.ts b/src/ui/move-info-overlay.ts index 42026082b36..6c58d32c515 100644 --- a/src/ui/move-info-overlay.ts +++ b/src/ui/move-info-overlay.ts @@ -1,4 +1,4 @@ -import BattleScene, {InfoToggle} from "../battle-scene"; +import BattleScene, { InfoToggle } from "../battle-scene"; import { TextStyle, addTextObject } from "./text"; import { addWindow } from "./ui-theme"; import * as Utils from "../utils"; @@ -62,7 +62,7 @@ export default class MoveInfoOverlay extends Phaser.GameObjects.Container implem this.add(this.descBg); // set up the description; wordWrap uses true pixels, unaffected by any scaling, while other values are affected - this.desc = addTextObject(scene, (options?.onSide && !options?.right ? EFF_WIDTH : 0) + BORDER, (options?.top ? EFF_HEIGHT : 0) + BORDER - 2, "", TextStyle.BATTLE_INFO, { wordWrap: { width: (width - (BORDER - 2) * 2 - (options?.onSide ? EFF_WIDTH : 0)) * GLOBAL_SCALE } }); + this.desc = addTextObject(scene, (options?.onSide && !options?.right ? EFF_WIDTH : 0) + BORDER, (options?.top ? EFF_HEIGHT : 0) + BORDER - 2, "", TextStyle.BATTLE_INFO, { wordWrap: { width: (width - (BORDER - 2) * 2 - (options?.onSide ? EFF_WIDTH : 0)) * GLOBAL_SCALE }}); this.desc.setLineSpacing(i18next.resolvedLanguage === "ja" ? 25 : 5); // limit the text rendering, required for scrolling later on diff --git a/src/ui/mystery-encounter-ui-handler.ts b/src/ui/mystery-encounter-ui-handler.ts index edff5c25cda..b568f8b71de 100644 --- a/src/ui/mystery-encounter-ui-handler.ts +++ b/src/ui/mystery-encounter-ui-handler.ts @@ -159,16 +159,16 @@ export default class MysteryEncounterUiHandler extends UiHandler { } } else { switch (this.optionsContainer.getAll()?.length) { - default: - case 3: - success = this.handleTwoOptionMoveInput(button); - break; - case 4: - success = this.handleThreeOptionMoveInput(button); - break; - case 5: - success = this.handleFourOptionMoveInput(button); - break; + default: + case 3: + success = this.handleTwoOptionMoveInput(button); + break; + case 4: + success = this.handleThreeOptionMoveInput(button); + break; + case 5: + success = this.handleFourOptionMoveInput(button); + break; } this.displayOptionTooltip(); @@ -185,26 +185,26 @@ export default class MysteryEncounterUiHandler extends UiHandler { let success = false; const cursor = this.getCursor(); switch (button) { - case Button.UP: - if (cursor < this.viewPartyIndex) { - success = this.setCursor(this.viewPartyIndex); - } - break; - case Button.DOWN: - if (cursor === this.viewPartyIndex) { - success = this.setCursor(1); - } - break; - case Button.LEFT: - if (cursor > 0) { - success = this.setCursor(cursor - 1); - } - break; - case Button.RIGHT: - if (cursor < this.viewPartyIndex) { - success = this.setCursor(cursor + 1); - } - break; + case Button.UP: + if (cursor < this.viewPartyIndex) { + success = this.setCursor(this.viewPartyIndex); + } + break; + case Button.DOWN: + if (cursor === this.viewPartyIndex) { + success = this.setCursor(1); + } + break; + case Button.LEFT: + if (cursor > 0) { + success = this.setCursor(cursor - 1); + } + break; + case Button.RIGHT: + if (cursor < this.viewPartyIndex) { + success = this.setCursor(cursor + 1); + } + break; } return success; @@ -214,34 +214,34 @@ export default class MysteryEncounterUiHandler extends UiHandler { let success = false; const cursor = this.getCursor(); switch (button) { - case Button.UP: - if (cursor === 2) { - success = this.setCursor(cursor - 2); - } else { - success = this.setCursor(this.viewPartyIndex); - } - break; - case Button.DOWN: - if (cursor === this.viewPartyIndex) { - success = this.setCursor(1); - } else { - success = this.setCursor(2); - } - break; - case Button.LEFT: - if (cursor === this.viewPartyIndex) { - success = this.setCursor(1); - } else if (cursor === 1) { - success = this.setCursor(cursor - 1); - } - break; - case Button.RIGHT: - if (cursor === 1) { - success = this.setCursor(this.viewPartyIndex); - } else if (cursor < 1) { - success = this.setCursor(cursor + 1); - } - break; + case Button.UP: + if (cursor === 2) { + success = this.setCursor(cursor - 2); + } else { + success = this.setCursor(this.viewPartyIndex); + } + break; + case Button.DOWN: + if (cursor === this.viewPartyIndex) { + success = this.setCursor(1); + } else { + success = this.setCursor(2); + } + break; + case Button.LEFT: + if (cursor === this.viewPartyIndex) { + success = this.setCursor(1); + } else if (cursor === 1) { + success = this.setCursor(cursor - 1); + } + break; + case Button.RIGHT: + if (cursor === 1) { + success = this.setCursor(this.viewPartyIndex); + } else if (cursor < 1) { + success = this.setCursor(cursor + 1); + } + break; } return success; @@ -251,34 +251,34 @@ export default class MysteryEncounterUiHandler extends UiHandler { let success = false; const cursor = this.getCursor(); switch (button) { - case Button.UP: - if (cursor >= 2 && cursor !== this.viewPartyIndex) { - success = this.setCursor(cursor - 2); - } else { - success = this.setCursor(this.viewPartyIndex); - } - break; - case Button.DOWN: - if (cursor <= 1) { - success = this.setCursor(cursor + 2); - } else if (cursor === this.viewPartyIndex) { - success = this.setCursor(1); - } - break; - case Button.LEFT: - if (cursor === this.viewPartyIndex) { - success = this.setCursor(1); - } else if (cursor % 2 === 1) { - success = this.setCursor(cursor - 1); - } - break; - case Button.RIGHT: - if (cursor === 1) { - success = this.setCursor(this.viewPartyIndex); - } else if (cursor % 2 === 0 && cursor !== this.viewPartyIndex) { - success = this.setCursor(cursor + 1); - } - break; + case Button.UP: + if (cursor >= 2 && cursor !== this.viewPartyIndex) { + success = this.setCursor(cursor - 2); + } else { + success = this.setCursor(this.viewPartyIndex); + } + break; + case Button.DOWN: + if (cursor <= 1) { + success = this.setCursor(cursor + 2); + } else if (cursor === this.viewPartyIndex) { + success = this.setCursor(1); + } + break; + case Button.LEFT: + if (cursor === this.viewPartyIndex) { + success = this.setCursor(1); + } else if (cursor % 2 === 1) { + success = this.setCursor(cursor - 1); + } + break; + case Button.RIGHT: + if (cursor === 1) { + success = this.setCursor(this.viewPartyIndex); + } else if (cursor % 2 === 0 && cursor !== this.viewPartyIndex) { + success = this.setCursor(cursor + 1); + } + break; } return success; @@ -351,16 +351,16 @@ export default class MysteryEncounterUiHandler extends UiHandler { let optionText: BBCodeText; switch (this.encounterOptions.length) { - default: - case 2: - optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, 8, "-", TextStyle.WINDOW, { fontSize: "80px", lineSpacing: -8 }); - break; - case 3: - optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, i < 2 ? 0 : 16, "-", TextStyle.WINDOW, { fontSize: "80px", lineSpacing: -8 }); - break; - case 4: - optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, i < 2 ? 0 : 16, "-", TextStyle.WINDOW, { fontSize: "80px", lineSpacing: -8 }); - break; + default: + case 2: + optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, 8, "-", TextStyle.WINDOW, { fontSize: "80px", lineSpacing: -8 }); + break; + case 3: + optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, i < 2 ? 0 : 16, "-", TextStyle.WINDOW, { fontSize: "80px", lineSpacing: -8 }); + break; + case 4: + optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, i < 2 ? 0 : 16, "-", TextStyle.WINDOW, { fontSize: "80px", lineSpacing: -8 }); + break; } this.optionsMeetsReqs.push(option.meetsRequirements(this.scene)); @@ -438,7 +438,7 @@ export default class MysteryEncounterUiHandler extends UiHandler { const ballType = getPokeballAtlasKey(index); this.rarityBall.setTexture("pb", ballType); - const descriptionTextObject = addBBCodeTextObject(this.scene, 6, 25, descriptionText ?? "", TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } }); + const descriptionTextObject = addBBCodeTextObject(this.scene, 6, 25, descriptionText ?? "", TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 }}); // Sets up the mask that hides the description text to give an illusion of scrolling const descriptionTextMaskRect = this.scene.make.graphics({}); @@ -472,7 +472,7 @@ export default class MysteryEncounterUiHandler extends UiHandler { this.descriptionContainer.add(descriptionTextObject); - const queryTextObject = addBBCodeTextObject(this.scene, 0, 0, queryText ?? "", TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } }); + const queryTextObject = addBBCodeTextObject(this.scene, 0, 0, queryText ?? "", TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 }}); this.descriptionContainer.add(queryTextObject); queryTextObject.setPosition(75 - queryTextObject.displayWidth / 2, 90); @@ -518,7 +518,7 @@ export default class MysteryEncounterUiHandler extends UiHandler { // Auto-color options green/blue for good/bad by looking for (+)/(-) if (text) { - const primaryStyleString = [...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))!][0]; + const primaryStyleString = [ ...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))! ][0]; text = text.replace(/(\(\+\)[^\(\[]*)/gi, substring => "[/color][/shadow]" + getBBCodeFrag(substring, TextStyle.SUMMARY_GREEN) + "[/color][/shadow]" + primaryStyleString); text = text.replace(/(\(\-\)[^\(\[]*)/gi, substring => "[/color][/shadow]" + getBBCodeFrag(substring, TextStyle.SUMMARY_BLUE) + "[/color][/shadow]" + primaryStyleString); } diff --git a/src/ui/outdated-modal-ui-handler.ts b/src/ui/outdated-modal-ui-handler.ts deleted file mode 100644 index fc4b93f9b8a..00000000000 --- a/src/ui/outdated-modal-ui-handler.ts +++ /dev/null @@ -1,47 +0,0 @@ -import BattleScene from "../battle-scene"; -import { ModalConfig, ModalUiHandler } from "./modal-ui-handler"; -import { addTextObject, TextStyle } from "./text"; -import { Mode } from "./ui"; - -export default class OutdatedModalUiHandler extends ModalUiHandler { - constructor(scene: BattleScene, mode: Mode | null = null) { - super(scene, mode); - } - - getModalTitle(): string { - return ""; - } - - getWidth(): number { - return 160; - } - - getHeight(): number { - return 64; - } - - getMargin(): [number, number, number, number] { - return [ 0, 0, 48, 0 ]; - } - - getButtonLabels(): string[] { - return [ ]; - } - - setup(): void { - super.setup(); - - const label = addTextObject(this.scene, this.getWidth() / 2, this.getHeight() / 2, "Your client is currently outdated.\nPlease reload to update the game.\n\nIf this error persists, please clear your browser cache.", TextStyle.WINDOW, { fontSize: "48px", align: "center" }); - label.setOrigin(0.5, 0.5); - - this.modalContainer.add(label); - } - - show(args: any[]): boolean { - const config: ModalConfig = { - buttonActions: [] - }; - - return super.show([ config ]); - } -} diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 72b34731842..e96fde8d54f 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -14,7 +14,7 @@ import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { addWindow } from "#app/ui/ui-theme"; import { SpeciesFormChangeItemTrigger, FormChangeItem } from "#app/data/pokemon-forms"; import { getVariantTint } from "#app/data/variant"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import { applyChallenges, ChallengeType } from "#app/data/challenge"; import MoveInfoOverlay from "#app/ui/move-info-overlay"; import i18next from "i18next"; @@ -216,7 +216,7 @@ export default class PartyUiHandler extends MessageUiHandler { public static NoEffectMessage = i18next.t("partyUiHandler:anyEffect"); - private localizedOptions = [PartyOption.SEND_OUT, PartyOption.SUMMARY, PartyOption.CANCEL, PartyOption.APPLY, PartyOption.RELEASE, PartyOption.TEACH, PartyOption.SPLICE, PartyOption.UNSPLICE, PartyOption.REVIVE, PartyOption.TRANSFER, PartyOption.UNPAUSE_EVOLUTION, PartyOption.PASS_BATON, PartyOption.RENAME, PartyOption.SELECT]; + private localizedOptions = [ PartyOption.SEND_OUT, PartyOption.SUMMARY, PartyOption.CANCEL, PartyOption.APPLY, PartyOption.RELEASE, PartyOption.TEACH, PartyOption.SPLICE, PartyOption.UNSPLICE, PartyOption.REVIVE, PartyOption.TRANSFER, PartyOption.UNPAUSE_EVOLUTION, PartyOption.PASS_BATON, PartyOption.RENAME, PartyOption.SELECT ]; constructor(scene: BattleScene) { super(scene, Mode.PARTY); @@ -468,7 +468,7 @@ export default class PartyUiHandler extends MessageUiHandler { this.clearOptions(); ui.playSelect(); pokemon.pauseEvolutions = !pokemon.pauseEvolutions; - this.showText(i18next.t(pokemon.pauseEvolutions? "partyUiHandler:pausedEvolutions" : "partyUiHandler:unpausedEvolutions", { pokemonName: getPokemonNameWithAffix(pokemon) }), undefined, () => this.showText("", 0), null, true); + this.showText(i18next.t(pokemon.pauseEvolutions ? "partyUiHandler:pausedEvolutions" : "partyUiHandler:unpausedEvolutions", { pokemonName: getPokemonNameWithAffix(pokemon) }), undefined, () => this.showText("", 0), null, true); } else if (option === PartyOption.UNSPLICE) { this.clearOptions(); ui.playSelect(); @@ -539,42 +539,42 @@ export default class PartyUiHandler extends MessageUiHandler { return true; } else { switch (button) { - case Button.LEFT: + case Button.LEFT: /** Decrease quantity for the current item and update UI */ - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { - this.transferQuantities[option] = this.transferQuantities[option] === 1 ? this.transferQuantitiesMax[option] : this.transferQuantities[option] - 1; - this.updateOptions(); - success = this.setCursor(this.optionsCursor); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */ - } - break; - case Button.RIGHT: + if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + this.transferQuantities[option] = this.transferQuantities[option] === 1 ? this.transferQuantitiesMax[option] : this.transferQuantities[option] - 1; + this.updateOptions(); + success = this.setCursor(this.optionsCursor); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */ + } + break; + case Button.RIGHT: /** Increase quantity for the current item and update UI */ - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { - this.transferQuantities[option] = this.transferQuantities[option] === this.transferQuantitiesMax[option] ? 1 : this.transferQuantities[option] + 1; - this.updateOptions(); - success = this.setCursor(this.optionsCursor); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */ - } - break; - case Button.UP: - /** If currently selecting items to transfer, reset quantity selection */ - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { - if (option !== PartyOption.ALL) { - this.transferQuantities[option] = this.transferQuantitiesMax[option]; + if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + this.transferQuantities[option] = this.transferQuantities[option] === this.transferQuantitiesMax[option] ? 1 : this.transferQuantities[option] + 1; + this.updateOptions(); + success = this.setCursor(this.optionsCursor); /** Place again the cursor at the same position. Necessary, otherwise the cursor disappears */ } - this.updateOptions(); - } - success = this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1); /** Move cursor */ - break; - case Button.DOWN: + break; + case Button.UP: /** If currently selecting items to transfer, reset quantity selection */ - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { - if (option !== PartyOption.ALL) { - this.transferQuantities[option] = this.transferQuantitiesMax[option]; + if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + if (option !== PartyOption.ALL) { + this.transferQuantities[option] = this.transferQuantitiesMax[option]; + } + this.updateOptions(); } - this.updateOptions(); - } - success = this.setCursor(this.optionsCursor < this.options.length - 1 ? this.optionsCursor + 1 : 0); /** Move cursor */ - break; + success = this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1); /** Move cursor */ + break; + case Button.DOWN: + /** If currently selecting items to transfer, reset quantity selection */ + if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + if (option !== PartyOption.ALL) { + this.transferQuantities[option] = this.transferQuantitiesMax[option]; + } + this.updateOptions(); + } + success = this.setCursor(this.optionsCursor < this.options.length - 1 ? this.optionsCursor + 1 : 0); /** Move cursor */ + break; } // show move description @@ -631,28 +631,28 @@ export default class PartyUiHandler extends MessageUiHandler { const battlerCount = this.scene.currentBattle.getBattlerCount(); switch (button) { - case Button.UP: - success = this.setCursor(this.cursor ? this.cursor < 6 ? this.cursor - 1 : slotCount - 1 : 6); - break; - case Button.DOWN: - success = this.setCursor(this.cursor < 6 ? this.cursor < slotCount - 1 ? this.cursor + 1 : 6 : 0); - break; - case Button.LEFT: - if (this.cursor >= battlerCount && this.cursor <= 6) { - success = this.setCursor(0); - } - break; - case Button.RIGHT: - if (slotCount === battlerCount) { - success = this.setCursor(6); + case Button.UP: + success = this.setCursor(this.cursor ? this.cursor < 6 ? this.cursor - 1 : slotCount - 1 : 6); break; - } else if (battlerCount >= 2 && slotCount > battlerCount && this.getCursor() === 0 && this.lastCursor === 1) { - success = this.setCursor(2); + case Button.DOWN: + success = this.setCursor(this.cursor < 6 ? this.cursor < slotCount - 1 ? this.cursor + 1 : 6 : 0); break; - } else if (slotCount > battlerCount && this.cursor < battlerCount) { - success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || battlerCount : battlerCount); + case Button.LEFT: + if (this.cursor >= battlerCount && this.cursor <= 6) { + success = this.setCursor(0); + } break; - } + case Button.RIGHT: + if (slotCount === battlerCount) { + success = this.setCursor(6); + break; + } else if (battlerCount >= 2 && slotCount > battlerCount && this.getCursor() === 0 && this.lastCursor === 1) { + success = this.setCursor(2); + break; + } else if (slotCount > battlerCount && this.cursor < battlerCount) { + success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || battlerCount : battlerCount); + break; + } } } @@ -671,6 +671,9 @@ export default class PartyUiHandler extends MessageUiHandler { } else if (this.cursor === 6) { this.partyCancelButton.select(); } + if (this.lastCursor < 6 && this.lastCursor >= party.length) { + this.lastCursor = party.length - 1; + } for (const p in party) { const slotIndex = parseInt(p); @@ -770,19 +773,19 @@ export default class PartyUiHandler extends MessageUiHandler { let optionsMessage = i18next.t("partyUiHandler:doWhatWithThisPokemon"); switch (this.partyUiMode) { - case PartyUiMode.MOVE_MODIFIER: - optionsMessage = i18next.t("partyUiHandler:selectAMove"); - break; - case PartyUiMode.MODIFIER_TRANSFER: - if (!this.transferMode) { - optionsMessage = i18next.t("partyUiHandler:changeQuantity"); - } - break; - case PartyUiMode.SPLICE: - if (!this.transferMode) { - optionsMessage = i18next.t("partyUiHandler:selectAnotherPokemonToSplice"); - } - break; + case PartyUiMode.MOVE_MODIFIER: + optionsMessage = i18next.t("partyUiHandler:selectAMove"); + break; + case PartyUiMode.MODIFIER_TRANSFER: + if (!this.transferMode) { + optionsMessage = i18next.t("partyUiHandler:changeQuantity"); + } + break; + case PartyUiMode.SPLICE: + if (!this.transferMode) { + optionsMessage = i18next.t("partyUiHandler:selectAnotherPokemonToSplice"); + } + break; } this.showText(optionsMessage, 0); @@ -826,64 +829,64 @@ export default class PartyUiHandler extends MessageUiHandler { if (this.partyUiMode !== PartyUiMode.MOVE_MODIFIER && this.partyUiMode !== PartyUiMode.REMEMBER_MOVE_MODIFIER && (this.transferMode || this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER)) { switch (this.partyUiMode) { - case PartyUiMode.SWITCH: - case PartyUiMode.FAINT_SWITCH: - case PartyUiMode.POST_BATTLE_SWITCH: - if (this.cursor >= this.scene.currentBattle.getBattlerCount()) { - const allowBatonModifierSwitch = + case PartyUiMode.SWITCH: + case PartyUiMode.FAINT_SWITCH: + case PartyUiMode.POST_BATTLE_SWITCH: + if (this.cursor >= this.scene.currentBattle.getBattlerCount()) { + const allowBatonModifierSwitch = this.partyUiMode !== PartyUiMode.FAINT_SWITCH && this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === this.scene.getPlayerField()[this.fieldIndex].id); - const moveHistory = this.scene.getPlayerField()[this.fieldIndex].getMoveHistory(); - const isBatonPassMove = this.partyUiMode === PartyUiMode.FAINT_SWITCH && moveHistory.length && allMoves[moveHistory[moveHistory.length - 1].move].getAttrs(ForceSwitchOutAttr)[0]?.isBatonPass() && moveHistory[moveHistory.length - 1].result === MoveResult.SUCCESS; + const moveHistory = this.scene.getPlayerField()[this.fieldIndex].getMoveHistory(); + const isBatonPassMove = this.partyUiMode === PartyUiMode.FAINT_SWITCH && moveHistory.length && allMoves[moveHistory[moveHistory.length - 1].move].getAttrs(ForceSwitchOutAttr)[0]?.isBatonPass() && moveHistory[moveHistory.length - 1].result === MoveResult.SUCCESS; - // isBatonPassMove and allowBatonModifierSwitch shouldn't ever be true - // at the same time, because they both explicitly check for a mutually - // exclusive partyUiMode. But better safe than sorry. - this.options.push(isBatonPassMove && !allowBatonModifierSwitch ? PartyOption.PASS_BATON : PartyOption.SEND_OUT); - if (allowBatonModifierSwitch && !isBatonPassMove) { + // isBatonPassMove and allowBatonModifierSwitch shouldn't ever be true + // at the same time, because they both explicitly check for a mutually + // exclusive partyUiMode. But better safe than sorry. + this.options.push(isBatonPassMove && !allowBatonModifierSwitch ? PartyOption.PASS_BATON : PartyOption.SEND_OUT); + if (allowBatonModifierSwitch && !isBatonPassMove) { // the BATON modifier gives an extra switch option for // pokemon-command switches, allowing buffs to be optionally passed - this.options.push(PartyOption.PASS_BATON); + this.options.push(PartyOption.PASS_BATON); + } } - } - break; - case PartyUiMode.REVIVAL_BLESSING: - this.options.push(PartyOption.REVIVE); - break; - case PartyUiMode.MODIFIER: - this.options.push(PartyOption.APPLY); - break; - case PartyUiMode.TM_MODIFIER: - this.options.push(PartyOption.TEACH); - break; - case PartyUiMode.MODIFIER_TRANSFER: - this.options.push(PartyOption.TRANSFER); - break; - case PartyUiMode.SPLICE: - if (this.transferMode) { - if (this.cursor !== this.transferCursor) { - this.options.push(PartyOption.SPLICE); - } - } else { + break; + case PartyUiMode.REVIVAL_BLESSING: + this.options.push(PartyOption.REVIVE); + break; + case PartyUiMode.MODIFIER: this.options.push(PartyOption.APPLY); - } - break; - case PartyUiMode.RELEASE: - this.options.push(PartyOption.RELEASE); - break; - case PartyUiMode.CHECK: - if (this.scene.getCurrentPhase() instanceof SelectModifierPhase) { - formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); - for (let i = 0; i < formChangeItemModifiers.length; i++) { - this.options.push(PartyOption.FORM_CHANGE_ITEM + i); + break; + case PartyUiMode.TM_MODIFIER: + this.options.push(PartyOption.TEACH); + break; + case PartyUiMode.MODIFIER_TRANSFER: + this.options.push(PartyOption.TRANSFER); + break; + case PartyUiMode.SPLICE: + if (this.transferMode) { + if (this.cursor !== this.transferCursor) { + this.options.push(PartyOption.SPLICE); + } + } else { + this.options.push(PartyOption.APPLY); } - } - break; - case PartyUiMode.SELECT: - this.options.push(PartyOption.SELECT); - break; + break; + case PartyUiMode.RELEASE: + this.options.push(PartyOption.RELEASE); + break; + case PartyUiMode.CHECK: + if (this.scene.getCurrentPhase() instanceof SelectModifierPhase) { + formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); + for (let i = 0; i < formChangeItemModifiers.length; i++) { + this.options.push(PartyOption.FORM_CHANGE_ITEM + i); + } + } + break; + case PartyUiMode.SELECT: + this.options.push(PartyOption.SELECT); + break; } this.options.push(PartyOption.SUMMARY); @@ -959,33 +962,33 @@ export default class PartyUiHandler extends MessageUiHandler { optionName = "↓"; } else if ((this.partyUiMode !== PartyUiMode.REMEMBER_MOVE_MODIFIER && (this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER || this.transferMode)) || option === PartyOption.CANCEL) { switch (option) { - case PartyOption.MOVE_1: - case PartyOption.MOVE_2: - case PartyOption.MOVE_3: - case PartyOption.MOVE_4: - const move = pokemon.moveset[option - PartyOption.MOVE_1]!; // TODO: is the bang correct? - if (this.showMovePp) { - const maxPP = move.getMovePp(); - const currPP = maxPP - move.ppUsed; - optionName = `${move.getName()} ${currPP}/${maxPP}`; - } else { - optionName = move.getName(); - } - break; - default: - if (formChangeItemModifiers && option >= PartyOption.FORM_CHANGE_ITEM) { - const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM]; - optionName = `${modifier.active ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${modifier.type.name}`; - } else if (option === PartyOption.UNPAUSE_EVOLUTION) { - optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`; - } else { - if (this.localizedOptions.includes(option)) { - optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`); + case PartyOption.MOVE_1: + case PartyOption.MOVE_2: + case PartyOption.MOVE_3: + case PartyOption.MOVE_4: + const move = pokemon.moveset[option - PartyOption.MOVE_1]!; // TODO: is the bang correct? + if (this.showMovePp) { + const maxPP = move.getMovePp(); + const currPP = maxPP - move.ppUsed; + optionName = `${move.getName()} ${currPP}/${maxPP}`; } else { - optionName = Utils.toReadableString(PartyOption[option]); + optionName = move.getName(); } - } - break; + break; + default: + if (formChangeItemModifiers && option >= PartyOption.FORM_CHANGE_ITEM) { + const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM]; + optionName = `${modifier.active ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${modifier.type.name}`; + } else if (option === PartyOption.UNPAUSE_EVOLUTION) { + optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`; + } else { + if (this.localizedOptions.includes(option)) { + optionName = i18next.t(`partyUiHandler:${PartyOption[option]}`); + } else { + optionName = Utils.toReadableString(PartyOption[option]); + } + } + break; } } else if (this.partyUiMode === PartyUiMode.REMEMBER_MOVE_MODIFIER) { const move = learnableLevelMoves[option]; @@ -1240,7 +1243,7 @@ class PartySlot extends Phaser.GameObjects.Container { slotLevelText.setPositionRelative(slotLevelLabel, 9, 0); slotLevelText.setOrigin(0, 0.25); - slotInfoContainer.add([this.slotName, slotLevelLabel, slotLevelText ]); + slotInfoContainer.add([ this.slotName, slotLevelLabel, slotLevelText ]); const genderSymbol = getGenderSymbol(this.pokemon.getGender(true)); @@ -1323,7 +1326,7 @@ class PartySlot extends Phaser.GameObjects.Container { this.slotDescriptionLabel.setOrigin(0, 1); this.slotDescriptionLabel.setVisible(false); - slotInfoContainer.add([this.slotHpBar, this.slotHpOverlay, this.slotHpText, this.slotDescriptionLabel]); + slotInfoContainer.add([ this.slotHpBar, this.slotHpOverlay, this.slotHpText, this.slotDescriptionLabel ]); if (partyUiMode !== PartyUiMode.TM_MODIFIER) { this.slotDescriptionLabel.setVisible(false); diff --git a/src/ui/pokemon-hatch-info-container.ts b/src/ui/pokemon-hatch-info-container.ts index 2c3f5110f53..146d70522fd 100644 --- a/src/ui/pokemon-hatch-info-container.ts +++ b/src/ui/pokemon-hatch-info-container.ts @@ -47,11 +47,11 @@ export default class PokemonHatchInfoContainer extends PokemonInfoContainer { this.pokemonListContainer.add(this.currentPokemonSprite); // setup name and number - this.pokemonNumberText = addTextObject(this.scene, 80, 107.5, "0000", TextStyle.SUMMARY, {fontSize: 74}); + this.pokemonNumberText = addTextObject(this.scene, 80, 107.5, "0000", TextStyle.SUMMARY, { fontSize: 74 }); this.pokemonNumberText.setOrigin(0, 0); this.pokemonListContainer.add(this.pokemonNumberText); - this.pokemonNameText = addTextObject(this.scene, 7, 107.5, "", TextStyle.SUMMARY, {fontSize: 74}); + this.pokemonNameText = addTextObject(this.scene, 7, 107.5, "", TextStyle.SUMMARY, { fontSize: 74 }); this.pokemonNameText.setOrigin(0, 0); this.pokemonListContainer.add(this.pokemonNameText); @@ -89,7 +89,7 @@ export default class PokemonHatchInfoContainer extends PokemonInfoContainer { const eggMoveBg = this.scene.add.nineslice(70, 0, "type_bgs", "unknown", 92, 14, 2, 2, 2, 2); eggMoveBg.setOrigin(1, 0); - const eggMoveLabel = addTextObject(this.scene, 70 -eggMoveBg.width / 2, 0, "???", TextStyle.PARTY); + const eggMoveLabel = addTextObject(this.scene, 70 - eggMoveBg.width / 2, 0, "???", TextStyle.PARTY); eggMoveLabel.setOrigin(0.5, 0); this.pokemonEggMoveBgs.push(eggMoveBg); diff --git a/src/ui/pokemon-icon-anim-handler.ts b/src/ui/pokemon-icon-anim-handler.ts index d6796d5cb5d..c7a24f69200 100644 --- a/src/ui/pokemon-icon-anim-handler.ts +++ b/src/ui/pokemon-icon-anim-handler.ts @@ -39,12 +39,12 @@ export default class PokemonIconAnimHandler { getModeYDelta(mode: PokemonIconAnimMode): number { switch (mode) { - case PokemonIconAnimMode.NONE: - return 0; - case PokemonIconAnimMode.PASSIVE: - return -1; - case PokemonIconAnimMode.ACTIVE: - return -2; + case PokemonIconAnimMode.NONE: + return 0; + case PokemonIconAnimMode.PASSIVE: + return -1; + case PokemonIconAnimMode.ACTIVE: + return -2; } } diff --git a/src/ui/pokemon-info-container.ts b/src/ui/pokemon-info-container.ts index 242e59c599b..6cc70bd598f 100644 --- a/src/ui/pokemon-info-container.ts +++ b/src/ui/pokemon-info-container.ts @@ -237,14 +237,20 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { const formKey = (pokemon.species?.forms?.[pokemon.formIndex!]?.formKey); const formText = Utils.capitalizeString(formKey, "-", false, false) || ""; - const speciesName = Utils.capitalizeString(Species[pokemon.species.getRootSpeciesId()], "_", true, false); + const speciesName = Utils.capitalizeString(Species[pokemon.species.speciesId], "_", true, false); let formName = ""; if (pokemon.species.speciesId === Species.ARCEUS) { formName = i18next.t(`pokemonInfo:Type.${formText?.toUpperCase()}`); } else { const i18key = `pokemonForm:${speciesName}${formText}`; - formName = i18next.exists(i18key) ? i18next.t(i18key) : formText; + if (i18next.exists(i18key)) { + formName = i18next.t(i18key); + } else { + const rootSpeciesName = Utils.capitalizeString(Species[pokemon.species.getRootSpeciesId()], "_", true, false); + const i18RootKey = `pokemonForm:${rootSpeciesName}${formText}`; + formName = i18next.exists(i18RootKey) ? i18next.t(i18RootKey) : formText; + } } if (formName) { @@ -279,11 +285,8 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { this.pokemonAbilityText.setColor(getTextColor(abilityTextStyle, false, this.scene.uiTheme)); this.pokemonAbilityText.setShadowColor(getTextColor(abilityTextStyle, true, this.scene.uiTheme)); - - const ownedAbilityAttrs = pokemon.scene.gameData.starterData[pokemon.species.getRootSpeciesId()].abilityAttr; - // Check if the player owns ability for the root form - const playerOwnsThisAbility = pokemon.checkIfPlayerHasAbilityOfStarter(ownedAbilityAttrs); + const playerOwnsThisAbility = pokemon.checkIfPlayerHasAbilityOfStarter(starterEntry.abilityAttr); if (!playerOwnsThisAbility) { this.pokemonAbilityLabelText.setColor(getTextColor(TextStyle.SUMMARY_BLUE, false, this.scene.uiTheme)); diff --git a/src/ui/registration-form-ui-handler.ts b/src/ui/registration-form-ui-handler.ts index 0c4b54ac723..fc9eb85cbaf 100644 --- a/src/ui/registration-form-ui-handler.ts +++ b/src/ui/registration-form-ui-handler.ts @@ -1,4 +1,4 @@ -import { FormModalUiHandler } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler"; import * as Utils from "../utils"; import { Mode } from "./ui"; @@ -24,10 +24,6 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler { return i18next.t("menu:register"); } - getFields(config?: ModalConfig): string[] { - return [ i18next.t("menu:username"), i18next.t("menu:password"), i18next.t("menu:confirmPassword") ]; - } - getWidth(config?: ModalConfig): number { return 160; } @@ -50,17 +46,25 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler { error = error.slice(0, colonIndex); } switch (error) { - case "invalid username": - return i18next.t("menu:invalidRegisterUsername"); - case "invalid password": - return i18next.t("menu:invalidRegisterPassword"); - case "failed to add account record": - return i18next.t("menu:usernameAlreadyUsed"); + case "invalid username": + return i18next.t("menu:invalidRegisterUsername"); + case "invalid password": + return i18next.t("menu:invalidRegisterPassword"); + case "failed to add account record": + return i18next.t("menu:usernameAlreadyUsed"); } return super.getReadableErrorMessage(error); } + override getInputFieldConfigs(): InputFieldConfig[] { + const inputFieldConfigs: InputFieldConfig[] = []; + inputFieldConfigs.push({ label: i18next.t("menu:username") }); + inputFieldConfigs.push({ label: i18next.t("menu:password"), isPassword: true }); + inputFieldConfigs.push({ label: i18next.t("menu:confirmPassword"), isPassword: true }); + return inputFieldConfigs; + } + setup(): void { super.setup(); @@ -74,7 +78,7 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler { }); const warningMessageFontSize = languageSettings[i18next.resolvedLanguage!]?.warningMessageFontSize ?? "42px"; - const label = addTextObject(this.scene, 10, 87, i18next.t("menu:registrationAgeWarning"), TextStyle.TOOLTIP_CONTENT, { fontSize: warningMessageFontSize}); + const label = addTextObject(this.scene, 10, 87, i18next.t("menu:registrationAgeWarning"), TextStyle.TOOLTIP_CONTENT, { fontSize: warningMessageFontSize }); this.modalContainer.add(label); } @@ -88,7 +92,7 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler { // Prevent overlapping overrides on action modification this.submitAction = originalRegistrationAction; this.sanitizeInputs(); - this.scene.ui.setMode(Mode.LOADING, { buttonActions: [] }); + this.scene.ui.setMode(Mode.LOADING, { buttonActions: []}); const onFail = error => { this.scene.ui.setMode(Mode.REGISTRATION_FORM, Object.assign(config, { errorMessage: error?.trim() })); this.scene.ui.playError(); diff --git a/src/ui/rename-form-ui-handler.ts b/src/ui/rename-form-ui-handler.ts index 078177cafb1..6e4c4c6809d 100644 --- a/src/ui/rename-form-ui-handler.ts +++ b/src/ui/rename-form-ui-handler.ts @@ -1,4 +1,4 @@ -import { FormModalUiHandler } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler"; import i18next from "i18next"; import { PlayerPokemon } from "#app/field/pokemon"; @@ -8,10 +8,6 @@ export default class RenameFormUiHandler extends FormModalUiHandler { return i18next.t("menu:renamePokemon"); } - getFields(config?: ModalConfig): string[] { - return [ i18next.t("menu:nickname") ]; - } - getWidth(config?: ModalConfig): number { return 160; } @@ -33,6 +29,10 @@ export default class RenameFormUiHandler extends FormModalUiHandler { return super.getReadableErrorMessage(error); } + override getInputFieldConfigs(): InputFieldConfig[] { + return [{ label: i18next.t("menu:nickname") }]; + } + show(args: any[]): boolean { if (super.show(args)) { const config = args[0] as ModalConfig; diff --git a/src/ui/run-history-ui-handler.ts b/src/ui/run-history-ui-handler.ts index d983fb0b0b8..061f15d0956 100644 --- a/src/ui/run-history-ui-handler.ts +++ b/src/ui/run-history-ui-handler.ts @@ -7,11 +7,12 @@ import * as Utils from "../utils"; import PokemonData from "../system/pokemon-data"; import MessageUiHandler from "./message-ui-handler"; import i18next from "i18next"; -import {Button} from "../enums/buttons"; +import { Button } from "../enums/buttons"; import { BattleType } from "../battle"; import { RunEntry } from "../system/game-data"; import { PlayerGender } from "#enums/player-gender"; import { TrainerVariant } from "../field/trainer"; +import { RunDisplayMode } from "#app/ui/run-info-ui-handler"; export type RunSelectCallback = (cursor: number) => void; @@ -100,11 +101,11 @@ export default class RunHistoryUiHandler extends MessageUiHandler { let success = false; const error = false; - if ([Button.ACTION, Button.CANCEL].includes(button)) { + if ([ Button.ACTION, Button.CANCEL ].includes(button)) { if (button === Button.ACTION) { const cursor = this.cursor + this.scrollCursor; if (this.runs[cursor]) { - this.scene.ui.setOverlayMode(Mode.RUN_INFO, this.runs[cursor].entryData, true); + this.scene.ui.setOverlayMode(Mode.RUN_INFO, this.runs[cursor].entryData, RunDisplayMode.RUN_HISTORY, true); } else { return false; } @@ -117,28 +118,28 @@ export default class RunHistoryUiHandler extends MessageUiHandler { } } else if (this.runs.length > 0) { switch (button) { - case Button.UP: - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } else if (this.scrollCursor) { - success = this.setScrollCursor(this.scrollCursor - 1); - } else if (this.runs.length > 1) { + case Button.UP: + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } else if (this.scrollCursor) { + success = this.setScrollCursor(this.scrollCursor - 1); + } else if (this.runs.length > 1) { // wrap around to the bottom - success = this.setCursor(Math.min(this.runs.length - 1, this.maxRows - 1)); - success = this.setScrollCursor(Math.max(0, this.runs.length - this.maxRows)) || success; - } - break; - case Button.DOWN: - if (this.cursor < Math.min(this.maxRows - 1, this.runs.length - this.scrollCursor - 1)) { - success = this.setCursor(this.cursor + 1); - } else if (this.scrollCursor < this.runs.length - this.maxRows) { - success = this.setScrollCursor(this.scrollCursor + 1); - } else if (this.runs.length > 1) { + success = this.setCursor(Math.min(this.runs.length - 1, this.maxRows - 1)); + success = this.setScrollCursor(Math.max(0, this.runs.length - this.maxRows)) || success; + } + break; + case Button.DOWN: + if (this.cursor < Math.min(this.maxRows - 1, this.runs.length - this.scrollCursor - 1)) { + success = this.setCursor(this.cursor + 1); + } else if (this.scrollCursor < this.runs.length - this.maxRows) { + success = this.setScrollCursor(this.scrollCursor + 1); + } else if (this.runs.length > 1) { // wrap around to the top - success = this.setCursor(0); - success = this.setScrollCursor(0) || success; - } - break; + success = this.setCursor(0); + success = this.setScrollCursor(0) || success; + } + break; } } @@ -186,8 +187,8 @@ export default class RunHistoryUiHandler extends MessageUiHandler { const emptyWindow = addWindow(this.scene, 0, 0, 304, 165); this.runsContainer.add(emptyWindow); const emptyWindowCoordinates = emptyWindow.getCenter(); - const emptyText = addTextObject(this.scene, 0, 0, i18next.t("saveSlotSelectUiHandler:empty"), TextStyle.WINDOW, {fontSize: "128px"}); - emptyText.setPosition(emptyWindowCoordinates.x-18, emptyWindowCoordinates.y-15); + const emptyText = addTextObject(this.scene, 0, 0, i18next.t("saveSlotSelectUiHandler:empty"), TextStyle.WINDOW, { fontSize: "128px" }); + emptyText.setPosition(emptyWindowCoordinates.x - 18, emptyWindowCoordinates.y - 15); this.runsContainer.add(emptyText); } @@ -255,7 +256,7 @@ class RunEntryContainer extends Phaser.GameObjects.Container { public entryData: RunEntry; constructor(scene: BattleScene, entryData: RunEntry, slotId: number) { - super(scene, 0, slotId*56); + super(scene, 0, slotId * 56); this.slotId = slotId; this.entryData = entryData; @@ -295,7 +296,7 @@ class RunEntryContainer extends Phaser.GameObjects.Container { const gameOutcomeLabel = addTextObject(this.scene, 0, 0, `${i18next.t("runHistory:defeatedWild", { context: genderStr })}`, TextStyle.WINDOW); enemyContainer.add(gameOutcomeLabel); data.enemyParty.forEach((enemyData, e) => { - const enemyIconContainer = this.scene.add.container(65+(e*25), -8); + const enemyIconContainer = this.scene.add.container(65 + (e * 25), -8); enemyIconContainer.setScale(0.75); enemyData.boss = false; enemyData["player"] = true; @@ -332,33 +333,33 @@ class RunEntryContainer extends Phaser.GameObjects.Container { const gameModeLabel = addTextObject(this.scene, 8, 19, "", TextStyle.WINDOW); let mode = ""; switch (data.gameMode) { - case GameModes.DAILY: - mode = i18next.t("gameMode:dailyRun"); - break; - case GameModes.SPLICED_ENDLESS: - case GameModes.ENDLESS: - mode = i18next.t("gameMode:endless"); - break; - case GameModes.CLASSIC: - mode = i18next.t("gameMode:classic"); - break; - case GameModes.CHALLENGE: - mode = i18next.t("gameMode:challenge"); - break; + case GameModes.DAILY: + mode = i18next.t("gameMode:dailyRun"); + break; + case GameModes.SPLICED_ENDLESS: + case GameModes.ENDLESS: + mode = i18next.t("gameMode:endless"); + break; + case GameModes.CLASSIC: + mode = i18next.t("gameMode:classic"); + break; + case GameModes.CHALLENGE: + mode = i18next.t("gameMode:challenge"); + break; } gameModeLabel.appendText(mode, false); if (data.gameMode === GameModes.SPLICED_ENDLESS) { const splicedIcon = this.scene.add.image(0, 0, "icon_spliced"); splicedIcon.setScale(0.75); const coords = gameModeLabel.getTopRight(); - splicedIcon.setPosition(coords.x+5, 27); + splicedIcon.setPosition(coords.x + 5, 27); this.add(splicedIcon); // 4 spaces of room for the Spliced icon gameModeLabel.appendText(" - ", false); } else { gameModeLabel.appendText(" - ", false); } - gameModeLabel.appendText(i18next.t("saveSlotSelectUiHandler:wave")+" "+data.waveIndex, false); + gameModeLabel.appendText(i18next.t("saveSlotSelectUiHandler:wave") + " " + data.waveIndex, false); this.add(gameModeLabel); const timestampLabel = addTextObject(this.scene, 8, 33, new Date(data.timestamp).toLocaleString(), TextStyle.WINDOW); diff --git a/src/ui/run-info-ui-handler.ts b/src/ui/run-info-ui-handler.ts index b4e4ad1130d..0ca47241136 100644 --- a/src/ui/run-info-ui-handler.ts +++ b/src/ui/run-info-ui-handler.ts @@ -5,10 +5,11 @@ import { SessionSaveData } from "../system/game-data"; import { TextStyle, addTextObject, addBBCodeTextObject, getTextColor } from "./text"; import { Mode } from "./ui"; import { addWindow } from "./ui-theme"; +import { getPokeballAtlasKey } from "#app/data/pokeball"; import * as Utils from "../utils"; import PokemonData from "../system/pokemon-data"; import i18next from "i18next"; -import {Button} from "../enums/buttons"; +import { Button } from "../enums/buttons"; import { BattleType } from "../battle"; import { TrainerVariant } from "../field/trainer"; import { Challenges } from "#enums/challenges"; @@ -22,6 +23,8 @@ import * as Modifier from "../modifier/modifier"; import { Species } from "#enums/species"; import { PlayerGender } from "#enums/player-gender"; import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; +import { getBiomeName } from "#app/data/balance/biomes"; +import { MysteryEncounterType } from "#enums/mystery-encounter-type"; /** * RunInfoUiMode indicates possible overlays of RunInfoUiHandler. @@ -34,6 +37,11 @@ enum RunInfoUiMode { ENDING_ART } +export enum RunDisplayMode { + RUN_HISTORY, + SESSION_PREVIEW +} + /** * Some variables are protected because this UI class will most likely be extended in the future to display more information. * These variables will most likely be shared across 'classes' aka pages. @@ -41,6 +49,7 @@ enum RunInfoUiMode { * For now, I leave as is. */ export default class RunInfoUiHandler extends UiHandler { + protected runDisplayMode: RunDisplayMode; protected runInfo: SessionSaveData; protected isVictory: boolean; protected pageMode: RunInfoUiMode; @@ -66,6 +75,7 @@ export default class RunInfoUiHandler extends UiHandler { // The import of the modifiersModule is loaded here to sidestep async/await issues. this.modifiersModule = Modifier; this.runContainer.setVisible(false); + this.scene.loadImage("encounter_exclaim", "mystery-encounters"); } /** @@ -87,9 +97,15 @@ export default class RunInfoUiHandler extends UiHandler { this.runContainer.add(gameStatsBg); const run = args[0]; + this.runDisplayMode = args[1]; + if (this.runDisplayMode === RunDisplayMode.RUN_HISTORY) { + this.runInfo = this.scene.gameData.parseSessionData(JSON.stringify(run.entry)); + this.isVictory = run.isVictory ?? false; + } else if (this.runDisplayMode === RunDisplayMode.SESSION_PREVIEW) { + this.runInfo = args[0]; + } // Assigning information necessary for the UI's creation - this.runInfo = this.scene.gameData.parseSessionData(JSON.stringify(run.entry)); - this.isVictory = run.isVictory; + this.pageMode = RunInfoUiMode.MAIN; // Creates Header and adds to this.runContainer @@ -99,20 +115,24 @@ export default class RunInfoUiHandler extends UiHandler { // Creates Run Result Container this.runResultContainer = this.scene.add.container(0, 24); - const runResultWindow = addWindow(this.scene, 0, 0, this.statsBgWidth-11, 65); + const runResultWindow = addWindow(this.scene, 0, 0, this.statsBgWidth - 11, 65); runResultWindow.setOrigin(0, 0); this.runResultContainer.add(runResultWindow); - this.parseRunResult(); + if (this.runDisplayMode === RunDisplayMode.RUN_HISTORY) { + this.parseRunResult(); + } else if (this.runDisplayMode === RunDisplayMode.SESSION_PREVIEW) { + this.parseRunStatus(); + } // Creates Run Info Container this.runInfoContainer = this.scene.add.container(0, 89); - const runInfoWindow = addWindow(this.scene, 0, 0, this.statsBgWidth-11, 90); + const runInfoWindow = addWindow(this.scene, 0, 0, this.statsBgWidth - 11, 90); const runInfoWindowCoords = runInfoWindow.getBottomRight(); this.runInfoContainer.add(runInfoWindow); this.parseRunInfo(runInfoWindowCoords.x, runInfoWindowCoords.y); // Creates Player Party Container - this.partyContainer = this.scene.add.container(this.statsBgWidth-10, 23); + this.partyContainer = this.scene.add.container(this.statsBgWidth - 10, 23); this.parsePartyInfo(); this.showParty(true); @@ -147,7 +167,7 @@ export default class RunInfoUiHandler extends UiHandler { if (this.runInfo.modifiers.length !== 0) { const headerBgCoords = headerBg.getTopRight(); const abilityButtonContainer = this.scene.add.container(0, 0); - const abilityButtonText = addTextObject(this.scene, 8, 0, i18next.t("runHistory:viewHeldItems"), TextStyle.WINDOW, {fontSize:"34px"}); + const abilityButtonText = addTextObject(this.scene, 8, 0, i18next.t("runHistory:viewHeldItems"), TextStyle.WINDOW, { fontSize:"34px" }); const gamepadType = this.getUi().getGamepadType(); let abilityButtonElement: Phaser.GameObjects.Sprite; if (gamepadType === "touch") { @@ -155,7 +175,7 @@ export default class RunInfoUiHandler extends UiHandler { } else { abilityButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 2, gamepadType, this.scene.inputController?.getIconForLatestInputRecorded(SettingKeyboard.Button_Cycle_Ability)); } - abilityButtonContainer.add([abilityButtonText, abilityButtonElement]); + abilityButtonContainer.add([ abilityButtonText, abilityButtonElement ]); abilityButtonContainer.setPosition(headerBgCoords.x - abilityButtonText.displayWidth - abilityButtonElement.displayWidth - 8, 10); this.runContainer.add(abilityButtonContainer); } @@ -178,12 +198,12 @@ export default class RunInfoUiHandler extends UiHandler { const genderStr = PlayerGender[genderIndex]; const runResultTextStyle = this.isVictory ? TextStyle.PERFECT_IV : TextStyle.SUMMARY_RED; const runResultTitle = this.isVictory ? i18next.t("runHistory:victory") : i18next.t("runHistory:defeated", { context: genderStr }); - const runResultText = addTextObject(this.scene, 6, 5, `${runResultTitle} - ${i18next.t("saveSlotSelectUiHandler:wave")} ${this.runInfo.waveIndex}`, runResultTextStyle, {fontSize : "65px", lineSpacing: 0.1}); + const runResultText = addTextObject(this.scene, 6, 5, `${runResultTitle} - ${i18next.t("saveSlotSelectUiHandler:wave")} ${this.runInfo.waveIndex}`, runResultTextStyle, { fontSize : "65px", lineSpacing: 0.1 }); if (this.isVictory) { const hallofFameInstructionContainer = this.scene.add.container(0, 0); - const shinyButtonText = addTextObject(this.scene, 8, 0, i18next.t("runHistory:viewHallOfFame"), TextStyle.WINDOW, {fontSize:"65px"}); - const formButtonText = addTextObject(this.scene, 8, 12, i18next.t("runHistory:viewEndingSplash"), TextStyle.WINDOW, {fontSize:"65px"}); + const shinyButtonText = addTextObject(this.scene, 8, 0, i18next.t("runHistory:viewHallOfFame"), TextStyle.WINDOW, { fontSize:"65px" }); + const formButtonText = addTextObject(this.scene, 8, 12, i18next.t("runHistory:viewEndingSplash"), TextStyle.WINDOW, { fontSize:"65px" }); const gamepadType = this.getUi().getGamepadType(); let shinyButtonElement: Phaser.GameObjects.Sprite; let formButtonElement: Phaser.GameObjects.Sprite; @@ -194,9 +214,9 @@ export default class RunInfoUiHandler extends UiHandler { shinyButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 4, gamepadType, this.scene.inputController?.getIconForLatestInputRecorded(SettingKeyboard.Button_Cycle_Shiny)); formButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 16, gamepadType, this.scene.inputController?.getIconForLatestInputRecorded(SettingKeyboard.Button_Cycle_Form)); } - hallofFameInstructionContainer.add([shinyButtonText, shinyButtonElement]); + hallofFameInstructionContainer.add([ shinyButtonText, shinyButtonElement ]); - hallofFameInstructionContainer.add([formButtonText, formButtonElement]); + hallofFameInstructionContainer.add([ formButtonText, formButtonElement ]); hallofFameInstructionContainer.setPosition(12, 25); this.runResultContainer.add(hallofFameInstructionContainer); @@ -209,14 +229,14 @@ export default class RunInfoUiHandler extends UiHandler { // Wild - Single and Doubles if (this.runInfo.battleType === BattleType.WILD || (this.runInfo.battleType === BattleType.MYSTERY_ENCOUNTER && !this.runInfo.trainer)) { switch (this.runInfo.enemyParty.length) { - case 1: + case 1: // Wild - Singles - this.parseWildSingleDefeat(enemyContainer); - break; - case 2: + this.parseWildSingleDefeat(enemyContainer); + break; + case 2: //Wild - Doubles - this.parseWildDoubleDefeat(enemyContainer); - break; + this.parseWildDoubleDefeat(enemyContainer); + break; } } else if (this.runInfo.battleType === BattleType.TRAINER || (this.runInfo.battleType === BattleType.MYSTERY_ENCOUNTER && this.runInfo.trainer)) { this.parseTrainerDefeat(enemyContainer); @@ -226,6 +246,66 @@ export default class RunInfoUiHandler extends UiHandler { this.runContainer.add(this.runResultContainer); } + /** + * This function is used when the Run Info UI is used to preview a Session. + * It edits {@linkcode runResultContainer}, but most importantly - does not display the negative results of a Mystery Encounter or any details of a trainer's party. + * Trainer Parties are replaced with their sprites, names, and their party size. + * Mystery Encounters contain sprites associated with MEs + the title of the specific ME. + */ + private parseRunStatus() { + const runStatusText = addTextObject(this.scene, 6, 5, `${i18next.t("saveSlotSelectUiHandler:wave")} ${this.runInfo.waveIndex} - ${getBiomeName(this.runInfo.arena.biome)}`, TextStyle.WINDOW, { fontSize : "65px", lineSpacing: 0.1 }); + + const enemyContainer = this.scene.add.container(0, 0); + this.runResultContainer.add(enemyContainer); + if (this.runInfo.battleType === BattleType.WILD) { + if (this.runInfo.enemyParty.length === 1) { + this.parseWildSingleDefeat(enemyContainer); + } else if (this.runInfo.enemyParty.length === 2) { + this.parseWildDoubleDefeat(enemyContainer); + } + } else if (this.runInfo.battleType === BattleType.TRAINER) { + this.showTrainerSprites(enemyContainer); + const row_limit = 3; + this.runInfo.enemyParty.forEach((p, i) => { + const pokeball = this.scene.add.sprite(0, 0, "pb"); + pokeball.setFrame(getPokeballAtlasKey(p.pokeball)); + pokeball.setScale(0.5); + pokeball.setPosition(52 + ((i % row_limit) * 8), (i <= 2) ? 18 : 25); + enemyContainer.add(pokeball); + }); + const trainerObj = this.runInfo.trainer.toTrainer(this.scene); + const RIVAL_TRAINER_ID_THRESHOLD = 375; + let trainerName = ""; + if (this.runInfo.trainer.trainerType >= RIVAL_TRAINER_ID_THRESHOLD) { + trainerName = (trainerObj.variant === TrainerVariant.FEMALE) ? i18next.t("trainerNames:rival_female") : i18next.t("trainerNames:rival"); + } else { + trainerName = trainerObj.getName(0, true); + } + const boxString = i18next.t(trainerObj.variant !== TrainerVariant.DOUBLE ? "battle:trainerAppeared" : "battle:trainerAppearedDouble", { trainerName: trainerName }).replace(/\n/g, " "); + const descContainer = this.scene.add.container(0, 0); + const textBox = addTextObject(this.scene, 0, 0, boxString, TextStyle.WINDOW, { fontSize : "35px", wordWrap: { width: 200 }}); + descContainer.add(textBox); + descContainer.setPosition(52, 29); + this.runResultContainer.add(descContainer); + } else if (this.runInfo.battleType === BattleType.MYSTERY_ENCOUNTER) { + const encounterExclaim = this.scene.add.sprite(0, 0, "encounter_exclaim"); + encounterExclaim.setPosition(34, 26); + encounterExclaim.setScale(0.65); + const subSprite = this.scene.add.sprite(56, -106, "pkmn__sub"); + subSprite.setScale(0.65); + subSprite.setPosition(34, 46); + const mysteryEncounterTitle = i18next.t(this.scene.getMysteryEncounter(this.runInfo.mysteryEncounterType as MysteryEncounterType, true).localizationKey + ":title"); + const descContainer = this.scene.add.container(0, 0); + const textBox = addTextObject(this.scene, 0, 0, mysteryEncounterTitle, TextStyle.WINDOW, { fontSize : "45px", wordWrap: { width: 160 }}); + descContainer.add(textBox); + descContainer.setPosition(47, 37); + this.runResultContainer.add([ encounterExclaim, subSprite, descContainer ]); + } + + this.runResultContainer.add(runStatusText); + this.runContainer.add(this.runResultContainer); + } + /** * This function is called to edit an enemyContainer to represent a loss from a defeat by a wild single Pokemon battle. * @param enemyContainer - container holding enemy visual and level information @@ -270,7 +350,7 @@ export default class RunInfoUiHandler extends UiHandler { enemyLevel.setOrigin(1, 0); enemyIconContainer.add(enemyIcon); enemyIconContainer.add(enemyLevel); - enemyIconContainer.setPosition(e*35, 0); + enemyIconContainer.setPosition(e * 35, 0); enemyContainer.add(enemyIconContainer); enemy.destroy(); }); @@ -278,40 +358,58 @@ export default class RunInfoUiHandler extends UiHandler { } /** - * This edits a container to represent a loss from a defeat by a trainer battle. - * @param enemyContainer - container holding enemy visuals and level information - * The trainers are placed to the left of their party. - * Depending on the trainer icon, there may be overlap between the edges of the box or their party. (Capes...) - * - * Party Pokemon have their icons, terastalization status, and level shown. + * This loads the enemy sprites, positions, and scales them according to the current display mode of the RunInfo UI and then adds them to the container parameter. + * Used by {@linkcode parseRunStatus} and {@linkcode parseTrainerDefeat} + * @param enemyContainer a Phaser Container that should hold enemy sprites */ - private parseTrainerDefeat(enemyContainer: Phaser.GameObjects.Container) { + private showTrainerSprites(enemyContainer: Phaser.GameObjects.Container) { // Creating the trainer sprite and adding it to enemyContainer const tObj = this.runInfo.trainer.toTrainer(this.scene); - // Loads trainer assets on demand, as they are not loaded by default in the scene tObj.config.loadAssets(this.scene, this.runInfo.trainer.variant).then(() => { const tObjSpriteKey = tObj.config.getSpriteKey(this.runInfo.trainer.variant === TrainerVariant.FEMALE, false); const tObjSprite = this.scene.add.sprite(0, 5, tObjSpriteKey); - if (this.runInfo.trainer.variant === TrainerVariant.DOUBLE) { + if (this.runInfo.trainer.variant === TrainerVariant.DOUBLE && !tObj.config.doubleOnly) { const doubleContainer = this.scene.add.container(5, 8); tObjSprite.setPosition(-3, -3); const tObjPartnerSpriteKey = tObj.config.getSpriteKey(true, true); const tObjPartnerSprite = this.scene.add.sprite(5, -3, tObjPartnerSpriteKey); // Double Trainers have smaller sprites than Single Trainers - tObjPartnerSprite.setScale(0.20); - tObjSprite.setScale(0.20); - doubleContainer.add(tObjSprite); - doubleContainer.add(tObjPartnerSprite); - doubleContainer.setPosition(12, 38); + if (this.runDisplayMode === RunDisplayMode.RUN_HISTORY) { + tObjPartnerSprite.setScale(0.20); + tObjSprite.setScale(0.20); + doubleContainer.add(tObjSprite); + doubleContainer.add(tObjPartnerSprite); + doubleContainer.setPosition(12, 38); + } else { + tObjSprite.setScale(0.55); + tObjSprite.setPosition(-9, -3); + tObjPartnerSprite.setScale(0.55); + doubleContainer.add([ tObjSprite, tObjPartnerSprite ]); + doubleContainer.setPosition(28, 40); + } enemyContainer.add(doubleContainer); } else { - tObjSprite.setScale(0.35, 0.35); - tObjSprite.setPosition(12, 28); + const scale = (this.runDisplayMode === RunDisplayMode.RUN_HISTORY) ? 0.35 : 0.65; + const position = (this.runDisplayMode === RunDisplayMode.RUN_HISTORY) ? [ 12, 28 ] : [ 32, 36 ]; + tObjSprite.setScale(scale, scale); + tObjSprite.setPosition(position[0], position[1]); enemyContainer.add(tObjSprite); } }); + } + /** + * This edits a container to represent a loss from a defeat by a trainer battle. + * The trainers are placed to the left of their party. + * Depending on the trainer icon, there may be overlap between the edges of the box or their party. (Capes...) + * + * Party Pokemon have their icons, terastalization status, and level shown. + * @param enemyContainer - container holding enemy visuals and level information + */ + private parseTrainerDefeat(enemyContainer: Phaser.GameObjects.Container) { + // Loads and adds trainer sprites to the UI + this.showTrainerSprites(enemyContainer); // Determining which Terastallize Modifier belongs to which Pokemon // Creates a dictionary {PokemonId: TeraShardType} const teraPokemon = {}; @@ -328,7 +426,7 @@ export default class RunInfoUiHandler extends UiHandler { // 2 Rows x 3 Columns const enemyPartyContainer = this.scene.add.container(0, 0); this.runInfo.enemyParty.forEach((enemyData, e) => { - const pokemonRowHeight = Math.floor(e/3); + const pokemonRowHeight = Math.floor(e / 3); const enemyIconContainer = this.scene.add.container(0, 0); enemyIconContainer.setScale(0.6); const isBoss = enemyData.boss; @@ -348,8 +446,8 @@ export default class RunInfoUiHandler extends UiHandler { enemySprite2.setTint(teraColor.color); } } - enemyIcon.setPosition(39*(e%3)+5, (35*pokemonRowHeight)); - const enemyLevel = addTextObject(this.scene, 43*(e%3), (27*(pokemonRowHeight+1)), `${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`, isBoss ? TextStyle.PARTY_RED : TextStyle.PARTY, { fontSize: "54px" }); + enemyIcon.setPosition(39 * (e % 3) + 5, (35 * pokemonRowHeight)); + const enemyLevel = addTextObject(this.scene, 43 * (e % 3), (27 * (pokemonRowHeight + 1)), `${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`, isBoss ? TextStyle.PARTY_RED : TextStyle.PARTY, { fontSize: "54px" }); enemyLevel.setShadow(0, 0, undefined); enemyLevel.setStroke("#424242", 14); enemyLevel.setOrigin(0, 0); @@ -372,37 +470,37 @@ export default class RunInfoUiHandler extends UiHandler { private async parseRunInfo(windowX: number, windowY: number) { // Parsing and displaying the mode. // In the future, parsing Challenges + Challenge Rules may have to be reworked as PokeRogue adds additional challenges and users can stack these challenges in various ways. - const modeText = addBBCodeTextObject(this.scene, 7, 0, "", TextStyle.WINDOW, {fontSize : "50px", lineSpacing:3}); + const modeText = addBBCodeTextObject(this.scene, 7, 0, "", TextStyle.WINDOW, { fontSize : "50px", lineSpacing:3 }); modeText.setPosition(7, 5); - modeText.appendText(i18next.t("runHistory:mode")+": ", false); + modeText.appendText(i18next.t("runHistory:mode") + ": ", false); switch (this.runInfo.gameMode) { - case GameModes.DAILY: - modeText.appendText(`${i18next.t("gameMode:dailyRun")}`, false); - break; - case GameModes.SPLICED_ENDLESS: - modeText.appendText(`${i18next.t("gameMode:endlessSpliced")}`, false); - break; - case GameModes.CHALLENGE: - modeText.appendText(`${i18next.t("gameMode:challenge")}`, false); - modeText.appendText(`${i18next.t("runHistory:challengeRules")}: `); - modeText.setWrapMode(1); // wrap by word - modeText.setWrapWidth(500); - const rules: string[] = this.challengeParser(); - if (rules) { - for (let i = 0; i < rules.length; i++) { - if (i > 0) { - modeText.appendText(" + ", false); + case GameModes.DAILY: + modeText.appendText(`${i18next.t("gameMode:dailyRun")}`, false); + break; + case GameModes.SPLICED_ENDLESS: + modeText.appendText(`${i18next.t("gameMode:endlessSpliced")}`, false); + break; + case GameModes.CHALLENGE: + modeText.appendText(`${i18next.t("gameMode:challenge")}`, false); + modeText.appendText(`${i18next.t("runHistory:challengeRules")}: `); + modeText.setWrapMode(1); // wrap by word + modeText.setWrapWidth(500); + const rules: string[] = this.challengeParser(); + if (rules) { + for (let i = 0; i < rules.length; i++) { + if (i > 0) { + modeText.appendText(" + ", false); + } + modeText.appendText(rules[i], false); } - modeText.appendText(rules[i], false); } - } - break; - case GameModes.ENDLESS: - modeText.appendText(`${i18next.t("gameMode:endless")}`, false); - break; - case GameModes.CLASSIC: - modeText.appendText(`${i18next.t("gameMode:classic")}`, false); - break; + break; + case GameModes.ENDLESS: + modeText.appendText(`${i18next.t("gameMode:endless")}`, false); + break; + case GameModes.CLASSIC: + modeText.appendText(`${i18next.t("gameMode:classic")}`, false); + break; } // If the player achieves a personal best in Endless, the mode text will be tinted similarly to SSS luck to celebrate their achievement. @@ -415,25 +513,25 @@ export default class RunInfoUiHandler extends UiHandler { const runInfoTextContainer = this.scene.add.container(0, 0); // Japanese is set to a greater line spacing of 35px in addBBCodeTextObject() if lineSpacing < 12. const lineSpacing = (i18next.resolvedLanguage === "ja") ? 12 : 3; - const runInfoText = addBBCodeTextObject(this.scene, 7, 0, "", TextStyle.WINDOW, {fontSize: "50px", lineSpacing: lineSpacing}); + const runInfoText = addBBCodeTextObject(this.scene, 7, 0, "", TextStyle.WINDOW, { fontSize: "50px", lineSpacing: lineSpacing }); const runTime = Utils.getPlayTimeString(this.runInfo.playTime); runInfoText.appendText(`${i18next.t("runHistory:runLength")}: ${runTime}`, false); const runMoney = Utils.formatMoney(this.scene.moneyFormat, this.runInfo.money); - runInfoText.appendText(`[color=${getTextColor(TextStyle.MONEY)}]${i18next.t("battleScene:moneyOwned", {formattedMoney : runMoney})}[/color]`); + runInfoText.appendText(`[color=${getTextColor(TextStyle.MONEY)}]${i18next.t("battleScene:moneyOwned", { formattedMoney : runMoney })}[/color]`); runInfoText.setPosition(7, 70); runInfoTextContainer.add(runInfoText); // Luck // Uses the parameters windowX and windowY to dynamically position the luck value neatly into the bottom right corner - const luckText = addBBCodeTextObject(this.scene, 0, 0, "", TextStyle.WINDOW, {fontSize: "55px"}); + const luckText = addBBCodeTextObject(this.scene, 0, 0, "", TextStyle.WINDOW, { fontSize: "55px" }); const luckValue = Phaser.Math.Clamp(this.runInfo.party.map(p => p.toPokemon(this.scene).getLuck()).reduce((total: integer, value: integer) => total += value, 0), 0, 14); - let luckInfo = i18next.t("runHistory:luck")+": "+getLuckString(luckValue); + let luckInfo = i18next.t("runHistory:luck") + ": " + getLuckString(luckValue); if (luckValue < 14) { - luckInfo = "[color=#"+(getLuckTextTint(luckValue)).toString(16)+"]"+luckInfo+"[/color]"; + luckInfo = "[color=#" + (getLuckTextTint(luckValue)).toString(16) + "]" + luckInfo + "[/color]"; } else { luckText.setTint(0xffef5c, 0x47ff69, 0x6b6bff, 0xff6969); } - luckText.appendText("[align=right]"+luckInfo+"[/align]", false); - luckText.setPosition(windowX-luckText.displayWidth-5, windowY-13); + luckText.appendText("[align=right]" + luckInfo + "[/align]", false); + luckText.setPosition(windowX - luckText.displayWidth - 5, windowY - 13); runInfoTextContainer.add(luckText); // Player Held Items @@ -450,8 +548,8 @@ export default class RunInfoUiHandler extends UiHandler { } const icon = modifier?.getIcon(this.scene, false); if (icon) { - const rowHeightModifier = Math.floor(visibleModifierIndex/7); - icon.setPosition(24 * (visibleModifierIndex%7), 20 + (35 * rowHeightModifier)); + const rowHeightModifier = Math.floor(visibleModifierIndex / 7); + icon.setPosition(24 * (visibleModifierIndex % 7), 20 + (35 * rowHeightModifier)); modifierIconsContainer.add(icon); } @@ -479,23 +577,23 @@ export default class RunInfoUiHandler extends UiHandler { for (let i = 0; i < this.runInfo.challenges.length; i++) { if (this.runInfo.challenges[i].value !== 0) { switch (this.runInfo.challenges[i].id) { - case Challenges.SINGLE_GENERATION: - rules.push(i18next.t(`runHistory:challengeMonoGen${this.runInfo.challenges[i].value}`)); - break; - case Challenges.SINGLE_TYPE: - const typeRule = Type[this.runInfo.challenges[i].value-1]; - const typeTextColor = `[color=${TypeColor[typeRule]}]`; - const typeShadowColor = `[shadow=${TypeShadow[typeRule]}]`; - const typeText = typeTextColor + typeShadowColor + i18next.t(`pokemonInfo:Type.${typeRule}`)!+"[/color]"+"[/shadow]"; - rules.push(typeText); - break; - case Challenges.FRESH_START: - rules.push(i18next.t("challenges:freshStart.name")); - break; - case Challenges.INVERSE_BATTLE: - // - rules.push(i18next.t("challenges:inverseBattle.shortName")); - break; + case Challenges.SINGLE_GENERATION: + rules.push(i18next.t(`runHistory:challengeMonoGen${this.runInfo.challenges[i].value}`)); + break; + case Challenges.SINGLE_TYPE: + const typeRule = Type[this.runInfo.challenges[i].value - 1]; + const typeTextColor = `[color=${TypeColor[typeRule]}]`; + const typeShadowColor = `[shadow=${TypeShadow[typeRule]}]`; + const typeText = typeTextColor + typeShadowColor + i18next.t(`pokemonInfo:Type.${typeRule}`)! + "[/color]" + "[/shadow]"; + rules.push(typeText); + break; + case Challenges.INVERSE_BATTLE: + rules.push(i18next.t("challenges:inverseBattle.shortName")); + break; + default: + const localisationKey = Challenges[this.runInfo.challenges[i].id].split("_").map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); + rules.push(i18next.t(`challenges:${localisationKey}.name`)); + break; } } } @@ -510,13 +608,13 @@ export default class RunInfoUiHandler extends UiHandler { private parsePartyInfo(): void { const party = this.runInfo.party; const currentLanguage = i18next.resolvedLanguage ?? "en"; - const windowHeight = ((this.scene.game.canvas.height / 6) - 23)/6; + const windowHeight = ((this.scene.game.canvas.height / 6) - 23) / 6; party.forEach((p: PokemonData, i: integer) => { - const pokemonInfoWindow = new RoundRectangle(this.scene, 0, 14, (this.statsBgWidth*2)+10, windowHeight-2, 3); + const pokemonInfoWindow = new RoundRectangle(this.scene, 0, 14, (this.statsBgWidth * 2) + 10, windowHeight - 2, 3); const pokemon = p.toPokemon(this.scene); - const pokemonInfoContainer = this.scene.add.container(this.statsBgWidth+5, (windowHeight-0.5)*i); + const pokemonInfoContainer = this.scene.add.container(this.statsBgWidth + 5, (windowHeight - 0.5) * i); const types = pokemon.getTypes(); const type1 = getTypeRgb(types[0]); @@ -544,18 +642,18 @@ export default class RunInfoUiHandler extends UiHandler { const pName = pokemon.getNameToRender(); //With the exception of Korean/Traditional Chinese/Simplified Chinese, the code shortens the terms for ability and passive to their first letter. //These languages are exempted because they are already short enough. - const exemptedLanguages = ["ko", "zh_CN", "zh_TW"]; + const exemptedLanguages = [ "ko", "zh_CN", "zh_TW" ]; let passiveLabel = i18next.t("starterSelectUiHandler:passive") ?? "-"; let abilityLabel = i18next.t("starterSelectUiHandler:ability") ?? "-"; if (!exemptedLanguages.includes(currentLanguage)) { passiveLabel = passiveLabel.charAt(0); abilityLabel = abilityLabel.charAt(0); } - const pPassiveInfo = pokemon.passive ? passiveLabel+": "+pokemon.getPassiveAbility().name : ""; + const pPassiveInfo = pokemon.passive ? passiveLabel + ": " + pokemon.getPassiveAbility().name : ""; const pAbilityInfo = abilityLabel + ": " + pokemon.getAbility().name; // Japanese is set to a greater line spacing of 35px in addBBCodeTextObject() if lineSpacing < 12. const lineSpacing = (i18next.resolvedLanguage === "ja") ? 12 : 3; - const pokeInfoText = addBBCodeTextObject(this.scene, 0, 0, pName, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing: lineSpacing}); + const pokeInfoText = addBBCodeTextObject(this.scene, 0, 0, pName, TextStyle.SUMMARY, { fontSize: textContainerFontSize, lineSpacing: lineSpacing }); pokeInfoText.appendText(`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatFancyLargeNumber(pokemon.level, 1)} - ${pNatureName}`); pokeInfoText.appendText(pAbilityInfo); pokeInfoText.appendText(pPassiveInfo); @@ -564,27 +662,27 @@ export default class RunInfoUiHandler extends UiHandler { // Pokemon Stats // Colored Arrows (Red/Blue) are placed by stats that are boosted from natures const pokeStatTextContainer = this.scene.add.container(-35, 6); - const pStats : string[]= []; + const pStats : string[] = []; pokemon.stats.forEach((element) => pStats.push(Utils.formatFancyLargeNumber(element, 1))); for (let i = 0; i < pStats.length; i++) { const isMult = getNatureStatMultiplier(pNature, i); pStats[i] = (isMult < 1) ? pStats[i] + "[color=#40c8f8]↓[/color]" : pStats[i]; pStats[i] = (isMult > 1) ? pStats[i] + "[color=#f89890]↑[/color]" : pStats[i]; } - const hp = i18next.t("pokemonInfo:Stat.HPshortened")+": "+pStats[0]; - const atk = i18next.t("pokemonInfo:Stat.ATKshortened")+": "+pStats[1]; - const def = i18next.t("pokemonInfo:Stat.DEFshortened")+": "+pStats[2]; - const spatk = i18next.t("pokemonInfo:Stat.SPATKshortened")+": "+pStats[3]; - const spdef = i18next.t("pokemonInfo:Stat.SPDEFshortened")+": "+pStats[4]; - const speedLabel = (currentLanguage==="es"||currentLanguage==="pt_BR") ? i18next.t("runHistory:SPDshortened") : i18next.t("pokemonInfo:Stat.SPDshortened"); - const speed = speedLabel+": "+pStats[5]; + const hp = i18next.t("pokemonInfo:Stat.HPshortened") + ": " + pStats[0]; + const atk = i18next.t("pokemonInfo:Stat.ATKshortened") + ": " + pStats[1]; + const def = i18next.t("pokemonInfo:Stat.DEFshortened") + ": " + pStats[2]; + const spatk = i18next.t("pokemonInfo:Stat.SPATKshortened") + ": " + pStats[3]; + const spdef = i18next.t("pokemonInfo:Stat.SPDEFshortened") + ": " + pStats[4]; + const speedLabel = (currentLanguage === "es" || currentLanguage === "pt_BR") ? i18next.t("runHistory:SPDshortened") : i18next.t("pokemonInfo:Stat.SPDshortened"); + const speed = speedLabel + ": " + pStats[5]; // Column 1: HP Atk Def - const pokeStatText1 = addBBCodeTextObject(this.scene, -5, 0, hp, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing: lineSpacing}); + const pokeStatText1 = addBBCodeTextObject(this.scene, -5, 0, hp, TextStyle.SUMMARY, { fontSize: textContainerFontSize, lineSpacing: lineSpacing }); pokeStatText1.appendText(atk); pokeStatText1.appendText(def); pokeStatTextContainer.add(pokeStatText1); // Column 2: SpAtk SpDef Speed - const pokeStatText2 = addBBCodeTextObject(this.scene, 25, 0, spatk, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing: lineSpacing}); + const pokeStatText2 = addBBCodeTextObject(this.scene, 25, 0, spatk, TextStyle.SUMMARY, { fontSize: textContainerFontSize, lineSpacing: lineSpacing }); pokeStatText2.appendText(spdef); pokeStatText2.appendText(speed); pokeStatTextContainer.add(pokeStatText2); @@ -612,7 +710,7 @@ export default class RunInfoUiHandler extends UiHandler { const fusionShinyStar = this.scene.add.image(0, 0, "shiny_star_small_2"); fusionShinyStar.setOrigin(0, 0); fusionShinyStar.setScale(0.5); - fusionShinyStar.setPosition(shinyStar.x+1, shinyStar.y+1); + fusionShinyStar.setPosition(shinyStar.x + 1, shinyStar.y + 1); fusionShinyStar.setTint(getVariantTint(pokemon.fusionVariant)); marksContainer.add(fusionShinyStar); this.getUi().bringToTop(fusionShinyStar); @@ -625,7 +723,7 @@ export default class RunInfoUiHandler extends UiHandler { const movesetContainer = this.scene.add.container(70, -29); const pokemonMoveBgs : Phaser.GameObjects.NineSlice[] = []; const pokemonMoveLabels : Phaser.GameObjects.Text[] = []; - const movePos = [[-6.5, 35.5], [37, 35.5], [-6.5, 43.5], [37, 43.5]]; + const movePos = [[ -6.5, 35.5 ], [ 37, 35.5 ], [ -6.5, 43.5 ], [ 37, 43.5 ]]; for (let m = 0; m < pokemonMoveset?.length; m++) { const moveContainer = this.scene.add.container(movePos[m][0], movePos[m][1]); moveContainer.setScale(0.5); @@ -660,7 +758,7 @@ export default class RunInfoUiHandler extends UiHandler { if (heldItemsList.length > 0) { (heldItemsList as Modifier.PokemonHeldItemModifier[]).sort(Modifier.modifierSortFunc); let row = 0; - for (const [index, item] of heldItemsList.entries()) { + for (const [ index, item ] of heldItemsList.entries()) { if ( index > 36 ) { const overflowIcon = addTextObject(this.scene, 182, 4, "+", TextStyle.WINDOW); heldItemsContainer.add(overflowIcon); @@ -671,7 +769,7 @@ export default class RunInfoUiHandler extends UiHandler { itemIcon.list[1].clearTint(); } itemIcon.setScale(heldItemsScale); - itemIcon.setPosition((index%19) * 10, row * 10); + itemIcon.setPosition((index % 19) * 10, row * 10); heldItemsContainer.add(itemIcon); if (index !== 0 && index % 18 === 0) { row++; @@ -754,15 +852,15 @@ export default class RunInfoUiHandler extends UiHandler { endCard.setScale(0.5); const endCardCoords = endCard.getBottomCenter(); const overlayColor = isFemale ? "red" : "blue"; - const hallofFameBg = this.scene.add.image(0, 0, "hall_of_fame_"+overlayColor); + const hallofFameBg = this.scene.add.image(0, 0, "hall_of_fame_" + overlayColor); hallofFameBg.setPosition(159, 89); - hallofFameBg.setSize(this.scene.game.canvas.width, this.scene.game.canvas.height+10); + hallofFameBg.setSize(this.scene.game.canvas.width, this.scene.game.canvas.height + 10); hallofFameBg.setAlpha(0.8); this.hallofFameContainer.add(endCard); this.hallofFameContainer.add(hallofFameBg); const hallofFameText = addTextObject(this.scene, 0, 0, i18next.t("runHistory:hallofFameText", { context: genderStr }), TextStyle.WINDOW); - hallofFameText.setPosition(endCardCoords.x-(hallofFameText.displayWidth/2), 164); + hallofFameText.setPosition(endCardCoords.x - (hallofFameText.displayWidth / 2), 164); this.hallofFameContainer.add(hallofFameText); this.runInfo.party.forEach((p, i) => { const pkmn = p.toPokemon(this.scene); @@ -813,36 +911,36 @@ export default class RunInfoUiHandler extends UiHandler { const error = false; switch (button) { - case Button.CANCEL: - success = true; - if (this.pageMode === RunInfoUiMode.MAIN) { - this.runInfoContainer.removeAll(true); - this.runResultContainer.removeAll(true); - this.partyContainer.removeAll(true); - this.runContainer.removeAll(true); - if (this.isVictory) { - this.hallofFameContainer.removeAll(true); + case Button.CANCEL: + success = true; + if (this.pageMode === RunInfoUiMode.MAIN) { + this.runInfoContainer.removeAll(true); + this.runResultContainer.removeAll(true); + this.partyContainer.removeAll(true); + this.runContainer.removeAll(true); + if (this.isVictory) { + this.hallofFameContainer.removeAll(true); + } + super.clear(); + this.runContainer.setVisible(false); + ui.revertMode(); + } else if (this.pageMode === RunInfoUiMode.HALL_OF_FAME) { + this.hallofFameContainer.setVisible(false); + this.pageMode = RunInfoUiMode.MAIN; + } else if (this.pageMode === RunInfoUiMode.ENDING_ART) { + this.endCardContainer.setVisible(false); + this.runContainer.remove(this.endCardContainer); + this.pageMode = RunInfoUiMode.MAIN; } - super.clear(); - this.runContainer.setVisible(false); - ui.revertMode(); - } else if (this.pageMode === RunInfoUiMode.HALL_OF_FAME) { - this.hallofFameContainer.setVisible(false); - this.pageMode = RunInfoUiMode.MAIN; - } else if (this.pageMode === RunInfoUiMode.ENDING_ART) { - this.endCardContainer.setVisible(false); - this.runContainer.remove(this.endCardContainer); - this.pageMode = RunInfoUiMode.MAIN; - } - break; - case Button.DOWN: - case Button.UP: - break; - case Button.CYCLE_FORM: - case Button.CYCLE_SHINY: - case Button.CYCLE_ABILITY: - this.buttonCycleOption(button); - break; + break; + case Button.DOWN: + case Button.UP: + break; + case Button.CYCLE_FORM: + case Button.CYCLE_SHINY: + case Button.CYCLE_ABILITY: + this.buttonCycleOption(button); + break; } if (success) { @@ -862,40 +960,40 @@ export default class RunInfoUiHandler extends UiHandler { */ private buttonCycleOption(button: Button) { switch (button) { - case Button.CYCLE_FORM: - if (this.isVictory && this.pageMode !== RunInfoUiMode.HALL_OF_FAME) { - if (!this.endCardContainer || !this.endCardContainer.visible) { - this.createVictorySplash(); - this.endCardContainer.setVisible(true); - this.runContainer.add(this.endCardContainer); - this.pageMode = RunInfoUiMode.ENDING_ART; - } else { - this.endCardContainer.setVisible(false); - this.runContainer.remove(this.endCardContainer); - this.pageMode = RunInfoUiMode.MAIN; + case Button.CYCLE_FORM: + if (this.isVictory && this.pageMode !== RunInfoUiMode.HALL_OF_FAME) { + if (!this.endCardContainer || !this.endCardContainer.visible) { + this.createVictorySplash(); + this.endCardContainer.setVisible(true); + this.runContainer.add(this.endCardContainer); + this.pageMode = RunInfoUiMode.ENDING_ART; + } else { + this.endCardContainer.setVisible(false); + this.runContainer.remove(this.endCardContainer); + this.pageMode = RunInfoUiMode.MAIN; + } } - } - break; - case Button.CYCLE_SHINY: - if (this.isVictory && this.pageMode !== RunInfoUiMode.ENDING_ART) { - if (!this.hallofFameContainer.visible) { - this.hallofFameContainer.setVisible(true); - this.pageMode = RunInfoUiMode.HALL_OF_FAME; - } else { - this.hallofFameContainer.setVisible(false); - this.pageMode = RunInfoUiMode.MAIN; + break; + case Button.CYCLE_SHINY: + if (this.isVictory && this.pageMode !== RunInfoUiMode.ENDING_ART) { + if (!this.hallofFameContainer.visible) { + this.hallofFameContainer.setVisible(true); + this.pageMode = RunInfoUiMode.HALL_OF_FAME; + } else { + this.hallofFameContainer.setVisible(false); + this.pageMode = RunInfoUiMode.MAIN; + } } - } - break; - case Button.CYCLE_ABILITY: - if (this.runInfo.modifiers.length !== 0 && this.pageMode === RunInfoUiMode.MAIN) { - if (this.partyVisibility) { - this.showParty(false); - } else { - this.showParty(true); + break; + case Button.CYCLE_ABILITY: + if (this.runInfo.modifiers.length !== 0 && this.pageMode === RunInfoUiMode.MAIN) { + if (this.partyVisibility) { + this.showParty(false); + } else { + this.showParty(true); + } } - } - break; + break; } } } diff --git a/src/ui/save-slot-select-ui-handler.ts b/src/ui/save-slot-select-ui-handler.ts index 89b20322a68..7bfecb1f99b 100644 --- a/src/ui/save-slot-select-ui-handler.ts +++ b/src/ui/save-slot-select-ui-handler.ts @@ -10,8 +10,10 @@ import MessageUiHandler from "./message-ui-handler"; import { TextStyle, addTextObject } from "./text"; import { Mode } from "./ui"; import { addWindow } from "./ui-theme"; +import { RunDisplayMode } from "#app/ui/run-info-ui-handler"; -const sessionSlotCount = 5; +const SESSION_SLOTS_COUNT = 5; +const SLOTS_ON_SCREEN = 3; export enum SaveSlotUiMode { LOAD, @@ -33,7 +35,7 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { private scrollCursor: integer = 0; - private cursorObj: Phaser.GameObjects.NineSlice | null; + private cursorObj: Phaser.GameObjects.Container | null; private sessionSlotsContainerInitialY: number; @@ -84,9 +86,9 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { this.saveSlotSelectContainer.setVisible(true); this.populateSessionSlots(); + this.setScrollCursor(0); this.setCursor(0); - return true; } @@ -104,40 +106,40 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { error = true; } else { switch (this.uiMode) { - case SaveSlotUiMode.LOAD: - this.saveSlotSelectCallback = null; - originalCallback && originalCallback(cursor); - break; - case SaveSlotUiMode.SAVE: - const saveAndCallback = () => { - const originalCallback = this.saveSlotSelectCallback; + case SaveSlotUiMode.LOAD: this.saveSlotSelectCallback = null; - ui.revertMode(); - ui.showText("", 0); - ui.setMode(Mode.MESSAGE); originalCallback && originalCallback(cursor); - }; - if (this.sessionSlots[cursor].hasData) { - ui.showText(i18next.t("saveSlotSelectUiHandler:overwriteData"), null, () => { - ui.setOverlayMode(Mode.CONFIRM, () => { - this.scene.gameData.deleteSession(cursor).then(response => { - if (response === false) { - this.scene.reset(true); - } else { - saveAndCallback(); - } - }); - }, () => { - ui.revertMode(); - ui.showText("", 0); - }, false, 0, 19, 2000); - }); - } else if (this.sessionSlots[cursor].hasData === false) { - saveAndCallback(); - } else { - return false; - } - break; + break; + case SaveSlotUiMode.SAVE: + const saveAndCallback = () => { + const originalCallback = this.saveSlotSelectCallback; + this.saveSlotSelectCallback = null; + ui.revertMode(); + ui.showText("", 0); + ui.setMode(Mode.MESSAGE); + originalCallback && originalCallback(cursor); + }; + if (this.sessionSlots[cursor].hasData) { + ui.showText(i18next.t("saveSlotSelectUiHandler:overwriteData"), null, () => { + ui.setOverlayMode(Mode.CONFIRM, () => { + this.scene.gameData.deleteSession(cursor).then(response => { + if (response === false) { + this.scene.reset(true); + } else { + saveAndCallback(); + } + }); + }, () => { + ui.revertMode(); + ui.showText("", 0); + }, false, 0, 19, 2000); + }); + } else if (this.sessionSlots[cursor].hasData === false) { + saveAndCallback(); + } else { + return false; + } + break; } success = true; } @@ -147,21 +149,28 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { success = true; } } else { + const cursorPosition = this.cursor + this.scrollCursor; switch (button) { - case Button.UP: - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } else if (this.scrollCursor) { - success = this.setScrollCursor(this.scrollCursor - 1); - } - break; - case Button.DOWN: - if (this.cursor < 2) { - success = this.setCursor(this.cursor + 1); - } else if (this.scrollCursor < sessionSlotCount - 3) { - success = this.setScrollCursor(this.scrollCursor + 1); - } - break; + case Button.UP: + if (this.cursor) { + // Check to prevent cursor from accessing a negative index + success = (this.cursor === 0) ? this.setCursor(this.cursor) : this.setCursor(this.cursor - 1, cursorPosition); + } else if (this.scrollCursor) { + success = this.setScrollCursor(this.scrollCursor - 1, cursorPosition); + } + break; + case Button.DOWN: + if (this.cursor < (SLOTS_ON_SCREEN - 1)) { + success = this.setCursor(this.cursor + 1, cursorPosition); + } else if (this.scrollCursor < SESSION_SLOTS_COUNT - SLOTS_ON_SCREEN) { + success = this.setScrollCursor(this.scrollCursor + 1, cursorPosition); + } + break; + case Button.RIGHT: + if (this.sessionSlots[cursorPosition].hasData && this.sessionSlots[cursorPosition].saveData) { + this.scene.ui.setOverlayMode(Mode.RUN_INFO, this.sessionSlots[cursorPosition].saveData, RunDisplayMode.SESSION_PREVIEW); + success = true; + } } } @@ -175,12 +184,18 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { } populateSessionSlots() { - for (let s = 0; s < sessionSlotCount; s++) { + for (let s = 0; s < SESSION_SLOTS_COUNT; s++) { const sessionSlot = new SessionSlot(this.scene, s); - sessionSlot.load(); this.scene.add.existing(sessionSlot); this.sessionSlotsContainer.add(sessionSlot); this.sessionSlots.push(sessionSlot); + sessionSlot.load().then((success) => { + // If the cursor was moved to this slot while the session was loading + // call setCursor again to shift the slot position and show the arrow for save preview + if (success && (this.cursor + this.scrollCursor) === s) { + this.setCursor(s); + } + }); } } @@ -198,25 +213,79 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { this.saveSlotSelectMessageBoxContainer.setVisible(!!text?.length); } - setCursor(cursor: integer): boolean { + /** + * Move the cursor to a new position and update the view accordingly + * @param cursor the new cursor position, between `0` and `SLOTS_ON_SCREEN - 1` + * @param prevSlotIndex index of the previous session occupied by the cursor, between `0` and `SESSION_SLOTS_COUNT - 1` - optional + * @returns `true` if the cursor position has changed | `false` if it has not + */ + override setCursor(cursor: integer, prevSlotIndex?: integer): boolean { const changed = super.setCursor(cursor); if (!this.cursorObj) { - this.cursorObj = this.scene.add.nineslice(0, 0, "select_cursor_highlight_thick", undefined, 296, 44, 6, 6, 6, 6); - this.cursorObj.setOrigin(0, 0); + this.cursorObj = this.scene.add.container(0, 0); + const cursorBox = this.scene.add.nineslice(0, 0, "select_cursor_highlight_thick", undefined, 296, 44, 6, 6, 6, 6); + const rightArrow = this.scene.add.image(0, 0, "cursor"); + rightArrow.setPosition(160, 0); + rightArrow.setName("rightArrow"); + this.cursorObj.add([ cursorBox, rightArrow ]); this.sessionSlotsContainer.add(this.cursorObj); } - this.cursorObj.setPosition(4, 4 + (cursor + this.scrollCursor) * 56); + const cursorPosition = cursor + this.scrollCursor; + const cursorIncrement = cursorPosition * 56; + if (this.sessionSlots[cursorPosition] && this.cursorObj) { + const hasData = this.sessionSlots[cursorPosition].hasData; + // If the session slot lacks session data, it does not move from its default, central position. + // Only session slots with session data will move leftwards and have a visible arrow. + if (!hasData) { + this.cursorObj.setPosition(151, 26 + cursorIncrement); + this.sessionSlots[cursorPosition].setPosition(0, cursorIncrement); + } else { + this.cursorObj.setPosition(145, 26 + cursorIncrement); + this.sessionSlots[cursorPosition].setPosition(-6, cursorIncrement); + } + this.setArrowVisibility(hasData); + } + if (!Utils.isNullOrUndefined(prevSlotIndex)) { + this.revertSessionSlot(prevSlotIndex); + } return changed; } - setScrollCursor(scrollCursor: integer): boolean { + /** + * Helper function that resets the given session slot to its default central position + */ + revertSessionSlot(slotIndex: integer): void { + const sessionSlot = this.sessionSlots[slotIndex]; + if (sessionSlot) { + sessionSlot.setPosition(0, slotIndex * 56); + } + } + + /** + * Helper function that checks if the session slot involved holds data or not + * @param hasData `true` if session slot contains data | 'false' if not + */ + setArrowVisibility(hasData: boolean): void { + if (this.cursorObj) { + const rightArrow = this.cursorObj?.getByName("rightArrow") as Phaser.GameObjects.Image; + rightArrow.setVisible(hasData); + } + } + + /** + * Move the scrolling cursor to a new position and update the view accordingly + * @param scrollCursor the new cursor position, between `0` and `SESSION_SLOTS_COUNT - SLOTS_ON_SCREEN` + * @param prevSlotIndex index of the previous slot occupied by the cursor, between `0` and `SESSION_SLOTS_COUNT-1` - optional + * @returns `true` if the cursor position has changed | `false` if it has not + */ + setScrollCursor(scrollCursor: integer, prevSlotIndex?: integer): boolean { const changed = scrollCursor !== this.scrollCursor; if (changed) { this.scrollCursor = scrollCursor; - this.setCursor(this.cursor); + this.setCursor(this.cursor, prevSlotIndex); this.scene.tweens.add({ targets: this.sessionSlotsContainer, y: this.sessionSlotsContainerInitialY - 56 * scrollCursor, @@ -231,6 +300,7 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { clear() { super.clear(); this.saveSlotSelectContainer.setVisible(false); + this.setScrollCursor(0); this.eraseCursor(); this.saveSlotSelectCallback = null; this.clearSessionSlots(); @@ -254,6 +324,8 @@ class SessionSlot extends Phaser.GameObjects.Container { public hasData: boolean; private loadingLabel: Phaser.GameObjects.Text; + public saveData: SessionSaveData; + constructor(scene: BattleScene, slotId: integer) { super(scene, 0, slotId * 56); @@ -330,6 +402,10 @@ class SessionSlot extends Phaser.GameObjects.Container { load(): Promise { return new Promise(resolve => { this.scene.gameData.getSession(this.slotId).then(async sessionData => { + // Ignore the results if the view was exited + if (!this.active) { + return; + } if (!sessionData) { this.hasData = false; this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty")); @@ -337,6 +413,7 @@ class SessionSlot extends Phaser.GameObjects.Container { return; } this.hasData = true; + this.saveData = sessionData; await this.setupWithData(sessionData); resolve(true); }); diff --git a/src/ui/scrollable-grid-handler.ts b/src/ui/scrollable-grid-handler.ts index f96f3c995b7..cced92a2083 100644 --- a/src/ui/scrollable-grid-handler.ts +++ b/src/ui/scrollable-grid-handler.ts @@ -106,48 +106,48 @@ export default class ScrollableGridUiHandler { const itemOffset = this.scrollCursor * this.COLUMNS; const lastVisibleIndex = Math.min(this.totalElements - 1, this.totalElements - maxScrollCursor * this.COLUMNS - 1); switch (button) { - case Button.UP: - if (currentRowIndex > 0) { - success = this.setCursor(this.cursor - this.COLUMNS); - } else if (this.scrollCursor > 0) { - success = this.setScrollCursor(this.scrollCursor - 1); - } else { + case Button.UP: + if (currentRowIndex > 0) { + success = this.setCursor(this.cursor - this.COLUMNS); + } else if (this.scrollCursor > 0) { + success = this.setScrollCursor(this.scrollCursor - 1); + } else { // wrap around to the last row - let newCursor = this.cursor + (onScreenRows - 1) * this.COLUMNS; - if (newCursor > lastVisibleIndex) { - newCursor -= this.COLUMNS; + let newCursor = this.cursor + (onScreenRows - 1) * this.COLUMNS; + if (newCursor > lastVisibleIndex) { + newCursor -= this.COLUMNS; + } + success = this.setScrollCursor(maxScrollCursor, newCursor); } - success = this.setScrollCursor(maxScrollCursor, newCursor); - } - break; - case Button.DOWN: - if (currentRowIndex < onScreenRows - 1) { + break; + case Button.DOWN: + if (currentRowIndex < onScreenRows - 1) { // Go down one row - success = this.setCursor(Math.min(this.cursor + this.COLUMNS, this.totalElements - itemOffset - 1)); - } else if (this.scrollCursor < maxScrollCursor) { + success = this.setCursor(Math.min(this.cursor + this.COLUMNS, this.totalElements - itemOffset - 1)); + } else if (this.scrollCursor < maxScrollCursor) { // Scroll down one row - success = this.setScrollCursor(this.scrollCursor + 1); - } else { + success = this.setScrollCursor(this.scrollCursor + 1); + } else { // Wrap around to the top row - success = this.setScrollCursor(0, this.cursor % this.COLUMNS); - } - break; - case Button.LEFT: - if (currentColumnIndex > 0) { - success = this.setCursor(this.cursor - 1); - } else if (this.scrollCursor === maxScrollCursor && currentRowIndex === onScreenRows - 1) { - success = this.setCursor(lastVisibleIndex); - } else { - success = this.setCursor(this.cursor + this.COLUMNS - 1); - } - break; - case Button.RIGHT: - if (currentColumnIndex < this.COLUMNS - 1 && this.cursor + itemOffset < this.totalElements - 1) { - success = this.setCursor(this.cursor + 1); - } else { - success = this.setCursor(this.cursor - currentColumnIndex); - } - break; + success = this.setScrollCursor(0, this.cursor % this.COLUMNS); + } + break; + case Button.LEFT: + if (currentColumnIndex > 0) { + success = this.setCursor(this.cursor - 1); + } else if (this.scrollCursor === maxScrollCursor && currentRowIndex === onScreenRows - 1) { + success = this.setCursor(lastVisibleIndex); + } else { + success = this.setCursor(this.cursor + this.COLUMNS - 1); + } + break; + case Button.RIGHT: + if (currentColumnIndex < this.COLUMNS - 1 && this.cursor + itemOffset < this.totalElements - 1) { + success = this.setCursor(this.cursor + 1); + } else { + success = this.setCursor(this.cursor - currentColumnIndex); + } + break; } return success; } diff --git a/src/ui/settings/abstract-binding-ui-handler.ts b/src/ui/settings/abstract-binding-ui-handler.ts index 5e6dd80c6d6..9ebc3c493a4 100644 --- a/src/ui/settings/abstract-binding-ui-handler.ts +++ b/src/ui/settings/abstract-binding-ui-handler.ts @@ -1,10 +1,10 @@ import UiHandler from "../ui-handler"; import BattleScene from "../../battle-scene"; -import {Mode} from "../ui"; -import {addWindow} from "../ui-theme"; -import {addTextObject, TextStyle} from "../text"; -import {Button} from "#enums/buttons"; -import {NavigationManager} from "#app/ui/settings/navigationMenu"; +import { Mode } from "../ui"; +import { addWindow } from "../ui-theme"; +import { addTextObject, TextStyle } from "../text"; +import { Button } from "#enums/buttons"; +import { NavigationManager } from "#app/ui/settings/navigationMenu"; import i18next from "i18next"; type CancelFn = (succes?: boolean) => boolean; @@ -88,7 +88,7 @@ export default abstract class AbstractBindingUiHandler extends UiHandler { this.timerText = addTextObject(this.scene, 0, 0, "(5)", TextStyle.WINDOW); this.timerText.setOrigin(0, 0); - this.timerText.setPositionRelative(this.unlockText, (this.unlockText.width/6) + 5, 0); + this.timerText.setPositionRelative(this.unlockText, (this.unlockText.width / 6) + 5, 0); this.optionSelectContainer.add(this.timerText); this.optionSelectBg = addWindow(this.scene, (this.scene.game.canvas.width / 6) - this.getWindowWidth(), -(this.scene.game.canvas.height / 6) + this.getWindowHeight() + 28, this.getWindowWidth(), this.getWindowHeight()); @@ -170,22 +170,22 @@ export default abstract class AbstractBindingUiHandler extends UiHandler { const ui = this.getUi(); let success = false; switch (button) { - case Button.LEFT: - case Button.RIGHT: + case Button.LEFT: + case Button.RIGHT: // Toggle between action and cancel options. - const cursor = this.cursor ? 0 : 1; - success = this.setCursor(cursor); - break; - case Button.ACTION: + const cursor = this.cursor ? 0 : 1; + success = this.setCursor(cursor); + break; + case Button.ACTION: // Process actions based on current cursor position. - if (this.cursor === 0) { - this.cancelFn && this.cancelFn(); - } else { - success = this.swapAction(); - NavigationManager.getInstance().updateIcons(); - this.cancelFn && this.cancelFn(success); - } - break; + if (this.cursor === 0) { + this.cancelFn && this.cancelFn(); + } else { + success = this.swapAction(); + NavigationManager.getInstance().updateIcons(); + this.cancelFn && this.cancelFn(success); + } + break; } // Plays a select sound effect if an action was successfully processed. diff --git a/src/ui/settings/abstract-control-settings-ui-handler.ts b/src/ui/settings/abstract-control-settings-ui-handler.ts index efa262bb2e9..69f8eb241d3 100644 --- a/src/ui/settings/abstract-control-settings-ui-handler.ts +++ b/src/ui/settings/abstract-control-settings-ui-handler.ts @@ -120,7 +120,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler const actionText = addTextObject(this.scene, 0, 0, i18next.t("settings:action"), TextStyle.SETTINGS_LABEL); actionText.setOrigin(0, 0.15); - actionText.setPositionRelative(iconAction, -actionText.width/6-2, 0); + actionText.setPositionRelative(iconAction, -actionText.width / 6 - 2, 0); const iconCancel = this.scene.add.sprite(0, 0, "keyboard"); iconCancel.setOrigin(0, -0.1); @@ -129,7 +129,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler const cancelText = addTextObject(this.scene, 0, 0, i18next.t("settings:back"), TextStyle.SETTINGS_LABEL); cancelText.setOrigin(0, 0.15); - cancelText.setPositionRelative(iconCancel, -cancelText.width/6-2, 0); + cancelText.setPositionRelative(iconCancel, -cancelText.width / 6 - 2, 0); const iconReset = this.scene.add.sprite(0, 0, "keyboard"); iconReset.setOrigin(0, -0.1); @@ -138,7 +138,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler const resetText = addTextObject(this.scene, 0, 0, i18next.t("settings:reset"), TextStyle.SETTINGS_LABEL); resetText.setOrigin(0, 0.15); - resetText.setPositionRelative(iconReset, -resetText.width/6-2, 0); + resetText.setPositionRelative(iconReset, -resetText.width / 6 - 2, 0); this.settingsContainer.add(this.optionsBg); this.settingsContainer.add(this.actionsBg); @@ -174,7 +174,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler // Fetch common setting keys such as 'Controller' and 'Gamepad Support' from gamepad settings. const commonSettingKeys = Object.keys(this.setting).slice(0, this.commonSettingsCount).map(key => this.setting[key]); // Combine common and specific bindings into a single array. - const specificBindingKeys = [...commonSettingKeys, ...Object.keys(config.settings)]; + const specificBindingKeys = [ ...commonSettingKeys, ...Object.keys(config.settings) ]; // Fetch default values for these settings and prepare to highlight selected options. const optionCursors = Object.values(Object.keys(this.settingDeviceDefaults).filter(s => specificBindingKeys.includes(s)).map(k => this.settingDeviceDefaults[k])); // Filter out settings that are not relevant to the current gamepad configuration. @@ -203,7 +203,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler const valueLabels: Phaser.GameObjects.GameObject[] = []; // Process each option for the current setting. - for (const [o, option] of this.settingDeviceOptions[this.setting[setting]].entries()) { + for (const [ o, option ] of this.settingDeviceOptions[this.setting[setting]].entries()) { // Check if the current setting is for binding keys. if (bindingSettings.includes(this.setting[setting])) { // Create a label for non-null options, typically indicating actionable options like 'change'. @@ -449,78 +449,78 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler const cursor = this.cursor + this.scrollCursor; // Calculate the absolute cursor position. const setting = this.setting[Object.keys(this.setting)[cursor]]; switch (button) { - case Button.ACTION: - if (!this.optionCursors || !this.optionValueLabels) { - return false; // TODO: is false correct as default? (previously was `undefined`) - } - if (this.settingBlacklisted.includes(setting) || !setting.includes("BUTTON_")) { - success = false; - } else { - success = this.setSetting(this.scene, setting, 1); - } - break; - case Button.UP: // Move up in the menu. - if (!this.optionValueLabels) { - return false; - } - if (cursor) { // If not at the top, move the cursor up. - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } else {// If at the top of the visible items, scroll up. - success = this.setScrollCursor(this.scrollCursor - 1); + case Button.ACTION: + if (!this.optionCursors || !this.optionValueLabels) { + return false; // TODO: is false correct as default? (previously was `undefined`) } - } else { + if (this.settingBlacklisted.includes(setting) || !setting.includes("BUTTON_")) { + success = false; + } else { + success = this.setSetting(this.scene, setting, 1); + } + break; + case Button.UP: // Move up in the menu. + if (!this.optionValueLabels) { + return false; + } + if (cursor) { // If not at the top, move the cursor up. + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } else {// If at the top of the visible items, scroll up. + success = this.setScrollCursor(this.scrollCursor - 1); + } + } else { // When at the top of the menu and pressing UP, move to the bottommost item. // First, set the cursor to the last visible element, preparing for the scroll to the end. - const successA = this.setCursor(this.rowsToDisplay - 1); - // Then, adjust the scroll to display the bottommost elements of the menu. - const successB = this.setScrollCursor(this.optionValueLabels.length - this.rowsToDisplay); - success = successA && successB; // success is just there to play the little validation sound effect - } - break; - case Button.DOWN: // Move down in the menu. - if (!this.optionValueLabels) { - return false; - } - if (cursor < this.optionValueLabels.length - 1) { - if (this.cursor < this.rowsToDisplay - 1) { - success = this.setCursor(this.cursor + 1); - } else if (this.scrollCursor < this.optionValueLabels.length - this.rowsToDisplay) { - success = this.setScrollCursor(this.scrollCursor + 1); + const successA = this.setCursor(this.rowsToDisplay - 1); + // Then, adjust the scroll to display the bottommost elements of the menu. + const successB = this.setScrollCursor(this.optionValueLabels.length - this.rowsToDisplay); + success = successA && successB; // success is just there to play the little validation sound effect } - } else { + break; + case Button.DOWN: // Move down in the menu. + if (!this.optionValueLabels) { + return false; + } + if (cursor < this.optionValueLabels.length - 1) { + if (this.cursor < this.rowsToDisplay - 1) { + success = this.setCursor(this.cursor + 1); + } else if (this.scrollCursor < this.optionValueLabels.length - this.rowsToDisplay) { + success = this.setScrollCursor(this.scrollCursor + 1); + } + } else { // When at the bottom of the menu and pressing DOWN, move to the topmost item. // First, set the cursor to the first visible element, resetting the scroll to the top. - const successA = this.setCursor(0); - // Then, reset the scroll to start from the first element of the menu. - const successB = this.setScrollCursor(0); - success = successA && successB; // Indicates a successful cursor and scroll adjustment. - } - break; - case Button.LEFT: // Move selection left within the current option set. - if (!this.optionCursors || !this.optionValueLabels) { - return false; // TODO: is false correct as default? (previously was `undefined`) - } - if (this.settingBlacklisted.includes(setting) || setting.includes("BUTTON_")) { - success = false; - } else if (this.optionCursors[cursor]) { - success = this.setOptionCursor(cursor, this.optionCursors[cursor] - 1, true); - } - break; - case Button.RIGHT: // Move selection right within the current option set. - if (!this.optionCursors || !this.optionValueLabels) { - return false; // TODO: is false correct as default? (previously was `undefined`) - } - if (this.settingBlacklisted.includes(setting) || setting.includes("BUTTON_")) { - success = false; - } else if (this.optionCursors[cursor] < this.optionValueLabels[cursor].length - 1) { - success = this.setOptionCursor(cursor, this.optionCursors[cursor] + 1, true); - } - break; - case Button.CYCLE_FORM: - case Button.CYCLE_SHINY: - success = this.navigationContainer.navigate(button); - break; + const successA = this.setCursor(0); + // Then, reset the scroll to start from the first element of the menu. + const successB = this.setScrollCursor(0); + success = successA && successB; // Indicates a successful cursor and scroll adjustment. + } + break; + case Button.LEFT: // Move selection left within the current option set. + if (!this.optionCursors || !this.optionValueLabels) { + return false; // TODO: is false correct as default? (previously was `undefined`) + } + if (this.settingBlacklisted.includes(setting) || setting.includes("BUTTON_")) { + success = false; + } else if (this.optionCursors[cursor]) { + success = this.setOptionCursor(cursor, this.optionCursors[cursor] - 1, true); + } + break; + case Button.RIGHT: // Move selection right within the current option set. + if (!this.optionCursors || !this.optionValueLabels) { + return false; // TODO: is false correct as default? (previously was `undefined`) + } + if (this.settingBlacklisted.includes(setting) || setting.includes("BUTTON_")) { + success = false; + } else if (this.optionCursors[cursor] < this.optionValueLabels[cursor].length - 1) { + success = this.setOptionCursor(cursor, this.optionCursors[cursor] + 1, true); + } + break; + case Button.CYCLE_FORM: + case Button.CYCLE_SHINY: + success = this.navigationContainer.navigate(button); + break; } } @@ -556,7 +556,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler // Check if the cursor object exists, if not, create it. if (!this.cursorObj) { - const cursorWidth = (this.scene.game.canvas.width / 6) - (this.scrollBar.visible? 16 : 10); + const cursorWidth = (this.scene.game.canvas.width / 6) - (this.scrollBar.visible ? 16 : 10); this.cursorObj = this.scene.add.nineslice(0, 0, "summary_moves_cursor", undefined, cursorWidth, 16, 1, 1, 1, 1); this.cursorObj.setOrigin(0, 0); // Set the origin to the top-left corner. this.optionsContainer.add(this.cursorObj); // Add the cursor to the options container. diff --git a/src/ui/settings/abstract-settings-ui-handler.ts b/src/ui/settings/abstract-settings-ui-handler.ts index 975a32127ff..83219e1ef5a 100644 --- a/src/ui/settings/abstract-settings-ui-handler.ts +++ b/src/ui/settings/abstract-settings-ui-handler.ts @@ -77,7 +77,7 @@ export default class AbstractSettingsUiHandler extends UiHandler { const actionText = addTextObject(this.scene, 0, 0, i18next.t("settings:action"), TextStyle.SETTINGS_LABEL); actionText.setOrigin(0, 0.15); - actionText.setPositionRelative(iconAction, -actionText.width/6-2, 0); + actionText.setPositionRelative(iconAction, -actionText.width / 6 - 2, 0); const iconCancel = this.scene.add.sprite(0, 0, "keyboard"); iconCancel.setOrigin(0, -0.1); @@ -86,7 +86,7 @@ export default class AbstractSettingsUiHandler extends UiHandler { const cancelText = addTextObject(this.scene, 0, 0, i18next.t("settings:back"), TextStyle.SETTINGS_LABEL); cancelText.setOrigin(0, 0.15); - cancelText.setPositionRelative(iconCancel, -cancelText.width/6-2, 0); + cancelText.setPositionRelative(iconCancel, -cancelText.width / 6 - 2, 0); this.optionsContainer = this.scene.add.container(0, 0); @@ -224,59 +224,59 @@ export default class AbstractSettingsUiHandler extends UiHandler { } else { const cursor = this.cursor + this.scrollCursor; switch (button) { - case Button.UP: - if (cursor) { - if (this.cursor) { - success = this.setCursor(this.cursor - 1); + case Button.UP: + if (cursor) { + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } else { + success = this.setScrollCursor(this.scrollCursor - 1); + } } else { - success = this.setScrollCursor(this.scrollCursor - 1); - } - } else { // When at the top of the menu and pressing UP, move to the bottommost item. // First, set the cursor to the last visible element, preparing for the scroll to the end. - const successA = this.setCursor(this.rowsToDisplay - 1); - // Then, adjust the scroll to display the bottommost elements of the menu. - const successB = this.setScrollCursor(this.optionValueLabels.length - this.rowsToDisplay); - success = successA && successB; // success is just there to play the little validation sound effect - } - break; - case Button.DOWN: - if (cursor < this.optionValueLabels.length - 1) { - if (this.cursor < this.rowsToDisplay - 1) {// if the visual cursor is in the frame of 0 to 8 - success = this.setCursor(this.cursor + 1); - } else if (this.scrollCursor < this.optionValueLabels.length - this.rowsToDisplay) { - success = this.setScrollCursor(this.scrollCursor + 1); + const successA = this.setCursor(this.rowsToDisplay - 1); + // Then, adjust the scroll to display the bottommost elements of the menu. + const successB = this.setScrollCursor(this.optionValueLabels.length - this.rowsToDisplay); + success = successA && successB; // success is just there to play the little validation sound effect } - } else { + break; + case Button.DOWN: + if (cursor < this.optionValueLabels.length - 1) { + if (this.cursor < this.rowsToDisplay - 1) {// if the visual cursor is in the frame of 0 to 8 + success = this.setCursor(this.cursor + 1); + } else if (this.scrollCursor < this.optionValueLabels.length - this.rowsToDisplay) { + success = this.setScrollCursor(this.scrollCursor + 1); + } + } else { // When at the bottom of the menu and pressing DOWN, move to the topmost item. // First, set the cursor to the first visible element, resetting the scroll to the top. - const successA = this.setCursor(0); - // Then, reset the scroll to start from the first element of the menu. - const successB = this.setScrollCursor(0); - success = successA && successB; // Indicates a successful cursor and scroll adjustment. - } - break; - case Button.LEFT: - if (this.optionCursors[cursor]) {// Moves the option cursor left, if possible. - success = this.setOptionCursor(cursor, this.optionCursors[cursor] - 1, true); - } - break; - case Button.RIGHT: + const successA = this.setCursor(0); + // Then, reset the scroll to start from the first element of the menu. + const successB = this.setScrollCursor(0); + success = successA && successB; // Indicates a successful cursor and scroll adjustment. + } + break; + case Button.LEFT: + if (this.optionCursors[cursor]) {// Moves the option cursor left, if possible. + success = this.setOptionCursor(cursor, this.optionCursors[cursor] - 1, true); + } + break; + case Button.RIGHT: // Moves the option cursor right, if possible. - if (this.optionCursors[cursor] < this.optionValueLabels[cursor].length - 1) { - success = this.setOptionCursor(cursor, this.optionCursors[cursor] + 1, true); - } - break; - case Button.CYCLE_FORM: - case Button.CYCLE_SHINY: - success = this.navigationContainer.navigate(button); - break; - case Button.ACTION: - const setting: Setting = this.settings[cursor]; - if (setting?.activatable) { - success = this.activateSetting(setting); - } - break; + if (this.optionCursors[cursor] < this.optionValueLabels[cursor].length - 1) { + success = this.setOptionCursor(cursor, this.optionCursors[cursor] + 1, true); + } + break; + case Button.CYCLE_FORM: + case Button.CYCLE_SHINY: + success = this.navigationContainer.navigate(button); + break; + case Button.ACTION: + const setting: Setting = this.settings[cursor]; + if (setting?.activatable) { + success = this.activateSetting(setting); + } + break; } } @@ -295,9 +295,9 @@ export default class AbstractSettingsUiHandler extends UiHandler { */ activateSetting(setting: Setting): boolean { switch (setting.key) { - case SettingKeys.Move_Touch_Controls: - this.scene.inputController.moveTouchControlsHandler.enableConfigurationMode(this.getUi(), this.scene); - return true; + case SettingKeys.Move_Touch_Controls: + this.scene.inputController.moveTouchControlsHandler.enableConfigurationMode(this.getUi(), this.scene); + return true; } return false; } @@ -312,7 +312,7 @@ export default class AbstractSettingsUiHandler extends UiHandler { const ret = super.setCursor(cursor); if (!this.cursorObj) { - const cursorWidth = (this.scene.game.canvas.width / 6) - (this.scrollBar.visible? 16 : 10); + const cursorWidth = (this.scene.game.canvas.width / 6) - (this.scrollBar.visible ? 16 : 10); this.cursorObj = this.scene.add.nineslice(0, 0, "summary_moves_cursor", undefined, cursorWidth, 16, 1, 1, 1, 1); this.cursorObj.setOrigin(0, 0); this.optionsContainer.add(this.cursorObj); diff --git a/src/ui/settings/gamepad-binding-ui-handler.ts b/src/ui/settings/gamepad-binding-ui-handler.ts index 4e5b4576b85..e89529f6453 100644 --- a/src/ui/settings/gamepad-binding-ui-handler.ts +++ b/src/ui/settings/gamepad-binding-ui-handler.ts @@ -1,9 +1,9 @@ import BattleScene from "../../battle-scene"; import AbstractBindingUiHandler from "./abstract-binding-ui-handler"; -import {Mode} from "../ui"; -import {Device} from "#enums/devices"; -import {getIconWithSettingName, getKeyWithKeycode} from "#app/configs/inputs/configHandler"; -import {addTextObject, TextStyle} from "#app/ui/text"; +import { Mode } from "../ui"; +import { Device } from "#enums/devices"; +import { getIconWithSettingName, getKeyWithKeycode } from "#app/configs/inputs/configHandler"; +import { addTextObject, TextStyle } from "#app/ui/text"; export default class GamepadBindingUiHandler extends AbstractBindingUiHandler { @@ -46,7 +46,7 @@ export default class GamepadBindingUiHandler extends AbstractBindingUiHandler { } gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void { - const blacklist = [12, 13, 14, 15]; // d-pad buttons are blacklisted. + const blacklist = [ 12, 13, 14, 15 ]; // d-pad buttons are blacklisted. // Check conditions before processing the button press. if (!this.listening || pad.id.toLowerCase() !== this.getSelectedDevice() || blacklist.includes(button.index) || this.buttonPressed !== null) { return; diff --git a/src/ui/settings/keyboard-binding-ui-handler.ts b/src/ui/settings/keyboard-binding-ui-handler.ts index 043c5fba6a5..52b1a0e385f 100644 --- a/src/ui/settings/keyboard-binding-ui-handler.ts +++ b/src/ui/settings/keyboard-binding-ui-handler.ts @@ -1,9 +1,9 @@ import BattleScene from "../../battle-scene"; import AbstractBindingUiHandler from "./abstract-binding-ui-handler"; -import {Mode} from "../ui"; -import { getKeyWithKeycode} from "#app/configs/inputs/configHandler"; -import {Device} from "#enums/devices"; -import {addTextObject, TextStyle} from "#app/ui/text"; +import { Mode } from "../ui"; +import { getKeyWithKeycode } from "#app/configs/inputs/configHandler"; +import { Device } from "#enums/devices"; +import { addTextObject, TextStyle } from "#app/ui/text"; export default class KeyboardBindingUiHandler extends AbstractBindingUiHandler { diff --git a/src/ui/settings/move-touch-controls-handler.ts b/src/ui/settings/move-touch-controls-handler.ts index cff68fa523d..eda75a54a63 100644 --- a/src/ui/settings/move-touch-controls-handler.ts +++ b/src/ui/settings/move-touch-controls-handler.ts @@ -6,7 +6,6 @@ export const TOUCH_CONTROL_POSITIONS_LANDSCAPE = "touchControlPositionsLandscape export const TOUCH_CONTROL_POSITIONS_PORTRAIT = "touchControlPositionsPortrait"; - type ControlPosition = { id: string, x: number, y: number }; type ConfigurationEventListeners = { @@ -72,7 +71,7 @@ export default class MoveTouchControlsHandler { if (this.inConfigurationMode) { const orientation = document.querySelector("#touchControls #orientation"); if (orientation) { - orientation.textContent = this.isLandscapeMode? "Landscape" : "Portrait"; + orientation.textContent = this.isLandscapeMode ? "Landscape" : "Portrait"; } } const positions = this.getSavedPositionsOfCurrentOrientation() ?? []; @@ -288,7 +287,7 @@ export default class MoveTouchControlsHandler { * @returns All control groups of the touch controls. */ private getControlGroupElements(): HTMLDivElement[] { - return [...document.querySelectorAll("#touchControls .control-group")] as HTMLDivElement[]; + return [ ...document.querySelectorAll("#touchControls .control-group") ] as HTMLDivElement[]; } /** diff --git a/src/ui/settings/navigationMenu.ts b/src/ui/settings/navigationMenu.ts index 7d7761b7b69..ab86fa1569a 100644 --- a/src/ui/settings/navigationMenu.ts +++ b/src/ui/settings/navigationMenu.ts @@ -1,9 +1,9 @@ import BattleScene from "#app/battle-scene"; -import {Mode} from "#app/ui/ui"; -import {InputsIcons} from "#app/ui/settings/abstract-control-settings-ui-handler"; -import {addTextObject, setTextStyle, TextStyle} from "#app/ui/text"; -import {addWindow} from "#app/ui/ui-theme"; -import {Button} from "#enums/buttons"; +import { Mode } from "#app/ui/ui"; +import { InputsIcons } from "#app/ui/settings/abstract-control-settings-ui-handler"; +import { addTextObject, setTextStyle, TextStyle } from "#app/ui/text"; +import { addWindow } from "#app/ui/ui-theme"; +import { Button } from "#enums/buttons"; import i18next from "i18next"; const LEFT = "LEFT"; @@ -33,7 +33,7 @@ export class NavigationManager { Mode.SETTINGS_GAMEPAD, Mode.SETTINGS_KEYBOARD, ]; - this.labels = [i18next.t("settings:general"), i18next.t("settings:display"), i18next.t("settings:audio"), i18next.t("settings:gamepad"), i18next.t("settings:keyboard")]; + this.labels = [ i18next.t("settings:general"), i18next.t("settings:display"), i18next.t("settings:audio"), i18next.t("settings:gamepad"), i18next.t("settings:keyboard") ]; } public reset() { @@ -134,11 +134,11 @@ export default class NavigationMenu extends Phaser.GameObjects.Container { this.navigationIcons["BUTTON_CYCLE_SHINY"] = iconNextTab; let relative: Phaser.GameObjects.Sprite | Phaser.GameObjects.Text = iconPreviousTab; - let relativeWidth: number = iconPreviousTab.width*6; + let relativeWidth: number = iconPreviousTab.width * 6; for (const label of navigationManager.labels) { const labelText = addTextObject(this.scene, 0, 0, label, TextStyle.SETTINGS_LABEL); labelText.setOrigin(0, 0); - labelText.setPositionRelative(relative, 6 + relativeWidth/6, 0); + labelText.setPositionRelative(relative, 6 + relativeWidth / 6, 0); this.add(labelText); this.headerTitles.push(labelText); relative = labelText; @@ -158,7 +158,7 @@ export default class NavigationMenu extends Phaser.GameObjects.Container { const navigationManager = NavigationManager.getInstance(); const posSelected = navigationManager.modes.indexOf(navigationManager.selectedMode); - for (const [index, title] of this.headerTitles.entries()) { + for (const [ index, title ] of this.headerTitles.entries()) { setTextStyle(title, this.scene, index === posSelected ? TextStyle.SETTINGS_SELECTED : TextStyle.SETTINGS_LABEL); } } @@ -198,12 +198,12 @@ export default class NavigationMenu extends Phaser.GameObjects.Container { navigate(button: Button): boolean { const navigationManager = NavigationManager.getInstance(); switch (button) { - case Button.CYCLE_FORM: - navigationManager.navigate(this.scene, LEFT); - return true; - case Button.CYCLE_SHINY: - navigationManager.navigate(this.scene, RIGHT); - return true; + case Button.CYCLE_FORM: + navigationManager.navigate(this.scene, LEFT); + return true; + case Button.CYCLE_SHINY: + navigationManager.navigate(this.scene, RIGHT); + return true; } return false; } diff --git a/src/ui/settings/settings-display-ui-handler.ts b/src/ui/settings/settings-display-ui-handler.ts index 3d602c50a78..a25dbf87b7d 100644 --- a/src/ui/settings/settings-display-ui-handler.ts +++ b/src/ui/settings/settings-display-ui-handler.ts @@ -23,79 +23,79 @@ export default class SettingsDisplayUiHandler extends AbstractSettingsUiHandler if (languageIndex >= 0) { const currentLocale = localStorage.getItem("prLang"); switch (currentLocale) { - case "en": - this.settings[languageIndex].options[0] = { - value: "English", - label: "English", - }; - break; - case "es": - this.settings[languageIndex].options[0] = { - value: "Español", - label: "Español", - }; - break; - case "it": - this.settings[languageIndex].options[0] = { - value: "Italiano", - label: "Italiano", - }; - break; - case "fr": - this.settings[languageIndex].options[0] = { - value: "Français", - label: "Français", - }; - break; - case "de": - this.settings[languageIndex].options[0] = { - value: "Deutsch", - label: "Deutsch", - }; - break; - case "pt-BR": - this.settings[languageIndex].options[0] = { - value: "Português (BR)", - label: "Português (BR)", - }; - break; - case "zh-CN": - this.settings[languageIndex].options[0] = { - value: "简体中文", - label: "简体中文", - }; - break; - case "zh-TW": - this.settings[languageIndex].options[0] = { - value: "繁體中文", - label: "繁體中文", - }; - break; - case "ko": - case "ko-KR": - this.settings[languageIndex].options[0] = { - value: "한국어", - label: "한국어", - }; - break; - case "ja": - this.settings[languageIndex].options[0] = { - value: "日本語", - label: "日本語", - }; - break; - case "ca-ES": - this.settings[languageIndex].options[0] = { - value: "Català", - label: "Català", - }; - break; - default: - this.settings[languageIndex].options[0] = { - value: "English", - label: "English", - }; - break; + case "en": + this.settings[languageIndex].options[0] = { + value: "English", + label: "English", + }; + break; + case "es": + this.settings[languageIndex].options[0] = { + value: "Español", + label: "Español", + }; + break; + case "it": + this.settings[languageIndex].options[0] = { + value: "Italiano", + label: "Italiano", + }; + break; + case "fr": + this.settings[languageIndex].options[0] = { + value: "Français", + label: "Français", + }; + break; + case "de": + this.settings[languageIndex].options[0] = { + value: "Deutsch", + label: "Deutsch", + }; + break; + case "pt-BR": + this.settings[languageIndex].options[0] = { + value: "Português (BR)", + label: "Português (BR)", + }; + break; + case "zh-CN": + this.settings[languageIndex].options[0] = { + value: "简体中文", + label: "简体中文", + }; + break; + case "zh-TW": + this.settings[languageIndex].options[0] = { + value: "繁體中文", + label: "繁體中文", + }; + break; + case "ko": + case "ko-KR": + this.settings[languageIndex].options[0] = { + value: "한국어", + label: "한국어", + }; + break; + case "ja": + this.settings[languageIndex].options[0] = { + value: "日本語", + label: "日本語", + }; + break; + case "ca-ES": + this.settings[languageIndex].options[0] = { + value: "Català", + label: "Català", + }; + break; + default: + this.settings[languageIndex].options[0] = { + value: "English", + label: "English", + }; + break; } } diff --git a/src/ui/settings/settings-gamepad-ui-handler.ts b/src/ui/settings/settings-gamepad-ui-handler.ts index 63a9d2ab23b..864142e055b 100644 --- a/src/ui/settings/settings-gamepad-ui-handler.ts +++ b/src/ui/settings/settings-gamepad-ui-handler.ts @@ -1,6 +1,6 @@ import BattleScene from "../../battle-scene"; -import {addTextObject, TextStyle} from "../text"; -import {Mode} from "../ui"; +import { addTextObject, TextStyle } from "../text"; +import { Mode } from "../ui"; import { setSettingGamepad, SettingGamepad, @@ -11,10 +11,10 @@ import { import pad_xbox360 from "#app/configs/inputs/pad_xbox360"; import pad_dualshock from "#app/configs/inputs/pad_dualshock"; import pad_unlicensedSNES from "#app/configs/inputs/pad_unlicensedSNES"; -import {InterfaceConfig} from "#app/inputs-controller"; +import { InterfaceConfig } from "#app/inputs-controller"; import AbstractControlSettingsUiHandler from "#app/ui/settings/abstract-control-settings-ui-handler"; -import {Device} from "#enums/devices"; -import {truncateString} from "#app/utils"; +import { Device } from "#enums/devices"; +import { truncateString } from "#app/utils"; import i18next from "i18next"; /** @@ -37,7 +37,7 @@ export default class SettingsGamepadUiHandler extends AbstractControlSettingsUiH this.setting = SettingGamepad; this.settingDeviceDefaults = settingGamepadDefaults; this.settingDeviceOptions = settingGamepadOptions; - this.configs = [pad_xbox360, pad_dualshock, pad_unlicensedSNES]; + this.configs = [ pad_xbox360, pad_dualshock, pad_unlicensedSNES ]; this.commonSettingsCount = 2; this.localStoragePropertyName = "settingsGamepad"; this.settingBlacklisted = settingGamepadBlackList; @@ -94,7 +94,7 @@ export default class SettingsGamepadUiHandler extends AbstractControlSettingsUiH this.resetScroll(); // Iterate over the keys in the settingDevice enumeration. - for (const [index, key] of Object.keys(this.setting).entries()) { + for (const [ index, key ] of Object.keys(this.setting).entries()) { const setting = this.setting[key]; // Get the actual setting value using the key. // Check if the current setting corresponds to the controller setting. diff --git a/src/ui/settings/settings-keyboard-ui-handler.ts b/src/ui/settings/settings-keyboard-ui-handler.ts index 7e020034bc6..17d91b27c57 100644 --- a/src/ui/settings/settings-keyboard-ui-handler.ts +++ b/src/ui/settings/settings-keyboard-ui-handler.ts @@ -1,5 +1,5 @@ import BattleScene from "../../battle-scene"; -import {Mode} from "../ui"; +import { Mode } from "../ui"; import cfg_keyboard_qwerty from "#app/configs/inputs/cfg_keyboard_qwerty"; import { setSettingKeyboard, @@ -8,13 +8,13 @@ import { settingKeyboardDefaults, settingKeyboardOptions } from "#app/system/settings/settings-keyboard"; -import {reverseValueToKeySetting, truncateString} from "#app/utils"; +import { reverseValueToKeySetting, truncateString } from "#app/utils"; import AbstractControlSettingsUiHandler from "#app/ui/settings/abstract-control-settings-ui-handler"; -import {InterfaceConfig} from "#app/inputs-controller"; -import {addTextObject, TextStyle} from "#app/ui/text"; -import {deleteBind} from "#app/configs/inputs/configHandler"; -import {Device} from "#enums/devices"; -import {NavigationManager} from "#app/ui/settings/navigationMenu"; +import { InterfaceConfig } from "#app/inputs-controller"; +import { addTextObject, TextStyle } from "#app/ui/text"; +import { deleteBind } from "#app/configs/inputs/configHandler"; +import { Device } from "#enums/devices"; +import { NavigationManager } from "#app/ui/settings/navigationMenu"; import i18next from "i18next"; /** @@ -35,7 +35,7 @@ export default class SettingsKeyboardUiHandler extends AbstractControlSettingsUi this.setting = SettingKeyboard; this.settingDeviceDefaults = settingKeyboardDefaults; this.settingDeviceOptions = settingKeyboardOptions; - this.configs = [cfg_keyboard_qwerty]; + this.configs = [ cfg_keyboard_qwerty ]; this.commonSettingsCount = 0; this.textureOverride = "keyboard"; this.localStoragePropertyName = "settingsKeyboard"; @@ -71,13 +71,12 @@ export default class SettingsKeyboardUiHandler extends AbstractControlSettingsUi const deleteText = addTextObject(this.scene, 0, 0, i18next.t("settings:delete"), TextStyle.SETTINGS_LABEL); deleteText.setOrigin(0, 0.15); - deleteText.setPositionRelative(iconDelete, -deleteText.width/6-2, 0); + deleteText.setPositionRelative(iconDelete, -deleteText.width / 6 - 2, 0); this.settingsContainer.add(iconDelete); this.settingsContainer.add(deleteText); - // Map the 'noKeyboard' layout options for easy access. this.layout["noKeyboard"].optionsContainer = optionsContainer; this.layout["noKeyboard"].label = label; @@ -87,7 +86,7 @@ export default class SettingsKeyboardUiHandler extends AbstractControlSettingsUi * Handle the home key press event. */ onHomeDown(): void { - if (![Mode.SETTINGS_KEYBOARD, Mode.SETTINGS_GAMEPAD].includes(this.scene.ui.getMode())) { + if (![ Mode.SETTINGS_KEYBOARD, Mode.SETTINGS_GAMEPAD ].includes(this.scene.ui.getMode())) { return; } this.scene.gameData.resetMappingToFactory(); @@ -142,7 +141,7 @@ export default class SettingsKeyboardUiHandler extends AbstractControlSettingsUi this.updateBindings(); // Iterate over the keys in the settingDevice enumeration. - for (const [index, key] of Object.keys(this.setting).entries()) { + for (const [ index, key ] of Object.keys(this.setting).entries()) { const setting = this.setting[key]; // Get the actual setting value using the key. // Check if the current setting corresponds to the layout setting. diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 38445f79e05..bb999dc736a 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -46,6 +46,7 @@ import { StarterContainer } from "#app/ui/starter-container"; import { DropDownColumn, FilterBar } from "#app/ui/filter-bar"; import { ScrollBar } from "#app/ui/scroll-bar"; import { SelectChallengePhase } from "#app/phases/select-challenge-phase"; +import { EncounterPhase } from "#app/phases/encounter-phase"; import { TitlePhase } from "#app/phases/title-phase"; import { Abilities } from "#enums/abilities"; import { getPassiveCandyCount, getValueReductionCandyCounts, getSameSpeciesEggCandyCounts } from "#app/data/balance/starters"; @@ -143,7 +144,7 @@ function calcStarterPosition(index: number, scrollCursor:number = 0): {x: number const x = (index % 9) * 18; const y = yOffset + (Math.floor(index / 9) - scrollCursor) * height; - return {x: x, y: y}; + return { x: x, y: y }; } /** @@ -186,7 +187,7 @@ function findClosestStarterRow(index: number, numberOfRows: number) { const currentY = calcStarterIconY(index) - 13; let smallestDistance = teamWindowHeight; let closestRowIndex = 0; - for (let i=0; i < numberOfRows; i++) { + for (let i = 0; i < numberOfRows; i++) { const distance = Math.abs(currentY - calcStarterPosition(i * 9).y); if (distance < smallestDistance) { closestRowIndex = i; @@ -308,13 +309,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private starterIconsCursorObj: Phaser.GameObjects.Image; private valueLimitLabel: Phaser.GameObjects.Text; private startCursorObj: Phaser.GameObjects.NineSlice; - // private starterValueLabels: Phaser.GameObjects.Text[]; - // private shinyIcons: Phaser.GameObjects.Image[][]; - // private hiddenAbilityIcons: Phaser.GameObjects.Image[]; - // private classicWinIcons: Phaser.GameObjects.Image[]; - // private candyUpgradeIcon: Phaser.GameObjects.Image[]; - // private candyUpgradeOverlayIcon: Phaser.GameObjects.Image[]; - // + private iconAnimHandler: PokemonIconAnimHandler; //variables to keep track of the dynamically rendered list of instruction prompts for starter select @@ -358,7 +353,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterSelectContainer.add(this.shinyOverlay); const starterContainerWindow = addWindow(this.scene, speciesContainerX, filterBarHeight + 1, 175, 161); - const starterContainerBg = this.scene.add.image(speciesContainerX+1, filterBarHeight + 2, "starter_container_bg"); + const starterContainerBg = this.scene.add.image(speciesContainerX + 1, filterBarHeight + 2, "starter_container_bg"); starterContainerBg.setOrigin(0, 0); this.starterSelectContainer.add(starterContainerBg); @@ -588,15 +583,15 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonEggMoveBgs = []; this.pokemonEggMoveLabels = []; - this.valueLimitLabel = addTextObject(this.scene, teamWindowX+17, 150, "0/10", TextStyle.TOOLTIP_CONTENT); + this.valueLimitLabel = addTextObject(this.scene, teamWindowX + 17, 150, "0/10", TextStyle.TOOLTIP_CONTENT); this.valueLimitLabel.setOrigin(0.5, 0); this.starterSelectContainer.add(this.valueLimitLabel); - const startLabel = addTextObject(this.scene, teamWindowX+17, 162, i18next.t("common:start"), TextStyle.TOOLTIP_CONTENT); + const startLabel = addTextObject(this.scene, teamWindowX + 17, 162, i18next.t("common:start"), TextStyle.TOOLTIP_CONTENT); startLabel.setOrigin(0.5, 0); this.starterSelectContainer.add(startLabel); - this.startCursorObj = this.scene.add.nineslice(teamWindowX+4, 160, "select_cursor", undefined, 26, 15, 6, 6, 6, 6); + this.startCursorObj = this.scene.add.nineslice(teamWindowX + 4, 160, "select_cursor", undefined, 26, 15, 6, 6, 6, 6); this.startCursorObj.setVisible(false); this.startCursorObj.setOrigin(0, 0); this.starterSelectContainer.add(this.startCursorObj); @@ -1155,7 +1150,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { ease: "Cubic.easeOut", yoyo: true } - ],}; + ], }; const isPassiveAvailable = this.isPassiveAvailable(species.speciesId); const isValueReductionAvailable = this.isValueReductionAvailable(species.speciesId); @@ -1308,109 +1303,119 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } else if (this.startCursorObj.visible) { // this checks to see if the start button is selected switch (button) { - case Button.ACTION: - if (this.tryStart(true)) { + case Button.ACTION: + if (this.tryStart(true)) { + success = true; + } else { + error = true; + } + break; + case Button.UP: + // UP from start button: go to pokemon in team if any, otherwise filter + this.startCursorObj.setVisible(false); + if (this.starterSpecies.length > 0) { + this.starterIconsCursorIndex = this.starterSpecies.length - 1; + this.moveStarterIconsCursor(this.starterIconsCursorIndex); + } else { + this.startCursorObj.setVisible(false); + this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); + this.setFilterMode(true); + } success = true; - } else { - error = true; - } - break; - case Button.UP: - this.startCursorObj.setVisible(false); - if (this.starterSpecies.length > 0) { - this.starterIconsCursorIndex = this.starterSpecies.length - 1; - this.moveStarterIconsCursor(this.starterIconsCursorIndex); - } else { - // up from start button with no Pokemon in the team > go to filter + break; + case Button.DOWN: + // DOWN from start button: Go to filters this.startCursorObj.setVisible(false); this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); this.setFilterMode(true); - } - success = true; - break; - case Button.DOWN: - this.startCursorObj.setVisible(false); - if (this.starterSpecies.length > 0) { - this.starterIconsCursorIndex = 0; - this.moveStarterIconsCursor(this.starterIconsCursorIndex); - } else { - // down from start button with no Pokemon in the team > go to filter - this.startCursorObj.setVisible(false); - this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); - this.setFilterMode(true); - } - success = true; - break; - case Button.LEFT: - this.startCursorObj.setVisible(false); - this.cursorObj.setVisible(true); - success = this.setCursor(onScreenFirstIndex + (onScreenNumberOfRows-1) * 9 + 8); // set last column - success = true; - break; - case Button.RIGHT: - this.startCursorObj.setVisible(false); - this.cursorObj.setVisible(true); - success = this.setCursor(onScreenFirstIndex + (onScreenNumberOfRows-1) * 9); // set first column - success = true; - break; + success = true; + break; + case Button.LEFT: + if (numberOfStarters > 0) { + this.startCursorObj.setVisible(false); + this.cursorObj.setVisible(true); + this.setCursor(onScreenFirstIndex + (onScreenNumberOfRows - 1) * 9 + 8); // set last column + success = true; + } + break; + case Button.RIGHT: + if (numberOfStarters > 0) { + this.startCursorObj.setVisible(false); + this.cursorObj.setVisible(true); + this.setCursor(onScreenFirstIndex + (onScreenNumberOfRows - 1) * 9); // set first column + success = true; + } + break; } } else if (this.filterMode) { switch (button) { - case Button.LEFT: - if (this.filterBarCursor > 0) { - success = this.setCursor(this.filterBarCursor - 1); - } else { - success = this.setCursor(this.filterBar.numFilters - 1); - } - break; - case Button.RIGHT: - if (this.filterBarCursor < this.filterBar.numFilters - 1) { - success = this.setCursor(this.filterBarCursor + 1); - } else { - success = this.setCursor(0); - } - break; - case Button.UP: - if (this.filterBar.openDropDown) { - success = this.filterBar.decDropDownCursor(); - // else if there is filtered starters - } else if (numberOfStarters > 0) { - // UP from filter bar to bottom of Pokemon list - this.setFilterMode(false); - this.scrollCursor = Math.max(0, numOfRows - 9); - this.updateScroll(); - const proportion = (this.filterBarCursor + 0.5) / this.filterBar.numFilters; - const targetCol = Math.min(8, Math.floor(proportion * 11)); - if (numberOfStarters % 9 > targetCol) { - this.setCursor(numberOfStarters - (numberOfStarters) % 9 + targetCol); + case Button.LEFT: + if (this.filterBarCursor > 0) { + success = this.setCursor(this.filterBarCursor - 1); } else { - this.setCursor(Math.max(numberOfStarters - (numberOfStarters) % 9 + targetCol - 9, 0)); + success = this.setCursor(this.filterBar.numFilters - 1); + } + break; + case Button.RIGHT: + if (this.filterBarCursor < this.filterBar.numFilters - 1) { + success = this.setCursor(this.filterBarCursor + 1); + } else { + success = this.setCursor(0); + } + break; + case Button.UP: + if (this.filterBar.openDropDown) { + success = this.filterBar.decDropDownCursor(); + } else if (this.filterBarCursor === this.filterBar.numFilters - 1 && this.starterSpecies.length > 0) { + // UP from the last filter, move to start button + this.setFilterMode(false); + this.cursorObj.setVisible(false); + this.startCursorObj.setVisible(true); + success = true; + } else if (numberOfStarters > 0) { + // UP from filter bar to bottom of Pokemon list + this.setFilterMode(false); + this.scrollCursor = Math.max(0, numOfRows - 9); + this.updateScroll(); + const proportion = (this.filterBarCursor + 0.5) / this.filterBar.numFilters; + const targetCol = Math.min(8, Math.floor(proportion * 11)); + if (numberOfStarters % 9 > targetCol) { + this.setCursor(numberOfStarters - (numberOfStarters) % 9 + targetCol); + } else { + this.setCursor(Math.max(numberOfStarters - (numberOfStarters) % 9 + targetCol - 9, 0)); + } + success = true; + } + break; + case Button.DOWN: + if (this.filterBar.openDropDown) { + success = this.filterBar.incDropDownCursor(); + } else if (this.filterBarCursor === this.filterBar.numFilters - 1 && this.starterSpecies.length > 0) { + // DOWN from the last filter, move to Pokemon in party if any + this.setFilterMode(false); + this.cursorObj.setVisible(false); + this.starterIconsCursorIndex = 0; + this.moveStarterIconsCursor(this.starterIconsCursorIndex); + success = true; + } else if (numberOfStarters > 0) { + // DOWN from filter bar to top of Pokemon list + this.setFilterMode(false); + this.scrollCursor = 0; + this.updateScroll(); + const proportion = this.filterBarCursor / Math.max(1, this.filterBar.numFilters - 1); + const targetCol = Math.min(8, Math.floor(proportion * 11)); + this.setCursor(Math.min(targetCol, numberOfStarters)); + success = true; + } + break; + case Button.ACTION: + if (!this.filterBar.openDropDown) { + this.filterBar.toggleDropDown(this.filterBarCursor); + } else { + this.filterBar.toggleOptionState(); } success = true; - } - break; - case Button.DOWN: - if (this.filterBar.openDropDown) { - success = this.filterBar.incDropDownCursor(); - } else if (numberOfStarters > 0) { - // DOWN from filter bar to top of Pokemon list - this.setFilterMode(false); - this.scrollCursor = 0; - this.updateScroll(); - const proportion = this.filterBarCursor / Math.max(1, this.filterBar.numFilters - 1); - const targetCol = Math.min(8, Math.floor(proportion * 11)); - this.setCursor(Math.min(targetCol, numberOfStarters)); - success = true; - } - break; - case Button.ACTION: - if (!this.filterBar.openDropDown) { - this.filterBar.toggleDropDown(this.filterBarCursor); - } else { - this.filterBar.toggleOptionState(); - } - success = true; - break; + break; } } else { @@ -1434,7 +1439,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const ui = this.getUi(); let options: any[] = []; // TODO: add proper type - const [isDupe, removeIndex]: [boolean, number] = this.isInParty(this.lastSpecies); // checks to see if the pokemon is a duplicate; if it is, returns the index that will be removed + const [ isDupe, removeIndex ]: [boolean, number] = this.isInParty(this.lastSpecies); // checks to see if the pokemon is a duplicate; if it is, returns the index that will be removed const isPartyValid = this.isPartyValid(); const isValidForChallenge = new Utils.BooleanHolder(true); @@ -1784,13 +1789,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { options.push({ label: `x${sameSpeciesEggCost} ${i18next.t("starterSelectUiHandler:sameSpeciesEgg")}`, handler: () => { - if (this.scene.gameData.eggs.length < 99 && (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= sameSpeciesEggCost)) { + if ((this.scene.gameData.eggs.length < 99 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) + && (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= sameSpeciesEggCost)) { if (!Overrides.FREE_CANDY_UPGRADE_OVERRIDE) { starterData.candyCount -= sameSpeciesEggCost; } this.pokemonCandyCountText.setText(`x${starterData.candyCount}`); - const egg = new Egg({scene: this.scene, species: this.lastSpecies.speciesId, sourceType: EggSourceType.SAME_SPECIES_EGG}); + const egg = new Egg({ scene: this.scene, species: this.lastSpecies.speciesId, sourceType: EggSourceType.SAME_SPECIES_EGG }); egg.addEggToGameData(this.scene); this.scene.gameData.saveSystem().then(success => { @@ -1850,259 +1856,259 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } else { const props = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId)); switch (button) { - case Button.CYCLE_SHINY: - if (this.canCycleShiny) { - starterAttributes.shiny = starterAttributes.shiny !== undefined ? !starterAttributes.shiny : false; + case Button.CYCLE_SHINY: + if (this.canCycleShiny) { + starterAttributes.shiny = starterAttributes.shiny !== undefined ? !starterAttributes.shiny : false; - if (starterAttributes.shiny) { + if (starterAttributes.shiny) { // Change to shiny, we need to get the proper default variant - const newProps = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId)); - const newVariant = starterAttributes.variant ? starterAttributes.variant as Variant : newProps.variant; - this.setSpeciesDetails(this.lastSpecies, true, undefined, undefined, newVariant, undefined, undefined); + const newProps = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId)); + const newVariant = starterAttributes.variant ? starterAttributes.variant as Variant : newProps.variant; + this.setSpeciesDetails(this.lastSpecies, true, undefined, undefined, newVariant, undefined, undefined); - this.scene.playSound("se/sparkle"); - // Set the variant label to the shiny tint - const tint = getVariantTint(newVariant); - this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant)); - this.pokemonShinyIcon.setTint(tint); - this.pokemonShinyIcon.setVisible(true); - } else { - this.setSpeciesDetails(this.lastSpecies, false, undefined, undefined, 0, undefined, undefined); - this.pokemonShinyIcon.setVisible(false); - success = true; - } - } - break; - case Button.CYCLE_FORM: - if (this.canCycleForm) { - const formCount = this.lastSpecies.forms.length; - let newFormIndex = props.formIndex; - do { - newFormIndex = (newFormIndex + 1) % formCount; - if (this.lastSpecies.forms[newFormIndex].isStarterSelectable && this.speciesStarterDexEntry!.caughtAttr! & this.scene.gameData.getFormAttr(newFormIndex)) { // TODO: are those bangs correct? - break; + this.scene.playSound("se/sparkle"); + // Set the variant label to the shiny tint + const tint = getVariantTint(newVariant); + this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant)); + this.pokemonShinyIcon.setTint(tint); + this.pokemonShinyIcon.setVisible(true); + } else { + this.setSpeciesDetails(this.lastSpecies, false, undefined, undefined, 0, undefined, undefined); + this.pokemonShinyIcon.setVisible(false); + success = true; } - } while (newFormIndex !== props.formIndex); - starterAttributes.form = newFormIndex; // store the selected form - this.setSpeciesDetails(this.lastSpecies, undefined, newFormIndex, undefined, undefined, undefined, undefined); - success = true; - } - break; - case Button.CYCLE_GENDER: - if (this.canCycleGender) { - starterAttributes.female = !props.female; - this.setSpeciesDetails(this.lastSpecies, undefined, undefined, !props.female, undefined, undefined, undefined); - success = true; - } - break; - case Button.CYCLE_ABILITY: - if (this.canCycleAbility) { - const abilityCount = this.lastSpecies.getAbilityCount(); - const abilityAttr = this.scene.gameData.starterData[this.lastSpecies.speciesId].abilityAttr; - const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1; - let newAbilityIndex = this.abilityCursor; - do { - newAbilityIndex = (newAbilityIndex + 1) % abilityCount; - if (newAbilityIndex === 0) { - if (hasAbility1) { + } + break; + case Button.CYCLE_FORM: + if (this.canCycleForm) { + const formCount = this.lastSpecies.forms.length; + let newFormIndex = props.formIndex; + do { + newFormIndex = (newFormIndex + 1) % formCount; + if (this.lastSpecies.forms[newFormIndex].isStarterSelectable && this.speciesStarterDexEntry!.caughtAttr! & this.scene.gameData.getFormAttr(newFormIndex)) { // TODO: are those bangs correct? break; } - } else if (newAbilityIndex === 1) { + } while (newFormIndex !== props.formIndex); + starterAttributes.form = newFormIndex; // store the selected form + this.setSpeciesDetails(this.lastSpecies, undefined, newFormIndex, undefined, undefined, undefined, undefined); + success = true; + } + break; + case Button.CYCLE_GENDER: + if (this.canCycleGender) { + starterAttributes.female = !props.female; + this.setSpeciesDetails(this.lastSpecies, undefined, undefined, !props.female, undefined, undefined, undefined); + success = true; + } + break; + case Button.CYCLE_ABILITY: + if (this.canCycleAbility) { + const abilityCount = this.lastSpecies.getAbilityCount(); + const abilityAttr = this.scene.gameData.starterData[this.lastSpecies.speciesId].abilityAttr; + const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1; + let newAbilityIndex = this.abilityCursor; + do { + newAbilityIndex = (newAbilityIndex + 1) % abilityCount; + if (newAbilityIndex === 0) { + if (hasAbility1) { + break; + } + } else if (newAbilityIndex === 1) { // If ability 1 and 2 are the same and ability 1 is unlocked, skip over ability 2 - if (this.lastSpecies.ability1 === this.lastSpecies.ability2 && hasAbility1) { - newAbilityIndex = (newAbilityIndex + 1) % abilityCount; - } - break; - } else { - if (abilityAttr & AbilityAttr.ABILITY_HIDDEN) { + if (this.lastSpecies.ability1 === this.lastSpecies.ability2 && hasAbility1) { + newAbilityIndex = (newAbilityIndex + 1) % abilityCount; + } break; + } else { + if (abilityAttr & AbilityAttr.ABILITY_HIDDEN) { + break; + } } - } - } while (newAbilityIndex !== this.abilityCursor); - starterAttributes.ability = newAbilityIndex; // store the selected ability + } while (newAbilityIndex !== this.abilityCursor); + starterAttributes.ability = newAbilityIndex; // store the selected ability - const { visible: tooltipVisible } = this.scene.ui.getTooltip(); + const { visible: tooltipVisible } = this.scene.ui.getTooltip(); - if (tooltipVisible && this.activeTooltip === "ABILITY") { - const newAbility = allAbilities[this.lastSpecies.getAbility(newAbilityIndex)]; - this.scene.ui.editTooltip(`${newAbility.name}`, `${newAbility.description}`); - } + if (tooltipVisible && this.activeTooltip === "ABILITY") { + const newAbility = allAbilities[this.lastSpecies.getAbility(newAbilityIndex)]; + this.scene.ui.editTooltip(`${newAbility.name}`, `${newAbility.description}`); + } - this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, newAbilityIndex, undefined); - success = true; - } - break; - case Button.CYCLE_NATURE: - if (this.canCycleNature) { - const natures = this.scene.gameData.getNaturesForAttr(this.speciesStarterDexEntry?.natureAttr); - const natureIndex = natures.indexOf(this.natureCursor); - const newNature = natures[natureIndex < natures.length - 1 ? natureIndex + 1 : 0]; - // store cycled nature as default - starterAttributes.nature = newNature as unknown as integer; - this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, undefined, newNature, undefined); - success = true; - } - break; - case Button.V: - if (this.canCycleVariant) { - let newVariant = props.variant; - do { - newVariant = (newVariant + 1) % 3; - if (!newVariant) { - if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.DEFAULT_VARIANT) { // TODO: is this bang correct? - break; - } - } else if (newVariant === 1) { - if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_2) { // TODO: is this bang correct? - break; - } - } else { - if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_3) { // TODO: is this bang correct? - break; - } - } - } while (newVariant !== props.variant); - starterAttributes.variant = newVariant; // store the selected variant - this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, newVariant as Variant, undefined, undefined); - // Cycle tint based on current sprite tint - const tint = getVariantTint(newVariant as Variant); - this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant as Variant)); - this.pokemonShinyIcon.setTint(tint); - success = true; - } - break; - case Button.UP: - if (!this.starterIconsCursorObj.visible) { - if (currentRow > 0) { - if (this.scrollCursor > 0 && currentRow - this.scrollCursor === 0) { - this.scrollCursor--; - this.updateScroll(); - } - success = this.setCursor(this.cursor - 9); - } else { - this.filterBarCursor = this.filterBar.getNearestFilter(this.filteredStarterContainers[this.cursor]); - this.setFilterMode(true); + this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, newAbilityIndex, undefined); success = true; } - } else { - if (this.starterIconsCursorIndex === 0) { + break; + case Button.CYCLE_NATURE: + if (this.canCycleNature) { + const natures = this.scene.gameData.getNaturesForAttr(this.speciesStarterDexEntry?.natureAttr); + const natureIndex = natures.indexOf(this.natureCursor); + const newNature = natures[natureIndex < natures.length - 1 ? natureIndex + 1 : 0]; + // store cycled nature as default + starterAttributes.nature = newNature as unknown as integer; + this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, undefined, newNature, undefined); + success = true; + } + break; + case Button.V: + if (this.canCycleVariant) { + let newVariant = props.variant; + do { + newVariant = (newVariant + 1) % 3; + if (!newVariant) { + if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.DEFAULT_VARIANT) { // TODO: is this bang correct? + break; + } + } else if (newVariant === 1) { + if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_2) { // TODO: is this bang correct? + break; + } + } else { + if (this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_3) { // TODO: is this bang correct? + break; + } + } + } while (newVariant !== props.variant); + starterAttributes.variant = newVariant; // store the selected variant + this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, newVariant as Variant, undefined, undefined); + // Cycle tint based on current sprite tint + const tint = getVariantTint(newVariant as Variant); + this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant as Variant)); + this.pokemonShinyIcon.setTint(tint); + success = true; + } + break; + case Button.UP: + if (!this.starterIconsCursorObj.visible) { + if (currentRow > 0) { + if (this.scrollCursor > 0 && currentRow - this.scrollCursor === 0) { + this.scrollCursor--; + this.updateScroll(); + } + success = this.setCursor(this.cursor - 9); + } else { + this.filterBarCursor = this.filterBar.getNearestFilter(this.filteredStarterContainers[this.cursor]); + this.setFilterMode(true); + success = true; + } + } else { + if (this.starterIconsCursorIndex === 0) { // Up from first Pokemon in the team > go to filter - this.starterIconsCursorObj.setVisible(false); - this.setSpecies(null); - this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); - this.setFilterMode(true); - } else { - this.starterIconsCursorIndex--; - this.moveStarterIconsCursor(this.starterIconsCursorIndex); - } - success = true; - } - break; - case Button.DOWN: - if (!this.starterIconsCursorObj.visible) { - if (currentRow < numOfRows - 1) { // not last row - if (currentRow - this.scrollCursor === 8) { // last row of visible starters - this.scrollCursor++; + this.starterIconsCursorObj.setVisible(false); + this.setSpecies(null); + this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); + this.setFilterMode(true); + } else { + this.starterIconsCursorIndex--; + this.moveStarterIconsCursor(this.starterIconsCursorIndex); } - success = this.setCursor(this.cursor + 9); - this.updateScroll(); - } else if (numOfRows > 1) { - // DOWN from last row of Pokemon > Wrap around to first row - this.scrollCursor = 0; - this.updateScroll(); - success = this.setCursor(this.cursor % 9); - } else { - // DOWN from single row of Pokemon > Go to filters - this.filterBarCursor = this.filterBar.getNearestFilter(this.filteredStarterContainers[this.cursor]); - this.setFilterMode(true); success = true; } - } else { - if (this.starterIconsCursorIndex <= this.starterSpecies.length - 2) { - this.starterIconsCursorIndex++; - this.moveStarterIconsCursor(this.starterIconsCursorIndex); + break; + case Button.DOWN: + if (!this.starterIconsCursorObj.visible) { + if (currentRow < numOfRows - 1) { // not last row + if (currentRow - this.scrollCursor === 8) { // last row of visible starters + this.scrollCursor++; + } + success = this.setCursor(this.cursor + 9); + this.updateScroll(); + } else if (numOfRows > 1) { + // DOWN from last row of Pokemon > Wrap around to first row + this.scrollCursor = 0; + this.updateScroll(); + success = this.setCursor(this.cursor % 9); + } else { + // DOWN from single row of Pokemon > Go to filters + this.filterBarCursor = this.filterBar.getNearestFilter(this.filteredStarterContainers[this.cursor]); + this.setFilterMode(true); + success = true; + } } else { - this.starterIconsCursorObj.setVisible(false); - this.setSpecies(null); - this.startCursorObj.setVisible(true); + if (this.starterIconsCursorIndex <= this.starterSpecies.length - 2) { + this.starterIconsCursorIndex++; + this.moveStarterIconsCursor(this.starterIconsCursorIndex); + } else { + this.starterIconsCursorObj.setVisible(false); + this.setSpecies(null); + this.startCursorObj.setVisible(true); + } + success = true; } - success = true; - } - break; - case Button.LEFT: - if (!this.starterIconsCursorObj.visible) { - if (this.cursor % 9 !== 0) { - success = this.setCursor(this.cursor - 1); - } else { + break; + case Button.LEFT: + if (!this.starterIconsCursorObj.visible) { + if (this.cursor % 9 !== 0) { + success = this.setCursor(this.cursor - 1); + } else { // LEFT from filtered Pokemon, on the left edge - if (this.starterSpecies.length === 0) { + if (this.starterSpecies.length === 0) { // no starter in team > wrap around to the last column - success = this.setCursor(this.cursor + Math.min(8, numberOfStarters - this.cursor)); + success = this.setCursor(this.cursor + Math.min(8, numberOfStarters - this.cursor)); - } else if (onScreenCurrentRow < 7) { + } else if (onScreenCurrentRow < 7) { // at least one pokemon in team > for the first 7 rows, go to closest starter - this.cursorObj.setVisible(false); - this.starterIconsCursorIndex = findClosestStarterIndex(this.cursorObj.y - 1, this.starterSpecies.length); - this.moveStarterIconsCursor(this.starterIconsCursorIndex); + this.cursorObj.setVisible(false); + this.starterIconsCursorIndex = findClosestStarterIndex(this.cursorObj.y - 1, this.starterSpecies.length); + this.moveStarterIconsCursor(this.starterIconsCursorIndex); - } else { + } else { // at least one pokemon in team > from the bottom 2 rows, go to start run button - this.cursorObj.setVisible(false); - this.setSpecies(null); - this.startCursorObj.setVisible(true); + this.cursorObj.setVisible(false); + this.setSpecies(null); + this.startCursorObj.setVisible(true); + } + success = true; } - success = true; - } - } else if (numberOfStarters > 0) { + } else if (numberOfStarters > 0) { // LEFT from team > Go to closest filtered Pokemon - const closestRowIndex = findClosestStarterRow(this.starterIconsCursorIndex, onScreenNumberOfRows); - this.starterIconsCursorObj.setVisible(false); - this.cursorObj.setVisible(true); - this.setCursor(Math.min(onScreenFirstIndex + closestRowIndex * 9 + 8, onScreenLastIndex)); - success = true; - } else { - // LEFT from team and no Pokemon in filter > do nothing - success = false; - } - break; - case Button.RIGHT: - if (!this.starterIconsCursorObj.visible) { - // is not right edge - if (this.cursor % 9 < (currentRow < numOfRows - 1 ? 8 : (numberOfStarters - 1) % 9)) { - success = this.setCursor(this.cursor + 1); - } else { - // RIGHT from filtered Pokemon, on the right edge - if (this.starterSpecies.length === 0) { - // no selected starter in team > wrap around to the first column - success = this.setCursor(this.cursor - Math.min(8, this.cursor % 9)); - - } else if (onScreenCurrentRow < 7) { - // at least one pokemon in team > for the first 7 rows, go to closest starter - this.cursorObj.setVisible(false); - this.starterIconsCursorIndex = findClosestStarterIndex(this.cursorObj.y - 1, this.starterSpecies.length); - this.moveStarterIconsCursor(this.starterIconsCursorIndex); - - } else { - // at least one pokemon in team > from the bottom 2 rows, go to start run button - this.cursorObj.setVisible(false); - this.setSpecies(null); - this.startCursorObj.setVisible(true); - } + const closestRowIndex = findClosestStarterRow(this.starterIconsCursorIndex, onScreenNumberOfRows); + this.starterIconsCursorObj.setVisible(false); + this.cursorObj.setVisible(true); + this.setCursor(Math.min(onScreenFirstIndex + closestRowIndex * 9 + 8, onScreenLastIndex)); success = true; + } else { + // LEFT from team and no Pokemon in filter > do nothing + success = false; } - } else if (numberOfStarters > 0) { + break; + case Button.RIGHT: + if (!this.starterIconsCursorObj.visible) { + // is not right edge + if (this.cursor % 9 < (currentRow < numOfRows - 1 ? 8 : (numberOfStarters - 1) % 9)) { + success = this.setCursor(this.cursor + 1); + } else { + // RIGHT from filtered Pokemon, on the right edge + if (this.starterSpecies.length === 0) { + // no selected starter in team > wrap around to the first column + success = this.setCursor(this.cursor - Math.min(8, this.cursor % 9)); + + } else if (onScreenCurrentRow < 7) { + // at least one pokemon in team > for the first 7 rows, go to closest starter + this.cursorObj.setVisible(false); + this.starterIconsCursorIndex = findClosestStarterIndex(this.cursorObj.y - 1, this.starterSpecies.length); + this.moveStarterIconsCursor(this.starterIconsCursorIndex); + + } else { + // at least one pokemon in team > from the bottom 2 rows, go to start run button + this.cursorObj.setVisible(false); + this.setSpecies(null); + this.startCursorObj.setVisible(true); + } + success = true; + } + } else if (numberOfStarters > 0) { // RIGHT from team > Go to closest filtered Pokemon - const closestRowIndex = findClosestStarterRow(this.starterIconsCursorIndex, onScreenNumberOfRows); - this.starterIconsCursorObj.setVisible(false); - this.cursorObj.setVisible(true); - this.setCursor(Math.min(onScreenFirstIndex + closestRowIndex * 9, onScreenLastIndex - (onScreenLastIndex % 9))); - success = true; - } else { + const closestRowIndex = findClosestStarterRow(this.starterIconsCursorIndex, onScreenNumberOfRows); + this.starterIconsCursorObj.setVisible(false); + this.cursorObj.setVisible(true); + this.setCursor(Math.min(onScreenFirstIndex + closestRowIndex * 9, onScreenLastIndex - (onScreenLastIndex % 9))); + success = true; + } else { // RIGHT from team and no Pokemon in filter > do nothing - success = false; - } - break; + success = false; + } + break; } } } @@ -2126,7 +2132,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { break; } } - return [isDupe, removeIndex]; + return [ isDupe, removeIndex ]; } addToParty(species: PokemonSpecies, dexAttr: bigint, abilityIndex: integer, nature: Nature, moveset: StarterMoveset) { @@ -2204,29 +2210,29 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (gamepadType === "touch") { gamepadType = "keyboard"; switch (iconSetting) { - case SettingKeyboard.Button_Cycle_Shiny: - iconPath = "R.png"; - break; - case SettingKeyboard.Button_Cycle_Form: - iconPath = "F.png"; - break; - case SettingKeyboard.Button_Cycle_Gender: - iconPath = "G.png"; - break; - case SettingKeyboard.Button_Cycle_Ability: - iconPath = "E.png"; - break; - case SettingKeyboard.Button_Cycle_Nature: - iconPath = "N.png"; - break; - case SettingKeyboard.Button_Cycle_Variant: - iconPath = "V.png"; - break; - case SettingKeyboard.Button_Stats: - iconPath = "C.png"; - break; - default: - break; + case SettingKeyboard.Button_Cycle_Shiny: + iconPath = "R.png"; + break; + case SettingKeyboard.Button_Cycle_Form: + iconPath = "F.png"; + break; + case SettingKeyboard.Button_Cycle_Gender: + iconPath = "G.png"; + break; + case SettingKeyboard.Button_Cycle_Ability: + iconPath = "E.png"; + break; + case SettingKeyboard.Button_Cycle_Nature: + iconPath = "N.png"; + break; + case SettingKeyboard.Button_Cycle_Variant: + iconPath = "V.png"; + break; + case SettingKeyboard.Button_Stats: + iconPath = "C.png"; + break; + default: + break; } } else { iconPath = this.scene.inputController?.getIconForLatestInputRecorded(iconSetting); @@ -2236,7 +2242,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { controlLabel.setPosition(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY); iconElement.setVisible(true); controlLabel.setVisible(true); - this.instructionsContainer.add([iconElement, controlLabel]); + this.instructionsContainer.add([ iconElement, controlLabel ]); this.instructionRowY += 8; if (this.instructionRowY >= 24) { this.instructionRowY = 0; @@ -2259,7 +2265,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { controlLabel.setPosition(this.filterInstructionRowX + this.instructionRowTextOffset, this.filterInstructionRowY); iconElement.setVisible(true); controlLabel.setVisible(true); - this.filterInstructionsContainer.add([iconElement, controlLabel]); + this.filterInstructionsContainer.add([ iconElement, controlLabel ]); this.filterInstructionRowY += 8; if (this.filterInstructionRowY >= 24) { this.filterInstructionRowY = 0; @@ -2317,12 +2323,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { getValueLimit(): integer { const valueLimit = new Utils.IntegerHolder(0); switch (this.scene.gameMode.modeId) { - case GameModes.ENDLESS: - case GameModes.SPLICED_ENDLESS: - valueLimit.value = 15; - break; - default: - valueLimit.value = 10; + case GameModes.ENDLESS: + case GameModes.SPLICED_ENDLESS: + valueLimit.value = 15; + break; + default: + valueLimit.value = 10; } Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_POINTS, valueLimit); @@ -2526,22 +2532,22 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const sort = this.filterBar.getVals(DropDownColumn.SORT)[0]; this.filteredStarterContainers.sort((a, b) => { switch (sort.val) { - default: - break; - case SortCriteria.NUMBER: - return (a.species.speciesId - b.species.speciesId) * -sort.dir; - case SortCriteria.COST: - return (a.cost - b.cost) * -sort.dir; - case SortCriteria.CANDY: - const candyCountA = this.scene.gameData.starterData[a.species.speciesId].candyCount; - const candyCountB = this.scene.gameData.starterData[b.species.speciesId].candyCount; - return (candyCountA - candyCountB) * -sort.dir; - case SortCriteria.IV: - const avgIVsA = this.scene.gameData.dexData[a.species.speciesId].ivs.reduce((a, b) => a + b, 0) / this.scene.gameData.dexData[a.species.speciesId].ivs.length; - const avgIVsB = this.scene.gameData.dexData[b.species.speciesId].ivs.reduce((a, b) => a + b, 0) / this.scene.gameData.dexData[b.species.speciesId].ivs.length; - return (avgIVsA - avgIVsB) * -sort.dir; - case SortCriteria.NAME: - return a.species.name.localeCompare(b.species.name) * -sort.dir; + default: + break; + case SortCriteria.NUMBER: + return (a.species.speciesId - b.species.speciesId) * -sort.dir; + case SortCriteria.COST: + return (a.cost - b.cost) * -sort.dir; + case SortCriteria.CANDY: + const candyCountA = this.scene.gameData.starterData[a.species.speciesId].candyCount; + const candyCountB = this.scene.gameData.starterData[b.species.speciesId].candyCount; + return (candyCountA - candyCountB) * -sort.dir; + case SortCriteria.IV: + const avgIVsA = this.scene.gameData.dexData[a.species.speciesId].ivs.reduce((a, b) => a + b, 0) / this.scene.gameData.dexData[a.species.speciesId].ivs.length; + const avgIVsB = this.scene.gameData.dexData[b.species.speciesId].ivs.reduce((a, b) => a + b, 0) / this.scene.gameData.dexData[b.species.speciesId].ivs.length; + return (avgIVsA - avgIVsB) * -sort.dir; + case SortCriteria.NAME: + return a.species.name.localeCompare(b.species.name) * -sort.dir; } return 0; }); @@ -2553,7 +2559,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const maxColumns = 9; const maxRows = 9; const onScreenFirstIndex = this.scrollCursor * maxColumns; - const onScreenLastIndex = Math.min(this.filteredStarterContainers.length - 1, onScreenFirstIndex + maxRows * maxColumns -1); + const onScreenLastIndex = Math.min(this.filteredStarterContainers.length - 1, onScreenFirstIndex + maxRows * maxColumns - 1); this.starterSelectScrollBar.setScrollCursor(this.scrollCursor); @@ -2656,9 +2662,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonShinyIcon.setTint(tint); this.setSpecies(species); this.updateInstructions(); - } else { - console.warn("Species is undefined for cursor position", cursor); - this.setFilterMode(true); } } @@ -2719,7 +2722,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonAbilityText.off("pointerover"); this.pokemonPassiveText.off("pointerover"); - const starterAttributes : StarterAttributes | null = species ? {...this.starterPreferences[species.speciesId]} : null; + const starterAttributes : StarterAttributes | null = species ? { ...this.starterPreferences[species.speciesId] } : null; if (starterAttributes?.nature) { // load default nature from stater save data, if set @@ -2778,7 +2781,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { let growthReadable = Utils.toReadableString(GrowthRate[species.growthRate]); const growthAux = growthReadable.replace(" ", "_"); if (i18next.exists("growth:" + growthAux)) { - growthReadable = i18next.t("growth:"+ growthAux as any); + growthReadable = i18next.t("growth:" + growthAux as any); } this.pokemonGrowthRateText.setText(growthReadable); @@ -2951,7 +2954,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } - setSpeciesDetails(species: PokemonSpecies, shiny?: boolean, formIndex?: integer, female?: boolean, variant?: Variant, abilityIndex?: integer, natureIndex?: integer, forSeen: boolean = false): void { const oldProps = species ? this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor) : null; const oldAbilityIndex = this.abilityCursor > -1 ? this.abilityCursor : this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species); @@ -2961,8 +2963,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.natureCursor = -1; if (this.activeTooltip === "CANDY") { - const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId); - this.scene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`); + if (this.lastSpecies) { + const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId); + this.scene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`); + } else { + this.scene.ui.hideTooltip(); + } } if (species?.forms?.find(f => f.formKey === "female")) { @@ -2980,7 +2986,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.dexAttrCursor |= this.scene.gameData.getFormAttr(formIndex !== undefined ? formIndex : (formIndex = oldProps!.formIndex)); // TODO: is this bang correct? this.abilityCursor = abilityIndex !== undefined ? abilityIndex : (abilityIndex = oldAbilityIndex); this.natureCursor = natureIndex !== undefined ? natureIndex : (natureIndex = oldNatureIndex); - const [isInParty, partyIndex]: [boolean, number] = this.isInParty(species); // we use this to firstly check if the pokemon is in the party, and if so, to get the party index in order to update the icon image + const [ isInParty, partyIndex ]: [boolean, number] = this.isInParty(species); // we use this to firstly check if the pokemon is in the party, and if so, to get the party index in order to update the icon image if (isInParty) { this.updatePartyIcon(species, partyIndex); } @@ -3077,7 +3083,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const isVariant3Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_3); this.canCycleShiny = isNonShinyCaught && isShinyCaught; - this.canCycleVariant = !!shiny && [ isVariant1Caught, isVariant2Caught, isVariant3Caught].filter(v => v).length > 1; + this.canCycleVariant = !!shiny && [ isVariant1Caught, isVariant2Caught, isVariant3Caught ].filter(v => v).length > 1; const isMaleCaught = !!(caughtAttr & DexAttr.MALE); const isFemaleCaught = !!(caughtAttr & DexAttr.FEMALE); @@ -3327,6 +3333,18 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } this.moveStarterIconsCursor(this.starterIconsCursorIndex); + } else if (this.startCursorObj.visible && this.starterSpecies.length === 0) { + // On the start button and no more Pokemon in party + this.startCursorObj.setVisible(false); + if (this.filteredStarterContainers.length > 0) { + // Back to the first Pokemon if there is one + this.cursorObj.setVisible(true); + this.setCursor(0 + this.scrollCursor * 9); + } else { + // Back to filters + this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); + this.setFilterMode(true); + } } this.tryUpdateValue(); @@ -3344,16 +3362,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler { starter.label.setText(valueStr); let textStyle: TextStyle; switch (baseStarterValue - starterValue) { - case 0: - textStyle = TextStyle.WINDOW; - break; - case 1: - case 0.5: - textStyle = TextStyle.SUMMARY_BLUE; - break; - default: - textStyle = TextStyle.SUMMARY_GOLD; - break; + case 0: + textStyle = TextStyle.WINDOW; + break; + case 1: + case 0.5: + textStyle = TextStyle.SUMMARY_BLUE; + break; + default: + textStyle = TextStyle.SUMMARY_GOLD; + break; } if (baseStarterValue - starterValue > 0) { starter.label.setColor(this.getTextColor(textStyle)); @@ -3456,6 +3474,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.scene.clearPhaseQueue(); if (this.scene.gameMode.isChallenge) { this.scene.pushPhase(new SelectChallengePhase(this.scene)); + this.scene.pushPhase(new EncounterPhase(this.scene, false)); } else { this.scene.pushPhase(new TitlePhase(this.scene)); } @@ -3640,6 +3659,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { StarterPrefs.save(this.starterPreferences); this.cursor = -1; this.hideInstructions(); + this.activeTooltip = undefined; + this.scene.ui.hideTooltip(); + this.starterSelectContainer.setVisible(false); this.blockInput = false; diff --git a/src/ui/stats-container.ts b/src/ui/stats-container.ts index 06dd6e7c035..7e026ede83e 100644 --- a/src/ui/stats-container.ts +++ b/src/ui/stats-container.ts @@ -6,12 +6,12 @@ import i18next from "i18next"; const ivChartSize = 24; -const ivChartStatCoordMultipliers = [[0, -1], [0.825, -0.5], [0.825, 0.5], [-0.825, -0.5], [-0.825, 0.5], [0, 1]]; +const ivChartStatCoordMultipliers = [[ 0, -1 ], [ 0.825, -0.5 ], [ 0.825, 0.5 ], [ -0.825, -0.5 ], [ -0.825, 0.5 ], [ 0, 1 ]]; const speedLabelOffset = -3; const sideLabelOffset = 1; -const ivLabelOffset = [0, sideLabelOffset, -sideLabelOffset, sideLabelOffset, -sideLabelOffset, speedLabelOffset]; -const ivChartLabelyOffset= [0, 5, 0, 5, 0, 0]; // doing this so attack does not overlap with (+N) -const ivChartStatIndexes = [0, 1, 2, 5, 4, 3]; // swap special attack and speed +const ivLabelOffset = [ 0, sideLabelOffset, -sideLabelOffset, sideLabelOffset, -sideLabelOffset, speedLabelOffset ]; +const ivChartLabelyOffset = [ 0, 5, 0, 5, 0, 0 ]; // doing this so attack does not overlap with (+N) +const ivChartStatIndexes = [ 0, 1, 2, 5, 4, 3 ]; // swap special attack and speed const defaultIvChartData = new Array(12).fill(null).map(() => 0); @@ -39,7 +39,7 @@ export class StatsContainer extends Phaser.GameObjects.Container { .setStrokeStyle(1, 0x484050); ivChartBorder.setOrigin(0, 0); - const ivChartBgLines = [ [ 0, -1, 0, 1 ], [ -0.825, -0.5, 0.825, 0.5 ], [ 0.825, -0.5, -0.825, 0.5 ] ].map(coords => { + const ivChartBgLines = [[ 0, -1, 0, 1 ], [ -0.825, -0.5, 0.825, 0.5 ], [ 0.825, -0.5, -0.825, 0.5 ]].map(coords => { const line = new Phaser.GameObjects.Line(this.scene, ivChartBg.x, ivChartBg.y, ivChartSize * coords[0], ivChartSize * coords[1], ivChartSize * coords[2], ivChartSize * coords[3], 0xffffff) .setLineWidth(0.5); line.setOrigin(0, 0); diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 28c3ccdb2e4..b35c0ca3303 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -87,6 +87,10 @@ export default class SummaryUiHandler extends UiHandler { private moveAccuracyText: Phaser.GameObjects.Text; private moveCategoryIcon: Phaser.GameObjects.Sprite; private summaryPageTransitionContainer: Phaser.GameObjects.Container; + private friendshipShadow: Phaser.GameObjects.Sprite; + private friendshipText: Phaser.GameObjects.Text; + private friendshipIcon: Phaser.GameObjects.Sprite; + private friendshipOverlay: Phaser.GameObjects.Sprite; private descriptionScrollTween: Phaser.Tweens.Tween | null; private moveCursorBlinkTimer: Phaser.Time.TimerEvent | null; @@ -187,6 +191,25 @@ export default class SummaryUiHandler extends UiHandler { this.candyCountText.setOrigin(0, 0); this.summaryContainer.add(this.candyCountText); + this.friendshipIcon = this.scene.add.sprite(13, -60, "friendship"); + this.friendshipIcon.setScale(0.8); + this.summaryContainer.add(this.friendshipIcon); + + this.friendshipOverlay = this.scene.add.sprite(13, -60, "friendship_overlay"); + this.friendshipOverlay.setScale(0.8); + this.summaryContainer.add(this.friendshipOverlay); + + this.friendshipShadow = this.scene.add.sprite(13, -60, "friendship"); + this.friendshipShadow.setTint(0x000000); + this.friendshipShadow.setAlpha(0.50); + this.friendshipShadow.setScale(0.8); + this.friendshipShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains); + this.summaryContainer.add(this.friendshipShadow); + + this.friendshipText = addTextObject(this.scene, 20, -66, "x0", TextStyle.WINDOW_ALT, { fontSize: "76px" }); + this.friendshipText.setOrigin(0, 0); + this.summaryContainer.add(this.friendshipText); + this.championRibbon = this.scene.add.image(88, -146, "champion_ribbon"); this.championRibbon.setOrigin(0, 0); //this.championRibbon.setScale(0.8); @@ -292,6 +315,7 @@ export default class SummaryUiHandler extends UiHandler { this.candyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0]))); this.candyOverlay.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1]))); + this.numberText.setText(Utils.padInt(this.pokemon.species.speciesId, 4)); this.numberText.setColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD)); this.numberText.setShadowColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD, true)); @@ -345,6 +369,15 @@ export default class SummaryUiHandler extends UiHandler { this.candyShadow.setCrop(0, 0, 16, candyCropY); + if (this.friendshipShadow.visible) { + this.friendshipShadow.on("pointerover", () => this.scene.ui.showTooltip("", `${i18next.t("pokemonSummary:friendship")}`, true)); + this.friendshipShadow.on("pointerout", () => this.scene.ui.hideTooltip()); + } + + this.friendshipText.setText(`${this.pokemon?.friendship || "0"} / 255`); + + this.friendshipShadow.setCrop(0, 0, 16, 16 - (16 * ((this.pokemon?.friendship || 0) / 255))); + const doubleShiny = isFusion && this.pokemon.shiny && this.pokemon.fusionShiny; const baseVariant = !doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant; @@ -373,22 +406,22 @@ export default class SummaryUiHandler extends UiHandler { this.genderText.setShadowColor(getGenderColor(this.pokemon.getGender(true), true)); switch (this.summaryUiMode) { - case SummaryUiMode.DEFAULT: - const page = args.length < 2 ? Page.PROFILE : args[2] as Page; - this.hideMoveEffect(true); - this.setCursor(page); - if (args.length > 3) { - this.selectCallback = args[3]; - } - break; - case SummaryUiMode.LEARN_MOVE: - this.newMove = args[2] as Move; - this.moveSelectFunction = args[3] as Function; + case SummaryUiMode.DEFAULT: + const page = args.length < 2 ? Page.PROFILE : args[2] as Page; + this.hideMoveEffect(true); + this.setCursor(page); + if (args.length > 3) { + this.selectCallback = args[3]; + } + break; + case SummaryUiMode.LEARN_MOVE: + this.newMove = args[2] as Move; + this.moveSelectFunction = args[3] as Function; - this.showMoveEffect(true); - this.setCursor(Page.MOVES); - this.showMoveSelect(); - break; + this.showMoveEffect(true); + this.setCursor(Page.MOVES); + this.showMoveSelect(); + break; } const fromSummary = args.length >= 2; @@ -456,25 +489,25 @@ export default class SummaryUiHandler extends UiHandler { success = true; } else { switch (button) { - case Button.UP: - success = this.setCursor(this.moveCursor ? this.moveCursor - 1 : 4); - break; - case Button.DOWN: - success = this.setCursor(this.moveCursor < 4 ? this.moveCursor + 1 : 0); - break; - case Button.LEFT: - this.moveSelect = false; - this.setCursor(Page.STATS); - if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { - this.hideMoveEffect(); - this.destroyBlinkCursor(); - success = true; + case Button.UP: + success = this.setCursor(this.moveCursor ? this.moveCursor - 1 : 4); break; - } else { - this.hideMoveSelect(); - success = true; + case Button.DOWN: + success = this.setCursor(this.moveCursor < 4 ? this.moveCursor + 1 : 0); break; - } + case Button.LEFT: + this.moveSelect = false; + this.setCursor(Page.STATS); + if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { + this.hideMoveEffect(); + this.destroyBlinkCursor(); + success = true; + break; + } else { + this.hideMoveSelect(); + success = true; + break; + } } } } else { @@ -513,35 +546,35 @@ export default class SummaryUiHandler extends UiHandler { } else { const pages = Utils.getEnumValues(Page); switch (button) { - case Button.UP: - case Button.DOWN: - if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { - break; - } else if (!fromPartyMode) { - break; - } - const isDown = button === Button.DOWN; - const party = this.scene.getParty(); - const partyMemberIndex = this.pokemon ? party.indexOf(this.pokemon) : -1; - if ((isDown && partyMemberIndex < party.length - 1) || (!isDown && partyMemberIndex)) { - const page = this.cursor; - this.clear(); - this.show([ party[partyMemberIndex + (isDown ? 1 : -1)], this.summaryUiMode, page ]); - } - break; - case Button.LEFT: - if (this.cursor) { - success = this.setCursor(this.cursor - 1); - } - break; - case Button.RIGHT: - if (this.cursor < pages.length - 1) { - success = this.setCursor(this.cursor + 1); - if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.cursor === Page.MOVES) { - this.moveSelect = true; + case Button.UP: + case Button.DOWN: + if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { + break; + } else if (!fromPartyMode) { + break; } - } - break; + const isDown = button === Button.DOWN; + const party = this.scene.getParty(); + const partyMemberIndex = this.pokemon ? party.indexOf(this.pokemon) : -1; + if ((isDown && partyMemberIndex < party.length - 1) || (!isDown && partyMemberIndex)) { + const page = this.cursor; + this.clear(); + this.show([ party[partyMemberIndex + (isDown ? 1 : -1)], this.summaryUiMode, page ]); + } + break; + case Button.LEFT: + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } + break; + case Button.RIGHT: + if (this.cursor < pages.length - 1) { + success = this.setCursor(this.cursor + 1); + if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.cursor === Page.MOVES) { + this.moveSelect = true; + } + } + break; } } } @@ -652,7 +685,7 @@ export default class SummaryUiHandler extends UiHandler { onComplete: () => { if (forward) { this.populatePageContainer(this.summaryPageContainer); - if (this.cursor===Page.MOVES) { + if (this.cursor === Page.MOVES) { this.moveCursorObj = null; this.showMoveSelect(); this.showMoveEffect(); @@ -697,308 +730,308 @@ export default class SummaryUiHandler extends UiHandler { } switch (page) { - case Page.PROFILE: - const profileContainer = this.scene.add.container(0, -pageBg.height); - pageContainer.add(profileContainer); + case Page.PROFILE: + const profileContainer = this.scene.add.container(0, -pageBg.height); + pageContainer.add(profileContainer); - // TODO: should add field for original trainer name to Pokemon object, to support gift/traded Pokemon from MEs - const trainerText = addBBCodeTextObject(this.scene, 7, 12, `${i18next.t("pokemonSummary:ot")}/${getBBCodeFrag(loggedInUser?.username || i18next.t("pokemonSummary:unknown"), this.scene.gameData.gender === PlayerGender.FEMALE ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY_BLUE)}`, TextStyle.SUMMARY_ALT); - trainerText.setOrigin(0, 0); - profileContainer.add(trainerText); + // TODO: should add field for original trainer name to Pokemon object, to support gift/traded Pokemon from MEs + const trainerText = addBBCodeTextObject(this.scene, 7, 12, `${i18next.t("pokemonSummary:ot")}/${getBBCodeFrag(loggedInUser?.username || i18next.t("pokemonSummary:unknown"), this.scene.gameData.gender === PlayerGender.FEMALE ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY_BLUE)}`, TextStyle.SUMMARY_ALT); + trainerText.setOrigin(0, 0); + profileContainer.add(trainerText); - const trainerIdText = addTextObject(this.scene, 174, 12, this.scene.gameData.trainerId.toString(), TextStyle.SUMMARY_ALT); - trainerIdText.setOrigin(0, 0); - profileContainer.add(trainerIdText); + const trainerIdText = addTextObject(this.scene, 174, 12, this.scene.gameData.trainerId.toString(), TextStyle.SUMMARY_ALT); + trainerIdText.setOrigin(0, 0); + profileContainer.add(trainerIdText); - const typeLabel = addTextObject(this.scene, 7, 28, `${i18next.t("pokemonSummary:type")}/`, TextStyle.WINDOW_ALT); - typeLabel.setOrigin(0, 0); - profileContainer.add(typeLabel); + const typeLabel = addTextObject(this.scene, 7, 28, `${i18next.t("pokemonSummary:type")}/`, TextStyle.WINDOW_ALT); + typeLabel.setOrigin(0, 0); + profileContainer.add(typeLabel); - const getTypeIcon = (index: integer, type: Type, tera: boolean = false) => { - const xCoord = typeLabel.width * typeLabel.scale + 9 + 34 * index; - const typeIcon = !tera - ? this.scene.add.sprite(xCoord, 42, Utils.getLocalizedSpriteKey("types"), Type[type].toLowerCase()) - : this.scene.add.sprite(xCoord, 42, "type_tera"); - if (tera) { - typeIcon.setScale(0.5); - const typeRgb = getTypeRgb(type); - typeIcon.setTint(Phaser.Display.Color.GetColor(typeRgb[0], typeRgb[1], typeRgb[2])); - } - typeIcon.setOrigin(0, 1); - return typeIcon; - }; - - const types = this.pokemon?.getTypes(false, false, true)!; // TODO: is this bang correct? - profileContainer.add(getTypeIcon(0, types[0])); - if (types.length > 1) { - profileContainer.add(getTypeIcon(1, types[1])); - } - if (this.pokemon?.isTerastallized()) { - profileContainer.add(getTypeIcon(types.length, this.pokemon.getTeraType(), true)); - } - - if (this.pokemon?.getLuck()) { - const luckLabelText = addTextObject(this.scene, 141, 28, i18next.t("common:luckIndicator"), TextStyle.SUMMARY_ALT); - luckLabelText.setOrigin(0, 0); - profileContainer.add(luckLabelText); - - const luckText = addTextObject(this.scene, 141 + luckLabelText.displayWidth + 2, 28, this.pokemon.getLuck().toString(), TextStyle.SUMMARY); - luckText.setOrigin(0, 0); - luckText.setTint(getVariantTint((Math.min(this.pokemon.getLuck() - 1, 2)) as Variant)); - profileContainer.add(luckText); - } - - this.abilityContainer = { - labelImage: this.scene.add.image(0, 0, "summary_profile_ability"), - ability: this.pokemon?.getAbility(true)!, // TODO: is this bang correct? - nameText: null, - descriptionText: null}; - - const allAbilityInfo = [this.abilityContainer]; // Creates an array to iterate through - // Only add to the array and set up displaying a passive if it's unlocked - if (this.pokemon?.hasPassive()) { - this.passiveContainer = { - labelImage: this.scene.add.image(0, 0, "summary_profile_passive"), - ability: this.pokemon.getPassiveAbility(), - nameText: null, - descriptionText: null}; - allAbilityInfo.push(this.passiveContainer); - - // Sets up the pixel button prompt image - this.abilityPrompt = this.scene.add.image(0, 0, !this.scene.inputController?.gamepadSupport ? "summary_profile_prompt_z" : "summary_profile_prompt_a"); - this.abilityPrompt.setPosition(8, 43); - this.abilityPrompt.setVisible(true); - this.abilityPrompt.setOrigin(0, 0); - profileContainer.add(this.abilityPrompt); - } - - allAbilityInfo.forEach(abilityInfo => { - abilityInfo.labelImage.setPosition(17, 43); - abilityInfo.labelImage.setVisible(true); - abilityInfo.labelImage.setOrigin(0, 0); - profileContainer.add(abilityInfo.labelImage); - - abilityInfo.nameText = addTextObject(this.scene, 7, 66, abilityInfo.ability?.name!, TextStyle.SUMMARY_ALT); // TODO: is this bang correct? - abilityInfo.nameText.setOrigin(0, 1); - profileContainer.add(abilityInfo.nameText); - - abilityInfo.descriptionText = addTextObject(this.scene, 7, 69, abilityInfo.ability?.description!, TextStyle.WINDOW_ALT, { wordWrap: { width: 1224 } }); // TODO: is this bang correct? - abilityInfo.descriptionText.setOrigin(0, 0); - profileContainer.add(abilityInfo.descriptionText); - - // Sets up the mask that hides the description text to give an illusion of scrolling - const descriptionTextMaskRect = this.scene.make.graphics({}); - descriptionTextMaskRect.setScale(6); - descriptionTextMaskRect.fillStyle(0xFFFFFF); - descriptionTextMaskRect.beginPath(); - descriptionTextMaskRect.fillRect(110, 90.5, 206, 31); - - const abilityDescriptionTextMask = descriptionTextMaskRect.createGeometryMask(); - - abilityInfo.descriptionText.setMask(abilityDescriptionTextMask); - - const abilityDescriptionLineCount = Math.floor(abilityInfo.descriptionText.displayHeight / 14.83); - - // Animates the description text moving upwards - if (abilityDescriptionLineCount > 2) { - abilityInfo.descriptionText.setY(69); - this.descriptionScrollTween = this.scene.tweens.add({ - targets: abilityInfo.descriptionText, - delay: Utils.fixedInt(2000), - loop: -1, - hold: Utils.fixedInt(2000), - duration: Utils.fixedInt((abilityDescriptionLineCount - 2) * 2000), - y: `-=${14.83 * (abilityDescriptionLineCount - 2)}` - }); - } - }); - // Turn off visibility of passive info by default - this.passiveContainer?.labelImage.setVisible(false); - this.passiveContainer?.nameText?.setVisible(false); - this.passiveContainer?.descriptionText?.setVisible(false); - - const closeFragment = getBBCodeFrag("", TextStyle.WINDOW_ALT); - const rawNature = Utils.toReadableString(Nature[this.pokemon?.getNature()!]); // TODO: is this bang correct? - const nature = `${getBBCodeFrag(Utils.toReadableString(getNatureName(this.pokemon?.getNature()!)), TextStyle.SUMMARY_RED)}${closeFragment}`; // TODO: is this bang correct? - - const memoString = i18next.t("pokemonSummary:memoString", { - metFragment: i18next.t(`pokemonSummary:metFragment.${this.pokemon?.metBiome === -1? "apparently": "normal"}`, { - biome: `${getBBCodeFrag(getBiomeName(this.pokemon?.metBiome!), TextStyle.SUMMARY_RED)}${closeFragment}`, // TODO: is this bang correct? - level: `${getBBCodeFrag(this.pokemon?.metLevel.toString()!, TextStyle.SUMMARY_RED)}${closeFragment}`, // TODO: is this bang correct? - wave: `${getBBCodeFrag((this.pokemon?.metWave ? this.pokemon.metWave.toString()! : i18next.t("pokemonSummary:unknownTrainer")), TextStyle.SUMMARY_RED)}${closeFragment}`, - }), - natureFragment: i18next.t(`pokemonSummary:natureFragment.${rawNature}`, { nature: nature }) - }); - - const memoText = addBBCodeTextObject(this.scene, 7, 113, String(memoString), TextStyle.WINDOW_ALT); - memoText.setOrigin(0, 0); - profileContainer.add(memoText); - break; - case Page.STATS: - const statsContainer = this.scene.add.container(0, -pageBg.height); - pageContainer.add(statsContainer); - - PERMANENT_STATS.forEach((stat, s) => { - const statName = i18next.t(getStatKey(stat)); - const rowIndex = s % 3; - const colIndex = Math.floor(s / 3); - - const natureStatMultiplier = getNatureStatMultiplier(this.pokemon?.getNature()!, s); // TODO: is this bang correct? - - const statLabel = addTextObject(this.scene, 27 + 115 * colIndex + (colIndex === 1 ? 5 : 0), 56 + 16 * rowIndex, statName, natureStatMultiplier === 1 ? TextStyle.SUMMARY : natureStatMultiplier > 1 ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY_BLUE); - statLabel.setOrigin(0.5, 0); - statsContainer.add(statLabel); - - const statValueText = stat !== Stat.HP - ? Utils.formatStat(this.pokemon?.getStat(stat)!) // TODO: is this bang correct? - : `${Utils.formatStat(this.pokemon?.hp!, true)}/${Utils.formatStat(this.pokemon?.getMaxHp()!, true)}`; // TODO: are those bangs correct? - - const statValue = addTextObject(this.scene, 120 + 88 * colIndex, 56 + 16 * rowIndex, statValueText, TextStyle.WINDOW_ALT); - statValue.setOrigin(1, 0); - statsContainer.add(statValue); - }); - - const itemModifiers = (this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier - && m.pokemonId === this.pokemon?.id, this.playerParty) as PokemonHeldItemModifier[]) - .sort(modifierSortFunc); - - itemModifiers.forEach((item, i) => { - const icon = item.getIcon(this.scene, true); - - icon.setPosition((i % 17) * 12 + 3, 14 * Math.floor(i / 17) + 15); - statsContainer.add(icon); - - icon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 32, 32), Phaser.Geom.Rectangle.Contains); - icon.on("pointerover", () => (this.scene as BattleScene).ui.showTooltip(item.type.name, item.type.getDescription(this.scene), true)); - icon.on("pointerout", () => (this.scene as BattleScene).ui.hideTooltip()); - }); - - const pkmLvl = this.pokemon?.level!; // TODO: is this bang correct? - const pkmLvlExp = this.pokemon?.levelExp!; // TODO: is this bang correct? - const pkmExp = this.pokemon?.exp!; // TODO: is this bang correct? - const pkmSpeciesGrowthRate = this.pokemon?.species.growthRate!; // TODO: is this bang correct? - const relLvExp = getLevelRelExp(pkmLvl + 1, pkmSpeciesGrowthRate); - const expRatio = pkmLvl < this.scene.getMaxExpLevel() ? pkmLvlExp / relLvExp : 0; - - const expLabel = addTextObject(this.scene, 6, 112, i18next.t("pokemonSummary:expPoints"), TextStyle.SUMMARY); - expLabel.setOrigin(0, 0); - statsContainer.add(expLabel); - - const nextLvExpLabel = addTextObject(this.scene, 6, 128, i18next.t("pokemonSummary:nextLv"), TextStyle.SUMMARY); - nextLvExpLabel.setOrigin(0, 0); - statsContainer.add(nextLvExpLabel); - - const expText = addTextObject(this.scene, 208, 112, pkmExp.toString(), TextStyle.WINDOW_ALT); - expText.setOrigin(1, 0); - statsContainer.add(expText); - - const nextLvExp = pkmLvl < this.scene.getMaxExpLevel() - ? getLevelTotalExp(pkmLvl + 1, pkmSpeciesGrowthRate) - pkmExp - : 0; - const nextLvExpText = addTextObject(this.scene, 208, 128, nextLvExp.toString(), TextStyle.WINDOW_ALT); - nextLvExpText.setOrigin(1, 0); - statsContainer.add(nextLvExpText); - - const expOverlay = this.scene.add.image(140, 145, "summary_stats_overlay_exp"); - expOverlay.setOrigin(0, 0); - statsContainer.add(expOverlay); - - const expMaskRect = this.scene.make.graphics({}); - expMaskRect.setScale(6); - expMaskRect.fillStyle(0xFFFFFF); - expMaskRect.beginPath(); - expMaskRect.fillRect(140 + pageContainer.x, 145 + pageContainer.y + 21, Math.floor(expRatio * 64), 3); - - const expMask = expMaskRect.createGeometryMask(); - - expOverlay.setMask(expMask); - break; - case Page.MOVES: - this.movesContainer = this.scene.add.container(5, -pageBg.height + 26); - pageContainer.add(this.movesContainer); - - this.extraMoveRowContainer = this.scene.add.container(0, 64); - this.extraMoveRowContainer.setVisible(false); - this.movesContainer.add(this.extraMoveRowContainer); - - const extraRowOverlay = this.scene.add.image(-2, 1, "summary_moves_overlay_row"); - extraRowOverlay.setOrigin(0, 1); - this.extraMoveRowContainer.add(extraRowOverlay); - - const extraRowText = addTextObject(this.scene, 35, 0, this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.newMove ? this.newMove.name : i18next.t("pokemonSummary:cancel"), - this.summaryUiMode === SummaryUiMode.LEARN_MOVE ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY); - extraRowText.setOrigin(0, 1); - this.extraMoveRowContainer.add(extraRowText); - - if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { - this.extraMoveRowContainer.setVisible(true); - - if (this.newMove && this.pokemon) { - const spriteKey = Utils.getLocalizedSpriteKey("types"); - const moveType = this.pokemon.getMoveType(this.newMove); - const newMoveTypeIcon = this.scene.add.sprite(0, 0, spriteKey, Type[moveType].toLowerCase()); - newMoveTypeIcon.setOrigin(0, 1); - this.extraMoveRowContainer.add(newMoveTypeIcon); - } - const ppOverlay = this.scene.add.image(163, -1, "summary_moves_overlay_pp"); - ppOverlay.setOrigin(0, 1); - this.extraMoveRowContainer.add(ppOverlay); - - const pp = Utils.padInt(this.newMove?.pp!, 2, " "); // TODO: is this bang correct? - const ppText = addTextObject(this.scene, 173, 1, `${pp}/${pp}`, TextStyle.WINDOW); - ppText.setOrigin(0, 1); - this.extraMoveRowContainer.add(ppText); - } - - this.moveRowsContainer = this.scene.add.container(0, 0); - this.movesContainer.add(this.moveRowsContainer); - - for (let m = 0; m < 4; m++) { - const move: PokemonMove | null = this.pokemon && this.pokemon.moveset.length > m ? this.pokemon?.moveset[m] : null; - const moveRowContainer = this.scene.add.container(0, 16 * m); - this.moveRowsContainer.add(moveRowContainer); - - if (move && this.pokemon) { - const spriteKey = Utils.getLocalizedSpriteKey("types"); - const moveType = this.pokemon.getMoveType(move.getMove()); - const typeIcon = this.scene.add.sprite(0, 0, spriteKey, Type[moveType].toLowerCase()); + const getTypeIcon = (index: integer, type: Type, tera: boolean = false) => { + const xCoord = typeLabel.width * typeLabel.scale + 9 + 34 * index; + const typeIcon = !tera + ? this.scene.add.sprite(xCoord, 42, Utils.getLocalizedSpriteKey("types"), Type[type].toLowerCase()) + : this.scene.add.sprite(xCoord, 42, "type_tera"); + if (tera) { + typeIcon.setScale(0.5); + const typeRgb = getTypeRgb(type); + typeIcon.setTint(Phaser.Display.Color.GetColor(typeRgb[0], typeRgb[1], typeRgb[2])); + } typeIcon.setOrigin(0, 1); - moveRowContainer.add(typeIcon); + return typeIcon; + }; + + const types = this.pokemon?.getTypes(false, false, true)!; // TODO: is this bang correct? + profileContainer.add(getTypeIcon(0, types[0])); + if (types.length > 1) { + profileContainer.add(getTypeIcon(1, types[1])); + } + if (this.pokemon?.isTerastallized()) { + profileContainer.add(getTypeIcon(types.length, this.pokemon.getTeraType(), true)); } - const moveText = addTextObject(this.scene, 35, 0, move ? move.getName() : "-", TextStyle.SUMMARY); - moveText.setOrigin(0, 1); - moveRowContainer.add(moveText); + if (this.pokemon?.getLuck()) { + const luckLabelText = addTextObject(this.scene, 141, 28, i18next.t("common:luckIndicator"), TextStyle.SUMMARY_ALT); + luckLabelText.setOrigin(0, 0); + profileContainer.add(luckLabelText); - const ppOverlay = this.scene.add.image(163, -1, "summary_moves_overlay_pp"); - ppOverlay.setOrigin(0, 1); - moveRowContainer.add(ppOverlay); - - const ppText = addTextObject(this.scene, 173, 1, "--/--", TextStyle.WINDOW); - ppText.setOrigin(0, 1); - - if (move) { - const maxPP = move.getMovePp(); - const pp = maxPP - move.ppUsed; - ppText.setText(`${Utils.padInt(pp, 2, " ")}/${Utils.padInt(maxPP, 2, " ")}`); + const luckText = addTextObject(this.scene, 141 + luckLabelText.displayWidth + 2, 28, this.pokemon.getLuck().toString(), TextStyle.SUMMARY); + luckText.setOrigin(0, 0); + luckText.setTint(getVariantTint((Math.min(this.pokemon.getLuck() - 1, 2)) as Variant)); + profileContainer.add(luckText); } - moveRowContainer.add(ppText); - } + this.abilityContainer = { + labelImage: this.scene.add.image(0, 0, "summary_profile_ability"), + ability: this.pokemon?.getAbility(true)!, // TODO: is this bang correct? + nameText: null, + descriptionText: null }; - this.moveDescriptionText = addTextObject(this.scene, 2, 84, "", TextStyle.WINDOW_ALT, { wordWrap: { width: 1212 } }); - this.movesContainer.add(this.moveDescriptionText); + const allAbilityInfo = [ this.abilityContainer ]; // Creates an array to iterate through + // Only add to the array and set up displaying a passive if it's unlocked + if (this.pokemon?.hasPassive()) { + this.passiveContainer = { + labelImage: this.scene.add.image(0, 0, "summary_profile_passive"), + ability: this.pokemon.getPassiveAbility(), + nameText: null, + descriptionText: null }; + allAbilityInfo.push(this.passiveContainer); - const moveDescriptionTextMaskRect = this.scene.make.graphics({}); - moveDescriptionTextMaskRect.setScale(6); - moveDescriptionTextMaskRect.fillStyle(0xFFFFFF); - moveDescriptionTextMaskRect.beginPath(); - moveDescriptionTextMaskRect.fillRect(112, 130, 202, 46); + // Sets up the pixel button prompt image + this.abilityPrompt = this.scene.add.image(0, 0, !this.scene.inputController?.gamepadSupport ? "summary_profile_prompt_z" : "summary_profile_prompt_a"); + this.abilityPrompt.setPosition(8, 43); + this.abilityPrompt.setVisible(true); + this.abilityPrompt.setOrigin(0, 0); + profileContainer.add(this.abilityPrompt); + } - const moveDescriptionTextMask = moveDescriptionTextMaskRect.createGeometryMask(); + allAbilityInfo.forEach(abilityInfo => { + abilityInfo.labelImage.setPosition(17, 43); + abilityInfo.labelImage.setVisible(true); + abilityInfo.labelImage.setOrigin(0, 0); + profileContainer.add(abilityInfo.labelImage); - this.moveDescriptionText.setMask(moveDescriptionTextMask); - break; + abilityInfo.nameText = addTextObject(this.scene, 7, 66, abilityInfo.ability?.name!, TextStyle.SUMMARY_ALT); // TODO: is this bang correct? + abilityInfo.nameText.setOrigin(0, 1); + profileContainer.add(abilityInfo.nameText); + + abilityInfo.descriptionText = addTextObject(this.scene, 7, 69, abilityInfo.ability?.description!, TextStyle.WINDOW_ALT, { wordWrap: { width: 1224 }}); // TODO: is this bang correct? + abilityInfo.descriptionText.setOrigin(0, 0); + profileContainer.add(abilityInfo.descriptionText); + + // Sets up the mask that hides the description text to give an illusion of scrolling + const descriptionTextMaskRect = this.scene.make.graphics({}); + descriptionTextMaskRect.setScale(6); + descriptionTextMaskRect.fillStyle(0xFFFFFF); + descriptionTextMaskRect.beginPath(); + descriptionTextMaskRect.fillRect(110, 90.5, 206, 31); + + const abilityDescriptionTextMask = descriptionTextMaskRect.createGeometryMask(); + + abilityInfo.descriptionText.setMask(abilityDescriptionTextMask); + + const abilityDescriptionLineCount = Math.floor(abilityInfo.descriptionText.displayHeight / 14.83); + + // Animates the description text moving upwards + if (abilityDescriptionLineCount > 2) { + abilityInfo.descriptionText.setY(69); + this.descriptionScrollTween = this.scene.tweens.add({ + targets: abilityInfo.descriptionText, + delay: Utils.fixedInt(2000), + loop: -1, + hold: Utils.fixedInt(2000), + duration: Utils.fixedInt((abilityDescriptionLineCount - 2) * 2000), + y: `-=${14.83 * (abilityDescriptionLineCount - 2)}` + }); + } + }); + // Turn off visibility of passive info by default + this.passiveContainer?.labelImage.setVisible(false); + this.passiveContainer?.nameText?.setVisible(false); + this.passiveContainer?.descriptionText?.setVisible(false); + + const closeFragment = getBBCodeFrag("", TextStyle.WINDOW_ALT); + const rawNature = Utils.toReadableString(Nature[this.pokemon?.getNature()!]); // TODO: is this bang correct? + const nature = `${getBBCodeFrag(Utils.toReadableString(getNatureName(this.pokemon?.getNature()!)), TextStyle.SUMMARY_RED)}${closeFragment}`; // TODO: is this bang correct? + + const memoString = i18next.t("pokemonSummary:memoString", { + metFragment: i18next.t(`pokemonSummary:metFragment.${this.pokemon?.metBiome === -1 ? "apparently" : "normal"}`, { + biome: `${getBBCodeFrag(getBiomeName(this.pokemon?.metBiome!), TextStyle.SUMMARY_RED)}${closeFragment}`, // TODO: is this bang correct? + level: `${getBBCodeFrag(this.pokemon?.metLevel.toString()!, TextStyle.SUMMARY_RED)}${closeFragment}`, // TODO: is this bang correct? + wave: `${getBBCodeFrag((this.pokemon?.metWave ? this.pokemon.metWave.toString()! : i18next.t("pokemonSummary:unknownTrainer")), TextStyle.SUMMARY_RED)}${closeFragment}`, + }), + natureFragment: i18next.t(`pokemonSummary:natureFragment.${rawNature}`, { nature: nature }) + }); + + const memoText = addBBCodeTextObject(this.scene, 7, 113, String(memoString), TextStyle.WINDOW_ALT); + memoText.setOrigin(0, 0); + profileContainer.add(memoText); + break; + case Page.STATS: + const statsContainer = this.scene.add.container(0, -pageBg.height); + pageContainer.add(statsContainer); + + PERMANENT_STATS.forEach((stat, s) => { + const statName = i18next.t(getStatKey(stat)); + const rowIndex = s % 3; + const colIndex = Math.floor(s / 3); + + const natureStatMultiplier = getNatureStatMultiplier(this.pokemon?.getNature()!, s); // TODO: is this bang correct? + + const statLabel = addTextObject(this.scene, 27 + 115 * colIndex + (colIndex === 1 ? 5 : 0), 56 + 16 * rowIndex, statName, natureStatMultiplier === 1 ? TextStyle.SUMMARY : natureStatMultiplier > 1 ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY_BLUE); + statLabel.setOrigin(0.5, 0); + statsContainer.add(statLabel); + + const statValueText = stat !== Stat.HP + ? Utils.formatStat(this.pokemon?.getStat(stat)!) // TODO: is this bang correct? + : `${Utils.formatStat(this.pokemon?.hp!, true)}/${Utils.formatStat(this.pokemon?.getMaxHp()!, true)}`; // TODO: are those bangs correct? + + const statValue = addTextObject(this.scene, 120 + 88 * colIndex, 56 + 16 * rowIndex, statValueText, TextStyle.WINDOW_ALT); + statValue.setOrigin(1, 0); + statsContainer.add(statValue); + }); + + const itemModifiers = (this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier + && m.pokemonId === this.pokemon?.id, this.playerParty) as PokemonHeldItemModifier[]) + .sort(modifierSortFunc); + + itemModifiers.forEach((item, i) => { + const icon = item.getIcon(this.scene, true); + + icon.setPosition((i % 17) * 12 + 3, 14 * Math.floor(i / 17) + 15); + statsContainer.add(icon); + + icon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 32, 32), Phaser.Geom.Rectangle.Contains); + icon.on("pointerover", () => (this.scene as BattleScene).ui.showTooltip(item.type.name, item.type.getDescription(this.scene), true)); + icon.on("pointerout", () => (this.scene as BattleScene).ui.hideTooltip()); + }); + + const pkmLvl = this.pokemon?.level!; // TODO: is this bang correct? + const pkmLvlExp = this.pokemon?.levelExp!; // TODO: is this bang correct? + const pkmExp = this.pokemon?.exp!; // TODO: is this bang correct? + const pkmSpeciesGrowthRate = this.pokemon?.species.growthRate!; // TODO: is this bang correct? + const relLvExp = getLevelRelExp(pkmLvl + 1, pkmSpeciesGrowthRate); + const expRatio = pkmLvl < this.scene.getMaxExpLevel() ? pkmLvlExp / relLvExp : 0; + + const expLabel = addTextObject(this.scene, 6, 112, i18next.t("pokemonSummary:expPoints"), TextStyle.SUMMARY); + expLabel.setOrigin(0, 0); + statsContainer.add(expLabel); + + const nextLvExpLabel = addTextObject(this.scene, 6, 128, i18next.t("pokemonSummary:nextLv"), TextStyle.SUMMARY); + nextLvExpLabel.setOrigin(0, 0); + statsContainer.add(nextLvExpLabel); + + const expText = addTextObject(this.scene, 208, 112, pkmExp.toString(), TextStyle.WINDOW_ALT); + expText.setOrigin(1, 0); + statsContainer.add(expText); + + const nextLvExp = pkmLvl < this.scene.getMaxExpLevel() + ? getLevelTotalExp(pkmLvl + 1, pkmSpeciesGrowthRate) - pkmExp + : 0; + const nextLvExpText = addTextObject(this.scene, 208, 128, nextLvExp.toString(), TextStyle.WINDOW_ALT); + nextLvExpText.setOrigin(1, 0); + statsContainer.add(nextLvExpText); + + const expOverlay = this.scene.add.image(140, 145, "summary_stats_overlay_exp"); + expOverlay.setOrigin(0, 0); + statsContainer.add(expOverlay); + + const expMaskRect = this.scene.make.graphics({}); + expMaskRect.setScale(6); + expMaskRect.fillStyle(0xFFFFFF); + expMaskRect.beginPath(); + expMaskRect.fillRect(140 + pageContainer.x, 145 + pageContainer.y + 21, Math.floor(expRatio * 64), 3); + + const expMask = expMaskRect.createGeometryMask(); + + expOverlay.setMask(expMask); + break; + case Page.MOVES: + this.movesContainer = this.scene.add.container(5, -pageBg.height + 26); + pageContainer.add(this.movesContainer); + + this.extraMoveRowContainer = this.scene.add.container(0, 64); + this.extraMoveRowContainer.setVisible(false); + this.movesContainer.add(this.extraMoveRowContainer); + + const extraRowOverlay = this.scene.add.image(-2, 1, "summary_moves_overlay_row"); + extraRowOverlay.setOrigin(0, 1); + this.extraMoveRowContainer.add(extraRowOverlay); + + const extraRowText = addTextObject(this.scene, 35, 0, this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.newMove ? this.newMove.name : i18next.t("pokemonSummary:cancel"), + this.summaryUiMode === SummaryUiMode.LEARN_MOVE ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY); + extraRowText.setOrigin(0, 1); + this.extraMoveRowContainer.add(extraRowText); + + if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { + this.extraMoveRowContainer.setVisible(true); + + if (this.newMove && this.pokemon) { + const spriteKey = Utils.getLocalizedSpriteKey("types"); + const moveType = this.pokemon.getMoveType(this.newMove); + const newMoveTypeIcon = this.scene.add.sprite(0, 0, spriteKey, Type[moveType].toLowerCase()); + newMoveTypeIcon.setOrigin(0, 1); + this.extraMoveRowContainer.add(newMoveTypeIcon); + } + const ppOverlay = this.scene.add.image(163, -1, "summary_moves_overlay_pp"); + ppOverlay.setOrigin(0, 1); + this.extraMoveRowContainer.add(ppOverlay); + + const pp = Utils.padInt(this.newMove?.pp!, 2, " "); // TODO: is this bang correct? + const ppText = addTextObject(this.scene, 173, 1, `${pp}/${pp}`, TextStyle.WINDOW); + ppText.setOrigin(0, 1); + this.extraMoveRowContainer.add(ppText); + } + + this.moveRowsContainer = this.scene.add.container(0, 0); + this.movesContainer.add(this.moveRowsContainer); + + for (let m = 0; m < 4; m++) { + const move: PokemonMove | null = this.pokemon && this.pokemon.moveset.length > m ? this.pokemon?.moveset[m] : null; + const moveRowContainer = this.scene.add.container(0, 16 * m); + this.moveRowsContainer.add(moveRowContainer); + + if (move && this.pokemon) { + const spriteKey = Utils.getLocalizedSpriteKey("types"); + const moveType = this.pokemon.getMoveType(move.getMove()); + const typeIcon = this.scene.add.sprite(0, 0, spriteKey, Type[moveType].toLowerCase()); + typeIcon.setOrigin(0, 1); + moveRowContainer.add(typeIcon); + } + + const moveText = addTextObject(this.scene, 35, 0, move ? move.getName() : "-", TextStyle.SUMMARY); + moveText.setOrigin(0, 1); + moveRowContainer.add(moveText); + + const ppOverlay = this.scene.add.image(163, -1, "summary_moves_overlay_pp"); + ppOverlay.setOrigin(0, 1); + moveRowContainer.add(ppOverlay); + + const ppText = addTextObject(this.scene, 173, 1, "--/--", TextStyle.WINDOW); + ppText.setOrigin(0, 1); + + if (move) { + const maxPP = move.getMovePp(); + const pp = maxPP - move.ppUsed; + ppText.setText(`${Utils.padInt(pp, 2, " ")}/${Utils.padInt(maxPP, 2, " ")}`); + } + + moveRowContainer.add(ppText); + } + + this.moveDescriptionText = addTextObject(this.scene, 2, 84, "", TextStyle.WINDOW_ALT, { wordWrap: { width: 1212 }}); + this.movesContainer.add(this.moveDescriptionText); + + const moveDescriptionTextMaskRect = this.scene.make.graphics({}); + moveDescriptionTextMaskRect.setScale(6); + moveDescriptionTextMaskRect.fillStyle(0xFFFFFF); + moveDescriptionTextMaskRect.beginPath(); + moveDescriptionTextMaskRect.fillRect(112, 130, 202, 46); + + const moveDescriptionTextMask = moveDescriptionTextMaskRect.createGeometryMask(); + + this.moveDescriptionText.setMask(moveDescriptionTextMask); + break; } } diff --git a/src/ui/target-select-ui-handler.ts b/src/ui/target-select-ui-handler.ts index 3cdda984d3c..4c55a4b960e 100644 --- a/src/ui/target-select-ui-handler.ts +++ b/src/ui/target-select-ui-handler.ts @@ -4,7 +4,7 @@ import { Mode } from "./ui"; import UiHandler from "./ui-handler"; import * as Utils from "../utils"; import { getMoveTargets } from "../data/move"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; import { Moves } from "#enums/moves"; import Pokemon from "#app/field/pokemon"; import { ModifierBar } from "#app/modifier/modifier"; @@ -64,33 +64,33 @@ export default class TargetSelectUiHandler extends UiHandler { let success = false; if (button === Button.ACTION || button === Button.CANCEL) { - const targetIndexes: BattlerIndex[] = this.isMultipleTargets ? this.targets : [this.cursor]; + const targetIndexes: BattlerIndex[] = this.isMultipleTargets ? this.targets : [ this.cursor ]; this.targetSelectCallback(button === Button.ACTION ? targetIndexes : []); success = true; } else if (this.isMultipleTargets) { success = false; } else { switch (button) { - case Button.UP: - if (this.cursor < BattlerIndex.ENEMY && this.targets.findIndex(t => t >= BattlerIndex.ENEMY) > -1) { - success = this.setCursor(this.targets.find(t => t >= BattlerIndex.ENEMY)!); // TODO: is the bang correct here? - } - break; - case Button.DOWN: - if (this.cursor >= BattlerIndex.ENEMY && this.targets.findIndex(t => t < BattlerIndex.ENEMY) > -1) { - success = this.setCursor(this.targets.find(t => t < BattlerIndex.ENEMY)!); // TODO: is the bang correct here? - } - break; - case Button.LEFT: - if (this.cursor % 2 && this.targets.findIndex(t => t === this.cursor - 1) > -1) { - success = this.setCursor(this.cursor - 1); - } - break; - case Button.RIGHT: - if (!(this.cursor % 2) && this.targets.findIndex(t => t === this.cursor + 1) > -1) { - success = this.setCursor(this.cursor + 1); - } - break; + case Button.UP: + if (this.cursor < BattlerIndex.ENEMY && this.targets.findIndex(t => t >= BattlerIndex.ENEMY) > -1) { + success = this.setCursor(this.targets.find(t => t >= BattlerIndex.ENEMY)!); // TODO: is the bang correct here? + } + break; + case Button.DOWN: + if (this.cursor >= BattlerIndex.ENEMY && this.targets.findIndex(t => t < BattlerIndex.ENEMY) > -1) { + success = this.setCursor(this.targets.find(t => t < BattlerIndex.ENEMY)!); // TODO: is the bang correct here? + } + break; + case Button.LEFT: + if (this.cursor % 2 && this.targets.findIndex(t => t === this.cursor - 1) > -1) { + success = this.setCursor(this.cursor - 1); + } + break; + case Button.RIGHT: + if (!(this.cursor % 2) && this.targets.findIndex(t => t === this.cursor + 1) > -1) { + success = this.setCursor(this.cursor + 1); + } + break; } } diff --git a/src/ui/test-dialogue-ui-handler.ts b/src/ui/test-dialogue-ui-handler.ts index 0acd9da193b..bf0e7f6723f 100644 --- a/src/ui/test-dialogue-ui-handler.ts +++ b/src/ui/test-dialogue-ui-handler.ts @@ -1,4 +1,4 @@ -import { FormModalUiHandler } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler"; import i18next from "i18next"; import { PlayerPokemon } from "#app/field/pokemon"; @@ -25,7 +25,7 @@ export default class TestDialogueUiHandler extends FormModalUiHandler { // If the value is an object, execute the same process // si el valor es un objeto ejecuta el mismo proceso - return flattenKeys(value, topKey ?? t, topKey ? midleKey ? [...midleKey, t] : [t] : undefined).filter((t) => t.length > 0); + return flattenKeys(value, topKey ?? t, topKey ? midleKey ? [ ...midleKey, t ] : [ t ] : undefined).filter((t) => t.length > 0); } else if (typeof value === "string" || isNullOrUndefined(value)) { // we check for null or undefined here as per above - the typeof is still an object but the value is null so we need to exit out of this and pass the null key // Return in the format expected by i18next @@ -43,10 +43,6 @@ export default class TestDialogueUiHandler extends FormModalUiHandler { return "Test Dialogue"; } - getFields(config?: ModalConfig): string[] { - return [ "Dialogue" ]; - } - getWidth(config?: ModalConfig): number { return 300; } @@ -68,13 +64,20 @@ export default class TestDialogueUiHandler extends FormModalUiHandler { return super.getReadableErrorMessage(error); } + override getInputFieldConfigs(): InputFieldConfig[] { + return [{ label: "Dialogue" }]; + } + show(args: any[]): boolean { const ui = this.getUi(); + const hasTitle = !!this.getModalTitle(); + this.updateFields(this.getInputFieldConfigs(), hasTitle); + this.updateContainer(args[0] as ModalConfig); const input = this.inputs[0]; input.setMaxLength(255); input.on("keydown", (inputObject, evt: KeyboardEvent) => { - if (["escape", "space"].some((v) => v === evt.key.toLowerCase() || v === evt.code.toLowerCase()) && ui.getMode() === Mode.AUTO_COMPLETE) { + if ([ "escape", "space" ].some((v) => v === evt.key.toLowerCase() || v === evt.code.toLowerCase()) && ui.getMode() === Mode.AUTO_COMPLETE) { // Delete autocomplete list and recovery focus. inputObject.on("blur", () => inputObject.node.focus(), { once: true }); ui.revertMode(); diff --git a/src/ui/text.ts b/src/ui/text.ts index 58b6343144a..069aa8680fc 100644 --- a/src/ui/text.ts +++ b/src/ui/text.ts @@ -129,84 +129,84 @@ export function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraSty } switch (style) { - case TextStyle.SUMMARY: - case TextStyle.SUMMARY_ALT: - case TextStyle.SUMMARY_BLUE: - case TextStyle.SUMMARY_RED: - case TextStyle.SUMMARY_PINK: - case TextStyle.SUMMARY_GOLD: - case TextStyle.SUMMARY_GRAY: - case TextStyle.SUMMARY_GREEN: - case TextStyle.WINDOW: - case TextStyle.WINDOW_ALT: - shadowXpos = 3; - shadowYpos = 3; - break; - case TextStyle.STATS_LABEL: - let fontSizeLabel = "96px"; - switch (lang) { - case "de": + case TextStyle.SUMMARY: + case TextStyle.SUMMARY_ALT: + case TextStyle.SUMMARY_BLUE: + case TextStyle.SUMMARY_RED: + case TextStyle.SUMMARY_PINK: + case TextStyle.SUMMARY_GOLD: + case TextStyle.SUMMARY_GRAY: + case TextStyle.SUMMARY_GREEN: + case TextStyle.WINDOW: + case TextStyle.WINDOW_ALT: shadowXpos = 3; shadowYpos = 3; - fontSizeLabel = "80px"; break; - default: - fontSizeLabel = "96px"; + case TextStyle.STATS_LABEL: + let fontSizeLabel = "96px"; + switch (lang) { + case "de": + shadowXpos = 3; + shadowYpos = 3; + fontSizeLabel = "80px"; + break; + default: + fontSizeLabel = "96px"; + break; + } + styleOptions.fontSize = fontSizeLabel; break; - } - styleOptions.fontSize = fontSizeLabel; - break; - case TextStyle.STATS_VALUE: - shadowXpos = 3; - shadowYpos = 3; - let fontSizeValue = "96px"; - switch (lang) { - case "de": - fontSizeValue = "80px"; + case TextStyle.STATS_VALUE: + shadowXpos = 3; + shadowYpos = 3; + let fontSizeValue = "96px"; + switch (lang) { + case "de": + fontSizeValue = "80px"; + break; + default: + fontSizeValue = "96px"; + break; + } + styleOptions.fontSize = fontSizeValue; break; - default: - fontSizeValue = "96px"; + case TextStyle.MESSAGE: + case TextStyle.SETTINGS_LABEL: + case TextStyle.SETTINGS_LOCKED: + case TextStyle.SETTINGS_SELECTED: + break; + case TextStyle.BATTLE_INFO: + case TextStyle.MONEY: + case TextStyle.TOOLTIP_TITLE: + styleOptions.fontSize = defaultFontSize - 24; + shadowXpos = 3.5; + shadowYpos = 3.5; + break; + case TextStyle.PARTY: + case TextStyle.PARTY_RED: + styleOptions.fontSize = defaultFontSize - 30; + styleOptions.fontFamily = "pkmnems"; + break; + case TextStyle.TOOLTIP_CONTENT: + styleOptions.fontSize = defaultFontSize - 32; + shadowXpos = 3; + shadowYpos = 3; + break; + case TextStyle.MOVE_INFO_CONTENT: + styleOptions.fontSize = defaultFontSize - 40; + shadowXpos = 3; + shadowYpos = 3; + break; + case TextStyle.SMALLER_WINDOW_ALT: + styleOptions.fontSize = defaultFontSize - 36; + shadowXpos = 3; + shadowYpos = 3; + break; + case TextStyle.BGM_BAR: + styleOptions.fontSize = defaultFontSize - 24; + shadowXpos = 3; + shadowYpos = 3; break; - } - styleOptions.fontSize = fontSizeValue; - break; - case TextStyle.MESSAGE: - case TextStyle.SETTINGS_LABEL: - case TextStyle.SETTINGS_LOCKED: - case TextStyle.SETTINGS_SELECTED: - break; - case TextStyle.BATTLE_INFO: - case TextStyle.MONEY: - case TextStyle.TOOLTIP_TITLE: - styleOptions.fontSize = defaultFontSize - 24; - shadowXpos = 3.5; - shadowYpos = 3.5; - break; - case TextStyle.PARTY: - case TextStyle.PARTY_RED: - styleOptions.fontSize = defaultFontSize - 30; - styleOptions.fontFamily = "pkmnems"; - break; - case TextStyle.TOOLTIP_CONTENT: - styleOptions.fontSize = defaultFontSize - 32; - shadowXpos = 3; - shadowYpos = 3; - break; - case TextStyle.MOVE_INFO_CONTENT: - styleOptions.fontSize = defaultFontSize - 40; - shadowXpos = 3; - shadowYpos = 3; - break; - case TextStyle.SMALLER_WINDOW_ALT: - styleOptions.fontSize = defaultFontSize - 36; - shadowXpos = 3; - shadowYpos = 3; - break; - case TextStyle.BGM_BAR: - styleOptions.fontSize = defaultFontSize - 24; - shadowXpos = 3; - shadowYpos = 3; - break; } const shadowColor = getTextColor(style, true, uiTheme); @@ -243,7 +243,7 @@ export function getBBCodeFrag(content: string, textStyle: TextStyle, uiTheme: Ui export function getTextWithColors(content: string, primaryStyle: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string { // Apply primary styling before anything else let text = getBBCodeFrag(content, primaryStyle, uiTheme) + "[/color][/shadow]"; - const primaryStyleString = [...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))!][0]; + const primaryStyleString = [ ...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))! ][0]; // Set custom colors text = text.replace(/@\[([^{]*)\]{([^}]*)}/gi, (substring, textStyle: string, textToColor: string) => { @@ -257,110 +257,110 @@ export function getTextWithColors(content: string, primaryStyle: TextStyle, uiTh export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: UiTheme = UiTheme.DEFAULT): string { const isLegacyTheme = uiTheme === UiTheme.LEGACY; switch (textStyle) { - case TextStyle.MESSAGE: - return !shadow ? "#f8f8f8" : "#6b5a73"; - case TextStyle.WINDOW: - case TextStyle.MOVE_INFO_CONTENT: - case TextStyle.MOVE_PP_FULL: - case TextStyle.TOOLTIP_CONTENT: - case TextStyle.SETTINGS_VALUE: - if (isLegacyTheme) { + case TextStyle.MESSAGE: + return !shadow ? "#f8f8f8" : "#6b5a73"; + case TextStyle.WINDOW: + case TextStyle.MOVE_INFO_CONTENT: + case TextStyle.MOVE_PP_FULL: + case TextStyle.TOOLTIP_CONTENT: + case TextStyle.SETTINGS_VALUE: + if (isLegacyTheme) { + return !shadow ? "#484848" : "#d0d0c8"; + } + return !shadow ? "#f8f8f8" : "#6b5a73"; + case TextStyle.MOVE_PP_HALF_FULL: + if (isLegacyTheme) { + return !shadow ? "#a68e17" : "#ebd773"; + } + return !shadow ? "#ccbe00" : "#6e672c"; + case TextStyle.MOVE_PP_NEAR_EMPTY: + if (isLegacyTheme) { + return !shadow ? "#d64b00" : "#f7b18b"; + } + return !shadow ? "#d64b00" : "#69402a"; + case TextStyle.MOVE_PP_EMPTY: + if (isLegacyTheme) { + return !shadow ? "#e13d3d" : "#fca2a2"; + } + return !shadow ? "#e13d3d" : "#632929"; + case TextStyle.WINDOW_ALT: return !shadow ? "#484848" : "#d0d0c8"; - } - return !shadow ? "#f8f8f8" : "#6b5a73"; - case TextStyle.MOVE_PP_HALF_FULL: - if (isLegacyTheme) { - return !shadow ? "#a68e17" : "#ebd773"; - } - return !shadow ? "#ccbe00" : "#6e672c"; - case TextStyle.MOVE_PP_NEAR_EMPTY: - if (isLegacyTheme) { - return !shadow ? "#d64b00" : "#f7b18b"; - } - return !shadow ? "#d64b00" : "#69402a"; - case TextStyle.MOVE_PP_EMPTY: - if (isLegacyTheme) { - return !shadow ? "#e13d3d" : "#fca2a2"; - } - return !shadow ? "#e13d3d" : "#632929"; - case TextStyle.WINDOW_ALT: - return !shadow ? "#484848" : "#d0d0c8"; - case TextStyle.BATTLE_INFO: - if (isLegacyTheme) { - return !shadow ? "#404040" : "#ded6b5"; - } - return !shadow ? "#f8f8f8" : "#6b5a73"; - case TextStyle.PARTY: - return !shadow ? "#f8f8f8" : "#707070"; - case TextStyle.PARTY_RED: - return !shadow ? "#f89890" : "#984038"; - case TextStyle.SUMMARY: - return !shadow ? "#f8f8f8" : "#636363"; - case TextStyle.SUMMARY_ALT: - if (isLegacyTheme) { + case TextStyle.BATTLE_INFO: + if (isLegacyTheme) { + return !shadow ? "#404040" : "#ded6b5"; + } + return !shadow ? "#f8f8f8" : "#6b5a73"; + case TextStyle.PARTY: + return !shadow ? "#f8f8f8" : "#707070"; + case TextStyle.PARTY_RED: + return !shadow ? "#f89890" : "#984038"; + case TextStyle.SUMMARY: return !shadow ? "#f8f8f8" : "#636363"; - } - return !shadow ? "#484848" : "#d0d0c8"; - case TextStyle.SUMMARY_RED: - case TextStyle.TOOLTIP_TITLE: - return !shadow ? "#e70808" : "#ffbd73"; - case TextStyle.SUMMARY_BLUE: - return !shadow ? "#40c8f8" : "#006090"; - case TextStyle.SUMMARY_PINK: - return !shadow ? "#f89890" : "#984038"; - case TextStyle.SUMMARY_GOLD: - case TextStyle.MONEY: - return !shadow ? "#e8e8a8" : "#a0a060"; - case TextStyle.SETTINGS_LOCKED: - case TextStyle.SUMMARY_GRAY: - return !shadow ? "#a0a0a0" : "#636363"; - case TextStyle.STATS_LABEL: - return !shadow ? "#f8b050" : "#c07800"; - case TextStyle.STATS_VALUE: - if (isLegacyTheme) { + case TextStyle.SUMMARY_ALT: + if (isLegacyTheme) { + return !shadow ? "#f8f8f8" : "#636363"; + } return !shadow ? "#484848" : "#d0d0c8"; - } - return !shadow ? "#f8f8f8" : "#6b5a73"; - case TextStyle.SUMMARY_GREEN: - return !shadow ? "#78c850" : "#306850"; - case TextStyle.SETTINGS_LABEL: - case TextStyle.PERFECT_IV: - return !shadow ? "#f8b050" : "#c07800"; - case TextStyle.SETTINGS_SELECTED: - return !shadow ? "#f88880" : "#f83018"; - case TextStyle.SMALLER_WINDOW_ALT: - return !shadow ? "#484848" : "#d0d0c8"; - case TextStyle.BGM_BAR: - return !shadow ? "#f8f8f8" : "#6b5a73"; + case TextStyle.SUMMARY_RED: + case TextStyle.TOOLTIP_TITLE: + return !shadow ? "#e70808" : "#ffbd73"; + case TextStyle.SUMMARY_BLUE: + return !shadow ? "#40c8f8" : "#006090"; + case TextStyle.SUMMARY_PINK: + return !shadow ? "#f89890" : "#984038"; + case TextStyle.SUMMARY_GOLD: + case TextStyle.MONEY: + return !shadow ? "#e8e8a8" : "#a0a060"; + case TextStyle.SETTINGS_LOCKED: + case TextStyle.SUMMARY_GRAY: + return !shadow ? "#a0a0a0" : "#636363"; + case TextStyle.STATS_LABEL: + return !shadow ? "#f8b050" : "#c07800"; + case TextStyle.STATS_VALUE: + if (isLegacyTheme) { + return !shadow ? "#484848" : "#d0d0c8"; + } + return !shadow ? "#f8f8f8" : "#6b5a73"; + case TextStyle.SUMMARY_GREEN: + return !shadow ? "#78c850" : "#306850"; + case TextStyle.SETTINGS_LABEL: + case TextStyle.PERFECT_IV: + return !shadow ? "#f8b050" : "#c07800"; + case TextStyle.SETTINGS_SELECTED: + return !shadow ? "#f88880" : "#f83018"; + case TextStyle.SMALLER_WINDOW_ALT: + return !shadow ? "#484848" : "#d0d0c8"; + case TextStyle.BGM_BAR: + return !shadow ? "#f8f8f8" : "#6b5a73"; } } export function getModifierTierTextTint(tier: ModifierTier): integer { switch (tier) { - case ModifierTier.COMMON: - return 0xf8f8f8; - case ModifierTier.GREAT: - return 0x4998f8; - case ModifierTier.ULTRA: - return 0xf8d038; - case ModifierTier.ROGUE: - return 0xdb4343; - case ModifierTier.MASTER: - return 0xe331c5; - case ModifierTier.LUXURY: - return 0xe74c18; + case ModifierTier.COMMON: + return 0xf8f8f8; + case ModifierTier.GREAT: + return 0x4998f8; + case ModifierTier.ULTRA: + return 0xf8d038; + case ModifierTier.ROGUE: + return 0xdb4343; + case ModifierTier.MASTER: + return 0xe331c5; + case ModifierTier.LUXURY: + return 0xe74c18; } } export function getEggTierTextTint(tier: EggTier): integer { switch (tier) { - case EggTier.COMMON: - return getModifierTierTextTint(ModifierTier.COMMON); - case EggTier.GREAT: - return getModifierTierTextTint(ModifierTier.GREAT); - case EggTier.ULTRA: - return getModifierTierTextTint(ModifierTier.ULTRA); - case EggTier.MASTER: - return getModifierTierTextTint(ModifierTier.MASTER); + case EggTier.COMMON: + return getModifierTierTextTint(ModifierTier.COMMON); + case EggTier.RARE: + return getModifierTierTextTint(ModifierTier.GREAT); + case EggTier.EPIC: + return getModifierTierTextTint(ModifierTier.ULTRA); + case EggTier.LEGENDARY: + return getModifierTierTextTint(ModifierTier.MASTER); } } diff --git a/src/ui/time-of-day-widget.ts b/src/ui/time-of-day-widget.ts index ea80a6e524a..66fe5cc9ac3 100644 --- a/src/ui/time-of-day-widget.ts +++ b/src/ui/time-of-day-widget.ts @@ -21,9 +21,9 @@ export default class TimeOfDayWidget extends Phaser.GameObjects.Container { /** A map containing all timeOfDayIcon arrays with a matching string key for easier iteration */ private timeOfDayIconPairs: Map = new Map([ - ["bg", this.timeOfDayIconBgs], - ["mg", this.timeOfDayIconMgs], - ["fg", this.timeOfDayIconFgs],]); + [ "bg", this.timeOfDayIconBgs ], + [ "mg", this.timeOfDayIconMgs ], + [ "fg", this.timeOfDayIconFgs ],]); /** The current time of day */ private currentTime: TimeOfDay = TimeOfDay.ALL; @@ -66,7 +66,7 @@ export default class TimeOfDayWidget extends Phaser.GameObjects.Container { } }); // Store a flat array of all icons for later - this.timeOfDayIcons = [this.timeOfDayIconBgs, this.timeOfDayIconMgs, this.timeOfDayIconFgs].flat(); + this.timeOfDayIcons = [ this.timeOfDayIconBgs, this.timeOfDayIconMgs, this.timeOfDayIconFgs ].flat(); this.add(this.timeOfDayIcons); this.battleScene.eventTarget.addEventListener(BattleSceneEventType.ENCOUNTER_PHASE, this.onEncounterPhaseEvent); @@ -78,21 +78,21 @@ export default class TimeOfDayWidget extends Phaser.GameObjects.Container { */ private getBackTween(): Phaser.Types.Tweens.TweenBuilderConfig[] { const rotate = { - targets: [this.timeOfDayIconMgs[0], this.timeOfDayIconMgs[1]], + targets: [ this.timeOfDayIconMgs[0], this.timeOfDayIconMgs[1] ], angle: "+=90", duration: Utils.fixedInt(1500), ease: "Back.easeOut", paused: !this.parentVisible, }; const fade = { - targets: [this.timeOfDayIconBgs[1], this.timeOfDayIconMgs[1], this.timeOfDayIconFgs[1]], + targets: [ this.timeOfDayIconBgs[1], this.timeOfDayIconMgs[1], this.timeOfDayIconFgs[1] ], alpha: 0, duration: Utils.fixedInt(500), ease: "Linear", paused: !this.parentVisible, }; - return [rotate, fade]; + return [ rotate, fade ]; } /** @@ -101,21 +101,21 @@ export default class TimeOfDayWidget extends Phaser.GameObjects.Container { */ private getBounceTween(): Phaser.Types.Tweens.TweenBuilderConfig[] { const bounce = { - targets: [this.timeOfDayIconMgs[0], this.timeOfDayIconMgs[1]], + targets: [ this.timeOfDayIconMgs[0], this.timeOfDayIconMgs[1] ], angle: "+=90", duration: Utils.fixedInt(2000), ease: "Bounce.easeOut", paused: !this.parentVisible, }; const fade = { - targets: [this.timeOfDayIconBgs[1], this.timeOfDayIconMgs[1], this.timeOfDayIconFgs[1]], + targets: [ this.timeOfDayIconBgs[1], this.timeOfDayIconMgs[1], this.timeOfDayIconFgs[1] ], alpha: 0, duration: Utils.fixedInt(800), ease: "Linear", paused: !this.parentVisible, }; - return [bounce, fade]; + return [ bounce, fade ]; } /** Resets all icons to the proper depth, texture, and alpha so they are ready to tween */ @@ -129,7 +129,7 @@ export default class TimeOfDayWidget extends Phaser.GameObjects.Container { icons[0].setTexture(TimeOfDay[this.currentTime].toLowerCase() + "_icon_" + key); icons[1].setTexture(TimeOfDay[this.previousTime].toLowerCase() + "_icon_" + key); }); - this.timeOfDayIconMgs[0].setRotation(-90 * (3.14/180)); + this.timeOfDayIconMgs[0].setRotation(-90 * (3.14 / 180)); this.timeOfDayIcons.forEach(icon => icon.setAlpha(1)); } diff --git a/src/ui/title-ui-handler.ts b/src/ui/title-ui-handler.ts index 79baf407fb6..3bfba71ef08 100644 --- a/src/ui/title-ui-handler.ts +++ b/src/ui/title-ui-handler.ts @@ -98,11 +98,12 @@ export default class TitleUiHandler extends OptionSelectUiHandler { this.splashMessage = Utils.randItem(getSplashMessages()); this.splashMessageText.setText(i18next.t(this.splashMessage, { count: TitleUiHandler.BATTLES_WON_FALLBACK })); - this.appVersionText.setText("v"+version); + this.appVersionText.setText("v" + version); const ui = this.getUi(); if (this.scene.eventManager.isEventActive()) { + this.eventDisplay.setWidth(this.scene.scaledCanvas.width - this.optionSelectBg.width - this.optionSelectBg.x); this.eventDisplay.show(); } diff --git a/src/ui/ui-handler.ts b/src/ui/ui-handler.ts index d9f0a876b71..bb7b1e038db 100644 --- a/src/ui/ui-handler.ts +++ b/src/ui/ui-handler.ts @@ -1,7 +1,7 @@ import BattleScene from "../battle-scene"; import { TextStyle, getTextColor } from "./text"; import { Mode } from "./ui"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; /** * A basic abstract class to act as a holder and processor for UI elements. diff --git a/src/ui/ui-theme.ts b/src/ui/ui-theme.ts index 75725910b82..89c56384bd0 100644 --- a/src/ui/ui-theme.ts +++ b/src/ui/ui-theme.ts @@ -10,12 +10,12 @@ export enum WindowVariant { export function getWindowVariantSuffix(windowVariant: WindowVariant): string { switch (windowVariant) { - case WindowVariant.THIN: - return "_thin"; - case WindowVariant.XTHIN: - return "_xthin"; - default: - return ""; + case WindowVariant.THIN: + return "_thin"; + case WindowVariant.XTHIN: + return "_xthin"; + default: + return ""; } } @@ -55,8 +55,8 @@ export function addWindow(scene: BattleScene, x: number, y: number, width: numbe */ const maskRect = new Phaser.GameObjects.Rectangle( scene, - 6*(x - (mergeMaskLeft ? 2 : 0) - (maskOffsetX || 0)), - 6*(y + (mergeMaskTop ? 2 : 0) + (maskOffsetY || 0)), + 6 * (x - (mergeMaskLeft ? 2 : 0) - (maskOffsetX || 0)), + 6 * (y + (mergeMaskTop ? 2 : 0) + (maskOffsetY || 0)), width - (mergeMaskLeft ? 2 : 0), height - (mergeMaskTop ? 2 : 0), 0xffffff diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 7e00c87cc5f..63cd48ab1cd 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -34,7 +34,6 @@ import SaveSlotSelectUiHandler from "./save-slot-select-ui-handler"; import TitleUiHandler from "./title-ui-handler"; import SavingIconHandler from "./saving-icon-handler"; import UnavailableModalUiHandler from "./unavailable-modal-ui-handler"; -import OutdatedModalUiHandler from "./outdated-modal-ui-handler"; import SessionReloadModalUiHandler from "./session-reload-modal-ui-handler"; import { Button } from "#enums/buttons"; import i18next from "i18next"; @@ -90,7 +89,6 @@ export enum Mode { LOADING, SESSION_RELOAD, UNAVAILABLE, - OUTDATED, CHALLENGE_SELECT, RENAME_POKEMON, RUN_HISTORY, @@ -134,7 +132,6 @@ const noTransitionModes = [ Mode.LOADING, Mode.SESSION_RELOAD, Mode.UNAVAILABLE, - Mode.OUTDATED, Mode.RENAME_POKEMON, Mode.TEST_DIALOGUE, Mode.AUTO_COMPLETE, @@ -200,7 +197,6 @@ export default class UI extends Phaser.GameObjects.Container { new LoadingModalUiHandler(scene), new SessionReloadModalUiHandler(scene), new UnavailableModalUiHandler(scene), - new OutdatedModalUiHandler(scene), new GameChallengesUiHandler(scene), new RenameFormUiHandler(scene), new RunHistoryUiHandler(scene), @@ -273,7 +269,7 @@ export default class UI extends Phaser.GameObjects.Container { } const battleScene = this.scene as BattleScene; - if ([Mode.CONFIRM, Mode.COMMAND, Mode.FIGHT, Mode.MESSAGE].includes(this.mode)) { + if ([ Mode.CONFIRM, Mode.COMMAND, Mode.FIGHT, Mode.MESSAGE ].includes(this.mode)) { battleScene?.processInfoButton(pressed); return true; } diff --git a/src/ui/unavailable-modal-ui-handler.ts b/src/ui/unavailable-modal-ui-handler.ts index 3375fb930e6..92b1c2f1b4e 100644 --- a/src/ui/unavailable-modal-ui-handler.ts +++ b/src/ui/unavailable-modal-ui-handler.ts @@ -52,7 +52,7 @@ export default class UnavailableModalUiHandler extends ModalUiHandler { tryReconnect(): void { updateUserInfo().then(response => { - if (response[0] || [200, 400].includes(response[1])) { + if (response[0] || [ 200, 400 ].includes(response[1])) { this.reconnectTimer = null; this.reconnectDuration = this.minTime; this.scene.playSound("se/pb_bounce_1"); diff --git a/src/utils.test.ts b/src/utils.test.ts index 93f2a96ec4c..3f5b835b03b 100644 --- a/src/utils.test.ts +++ b/src/utils.test.ts @@ -1,4 +1,4 @@ -import {expect, describe, it, beforeAll} from "vitest"; +import { expect, describe, it, beforeAll } from "vitest"; import { randomString, padInt } from "./utils"; import Phaser from "phaser"; diff --git a/src/utils.ts b/src/utils.ts index 7a0def1a950..8a35a4b3f07 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -38,10 +38,6 @@ export function shiftCharCodes(str: string, shiftCount: integer) { return newStr; } -export function clampInt(value: integer, min: integer, max: integer): integer { - return Math.min(Math.max(value, min), max); -} - export function randGauss(stdev: number, mean: number = 0): number { if (!stdev) { return 0; @@ -149,7 +145,7 @@ export function randSeedShuffle(items: T[]): T[] { const newArray = items.slice(0); for (let i = items.length - 1; i > 0; i--) { const j = Phaser.Math.RND.integerInRange(0, i); - [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; + [ newArray[i], newArray[j] ] = [ newArray[j], newArray[i] ]; } return newArray; } @@ -198,23 +194,23 @@ export function formatLargeNumber(count: integer, threshold: integer): string { const ret = count.toString(); let suffix = ""; switch (Math.ceil(ret.length / 3) - 1) { - case 1: - suffix = "K"; - break; - case 2: - suffix = "M"; - break; - case 3: - suffix = "B"; - break; - case 4: - suffix = "T"; - break; - case 5: - suffix = "q"; - break; - default: - return "?"; + case 1: + suffix = "K"; + break; + case 2: + suffix = "M"; + break; + case 3: + suffix = "B"; + break; + case 4: + suffix = "T"; + break; + case 5: + suffix = "q"; + break; + default: + return "?"; } const digits = ((ret.length + 2) % 3) + 1; let decimalNumber = ret.slice(digits, digits + 2); @@ -225,7 +221,7 @@ export function formatLargeNumber(count: integer, threshold: integer): string { } // Abbreviations from 10^0 to 10^33 -const AbbreviationsLargeNumber: string[] = ["", "K", "M", "B", "t", "q", "Q", "s", "S", "o", "n", "d"]; +const AbbreviationsLargeNumber: string[] = [ "", "K", "M", "B", "t", "q", "Q", "s", "S", "o", "n", "d" ]; export function formatFancyLargeNumber(number: number, rounded: number = 3): string { let exponent: number; @@ -274,7 +270,7 @@ export const isLocal = ( /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/.test(window.location.hostname)) && window.location.port !== "") || window.location.hostname === ""; -export const localServerUrl = import.meta.env.VITE_SERVER_URL ?? `http://${window.location.hostname}:${window.location.port+1}`; +export const localServerUrl = import.meta.env.VITE_SERVER_URL ?? `http://${window.location.hostname}:${window.location.port + 1}`; // Set the server URL based on whether it's local or not export const apiUrl = localServerUrl ?? "https://api.pokerogue.net"; @@ -425,7 +421,7 @@ export function rgbToHsv(r: integer, g: integer, b: integer) { const v = Math.max(r, g, b); const c = v - Math.min(r, g, b); const h = c && ((v === r) ? (g - b) / c : ((v === g) ? 2 + (b - r) / c : 4 + (r - g) / c)); - return [ 60 * (h < 0 ? h + 6 : h), v && c / v, v]; + return [ 60 * (h < 0 ? h + 6 : h), v && c / v, v ]; } /** @@ -445,7 +441,7 @@ export function deltaRgb(rgb1: integer[], rgb2: integer[]): integer { } export function rgbHexToRgba(hex: string) { - const color = hex.match(/^([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i) ?? ["000000", "00", "00", "00"]; + const color = hex.match(/^([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i) ?? [ "000000", "00", "00", "00" ]; return { r: parseInt(color[1], 16), g: parseInt(color[2], 16), @@ -491,18 +487,18 @@ export function verifyLang(lang?: string): boolean { } switch (lang) { - case "es": - case "fr": - case "de": - case "it": - case "zh-CN": - case "zh-TW": - case "pt-BR": - case "ko": - case "ja": - return true; - default: - return false; + case "es": + case "fr": + case "de": + case "it": + case "zh-CN": + case "zh-TW": + case "pt-BR": + case "ko": + case "ja": + return true; + default: + return false; } } @@ -512,7 +508,7 @@ export function verifyLang(lang?: string): boolean { */ export function printContainerList(container: Phaser.GameObjects.Container): void { console.log(container.list.map(go => { - return {type: go.type, name: go.name}; + return { type: go.type, name: go.name }; })); }