diff --git a/.gitattributes b/.gitattributes index dfe0770424b..a6bfb838587 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ # Auto detect text files and perform LF normalization * text=auto +* -crlf diff --git a/.github/workflows/test-shard-template.yml b/.github/workflows/test-shard-template.yml index 185764c86a8..9fc41d1b965 100644 --- a/.github/workflows/test-shard-template.yml +++ b/.github/workflows/test-shard-template.yml @@ -29,4 +29,4 @@ jobs: - name: Install Node.js dependencies run: npm ci - name: Run tests - run: npx vitest --project ${{ inputs.project }} --shard=${{ inputs.shard }}/${{ inputs.totalShards }} ${{ !runner.debug && '--silent' || '' }} + run: npx vitest --project ${{ inputs.project }} --no-isolate --shard=${{ inputs.shard }}/${{ inputs.totalShards }} ${{ !runner.debug && '--silent' || '' }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d30d8adba38..167a108e58c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,29 +15,8 @@ on: types: [checks_requested] jobs: - pre-test: - name: Run Pre-test - runs-on: ubuntu-latest - steps: - - name: Check out Git repository - uses: actions/checkout@v4 - with: - submodules: 'recursive' - path: tests-action - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - - name: Install Node.js dependencies - working-directory: tests-action - run: npm ci - - name: Run Pre-test - working-directory: tests-action - run: npx vitest run --project pre ${{ !runner.debug && '--silent' || '' }} - run-tests: name: Run Tests - needs: [pre-test] strategy: matrix: shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] diff --git a/biome.jsonc b/biome.jsonc index 3ec4552d359..c5e1d713d86 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -50,7 +50,8 @@ "noUndeclaredVariables": "off", "noUnusedVariables": "error", "noSwitchDeclarations": "warn", // TODO: refactor and make this an error - "noVoidTypeReturn": "warn" // TODO: Refactor and make this an error + "noVoidTypeReturn": "warn", // TODO: Refactor and make this an error + "noUnusedImports": "error" }, "style": { "noVar": "error", diff --git a/index.css b/index.css index 49e570bdccc..62ad6266d30 100644 --- a/index.css +++ b/index.css @@ -68,6 +68,10 @@ input:-internal-autofill-selected { background-clip: text; } +input:-webkit-autofill { + -webkit-text-fill-color: #a1a1a1; +} + /* Need adjust input font-size */ input { font-size: 3.2rem; diff --git a/lefthook.yml b/lefthook.yml index 4eff2ad1f8e..ddf875f15de 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -8,12 +8,6 @@ pre-commit: skip: - merge - rebase - -pre-push: - commands: - biome-lint: - glob: "*.{js,ts,jsx,tsx}" - run: npx @biomejs/biome check --write --reporter=summary {push_files} --no-errors-on-unmatched post-merge: commands: diff --git a/package-lock.json b/package-lock.json index 87e2e150c65..40ef47965ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "@types/node": "^20.12.13", "@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54", "@typescript-eslint/parser": "^8.0.0-alpha.54", - "@vitest/coverage-istanbul": "^2.1.9", + "@vitest/coverage-istanbul": "^3.0.9", "dependency-cruiser": "^16.3.10", "eslint": "^9.7.0", "eslint-plugin-import-x": "^4.2.1", @@ -43,7 +43,7 @@ "typescript-eslint": "^8.0.0-alpha.54", "vite": "^5.4.14", "vite-tsconfig-paths": "^4.3.2", - "vitest": "^2.1.9", + "vitest": "^3.0.9", "vitest-canvas-mock": "^0.3.3" }, "engines": { @@ -2312,14 +2312,14 @@ } }, "node_modules/@vitest/coverage-istanbul": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-2.1.9.tgz", - "integrity": "sha512-vdYE4FkC/y2lxcN3Dcj54Bw+ericmDwiex0B8LV5F/YNYEYP1mgVwhPnHwWGAXu38qizkjOuyczKbFTALfzFKw==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-3.0.9.tgz", + "integrity": "sha512-/TXh2qmOhclmVPjOnPTpIO4Xr6l2P5EwyXQygenwq4/ZQ/vPsrz+GCRZF9kBeQi6xrGcHv368Si9PGImWQawVg==", "dev": true, "license": "MIT", "dependencies": { "@istanbuljs/schema": "^0.1.3", - "debug": "^4.3.7", + "debug": "^4.4.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-instrument": "^6.0.3", "istanbul-lib-report": "^3.0.1", @@ -2327,48 +2327,48 @@ "istanbul-reports": "^3.1.7", "magicast": "^0.3.5", "test-exclude": "^7.0.1", - "tinyrainbow": "^1.2.0" + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "2.1.9" + "vitest": "3.0.9" } }, "node_modules/@vitest/expect": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", - "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.9.tgz", + "integrity": "sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "tinyrainbow": "^1.2.0" + "@vitest/spy": "3.0.9", + "@vitest/utils": "3.0.9", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", - "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.9.tgz", + "integrity": "sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.9", + "@vitest/spy": "3.0.9", "estree-walker": "^3.0.3", - "magic-string": "^0.30.12" + "magic-string": "^0.30.17" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0" + "vite": "^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { "msw": { @@ -2380,51 +2380,51 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", - "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.9.tgz", + "integrity": "sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^1.2.0" + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", - "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.9.tgz", + "integrity": "sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.1.9", - "pathe": "^1.1.2" + "@vitest/utils": "3.0.9", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", - "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.9.tgz", + "integrity": "sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.9", - "magic-string": "^0.30.12", - "pathe": "^1.1.2" + "@vitest/pretty-format": "3.0.9", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", - "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.9.tgz", + "integrity": "sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2435,15 +2435,15 @@ } }, "node_modules/@vitest/utils": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", - "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.9.tgz", + "integrity": "sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.9", - "loupe": "^3.1.2", - "tinyrainbow": "^1.2.0" + "@vitest/pretty-format": "3.0.9", + "loupe": "^3.1.3", + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2738,9 +2738,9 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", - "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", "dev": true, "license": "MIT", "dependencies": { @@ -5450,9 +5450,9 @@ } }, "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, @@ -6308,9 +6308,9 @@ } }, "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", "dev": true, "license": "MIT", "engines": { @@ -6677,23 +6677,23 @@ } }, "node_modules/vite-node": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", - "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.9.tgz", + "integrity": "sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.7", - "es-module-lexer": "^1.5.4", - "pathe": "^1.1.2", - "vite": "^5.0.0" + "debug": "^4.4.0", + "es-module-lexer": "^1.6.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0" }, "bin": { "vite-node": "vite-node.mjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -6720,47 +6720,48 @@ } }, "node_modules/vitest": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", - "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz", + "integrity": "sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "2.1.9", - "@vitest/mocker": "2.1.9", - "@vitest/pretty-format": "^2.1.9", - "@vitest/runner": "2.1.9", - "@vitest/snapshot": "2.1.9", - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "debug": "^4.3.7", + "@vitest/expect": "3.0.9", + "@vitest/mocker": "3.0.9", + "@vitest/pretty-format": "^3.0.9", + "@vitest/runner": "3.0.9", + "@vitest/snapshot": "3.0.9", + "@vitest/spy": "3.0.9", + "@vitest/utils": "3.0.9", + "chai": "^5.2.0", + "debug": "^4.4.0", "expect-type": "^1.1.0", - "magic-string": "^0.30.12", - "pathe": "^1.1.2", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", "std-env": "^3.8.0", "tinybench": "^2.9.0", - "tinyexec": "^0.3.1", - "tinypool": "^1.0.1", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.1.9", + "tinyexec": "^0.3.2", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.0.9", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.9", - "@vitest/ui": "2.1.9", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.0.9", + "@vitest/ui": "3.0.9", "happy-dom": "*", "jsdom": "*" }, @@ -6768,6 +6769,9 @@ "@edge-runtime/vm": { "optional": true }, + "@types/debug": { + "optional": true + }, "@types/node": { "optional": true }, diff --git a/package.json b/package.json index ce9e8b4a07b..6048b0bae36 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,10 @@ "build": "vite build", "build:beta": "vite build --mode beta", "preview": "vite preview", - "test": "vitest run --project pre && vitest run --project main", - "test:cov": "vitest run --project pre && vitest run --project main --coverage", - "test:watch": "vitest run --project pre && vitest watch --project main --coverage", - "test:silent": "vitest run --project pre && vitest run --project main --silent", + "test": "vitest run", + "test:cov": "vitest run --coverage --no-isolate", + "test:watch": "vitest watch --coverage --no-isolate", + "test:silent": "vitest run --silent --no-isolate", "typecheck": "tsc --noEmit", "eslint": "eslint --fix .", "eslint-ci": "eslint .", @@ -36,7 +36,7 @@ "@types/node": "^20.12.13", "@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54", "@typescript-eslint/parser": "^8.0.0-alpha.54", - "@vitest/coverage-istanbul": "^2.1.9", + "@vitest/coverage-istanbul": "^3.0.9", "dependency-cruiser": "^16.3.10", "eslint": "^9.7.0", "eslint-plugin-import-x": "^4.2.1", @@ -50,7 +50,7 @@ "typescript-eslint": "^8.0.0-alpha.54", "vite": "^5.4.14", "vite-tsconfig-paths": "^4.3.2", - "vitest": "^2.1.9", + "vitest": "^3.0.9", "vitest-canvas-mock": "^0.3.3" }, "dependencies": { diff --git a/public/exp-sprites.json b/public/exp-sprites.json index 50e10a8822d..c83fb910010 100644 --- a/public/exp-sprites.json +++ b/public/exp-sprites.json @@ -13,10 +13,10 @@ "1005", "1006", "1006", - "1007-apex", - "1007-apex", - "1008-ultimate", - "1008-ultimate", + "1007-apex-build-Disabled", + "1007-apex-build-Disabled", + "1008-ultimate-mode-Disabled", + "1008-ultimate-mode-Disabled", "115-mega", "115-mega", "127-mega", @@ -185,9 +185,9 @@ "531-mega", "569-gigantamax", "569-gigantamax", - "6-mega", - "6-mega", "6-mega-x", + "6-mega-x", + "6-mega-y", "6-mega-y", "6058", "6058", @@ -825,8 +825,8 @@ "873", "874", "874", - "875-no", - "875-no", + "875-no-ice", + "875-no-ice", "875", "875", "876-female", @@ -963,26 +963,26 @@ "929", "930", "930", - "931-blue", - "931-blue", - "931-green", - "931-green", - "931-white", - "931-white", - "931-yellow", - "931-yellow", + "931-blue-plumage-Disabled", + "931-blue-plumage-Disabled", + "931-green-plumage-Disabled", + "931-green-plumage-Disabled", + "931-white-plumage-Disabled", + "931-white-plumage-Disabled", + "931-yellow-plumage-Disabled", + "931-yellow-plumage-Disabled", "932", "932", "933", "933", "934", "934", - "935", - "935", - "936", - "936", - "937", - "937", + "935-Disabled", + "935-Disabled", + "936-Disabled", + "936-Disabled", + "937-Disabled", + "937-Disabled", "938", "938", "939", @@ -1073,6 +1073,8 @@ "978-droopy", "978-stretchy", "978-stretchy", + "979-Disabled", + "979-Disabled", "980", "980", "981", @@ -1131,10 +1133,10 @@ "1005b", "1006b", "1006b", - "1007b-apex", - "1007b-apex", - "1008b-ultimate", - "1008b-ultimate", + "1007b-apex-build-Disabled", + "1007b-apex-build-Disabled", + "1008b-ultimate-mode-Disabled", + "1008b-ultimate-mode-Disabled", "115b-mega", "115b-mega", "127b-mega", @@ -1303,9 +1305,9 @@ "531b-mega", "569b-gigantamax", "569b-gigantamax", - "6b-mega", - "6b-mega", "6b-mega-x", + "6b-mega-x", + "6b-mega-y", "6b-mega-y", "6058b", "6058b", @@ -1943,8 +1945,8 @@ "873b", "874b", "874b", - "875b-no", - "875b-no", + "875b-no-ice", + "875b-no-ice", "875b", "875b", "876b-female", @@ -2083,26 +2085,26 @@ "929b", "930b", "930b", - "931b-blue", - "931b-blue", - "931b-green", - "931b-green", - "931b-white", - "931b-white", - "931b-yellow", - "931b-yellow", + "931b-blue-plumage-Disabled", + "931b-blue-plumage-Disabled", + "931b-green-plumage-Disabled", + "931b-green-plumage-Disabled", + "931b-white-plumage-Disabled", + "931b-white-plumage-Disabled", + "931b-yellow-plumage-Disabled", + "931b-yellow-plumage-Disabled", "932b", "932b", "933b", "933b", "934b", "934b", - "935b", - "935b", - "936b", - "936b", - "937b", - "937b", + "935b-Disabled", + "935b-Disabled", + "936b-Disabled", + "936b-Disabled", + "937b-Disabled", + "937b-Disabled", "938b", "938b", "939b", @@ -2251,10 +2253,10 @@ "1005sb", "1006sb", "1006sb", - "1007sb-apex", - "1007sb-apex", - "1008sb-ultimate", - "1008sb-ultimate", + "1007sb-apex-build-Disabled", + "1007sb-apex-build-Disabled", + "1008sb-ultimate-mode-Disabled", + "1008sb-ultimate-mode-Disabled", "115sb-mega", "115sb-mega", "127sb-mega", @@ -3063,8 +3065,8 @@ "873sb", "874sb", "874sb", - "875sb-no", - "875sb-no", + "875sb-no-ice", + "875sb-no-ice", "875sb", "875sb", "876sb-female", @@ -3203,26 +3205,26 @@ "929sb", "930sb", "930sb", - "931sb-blue", - "931sb-blue", - "931sb-green", - "931sb-green", - "931sb-white", - "931sb-white", - "931sb-yellow", - "931sb-yellow", + "931sb-blue-plumage-Disabled", + "931sb-blue-plumage-Disabled", + "931sb-green-plumage-Disabled", + "931sb-green-plumage-Disabled", + "931sb-white-plumage-Disabled", + "931sb-white-plumage-Disabled", + "931sb-yellow-plumage-Disabled", + "931sb-yellow-plumage-Disabled", "932sb", "932sb", "933sb", "933sb", "934sb", "934sb", - "935sb", - "935sb", - "936sb", - "936sb", - "937sb", - "937sb", + "935sb-Disabled", + "935sb-Disabled", + "936sb-Disabled", + "936sb-Disabled", + "937sb-Disabled", + "937sb-Disabled", "938sb", "938sb", "939sb", @@ -3376,10 +3378,10 @@ "1005s", "1006s", "1006s", - "1007s-apex", - "1007s-apex", - "1008s-ultimate", - "1008s-ultimate", + "1007s-apex-build-Disabled", + "1007s-apex-build-Disabled", + "1008s-ultimate-mode-Disabled", + "1008s-ultimate-mode-Disabled", "115s-mega", "115s-mega", "127s-mega", @@ -4188,8 +4190,8 @@ "873s", "874s", "874s", - "875s-no", - "875s-no", + "875s-no-ice", + "875s-no-ice", "875s", "875s", "876s-female", @@ -4328,26 +4330,26 @@ "929s", "930s", "930s", - "931s-blue", - "931s-blue", - "931s-green", - "931s-green", - "931s-white", - "931s-white", - "931s-yellow", - "931s-yellow", + "931s-blue-plumage-Disabled", + "931s-blue-plumage-Disabled", + "931s-green-plumage-Disabled", + "931s-green-plumage-Disabled", + "931s-white-plumage-Disabled", + "931s-white-plumage-Disabled", + "931s-yellow-plumage-Disabled", + "931s-yellow-plumage-Disabled", "932s", "932s", "933s", "933s", "934s", "934s", - "935s", - "935s", - "936s", - "936s", - "937s", - "937s", + "935s-Disabled", + "935s-Disabled", + "936s-Disabled", + "936s-Disabled", + "937s-Disabled", + "937s-Disabled", "938s", "938s", "939s", @@ -4438,6 +4440,8 @@ "978s-droopy", "978s-stretchy", "978s-stretchy", + "979s-Disabled", + "979s-Disabled", "980s", "980s", "981s", @@ -4485,11 +4489,10 @@ "1000", "1001", "1004", - "1007-apex", - "1007-apex", - "1007-apex", - "1007-apex", - "1008-ultimate", + "1007-apex-build-Disabled", + "1007-apex-build-Disabled", + "1008-ultimate-mode-Disabled", + "1008-ultimate-mode-Disabled", "127-mega", "142-mega", "150-mega", @@ -4698,21 +4701,21 @@ "933_3", "933_3", "934", - "935", - "935_3", - "935_3", - "936_1", - "936_1", - "936_2", - "936_2", - "936_3", - "936_3", - "937_1", - "937_1", - "937_2", - "937_2", - "937_3", - "937_3", + "935-Disabled", + "935_3-Disabled", + "935_3-Disabled", + "936_1-Disabled", + "936_1-Disabled", + "936_2-Disabled", + "936_2-Disabled", + "936_3-Disabled", + "936_3-Disabled", + "937_1-Disabled", + "937_1-Disabled", + "937_2-Disabled", + "937_2-Disabled", + "937_3-Disabled", + "937_3-Disabled", "94-mega_1", "94-mega_1", "94-mega_2", @@ -4755,11 +4758,10 @@ "1000b", "1001b", "1004b", - "1007b-apex", - "1007b-apex", - "1007b-apex", - "1007b-apex", - "1008b-ultimate", + "1007b-apex-build-Disabled", + "1007b-apex-build-Disabled", + "1008b-ultimate-mode-Disabled", + "1008b-ultimate-mode-Disabled", "127b-mega", "142b-mega", "150b-mega", @@ -4920,24 +4922,24 @@ "932b", "933b", "934b", - "935_1b", - "935_1b", - "935_2b", - "935_2b", - "935_3b", - "935_3b", - "936_1b", - "936_1b", - "936_2b", - "936_2b", - "936_3b", - "936_3b", - "937_1b", - "937_1b", - "937_2b", - "937_2b", - "937_3b", - "937_3b", + "935_1b-Disabled", + "935_1b-Disabled", + "935_2b-Disabled", + "935_2b-Disabled", + "935_3b-Disabled", + "935_3b-Disabled", + "936_1b-Disabled", + "936_1b-Disabled", + "936_2b-Disabled", + "936_2b-Disabled", + "936_3b-Disabled", + "936_3b-Disabled", + "937_1b-Disabled", + "937_1b-Disabled", + "937_2b-Disabled", + "937_2b-Disabled", + "937_3b-Disabled", + "937_3b-Disabled", "94b-mega", "948b", "949b", diff --git a/public/images/items.json b/public/images/items.json index 9d84476a8a0..5848b02dd6a 100644 --- a/public/images/items.json +++ b/public/images/items.json @@ -4,13 +4,13 @@ "image": "items.png", "format": "RGBA8888", "size": { - "w": 431, - "h": 431 + "w": 435, + "h": 435 }, "scale": 1, "frames": [ { - "filename": "galarica_cuff", + "filename": "relic_gold", "rotated": false, "trimmed": true, "sourceSize": { @@ -18,1612 +18,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 29, - "h": 30 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 30 - } - }, - { - "filename": "galarica_wreath", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 32, - "h": 27 - }, - "frame": { - "x": 29, - "y": 0, - "w": 32, - "h": 27 - } - }, - { - "filename": "max_mushrooms", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 1, - "y": 3, - "w": 29, - "h": 28 - }, - "frame": { - "x": 0, - "y": 30, - "w": 29, - "h": 28 - } - }, - { - "filename": "ribbon_gen4", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 30, - "h": 28 - }, - "frame": { - "x": 29, - "y": 27, - "w": 30, - "h": 28 - } - }, - { - "filename": "leaders_crest", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 29, - "h": 27 - }, - "frame": { - "x": 61, - "y": 0, - "w": 29, - "h": 27 - } - }, - { - "filename": "ribbon_gen2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 28, - "h": 28 - }, - "frame": { - "x": 0, - "y": 58, - "w": 28, - "h": 28 - } - }, - { - "filename": "bronze_ribbon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 31 - }, - "frame": { - "x": 0, - "y": 86, - "w": 22, - "h": 31 - } - }, - { - "filename": "great_ribbon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 31 - }, - "frame": { - "x": 0, - "y": 117, - "w": 22, - "h": 31 - } - }, - { - "filename": "linking_cord", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 27, - "h": 26 - }, - "frame": { - "x": 59, - "y": 27, - "w": 27, - "h": 26 - } - }, - { - "filename": "master_ribbon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 31 - }, - "frame": { - "x": 0, - "y": 148, - "w": 22, - "h": 31 - } - }, - { - "filename": "rogue_ribbon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 31 - }, - "frame": { - "x": 0, - "y": 179, - "w": 22, - "h": 31 - } - }, - { - "filename": "ultra_ribbon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 31 - }, - "frame": { - "x": 0, - "y": 210, - "w": 22, - "h": 31 - } - }, - { - "filename": "inverse", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 30 - }, - "frame": { - "x": 0, - "y": 241, - "w": 22, - "h": 30 - } - }, - { - "filename": "ribbon_gen3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 29 - }, - "frame": { - "x": 0, - "y": 271, - "w": 22, - "h": 29 - } - }, - { - "filename": "ribbon_gen7", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 29 - }, - "frame": { - "x": 0, - "y": 300, - "w": 22, - "h": 29 - } - }, - { - "filename": "ribbon_gen9", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 22, - "h": 29 - }, - "frame": { - "x": 0, - "y": 329, - "w": 22, - "h": 29 - } - }, - { - "filename": "cornerstone_mask", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 24, - "h": 26 - }, - "frame": { - "x": 90, - "y": 0, - "w": 24, - "h": 26 - } - }, - { - "filename": "ribbon_gen1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 22, - "h": 28 - }, - "frame": { - "x": 0, - "y": 358, - "w": 22, - "h": 28 - } - }, - { - "filename": "ribbon_gen5", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 22, - "h": 28 - }, - "frame": { - "x": 0, - "y": 386, - "w": 22, - "h": 28 - } - }, - { - "filename": "black_glasses", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 0, - "y": 414, - "w": 23, - "h": 17 - } - }, - { - "filename": "ability_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 23, - "h": 26 - }, - "frame": { - "x": 114, - "y": 0, - "w": 23, - "h": 26 - } - }, - { - "filename": "map", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 3, - "y": 5, - "w": 27, - "h": 22 - }, - "frame": { - "x": 137, - "y": 0, - "w": 27, - "h": 22 - } - }, - { - "filename": "mint_atk", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 2, - "y": 5, - "w": 28, - "h": 21 - }, - "frame": { - "x": 164, - "y": 0, - "w": 28, - "h": 21 - } - }, - { - "filename": "mint_def", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 2, - "y": 5, - "w": 28, - "h": 21 - }, - "frame": { - "x": 192, - "y": 0, - "w": 28, - "h": 21 - } - }, - { - "filename": "mint_neutral", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 2, - "y": 5, - "w": 28, - "h": 21 - }, - "frame": { - "x": 220, - "y": 0, - "w": 28, - "h": 21 - } - }, - { - "filename": "mint_spatk", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 2, - "y": 5, - "w": 28, - "h": 21 - }, - "frame": { - "x": 248, - "y": 0, - "w": 28, - "h": 21 - } - }, - { - "filename": "mint_spd", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 2, - "y": 5, - "w": 28, - "h": 21 - }, - "frame": { - "x": 276, - "y": 0, - "w": 28, - "h": 21 - } - }, - { - "filename": "mint_spdef", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 2, - "y": 5, - "w": 28, - "h": 21 - }, - "frame": { - "x": 304, - "y": 0, - "w": 28, - "h": 21 - } - }, - { - "filename": "chipped_pot", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 3, - "y": 6, - "w": 26, - "h": 20 - }, - "frame": { - "x": 332, - "y": 0, - "w": 26, - "h": 20 - } - }, - { - "filename": "cracked_pot", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 3, - "y": 6, - "w": 26, - "h": 20 - }, - "frame": { - "x": 358, - "y": 0, - "w": 26, - "h": 20 - } - }, - { - "filename": "legend_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 3, - "y": 6, - "w": 25, - "h": 20 - }, - "frame": { - "x": 384, - "y": 0, - "w": 25, - "h": 20 - } - }, - { - "filename": "ribbon_gen6", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 22, - "h": 28 - }, - "frame": { - "x": 409, - "y": 0, - "w": 22, - "h": 28 - } - }, - { - "filename": "exp_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 17, - "h": 31 - }, - "frame": { - "x": 22, - "y": 86, - "w": 17, - "h": 31 - } - }, - { - "filename": "golden_exp_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 17, - "h": 31 - }, - "frame": { - "x": 22, - "y": 117, - "w": 17, - "h": 31 - } - }, - { - "filename": "super_exp_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 17, - "h": 31 - }, - "frame": { - "x": 22, - "y": 148, - "w": 17, - "h": 31 - } - }, - { - "filename": "prison_bottle", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 17, - "h": 30 - }, - "frame": { - "x": 22, - "y": 179, - "w": 17, - "h": 30 - } - }, - { - "filename": "ribbon_gen8", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 22, - "h": 28 - }, - "frame": { - "x": 22, - "y": 209, - "w": 22, - "h": 28 - } - }, - { - "filename": "black_augurite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 3, - "w": 22, - "h": 25 - }, - "frame": { - "x": 22, - "y": 237, - "w": 22, - "h": 25 - } - }, - { - "filename": "big_root", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 22, - "y": 262, - "w": 23, - "h": 24 - } - }, - { - "filename": "blank_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 22, - "y": 286, - "w": 24, - "h": 24 - } - }, - { - "filename": "choice_scarf", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 22, - "y": 310, - "w": 24, - "h": 24 - } - }, - { - "filename": "draco_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 22, - "y": 334, - "w": 24, - "h": 24 - } - }, - { - "filename": "dread_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 22, - "y": 358, - "w": 24, - "h": 24 - } - }, - { - "filename": "earth_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 22, - "y": 382, - "w": 24, - "h": 24 - } - }, - { - "filename": "fist_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 23, - "y": 406, - "w": 24, - "h": 24 - } - }, - { - "filename": "ultranecrozium_z", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 1, - "y": 9, - "w": 30, - "h": 15 - }, - "frame": { - "x": 29, - "y": 55, - "w": 30, - "h": 15 - } - }, - { - "filename": "mega_bracelet", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 16 - }, - "frame": { - "x": 28, - "y": 70, - "w": 20, - "h": 16 - } - }, - { - "filename": "choice_specs", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 24, - "h": 18 - }, - "frame": { - "x": 59, - "y": 53, - "w": 24, - "h": 18 - } - }, - { - "filename": "calcium", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 39, - "y": 86, - "w": 16, - "h": 24 - } - }, - { - "filename": "carbos", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 39, - "y": 110, - "w": 16, - "h": 24 - } - }, - { - "filename": "catching_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 21, - "h": 24 - }, - "frame": { - "x": 39, - "y": 134, - "w": 21, - "h": 24 - } - }, - { - "filename": "flame_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 39, - "y": 158, - "w": 24, - "h": 24 - } - }, - { - "filename": "focus_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 39, - "y": 182, - "w": 24, - "h": 24 - } - }, - { - "filename": "golden_punch", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 44, - "y": 206, - "w": 24, - "h": 24 - } - }, - { - "filename": "gracidea", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 44, - "y": 230, - "w": 24, - "h": 24 - } - }, - { - "filename": "grip_claw", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 45, - "y": 254, - "w": 24, - "h": 24 - } - }, - { - "filename": "icicle_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 46, - "y": 278, - "w": 24, - "h": 24 - } - }, - { - "filename": "insect_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 46, - "y": 302, - "w": 24, - "h": 24 - } - }, - { - "filename": "iron_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 46, - "y": 326, - "w": 24, - "h": 24 - } - }, - { - "filename": "lucky_punch", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 46, - "y": 350, - "w": 24, - "h": 24 - } - }, - { - "filename": "lucky_punch_great", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 46, - "y": 374, - "w": 24, - "h": 24 - } - }, - { - "filename": "kings_rock", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 47, - "y": 398, - "w": 23, - "h": 24 - } - }, - { - "filename": "silver_powder", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, + "x": 9, "y": 11, - "w": 24, - "h": 15 + "w": 15, + "h": 11 }, "frame": { - "x": 48, - "y": 71, - "w": 24, - "h": 15 - } - }, - { - "filename": "elixir", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 18, - "h": 24 - }, - "frame": { - "x": 55, - "y": 86, - "w": 18, - "h": 24 - } - }, - { - "filename": "ether", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 18, - "h": 24 - }, - "frame": { - "x": 55, - "y": 110, - "w": 18, - "h": 24 - } - }, - { - "filename": "full_restore", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 18, - "h": 24 - }, - "frame": { - "x": 60, - "y": 134, - "w": 18, - "h": 24 - } - }, - { - "filename": "hp_up", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 63, - "y": 158, - "w": 16, - "h": 24 - } - }, - { - "filename": "iron", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 63, - "y": 182, - "w": 16, - "h": 24 - } - }, - { - "filename": "lucky_punch_master", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 68, - "y": 206, - "w": 24, - "h": 24 - } - }, - { - "filename": "lucky_punch_ultra", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 68, - "y": 230, - "w": 24, - "h": 24 - } - }, - { - "filename": "lustrous_globe", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 69, - "y": 254, - "w": 24, - "h": 24 - } - }, - { - "filename": "meadow_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 70, - "y": 278, - "w": 24, - "h": 24 - } - }, - { - "filename": "mind_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 70, - "y": 302, - "w": 24, - "h": 24 - } - }, - { - "filename": "muscle_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 70, - "y": 326, - "w": 24, - "h": 24 - } - }, - { - "filename": "pixie_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 70, - "y": 350, - "w": 24, - "h": 24 - } - }, - { - "filename": "salac_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 70, - "y": 374, - "w": 24, - "h": 24 - } - }, - { - "filename": "scanner", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 70, - "y": 398, - "w": 24, - "h": 24 + "x": 0, + "y": 0, + "w": 15, + "h": 11 } }, { @@ -1641,411 +45,12 @@ "h": 14 }, "frame": { - "x": 137, - "y": 22, + "x": 15, + "y": 0, "w": 24, "h": 14 } }, - { - "filename": "lure", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 17, - "h": 24 - }, - "frame": { - "x": 86, - "y": 27, - "w": 17, - "h": 24 - } - }, - { - "filename": "silk_scarf", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 103, - "y": 26, - "w": 24, - "h": 24 - } - }, - { - "filename": "clefairy_doll", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 127, - "y": 36, - "w": 24, - "h": 23 - } - }, - { - "filename": "coin_case", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 103, - "y": 50, - "w": 24, - "h": 23 - } - }, - { - "filename": "big_nugget", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 83, - "y": 53, - "w": 20, - "h": 20 - } - }, - { - "filename": "dragon_scale", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 24, - "h": 18 - }, - "frame": { - "x": 127, - "y": 59, - "w": 24, - "h": 18 - } - }, - { - "filename": "max_elixir", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 18, - "h": 24 - }, - "frame": { - "x": 151, - "y": 36, - "w": 18, - "h": 24 - } - }, - { - "filename": "adamant_crystal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 151, - "y": 60, - "w": 23, - "h": 21 - } - }, - { - "filename": "sky_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 169, - "y": 21, - "w": 24, - "h": 24 - } - }, - { - "filename": "splash_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 193, - "y": 21, - "w": 24, - "h": 24 - } - }, - { - "filename": "spooky_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 217, - "y": 21, - "w": 24, - "h": 24 - } - }, - { - "filename": "stone_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 241, - "y": 21, - "w": 24, - "h": 24 - } - }, - { - "filename": "sun_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 265, - "y": 21, - "w": 24, - "h": 24 - } - }, - { - "filename": "toxic_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 289, - "y": 21, - "w": 24, - "h": 24 - } - }, - { - "filename": "max_revive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 24 - }, - "frame": { - "x": 313, - "y": 21, - "w": 22, - "h": 24 - } - }, - { - "filename": "zap_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 335, - "y": 20, - "w": 24, - "h": 24 - } - }, - { - "filename": "expert_belt", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 23 - }, - "frame": { - "x": 359, - "y": 20, - "w": 24, - "h": 23 - } - }, - { - "filename": "hearthflame_mask", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 23 - }, - "frame": { - "x": 383, - "y": 20, - "w": 24, - "h": 23 - } - }, - { - "filename": "leppa_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 407, - "y": 28, - "w": 24, - "h": 23 - } - }, { "filename": "candy_overlay", "rotated": false, @@ -2061,600 +66,12 @@ "h": 15 }, "frame": { - "x": 169, - "y": 45, + "x": 39, + "y": 0, "w": 16, "h": 15 } }, - { - "filename": "exp_balance", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 22 - }, - "frame": { - "x": 185, - "y": 45, - "w": 24, - "h": 22 - } - }, - { - "filename": "exp_share", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 22 - }, - "frame": { - "x": 209, - "y": 45, - "w": 24, - "h": 22 - } - }, - { - "filename": "peat_block", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 22 - }, - "frame": { - "x": 233, - "y": 45, - "w": 24, - "h": 22 - } - }, - { - "filename": "scope_lens", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 257, - "y": 45, - "w": 24, - "h": 23 - } - }, - { - "filename": "twisted_spoon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 281, - "y": 45, - "w": 24, - "h": 23 - } - }, - { - "filename": "berry_pouch", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 305, - "y": 45, - "w": 23, - "h": 23 - } - }, - { - "filename": "black_belt", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 328, - "y": 45, - "w": 22, - "h": 23 - } - }, - { - "filename": "max_ether", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 18, - "h": 24 - }, - "frame": { - "x": 350, - "y": 44, - "w": 18, - "h": 24 - } - }, - { - "filename": "reveal_glass", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 368, - "y": 43, - "w": 23, - "h": 24 - } - }, - { - "filename": "max_repel", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 391, - "y": 43, - "w": 16, - "h": 24 - } - }, - { - "filename": "golden_net", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 21 - }, - "frame": { - "x": 407, - "y": 51, - "w": 24, - "h": 21 - } - }, - { - "filename": "icy_reins_of_unity", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 24, - "h": 20 - }, - "frame": { - "x": 174, - "y": 67, - "w": 24, - "h": 20 - } - }, - { - "filename": "metal_powder", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 24, - "h": 20 - }, - "frame": { - "x": 198, - "y": 67, - "w": 24, - "h": 20 - } - }, - { - "filename": "quick_powder", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 24, - "h": 20 - }, - "frame": { - "x": 222, - "y": 67, - "w": 24, - "h": 20 - } - }, - { - "filename": "rusted_shield", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 24, - "h": 20 - }, - "frame": { - "x": 246, - "y": 68, - "w": 24, - "h": 20 - } - }, - { - "filename": "sacred_ash", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 24, - "h": 20 - }, - "frame": { - "x": 270, - "y": 68, - "w": 24, - "h": 20 - } - }, - { - "filename": "shadow_reins_of_unity", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 24, - "h": 20 - }, - "frame": { - "x": 294, - "y": 68, - "w": 24, - "h": 20 - } - }, - { - "filename": "soft_sand", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 24, - "h": 20 - }, - "frame": { - "x": 318, - "y": 68, - "w": 24, - "h": 20 - } - }, - { - "filename": "amulet_coin", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 23, - "h": 21 - }, - "frame": { - "x": 342, - "y": 68, - "w": 23, - "h": 21 - } - }, - { - "filename": "auspicious_armor", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 21 - }, - "frame": { - "x": 368, - "y": 67, - "w": 23, - "h": 21 - } - }, - { - "filename": "pp_max", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 391, - "y": 67, - "w": 16, - "h": 24 - } - }, - { - "filename": "binding_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 23, - "h": 20 - }, - "frame": { - "x": 407, - "y": 72, - "w": 23, - "h": 20 - } - }, - { - "filename": "max_lure", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 17, - "h": 24 - }, - "frame": { - "x": 73, - "y": 87, - "w": 17, - "h": 24 - } - }, - { - "filename": "bug_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 73, - "y": 111, - "w": 22, - "h": 23 - } - }, - { - "filename": "max_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 18, - "h": 24 - }, - "frame": { - "x": 78, - "y": 134, - "w": 18, - "h": 24 - } - }, - { - "filename": "oval_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 21, - "h": 24 - }, - "frame": { - "x": 79, - "y": 158, - "w": 21, - "h": 24 - } - }, - { - "filename": "shiny_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 21, - "h": 24 - }, - "frame": { - "x": 79, - "y": 182, - "w": 21, - "h": 24 - } - }, - { - "filename": "dynamax_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 23, - "h": 23 - }, - "frame": { - "x": 90, - "y": 73, - "w": 23, - "h": 23 - } - }, { "filename": "eviolite", "rotated": false, @@ -2670,306 +87,12 @@ "h": 15 }, "frame": { - "x": 90, - "y": 96, + "x": 55, + "y": 0, "w": 15, "h": 15 } }, - { - "filename": "dark_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 95, - "y": 111, - "w": 22, - "h": 23 - } - }, - { - "filename": "red_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 20, - "h": 24 - }, - "frame": { - "x": 96, - "y": 134, - "w": 20, - "h": 24 - } - }, - { - "filename": "pp_up", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 100, - "y": 158, - "w": 16, - "h": 24 - } - }, - { - "filename": "protein", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 100, - "y": 182, - "w": 16, - "h": 24 - } - }, - { - "filename": "griseous_core", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 92, - "y": 206, - "w": 23, - "h": 23 - } - }, - { - "filename": "leek", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 92, - "y": 229, - "w": 23, - "h": 23 - } - }, - { - "filename": "dragon_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 93, - "y": 252, - "w": 22, - "h": 23 - } - }, - { - "filename": "dragon_fang", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 94, - "y": 275, - "w": 21, - "h": 23 - } - }, - { - "filename": "electric_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 94, - "y": 298, - "w": 22, - "h": 23 - } - }, - { - "filename": "fairy_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 94, - "y": 321, - "w": 22, - "h": 23 - } - }, - { - "filename": "fighting_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 94, - "y": 344, - "w": 22, - "h": 23 - } - }, - { - "filename": "fire_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 94, - "y": 367, - "w": 22, - "h": 23 - } - }, - { - "filename": "fire_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 94, - "y": 390, - "w": 22, - "h": 23 - } - }, - { - "filename": "relic_crown", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 18 - }, - "frame": { - "x": 94, - "y": 413, - "w": 23, - "h": 18 - } - }, { "filename": "prism_scale", "rotated": false, @@ -2985,14 +108,14 @@ "h": 15 }, "frame": { - "x": 105, - "y": 96, + "x": 70, + "y": 0, "w": 15, "h": 15 } }, { - "filename": "coupon", + "filename": "silver_powder", "rotated": false, "trimmed": true, "sourceSize": { @@ -3001,19 +124,19 @@ }, "spriteSourceSize": { "x": 4, - "y": 7, - "w": 23, - "h": 19 + "y": 11, + "w": 24, + "h": 15 }, "frame": { - "x": 113, - "y": 77, - "w": 23, - "h": 19 + "x": 85, + "y": 0, + "w": 24, + "h": 15 } }, { - "filename": "full_heal", + "filename": "ultranecrozium_z", "rotated": false, "trimmed": true, "sourceSize": { @@ -3021,205 +144,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 15, - "h": 23 + "x": 1, + "y": 9, + "w": 30, + "h": 15 }, "frame": { - "x": 136, - "y": 77, - "w": 15, - "h": 23 - } - }, - { - "filename": "golden_mystic_ticket", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 151, - "y": 81, - "w": 23, - "h": 19 - } - }, - { - "filename": "burn_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 174, - "y": 87, - "w": 23, - "h": 17 - } - }, - { - "filename": "chill_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 197, - "y": 87, - "w": 23, - "h": 17 - } - }, - { - "filename": "douse_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 220, - "y": 87, - "w": 23, - "h": 17 - } - }, - { - "filename": "healing_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 23, - "h": 22 - }, - "frame": { - "x": 243, - "y": 88, - "w": 23, - "h": 22 - } - }, - { - "filename": "macho_brace", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 266, - "y": 88, - "w": 23, - "h": 23 - } - }, - { - "filename": "rare_candy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 289, - "y": 88, - "w": 23, - "h": 23 - } - }, - { - "filename": "rarer_candy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 312, - "y": 88, - "w": 23, - "h": 23 - } - }, - { - "filename": "rusted_sword", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 22 - }, - "frame": { - "x": 335, - "y": 89, - "w": 23, - "h": 22 + "x": 109, + "y": 0, + "w": 30, + "h": 15 } }, { @@ -3237,2847 +171,12 @@ "h": 16 }, "frame": { - "x": 120, - "y": 96, + "x": 139, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "bug_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 117, - "y": 112, - "w": 22, - "h": 22 - } - }, - { - "filename": "flying_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 116, - "y": 134, - "w": 22, - "h": 23 - } - }, - { - "filename": "focus_sash", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 116, - "y": 157, - "w": 22, - "h": 23 - } - }, - { - "filename": "ghost_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 116, - "y": 180, - "w": 22, - "h": 23 - } - }, - { - "filename": "grass_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 139, - "y": 100, - "w": 22, - "h": 23 - } - }, - { - "filename": "berry_juice", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 21 - }, - "frame": { - "x": 139, - "y": 123, - "w": 22, - "h": 21 - } - }, - { - "filename": "ground_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 138, - "y": 144, - "w": 22, - "h": 23 - } - }, - { - "filename": "ice_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 138, - "y": 167, - "w": 22, - "h": 23 - } - }, - { - "filename": "black_sludge", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 19 - }, - "frame": { - "x": 138, - "y": 190, - "w": 22, - "h": 19 - } - }, - { - "filename": "never_melt_ice", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 161, - "y": 104, - "w": 22, - "h": 23 - } - }, - { - "filename": "normal_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 183, - "y": 104, - "w": 22, - "h": 23 - } - }, - { - "filename": "petaya_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 205, - "y": 104, - "w": 22, - "h": 23 - } - }, - { - "filename": "repel", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 227, - "y": 104, - "w": 16, - "h": 24 - } - }, - { - "filename": "moon_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 243, - "y": 110, - "w": 23, - "h": 21 - } - }, - { - "filename": "n_lunarizer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 266, - "y": 111, - "w": 23, - "h": 21 - } - }, - { - "filename": "n_solarizer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 289, - "y": 111, - "w": 23, - "h": 21 - } - }, - { - "filename": "wellspring_mask", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 21 - }, - "frame": { - "x": 312, - "y": 111, - "w": 23, - "h": 21 - } - }, - { - "filename": "charcoal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 335, - "y": 111, - "w": 22, - "h": 22 - } - }, - { - "filename": "mystic_ticket", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 161, - "y": 127, - "w": 23, - "h": 19 - } - }, - { - "filename": "poison_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 160, - "y": 146, - "w": 22, - "h": 23 - } - }, - { - "filename": "psychic_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 160, - "y": 169, - "w": 22, - "h": 23 - } - }, - { - "filename": "pair_of_tickets", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 184, - "y": 127, - "w": 23, - "h": 19 - } - }, - { - "filename": "reaper_cloth", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 182, - "y": 146, - "w": 22, - "h": 23 - } - }, - { - "filename": "rock_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 182, - "y": 169, - "w": 22, - "h": 23 - } - }, - { - "filename": "blue_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 207, - "y": 127, - "w": 20, - "h": 20 - } - }, - { - "filename": "steel_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 204, - "y": 147, - "w": 22, - "h": 23 - } - }, - { - "filename": "dark_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 204, - "y": 170, - "w": 22, - "h": 22 - } - }, - { - "filename": "reviver_seed", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 8, - "w": 23, - "h": 20 - }, - "frame": { - "x": 160, - "y": 192, - "w": 23, - "h": 20 - } - }, - { - "filename": "shell_bell", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 23, - "h": 20 - }, - "frame": { - "x": 183, - "y": 192, - "w": 23, - "h": 20 - } - }, - { - "filename": "dawn_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 21 - }, - "frame": { - "x": 206, - "y": 192, - "w": 20, - "h": 21 - } - }, - { - "filename": "super_repel", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 227, - "y": 128, - "w": 16, - "h": 24 - } - }, - { - "filename": "deep_sea_tooth", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 243, - "y": 131, - "w": 22, - "h": 21 - } - }, - { - "filename": "stellar_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 226, - "y": 152, - "w": 22, - "h": 23 - } - }, - { - "filename": "water_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 226, - "y": 175, - "w": 22, - "h": 23 - } - }, - { - "filename": "deep_sea_scale", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 20 - }, - "frame": { - "x": 265, - "y": 132, - "w": 22, - "h": 20 - } - }, - { - "filename": "wide_lens", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 248, - "y": 152, - "w": 22, - "h": 23 - } - }, - { - "filename": "dire_hit", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 248, - "y": 175, - "w": 22, - "h": 22 - } - }, - { - "filename": "dna_splicers", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 287, - "y": 132, - "w": 22, - "h": 22 - } - }, - { - "filename": "dragon_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 309, - "y": 132, - "w": 22, - "h": 22 - } - }, - { - "filename": "super_lure", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 17, - "h": 24 - }, - "frame": { - "x": 270, - "y": 152, - "w": 17, - "h": 24 - } - }, - { - "filename": "electirizer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 287, - "y": 154, - "w": 22, - "h": 22 - } - }, - { - "filename": "electric_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 309, - "y": 154, - "w": 22, - "h": 22 - } - }, - { - "filename": "enigma_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 270, - "y": 176, - "w": 22, - "h": 22 - } - }, - { - "filename": "fairy_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 292, - "y": 176, - "w": 22, - "h": 22 - } - }, - { - "filename": "fighting_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 331, - "y": 133, - "w": 22, - "h": 22 - } - }, - { - "filename": "fire_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 331, - "y": 155, - "w": 22, - "h": 22 - } - }, - { - "filename": "hyper_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 314, - "y": 176, - "w": 17, - "h": 23 - } - }, - { - "filename": "flying_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 331, - "y": 177, - "w": 22, - "h": 22 - } - }, - { - "filename": "blunder_policy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 19 - }, - "frame": { - "x": 226, - "y": 198, - "w": 22, - "h": 19 - } - }, - { - "filename": "fairy_feather", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 20 - }, - "frame": { - "x": 248, - "y": 197, - "w": 22, - "h": 20 - } - }, - { - "filename": "dubious_disc", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 19 - }, - "frame": { - "x": 270, - "y": 198, - "w": 22, - "h": 19 - } - }, - { - "filename": "ganlon_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 292, - "y": 198, - "w": 22, - "h": 22 - } - }, - { - "filename": "ghost_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 314, - "y": 199, - "w": 22, - "h": 22 - } - }, - { - "filename": "berry_pot", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 18, - "h": 22 - }, - "frame": { - "x": 336, - "y": 199, - "w": 18, - "h": 22 - } - }, - { - "filename": "grass_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 116, - "y": 203, - "w": 22, - "h": 22 - } - }, - { - "filename": "ground_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 115, - "y": 225, - "w": 22, - "h": 22 - } - }, - { - "filename": "guard_spec", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 115, - "y": 247, - "w": 22, - "h": 22 - } - }, - { - "filename": "ice_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 115, - "y": 269, - "w": 22, - "h": 22 - } - }, - { - "filename": "ice_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 138, - "y": 209, - "w": 22, - "h": 22 - } - }, - { - "filename": "lansat_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 21, - "h": 23 - }, - "frame": { - "x": 137, - "y": 231, - "w": 21, - "h": 23 - } - }, - { - "filename": "leaf_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 137, - "y": 254, - "w": 21, - "h": 23 - } - }, - { - "filename": "liechi_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 160, - "y": 212, - "w": 22, - "h": 21 - } - }, - { - "filename": "magmarizer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 182, - "y": 212, - "w": 22, - "h": 22 - } - }, - { - "filename": "mini_black_hole", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 204, - "y": 213, - "w": 22, - "h": 22 - } - }, - { - "filename": "moon_flute", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 158, - "y": 233, - "w": 22, - "h": 22 - } - }, - { - "filename": "normal_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 158, - "y": 255, - "w": 22, - "h": 22 - } - }, - { - "filename": "poison_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 180, - "y": 234, - "w": 22, - "h": 22 - } - }, - { - "filename": "protector", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 180, - "y": 256, - "w": 22, - "h": 22 - } - }, - { - "filename": "psychic_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 202, - "y": 235, - "w": 22, - "h": 22 - } - }, - { - "filename": "rock_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 202, - "y": 257, - "w": 22, - "h": 22 - } - }, - { - "filename": "malicious_armor", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 20 - }, - "frame": { - "x": 226, - "y": 217, - "w": 22, - "h": 20 - } - }, - { - "filename": "scroll_of_darkness", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 248, - "y": 217, - "w": 22, - "h": 22 - } - }, - { - "filename": "scroll_of_waters", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 270, - "y": 217, - "w": 22, - "h": 22 - } - }, - { - "filename": "sharp_beak", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 224, - "y": 237, - "w": 21, - "h": 23 - } - }, - { - "filename": "shed_shell", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 292, - "y": 220, - "w": 22, - "h": 22 - } - }, - { - "filename": "starf_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 314, - "y": 221, - "w": 22, - "h": 22 - } - }, - { - "filename": "dusk_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 224, - "y": 260, - "w": 21, - "h": 21 - } - }, - { - "filename": "steel_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 245, - "y": 239, - "w": 22, - "h": 22 - } - }, - { - "filename": "sun_flute", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 267, - "y": 239, - "w": 22, - "h": 22 - } - }, - { - "filename": "sweet_apple", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 245, - "y": 261, - "w": 22, - "h": 21 - } - }, - { - "filename": "syrupy_apple", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 267, - "y": 261, - "w": 22, - "h": 21 - } - }, - { - "filename": "thick_club", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 289, - "y": 242, - "w": 22, - "h": 22 - } - }, - { - "filename": "hard_meteorite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 20, - "h": 22 - }, - "frame": { - "x": 336, - "y": 221, - "w": 20, - "h": 22 - } - }, - { - "filename": "tart_apple", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 289, - "y": 264, - "w": 22, - "h": 21 - } - }, - { - "filename": "thunder_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 311, - "y": 243, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_bug", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 333, - "y": 243, - "w": 22, - "h": 22 - } - }, - { - "filename": "tera_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 20 - }, - "frame": { - "x": 311, - "y": 265, - "w": 22, - "h": 20 - } - }, - { - "filename": "tm_dark", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 333, - "y": 265, - "w": 22, - "h": 22 - } - }, - { - "filename": "shock_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 137, - "y": 277, - "w": 23, - "h": 17 - } - }, - { - "filename": "whipped_dream", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 21, - "h": 23 - }, - "frame": { - "x": 116, - "y": 291, - "w": 21, - "h": 23 - } - }, - { - "filename": "mystic_water", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 20, - "h": 23 - }, - "frame": { - "x": 116, - "y": 314, - "w": 20, - "h": 23 - } - }, - { - "filename": "sitrus_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 20, - "h": 22 - }, - "frame": { - "x": 116, - "y": 337, - "w": 20, - "h": 22 - } - }, - { - "filename": "tm_dragon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 137, - "y": 294, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_electric", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 136, - "y": 316, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_fairy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 136, - "y": 338, - "w": 22, - "h": 22 - } - }, - { - "filename": "gb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 116, - "y": 359, - "w": 20, - "h": 20 - } - }, - { - "filename": "tm_fighting", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 116, - "y": 379, - "w": 22, - "h": 22 - } - }, - { - "filename": "upgrade", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 19 - }, - "frame": { - "x": 136, - "y": 360, - "w": 22, - "h": 19 - } - }, - { - "filename": "tm_fire", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 138, - "y": 379, - "w": 22, - "h": 22 - } - }, - { - "filename": "everstone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 17 - }, - "frame": { - "x": 160, - "y": 277, - "w": 20, - "h": 17 - } - }, - { - "filename": "tm_flying", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 159, - "y": 294, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_ghost", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 158, - "y": 316, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_grass", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 158, - "y": 338, - "w": 22, - "h": 22 - } - }, - { - "filename": "metal_alloy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 21, - "h": 19 - }, - "frame": { - "x": 158, - "y": 360, - "w": 21, - "h": 19 - } - }, - { - "filename": "lock_capsule", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 19, - "h": 22 - }, - "frame": { - "x": 160, - "y": 379, - "w": 19, - "h": 22 - } - }, - { - "filename": "relic_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 17, - "h": 16 - }, - "frame": { - "x": 180, - "y": 278, - "w": 17, - "h": 16 - } - }, - { - "filename": "metal_coat", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 19, - "h": 22 - }, - "frame": { - "x": 181, - "y": 294, - "w": 19, - "h": 22 - } - }, - { - "filename": "tm_ground", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 180, - "y": 316, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_ice", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 180, - "y": 338, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_normal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 179, - "y": 360, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_poison", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 179, - "y": 382, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_psychic", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 117, - "y": 401, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_rock", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 139, - "y": 401, - "w": 22, - "h": 22 - } - }, - { - "filename": "sachet", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 18, - "h": 23 - }, - "frame": { - "x": 161, - "y": 401, - "w": 18, - "h": 23 - } - }, - { - "filename": "tm_steel", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 179, - "y": 404, - "w": 22, - "h": 22 - } - }, - { - "filename": "leftovers", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 15, - "h": 22 - }, - "frame": { - "x": 358, - "y": 89, - "w": 15, - "h": 22 - } - }, - { - "filename": "razor_fang", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 18, - "h": 20 - }, - "frame": { - "x": 373, - "y": 88, - "w": 18, - "h": 20 - } - }, - { - "filename": "metronome", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 17, - "h": 22 - }, - "frame": { - "x": 357, - "y": 111, - "w": 17, - "h": 22 - } - }, - { - "filename": "tm_water", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 353, - "y": 133, - "w": 22, - "h": 22 - } - }, - { - "filename": "water_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 353, - "y": 155, - "w": 22, - "h": 22 - } - }, - { - "filename": "water_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 353, - "y": 177, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_accuracy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 354, - "y": 199, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_attack", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 356, - "y": 221, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_defense", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 355, - "y": 243, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_sp_atk", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 355, - "y": 265, - "w": 22, - "h": 22 - } - }, - { - "filename": "potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 374, - "y": 108, - "w": 17, - "h": 23 - } - }, - { - "filename": "unknown", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 391, - "y": 91, - "w": 16, - "h": 24 - } - }, - { - "filename": "x_sp_def", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 407, - "y": 92, - "w": 22, - "h": 22 - } - }, - { - "filename": "zinc", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 375, - "y": 131, - "w": 16, - "h": 24 - } - }, - { - "filename": "super_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 391, - "y": 115, - "w": 17, - "h": 23 - } - }, - { - "filename": "wise_glasses", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 408, - "y": 114, - "w": 23, - "h": 17 - } - }, - { - "filename": "soothe_bell", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 22 - }, - "frame": { - "x": 375, - "y": 155, - "w": 17, - "h": 22 - } - }, - { - "filename": "x_speed", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 375, - "y": 177, - "w": 22, - "h": 22 - } - }, - { - "filename": "poison_barb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 376, - "y": 199, - "w": 21, - "h": 21 - } - }, - { - "filename": "quick_claw", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 21 - }, - "frame": { - "x": 378, - "y": 220, - "w": 19, - "h": 21 - } - }, { "filename": "absolite", "rotated": false, @@ -6093,138 +192,12 @@ "h": 16 }, "frame": { - "x": 391, - "y": 138, + "x": 155, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "shiny_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 392, - "y": 154, - "w": 21, - "h": 21 - } - }, - { - "filename": "oval_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 19 - }, - "frame": { - "x": 413, - "y": 131, - "w": 18, - "h": 19 - } - }, - { - "filename": "baton", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 413, - "y": 150, - "w": 18, - "h": 18 - } - }, - { - "filename": "candy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 11, - "w": 18, - "h": 18 - }, - "frame": { - "x": 413, - "y": 168, - "w": 18, - "h": 18 - } - }, - { - "filename": "mystery_egg", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 18 - }, - "frame": { - "x": 397, - "y": 175, - "w": 16, - "h": 18 - } - }, - { - "filename": "dark_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 413, - "y": 186, - "w": 18, - "h": 18 - } - }, { "filename": "aerodactylite", "rotated": false, @@ -6240,33 +213,12 @@ "h": 16 }, "frame": { - "x": 397, - "y": 193, + "x": 171, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "flame_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 413, - "y": 204, - "w": 18, - "h": 18 - } - }, { "filename": "aggronite", "rotated": false, @@ -6282,33 +234,12 @@ "h": 16 }, "frame": { - "x": 397, - "y": 209, + "x": 187, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "light_ball", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 413, - "y": 222, - "w": 18, - "h": 18 - } - }, { "filename": "alakazite", "rotated": false, @@ -6324,117 +255,12 @@ "h": 16 }, "frame": { - "x": 397, - "y": 225, + "x": 203, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "light_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 413, - "y": 240, - "w": 18, - "h": 18 - } - }, - { - "filename": "zoom_lens", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 200, - "y": 279, - "w": 21, - "h": 21 - } - }, - { - "filename": "lum_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 20, - "h": 19 - }, - "frame": { - "x": 221, - "y": 281, - "w": 20, - "h": 19 - } - }, - { - "filename": "masterpiece_teacup", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 21, - "h": 18 - }, - "frame": { - "x": 241, - "y": 282, - "w": 21, - "h": 18 - } - }, - { - "filename": "old_gateau", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 21, - "h": 18 - }, - "frame": { - "x": 262, - "y": 282, - "w": 21, - "h": 18 - } - }, { "filename": "altarianite", "rotated": false, @@ -6450,810 +276,12 @@ "h": 16 }, "frame": { - "x": 200, - "y": 300, + "x": 219, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "sharp_meteorite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 21, - "h": 18 - }, - "frame": { - "x": 216, - "y": 300, - "w": 21, - "h": 18 - } - }, - { - "filename": "unremarkable_teacup", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 21, - "h": 18 - }, - "frame": { - "x": 237, - "y": 300, - "w": 21, - "h": 18 - } - }, - { - "filename": "magnet", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 258, - "y": 300, - "w": 20, - "h": 20 - } - }, - { - "filename": "mb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 283, - "y": 285, - "w": 20, - "h": 20 - } - }, - { - "filename": "pb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 303, - "y": 285, - "w": 20, - "h": 20 - } - }, - { - "filename": "pb_gold", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 278, - "y": 305, - "w": 20, - "h": 20 - } - }, - { - "filename": "pb_silver", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 298, - "y": 305, - "w": 20, - "h": 20 - } - }, - { - "filename": "revive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 12, - "h": 17 - }, - "frame": { - "x": 202, - "y": 316, - "w": 12, - "h": 17 - } - }, - { - "filename": "power_herb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 20, - "h": 19 - }, - "frame": { - "x": 214, - "y": 318, - "w": 20, - "h": 19 - } - }, - { - "filename": "razor_claw", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 20, - "h": 19 - }, - "frame": { - "x": 234, - "y": 318, - "w": 20, - "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, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 274, - "y": 325, - "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": 294, - "y": 325, - "w": 20, - "h": 20 - } - }, - { - "filename": "spell_tag", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 19, - "h": 21 - }, - "frame": { - "x": 202, - "y": 337, - "w": 19, - "h": 21 - } - }, - { - "filename": "ub", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 221, - "y": 337, - "w": 20, - "h": 20 - } - }, - { - "filename": "white_herb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 20, - "h": 19 - }, - "frame": { - "x": 323, - "y": 287, - "w": 20, - "h": 19 - } - }, - { - "filename": "apicot_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 20 - }, - "frame": { - "x": 343, - "y": 287, - "w": 19, - "h": 20 - } - }, - { - "filename": "candy_jar", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 20 - }, - "frame": { - "x": 362, - "y": 287, - "w": 19, - "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, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 20 - }, - "frame": { - "x": 314, - "y": 325, - "w": 19, - "h": 20 - } - }, - { - "filename": "wl_ability_urge", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "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, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "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, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 17, - "h": 20 - }, - "frame": { - "x": 372, - "y": 325, - "w": 17, - "h": 20 - } - }, - { - "filename": "toxic_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 377, - "y": 307, - "w": 18, - "h": 18 - } - }, - { - "filename": "lucky_egg", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 17, - "h": 20 - }, - "frame": { - "x": 389, - "y": 325, - "w": 17, - "h": 20 - } - }, - { - "filename": "wl_custom_spliced", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 352, - "y": 343, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_custom_thief", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 372, - "y": 345, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_elixir", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 392, - "y": 345, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_ether", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 378, - "y": 241, - "w": 20, - "h": 18 - } - }, - { - "filename": "relic_gold", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 15, - "h": 11 - }, - "frame": { - "x": 398, - "y": 241, - "w": 15, - "h": 11 - } - }, - { - "filename": "wl_full_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 377, - "y": 259, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_full_restore", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 381, - "y": 277, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_guard_spec", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 397, - "y": 259, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_hyper_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 401, - "y": 277, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_ice_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 395, - "y": 295, - "w": 20, - "h": 18 - } - }, { "filename": "ampharosite", "rotated": false, @@ -7269,8 +297,8 @@ "h": 16 }, "frame": { - "x": 415, - "y": 295, + "x": 235, + "y": 0, "w": 16, "h": 16 } @@ -7290,33 +318,12 @@ "h": 16 }, "frame": { - "x": 415, - "y": 311, + "x": 251, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "wl_item_drop", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 406, - "y": 327, - "w": 20, - "h": 18 - } - }, { "filename": "banettite", "rotated": false, @@ -7332,201 +339,12 @@ "h": 16 }, "frame": { - "x": 412, - "y": 345, + "x": 267, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "wl_item_urge", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 221, - "y": 357, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_max_elixir", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 241, - "y": 358, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_max_ether", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 201, - "y": 360, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_max_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 201, - "y": 378, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_max_revive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 221, - "y": 375, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_paralyze_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 201, - "y": 396, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 221, - "y": 393, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_reset_urge", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 241, - "y": 376, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_revive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 241, - "y": 394, - "w": 20, - "h": 18 - } - }, { "filename": "beedrillite", "rotated": false, @@ -7542,33 +360,12 @@ "h": 16 }, "frame": { - "x": 201, - "y": 414, + "x": 283, + "y": 0, "w": 16, "h": 16 } }, - { - "filename": "wl_super_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 261, - "y": 345, - "w": 20, - "h": 18 - } - }, { "filename": "blastoisinite", "rotated": false, @@ -7584,8 +381,8 @@ "h": 16 }, "frame": { - "x": 261, - "y": 363, + "x": 299, + "y": 0, "w": 16, "h": 16 } @@ -7605,8 +402,8 @@ "h": 16 }, "frame": { - "x": 281, - "y": 345, + "x": 315, + "y": 0, "w": 16, "h": 16 } @@ -7626,8 +423,8 @@ "h": 16 }, "frame": { - "x": 261, - "y": 379, + "x": 331, + "y": 0, "w": 16, "h": 16 } @@ -7647,8 +444,8 @@ "h": 16 }, "frame": { - "x": 297, - "y": 345, + "x": 347, + "y": 0, "w": 16, "h": 16 } @@ -7668,8 +465,8 @@ "h": 16 }, "frame": { - "x": 261, - "y": 395, + "x": 363, + "y": 0, "w": 16, "h": 16 } @@ -7689,8 +486,8 @@ "h": 16 }, "frame": { - "x": 313, - "y": 345, + "x": 379, + "y": 0, "w": 16, "h": 16 } @@ -7710,8 +507,8 @@ "h": 16 }, "frame": { - "x": 217, - "y": 414, + "x": 395, + "y": 0, "w": 16, "h": 16 } @@ -7731,12 +528,33 @@ "h": 16 }, "frame": { - "x": 233, - "y": 412, + "x": 411, + "y": 0, "w": 16, "h": 16 } }, + { + "filename": "revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 12, + "h": 17 + }, + "frame": { + "x": 0, + "y": 11, + "w": 12, + "h": 17 + } + }, { "filename": "gardevoirite", "rotated": false, @@ -7752,8 +570,8 @@ "h": 16 }, "frame": { - "x": 249, - "y": 412, + "x": 12, + "y": 14, "w": 16, "h": 16 } @@ -7773,8 +591,8 @@ "h": 16 }, "frame": { - "x": 265, - "y": 411, + "x": 28, + "y": 15, "w": 16, "h": 16 } @@ -7794,8 +612,8 @@ "h": 16 }, "frame": { - "x": 329, - "y": 345, + "x": 44, + "y": 15, "w": 16, "h": 16 } @@ -7815,8 +633,8 @@ "h": 16 }, "frame": { - "x": 277, - "y": 363, + "x": 60, + "y": 15, "w": 16, "h": 16 } @@ -7836,8 +654,8 @@ "h": 16 }, "frame": { - "x": 277, - "y": 379, + "x": 76, + "y": 15, "w": 16, "h": 16 } @@ -7857,8 +675,8 @@ "h": 16 }, "frame": { - "x": 277, - "y": 395, + "x": 92, + "y": 15, "w": 16, "h": 16 } @@ -7878,8 +696,8 @@ "h": 16 }, "frame": { - "x": 293, - "y": 361, + "x": 108, + "y": 15, "w": 16, "h": 16 } @@ -7899,8 +717,8 @@ "h": 16 }, "frame": { - "x": 309, - "y": 361, + "x": 124, + "y": 16, "w": 16, "h": 16 } @@ -7920,8 +738,8 @@ "h": 16 }, "frame": { - "x": 293, - "y": 377, + "x": 140, + "y": 16, "w": 16, "h": 16 } @@ -7941,8 +759,8 @@ "h": 16 }, "frame": { - "x": 325, - "y": 361, + "x": 156, + "y": 16, "w": 16, "h": 16 } @@ -7962,8 +780,8 @@ "h": 16 }, "frame": { - "x": 293, - "y": 393, + "x": 172, + "y": 16, "w": 16, "h": 16 } @@ -7983,8 +801,8 @@ "h": 16 }, "frame": { - "x": 309, - "y": 377, + "x": 188, + "y": 16, "w": 16, "h": 16 } @@ -8004,8 +822,8 @@ "h": 16 }, "frame": { - "x": 309, - "y": 393, + "x": 204, + "y": 16, "w": 16, "h": 16 } @@ -8025,12 +843,33 @@ "h": 16 }, "frame": { - "x": 325, - "y": 377, + "x": 220, + "y": 16, "w": 16, "h": 16 } }, + { + "filename": "mega_bracelet", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 16 + }, + "frame": { + "x": 236, + "y": 16, + "w": 20, + "h": 16 + } + }, { "filename": "metagrossite", "rotated": false, @@ -8046,8 +885,8 @@ "h": 16 }, "frame": { - "x": 325, - "y": 393, + "x": 256, + "y": 16, "w": 16, "h": 16 } @@ -8067,8 +906,8 @@ "h": 16 }, "frame": { - "x": 281, - "y": 411, + "x": 272, + "y": 16, "w": 16, "h": 16 } @@ -8088,8 +927,8 @@ "h": 16 }, "frame": { - "x": 297, - "y": 409, + "x": 288, + "y": 16, "w": 16, "h": 16 } @@ -8109,8 +948,8 @@ "h": 16 }, "frame": { - "x": 313, - "y": 409, + "x": 304, + "y": 16, "w": 16, "h": 16 } @@ -8130,8 +969,8 @@ "h": 16 }, "frame": { - "x": 329, - "y": 409, + "x": 320, + "y": 16, "w": 16, "h": 16 } @@ -8151,8 +990,8 @@ "h": 16 }, "frame": { - "x": 341, - "y": 361, + "x": 336, + "y": 16, "w": 16, "h": 16 } @@ -8172,12 +1011,33 @@ "h": 16 }, "frame": { - "x": 341, - "y": 377, + "x": 352, + "y": 16, "w": 16, "h": 16 } }, + { + "filename": "relic_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 9, + "w": 17, + "h": 16 + }, + "frame": { + "x": 368, + "y": 16, + "w": 17, + "h": 16 + } + }, { "filename": "sablenite", "rotated": false, @@ -8193,8 +1053,8 @@ "h": 16 }, "frame": { - "x": 341, - "y": 393, + "x": 385, + "y": 16, "w": 16, "h": 16 } @@ -8214,8 +1074,8 @@ "h": 16 }, "frame": { - "x": 345, - "y": 409, + "x": 401, + "y": 16, "w": 16, "h": 16 } @@ -8235,8 +1095,8 @@ "h": 16 }, "frame": { - "x": 412, - "y": 361, + "x": 417, + "y": 16, "w": 16, "h": 16 } @@ -8256,8 +1116,8 @@ "h": 16 }, "frame": { - "x": 357, - "y": 363, + "x": 0, + "y": 30, "w": 16, "h": 16 } @@ -8277,8 +1137,8 @@ "h": 16 }, "frame": { - "x": 357, - "y": 379, + "x": 16, + "y": 31, "w": 16, "h": 16 } @@ -8298,8 +1158,8 @@ "h": 16 }, "frame": { - "x": 373, - "y": 363, + "x": 32, + "y": 31, "w": 16, "h": 16 } @@ -8319,8 +1179,8 @@ "h": 16 }, "frame": { - "x": 373, - "y": 379, + "x": 48, + "y": 31, "w": 16, "h": 16 } @@ -8340,8 +1200,8 @@ "h": 16 }, "frame": { - "x": 389, - "y": 363, + "x": 64, + "y": 31, "w": 16, "h": 16 } @@ -8361,8 +1221,8 @@ "h": 16 }, "frame": { - "x": 389, - "y": 379, + "x": 80, + "y": 31, "w": 16, "h": 16 } @@ -8382,8 +1242,8 @@ "h": 16 }, "frame": { - "x": 405, - "y": 377, + "x": 96, + "y": 31, "w": 16, "h": 16 } @@ -8403,8 +1263,8 @@ "h": 16 }, "frame": { - "x": 361, - "y": 395, + "x": 112, + "y": 32, "w": 16, "h": 16 } @@ -8424,11 +1284,7172 @@ "h": 16 }, "frame": { - "x": 377, - "y": 395, + "x": 128, + "y": 32, "w": 16, "h": 16 } + }, + { + "filename": "black_glasses", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 144, + "y": 32, + "w": 23, + "h": 17 + } + }, + { + "filename": "burn_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 167, + "y": 32, + "w": 23, + "h": 17 + } + }, + { + "filename": "chill_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 190, + "y": 32, + "w": 23, + "h": 17 + } + }, + { + "filename": "douse_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 213, + "y": 32, + "w": 23, + "h": 17 + } + }, + { + "filename": "everstone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 17 + }, + "frame": { + "x": 236, + "y": 32, + "w": 20, + "h": 17 + } + }, + { + "filename": "shock_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 256, + "y": 32, + "w": 23, + "h": 17 + } + }, + { + "filename": "wise_glasses", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 279, + "y": 32, + "w": 23, + "h": 17 + } + }, + { + "filename": "baton", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 302, + "y": 32, + "w": 18, + "h": 18 + } + }, + { + "filename": "candy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 11, + "w": 18, + "h": 18 + }, + "frame": { + "x": 320, + "y": 32, + "w": 18, + "h": 18 + } + }, + { + "filename": "choice_specs", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 24, + "h": 18 + }, + "frame": { + "x": 338, + "y": 32, + "w": 24, + "h": 18 + } + }, + { + "filename": "dark_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 362, + "y": 32, + "w": 18, + "h": 18 + } + }, + { + "filename": "dragon_scale", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 24, + "h": 18 + }, + "frame": { + "x": 380, + "y": 32, + "w": 24, + "h": 18 + } + }, + { + "filename": "flame_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 404, + "y": 32, + "w": 18, + "h": 18 + } + }, + { + "filename": "mystery_egg", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 18 + }, + "frame": { + "x": 0, + "y": 46, + "w": 16, + "h": 18 + } + }, + { + "filename": "light_ball", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 16, + "y": 47, + "w": 18, + "h": 18 + } + }, + { + "filename": "light_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 34, + "y": 47, + "w": 18, + "h": 18 + } + }, + { + "filename": "masterpiece_teacup", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 21, + "h": 18 + }, + "frame": { + "x": 52, + "y": 47, + "w": 21, + "h": 18 + } + }, + { + "filename": "old_gateau", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 21, + "h": 18 + }, + "frame": { + "x": 73, + "y": 47, + "w": 21, + "h": 18 + } + }, + { + "filename": "toxic_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 94, + "y": 47, + "w": 18, + "h": 18 + } + }, + { + "filename": "relic_crown", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 18 + }, + "frame": { + "x": 112, + "y": 48, + "w": 23, + "h": 18 + } + }, + { + "filename": "sharp_meteorite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 21, + "h": 18 + }, + "frame": { + "x": 135, + "y": 49, + "w": 21, + "h": 18 + } + }, + { + "filename": "unremarkable_teacup", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 21, + "h": 18 + }, + "frame": { + "x": 156, + "y": 49, + "w": 21, + "h": 18 + } + }, + { + "filename": "wl_ability_urge", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 177, + "y": 49, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_antidote", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 197, + "y": 49, + "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": 217, + "y": 49, + "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": 237, + "y": 49, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_custom_spliced", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 257, + "y": 49, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_custom_thief", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 277, + "y": 49, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_elixir", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 297, + "y": 50, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_ether", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 317, + "y": 50, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_full_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 337, + "y": 50, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_full_restore", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 357, + "y": 50, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_guard_spec", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 377, + "y": 50, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_hyper_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 397, + "y": 50, + "w": 20, + "h": 18 + } + }, + { + "filename": "oval_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 19 + }, + "frame": { + "x": 417, + "y": 50, + "w": 18, + "h": 19 + } + }, + { + "filename": "wl_ice_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 0, + "y": 65, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_item_drop", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 20, + "y": 65, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_item_urge", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 40, + "y": 65, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_max_elixir", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 60, + "y": 65, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_max_ether", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 80, + "y": 65, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_max_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 100, + "y": 66, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_max_revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 120, + "y": 67, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_paralyze_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 140, + "y": 67, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 160, + "y": 67, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_reset_urge", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 180, + "y": 67, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 200, + "y": 67, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_super_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 220, + "y": 67, + "w": 20, + "h": 18 + } + }, + { + "filename": "big_mushroom", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 19 + }, + "frame": { + "x": 240, + "y": 67, + "w": 19, + "h": 19 + } + }, + { + "filename": "black_sludge", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 19 + }, + "frame": { + "x": 259, + "y": 67, + "w": 22, + "h": 19 + } + }, + { + "filename": "blunder_policy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 19 + }, + "frame": { + "x": 281, + "y": 68, + "w": 22, + "h": 19 + } + }, + { + "filename": "coupon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 303, + "y": 68, + "w": 23, + "h": 19 + } + }, + { + "filename": "dubious_disc", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 19 + }, + "frame": { + "x": 326, + "y": 68, + "w": 22, + "h": 19 + } + }, + { + "filename": "golden_mystic_ticket", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 348, + "y": 68, + "w": 23, + "h": 19 + } + }, + { + "filename": "lum_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 20, + "h": 19 + }, + "frame": { + "x": 371, + "y": 68, + "w": 20, + "h": 19 + } + }, + { + "filename": "metal_alloy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 21, + "h": 19 + }, + "frame": { + "x": 391, + "y": 68, + "w": 21, + "h": 19 + } + }, + { + "filename": "miracle_seed", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 19, + "h": 19 + }, + "frame": { + "x": 412, + "y": 69, + "w": 19, + "h": 19 + } + }, + { + "filename": "mystic_ticket", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 0, + "y": 83, + "w": 23, + "h": 19 + } + }, + { + "filename": "pair_of_tickets", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 23, + "y": 83, + "w": 23, + "h": 19 + } + }, + { + "filename": "power_herb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 20, + "h": 19 + }, + "frame": { + "x": 46, + "y": 83, + "w": 20, + "h": 19 + } + }, + { + "filename": "razor_claw", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 20, + "h": 19 + }, + "frame": { + "x": 66, + "y": 83, + "w": 20, + "h": 19 + } + }, + { + "filename": "upgrade", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 19 + }, + "frame": { + "x": 86, + "y": 84, + "w": 22, + "h": 19 + } + }, + { + "filename": "white_herb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 20, + "h": 19 + }, + "frame": { + "x": 108, + "y": 85, + "w": 20, + "h": 19 + } + }, + { + "filename": "apicot_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 20 + }, + "frame": { + "x": 128, + "y": 85, + "w": 19, + "h": 20 + } + }, + { + "filename": "big_nugget", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 147, + "y": 85, + "w": 20, + "h": 20 + } + }, + { + "filename": "binding_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 23, + "h": 20 + }, + "frame": { + "x": 167, + "y": 85, + "w": 23, + "h": 20 + } + }, + { + "filename": "blue_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 190, + "y": 85, + "w": 20, + "h": 20 + } + }, + { + "filename": "candy_jar", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 20 + }, + "frame": { + "x": 210, + "y": 85, + "w": 19, + "h": 20 + } + }, + { + "filename": "chipped_pot", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 3, + "y": 6, + "w": 26, + "h": 20 + }, + "frame": { + "x": 229, + "y": 86, + "w": 26, + "h": 20 + } + }, + { + "filename": "cracked_pot", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 3, + "y": 6, + "w": 26, + "h": 20 + }, + "frame": { + "x": 255, + "y": 86, + "w": 26, + "h": 20 + } + }, + { + "filename": "deep_sea_scale", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 20 + }, + "frame": { + "x": 281, + "y": 87, + "w": 22, + "h": 20 + } + }, + { + "filename": "fairy_feather", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 20 + }, + "frame": { + "x": 303, + "y": 87, + "w": 22, + "h": 20 + } + }, + { + "filename": "gb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 325, + "y": 87, + "w": 20, + "h": 20 + } + }, + { + "filename": "golden_egg", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 17, + "h": 20 + }, + "frame": { + "x": 345, + "y": 87, + "w": 17, + "h": 20 + } + }, + { + "filename": "hard_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 20 + }, + "frame": { + "x": 362, + "y": 87, + "w": 19, + "h": 20 + } + }, + { + "filename": "icy_reins_of_unity", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 24, + "h": 20 + }, + "frame": { + "x": 381, + "y": 87, + "w": 24, + "h": 20 + } + }, + { + "filename": "legend_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 3, + "y": 6, + "w": 25, + "h": 20 + }, + "frame": { + "x": 405, + "y": 88, + "w": 25, + "h": 20 + } + }, + { + "filename": "lucky_egg", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 17, + "h": 20 + }, + "frame": { + "x": 0, + "y": 102, + "w": 17, + "h": 20 + } + }, + { + "filename": "magnet", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 17, + "y": 102, + "w": 20, + "h": 20 + } + }, + { + "filename": "malicious_armor", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 20 + }, + "frame": { + "x": 37, + "y": 102, + "w": 22, + "h": 20 + } + }, + { + "filename": "mb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 59, + "y": 102, + "w": 20, + "h": 20 + } + }, + { + "filename": "metal_powder", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 24, + "h": 20 + }, + "frame": { + "x": 79, + "y": 103, + "w": 24, + "h": 20 + } + }, + { + "filename": "pb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 103, + "y": 104, + "w": 20, + "h": 20 + } + }, + { + "filename": "pb_gold", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 123, + "y": 105, + "w": 20, + "h": 20 + } + }, + { + "filename": "pb_silver", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 143, + "y": 105, + "w": 20, + "h": 20 + } + }, + { + "filename": "quick_powder", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 24, + "h": 20 + }, + "frame": { + "x": 163, + "y": 105, + "w": 24, + "h": 20 + } + }, + { + "filename": "razor_fang", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 18, + "h": 20 + }, + "frame": { + "x": 187, + "y": 105, + "w": 18, + "h": 20 + } + }, + { + "filename": "rb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 205, + "y": 105, + "w": 20, + "h": 20 + } + }, + { + "filename": "reviver_seed", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 8, + "w": 23, + "h": 20 + }, + "frame": { + "x": 225, + "y": 106, + "w": 23, + "h": 20 + } + }, + { + "filename": "rusted_shield", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 24, + "h": 20 + }, + "frame": { + "x": 248, + "y": 106, + "w": 24, + "h": 20 + } + }, + { + "filename": "sacred_ash", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 24, + "h": 20 + }, + "frame": { + "x": 272, + "y": 107, + "w": 24, + "h": 20 + } + }, + { + "filename": "shadow_reins_of_unity", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 24, + "h": 20 + }, + "frame": { + "x": 296, + "y": 107, + "w": 24, + "h": 20 + } + }, + { + "filename": "shell_bell", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 23, + "h": 20 + }, + "frame": { + "x": 320, + "y": 107, + "w": 23, + "h": 20 + } + }, + { + "filename": "smooth_meteorite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 343, + "y": 107, + "w": 20, + "h": 20 + } + }, + { + "filename": "soft_sand", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 24, + "h": 20 + }, + "frame": { + "x": 363, + "y": 107, + "w": 24, + "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": 387, + "y": 108, + "w": 20, + "h": 20 + } + }, + { + "filename": "tera_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 20 + }, + "frame": { + "x": 407, + "y": 108, + "w": 22, + "h": 20 + } + }, + { + "filename": "ub", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 0, + "y": 122, + "w": 20, + "h": 20 + } + }, + { + "filename": "adamant_crystal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 23, + "h": 21 + }, + "frame": { + "x": 20, + "y": 122, + "w": 23, + "h": 21 + } + }, + { + "filename": "amulet_coin", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 43, + "y": 122, + "w": 23, + "h": 21 + } + }, + { + "filename": "auspicious_armor", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 66, + "y": 123, + "w": 23, + "h": 21 + } + }, + { + "filename": "berry_juice", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 21 + }, + "frame": { + "x": 89, + "y": 124, + "w": 22, + "h": 21 + } + }, + { + "filename": "dawn_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 21 + }, + "frame": { + "x": 111, + "y": 125, + "w": 20, + "h": 21 + } + }, + { + "filename": "deep_sea_tooth", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 131, + "y": 125, + "w": 22, + "h": 21 + } + }, + { + "filename": "dusk_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 153, + "y": 125, + "w": 21, + "h": 21 + } + }, + { + "filename": "flying_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 20, + "h": 21 + }, + "frame": { + "x": 174, + "y": 125, + "w": 20, + "h": 21 + } + }, + { + "filename": "golden_net", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 21 + }, + "frame": { + "x": 194, + "y": 125, + "w": 24, + "h": 21 + } + }, + { + "filename": "liechi_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 218, + "y": 126, + "w": 22, + "h": 21 + } + }, + { + "filename": "mint_atk", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 28, + "h": 21 + }, + "frame": { + "x": 240, + "y": 126, + "w": 28, + "h": 21 + } + }, + { + "filename": "mint_def", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 28, + "h": 21 + }, + "frame": { + "x": 268, + "y": 127, + "w": 28, + "h": 21 + } + }, + { + "filename": "mint_neutral", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 28, + "h": 21 + }, + "frame": { + "x": 296, + "y": 127, + "w": 28, + "h": 21 + } + }, + { + "filename": "mint_spatk", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 28, + "h": 21 + }, + "frame": { + "x": 324, + "y": 127, + "w": 28, + "h": 21 + } + }, + { + "filename": "mint_spd", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 28, + "h": 21 + }, + "frame": { + "x": 352, + "y": 127, + "w": 28, + "h": 21 + } + }, + { + "filename": "mint_spdef", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 5, + "w": 28, + "h": 21 + }, + "frame": { + "x": 380, + "y": 128, + "w": 28, + "h": 21 + } + }, + { + "filename": "moon_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 23, + "h": 21 + }, + "frame": { + "x": 408, + "y": 128, + "w": 23, + "h": 21 + } + }, + { + "filename": "quick_claw", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 21 + }, + "frame": { + "x": 0, + "y": 142, + "w": 19, + "h": 21 + } + }, + { + "filename": "n_lunarizer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 23, + "h": 21 + }, + "frame": { + "x": 19, + "y": 143, + "w": 23, + "h": 21 + } + }, + { + "filename": "n_solarizer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 23, + "h": 21 + }, + "frame": { + "x": 42, + "y": 143, + "w": 23, + "h": 21 + } + }, + { + "filename": "poison_barb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 65, + "y": 144, + "w": 21, + "h": 21 + } + }, + { + "filename": "shiny_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 86, + "y": 145, + "w": 21, + "h": 21 + } + }, + { + "filename": "spell_tag", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 19, + "h": 21 + }, + "frame": { + "x": 107, + "y": 146, + "w": 19, + "h": 21 + } + }, + { + "filename": "sweet_apple", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 126, + "y": 146, + "w": 22, + "h": 21 + } + }, + { + "filename": "syrupy_apple", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 148, + "y": 146, + "w": 22, + "h": 21 + } + }, + { + "filename": "tart_apple", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 170, + "y": 146, + "w": 22, + "h": 21 + } + }, + { + "filename": "wellspring_mask", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 192, + "y": 146, + "w": 23, + "h": 21 + } + }, + { + "filename": "zoom_lens", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 215, + "y": 147, + "w": 21, + "h": 21 + } + }, + { + "filename": "berry_pot", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 18, + "h": 22 + }, + "frame": { + "x": 236, + "y": 147, + "w": 18, + "h": 22 + } + }, + { + "filename": "bug_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 254, + "y": 148, + "w": 22, + "h": 22 + } + }, + { + "filename": "charcoal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 276, + "y": 148, + "w": 22, + "h": 22 + } + }, + { + "filename": "dark_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 298, + "y": 148, + "w": 22, + "h": 22 + } + }, + { + "filename": "dire_hit", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 320, + "y": 148, + "w": 22, + "h": 22 + } + }, + { + "filename": "dna_splicers", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 342, + "y": 148, + "w": 22, + "h": 22 + } + }, + { + "filename": "leftovers", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 15, + "h": 22 + }, + "frame": { + "x": 364, + "y": 148, + "w": 15, + "h": 22 + } + }, + { + "filename": "dragon_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 379, + "y": 149, + "w": 22, + "h": 22 + } + }, + { + "filename": "electirizer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 401, + "y": 149, + "w": 22, + "h": 22 + } + }, + { + "filename": "lock_capsule", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 19, + "h": 22 + }, + "frame": { + "x": 0, + "y": 163, + "w": 19, + "h": 22 + } + }, + { + "filename": "electric_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 19, + "y": 164, + "w": 22, + "h": 22 + } + }, + { + "filename": "enigma_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 41, + "y": 164, + "w": 22, + "h": 22 + } + }, + { + "filename": "fairy_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 63, + "y": 165, + "w": 22, + "h": 22 + } + }, + { + "filename": "fighting_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 85, + "y": 166, + "w": 22, + "h": 22 + } + }, + { + "filename": "exp_balance", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 22 + }, + "frame": { + "x": 107, + "y": 167, + "w": 24, + "h": 22 + } + }, + { + "filename": "exp_share", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 22 + }, + "frame": { + "x": 131, + "y": 167, + "w": 24, + "h": 22 + } + }, + { + "filename": "fire_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 155, + "y": 167, + "w": 22, + "h": 22 + } + }, + { + "filename": "flying_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 177, + "y": 167, + "w": 22, + "h": 22 + } + }, + { + "filename": "full_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 15, + "h": 23 + }, + "frame": { + "x": 199, + "y": 167, + "w": 15, + "h": 23 + } + }, + { + "filename": "ganlon_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 214, + "y": 168, + "w": 22, + "h": 22 + } + }, + { + "filename": "metronome", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 236, + "y": 169, + "w": 17, + "h": 22 + } + }, + { + "filename": "ghost_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 253, + "y": 170, + "w": 22, + "h": 22 + } + }, + { + "filename": "grass_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 275, + "y": 170, + "w": 22, + "h": 22 + } + }, + { + "filename": "ground_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 297, + "y": 170, + "w": 22, + "h": 22 + } + }, + { + "filename": "guard_spec", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 319, + "y": 170, + "w": 22, + "h": 22 + } + }, + { + "filename": "hard_meteorite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 20, + "h": 22 + }, + "frame": { + "x": 341, + "y": 170, + "w": 20, + "h": 22 + } + }, + { + "filename": "soothe_bell", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 361, + "y": 170, + "w": 17, + "h": 22 + } + }, + { + "filename": "healing_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 23, + "h": 22 + }, + "frame": { + "x": 378, + "y": 171, + "w": 23, + "h": 22 + } + }, + { + "filename": "ice_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 401, + "y": 171, + "w": 22, + "h": 22 + } + }, + { + "filename": "metal_coat", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 19, + "h": 22 + }, + "frame": { + "x": 0, + "y": 185, + "w": 19, + "h": 22 + } + }, + { + "filename": "ice_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 19, + "y": 186, + "w": 22, + "h": 22 + } + }, + { + "filename": "magmarizer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 41, + "y": 186, + "w": 22, + "h": 22 + } + }, + { + "filename": "mini_black_hole", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 63, + "y": 187, + "w": 22, + "h": 22 + } + }, + { + "filename": "moon_flute", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 85, + "y": 188, + "w": 22, + "h": 22 + } + }, + { + "filename": "map", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 3, + "y": 5, + "w": 27, + "h": 22 + }, + "frame": { + "x": 107, + "y": 189, + "w": 27, + "h": 22 + } + }, + { + "filename": "normal_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 134, + "y": 189, + "w": 22, + "h": 22 + } + }, + { + "filename": "peat_block", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 22 + }, + "frame": { + "x": 156, + "y": 189, + "w": 24, + "h": 22 + } + }, + { + "filename": "hyper_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 180, + "y": 189, + "w": 17, + "h": 23 + } + }, + { + "filename": "poison_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 197, + "y": 190, + "w": 22, + "h": 22 + } + }, + { + "filename": "potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 219, + "y": 190, + "w": 17, + "h": 23 + } + }, + { + "filename": "protector", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 236, + "y": 192, + "w": 22, + "h": 22 + } + }, + { + "filename": "psychic_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 258, + "y": 192, + "w": 22, + "h": 22 + } + }, + { + "filename": "rock_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 280, + "y": 192, + "w": 22, + "h": 22 + } + }, + { + "filename": "rusted_sword", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 22 + }, + "frame": { + "x": 302, + "y": 192, + "w": 23, + "h": 22 + } + }, + { + "filename": "scroll_of_darkness", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 325, + "y": 192, + "w": 22, + "h": 22 + } + }, + { + "filename": "scroll_of_waters", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 347, + "y": 192, + "w": 22, + "h": 22 + } + }, + { + "filename": "shed_shell", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 369, + "y": 193, + "w": 22, + "h": 22 + } + }, + { + "filename": "sitrus_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 20, + "h": 22 + }, + "frame": { + "x": 391, + "y": 193, + "w": 20, + "h": 22 + } + }, + { + "filename": "starf_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 411, + "y": 193, + "w": 22, + "h": 22 + } + }, + { + "filename": "sachet", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 18, + "h": 23 + }, + "frame": { + "x": 0, + "y": 207, + "w": 18, + "h": 23 + } + }, + { + "filename": "steel_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 18, + "y": 208, + "w": 22, + "h": 22 + } + }, + { + "filename": "sun_flute", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 40, + "y": 208, + "w": 22, + "h": 22 + } + }, + { + "filename": "thick_club", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 62, + "y": 209, + "w": 22, + "h": 22 + } + }, + { + "filename": "thunder_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 84, + "y": 210, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_bug", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 106, + "y": 211, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_dark", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 128, + "y": 211, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_dragon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 150, + "y": 211, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_electric", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 172, + "y": 212, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_fairy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 194, + "y": 212, + "w": 22, + "h": 22 + } + }, + { + "filename": "mystic_water", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 20, + "h": 23 + }, + "frame": { + "x": 216, + "y": 213, + "w": 20, + "h": 23 + } + }, + { + "filename": "tm_fighting", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 236, + "y": 214, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_fire", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 258, + "y": 214, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_flying", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 280, + "y": 214, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_ghost", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 302, + "y": 214, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_grass", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 324, + "y": 214, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_ground", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 346, + "y": 214, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_ice", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 368, + "y": 215, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_normal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 390, + "y": 215, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_poison", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 412, + "y": 215, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_psychic", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 0, + "y": 230, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_rock", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 22, + "y": 230, + "w": 22, + "h": 22 + } + }, + { + "filename": "super_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 44, + "y": 230, + "w": 17, + "h": 23 + } + }, + { + "filename": "tm_steel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 61, + "y": 231, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_water", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 83, + "y": 232, + "w": 22, + "h": 22 + } + }, + { + "filename": "water_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 105, + "y": 233, + "w": 22, + "h": 22 + } + }, + { + "filename": "water_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 127, + "y": 233, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_accuracy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 149, + "y": 233, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_attack", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 171, + "y": 234, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_defense", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 193, + "y": 234, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_sp_atk", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 215, + "y": 236, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_sp_def", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 237, + "y": 236, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_speed", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 259, + "y": 236, + "w": 22, + "h": 22 + } + }, + { + "filename": "berry_pouch", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 281, + "y": 236, + "w": 23, + "h": 23 + } + }, + { + "filename": "black_belt", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 304, + "y": 236, + "w": 22, + "h": 23 + } + }, + { + "filename": "bug_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 326, + "y": 236, + "w": 22, + "h": 23 + } + }, + { + "filename": "calcium", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 348, + "y": 236, + "w": 16, + "h": 24 + } + }, + { + "filename": "clefairy_doll", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 364, + "y": 237, + "w": 24, + "h": 23 + } + }, + { + "filename": "coin_case", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 388, + "y": 237, + "w": 24, + "h": 23 + } + }, + { + "filename": "dark_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 412, + "y": 237, + "w": 22, + "h": 23 + } + }, + { + "filename": "dragon_fang", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 21, + "h": 23 + }, + "frame": { + "x": 0, + "y": 252, + "w": 21, + "h": 23 + } + }, + { + "filename": "dragon_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 21, + "y": 252, + "w": 22, + "h": 23 + } + }, + { + "filename": "dynamax_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 23, + "h": 23 + }, + "frame": { + "x": 43, + "y": 253, + "w": 23, + "h": 23 + } + }, + { + "filename": "carbos", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 66, + "y": 253, + "w": 16, + "h": 24 + } + }, + { + "filename": "electric_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 82, + "y": 254, + "w": 22, + "h": 23 + } + }, + { + "filename": "expert_belt", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 23 + }, + "frame": { + "x": 104, + "y": 255, + "w": 24, + "h": 23 + } + }, + { + "filename": "fairy_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 128, + "y": 255, + "w": 22, + "h": 23 + } + }, + { + "filename": "lansat_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 21, + "h": 23 + }, + "frame": { + "x": 150, + "y": 255, + "w": 21, + "h": 23 + } + }, + { + "filename": "fighting_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 171, + "y": 256, + "w": 22, + "h": 23 + } + }, + { + "filename": "fire_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 193, + "y": 256, + "w": 22, + "h": 23 + } + }, + { + "filename": "fire_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 215, + "y": 258, + "w": 22, + "h": 23 + } + }, + { + "filename": "focus_sash", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 237, + "y": 258, + "w": 22, + "h": 23 + } + }, + { + "filename": "ghost_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 259, + "y": 258, + "w": 22, + "h": 23 + } + }, + { + "filename": "grass_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 281, + "y": 259, + "w": 22, + "h": 23 + } + }, + { + "filename": "griseous_core", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 303, + "y": 259, + "w": 23, + "h": 23 + } + }, + { + "filename": "ground_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 326, + "y": 259, + "w": 22, + "h": 23 + } + }, + { + "filename": "hearthflame_mask", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 23 + }, + "frame": { + "x": 348, + "y": 260, + "w": 24, + "h": 23 + } + }, + { + "filename": "ice_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 372, + "y": 260, + "w": 22, + "h": 23 + } + }, + { + "filename": "leaf_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 21, + "h": 23 + }, + "frame": { + "x": 394, + "y": 260, + "w": 21, + "h": 23 + } + }, + { + "filename": "elixir", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 415, + "y": 260, + "w": 18, + "h": 24 + } + }, + { + "filename": "leek", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 0, + "y": 275, + "w": 23, + "h": 23 + } + }, + { + "filename": "ether", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 23, + "y": 275, + "w": 18, + "h": 24 + } + }, + { + "filename": "leppa_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 41, + "y": 276, + "w": 24, + "h": 23 + } + }, + { + "filename": "macho_brace", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 65, + "y": 277, + "w": 23, + "h": 23 + } + }, + { + "filename": "hp_up", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 88, + "y": 277, + "w": 16, + "h": 24 + } + }, + { + "filename": "never_melt_ice", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 104, + "y": 278, + "w": 22, + "h": 23 + } + }, + { + "filename": "normal_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 126, + "y": 278, + "w": 22, + "h": 23 + } + }, + { + "filename": "petaya_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 148, + "y": 278, + "w": 22, + "h": 23 + } + }, + { + "filename": "poison_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 170, + "y": 279, + "w": 22, + "h": 23 + } + }, + { + "filename": "psychic_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 192, + "y": 279, + "w": 22, + "h": 23 + } + }, + { + "filename": "rare_candy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 214, + "y": 281, + "w": 23, + "h": 23 + } + }, + { + "filename": "rarer_candy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 237, + "y": 281, + "w": 23, + "h": 23 + } + }, + { + "filename": "sharp_beak", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 21, + "h": 23 + }, + "frame": { + "x": 260, + "y": 281, + "w": 21, + "h": 23 + } + }, + { + "filename": "reaper_cloth", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 281, + "y": 282, + "w": 22, + "h": 23 + } + }, + { + "filename": "rock_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 303, + "y": 282, + "w": 22, + "h": 23 + } + }, + { + "filename": "steel_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 325, + "y": 282, + "w": 22, + "h": 23 + } + }, + { + "filename": "scope_lens", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 347, + "y": 283, + "w": 24, + "h": 23 + } + }, + { + "filename": "stellar_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 371, + "y": 283, + "w": 22, + "h": 23 + } + }, + { + "filename": "water_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 393, + "y": 283, + "w": 22, + "h": 23 + } + }, + { + "filename": "full_restore", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 415, + "y": 284, + "w": 18, + "h": 24 + } + }, + { + "filename": "whipped_dream", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 21, + "h": 23 + }, + "frame": { + "x": 0, + "y": 298, + "w": 21, + "h": 23 + } + }, + { + "filename": "twisted_spoon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 21, + "y": 299, + "w": 24, + "h": 23 + } + }, + { + "filename": "iron", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 45, + "y": 299, + "w": 16, + "h": 24 + } + }, + { + "filename": "wide_lens", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 61, + "y": 300, + "w": 22, + "h": 23 + } + }, + { + "filename": "big_root", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 83, + "y": 301, + "w": 23, + "h": 24 + } + }, + { + "filename": "blank_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 106, + "y": 301, + "w": 24, + "h": 24 + } + }, + { + "filename": "catching_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 130, + "y": 301, + "w": 21, + "h": 24 + } + }, + { + "filename": "lure", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 17, + "h": 24 + }, + "frame": { + "x": 151, + "y": 301, + "w": 17, + "h": 24 + } + }, + { + "filename": "choice_scarf", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 168, + "y": 302, + "w": 24, + "h": 24 + } + }, + { + "filename": "max_elixir", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 192, + "y": 302, + "w": 18, + "h": 24 + } + }, + { + "filename": "draco_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 210, + "y": 304, + "w": 24, + "h": 24 + } + }, + { + "filename": "dread_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 234, + "y": 304, + "w": 24, + "h": 24 + } + }, + { + "filename": "kings_rock", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 258, + "y": 304, + "w": 23, + "h": 24 + } + }, + { + "filename": "earth_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 281, + "y": 305, + "w": 24, + "h": 24 + } + }, + { + "filename": "fist_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 305, + "y": 305, + "w": 24, + "h": 24 + } + }, + { + "filename": "max_ether", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 329, + "y": 305, + "w": 18, + "h": 24 + } + }, + { + "filename": "flame_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 347, + "y": 306, + "w": 24, + "h": 24 + } + }, + { + "filename": "focus_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 371, + "y": 306, + "w": 24, + "h": 24 + } + }, + { + "filename": "max_lure", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 17, + "h": 24 + }, + "frame": { + "x": 395, + "y": 306, + "w": 17, + "h": 24 + } + }, + { + "filename": "max_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 412, + "y": 308, + "w": 18, + "h": 24 + } + }, + { + "filename": "max_repel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 0, + "y": 321, + "w": 16, + "h": 24 + } + }, + { + "filename": "golden_punch", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 16, + "y": 322, + "w": 24, + "h": 24 + } + }, + { + "filename": "gracidea", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 40, + "y": 323, + "w": 24, + "h": 24 + } + }, + { + "filename": "pp_max", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 64, + "y": 323, + "w": 16, + "h": 24 + } + }, + { + "filename": "grip_claw", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 80, + "y": 325, + "w": 24, + "h": 24 + } + }, + { + "filename": "icicle_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 104, + "y": 325, + "w": 24, + "h": 24 + } + }, + { + "filename": "insect_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 128, + "y": 325, + "w": 24, + "h": 24 + } + }, + { + "filename": "pp_up", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 152, + "y": 325, + "w": 16, + "h": 24 + } + }, + { + "filename": "iron_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 168, + "y": 326, + "w": 24, + "h": 24 + } + }, + { + "filename": "protein", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 192, + "y": 326, + "w": 16, + "h": 24 + } + }, + { + "filename": "lucky_punch", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 208, + "y": 328, + "w": 24, + "h": 24 + } + }, + { + "filename": "lucky_punch_great", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 232, + "y": 328, + "w": 24, + "h": 24 + } + }, + { + "filename": "lucky_punch_master", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 256, + "y": 328, + "w": 24, + "h": 24 + } + }, + { + "filename": "lucky_punch_ultra", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 280, + "y": 329, + "w": 24, + "h": 24 + } + }, + { + "filename": "lustrous_globe", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 304, + "y": 329, + "w": 24, + "h": 24 + } + }, + { + "filename": "repel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 328, + "y": 329, + "w": 16, + "h": 24 + } + }, + { + "filename": "max_revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 24 + }, + "frame": { + "x": 344, + "y": 330, + "w": 22, + "h": 24 + } + }, + { + "filename": "meadow_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 366, + "y": 330, + "w": 24, + "h": 24 + } + }, + { + "filename": "oval_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 390, + "y": 330, + "w": 21, + "h": 24 + } + }, + { + "filename": "mind_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 411, + "y": 332, + "w": 24, + "h": 24 + } + }, + { + "filename": "super_repel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 0, + "y": 345, + "w": 16, + "h": 24 + } + }, + { + "filename": "muscle_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 16, + "y": 346, + "w": 24, + "h": 24 + } + }, + { + "filename": "pixie_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 40, + "y": 347, + "w": 24, + "h": 24 + } + }, + { + "filename": "unknown", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 64, + "y": 347, + "w": 16, + "h": 24 + } + }, + { + "filename": "red_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 20, + "h": 24 + }, + "frame": { + "x": 80, + "y": 349, + "w": 20, + "h": 24 + } + }, + { + "filename": "reveal_glass", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 100, + "y": 349, + "w": 23, + "h": 24 + } + }, + { + "filename": "salac_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 123, + "y": 349, + "w": 24, + "h": 24 + } + }, + { + "filename": "shiny_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 147, + "y": 349, + "w": 21, + "h": 24 + } + }, + { + "filename": "scanner", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 168, + "y": 350, + "w": 24, + "h": 24 + } + }, + { + "filename": "zinc", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 192, + "y": 350, + "w": 16, + "h": 24 + } + }, + { + "filename": "silk_scarf", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 208, + "y": 352, + "w": 24, + "h": 24 + } + }, + { + "filename": "sky_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 232, + "y": 352, + "w": 24, + "h": 24 + } + }, + { + "filename": "splash_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 256, + "y": 352, + "w": 24, + "h": 24 + } + }, + { + "filename": "spooky_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 280, + "y": 353, + "w": 24, + "h": 24 + } + }, + { + "filename": "stone_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 304, + "y": 353, + "w": 24, + "h": 24 + } + }, + { + "filename": "sun_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 328, + "y": 354, + "w": 24, + "h": 24 + } + }, + { + "filename": "super_lure", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 17, + "h": 24 + }, + "frame": { + "x": 352, + "y": 354, + "w": 17, + "h": 24 + } + }, + { + "filename": "toxic_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 369, + "y": 354, + "w": 24, + "h": 24 + } + }, + { + "filename": "zap_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 393, + "y": 356, + "w": 24, + "h": 24 + } + }, + { + "filename": "prison_bottle", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 1, + "w": 17, + "h": 30 + }, + "frame": { + "x": 417, + "y": 356, + "w": 17, + "h": 30 + } + }, + { + "filename": "black_augurite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 3, + "w": 22, + "h": 25 + }, + "frame": { + "x": 0, + "y": 370, + "w": 22, + "h": 25 + } + }, + { + "filename": "ability_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 23, + "h": 26 + }, + "frame": { + "x": 22, + "y": 371, + "w": 23, + "h": 26 + } + }, + { + "filename": "cornerstone_mask", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 3, + "w": 24, + "h": 26 + }, + "frame": { + "x": 45, + "y": 371, + "w": 24, + "h": 26 + } + }, + { + "filename": "linking_cord", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 3, + "y": 3, + "w": 27, + "h": 26 + }, + "frame": { + "x": 69, + "y": 373, + "w": 27, + "h": 26 + } + }, + { + "filename": "mystical_rock", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 28, + "h": 26 + }, + "frame": { + "x": 96, + "y": 373, + "w": 28, + "h": 26 + } + }, + { + "filename": "galarica_wreath", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 0, + "y": 3, + "w": 32, + "h": 27 + }, + "frame": { + "x": 124, + "y": 373, + "w": 32, + "h": 27 + } + }, + { + "filename": "leaders_crest", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 29, + "h": 27 + }, + "frame": { + "x": 156, + "y": 374, + "w": 29, + "h": 27 + } + }, + { + "filename": "ribbon_gen1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 2, + "w": 22, + "h": 28 + }, + "frame": { + "x": 185, + "y": 374, + "w": 22, + "h": 28 + } + }, + { + "filename": "max_mushrooms", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 1, + "y": 3, + "w": 29, + "h": 28 + }, + "frame": { + "x": 207, + "y": 376, + "w": 29, + "h": 28 + } + }, + { + "filename": "ribbon_gen2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 2, + "y": 2, + "w": 28, + "h": 28 + }, + "frame": { + "x": 236, + "y": 376, + "w": 28, + "h": 28 + } + }, + { + "filename": "ribbon_gen4", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 1, + "y": 2, + "w": 30, + "h": 28 + }, + "frame": { + "x": 264, + "y": 377, + "w": 30, + "h": 28 + } + }, + { + "filename": "ribbon_gen5", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 2, + "w": 22, + "h": 28 + }, + "frame": { + "x": 294, + "y": 377, + "w": 22, + "h": 28 + } + }, + { + "filename": "ribbon_gen6", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 2, + "w": 22, + "h": 28 + }, + "frame": { + "x": 316, + "y": 378, + "w": 22, + "h": 28 + } + }, + { + "filename": "ribbon_gen8", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 2, + "w": 22, + "h": 28 + }, + "frame": { + "x": 338, + "y": 378, + "w": 22, + "h": 28 + } + }, + { + "filename": "ribbon_gen3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 29 + }, + "frame": { + "x": 360, + "y": 378, + "w": 22, + "h": 29 + } + }, + { + "filename": "ribbon_gen7", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 29 + }, + "frame": { + "x": 382, + "y": 380, + "w": 22, + "h": 29 + } + }, + { + "filename": "ribbon_gen9", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 29 + }, + "frame": { + "x": 404, + "y": 386, + "w": 22, + "h": 29 + } + }, + { + "filename": "inverse", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 30 + }, + "frame": { + "x": 0, + "y": 395, + "w": 22, + "h": 30 + } + }, + { + "filename": "galarica_cuff", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 29, + "h": 30 + }, + "frame": { + "x": 22, + "y": 397, + "w": 29, + "h": 30 + } + }, + { + "filename": "exp_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 1, + "w": 17, + "h": 31 + }, + "frame": { + "x": 51, + "y": 397, + "w": 17, + "h": 31 + } + }, + { + "filename": "bronze_ribbon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 31 + }, + "frame": { + "x": 68, + "y": 399, + "w": 22, + "h": 31 + } + }, + { + "filename": "golden_exp_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 1, + "w": 17, + "h": 31 + }, + "frame": { + "x": 90, + "y": 399, + "w": 17, + "h": 31 + } + }, + { + "filename": "super_exp_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 1, + "w": 17, + "h": 31 + }, + "frame": { + "x": 107, + "y": 399, + "w": 17, + "h": 31 + } + }, + { + "filename": "great_ribbon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 31 + }, + "frame": { + "x": 124, + "y": 400, + "w": 22, + "h": 31 + } + }, + { + "filename": "master_ribbon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 31 + }, + "frame": { + "x": 146, + "y": 401, + "w": 22, + "h": 31 + } + }, + { + "filename": "rogue_ribbon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 31 + }, + "frame": { + "x": 168, + "y": 402, + "w": 22, + "h": 31 + } + }, + { + "filename": "ultra_ribbon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 1, + "w": 22, + "h": 31 + }, + "frame": { + "x": 190, + "y": 404, + "w": 22, + "h": 31 + } } ] } @@ -8436,6 +8457,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:d91a46c431ace3f09f5ca68916a2171e:1e84369d9a13e1416fa58028d629d116:110e074689c9edd2c54833ce2e4d9270$" + "smartupdate": "$TexturePacker:SmartUpdate:7b927dc715c6335dfca9e369b61374b2:fb24603dd37bbe0cbdf1d74fcbcbd223:110e074689c9edd2c54833ce2e4d9270$" } } diff --git a/public/images/items.png b/public/images/items.png index 191766f520e..4433ce43a40 100644 Binary files a/public/images/items.png and b/public/images/items.png differ diff --git a/public/images/items/ability_capsule.png b/public/images/items/ability_capsule.png index 06b6b3e173d..ee8aec6b346 100644 Binary files a/public/images/items/ability_capsule.png and b/public/images/items/ability_capsule.png differ diff --git a/public/images/items/ability_charm.png b/public/images/items/ability_charm.png index 943783ba348..2e9e0368667 100644 Binary files a/public/images/items/ability_charm.png and b/public/images/items/ability_charm.png differ diff --git a/public/images/items/abomasite.png b/public/images/items/abomasite.png index 09177d97a44..0758786bb0f 100644 Binary files a/public/images/items/abomasite.png and b/public/images/items/abomasite.png differ diff --git a/public/images/items/absolite.png b/public/images/items/absolite.png index 617969f6037..f7fe8b7ac12 100644 Binary files a/public/images/items/absolite.png and b/public/images/items/absolite.png differ diff --git a/public/images/items/adamant_crystal.png b/public/images/items/adamant_crystal.png index d729c40ce25..eb35af1540e 100644 Binary files a/public/images/items/adamant_crystal.png and b/public/images/items/adamant_crystal.png differ diff --git a/public/images/items/aerodactylite.png b/public/images/items/aerodactylite.png index 1cf5e028d6f..4feb04f3702 100644 Binary files a/public/images/items/aerodactylite.png and b/public/images/items/aerodactylite.png differ diff --git a/public/images/items/aggronite.png b/public/images/items/aggronite.png index 18eb9d86270..8feb64633ec 100644 Binary files a/public/images/items/aggronite.png and b/public/images/items/aggronite.png differ diff --git a/public/images/items/alakazite.png b/public/images/items/alakazite.png index 02d8ff580f4..ed6acab02ca 100644 Binary files a/public/images/items/alakazite.png and b/public/images/items/alakazite.png differ diff --git a/public/images/items/altarianite.png b/public/images/items/altarianite.png index 8d2436bc24a..0bb6be23819 100644 Binary files a/public/images/items/altarianite.png and b/public/images/items/altarianite.png differ diff --git a/public/images/items/ampharosite.png b/public/images/items/ampharosite.png index 5ff26217d23..3084c05c1a9 100644 Binary files a/public/images/items/ampharosite.png and b/public/images/items/ampharosite.png differ diff --git a/public/images/items/amulet_coin.png b/public/images/items/amulet_coin.png index 88ce369def5..3cda2b2a53b 100644 Binary files a/public/images/items/amulet_coin.png and b/public/images/items/amulet_coin.png differ diff --git a/public/images/items/apicot_berry.png b/public/images/items/apicot_berry.png index 2cfa66acdfa..4719671eaf3 100644 Binary files a/public/images/items/apicot_berry.png and b/public/images/items/apicot_berry.png differ diff --git a/public/images/items/audinite.png b/public/images/items/audinite.png index 51fdc9310b0..f7c21bf8e3b 100644 Binary files a/public/images/items/audinite.png and b/public/images/items/audinite.png differ diff --git a/public/images/items/auspicious_armor.png b/public/images/items/auspicious_armor.png index e3620bb6054..27c40ae0bd0 100644 Binary files a/public/images/items/auspicious_armor.png and b/public/images/items/auspicious_armor.png differ diff --git a/public/images/items/banettite.png b/public/images/items/banettite.png index 20704d624c2..b6bcadd72fc 100644 Binary files a/public/images/items/banettite.png and b/public/images/items/banettite.png differ diff --git a/public/images/items/baton.png b/public/images/items/baton.png index 8e9ebfae06d..ece81f82b2f 100644 Binary files a/public/images/items/baton.png and b/public/images/items/baton.png differ diff --git a/public/images/items/beedrillite.png b/public/images/items/beedrillite.png index 3dd1444bf76..99e516446d7 100644 Binary files a/public/images/items/beedrillite.png and b/public/images/items/beedrillite.png differ diff --git a/public/images/items/berry_juice.png b/public/images/items/berry_juice.png index 127fa458906..2f6272eca7c 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/berry_pot.png b/public/images/items/berry_pot.png index 5841ef1c324..3cb9b90dc53 100644 Binary files a/public/images/items/berry_pot.png and b/public/images/items/berry_pot.png differ diff --git a/public/images/items/berry_pouch.png b/public/images/items/berry_pouch.png index 878ef600239..d14d71358a9 100644 Binary files a/public/images/items/berry_pouch.png and b/public/images/items/berry_pouch.png differ diff --git a/public/images/items/big_mushroom.png b/public/images/items/big_mushroom.png index 4384c7933b3..eb203a7374c 100644 Binary files a/public/images/items/big_mushroom.png and b/public/images/items/big_mushroom.png differ diff --git a/public/images/items/big_nugget.png b/public/images/items/big_nugget.png index 54a5456ad60..e8839daa0b6 100644 Binary files a/public/images/items/big_nugget.png and b/public/images/items/big_nugget.png differ diff --git a/public/images/items/big_root.png b/public/images/items/big_root.png index 37eeb5c2f93..24b863ee238 100644 Binary files a/public/images/items/big_root.png and b/public/images/items/big_root.png differ diff --git a/public/images/items/binding_band.png b/public/images/items/binding_band.png index f634b02053d..b33256b7b8c 100644 Binary files a/public/images/items/binding_band.png and b/public/images/items/binding_band.png differ diff --git a/public/images/items/black_augurite.png b/public/images/items/black_augurite.png index e8531a1a8cf..b34127e2942 100644 Binary files a/public/images/items/black_augurite.png and b/public/images/items/black_augurite.png differ diff --git a/public/images/items/black_belt.png b/public/images/items/black_belt.png index 70d13097882..9dde3ff83cd 100644 Binary files a/public/images/items/black_belt.png and b/public/images/items/black_belt.png differ diff --git a/public/images/items/black_glasses.png b/public/images/items/black_glasses.png index 52fe0e60a1e..4b18d828964 100644 Binary files a/public/images/items/black_glasses.png and b/public/images/items/black_glasses.png differ diff --git a/public/images/items/black_sludge.png b/public/images/items/black_sludge.png index 37aa31de43e..fe308586dd3 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/blank_plate.png b/public/images/items/blank_plate.png index ec82203340c..c08d25aa3c3 100644 Binary files a/public/images/items/blank_plate.png and b/public/images/items/blank_plate.png differ diff --git a/public/images/items/blastoisinite.png b/public/images/items/blastoisinite.png index 6b8310610e8..ea2ddef0640 100644 Binary files a/public/images/items/blastoisinite.png and b/public/images/items/blastoisinite.png differ diff --git a/public/images/items/blazikenite.png b/public/images/items/blazikenite.png index f14b108de60..9b6e9e59212 100644 Binary files a/public/images/items/blazikenite.png and b/public/images/items/blazikenite.png differ diff --git a/public/images/items/blue_orb.png b/public/images/items/blue_orb.png index 91094d82147..34c19c8aea8 100644 Binary files a/public/images/items/blue_orb.png and b/public/images/items/blue_orb.png differ diff --git a/public/images/items/blunder_policy.png b/public/images/items/blunder_policy.png index c1e2e380648..8d5b11cb3f6 100644 Binary files a/public/images/items/blunder_policy.png and b/public/images/items/blunder_policy.png differ diff --git a/public/images/items/bronze_ribbon.png b/public/images/items/bronze_ribbon.png index eb9b926c50c..cab218e09f5 100644 Binary files a/public/images/items/bronze_ribbon.png and b/public/images/items/bronze_ribbon.png differ diff --git a/public/images/items/bug_memory.png b/public/images/items/bug_memory.png index e166636c780..004b499ba7a 100644 Binary files a/public/images/items/bug_memory.png and b/public/images/items/bug_memory.png differ diff --git a/public/images/items/bug_tera_shard.png b/public/images/items/bug_tera_shard.png index c08a3f29ffd..5711fe193bd 100644 Binary files a/public/images/items/bug_tera_shard.png and b/public/images/items/bug_tera_shard.png differ diff --git a/public/images/items/burn_drive.png b/public/images/items/burn_drive.png index 47ad9cc8f38..02ee18c02bd 100644 Binary files a/public/images/items/burn_drive.png and b/public/images/items/burn_drive.png differ diff --git a/public/images/items/calcium.png b/public/images/items/calcium.png index e98416f6280..4c42228d724 100644 Binary files a/public/images/items/calcium.png and b/public/images/items/calcium.png differ diff --git a/public/images/items/cameruptite.png b/public/images/items/cameruptite.png index 5410fc85a39..9eda37e14e1 100644 Binary files a/public/images/items/cameruptite.png and b/public/images/items/cameruptite.png differ diff --git a/public/images/items/candy.png b/public/images/items/candy.png index 9a68bdab606..81cf5e19ee2 100644 Binary files a/public/images/items/candy.png and b/public/images/items/candy.png differ diff --git a/public/images/items/candy_jar.png b/public/images/items/candy_jar.png index 2718b9fa083..0338b64a86d 100644 Binary files a/public/images/items/candy_jar.png and b/public/images/items/candy_jar.png differ diff --git a/public/images/items/candy_overlay.png b/public/images/items/candy_overlay.png index 67df546a633..a1cb428cdee 100644 Binary files a/public/images/items/candy_overlay.png and b/public/images/items/candy_overlay.png differ diff --git a/public/images/items/carbos.png b/public/images/items/carbos.png index beb31dcea9e..7dd09f2ec12 100644 Binary files a/public/images/items/carbos.png and b/public/images/items/carbos.png differ diff --git a/public/images/items/catching_charm.png b/public/images/items/catching_charm.png index c220ff70c03..57545622131 100644 Binary files a/public/images/items/catching_charm.png and b/public/images/items/catching_charm.png differ diff --git a/public/images/items/charcoal.png b/public/images/items/charcoal.png index 4d2511773ef..e10f8f20fd6 100644 Binary files a/public/images/items/charcoal.png and b/public/images/items/charcoal.png differ diff --git a/public/images/items/charizardite_x.png b/public/images/items/charizardite_x.png index 81590bb86da..d238a77a9e2 100644 Binary files a/public/images/items/charizardite_x.png and b/public/images/items/charizardite_x.png differ diff --git a/public/images/items/charizardite_y.png b/public/images/items/charizardite_y.png index 784eed51ace..5a3ea59d091 100644 Binary files a/public/images/items/charizardite_y.png and b/public/images/items/charizardite_y.png differ diff --git a/public/images/items/chill_drive.png b/public/images/items/chill_drive.png index d5ef99b1686..fbf7462479a 100644 Binary files a/public/images/items/chill_drive.png and b/public/images/items/chill_drive.png differ diff --git a/public/images/items/chipped_pot.png b/public/images/items/chipped_pot.png index a2f35f9aed9..969c3dc3c16 100644 Binary files a/public/images/items/chipped_pot.png and b/public/images/items/chipped_pot.png differ diff --git a/public/images/items/choice_scarf.png b/public/images/items/choice_scarf.png index a83fd1f4b30..2ddf7d3be16 100644 Binary files a/public/images/items/choice_scarf.png and b/public/images/items/choice_scarf.png differ diff --git a/public/images/items/choice_specs.png b/public/images/items/choice_specs.png index 513986c524e..09b58f64381 100644 Binary files a/public/images/items/choice_specs.png and b/public/images/items/choice_specs.png differ diff --git a/public/images/items/clefairy_doll.png b/public/images/items/clefairy_doll.png index 8e1691dddfa..3b54c83df47 100644 Binary files a/public/images/items/clefairy_doll.png and b/public/images/items/clefairy_doll.png differ diff --git a/public/images/items/coin_case.png b/public/images/items/coin_case.png index 14f9878e5c4..3c17c2b13f8 100644 Binary files a/public/images/items/coin_case.png and b/public/images/items/coin_case.png differ diff --git a/public/images/items/cornerstone_mask.png b/public/images/items/cornerstone_mask.png index 441af6607a5..205bdef9805 100644 Binary files a/public/images/items/cornerstone_mask.png and b/public/images/items/cornerstone_mask.png differ diff --git a/public/images/items/coupon.png b/public/images/items/coupon.png index b1e8089b485..b08fa65fecc 100644 Binary files a/public/images/items/coupon.png and b/public/images/items/coupon.png differ diff --git a/public/images/items/cracked_pot.png b/public/images/items/cracked_pot.png index 61cad0d85b7..4afc2caf2c8 100644 Binary files a/public/images/items/cracked_pot.png and b/public/images/items/cracked_pot.png differ diff --git a/public/images/items/dark_memory.png b/public/images/items/dark_memory.png index 4349ba8f8cd..e1e503bd036 100644 Binary files a/public/images/items/dark_memory.png and b/public/images/items/dark_memory.png differ diff --git a/public/images/items/dark_stone.png b/public/images/items/dark_stone.png index eb8eaa13ba8..c28a93ecabc 100644 Binary files a/public/images/items/dark_stone.png and b/public/images/items/dark_stone.png differ diff --git a/public/images/items/dark_tera_shard.png b/public/images/items/dark_tera_shard.png index 4060f9142f6..ca24664b74e 100644 Binary files a/public/images/items/dark_tera_shard.png and b/public/images/items/dark_tera_shard.png differ diff --git a/public/images/items/dawn_stone.png b/public/images/items/dawn_stone.png index 0e3da086649..b29d2016a56 100644 Binary files a/public/images/items/dawn_stone.png and b/public/images/items/dawn_stone.png differ diff --git a/public/images/items/deep_sea_scale.png b/public/images/items/deep_sea_scale.png index 6a84b01c99e..cf40e652319 100644 Binary files a/public/images/items/deep_sea_scale.png and b/public/images/items/deep_sea_scale.png differ diff --git a/public/images/items/deep_sea_tooth.png b/public/images/items/deep_sea_tooth.png index 448c8406867..2cd1980aeb4 100644 Binary files a/public/images/items/deep_sea_tooth.png and b/public/images/items/deep_sea_tooth.png differ diff --git a/public/images/items/diancite.png b/public/images/items/diancite.png index 6fff5008673..293d327524e 100644 Binary files a/public/images/items/diancite.png and b/public/images/items/diancite.png differ diff --git a/public/images/items/dire_hit.png b/public/images/items/dire_hit.png index 5917fd02d99..0c060710ff2 100644 Binary files a/public/images/items/dire_hit.png and b/public/images/items/dire_hit.png differ diff --git a/public/images/items/dna_splicers.png b/public/images/items/dna_splicers.png index 5a3c7fed75b..51c1524076e 100644 Binary files a/public/images/items/dna_splicers.png and b/public/images/items/dna_splicers.png differ diff --git a/public/images/items/douse_drive.png b/public/images/items/douse_drive.png index 0f9f780e5cb..fb8e7623184 100644 Binary files a/public/images/items/douse_drive.png and b/public/images/items/douse_drive.png differ diff --git a/public/images/items/draco_plate.png b/public/images/items/draco_plate.png index b25df530171..b4702aadba3 100644 Binary files a/public/images/items/draco_plate.png and b/public/images/items/draco_plate.png differ diff --git a/public/images/items/dragon_fang.png b/public/images/items/dragon_fang.png index 33659e50307..4a9904e0ef3 100644 Binary files a/public/images/items/dragon_fang.png and b/public/images/items/dragon_fang.png differ diff --git a/public/images/items/dragon_memory.png b/public/images/items/dragon_memory.png index 15a3cd170cd..01a14cadf3e 100644 Binary files a/public/images/items/dragon_memory.png and b/public/images/items/dragon_memory.png differ diff --git a/public/images/items/dragon_scale.png b/public/images/items/dragon_scale.png index bb8bb028db7..9cec39b22f6 100644 Binary files a/public/images/items/dragon_scale.png and b/public/images/items/dragon_scale.png differ diff --git a/public/images/items/dragon_tera_shard.png b/public/images/items/dragon_tera_shard.png index 8c16e2f8eb6..51f20d9f5cb 100644 Binary files a/public/images/items/dragon_tera_shard.png and b/public/images/items/dragon_tera_shard.png differ diff --git a/public/images/items/dread_plate.png b/public/images/items/dread_plate.png index 4cdbb76f180..6537320bc0a 100644 Binary files a/public/images/items/dread_plate.png and b/public/images/items/dread_plate.png differ diff --git a/public/images/items/dubious_disc.png b/public/images/items/dubious_disc.png index 8bb23497462..122958f9550 100644 Binary files a/public/images/items/dubious_disc.png and b/public/images/items/dubious_disc.png differ diff --git a/public/images/items/dusk_stone.png b/public/images/items/dusk_stone.png index 12ad19505d0..e2cf73d04f3 100644 Binary files a/public/images/items/dusk_stone.png and b/public/images/items/dusk_stone.png differ diff --git a/public/images/items/dynamax_band.png b/public/images/items/dynamax_band.png index 633da7bdc90..57b9a0caef5 100644 Binary files a/public/images/items/dynamax_band.png and b/public/images/items/dynamax_band.png differ diff --git a/public/images/items/earth_plate.png b/public/images/items/earth_plate.png index d40da06f6b6..79fbbad5a84 100644 Binary files a/public/images/items/earth_plate.png and b/public/images/items/earth_plate.png differ diff --git a/public/images/items/electirizer.png b/public/images/items/electirizer.png index 7d4488d0ff3..a5589a27e42 100644 Binary files a/public/images/items/electirizer.png and b/public/images/items/electirizer.png differ diff --git a/public/images/items/electric_memory.png b/public/images/items/electric_memory.png index 494b0d0d653..d0595356482 100644 Binary files a/public/images/items/electric_memory.png and b/public/images/items/electric_memory.png differ diff --git a/public/images/items/electric_tera_shard.png b/public/images/items/electric_tera_shard.png index e4e1003edbc..2195be32929 100644 Binary files a/public/images/items/electric_tera_shard.png and b/public/images/items/electric_tera_shard.png differ diff --git a/public/images/items/elixir.png b/public/images/items/elixir.png index 694b07f34b6..b4bf7834e17 100644 Binary files a/public/images/items/elixir.png and b/public/images/items/elixir.png differ diff --git a/public/images/items/enigma_berry.png b/public/images/items/enigma_berry.png index 26c7f11ee9c..1a1a20854ed 100644 Binary files a/public/images/items/enigma_berry.png and b/public/images/items/enigma_berry.png differ diff --git a/public/images/items/ether.png b/public/images/items/ether.png index 970c9a27778..44a6e79de8e 100644 Binary files a/public/images/items/ether.png and b/public/images/items/ether.png differ diff --git a/public/images/items/everstone.png b/public/images/items/everstone.png index 07b32e8850e..194f7b63baf 100644 Binary files a/public/images/items/everstone.png and b/public/images/items/everstone.png differ diff --git a/public/images/items/eviolite.png b/public/images/items/eviolite.png index 8eb195ece2a..8591791a5a1 100644 Binary files a/public/images/items/eviolite.png and b/public/images/items/eviolite.png differ diff --git a/public/images/items/exp_balance.png b/public/images/items/exp_balance.png index 56c645b70fc..6a03556a3a2 100644 Binary files a/public/images/items/exp_balance.png and b/public/images/items/exp_balance.png differ diff --git a/public/images/items/exp_charm.png b/public/images/items/exp_charm.png index b42da73301e..2635e4d8020 100644 Binary files a/public/images/items/exp_charm.png and b/public/images/items/exp_charm.png differ diff --git a/public/images/items/exp_share.png b/public/images/items/exp_share.png index d7f4e4d04fb..6b866c63427 100644 Binary files a/public/images/items/exp_share.png and b/public/images/items/exp_share.png differ diff --git a/public/images/items/expert_belt.png b/public/images/items/expert_belt.png index 225756626da..86cfd7170de 100644 Binary files a/public/images/items/expert_belt.png and b/public/images/items/expert_belt.png differ diff --git a/public/images/items/fairy_feather.png b/public/images/items/fairy_feather.png index 64cabec7500..44923a1db94 100644 Binary files a/public/images/items/fairy_feather.png and b/public/images/items/fairy_feather.png differ diff --git a/public/images/items/fairy_memory.png b/public/images/items/fairy_memory.png index 598f3c804ce..b5d0b32ff95 100644 Binary files a/public/images/items/fairy_memory.png and b/public/images/items/fairy_memory.png differ diff --git a/public/images/items/fairy_tera_shard.png b/public/images/items/fairy_tera_shard.png index 83e19aeaeba..36fb5e88f1c 100644 Binary files a/public/images/items/fairy_tera_shard.png and b/public/images/items/fairy_tera_shard.png differ diff --git a/public/images/items/fighting_memory.png b/public/images/items/fighting_memory.png index 3c152f43900..13789836880 100644 Binary files a/public/images/items/fighting_memory.png and b/public/images/items/fighting_memory.png differ diff --git a/public/images/items/fighting_tera_shard.png b/public/images/items/fighting_tera_shard.png index 4241a901902..8423a41cbe8 100644 Binary files a/public/images/items/fighting_tera_shard.png and b/public/images/items/fighting_tera_shard.png differ diff --git a/public/images/items/fire_memory.png b/public/images/items/fire_memory.png index 8778baa5f56..4f341417b6e 100644 Binary files a/public/images/items/fire_memory.png and b/public/images/items/fire_memory.png differ diff --git a/public/images/items/fire_stone.png b/public/images/items/fire_stone.png index 7fc77cd5975..3db1942dfed 100644 Binary files a/public/images/items/fire_stone.png and b/public/images/items/fire_stone.png differ diff --git a/public/images/items/fire_tera_shard.png b/public/images/items/fire_tera_shard.png index 74a04df1680..5783a5e9720 100644 Binary files a/public/images/items/fire_tera_shard.png and b/public/images/items/fire_tera_shard.png differ diff --git a/public/images/items/fist_plate.png b/public/images/items/fist_plate.png index 6892d821da6..d992e4ab1c2 100644 Binary files a/public/images/items/fist_plate.png and b/public/images/items/fist_plate.png differ diff --git a/public/images/items/flame_orb.png b/public/images/items/flame_orb.png index 32f11719a5d..5132bbb6153 100644 Binary files a/public/images/items/flame_orb.png and b/public/images/items/flame_orb.png differ diff --git a/public/images/items/flame_plate.png b/public/images/items/flame_plate.png index 26a56f18462..7633773eee1 100644 Binary files a/public/images/items/flame_plate.png and b/public/images/items/flame_plate.png differ diff --git a/public/images/items/flying_memory.png b/public/images/items/flying_memory.png index d4b31e2c240..8d3efbf1401 100644 Binary files a/public/images/items/flying_memory.png and b/public/images/items/flying_memory.png differ diff --git a/public/images/items/flying_tera_shard.png b/public/images/items/flying_tera_shard.png index bee18637918..97d3013f70b 100644 Binary files a/public/images/items/flying_tera_shard.png and b/public/images/items/flying_tera_shard.png differ diff --git a/public/images/items/focus_band.png b/public/images/items/focus_band.png index 830e1294213..3a04ae17023 100644 Binary files a/public/images/items/focus_band.png and b/public/images/items/focus_band.png differ diff --git a/public/images/items/focus_sash.png b/public/images/items/focus_sash.png index 6dcd0f2f146..7700ceecf6b 100644 Binary files a/public/images/items/focus_sash.png and b/public/images/items/focus_sash.png differ diff --git a/public/images/items/full_heal.png b/public/images/items/full_heal.png index 61663fd5e2d..4e59dcf44fa 100644 Binary files a/public/images/items/full_heal.png and b/public/images/items/full_heal.png differ diff --git a/public/images/items/full_restore.png b/public/images/items/full_restore.png index bd3ebfd3022..ba64f2edad8 100644 Binary files a/public/images/items/full_restore.png and b/public/images/items/full_restore.png differ diff --git a/public/images/items/galarica_cuff.png b/public/images/items/galarica_cuff.png index 1b3f9c69296..56523da5230 100644 Binary files a/public/images/items/galarica_cuff.png and b/public/images/items/galarica_cuff.png differ diff --git a/public/images/items/galarica_wreath.png b/public/images/items/galarica_wreath.png index 7fe319f20cf..20356bafd8a 100644 Binary files a/public/images/items/galarica_wreath.png and b/public/images/items/galarica_wreath.png differ diff --git a/public/images/items/galladite.png b/public/images/items/galladite.png index b204209a91c..15c93cd9c7e 100644 Binary files a/public/images/items/galladite.png and b/public/images/items/galladite.png differ diff --git a/public/images/items/ganlon_berry.png b/public/images/items/ganlon_berry.png index 81aecd83011..f9b88fc563a 100644 Binary files a/public/images/items/ganlon_berry.png and b/public/images/items/ganlon_berry.png differ diff --git a/public/images/items/garchompite.png b/public/images/items/garchompite.png index 045fc815b27..4276146a858 100644 Binary files a/public/images/items/garchompite.png and b/public/images/items/garchompite.png differ diff --git a/public/images/items/gardevoirite.png b/public/images/items/gardevoirite.png index d29ee3eab03..66a90b93bce 100644 Binary files a/public/images/items/gardevoirite.png and b/public/images/items/gardevoirite.png differ diff --git a/public/images/items/gb.png b/public/images/items/gb.png index 5a69585f5cd..4b437277849 100644 Binary files a/public/images/items/gb.png and b/public/images/items/gb.png differ diff --git a/public/images/items/gengarite.png b/public/images/items/gengarite.png index dcbaf4bf13a..4ccaae6ee8d 100644 Binary files a/public/images/items/gengarite.png and b/public/images/items/gengarite.png differ diff --git a/public/images/items/ghost_memory.png b/public/images/items/ghost_memory.png index d3f174de758..cb3c31ea4de 100644 Binary files a/public/images/items/ghost_memory.png and b/public/images/items/ghost_memory.png differ diff --git a/public/images/items/ghost_tera_shard.png b/public/images/items/ghost_tera_shard.png index fd3557e5534..8b9c6e750a9 100644 Binary files a/public/images/items/ghost_tera_shard.png and b/public/images/items/ghost_tera_shard.png differ diff --git a/public/images/items/glalitite.png b/public/images/items/glalitite.png index 83e05f132fa..ed7858c631c 100644 Binary files a/public/images/items/glalitite.png and b/public/images/items/glalitite.png differ diff --git a/public/images/items/golden_egg.png b/public/images/items/golden_egg.png index bfc517c6632..5727b4cb513 100644 Binary files a/public/images/items/golden_egg.png and b/public/images/items/golden_egg.png differ diff --git a/public/images/items/golden_exp_charm.png b/public/images/items/golden_exp_charm.png index 199832159d6..1895bfaa6b9 100644 Binary files a/public/images/items/golden_exp_charm.png and b/public/images/items/golden_exp_charm.png differ diff --git a/public/images/items/golden_mystic_ticket.png b/public/images/items/golden_mystic_ticket.png index ff44d3307b6..57f5b9efca6 100644 Binary files a/public/images/items/golden_mystic_ticket.png and b/public/images/items/golden_mystic_ticket.png differ diff --git a/public/images/items/golden_net.png b/public/images/items/golden_net.png index 5fea1ee7dba..3205d545e27 100644 Binary files a/public/images/items/golden_net.png and b/public/images/items/golden_net.png differ diff --git a/public/images/items/golden_punch.png b/public/images/items/golden_punch.png index 25c2233e714..291ff7e248f 100644 Binary files a/public/images/items/golden_punch.png and b/public/images/items/golden_punch.png differ diff --git a/public/images/items/gracidea.png b/public/images/items/gracidea.png index 0552d11b01b..6e464390f17 100644 Binary files a/public/images/items/gracidea.png and b/public/images/items/gracidea.png differ diff --git a/public/images/items/grass_memory.png b/public/images/items/grass_memory.png index 28ffc343c66..9d7d27de770 100644 Binary files a/public/images/items/grass_memory.png and b/public/images/items/grass_memory.png differ diff --git a/public/images/items/grass_tera_shard.png b/public/images/items/grass_tera_shard.png index 01bf4bde640..30e8762b5b6 100644 Binary files a/public/images/items/grass_tera_shard.png and b/public/images/items/grass_tera_shard.png differ diff --git a/public/images/items/great_ribbon.png b/public/images/items/great_ribbon.png index 720c0d85366..e7d7e452122 100644 Binary files a/public/images/items/great_ribbon.png and b/public/images/items/great_ribbon.png differ diff --git a/public/images/items/grip_claw.png b/public/images/items/grip_claw.png index e37e2a2eaf3..61cbb89e9b2 100644 Binary files a/public/images/items/grip_claw.png and b/public/images/items/grip_claw.png differ diff --git a/public/images/items/griseous_core.png b/public/images/items/griseous_core.png index fa131cccfda..7f3f683eda8 100644 Binary files a/public/images/items/griseous_core.png and b/public/images/items/griseous_core.png differ diff --git a/public/images/items/ground_memory.png b/public/images/items/ground_memory.png index 8ab042c02ff..808a4e13eeb 100644 Binary files a/public/images/items/ground_memory.png and b/public/images/items/ground_memory.png differ diff --git a/public/images/items/ground_tera_shard.png b/public/images/items/ground_tera_shard.png index 153bbd9058c..d7760f7dc1b 100644 Binary files a/public/images/items/ground_tera_shard.png and b/public/images/items/ground_tera_shard.png differ diff --git a/public/images/items/guard_spec.png b/public/images/items/guard_spec.png index 3efc9448404..95a37d0d28e 100644 Binary files a/public/images/items/guard_spec.png and b/public/images/items/guard_spec.png differ diff --git a/public/images/items/gyaradosite.png b/public/images/items/gyaradosite.png index bc8e6d6b115..e4cae1366ab 100644 Binary files a/public/images/items/gyaradosite.png and b/public/images/items/gyaradosite.png differ diff --git a/public/images/items/hard_meteorite.png b/public/images/items/hard_meteorite.png index d8f3490c581..8e8a2b5688b 100644 Binary files a/public/images/items/hard_meteorite.png and b/public/images/items/hard_meteorite.png differ diff --git a/public/images/items/hard_stone.png b/public/images/items/hard_stone.png index 604b44f9915..571d96afaa8 100644 Binary files a/public/images/items/hard_stone.png and b/public/images/items/hard_stone.png differ diff --git a/public/images/items/healing_charm.png b/public/images/items/healing_charm.png index b6f4c593c53..4601eeef593 100644 Binary files a/public/images/items/healing_charm.png and b/public/images/items/healing_charm.png differ diff --git a/public/images/items/hearthflame_mask.png b/public/images/items/hearthflame_mask.png index cd2ecdf1949..deed3d0cde8 100644 Binary files a/public/images/items/hearthflame_mask.png and b/public/images/items/hearthflame_mask.png differ diff --git a/public/images/items/heracronite.png b/public/images/items/heracronite.png index 164da1c9d30..ffcfc440c19 100644 Binary files a/public/images/items/heracronite.png and b/public/images/items/heracronite.png differ diff --git a/public/images/items/houndoominite.png b/public/images/items/houndoominite.png index 9e2e5f2eacd..c9ea1954dfa 100644 Binary files a/public/images/items/houndoominite.png and b/public/images/items/houndoominite.png differ diff --git a/public/images/items/hp_up.png b/public/images/items/hp_up.png index ff456d25289..5c6baff0673 100644 Binary files a/public/images/items/hp_up.png and b/public/images/items/hp_up.png differ diff --git a/public/images/items/hyper_potion.png b/public/images/items/hyper_potion.png index fa1c1432795..197aaac690c 100644 Binary files a/public/images/items/hyper_potion.png and b/public/images/items/hyper_potion.png differ diff --git a/public/images/items/ice_memory.png b/public/images/items/ice_memory.png index 01e68c08f82..812548cf36c 100644 Binary files a/public/images/items/ice_memory.png and b/public/images/items/ice_memory.png differ diff --git a/public/images/items/ice_stone.png b/public/images/items/ice_stone.png index a0fc0c12c5d..945714b759c 100644 Binary files a/public/images/items/ice_stone.png and b/public/images/items/ice_stone.png differ diff --git a/public/images/items/ice_tera_shard.png b/public/images/items/ice_tera_shard.png index 3e07acee397..5644d647c2b 100644 Binary files a/public/images/items/ice_tera_shard.png and b/public/images/items/ice_tera_shard.png differ diff --git a/public/images/items/icicle_plate.png b/public/images/items/icicle_plate.png index 67b5138e3e6..f9797d91f6a 100644 Binary files a/public/images/items/icicle_plate.png and b/public/images/items/icicle_plate.png differ diff --git a/public/images/items/icy_reins_of_unity.png b/public/images/items/icy_reins_of_unity.png index 84ec94a1d87..b7af48d6a81 100644 Binary files a/public/images/items/icy_reins_of_unity.png and b/public/images/items/icy_reins_of_unity.png differ diff --git a/public/images/items/insect_plate.png b/public/images/items/insect_plate.png index 75b44640a1b..5bcc0eebaf5 100644 Binary files a/public/images/items/insect_plate.png and b/public/images/items/insect_plate.png differ diff --git a/public/images/items/inverse.png b/public/images/items/inverse.png index b1ad5d2c00e..0d77ce77dde 100644 Binary files a/public/images/items/inverse.png and b/public/images/items/inverse.png differ diff --git a/public/images/items/iron.png b/public/images/items/iron.png index 3bb8ab15a8f..5cfff11b059 100644 Binary files a/public/images/items/iron.png and b/public/images/items/iron.png differ diff --git a/public/images/items/iron_plate.png b/public/images/items/iron_plate.png index ee892755660..65d660e34eb 100644 Binary files a/public/images/items/iron_plate.png and b/public/images/items/iron_plate.png differ diff --git a/public/images/items/kangaskhanite.png b/public/images/items/kangaskhanite.png index b7eb6849729..3d65d2cc5ca 100644 Binary files a/public/images/items/kangaskhanite.png and b/public/images/items/kangaskhanite.png differ diff --git a/public/images/items/kings_rock.png b/public/images/items/kings_rock.png index 0ea43c267bc..bfda9d559d3 100644 Binary files a/public/images/items/kings_rock.png and b/public/images/items/kings_rock.png differ diff --git a/public/images/items/lansat_berry.png b/public/images/items/lansat_berry.png index 6b2a8fb4760..223bff3eb26 100644 Binary files a/public/images/items/lansat_berry.png and b/public/images/items/lansat_berry.png differ diff --git a/public/images/items/latiasite.png b/public/images/items/latiasite.png index 6b92d1851cc..486a542576f 100644 Binary files a/public/images/items/latiasite.png and b/public/images/items/latiasite.png differ diff --git a/public/images/items/latiosite.png b/public/images/items/latiosite.png index 0d2af34781f..69708835c7b 100644 Binary files a/public/images/items/latiosite.png and b/public/images/items/latiosite.png differ diff --git a/public/images/items/leaders_crest.png b/public/images/items/leaders_crest.png index 45cf1656374..86b71f1eb6d 100644 Binary files a/public/images/items/leaders_crest.png and b/public/images/items/leaders_crest.png differ diff --git a/public/images/items/leaf_stone.png b/public/images/items/leaf_stone.png index a384af2a9c7..dc68e916bcf 100644 Binary files a/public/images/items/leaf_stone.png and b/public/images/items/leaf_stone.png differ diff --git a/public/images/items/leek.png b/public/images/items/leek.png index 7ef3fb989a4..1cb136aa78c 100644 Binary files a/public/images/items/leek.png and b/public/images/items/leek.png differ diff --git a/public/images/items/leftovers.png b/public/images/items/leftovers.png index 48ff07fbed3..4732d149b64 100644 Binary files a/public/images/items/leftovers.png and b/public/images/items/leftovers.png differ diff --git a/public/images/items/legend_plate.png b/public/images/items/legend_plate.png index 5b8681ebfe7..e96f12b45f5 100644 Binary files a/public/images/items/legend_plate.png and b/public/images/items/legend_plate.png differ diff --git a/public/images/items/leppa_berry.png b/public/images/items/leppa_berry.png index 4bc1349fe94..7a0f13b5199 100644 Binary files a/public/images/items/leppa_berry.png and b/public/images/items/leppa_berry.png differ diff --git a/public/images/items/liechi_berry.png b/public/images/items/liechi_berry.png index 492ef7e86f1..192d8f001ef 100644 Binary files a/public/images/items/liechi_berry.png and b/public/images/items/liechi_berry.png differ diff --git a/public/images/items/light_ball.png b/public/images/items/light_ball.png index cd421446608..7748f735d37 100644 Binary files a/public/images/items/light_ball.png and b/public/images/items/light_ball.png differ diff --git a/public/images/items/light_stone.png b/public/images/items/light_stone.png index 2b2be824020..97258cf3970 100644 Binary files a/public/images/items/light_stone.png and b/public/images/items/light_stone.png differ diff --git a/public/images/items/linking_cord.png b/public/images/items/linking_cord.png index ab695ae1fc8..4cde9da3f14 100644 Binary files a/public/images/items/linking_cord.png and b/public/images/items/linking_cord.png differ diff --git a/public/images/items/lock_capsule.png b/public/images/items/lock_capsule.png index b2e64dfdbfd..25d0cc14cff 100644 Binary files a/public/images/items/lock_capsule.png and b/public/images/items/lock_capsule.png differ diff --git a/public/images/items/lopunnite.png b/public/images/items/lopunnite.png index 416807c0c81..bd67cf159ed 100644 Binary files a/public/images/items/lopunnite.png and b/public/images/items/lopunnite.png differ diff --git a/public/images/items/lucarionite.png b/public/images/items/lucarionite.png index 82d3b19129d..b97161df68c 100644 Binary files a/public/images/items/lucarionite.png and b/public/images/items/lucarionite.png differ diff --git a/public/images/items/lucky_egg.png b/public/images/items/lucky_egg.png index 2760c303d37..fa9a1e4b390 100644 Binary files a/public/images/items/lucky_egg.png and b/public/images/items/lucky_egg.png differ diff --git a/public/images/items/lucky_punch.png b/public/images/items/lucky_punch.png index ed783c43e9a..97887631d9a 100644 Binary files a/public/images/items/lucky_punch.png and b/public/images/items/lucky_punch.png differ diff --git a/public/images/items/lucky_punch_great.png b/public/images/items/lucky_punch_great.png index c66df778210..77c77daf535 100644 Binary files a/public/images/items/lucky_punch_great.png and b/public/images/items/lucky_punch_great.png differ diff --git a/public/images/items/lucky_punch_master.png b/public/images/items/lucky_punch_master.png index d48fdf04bae..89fc1b67cf4 100644 Binary files a/public/images/items/lucky_punch_master.png and b/public/images/items/lucky_punch_master.png differ diff --git a/public/images/items/lucky_punch_ultra.png b/public/images/items/lucky_punch_ultra.png index aee27600f5c..a95c23666bb 100644 Binary files a/public/images/items/lucky_punch_ultra.png and b/public/images/items/lucky_punch_ultra.png differ diff --git a/public/images/items/lum_berry.png b/public/images/items/lum_berry.png index 8feb811e411..d19c4fba583 100644 Binary files a/public/images/items/lum_berry.png and b/public/images/items/lum_berry.png differ diff --git a/public/images/items/lure.png b/public/images/items/lure.png index a148aa70db9..1c3ea6cc8e8 100644 Binary files a/public/images/items/lure.png and b/public/images/items/lure.png differ diff --git a/public/images/items/lustrous_globe.png b/public/images/items/lustrous_globe.png index a16cf80c350..2a854db742b 100644 Binary files a/public/images/items/lustrous_globe.png and b/public/images/items/lustrous_globe.png differ diff --git a/public/images/items/macho_brace.png b/public/images/items/macho_brace.png index 2085829e1ce..760139cf7f8 100644 Binary files a/public/images/items/macho_brace.png and b/public/images/items/macho_brace.png differ diff --git a/public/images/items/magmarizer.png b/public/images/items/magmarizer.png index 0fca34c1e28..4f4d5f45851 100644 Binary files a/public/images/items/magmarizer.png and b/public/images/items/magmarizer.png differ diff --git a/public/images/items/magnet.png b/public/images/items/magnet.png index 7a07f557ec4..9ce8b686e9f 100644 Binary files a/public/images/items/magnet.png and b/public/images/items/magnet.png differ diff --git a/public/images/items/malicious_armor.png b/public/images/items/malicious_armor.png index 495024ced20..b7bfb55195b 100644 Binary files a/public/images/items/malicious_armor.png and b/public/images/items/malicious_armor.png differ diff --git a/public/images/items/manectite.png b/public/images/items/manectite.png index 0dd7406cdc4..c9df61669bc 100644 Binary files a/public/images/items/manectite.png and b/public/images/items/manectite.png differ diff --git a/public/images/items/map.png b/public/images/items/map.png index a641a7e8a69..dc2fc6b95d8 100644 Binary files a/public/images/items/map.png and b/public/images/items/map.png differ diff --git a/public/images/items/master_ribbon.png b/public/images/items/master_ribbon.png index 86be493b74a..0443215c1f9 100644 Binary files a/public/images/items/master_ribbon.png and b/public/images/items/master_ribbon.png differ diff --git a/public/images/items/masterpiece_teacup.png b/public/images/items/masterpiece_teacup.png index 36b8c39dcc7..ec2455c0763 100644 Binary files a/public/images/items/masterpiece_teacup.png and b/public/images/items/masterpiece_teacup.png differ diff --git a/public/images/items/mawilite.png b/public/images/items/mawilite.png index 95ddf987f12..60ea4017f56 100644 Binary files a/public/images/items/mawilite.png and b/public/images/items/mawilite.png differ diff --git a/public/images/items/max_elixir.png b/public/images/items/max_elixir.png index a4f134dd13c..1f528c2bb61 100644 Binary files a/public/images/items/max_elixir.png and b/public/images/items/max_elixir.png differ diff --git a/public/images/items/max_ether.png b/public/images/items/max_ether.png index 0ecdf09397a..8cee7152a86 100644 Binary files a/public/images/items/max_ether.png and b/public/images/items/max_ether.png differ diff --git a/public/images/items/max_lure.png b/public/images/items/max_lure.png index 384db7d7df8..812229d140a 100644 Binary files a/public/images/items/max_lure.png and b/public/images/items/max_lure.png differ diff --git a/public/images/items/max_mushrooms.png b/public/images/items/max_mushrooms.png index 443f1d5c369..8d5c015c963 100644 Binary files a/public/images/items/max_mushrooms.png and b/public/images/items/max_mushrooms.png differ diff --git a/public/images/items/max_potion.png b/public/images/items/max_potion.png index f51e7bde976..d8fadc9cb93 100644 Binary files a/public/images/items/max_potion.png and b/public/images/items/max_potion.png differ diff --git a/public/images/items/max_repel.png b/public/images/items/max_repel.png index d8bef707913..4d88ae6d0b5 100644 Binary files a/public/images/items/max_repel.png and b/public/images/items/max_repel.png differ diff --git a/public/images/items/max_revive.png b/public/images/items/max_revive.png index 25849a3b940..609fd17c3b9 100644 Binary files a/public/images/items/max_revive.png and b/public/images/items/max_revive.png differ diff --git a/public/images/items/mb.png b/public/images/items/mb.png index cfa421d6219..d80b3b89108 100644 Binary files a/public/images/items/mb.png and b/public/images/items/mb.png differ diff --git a/public/images/items/meadow_plate.png b/public/images/items/meadow_plate.png index a687cb7920d..e2b991776ba 100644 Binary files a/public/images/items/meadow_plate.png and b/public/images/items/meadow_plate.png differ diff --git a/public/images/items/medichamite.png b/public/images/items/medichamite.png index 4dd57f10bed..42f22ed6cd6 100644 Binary files a/public/images/items/medichamite.png and b/public/images/items/medichamite.png differ diff --git a/public/images/items/mega_bracelet.png b/public/images/items/mega_bracelet.png index e593b907631..5e8ff02be8c 100644 Binary files a/public/images/items/mega_bracelet.png and b/public/images/items/mega_bracelet.png differ diff --git a/public/images/items/metagrossite.png b/public/images/items/metagrossite.png index 445deff40c1..c245368758d 100644 Binary files a/public/images/items/metagrossite.png and b/public/images/items/metagrossite.png differ diff --git a/public/images/items/metal_alloy.png b/public/images/items/metal_alloy.png index 1201f58b463..41f22df4254 100644 Binary files a/public/images/items/metal_alloy.png and b/public/images/items/metal_alloy.png differ diff --git a/public/images/items/metal_coat.png b/public/images/items/metal_coat.png index f016d48bd2e..88f055c3fb3 100644 Binary files a/public/images/items/metal_coat.png and b/public/images/items/metal_coat.png differ diff --git a/public/images/items/metal_powder.png b/public/images/items/metal_powder.png index 11c3a39314c..64af0b144fe 100644 Binary files a/public/images/items/metal_powder.png and b/public/images/items/metal_powder.png differ diff --git a/public/images/items/metronome.png b/public/images/items/metronome.png index dfde7e365eb..837d75b4c03 100644 Binary files a/public/images/items/metronome.png and b/public/images/items/metronome.png differ diff --git a/public/images/items/mewtwonite_x.png b/public/images/items/mewtwonite_x.png index 3ec18a1c683..507d17e54e8 100644 Binary files a/public/images/items/mewtwonite_x.png and b/public/images/items/mewtwonite_x.png differ diff --git a/public/images/items/mewtwonite_y.png b/public/images/items/mewtwonite_y.png index eb9b1d0dc55..ff0c53396d2 100644 Binary files a/public/images/items/mewtwonite_y.png and b/public/images/items/mewtwonite_y.png differ diff --git a/public/images/items/mind_plate.png b/public/images/items/mind_plate.png index 04001796831..ff6fcc4f3af 100644 Binary files a/public/images/items/mind_plate.png and b/public/images/items/mind_plate.png differ diff --git a/public/images/items/mini_black_hole.png b/public/images/items/mini_black_hole.png index dd7458b8b2a..6edcaad16e3 100644 Binary files a/public/images/items/mini_black_hole.png and b/public/images/items/mini_black_hole.png differ diff --git a/public/images/items/mint_atk.png b/public/images/items/mint_atk.png index 727a7b3f792..88315c0cd07 100644 Binary files a/public/images/items/mint_atk.png and b/public/images/items/mint_atk.png differ diff --git a/public/images/items/mint_def.png b/public/images/items/mint_def.png index 9cd92eac07e..584c610ffd7 100644 Binary files a/public/images/items/mint_def.png and b/public/images/items/mint_def.png differ diff --git a/public/images/items/mint_neutral.png b/public/images/items/mint_neutral.png index e2e556d475b..f5287539e78 100644 Binary files a/public/images/items/mint_neutral.png and b/public/images/items/mint_neutral.png differ diff --git a/public/images/items/mint_spatk.png b/public/images/items/mint_spatk.png index 191ba6c4a1a..90a57c5608b 100644 Binary files a/public/images/items/mint_spatk.png and b/public/images/items/mint_spatk.png differ diff --git a/public/images/items/mint_spd.png b/public/images/items/mint_spd.png index 687119f2502..5420b0997b3 100644 Binary files a/public/images/items/mint_spd.png and b/public/images/items/mint_spd.png differ diff --git a/public/images/items/mint_spdef.png b/public/images/items/mint_spdef.png index cd902ce0984..54a1b4ed21d 100644 Binary files a/public/images/items/mint_spdef.png and b/public/images/items/mint_spdef.png differ diff --git a/public/images/items/miracle_seed.png b/public/images/items/miracle_seed.png index f5bc766545a..8be7ba72d33 100644 Binary files a/public/images/items/miracle_seed.png and b/public/images/items/miracle_seed.png differ diff --git a/public/images/items/moon_flute.png b/public/images/items/moon_flute.png index 893cb6a7579..5d3c0caf5f2 100644 Binary files a/public/images/items/moon_flute.png and b/public/images/items/moon_flute.png differ diff --git a/public/images/items/moon_stone.png b/public/images/items/moon_stone.png index b4af61969a2..f002fb18073 100644 Binary files a/public/images/items/moon_stone.png and b/public/images/items/moon_stone.png differ diff --git a/public/images/items/muscle_band.png b/public/images/items/muscle_band.png index 011716e7124..0be9d010767 100644 Binary files a/public/images/items/muscle_band.png and b/public/images/items/muscle_band.png differ diff --git a/public/images/items/mystery_egg.png b/public/images/items/mystery_egg.png index bb117a137b0..ac631cec7c8 100644 Binary files a/public/images/items/mystery_egg.png and b/public/images/items/mystery_egg.png differ diff --git a/public/images/items/mystic_ticket.png b/public/images/items/mystic_ticket.png index bd206998fed..cab03fa5470 100644 Binary files a/public/images/items/mystic_ticket.png and b/public/images/items/mystic_ticket.png differ diff --git a/public/images/items/mystic_water.png b/public/images/items/mystic_water.png index f944fac1a9c..2128895b385 100644 Binary files a/public/images/items/mystic_water.png and b/public/images/items/mystic_water.png differ diff --git a/public/images/items/mystical_rock.png b/public/images/items/mystical_rock.png new file mode 100644 index 00000000000..f87fe2a9dcb Binary files /dev/null and b/public/images/items/mystical_rock.png differ diff --git a/public/images/items/n_lunarizer.png b/public/images/items/n_lunarizer.png index e45fb8ecf8d..a03b48ad387 100644 Binary files a/public/images/items/n_lunarizer.png and b/public/images/items/n_lunarizer.png differ diff --git a/public/images/items/n_solarizer.png b/public/images/items/n_solarizer.png index e706a42c973..69153fd38dd 100644 Binary files a/public/images/items/n_solarizer.png and b/public/images/items/n_solarizer.png differ diff --git a/public/images/items/never_melt_ice.png b/public/images/items/never_melt_ice.png index bec7cc0e5d4..35b1ada771d 100644 Binary files a/public/images/items/never_melt_ice.png and b/public/images/items/never_melt_ice.png differ diff --git a/public/images/items/normal_memory.png b/public/images/items/normal_memory.png index ddc22d1d4ab..e1ff89a9993 100644 Binary files a/public/images/items/normal_memory.png and b/public/images/items/normal_memory.png differ diff --git a/public/images/items/normal_tera_shard.png b/public/images/items/normal_tera_shard.png index fe2b9b93fd6..1c7a41ea0ec 100644 Binary files a/public/images/items/normal_tera_shard.png and b/public/images/items/normal_tera_shard.png differ diff --git a/public/images/items/nugget.png b/public/images/items/nugget.png index e8d39912349..0340f5d4000 100644 Binary files a/public/images/items/nugget.png and b/public/images/items/nugget.png differ diff --git a/public/images/items/old_gateau.png b/public/images/items/old_gateau.png index c910e90f101..dd5f0e05a94 100644 Binary files a/public/images/items/old_gateau.png and b/public/images/items/old_gateau.png differ diff --git a/public/images/items/oval_charm.png b/public/images/items/oval_charm.png index dc791175588..fcdb914ec22 100644 Binary files a/public/images/items/oval_charm.png and b/public/images/items/oval_charm.png differ diff --git a/public/images/items/oval_stone.png b/public/images/items/oval_stone.png index d48b0688821..d58ffde18e3 100644 Binary files a/public/images/items/oval_stone.png and b/public/images/items/oval_stone.png differ diff --git a/public/images/items/pair_of_tickets.png b/public/images/items/pair_of_tickets.png index b4b6ececbd2..b06c9a8727f 100644 Binary files a/public/images/items/pair_of_tickets.png and b/public/images/items/pair_of_tickets.png differ diff --git a/public/images/items/pb.png b/public/images/items/pb.png index ec4fe69c86f..37c37edb8c1 100644 Binary files a/public/images/items/pb.png and b/public/images/items/pb.png differ diff --git a/public/images/items/pb_gold.png b/public/images/items/pb_gold.png index fd71feb8e55..6dff6824158 100644 Binary files a/public/images/items/pb_gold.png and b/public/images/items/pb_gold.png differ diff --git a/public/images/items/pb_silver.png b/public/images/items/pb_silver.png index f60a8348a94..9528517a77a 100644 Binary files a/public/images/items/pb_silver.png and b/public/images/items/pb_silver.png differ diff --git a/public/images/items/peat_block.png b/public/images/items/peat_block.png index b62e94d523f..f3c65449b87 100644 Binary files a/public/images/items/peat_block.png and b/public/images/items/peat_block.png differ diff --git a/public/images/items/petaya_berry.png b/public/images/items/petaya_berry.png index e1dae467187..0fba884c2e2 100644 Binary files a/public/images/items/petaya_berry.png and b/public/images/items/petaya_berry.png differ diff --git a/public/images/items/pidgeotite.png b/public/images/items/pidgeotite.png index 86d1b23558c..52cb40852d6 100644 Binary files a/public/images/items/pidgeotite.png and b/public/images/items/pidgeotite.png differ diff --git a/public/images/items/pinsirite.png b/public/images/items/pinsirite.png index 2616cf6dfe1..88ecc8e9ea9 100644 Binary files a/public/images/items/pinsirite.png and b/public/images/items/pinsirite.png differ diff --git a/public/images/items/pixie_plate.png b/public/images/items/pixie_plate.png index dcc829c107f..e123ae6a49a 100644 Binary files a/public/images/items/pixie_plate.png and b/public/images/items/pixie_plate.png differ diff --git a/public/images/items/poison_barb.png b/public/images/items/poison_barb.png index 913ede4d819..3f9d714b08c 100644 Binary files a/public/images/items/poison_barb.png and b/public/images/items/poison_barb.png differ diff --git a/public/images/items/poison_memory.png b/public/images/items/poison_memory.png index 2b0036201d9..6c2b0aea77b 100644 Binary files a/public/images/items/poison_memory.png and b/public/images/items/poison_memory.png differ diff --git a/public/images/items/poison_tera_shard.png b/public/images/items/poison_tera_shard.png index b124fa051b9..4f21d158a41 100644 Binary files a/public/images/items/poison_tera_shard.png and b/public/images/items/poison_tera_shard.png differ diff --git a/public/images/items/potion.png b/public/images/items/potion.png index 10a7d5848db..f69c3210f03 100644 Binary files a/public/images/items/potion.png and b/public/images/items/potion.png differ diff --git a/public/images/items/power_herb.png b/public/images/items/power_herb.png index 15a581490a0..ba156c62122 100644 Binary files a/public/images/items/power_herb.png and b/public/images/items/power_herb.png differ diff --git a/public/images/items/pp_max.png b/public/images/items/pp_max.png index 48752829557..787641e26ac 100644 Binary files a/public/images/items/pp_max.png and b/public/images/items/pp_max.png differ diff --git a/public/images/items/pp_up.png b/public/images/items/pp_up.png index 1334d228bc3..463c3a0578d 100644 Binary files a/public/images/items/pp_up.png and b/public/images/items/pp_up.png differ diff --git a/public/images/items/prism_scale.png b/public/images/items/prism_scale.png index 5a0d45c686b..2436e96bf73 100644 Binary files a/public/images/items/prism_scale.png and b/public/images/items/prism_scale.png differ diff --git a/public/images/items/prison_bottle.png b/public/images/items/prison_bottle.png index da733bb14bb..06217988364 100644 Binary files a/public/images/items/prison_bottle.png and b/public/images/items/prison_bottle.png differ diff --git a/public/images/items/protector.png b/public/images/items/protector.png index a7b01a8c53d..8f65be09b2f 100644 Binary files a/public/images/items/protector.png and b/public/images/items/protector.png differ diff --git a/public/images/items/protein.png b/public/images/items/protein.png index b3386a8841b..54df13c6753 100644 Binary files a/public/images/items/protein.png and b/public/images/items/protein.png differ diff --git a/public/images/items/psychic_memory.png b/public/images/items/psychic_memory.png index a17afa4a617..21d62daa483 100644 Binary files a/public/images/items/psychic_memory.png and b/public/images/items/psychic_memory.png differ diff --git a/public/images/items/psychic_tera_shard.png b/public/images/items/psychic_tera_shard.png index 0a5656ccea1..f4b1cf7b259 100644 Binary files a/public/images/items/psychic_tera_shard.png and b/public/images/items/psychic_tera_shard.png differ diff --git a/public/images/items/quick_claw.png b/public/images/items/quick_claw.png index e6317898e2a..ff4f76d0576 100644 Binary files a/public/images/items/quick_claw.png and b/public/images/items/quick_claw.png differ diff --git a/public/images/items/quick_powder.png b/public/images/items/quick_powder.png index c73ec09eb05..58a8a1187a9 100644 Binary files a/public/images/items/quick_powder.png and b/public/images/items/quick_powder.png differ diff --git a/public/images/items/rare_candy.png b/public/images/items/rare_candy.png index d81e7ad0844..a860a116905 100644 Binary files a/public/images/items/rare_candy.png and b/public/images/items/rare_candy.png differ diff --git a/public/images/items/rarer_candy.png b/public/images/items/rarer_candy.png index b8432bd8216..4424caa659a 100644 Binary files a/public/images/items/rarer_candy.png and b/public/images/items/rarer_candy.png differ diff --git a/public/images/items/rayquazite.png b/public/images/items/rayquazite.png index 068f02936be..b39957b857d 100644 Binary files a/public/images/items/rayquazite.png and b/public/images/items/rayquazite.png differ diff --git a/public/images/items/razor_claw.png b/public/images/items/razor_claw.png index a9541c4d251..0ba506e8706 100644 Binary files a/public/images/items/razor_claw.png and b/public/images/items/razor_claw.png differ diff --git a/public/images/items/razor_fang.png b/public/images/items/razor_fang.png index 77c3da44c92..75306db5c4c 100644 Binary files a/public/images/items/razor_fang.png and b/public/images/items/razor_fang.png differ diff --git a/public/images/items/rb.png b/public/images/items/rb.png index 440ab8bf1b4..020f2ff878b 100644 Binary files a/public/images/items/rb.png and b/public/images/items/rb.png differ diff --git a/public/images/items/reaper_cloth.png b/public/images/items/reaper_cloth.png index a86714bfc4f..9caf7665e95 100644 Binary files a/public/images/items/reaper_cloth.png and b/public/images/items/reaper_cloth.png differ diff --git a/public/images/items/red_orb.png b/public/images/items/red_orb.png index b982649c9b3..cee83740ca5 100644 Binary files a/public/images/items/red_orb.png and b/public/images/items/red_orb.png differ diff --git a/public/images/items/relic_band.png b/public/images/items/relic_band.png index 634b91e41b3..adbd73bc46b 100644 Binary files a/public/images/items/relic_band.png and b/public/images/items/relic_band.png differ diff --git a/public/images/items/relic_crown.png b/public/images/items/relic_crown.png index d8c4552ea3c..de090041c1c 100644 Binary files a/public/images/items/relic_crown.png and b/public/images/items/relic_crown.png differ diff --git a/public/images/items/relic_gold.png b/public/images/items/relic_gold.png index da3f33fdfa1..af5b1797938 100644 Binary files a/public/images/items/relic_gold.png and b/public/images/items/relic_gold.png differ diff --git a/public/images/items/repel.png b/public/images/items/repel.png index 3d1359e688e..80c7738e9ff 100644 Binary files a/public/images/items/repel.png and b/public/images/items/repel.png differ diff --git a/public/images/items/reveal_glass.png b/public/images/items/reveal_glass.png index 3fae3bdf934..469d20a2752 100644 Binary files a/public/images/items/reveal_glass.png and b/public/images/items/reveal_glass.png differ diff --git a/public/images/items/revive.png b/public/images/items/revive.png index d7952b7653f..e84659867d8 100644 Binary files a/public/images/items/revive.png and b/public/images/items/revive.png differ diff --git a/public/images/items/reviver_seed.png b/public/images/items/reviver_seed.png index 31cfae46f94..10bc5c32451 100644 Binary files a/public/images/items/reviver_seed.png and b/public/images/items/reviver_seed.png differ diff --git a/public/images/items/ribbon_gen1.png b/public/images/items/ribbon_gen1.png index a9774d18ad0..1d731cf2e98 100644 Binary files a/public/images/items/ribbon_gen1.png and b/public/images/items/ribbon_gen1.png differ diff --git a/public/images/items/ribbon_gen2.png b/public/images/items/ribbon_gen2.png index a04f6a32a62..2ff54112105 100644 Binary files a/public/images/items/ribbon_gen2.png and b/public/images/items/ribbon_gen2.png differ diff --git a/public/images/items/ribbon_gen3.png b/public/images/items/ribbon_gen3.png index 0cf20ed92ee..14a5eb09f7d 100644 Binary files a/public/images/items/ribbon_gen3.png and b/public/images/items/ribbon_gen3.png differ diff --git a/public/images/items/ribbon_gen4.png b/public/images/items/ribbon_gen4.png index aa24433b71b..c482ac1d04a 100644 Binary files a/public/images/items/ribbon_gen4.png and b/public/images/items/ribbon_gen4.png differ diff --git a/public/images/items/ribbon_gen5.png b/public/images/items/ribbon_gen5.png index 7bb7800671f..52560cde636 100644 Binary files a/public/images/items/ribbon_gen5.png and b/public/images/items/ribbon_gen5.png differ diff --git a/public/images/items/ribbon_gen6.png b/public/images/items/ribbon_gen6.png index e466eb78842..3dd04927acd 100644 Binary files a/public/images/items/ribbon_gen6.png and b/public/images/items/ribbon_gen6.png differ diff --git a/public/images/items/ribbon_gen7.png b/public/images/items/ribbon_gen7.png index 9c156ebd1c6..225b40da419 100644 Binary files a/public/images/items/ribbon_gen7.png and b/public/images/items/ribbon_gen7.png differ diff --git a/public/images/items/ribbon_gen8.png b/public/images/items/ribbon_gen8.png index 86b3748e348..32aaa803699 100644 Binary files a/public/images/items/ribbon_gen8.png and b/public/images/items/ribbon_gen8.png differ diff --git a/public/images/items/ribbon_gen9.png b/public/images/items/ribbon_gen9.png index e9609daf3cd..ad489005e23 100644 Binary files a/public/images/items/ribbon_gen9.png and b/public/images/items/ribbon_gen9.png differ diff --git a/public/images/items/rock_memory.png b/public/images/items/rock_memory.png index 01f436dd461..cfa71c851c0 100644 Binary files a/public/images/items/rock_memory.png and b/public/images/items/rock_memory.png differ diff --git a/public/images/items/rock_tera_shard.png b/public/images/items/rock_tera_shard.png index b4e6f8a29cf..a07ca7955a4 100644 Binary files a/public/images/items/rock_tera_shard.png and b/public/images/items/rock_tera_shard.png differ diff --git a/public/images/items/rogue_ribbon.png b/public/images/items/rogue_ribbon.png index 85986d93c8a..c3cfdcd85f3 100644 Binary files a/public/images/items/rogue_ribbon.png and b/public/images/items/rogue_ribbon.png differ diff --git a/public/images/items/rusted_shield.png b/public/images/items/rusted_shield.png index 569f86c15c7..3748f13dc4b 100644 Binary files a/public/images/items/rusted_shield.png and b/public/images/items/rusted_shield.png differ diff --git a/public/images/items/rusted_sword.png b/public/images/items/rusted_sword.png index c42e669441c..249233374e0 100644 Binary files a/public/images/items/rusted_sword.png and b/public/images/items/rusted_sword.png differ diff --git a/public/images/items/sablenite.png b/public/images/items/sablenite.png index 904abea5ce4..48eac2d5875 100644 Binary files a/public/images/items/sablenite.png and b/public/images/items/sablenite.png differ diff --git a/public/images/items/sachet.png b/public/images/items/sachet.png index 1ec6010f1af..6d91fa210fc 100644 Binary files a/public/images/items/sachet.png and b/public/images/items/sachet.png differ diff --git a/public/images/items/sacred_ash.png b/public/images/items/sacred_ash.png index 389b2605b93..4fab9dc0dc7 100644 Binary files a/public/images/items/sacred_ash.png and b/public/images/items/sacred_ash.png differ diff --git a/public/images/items/salac_berry.png b/public/images/items/salac_berry.png index ac0d29f2159..846dbb4f160 100644 Binary files a/public/images/items/salac_berry.png and b/public/images/items/salac_berry.png differ diff --git a/public/images/items/salamencite.png b/public/images/items/salamencite.png index 1a0096b4de5..f175f39d351 100644 Binary files a/public/images/items/salamencite.png and b/public/images/items/salamencite.png differ diff --git a/public/images/items/scanner.png b/public/images/items/scanner.png index 27a67484f19..a291d3f43f8 100644 Binary files a/public/images/items/scanner.png and b/public/images/items/scanner.png differ diff --git a/public/images/items/sceptilite.png b/public/images/items/sceptilite.png index 123e79d9893..ff81c4a55fe 100644 Binary files a/public/images/items/sceptilite.png and b/public/images/items/sceptilite.png differ diff --git a/public/images/items/scizorite.png b/public/images/items/scizorite.png index ce86b80701c..8ffca143835 100644 Binary files a/public/images/items/scizorite.png and b/public/images/items/scizorite.png differ diff --git a/public/images/items/scope_lens.png b/public/images/items/scope_lens.png index 57ec2c4148e..d3b1f354313 100644 Binary files a/public/images/items/scope_lens.png and b/public/images/items/scope_lens.png differ diff --git a/public/images/items/scroll_of_darkness.png b/public/images/items/scroll_of_darkness.png index 19be0feb6dc..ff6a6065e40 100644 Binary files a/public/images/items/scroll_of_darkness.png and b/public/images/items/scroll_of_darkness.png differ diff --git a/public/images/items/scroll_of_waters.png b/public/images/items/scroll_of_waters.png index d1e6a0388b6..e4a0cb725eb 100644 Binary files a/public/images/items/scroll_of_waters.png and b/public/images/items/scroll_of_waters.png differ diff --git a/public/images/items/shadow_reins_of_unity.png b/public/images/items/shadow_reins_of_unity.png index 929aeac6fb4..85cbc446851 100644 Binary files a/public/images/items/shadow_reins_of_unity.png and b/public/images/items/shadow_reins_of_unity.png differ diff --git a/public/images/items/sharp_beak.png b/public/images/items/sharp_beak.png index 3ce8d83e3aa..f22019e658b 100644 Binary files a/public/images/items/sharp_beak.png and b/public/images/items/sharp_beak.png differ diff --git a/public/images/items/sharp_meteorite.png b/public/images/items/sharp_meteorite.png index 1a135b64980..61a139fab05 100644 Binary files a/public/images/items/sharp_meteorite.png and b/public/images/items/sharp_meteorite.png differ diff --git a/public/images/items/sharpedonite.png b/public/images/items/sharpedonite.png index 3a71f7258ce..b3eabd5650f 100644 Binary files a/public/images/items/sharpedonite.png and b/public/images/items/sharpedonite.png differ diff --git a/public/images/items/shed_shell.png b/public/images/items/shed_shell.png index a0570cf29c4..17981864897 100644 Binary files a/public/images/items/shed_shell.png and b/public/images/items/shed_shell.png differ diff --git a/public/images/items/shell_bell.png b/public/images/items/shell_bell.png index a185be50188..6367d134672 100644 Binary files a/public/images/items/shell_bell.png and b/public/images/items/shell_bell.png differ diff --git a/public/images/items/shiny_charm.png b/public/images/items/shiny_charm.png index d0c8197f7c4..9f692828d04 100644 Binary files a/public/images/items/shiny_charm.png and b/public/images/items/shiny_charm.png differ diff --git a/public/images/items/shiny_stone.png b/public/images/items/shiny_stone.png index d9d1e8b77ca..d2fabe6ec8b 100644 Binary files a/public/images/items/shiny_stone.png and b/public/images/items/shiny_stone.png differ diff --git a/public/images/items/shock_drive.png b/public/images/items/shock_drive.png index e0bcc66f202..592b0085a8f 100644 Binary files a/public/images/items/shock_drive.png and b/public/images/items/shock_drive.png differ diff --git a/public/images/items/silk_scarf.png b/public/images/items/silk_scarf.png index 2eaea7aa435..83f056c8b41 100644 Binary files a/public/images/items/silk_scarf.png and b/public/images/items/silk_scarf.png differ diff --git a/public/images/items/silver_powder.png b/public/images/items/silver_powder.png index 03f62b45250..eb717fc6776 100644 Binary files a/public/images/items/silver_powder.png and b/public/images/items/silver_powder.png differ diff --git a/public/images/items/sitrus_berry.png b/public/images/items/sitrus_berry.png index 8e9463a80c2..703657ad8dd 100644 Binary files a/public/images/items/sitrus_berry.png and b/public/images/items/sitrus_berry.png differ diff --git a/public/images/items/sky_plate.png b/public/images/items/sky_plate.png index 1fed973142b..293bb8f5dc2 100644 Binary files a/public/images/items/sky_plate.png and b/public/images/items/sky_plate.png differ diff --git a/public/images/items/slowbronite.png b/public/images/items/slowbronite.png index 7eac1fb82d5..3dc21ffb550 100644 Binary files a/public/images/items/slowbronite.png and b/public/images/items/slowbronite.png differ diff --git a/public/images/items/smooth_meteorite.png b/public/images/items/smooth_meteorite.png index 4c2e5e07978..059e8e91a30 100644 Binary files a/public/images/items/smooth_meteorite.png and b/public/images/items/smooth_meteorite.png differ diff --git a/public/images/items/soft_sand.png b/public/images/items/soft_sand.png index c627bc10a8e..feda8cd3858 100644 Binary files a/public/images/items/soft_sand.png and b/public/images/items/soft_sand.png differ diff --git a/public/images/items/soothe_bell.png b/public/images/items/soothe_bell.png index 62fd6ff26c5..fbceb808c56 100644 Binary files a/public/images/items/soothe_bell.png and b/public/images/items/soothe_bell.png differ diff --git a/public/images/items/soul_dew.png b/public/images/items/soul_dew.png index 9c0abfdef9a..56b9655714b 100644 Binary files a/public/images/items/soul_dew.png and b/public/images/items/soul_dew.png differ diff --git a/public/images/items/spell_tag.png b/public/images/items/spell_tag.png index ccf071e122d..f9270c6e0a6 100644 Binary files a/public/images/items/spell_tag.png and b/public/images/items/spell_tag.png differ diff --git a/public/images/items/splash_plate.png b/public/images/items/splash_plate.png index a832f3dbf8a..d86ae5eab57 100644 Binary files a/public/images/items/splash_plate.png and b/public/images/items/splash_plate.png differ diff --git a/public/images/items/spooky_plate.png b/public/images/items/spooky_plate.png index b5794713d0d..d7df7d25e32 100644 Binary files a/public/images/items/spooky_plate.png and b/public/images/items/spooky_plate.png differ diff --git a/public/images/items/starf_berry.png b/public/images/items/starf_berry.png index 71fe1ac116f..cbf423e8343 100644 Binary files a/public/images/items/starf_berry.png and b/public/images/items/starf_berry.png differ diff --git a/public/images/items/steel_memory.png b/public/images/items/steel_memory.png index fbc13016c00..8c45bc8b640 100644 Binary files a/public/images/items/steel_memory.png and b/public/images/items/steel_memory.png differ diff --git a/public/images/items/steel_tera_shard.png b/public/images/items/steel_tera_shard.png index b0b2ccb1737..c93f8c52f60 100644 Binary files a/public/images/items/steel_tera_shard.png and b/public/images/items/steel_tera_shard.png differ diff --git a/public/images/items/steelixite.png b/public/images/items/steelixite.png index 62f688f0842..429c668e656 100644 Binary files a/public/images/items/steelixite.png and b/public/images/items/steelixite.png differ diff --git a/public/images/items/stellar_tera_shard.png b/public/images/items/stellar_tera_shard.png index b6625066e16..1d5982f5b94 100644 Binary files a/public/images/items/stellar_tera_shard.png and b/public/images/items/stellar_tera_shard.png differ diff --git a/public/images/items/stone_plate.png b/public/images/items/stone_plate.png index 44653583e60..dfc3a0cd132 100644 Binary files a/public/images/items/stone_plate.png and b/public/images/items/stone_plate.png differ diff --git a/public/images/items/strange_ball.png b/public/images/items/strange_ball.png index 64246f031ee..2ddce33d7ac 100644 Binary files a/public/images/items/strange_ball.png and b/public/images/items/strange_ball.png differ diff --git a/public/images/items/strawberry_sweet.png b/public/images/items/strawberry_sweet.png index b08fece34cc..5df6e1cd8be 100644 Binary files a/public/images/items/strawberry_sweet.png and b/public/images/items/strawberry_sweet.png differ diff --git a/public/images/items/sun_flute.png b/public/images/items/sun_flute.png index 7010c9fefbd..f81d35fde9c 100644 Binary files a/public/images/items/sun_flute.png and b/public/images/items/sun_flute.png differ diff --git a/public/images/items/sun_stone.png b/public/images/items/sun_stone.png index d22b24792fb..33a7e8f8387 100644 Binary files a/public/images/items/sun_stone.png and b/public/images/items/sun_stone.png differ diff --git a/public/images/items/super_exp_charm.png b/public/images/items/super_exp_charm.png index 8697edf4be6..ccd73f558cc 100644 Binary files a/public/images/items/super_exp_charm.png and b/public/images/items/super_exp_charm.png differ diff --git a/public/images/items/super_lure.png b/public/images/items/super_lure.png index 1a80c8ea309..9c2213cd964 100644 Binary files a/public/images/items/super_lure.png and b/public/images/items/super_lure.png differ diff --git a/public/images/items/super_potion.png b/public/images/items/super_potion.png index bfd1868b545..16205cb0fff 100644 Binary files a/public/images/items/super_potion.png and b/public/images/items/super_potion.png differ diff --git a/public/images/items/super_repel.png b/public/images/items/super_repel.png index db09ded8a26..628cdbc5c1d 100644 Binary files a/public/images/items/super_repel.png and b/public/images/items/super_repel.png differ diff --git a/public/images/items/swampertite.png b/public/images/items/swampertite.png index bfcdd99606b..d4d6415f6f4 100644 Binary files a/public/images/items/swampertite.png and b/public/images/items/swampertite.png differ diff --git a/public/images/items/sweet_apple.png b/public/images/items/sweet_apple.png index 5070af6ae64..cfdf79a9eac 100644 Binary files a/public/images/items/sweet_apple.png and b/public/images/items/sweet_apple.png differ diff --git a/public/images/items/syrupy_apple.png b/public/images/items/syrupy_apple.png index 99a0b7b5627..9c9d05e2e0a 100644 Binary files a/public/images/items/syrupy_apple.png and b/public/images/items/syrupy_apple.png differ diff --git a/public/images/items/tart_apple.png b/public/images/items/tart_apple.png index 8f9cf89da9f..ad9a1728bb5 100644 Binary files a/public/images/items/tart_apple.png and b/public/images/items/tart_apple.png differ diff --git a/public/images/items/tera_orb.png b/public/images/items/tera_orb.png index f4b6e47398e..d8720e41669 100644 Binary files a/public/images/items/tera_orb.png and b/public/images/items/tera_orb.png differ diff --git a/public/images/items/thick_club.png b/public/images/items/thick_club.png index a4459aa7701..f15885f0190 100644 Binary files a/public/images/items/thick_club.png and b/public/images/items/thick_club.png differ diff --git a/public/images/items/thunder_stone.png b/public/images/items/thunder_stone.png index 8b853b2f758..9e87909516b 100644 Binary files a/public/images/items/thunder_stone.png and b/public/images/items/thunder_stone.png differ diff --git a/public/images/items/tm_bug.png b/public/images/items/tm_bug.png index 56278cf2f66..229230198c4 100644 Binary files a/public/images/items/tm_bug.png and b/public/images/items/tm_bug.png differ diff --git a/public/images/items/tm_dark.png b/public/images/items/tm_dark.png index 6168cd2f070..6856b1d5444 100644 Binary files a/public/images/items/tm_dark.png and b/public/images/items/tm_dark.png differ diff --git a/public/images/items/tm_dragon.png b/public/images/items/tm_dragon.png index 9e1866cc2d6..62405519132 100644 Binary files a/public/images/items/tm_dragon.png and b/public/images/items/tm_dragon.png differ diff --git a/public/images/items/tm_electric.png b/public/images/items/tm_electric.png index 0610c3f3337..34e4fe8de7b 100644 Binary files a/public/images/items/tm_electric.png and b/public/images/items/tm_electric.png differ diff --git a/public/images/items/tm_fairy.png b/public/images/items/tm_fairy.png index de6335acbc8..056783a8d63 100644 Binary files a/public/images/items/tm_fairy.png and b/public/images/items/tm_fairy.png differ diff --git a/public/images/items/tm_fighting.png b/public/images/items/tm_fighting.png index b9f812767e3..144d75826cd 100644 Binary files a/public/images/items/tm_fighting.png and b/public/images/items/tm_fighting.png differ diff --git a/public/images/items/tm_fire.png b/public/images/items/tm_fire.png index 1de4b7a4a64..ae19e381873 100644 Binary files a/public/images/items/tm_fire.png and b/public/images/items/tm_fire.png differ diff --git a/public/images/items/tm_flying.png b/public/images/items/tm_flying.png index 4d738edb57f..3db06a69e68 100644 Binary files a/public/images/items/tm_flying.png and b/public/images/items/tm_flying.png differ diff --git a/public/images/items/tm_ghost.png b/public/images/items/tm_ghost.png index 71a6b558fae..a7e8928aa7e 100644 Binary files a/public/images/items/tm_ghost.png and b/public/images/items/tm_ghost.png differ diff --git a/public/images/items/tm_grass.png b/public/images/items/tm_grass.png index 6811d354fd9..42f11f590eb 100644 Binary files a/public/images/items/tm_grass.png and b/public/images/items/tm_grass.png differ diff --git a/public/images/items/tm_ground.png b/public/images/items/tm_ground.png index 0408eb71125..ff9dc7c7384 100644 Binary files a/public/images/items/tm_ground.png and b/public/images/items/tm_ground.png differ diff --git a/public/images/items/tm_ice.png b/public/images/items/tm_ice.png index b628d39f801..4edbb447a3e 100644 Binary files a/public/images/items/tm_ice.png and b/public/images/items/tm_ice.png differ diff --git a/public/images/items/tm_normal.png b/public/images/items/tm_normal.png index ab6e5e82729..19afe85d442 100644 Binary files a/public/images/items/tm_normal.png and b/public/images/items/tm_normal.png differ diff --git a/public/images/items/tm_poison.png b/public/images/items/tm_poison.png index f9f31b015dc..83cb4488f33 100644 Binary files a/public/images/items/tm_poison.png and b/public/images/items/tm_poison.png differ diff --git a/public/images/items/tm_psychic.png b/public/images/items/tm_psychic.png index 3c3becc0af2..4296914eda2 100644 Binary files a/public/images/items/tm_psychic.png and b/public/images/items/tm_psychic.png differ diff --git a/public/images/items/tm_rock.png b/public/images/items/tm_rock.png index d05ee8c1a7c..6e13a1835e7 100644 Binary files a/public/images/items/tm_rock.png and b/public/images/items/tm_rock.png differ diff --git a/public/images/items/tm_steel.png b/public/images/items/tm_steel.png index 840caff9ace..32071b0843b 100644 Binary files a/public/images/items/tm_steel.png and b/public/images/items/tm_steel.png differ diff --git a/public/images/items/tm_water.png b/public/images/items/tm_water.png index 2082766777d..85403f20be7 100644 Binary files a/public/images/items/tm_water.png and b/public/images/items/tm_water.png differ diff --git a/public/images/items/toxic_orb.png b/public/images/items/toxic_orb.png index 7fb36db516e..3483c13ba2b 100644 Binary files a/public/images/items/toxic_orb.png and b/public/images/items/toxic_orb.png differ diff --git a/public/images/items/toxic_plate.png b/public/images/items/toxic_plate.png index 8538e9fce2a..efb2cff129c 100644 Binary files a/public/images/items/toxic_plate.png and b/public/images/items/toxic_plate.png differ diff --git a/public/images/items/twisted_spoon.png b/public/images/items/twisted_spoon.png index 54a96de7d03..9bb23b04386 100644 Binary files a/public/images/items/twisted_spoon.png and b/public/images/items/twisted_spoon.png differ diff --git a/public/images/items/tyranitarite.png b/public/images/items/tyranitarite.png index 3d94f05c35f..691f8c6123d 100644 Binary files a/public/images/items/tyranitarite.png and b/public/images/items/tyranitarite.png differ diff --git a/public/images/items/ub.png b/public/images/items/ub.png index 964fb6b25c3..6ad0702223a 100644 Binary files a/public/images/items/ub.png and b/public/images/items/ub.png differ diff --git a/public/images/items/ultra_ribbon.png b/public/images/items/ultra_ribbon.png index 69dc7365bb4..a63ec63e394 100644 Binary files a/public/images/items/ultra_ribbon.png and b/public/images/items/ultra_ribbon.png differ diff --git a/public/images/items/ultranecrozium_z.png b/public/images/items/ultranecrozium_z.png index 208f3fb173d..cdcb29e6c26 100644 Binary files a/public/images/items/ultranecrozium_z.png and b/public/images/items/ultranecrozium_z.png differ diff --git a/public/images/items/unknown.png b/public/images/items/unknown.png index 4e01608daed..2d0637048ae 100644 Binary files a/public/images/items/unknown.png and b/public/images/items/unknown.png differ diff --git a/public/images/items/unremarkable_teacup.png b/public/images/items/unremarkable_teacup.png index fd4298b6a59..340214b6a5c 100644 Binary files a/public/images/items/unremarkable_teacup.png and b/public/images/items/unremarkable_teacup.png differ diff --git a/public/images/items/upgrade.png b/public/images/items/upgrade.png index 38db96a1792..11a7ade4d6a 100644 Binary files a/public/images/items/upgrade.png and b/public/images/items/upgrade.png differ diff --git a/public/images/items/venusaurite.png b/public/images/items/venusaurite.png index b8118a6c02d..845d1cef75a 100644 Binary files a/public/images/items/venusaurite.png and b/public/images/items/venusaurite.png differ diff --git a/public/images/items/water_memory.png b/public/images/items/water_memory.png index 4586a618836..a0cf8b3c5c9 100644 Binary files a/public/images/items/water_memory.png and b/public/images/items/water_memory.png differ diff --git a/public/images/items/water_stone.png b/public/images/items/water_stone.png index ab4543ee61a..fa3d924960b 100644 Binary files a/public/images/items/water_stone.png and b/public/images/items/water_stone.png differ diff --git a/public/images/items/water_tera_shard.png b/public/images/items/water_tera_shard.png index c00c1b5c1cb..eec8caf1245 100644 Binary files a/public/images/items/water_tera_shard.png and b/public/images/items/water_tera_shard.png differ diff --git a/public/images/items/wellspring_mask.png b/public/images/items/wellspring_mask.png index d5546cdb8da..921c71e1493 100644 Binary files a/public/images/items/wellspring_mask.png and b/public/images/items/wellspring_mask.png differ diff --git a/public/images/items/whipped_dream.png b/public/images/items/whipped_dream.png index 94628a443d1..16090ccaac0 100644 Binary files a/public/images/items/whipped_dream.png and b/public/images/items/whipped_dream.png differ diff --git a/public/images/items/white_herb.png b/public/images/items/white_herb.png index 56ca7c6aeb2..829c64f188e 100644 Binary files a/public/images/items/white_herb.png and b/public/images/items/white_herb.png differ diff --git a/public/images/items/wide_lens.png b/public/images/items/wide_lens.png index bf622521a9a..f7dbe9843fa 100644 Binary files a/public/images/items/wide_lens.png and b/public/images/items/wide_lens.png differ diff --git a/public/images/items/wise_glasses.png b/public/images/items/wise_glasses.png index 49a95761afd..b48d2cb3ffd 100644 Binary files a/public/images/items/wise_glasses.png and b/public/images/items/wise_glasses.png differ diff --git a/public/images/items/wl_ability_urge.png b/public/images/items/wl_ability_urge.png index a9eaa834313..b6b2c8bd398 100644 Binary files a/public/images/items/wl_ability_urge.png and b/public/images/items/wl_ability_urge.png differ diff --git a/public/images/items/wl_antidote.png b/public/images/items/wl_antidote.png index dbe0d5b94ea..93e4757938b 100644 Binary files a/public/images/items/wl_antidote.png and b/public/images/items/wl_antidote.png differ diff --git a/public/images/items/wl_awakening.png b/public/images/items/wl_awakening.png index 9a0adcda904..57e83b30cda 100644 Binary files a/public/images/items/wl_awakening.png and b/public/images/items/wl_awakening.png differ diff --git a/public/images/items/wl_burn_heal.png b/public/images/items/wl_burn_heal.png index d2f65e7da4c..3565af12d62 100644 Binary files a/public/images/items/wl_burn_heal.png and b/public/images/items/wl_burn_heal.png differ diff --git a/public/images/items/wl_custom_spliced.png b/public/images/items/wl_custom_spliced.png index 6a0ad4f8349..8aef30edb27 100644 Binary files a/public/images/items/wl_custom_spliced.png and b/public/images/items/wl_custom_spliced.png differ diff --git a/public/images/items/wl_custom_thief.png b/public/images/items/wl_custom_thief.png index cc1302ffb35..de6d62a48bc 100644 Binary files a/public/images/items/wl_custom_thief.png and b/public/images/items/wl_custom_thief.png differ diff --git a/public/images/items/wl_elixir.png b/public/images/items/wl_elixir.png index 29e413aa634..05eb590c484 100644 Binary files a/public/images/items/wl_elixir.png and b/public/images/items/wl_elixir.png differ diff --git a/public/images/items/wl_ether.png b/public/images/items/wl_ether.png index d3c0fe85918..114e8ffc941 100644 Binary files a/public/images/items/wl_ether.png and b/public/images/items/wl_ether.png differ diff --git a/public/images/items/wl_full_heal.png b/public/images/items/wl_full_heal.png index 68b8272c08f..215f9801d65 100644 Binary files a/public/images/items/wl_full_heal.png and b/public/images/items/wl_full_heal.png differ diff --git a/public/images/items/wl_guard_spec.png b/public/images/items/wl_guard_spec.png index b494123e92e..9d22029e927 100644 Binary files a/public/images/items/wl_guard_spec.png and b/public/images/items/wl_guard_spec.png differ diff --git a/public/images/items/wl_hyper_potion.png b/public/images/items/wl_hyper_potion.png index 51e81461da9..1eb075445e4 100644 Binary files a/public/images/items/wl_hyper_potion.png and b/public/images/items/wl_hyper_potion.png differ diff --git a/public/images/items/wl_ice_heal.png b/public/images/items/wl_ice_heal.png index e28f3205a80..9ac297c0e7c 100644 Binary files a/public/images/items/wl_ice_heal.png and b/public/images/items/wl_ice_heal.png differ diff --git a/public/images/items/wl_item_drop.png b/public/images/items/wl_item_drop.png index fe7ffdbdc1f..73425749670 100644 Binary files a/public/images/items/wl_item_drop.png and b/public/images/items/wl_item_drop.png differ diff --git a/public/images/items/wl_item_urge.png b/public/images/items/wl_item_urge.png index 5c291188dee..17a6343058f 100644 Binary files a/public/images/items/wl_item_urge.png and b/public/images/items/wl_item_urge.png differ diff --git a/public/images/items/wl_max_elixir.png b/public/images/items/wl_max_elixir.png index ba900bc2e97..4a33dc853fd 100644 Binary files a/public/images/items/wl_max_elixir.png and b/public/images/items/wl_max_elixir.png differ diff --git a/public/images/items/wl_max_ether.png b/public/images/items/wl_max_ether.png index 3cd58498fa7..d3f69ce053d 100644 Binary files a/public/images/items/wl_max_ether.png and b/public/images/items/wl_max_ether.png differ diff --git a/public/images/items/wl_max_potion.png b/public/images/items/wl_max_potion.png index cf92810943c..6b58c07e86a 100644 Binary files a/public/images/items/wl_max_potion.png and b/public/images/items/wl_max_potion.png differ diff --git a/public/images/items/wl_max_revive.png b/public/images/items/wl_max_revive.png index 12e3b263c21..f2eabaa8d5b 100644 Binary files a/public/images/items/wl_max_revive.png and b/public/images/items/wl_max_revive.png differ diff --git a/public/images/items/wl_paralyze_heal.png b/public/images/items/wl_paralyze_heal.png index 9a741c705d4..8e89e54c156 100644 Binary files a/public/images/items/wl_paralyze_heal.png and b/public/images/items/wl_paralyze_heal.png differ diff --git a/public/images/items/wl_potion.png b/public/images/items/wl_potion.png index 42086fc20ba..619c5d2b014 100644 Binary files a/public/images/items/wl_potion.png and b/public/images/items/wl_potion.png differ diff --git a/public/images/items/wl_reset_urge.png b/public/images/items/wl_reset_urge.png index 25ba0dfcdb9..0d2f94504f0 100644 Binary files a/public/images/items/wl_reset_urge.png and b/public/images/items/wl_reset_urge.png differ diff --git a/public/images/items/wl_revive.png b/public/images/items/wl_revive.png index c0881125c52..c01b5f68853 100644 Binary files a/public/images/items/wl_revive.png and b/public/images/items/wl_revive.png differ diff --git a/public/images/items/wl_super_potion.png b/public/images/items/wl_super_potion.png index da9ccec78ce..eaf60d6c882 100644 Binary files a/public/images/items/wl_super_potion.png and b/public/images/items/wl_super_potion.png differ diff --git a/public/images/items/x_accuracy.png b/public/images/items/x_accuracy.png index d119a75f1bb..e7af52fc684 100644 Binary files a/public/images/items/x_accuracy.png and b/public/images/items/x_accuracy.png differ diff --git a/public/images/items/x_attack.png b/public/images/items/x_attack.png index 36c76da9486..711aca7269c 100644 Binary files a/public/images/items/x_attack.png and b/public/images/items/x_attack.png differ diff --git a/public/images/items/x_defense.png b/public/images/items/x_defense.png index 2eb14b06ffb..ee8d3fa5e2d 100644 Binary files a/public/images/items/x_defense.png and b/public/images/items/x_defense.png differ diff --git a/public/images/items/x_sp_atk.png b/public/images/items/x_sp_atk.png index 772f9fe3315..f0e674e4d45 100644 Binary files a/public/images/items/x_sp_atk.png and b/public/images/items/x_sp_atk.png differ diff --git a/public/images/items/x_sp_def.png b/public/images/items/x_sp_def.png index 8c9baf03a4c..2ab43574af9 100644 Binary files a/public/images/items/x_sp_def.png and b/public/images/items/x_sp_def.png differ diff --git a/public/images/items/x_speed.png b/public/images/items/x_speed.png index cbd1747142f..daebb295d77 100644 Binary files a/public/images/items/x_speed.png and b/public/images/items/x_speed.png differ diff --git a/public/images/items/zap_plate.png b/public/images/items/zap_plate.png index e582b41937f..a966fb76cd3 100644 Binary files a/public/images/items/zap_plate.png and b/public/images/items/zap_plate.png differ diff --git a/public/images/items/zinc.png b/public/images/items/zinc.png index d2602f43328..c1dfd47a9fc 100644 Binary files a/public/images/items/zinc.png and b/public/images/items/zinc.png differ diff --git a/public/images/items/zoom_lens.png b/public/images/items/zoom_lens.png index f46855135bf..30b3ed55bdf 100644 Binary files a/public/images/items/zoom_lens.png and b/public/images/items/zoom_lens.png differ diff --git a/public/images/statuses_ca-ES.png b/public/images/statuses_ca-ES.png index d372b989be9..fe05e243f7a 100644 Binary files a/public/images/statuses_ca-ES.png and b/public/images/statuses_ca-ES.png differ diff --git a/public/images/types_ca-ES.json b/public/images/types_ca-ES.json new file mode 100644 index 00000000000..fa3abaaf259 --- /dev/null +++ b/public/images/types_ca-ES.json @@ -0,0 +1,440 @@ +{ + "textures": [ + { + "image": "types_ca-ES.png", + "format": "RGBA8888", + "size": { + "w": 32, + "h": 280 + }, + "scale": 1, + "frames": [ + { + "filename": "unknown", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + } + }, + { + "filename": "bug", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 14, + "w": 32, + "h": 14 + } + }, + { + "filename": "dark", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 28, + "w": 32, + "h": 14 + } + }, + { + "filename": "dragon", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 42, + "w": 32, + "h": 14 + } + }, + { + "filename": "electric", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 56, + "w": 32, + "h": 14 + } + }, + { + "filename": "fairy", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 70, + "w": 32, + "h": 14 + } + }, + { + "filename": "fighting", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 84, + "w": 32, + "h": 14 + } + }, + { + "filename": "fire", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 98, + "w": 32, + "h": 14 + } + }, + { + "filename": "flying", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 112, + "w": 32, + "h": 14 + } + }, + { + "filename": "ghost", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 126, + "w": 32, + "h": 14 + } + }, + { + "filename": "grass", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 140, + "w": 32, + "h": 14 + } + }, + { + "filename": "ground", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 154, + "w": 32, + "h": 14 + } + }, + { + "filename": "ice", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 168, + "w": 32, + "h": 14 + } + }, + { + "filename": "normal", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 182, + "w": 32, + "h": 14 + } + }, + { + "filename": "poison", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 196, + "w": 32, + "h": 14 + } + }, + { + "filename": "psychic", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 210, + "w": 32, + "h": 14 + } + }, + { + "filename": "rock", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 224, + "w": 32, + "h": 14 + } + }, + { + "filename": "steel", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 238, + "w": 32, + "h": 14 + } + }, + { + "filename": "water", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 252, + "w": 32, + "h": 14 + } + }, + { + "filename": "stellar", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 266, + "w": 32, + "h": 14 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:f14cf47d9a8f1d40c8e03aa6ba00fff3:6fc4227b57a95d429a1faad4280f7ec8:5961efbfbf4c56b8745347e7a663a32f$" + } +} diff --git a/public/images/types_ca-ES.png b/public/images/types_ca-ES.png new file mode 100644 index 00000000000..e85c84ed9c9 Binary files /dev/null and b/public/images/types_ca-ES.png differ diff --git a/public/locales b/public/locales index 6b3f37cb351..cae82762eab 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 6b3f37cb351552721232f4dabefa17bddb5b9004 +Subproject commit cae82762eab25f928500b73e0e9a3e7df1ae6bbe diff --git a/src/@types/DexData.ts b/src/@types/DexData.ts new file mode 100644 index 00000000000..19bb0357471 --- /dev/null +++ b/src/@types/DexData.ts @@ -0,0 +1,16 @@ +/** + * Dex entry for a single Pokemon Species + */ +export interface DexEntry { + seenAttr: bigint; + caughtAttr: bigint; + natureAttr: number; + seenCount: number; + caughtCount: number; + hatchedCount: number; + ivs: number[]; +} + +export interface DexData { + [key: number]: DexEntry; +} diff --git a/src/battle-scene.ts b/src/battle-scene.ts index a6c986d3d0f..5797fda5611 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -72,8 +72,8 @@ import { 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 type { TrainerSlot } from "#app/data/trainer-config"; -import { trainerConfigs } from "#app/data/trainer-config"; +import type { TrainerSlot } from "./enums/trainer-slot"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; import Trainer, { TrainerVariant } from "#app/field/trainer"; import type TrainerData from "#app/system/trainer-data"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; @@ -1371,6 +1371,7 @@ export default class BattleScene extends SceneBase { return Math.max(doubleChance.value, 1); } + // TODO: ...this never actually returns `null`, right? newBattle( waveIndex?: number, battleType?: BattleType, @@ -1402,7 +1403,10 @@ export default class BattleScene extends SceneBase { this.field.add(newTrainer); } } else { - if (!this.gameMode.hasTrainers) { + if ( + !this.gameMode.hasTrainers || + (Overrides.DISABLE_STANDARD_TRAINERS_OVERRIDE && isNullOrUndefined(trainerData)) + ) { newBattleType = BattleType.WILD; } else if (battleType === undefined) { newBattleType = this.gameMode.isWaveTrainer(newWaveIndex, this.arena) ? BattleType.TRAINER : BattleType.WILD; @@ -2720,6 +2724,18 @@ export default class BattleScene extends SceneBase { this.phaseQueue.splice(0, this.phaseQueue.length); } + /** + * Clears all phase-related stuff, including all phase queues, the current and standby phases, and a splice index + */ + clearAllPhases(): void { + for (const queue of [this.phaseQueue, this.phaseQueuePrepend, this.conditionalQueue, this.nextCommandPhaseQueue]) { + queue.splice(0, queue.length); + } + this.currentPhase = null; + this.standbyPhase = null; + this.clearPhaseQueueSplice(); + } + /** * Used by function unshiftPhase(), sets index to start inserting at current length instead of the end of the array, useful if phaseQueuePrepend gets longer with Phases */ diff --git a/src/battle.ts b/src/battle.ts index 5ada921bf5a..367c52568dc 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -5,7 +5,7 @@ import Trainer, { TrainerVariant } from "./field/trainer"; import type { GameMode } from "./game-mode"; import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier"; import type { PokeballType } from "#enums/pokeball"; -import { trainerConfigs } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; import { SpeciesFormKey } from "#enums/species-form-key"; import type { EnemyPokemon, PlayerPokemon, TurnMove } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; diff --git a/src/data/ability.ts b/src/data/ability.ts index 761df44f6d2..f01d0194d54 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -308,7 +308,7 @@ export class ClearWeatherAbAttr extends AbAttr { public override apply(pokemon: Pokemon, passive: boolean, simulated:boolean, cancelled: Utils.BooleanHolder, args: any[]): void { if (!simulated) { - globalScene.arena.trySetWeather(WeatherType.NONE, true); + globalScene.arena.trySetWeather(WeatherType.NONE, pokemon); } } } @@ -334,7 +334,7 @@ export class ClearTerrainAbAttr extends AbAttr { public override apply(pokemon: Pokemon, passive: boolean, simulated:boolean, cancelled: Utils.BooleanHolder, args: any[]): void { if (!simulated) { - globalScene.arena.trySetTerrain(TerrainType.NONE, true, true); + globalScene.arena.trySetTerrain(TerrainType.NONE, true, pokemon); } } } @@ -959,7 +959,7 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr { override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): void { if (!simulated) { - globalScene.arena.trySetTerrain(this.terrainType, true); + globalScene.arena.trySetTerrain(this.terrainType, false, pokemon); } } } @@ -1069,7 +1069,7 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr { } override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void { - attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); + attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), { result: HitResult.INDIRECT }); attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)); } @@ -1131,7 +1131,7 @@ export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr { override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void { if (!simulated) { - globalScene.arena.trySetWeather(this.weatherType, true); + globalScene.arena.trySetWeather(this.weatherType, pokemon); } } } @@ -1290,6 +1290,9 @@ export class MoveEffectChanceMultiplierAbAttr extends AbAttr { * @see {@linkcode applyPreDefend} */ export class IgnoreMoveEffectsAbAttr extends PreDefendAbAttr { + constructor(showAbility: boolean = false) { + super(showAbility); + } override canApplyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move | null, cancelled: Utils.BooleanHolder | null, args: any[]): boolean { return (args[0] as Utils.NumberHolder).value > 0; @@ -1714,6 +1717,62 @@ export class PostAttackAbAttr extends AbAttr { args: any[]): void {} } +/** + * Multiplies a Stat from an ally pokemon's ability. + * @see {@link applyAllyStatMultiplierAbAttrs} + * @see {@link applyAllyStat} + */ +export class AllyStatMultiplierAbAttr extends AbAttr { + private stat: BattleStat; + private multiplier: number; + private ignorable: boolean; + + /** + * @param stat - The stat being modified + * @param multipler - The multiplier to apply to the stat + * @param ignorable - Whether the multiplier can be ignored by mold breaker-like moves and abilities + */ + constructor(stat: BattleStat, multiplier: number, ignorable: boolean = true) { + super(false); + + this.stat = stat; + this.multiplier = multiplier; + this.ignorable = ignorable; + } + + /** + * Multiply a Pokemon's Stat due to an Ally's ability. + * @param _pokemon - The ally {@linkcode Pokemon} with the ability (unused) + * @param passive - unused + * @param _simulated - Whether the ability is being simulated (unused) + * @param _stat - The type of the checked {@linkcode Stat} (unused) + * @param statValue - {@linkcode Utils.NumberHolder} containing the value of the checked stat + * @param _checkedPokemon - The {@linkcode Pokemon} this ability is targeting (unused) + * @param _ignoreAbility - Whether the ability should be ignored if possible + * @param _args - unused + * @returns `true` if this changed the checked stat, `false` otherwise. + */ + applyAllyStat(_pokemon: Pokemon, _passive: boolean, _simulated: boolean, _stat: BattleStat, statValue: Utils.NumberHolder, _checkedPokemon: Pokemon, _ignoreAbility: boolean, _args: any[]) { + statValue.value *= this.multiplier; + } + + /** + * Check if this ability can apply to the checked stat. + * @param pokemon - The ally {@linkcode Pokemon} with the ability (unused) + * @param passive - unused + * @param simulated - Whether the ability is being simulated (unused) + * @param stat - The type of the checked {@linkcode Stat} + * @param statValue - {@linkcode Utils.NumberHolder} containing the value of the checked stat + * @param checkedPokemon - The {@linkcode Pokemon} this ability is targeting (unused) + * @param ignoreAbility - Whether the ability should be ignored if possible + * @param args - unused + * @returns `true` if this can apply to the checked stat, `false` otherwise. + */ + canApplyAllyStat(pokemon: Pokemon, _passive: boolean, simulated: boolean, stat: BattleStat, statValue: Utils.NumberHolder, checkedPokemon: Pokemon, ignoreAbility: boolean, args: any[]): boolean { + return stat === this.stat && !(ignoreAbility && this.ignorable); + } +} + /** * Ability attribute for Gorilla Tactics * @extends PostAttackAbAttr @@ -2488,7 +2547,7 @@ export class PostSummonWeatherChangeAbAttr extends PostSummonAbAttr { override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void { if (!simulated) { - globalScene.arena.trySetWeather(this.weatherType, true); + globalScene.arena.trySetWeather(this.weatherType, pokemon); } } } @@ -2508,7 +2567,7 @@ export class PostSummonTerrainChangeAbAttr extends PostSummonAbAttr { override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void { if (!simulated) { - globalScene.arena.trySetTerrain(this.terrainType, true); + globalScene.arena.trySetTerrain(this.terrainType, false, pokemon); } } } @@ -2891,7 +2950,7 @@ export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr { } if (turnOffWeather) { - globalScene.arena.trySetWeather(WeatherType.NONE, false); + globalScene.arena.trySetWeather(WeatherType.NONE); return true; } @@ -2991,7 +3050,7 @@ export class PreLeaveFieldClearWeatherAbAttr extends PreLeaveFieldAbAttr { */ override applyPreLeaveField(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void { if (!simulated) { - globalScene.arena.trySetWeather(WeatherType.NONE, false); + globalScene.arena.trySetWeather(WeatherType.NONE); } } } @@ -3797,7 +3856,7 @@ export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr { if (!simulated) { const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name; globalScene.queueMessage(i18next.t("abilityTriggers:postWeatherLapseDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName })); - pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / (16 / this.damageFactor)), HitResult.OTHER); + pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / (16 / this.damageFactor)), { result: HitResult.INDIRECT }); } } } @@ -3865,7 +3924,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr { } override canApplyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { - return (pokemon.status !== null) && this.effects.includes(pokemon.status.effect) && !pokemon.isFullHp(); + return !Utils.isNullOrUndefined(pokemon.status) && this.effects.includes(pokemon.status.effect) && !pokemon.isFullHp(); } /** @@ -4089,7 +4148,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr { for (const opp of pokemon.getOpponents()) { if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !opp.switchOutStatus) { if (!simulated) { - opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER); + opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), { result: HitResult.INDIRECT }); globalScene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) })); } } @@ -4108,7 +4167,7 @@ export class FetchBallAbAttr extends PostTurnAbAttr { } override canApplyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { - return !simulated && globalScene.currentBattle.lastUsedPokeball !== null && !!pokemon.isPlayer; + return !simulated && !Utils.isNullOrUndefined(globalScene.currentBattle.lastUsedPokeball) && !!pokemon.isPlayer; } /** @@ -4142,7 +4201,7 @@ export class PostBiomeChangeWeatherChangeAbAttr extends PostBiomeChangeAbAttr { override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): void { if (!simulated) { - globalScene.arena.trySetWeather(this.weatherType, true); + globalScene.arena.trySetWeather(this.weatherType, pokemon); } } } @@ -4162,7 +4221,7 @@ export class PostBiomeChangeTerrainChangeAbAttr extends PostBiomeChangeAbAttr { override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): void { if (!simulated) { - globalScene.arena.trySetTerrain(this.terrainType, true); + globalScene.arena.trySetTerrain(this.terrainType, false, pokemon); } } } @@ -4572,7 +4631,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr { override applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): void { if (!simulated) { - attacker!.damageAndUpdate(Utils.toDmgValue(attacker!.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); + attacker!.damageAndUpdate(Utils.toDmgValue(attacker!.getMaxHp() * (1 / this.damageRatio)), { result: HitResult.INDIRECT }); attacker!.turnData.damageTaken += Utils.toDmgValue(attacker!.getMaxHp() * (1 / this.damageRatio)); } } @@ -4593,7 +4652,7 @@ export class PostFaintHPDamageAbAttr extends PostFaintAbAttr { override applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): void { if (move !== undefined && attacker !== undefined && !simulated) { //If the mon didn't die to indirect damage const damage = pokemon.turnData.attacksReceived[0].damage; - attacker.damageAndUpdate((damage), HitResult.OTHER); + attacker.damageAndUpdate((damage), { result: HitResult.INDIRECT }); attacker.turnData.damageTaken += damage; } } @@ -4716,7 +4775,7 @@ export class ForceSwitchOutImmunityAbAttr extends AbAttr { export class ReduceBerryUseThresholdAbAttr extends AbAttr { constructor() { - super(); + super(false); } override canApply(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { @@ -4994,7 +5053,7 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr { (args[0] as Utils.NumberHolder).value = this.multiplier; pokemon.removeTag(this.tagType); if (this.recoilDamageFunc) { - pokemon.damageAndUpdate(this.recoilDamageFunc(pokemon), HitResult.OTHER, false, false, true, true); + pokemon.damageAndUpdate(this.recoilDamageFunc(pokemon), { result: HitResult.INDIRECT, ignoreSegments: true, ignoreFaintPhase: true }); } } } @@ -5596,6 +5655,30 @@ export function applyStatMultiplierAbAttrs( args, ); } + +/** + * Applies an ally's Stat multiplier attribute + * @param attrType - {@linkcode AllyStatMultiplierAbAttr} should always be AllyStatMultiplierAbAttr for the time being + * @param pokemon - The {@linkcode Pokemon} with the ability + * @param stat - The type of the checked {@linkcode Stat} + * @param statValue - {@linkcode Utils.NumberHolder} containing the value of the checked stat + * @param checkedPokemon - The {@linkcode Pokemon} with the checked stat + * @param ignoreAbility - Whether or not the ability should be ignored by the pokemon or its move. + * @param args - unused + */ +export function applyAllyStatMultiplierAbAttrs(attrType: Constructor, + pokemon: Pokemon, stat: BattleStat, statValue: Utils.NumberHolder, simulated: boolean = false, checkedPokemon: Pokemon, ignoreAbility: boolean, ...args: any[] +): void { + return applyAbAttrsInternal( + attrType, + pokemon, + (attr, passive) => attr.applyAllyStat(pokemon, passive, simulated, stat, statValue, checkedPokemon, ignoreAbility, args), + (attr, passive) => attr.canApplyAllyStat(pokemon, passive, simulated, stat, statValue, checkedPokemon, ignoreAbility, args), + args, + simulated, + ); +} + export function applyPostSetStatusAbAttrs( attrType: Constructor, pokemon: Pokemon, @@ -5608,7 +5691,8 @@ export function applyPostSetStatusAbAttrs( attrType, pokemon, (attr, passive) => attr.applyPostSetStatus(pokemon, sourcePokemon, passive, effect, simulated, args), - (attr, passive) => attr.canApplyPostSetStatus(pokemon, sourcePokemon, passive, effect, simulated, args), args, + (attr, passive) => attr.canApplyPostSetStatus(pokemon, sourcePokemon, passive, effect, simulated, args), + args, simulated, ); } @@ -6439,11 +6523,12 @@ export function initAbilities() { new Ability(Abilities.FLOWER_GIFT, 4) .conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), StatMultiplierAbAttr, Stat.ATK, 1.5) .conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), StatMultiplierAbAttr, Stat.SPDEF, 1.5) + .conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), AllyStatMultiplierAbAttr, Stat.ATK, 1.5) + .conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), AllyStatMultiplierAbAttr, Stat.SPDEF, 1.5) .attr(UncopiableAbilityAbAttr) .attr(NoFusionAbilityAbAttr) .attr(PostSummonFormChangeByWeatherAbAttr, Abilities.FLOWER_GIFT) .attr(PostWeatherChangeFormChangeAbAttr, Abilities.FLOWER_GIFT, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG, WeatherType.HAIL, WeatherType.HEAVY_RAIN, WeatherType.SNOW, WeatherType.RAIN ]) - .partial() // Should also boosts stats of ally .ignorable(), new Ability(Abilities.BAD_DREAMS, 4) .attr(PostTurnHurtIfSleepingAbAttr), @@ -6579,7 +6664,7 @@ export function initAbilities() { .bypassFaint(), new Ability(Abilities.VICTORY_STAR, 5) .attr(StatMultiplierAbAttr, Stat.ACC, 1.1) - .partial(), // Does not boost ally's accuracy + .attr(AllyStatMultiplierAbAttr, Stat.ACC, 1.1, false), new Ability(Abilities.TURBOBLAZE, 5) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTurboblaze", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })) .attr(MoveAbilityBypassAbAttr), diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 276cfa035b8..8f1d6b09a73 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -64,7 +64,7 @@ export abstract class ArenaTag { } } - onOverlap(_arena: Arena): void {} + onOverlap(_arena: Arena, _source: Pokemon | null): void {} lapse(_arena: Arena): boolean { return this.turnCount < 1 || !!--this.turnCount; @@ -706,7 +706,7 @@ export class ArenaTrapTag extends ArenaTag { this.maxLayers = maxLayers; } - onOverlap(arena: Arena): void { + onOverlap(arena: Arena, _source: Pokemon | null): void { if (this.layers < this.maxLayers) { this.layers++; @@ -788,7 +788,7 @@ class SpikesTag extends ArenaTrapTag { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), }), ); - pokemon.damageAndUpdate(damage, HitResult.OTHER); + pokemon.damageAndUpdate(damage, { result: HitResult.INDIRECT }); if (pokemon.turnData) { pokemon.turnData.damageTaken += damage; } @@ -982,7 +982,7 @@ class StealthRockTag extends ArenaTrapTag { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), }), ); - pokemon.damageAndUpdate(damage, HitResult.OTHER); + pokemon.damageAndUpdate(damage, { result: HitResult.INDIRECT }); if (pokemon.turnData) { pokemon.turnData.damageTaken += damage; } @@ -1327,7 +1327,7 @@ class FireGrassPledgeTag extends ArenaTag { globalScene.unshiftPhase( new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.MAGMA_STORM), ); - pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT }); }); return super.lapse(arena); @@ -1427,11 +1427,7 @@ export class SuppressAbilitiesTag extends ArenaTag { public override onAdd(_arena: Arena): void { const pokemon = this.getSourcePokemon(); if (pokemon) { - globalScene.queueMessage( - i18next.t("arenaTag:neutralizingGasOnAdd", { - pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - }), - ); + this.playActivationMessage(pokemon); for (const fieldPokemon of globalScene.getField(true)) { if (fieldPokemon && fieldPokemon.id !== pokemon.id) { @@ -1441,8 +1437,9 @@ export class SuppressAbilitiesTag extends ArenaTag { } } - public override onOverlap(_arena: Arena): void { + public override onOverlap(_arena: Arena, source: Pokemon | null): void { this.sourceCount++; + this.playActivationMessage(source); } public onSourceLeave(arena: Arena): void { @@ -1481,6 +1478,16 @@ export class SuppressAbilitiesTag extends ArenaTag { public isBeingRemoved() { return this.beingRemoved; } + + private playActivationMessage(pokemon: Pokemon | null) { + if (pokemon) { + globalScene.queueMessage( + i18next.t("arenaTag:neutralizingGasOnAdd", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + }), + ); + } + } } // TODO: swap `sourceMove` and `sourceId` and make `sourceMove` an optional parameter diff --git a/src/data/balance/biomes.ts b/src/data/balance/biomes.ts index 71a48162e57..3dff1722af6 100644 --- a/src/data/balance/biomes.ts +++ b/src/data/balance/biomes.ts @@ -1659,7 +1659,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { }, [Biome.GRASS]: { [BiomePoolTier.COMMON]: [ TrainerType.BREEDER, TrainerType.SCHOOL_KID ], - [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER ], + [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER, TrainerType.POKEFAN ], [BiomePoolTier.RARE]: [ TrainerType.BLACK_BELT ], [BiomePoolTier.SUPER_RARE]: [], [BiomePoolTier.ULTRA_RARE]: [], @@ -1680,9 +1680,9 @@ export const biomeTrainerPools: BiomeTrainerPools = { [BiomePoolTier.BOSS_ULTRA_RARE]: [] }, [Biome.METROPOLIS]: { - [BiomePoolTier.COMMON]: [ TrainerType.CLERK, TrainerType.CYCLIST, TrainerType.OFFICER, TrainerType.WAITER ], + [BiomePoolTier.COMMON]: [ TrainerType.BEAUTY, TrainerType.CLERK, TrainerType.CYCLIST, TrainerType.OFFICER, TrainerType.WAITER ], [BiomePoolTier.UNCOMMON]: [ TrainerType.BREEDER, TrainerType.DEPOT_AGENT, TrainerType.GUITARIST ], - [BiomePoolTier.RARE]: [ TrainerType.ARTIST ], + [BiomePoolTier.RARE]: [ TrainerType.ARTIST, TrainerType.RICH_KID ], [BiomePoolTier.SUPER_RARE]: [], [BiomePoolTier.ULTRA_RARE]: [], [BiomePoolTier.BOSS]: [ TrainerType.WHITNEY, TrainerType.NORMAN, TrainerType.IONO, TrainerType.LARRY ], @@ -1702,7 +1702,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { [BiomePoolTier.BOSS_ULTRA_RARE]: [] }, [Biome.SEA]: { - [BiomePoolTier.COMMON]: [ TrainerType.SWIMMER, TrainerType.SAILOR ], + [BiomePoolTier.COMMON]: [ TrainerType.SAILOR, TrainerType.SWIMMER ], [BiomePoolTier.UNCOMMON]: [], [BiomePoolTier.RARE]: [], [BiomePoolTier.SUPER_RARE]: [], @@ -1713,7 +1713,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { [BiomePoolTier.BOSS_ULTRA_RARE]: [] }, [Biome.SWAMP]: { - [BiomePoolTier.COMMON]: [], + [BiomePoolTier.COMMON]: [ TrainerType.PARASOL_LADY ], [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER ], [BiomePoolTier.RARE]: [ TrainerType.BLACK_BELT ], [BiomePoolTier.SUPER_RARE]: [], @@ -1724,7 +1724,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { [BiomePoolTier.BOSS_ULTRA_RARE]: [] }, [Biome.BEACH]: { - [BiomePoolTier.COMMON]: [ TrainerType.FISHERMAN, TrainerType.PARASOL_LADY, TrainerType.SAILOR ], + [BiomePoolTier.COMMON]: [ TrainerType.FISHERMAN, TrainerType.SAILOR ], [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER, TrainerType.BREEDER ], [BiomePoolTier.RARE]: [ TrainerType.BLACK_BELT ], [BiomePoolTier.SUPER_RARE]: [], @@ -1735,7 +1735,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { [BiomePoolTier.BOSS_ULTRA_RARE]: [] }, [Biome.LAKE]: { - [BiomePoolTier.COMMON]: [ TrainerType.BREEDER, TrainerType.FISHERMAN ], + [BiomePoolTier.COMMON]: [ TrainerType.BREEDER, TrainerType.FISHERMAN, TrainerType.PARASOL_LADY ], [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER ], [BiomePoolTier.RARE]: [ TrainerType.BLACK_BELT ], [BiomePoolTier.SUPER_RARE]: [], @@ -1758,7 +1758,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { }, [Biome.MOUNTAIN]: { [BiomePoolTier.COMMON]: [ TrainerType.BACKPACKER, TrainerType.BLACK_BELT, TrainerType.HIKER ], - [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER ], + [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER, TrainerType.PILOT ], [BiomePoolTier.RARE]: [], [BiomePoolTier.SUPER_RARE]: [], [BiomePoolTier.ULTRA_RARE]: [], @@ -1790,7 +1790,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { [BiomePoolTier.BOSS_ULTRA_RARE]: [] }, [Biome.DESERT]: { - [BiomePoolTier.COMMON]: [ TrainerType.SCIENTIST ], + [BiomePoolTier.COMMON]: [ TrainerType.BACKPACKER, TrainerType.SCIENTIST ], [BiomePoolTier.UNCOMMON]: [], [BiomePoolTier.RARE]: [], [BiomePoolTier.SUPER_RARE]: [], @@ -1812,8 +1812,8 @@ export const biomeTrainerPools: BiomeTrainerPools = { [BiomePoolTier.BOSS_ULTRA_RARE]: [] }, [Biome.MEADOW]: { - [BiomePoolTier.COMMON]: [ TrainerType.PARASOL_LADY ], - [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER, TrainerType.BREEDER ], + [BiomePoolTier.COMMON]: [ TrainerType.BEAUTY, TrainerType.MUSICIAN, TrainerType.PARASOL_LADY ], + [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER, TrainerType.BAKER, TrainerType.BREEDER, TrainerType.POKEFAN ], [BiomePoolTier.RARE]: [], [BiomePoolTier.SUPER_RARE]: [], [BiomePoolTier.ULTRA_RARE]: [], @@ -1879,7 +1879,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { }, [Biome.RUINS]: { [BiomePoolTier.COMMON]: [ TrainerType.PSYCHIC, TrainerType.SCIENTIST ], - [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER, TrainerType.BLACK_BELT ], + [BiomePoolTier.UNCOMMON]: [ TrainerType.ACE_TRAINER, TrainerType.BLACK_BELT, TrainerType.HEX_MANIAC ], [BiomePoolTier.RARE]: [], [BiomePoolTier.SUPER_RARE]: [], [BiomePoolTier.ULTRA_RARE]: [], @@ -1967,7 +1967,7 @@ export const biomeTrainerPools: BiomeTrainerPools = { }, [Biome.SLUM]: { [BiomePoolTier.COMMON]: [ TrainerType.BIKER, TrainerType.OFFICER, TrainerType.ROUGHNECK ], - [BiomePoolTier.UNCOMMON]: [ TrainerType.BAKER ], + [BiomePoolTier.UNCOMMON]: [ TrainerType.BAKER, TrainerType.HOOLIGANS ], [BiomePoolTier.RARE]: [], [BiomePoolTier.SUPER_RARE]: [], [BiomePoolTier.ULTRA_RARE]: [], @@ -1988,8 +1988,8 @@ export const biomeTrainerPools: BiomeTrainerPools = { [BiomePoolTier.BOSS_ULTRA_RARE]: [] }, [Biome.ISLAND]: { - [BiomePoolTier.COMMON]: [], - [BiomePoolTier.UNCOMMON]: [], + [BiomePoolTier.COMMON]: [ TrainerType.RICH_KID ], + [BiomePoolTier.UNCOMMON]: [ TrainerType.RICH ], [BiomePoolTier.RARE]: [], [BiomePoolTier.SUPER_RARE]: [], [BiomePoolTier.ULTRA_RARE]: [], @@ -7165,16 +7165,21 @@ export function initBiomes() { [ Biome.MOUNTAIN, BiomePoolTier.COMMON ], [ Biome.CAVE, BiomePoolTier.COMMON ], [ Biome.BADLANDS, BiomePoolTier.COMMON ], - [ Biome.JUNGLE, BiomePoolTier.COMMON ] + [ Biome.JUNGLE, BiomePoolTier.COMMON ], + [ Biome.DESERT, BiomePoolTier.COMMON ] ] ], [ TrainerType.BAKER, [ - [ Biome.SLUM, BiomePoolTier.UNCOMMON ] + [ Biome.SLUM, BiomePoolTier.UNCOMMON ], + [ Biome.MEADOW, BiomePoolTier.UNCOMMON ] ] ], [ TrainerType.BEAUTY, [ + [ Biome.METROPOLIS, BiomePoolTier.COMMON ], + [ Biome.MEADOW, BiomePoolTier.COMMON ], [ Biome.FAIRY_CAVE, BiomePoolTier.COMMON ] - ]], + ] + ], [ TrainerType.BIKER, [ [ Biome.SLUM, BiomePoolTier.COMMON ] ] @@ -7204,7 +7209,8 @@ export function initBiomes() { ], [ TrainerType.CLERK, [ [ Biome.METROPOLIS, BiomePoolTier.COMMON ] - ]], + ] + ], [ TrainerType.CYCLIST, [ [ Biome.PLAINS, BiomePoolTier.UNCOMMON ], [ Biome.METROPOLIS, BiomePoolTier.COMMON ] @@ -7213,18 +7219,23 @@ export function initBiomes() { [ TrainerType.DANCER, []], [ TrainerType.DEPOT_AGENT, [ [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON ] - ]], + ] + ], [ TrainerType.DOCTOR, []], + [ TrainerType.FIREBREATHER, [ + [ Biome.VOLCANO, BiomePoolTier.COMMON ] + ] + ], [ TrainerType.FISHERMAN, [ [ Biome.LAKE, BiomePoolTier.COMMON ], [ Biome.BEACH, BiomePoolTier.COMMON ] ] ], - [ TrainerType.RICH, []], [ TrainerType.GUITARIST, [ [ Biome.METROPOLIS, BiomePoolTier.UNCOMMON ], [ Biome.POWER_PLANT, BiomePoolTier.COMMON ] - ]], + ] + ], [ TrainerType.HARLEQUIN, []], [ TrainerType.HIKER, [ [ Biome.MOUNTAIN, BiomePoolTier.COMMON ], @@ -7232,13 +7243,24 @@ export function initBiomes() { [ Biome.BADLANDS, BiomePoolTier.COMMON ] ] ], - [ TrainerType.HOOLIGANS, []], + [ TrainerType.HOOLIGANS, [ + [ Biome.SLUM, BiomePoolTier.UNCOMMON ] + ] + ], [ TrainerType.HOOPSTER, []], [ TrainerType.INFIELDER, []], [ TrainerType.JANITOR, []], [ TrainerType.LINEBACKER, []], [ TrainerType.MAID, []], - [ TrainerType.MUSICIAN, []], + [ TrainerType.MUSICIAN, [ + [ Biome.MEADOW, BiomePoolTier.COMMON ] + ] + ], + [ TrainerType.HEX_MANIAC, [ + [ Biome.RUINS, BiomePoolTier.UNCOMMON ], + [ Biome.GRAVEYARD, BiomePoolTier.UNCOMMON ] + ] + ], [ TrainerType.NURSERY_AIDE, []], [ TrainerType.OFFICER, [ [ Biome.METROPOLIS, BiomePoolTier.COMMON ], @@ -7247,12 +7269,20 @@ export function initBiomes() { ] ], [ TrainerType.PARASOL_LADY, [ - [ Biome.BEACH, BiomePoolTier.COMMON ], + [ Biome.SWAMP, BiomePoolTier.COMMON ], + [ Biome.LAKE, BiomePoolTier.COMMON ], [ Biome.MEADOW, BiomePoolTier.COMMON ] ] ], - [ TrainerType.PILOT, []], - [ TrainerType.POKEFAN, []], + [ TrainerType.PILOT, [ + [ Biome.MOUNTAIN, BiomePoolTier.UNCOMMON ] + ] + ], + [ TrainerType.POKEFAN, [ + [ Biome.GRASS, BiomePoolTier.UNCOMMON ], + [ Biome.MEADOW, BiomePoolTier.UNCOMMON ] + ] + ], [ TrainerType.PRESCHOOLER, []], [ TrainerType.PSYCHIC, [ [ Biome.GRAVEYARD, BiomePoolTier.COMMON ], @@ -7265,11 +7295,24 @@ export function initBiomes() { [ Biome.JUNGLE, BiomePoolTier.COMMON ] ] ], - [ TrainerType.RICH_KID, []], + [ TrainerType.RICH, [ + [ Biome.ISLAND, BiomePoolTier.UNCOMMON ] + ] + ], + [ TrainerType.RICH_KID, [ + [ Biome.METROPOLIS, BiomePoolTier.RARE ], + [ Biome.ISLAND, BiomePoolTier.COMMON ] + ] + ], [ TrainerType.ROUGHNECK, [ [ Biome.SLUM, BiomePoolTier.COMMON ] ] ], + [ TrainerType.SAILOR, [ + [ Biome.SEA, BiomePoolTier.COMMON ], + [ Biome.BEACH, BiomePoolTier.COMMON ] + ] + ], [ TrainerType.SCIENTIST, [ [ Biome.DESERT, BiomePoolTier.COMMON ], [ Biome.RUINS, BiomePoolTier.COMMON ] @@ -7312,19 +7355,6 @@ export function initBiomes() { [ Biome.TOWN, BiomePoolTier.COMMON ] ] ], - [ TrainerType.HEX_MANIAC, [ - [ Biome.GRAVEYARD, BiomePoolTier.UNCOMMON ] - ] - ], - [ TrainerType.FIREBREATHER, [ - [ Biome.VOLCANO, BiomePoolTier.COMMON ] - ] - ], - [ TrainerType.SAILOR, [ - [ Biome.SEA, BiomePoolTier.COMMON ], - [ Biome.BEACH, BiomePoolTier.COMMON ] - ] - ], [ TrainerType.BROCK, [ [ Biome.CAVE, BiomePoolTier.BOSS ] ] diff --git a/src/data/balance/passives.ts b/src/data/balance/passives.ts index c613be0137b..f7929650e67 100644 --- a/src/data/balance/passives.ts +++ b/src/data/balance/passives.ts @@ -11,418 +11,824 @@ interface StarterPassiveAbilities { export const starterPassiveAbilities: StarterPassiveAbilities = { [Species.BULBASAUR]: { 0: Abilities.GRASSY_SURGE }, + [Species.IVYSAUR]: { 0: Abilities.GRASSY_SURGE }, + [Species.VENUSAUR]: { 0: Abilities.GRASSY_SURGE, 1: Abilities.SEED_SOWER, 2: Abilities.FLOWER_VEIL }, [Species.CHARMANDER]: { 0: Abilities.BEAST_BOOST }, + [Species.CHARMELEON]: { 0: Abilities.BEAST_BOOST }, + [Species.CHARIZARD]: { 0: Abilities.BEAST_BOOST, 1: Abilities.LEVITATE, 2: Abilities.INTIMIDATE, 3: Abilities.UNNERVE }, [Species.SQUIRTLE]: { 0: Abilities.DAUNTLESS_SHIELD }, - [Species.CATERPIE]: { 0: Abilities.MAGICIAN }, - [Species.WEEDLE]: { 0: Abilities.TINTED_LENS }, + [Species.WARTORTLE]: { 0: Abilities.DAUNTLESS_SHIELD }, + [Species.BLASTOISE]: { 0: Abilities.DAUNTLESS_SHIELD, 1: Abilities.BULLETPROOF, 2: Abilities.BULLETPROOF }, + [Species.CATERPIE]: { 0: Abilities.GLUTTONY }, + [Species.METAPOD]: { 0: Abilities.STURDY }, + [Species.BUTTERFREE]: { 0: Abilities.MAGICIAN, 1: Abilities.MAGICIAN }, + [Species.WEEDLE]: { 0: Abilities.POISON_TOUCH }, + [Species.KAKUNA]: { 0: Abilities.STURDY }, + [Species.BEEDRILL]: { 0: Abilities.ADAPTABILITY, 1: Abilities.TINTED_LENS }, [Species.PIDGEY]: { 0: Abilities.SHEER_FORCE }, + [Species.PIDGEOTTO]: { 0: Abilities.SHEER_FORCE }, + [Species.PIDGEOT]: { 0: Abilities.SHEER_FORCE, 1: Abilities.SHEER_FORCE }, [Species.RATTATA]: { 0: Abilities.STRONG_JAW }, + [Species.RATICATE]: { 0: Abilities.STRONG_JAW }, [Species.SPEAROW]: { 0: Abilities.MOXIE }, + [Species.FEAROW]: { 0: Abilities.MOXIE }, [Species.EKANS]: { 0: Abilities.REGENERATOR }, + [Species.ARBOK]: { 0: Abilities.REGENERATOR }, [Species.SANDSHREW]: { 0: Abilities.TOUGH_CLAWS }, + [Species.SANDSLASH]: { 0: Abilities.TOUGH_CLAWS }, [Species.NIDORAN_F]: { 0: Abilities.FLARE_BOOST }, + [Species.NIDORINA]: { 0: Abilities.FLARE_BOOST }, + [Species.NIDOQUEEN]: { 0: Abilities.FLARE_BOOST }, [Species.NIDORAN_M]: { 0: Abilities.GUTS }, + [Species.NIDORINO]: { 0: Abilities.GUTS }, + [Species.NIDOKING]: { 0: Abilities.GUTS }, [Species.VULPIX]: { 0: Abilities.FUR_COAT }, + [Species.NINETALES]: { 0: Abilities.FUR_COAT }, [Species.ZUBAT]: { 0: Abilities.INTIMIDATE }, + [Species.GOLBAT]: { 0: Abilities.INTIMIDATE }, + [Species.CROBAT]: { 0: Abilities.INTIMIDATE }, [Species.ODDISH]: { 0: Abilities.TRIAGE }, + [Species.GLOOM]: { 0: Abilities.TRIAGE }, + [Species.VILEPLUME]: { 0: Abilities.TRIAGE }, + [Species.BELLOSSOM]: { 0: Abilities.TRIAGE }, [Species.PARAS]: { 0: Abilities.TRIAGE }, - [Species.VENONAT]: { 0: Abilities.SIMPLE }, + [Species.PARASECT]: { 0: Abilities.TRIAGE }, + [Species.VENONAT]: { 0: Abilities.FLUFFY }, + [Species.VENOMOTH]: { 0: Abilities.SIMPLE }, [Species.DIGLETT]: { 0: Abilities.STURDY }, - [Species.MEOWTH]: { 0: Abilities.TOUGH_CLAWS }, + [Species.DUGTRIO]: { 0: Abilities.STURDY }, + [Species.MEOWTH]: { 0: Abilities.TOUGH_CLAWS, 1: Abilities.TOUGH_CLAWS }, + [Species.PERSIAN]: { 0: Abilities.TOUGH_CLAWS }, [Species.PSYDUCK]: { 0: Abilities.SIMPLE }, + [Species.GOLDUCK]: { 0: Abilities.SIMPLE }, [Species.MANKEY]: { 0: Abilities.IRON_FIST }, + [Species.PRIMEAPE]: { 0: Abilities.IRON_FIST }, + [Species.ANNIHILAPE]: { 0: Abilities.IRON_FIST }, [Species.GROWLITHE]: { 0: Abilities.FLUFFY }, + [Species.ARCANINE]: { 0: Abilities.FLUFFY }, [Species.POLIWAG]: { 0: Abilities.NO_GUARD }, - [Species.ABRA]: { 0: Abilities.MAGICIAN }, + [Species.POLIWHIRL]: { 0: Abilities.NO_GUARD }, + [Species.POLIWRATH]: { 0: Abilities.NO_GUARD }, + [Species.POLITOED]: { 0: Abilities.NO_GUARD }, + [Species.ABRA]: { 0: Abilities.COMATOSE }, + [Species.KADABRA]: { 0: Abilities.MAGICIAN }, + [Species.ALAKAZAM]: { 0: Abilities.MAGICIAN, 1: Abilities.MAGICIAN }, [Species.MACHOP]: { 0: Abilities.QUICK_FEET }, + [Species.MACHOKE]: { 0: Abilities.QUICK_FEET }, + [Species.MACHAMP]: { 0: Abilities.QUICK_FEET, 1: Abilities.QUICK_FEET }, [Species.BELLSPROUT]: { 0: Abilities.FLOWER_GIFT }, + [Species.WEEPINBELL]: { 0: Abilities.FLOWER_GIFT }, + [Species.VICTREEBEL]: { 0: Abilities.FLOWER_GIFT }, [Species.TENTACOOL]: { 0: Abilities.TOXIC_CHAIN }, + [Species.TENTACRUEL]: { 0: Abilities.TOXIC_CHAIN }, [Species.GEODUDE]: { 0: Abilities.DRY_SKIN }, + [Species.GRAVELER]: { 0: Abilities.DRY_SKIN }, + [Species.GOLEM]: { 0: Abilities.DRY_SKIN }, [Species.PONYTA]: { 0: Abilities.MAGIC_GUARD }, + [Species.RAPIDASH]: { 0: Abilities.MAGIC_GUARD }, [Species.SLOWPOKE]: { 0: Abilities.UNAWARE }, + [Species.SLOWBRO]: { 0: Abilities.UNAWARE, 1: Abilities.REGENERATOR }, + [Species.SLOWKING]: { 0: Abilities.UNAWARE }, [Species.MAGNEMITE]: { 0: Abilities.LEVITATE }, + [Species.MAGNETON]: { 0: Abilities.LEVITATE }, + [Species.MAGNEZONE]: { 0: Abilities.LEVITATE }, [Species.FARFETCHD]: { 0: Abilities.SNIPER }, [Species.DODUO]: { 0: Abilities.PARENTAL_BOND }, + [Species.DODRIO]: { 0: Abilities.PARENTAL_BOND }, [Species.SEEL]: { 0: Abilities.WATER_BUBBLE }, + [Species.DEWGONG]: { 0: Abilities.WATER_BUBBLE }, [Species.GRIMER]: { 0: Abilities.WATER_ABSORB }, - [Species.SHELLDER]: { 0: Abilities.ICE_SCALES }, + [Species.MUK]: { 0: Abilities.WATER_ABSORB }, + [Species.SHELLDER]: { 0: Abilities.STURDY }, + [Species.CLOYSTER]: { 0: Abilities.ICE_SCALES }, [Species.GASTLY]: { 0: Abilities.SHADOW_SHIELD }, + [Species.HAUNTER]: { 0: Abilities.SHADOW_SHIELD }, + [Species.GENGAR]: { 0: Abilities.SHADOW_SHIELD, 1: Abilities.UNNERVE, 2: Abilities.GLUTTONY }, [Species.ONIX]: { 0: Abilities.ROCKY_PAYLOAD }, + [Species.STEELIX]: { 0: Abilities.ROCKY_PAYLOAD, 1: Abilities.SAND_SPIT }, [Species.DROWZEE]: { 0: Abilities.MAGICIAN }, + [Species.HYPNO]: { 0: Abilities.MAGICIAN }, [Species.KRABBY]: { 0: Abilities.UNBURDEN }, + [Species.KINGLER]: { 0: Abilities.UNBURDEN, 1: Abilities.UNBURDEN }, [Species.VOLTORB]: { 0: Abilities.TRANSISTOR }, + [Species.ELECTRODE]: { 0: Abilities.TRANSISTOR }, [Species.EXEGGCUTE]: { 0: Abilities.RIPEN }, + [Species.EXEGGUTOR]: { 0: Abilities.RIPEN }, + [Species.ALOLA_EXEGGUTOR]: { 0: Abilities.UNBURDEN }, [Species.CUBONE]: { 0: Abilities.PARENTAL_BOND }, + [Species.MAROWAK]: { 0: Abilities.PARENTAL_BOND }, + [Species.ALOLA_MAROWAK]: { 0: Abilities.PARENTAL_BOND }, [Species.LICKITUNG]: { 0: Abilities.CHEEK_POUCH }, - [Species.KOFFING]: { 0: Abilities.PARENTAL_BOND }, - [Species.RHYHORN]: { 0: Abilities.FILTER }, + [Species.LICKILICKY]: { 0: Abilities.CHEEK_POUCH }, + [Species.KOFFING]: { 0: Abilities.WHITE_SMOKE }, + [Species.WEEZING]: { 0: Abilities.PARENTAL_BOND }, + [Species.GALAR_WEEZING]: { 0: Abilities.PARENTAL_BOND }, + [Species.RHYHORN]: { 0: Abilities.SOLID_ROCK }, + [Species.RHYDON]: { 0: Abilities.SOLID_ROCK }, + [Species.RHYPERIOR]: { 0: Abilities.FILTER }, [Species.TANGELA]: { 0: Abilities.SEED_SOWER }, - [Species.KANGASKHAN]: { 0: Abilities.TECHNICIAN }, + [Species.TANGROWTH]: { 0: Abilities.SEED_SOWER }, + [Species.KANGASKHAN]: { 0: Abilities.TECHNICIAN, 1: Abilities.TECHNICIAN }, [Species.HORSEA]: { 0: Abilities.DRAGONS_MAW }, + [Species.SEADRA]: { 0: Abilities.DRAGONS_MAW }, + [Species.KINGDRA]: { 0: Abilities.MULTISCALE }, [Species.GOLDEEN]: { 0: Abilities.MULTISCALE }, + [Species.SEAKING]: { 0: Abilities.MULTISCALE }, [Species.STARYU]: { 0: Abilities.REGENERATOR }, + [Species.STARMIE]: { 0: Abilities.REGENERATOR }, [Species.SCYTHER]: { 0: Abilities.TINTED_LENS }, - [Species.PINSIR]: { 0: Abilities.TINTED_LENS }, + [Species.SCIZOR]: { 0: Abilities.TOUGH_CLAWS, 1: Abilities.TOUGH_CLAWS }, + [Species.KLEAVOR]: { 0: Abilities.WEAK_ARMOR }, + [Species.PINSIR]: { 0: Abilities.TINTED_LENS, 1: Abilities.MOLD_BREAKER }, [Species.TAUROS]: { 0: Abilities.STAMINA }, [Species.MAGIKARP]: { 0: Abilities.MULTISCALE }, - [Species.LAPRAS]: { 0: Abilities.LIGHTNING_ROD }, + [Species.GYARADOS]: { 0: Abilities.MULTISCALE, 1: Abilities.MULTISCALE }, + [Species.LAPRAS]: { 0: Abilities.LIGHTNING_ROD, 1: Abilities.FILTER }, [Species.DITTO]: { 0: Abilities.ADAPTABILITY }, - [Species.EEVEE]: { 0: Abilities.PICKUP }, - [Species.PORYGON]: { 0: Abilities.PROTEAN }, + [Species.EEVEE]: { 0: Abilities.PICKUP, 1: Abilities.PICKUP, 2: Abilities.FLUFFY }, + [Species.VAPOREON]: { 0: Abilities.REGENERATOR }, + [Species.JOLTEON]: { 0: Abilities.TRANSISTOR }, + [Species.FLAREON]: { 0: Abilities.FUR_COAT }, + [Species.ESPEON]: { 0: Abilities.MAGICIAN }, + [Species.UMBREON]: { 0: Abilities.TOXIC_CHAIN }, + [Species.LEAFEON]: { 0: Abilities.GRASSY_SURGE }, + [Species.GLACEON]: { 0: Abilities.SNOW_WARNING }, + [Species.SYLVEON]: { 0: Abilities.COMPETITIVE }, + [Species.PORYGON]: { 0: Abilities.LEVITATE }, + [Species.PORYGON2]: { 0: Abilities.LEVITATE }, + [Species.PORYGON_Z]: { 0: Abilities.PROTEAN }, [Species.OMANYTE]: { 0: Abilities.STURDY }, + [Species.OMASTAR]: { 0: Abilities.STURDY }, [Species.KABUTO]: { 0: Abilities.TOUGH_CLAWS }, - [Species.AERODACTYL]: { 0: Abilities.ORICHALCUM_PULSE }, + [Species.KABUTOPS]: { 0: Abilities.TOUGH_CLAWS }, + [Species.AERODACTYL]: { 0: Abilities.INTIMIDATE, 1: Abilities.DELTA_STREAM }, [Species.ARTICUNO]: { 0: Abilities.SNOW_WARNING }, [Species.ZAPDOS]: { 0: Abilities.DRIZZLE }, [Species.MOLTRES]: { 0: Abilities.DROUGHT }, - [Species.DRATINI]: { 0: Abilities.AERILATE }, - [Species.MEWTWO]: { 0: Abilities.NEUROFORCE }, + [Species.DRATINI]: { 0: Abilities.MULTISCALE }, + [Species.DRAGONAIR]: { 0: Abilities.MULTISCALE }, + [Species.DRAGONITE]: { 0: Abilities.AERILATE }, + [Species.MEWTWO]: { 0: Abilities.NEUROFORCE, 1: Abilities.NEUROFORCE, 2: Abilities.NEUROFORCE }, [Species.MEW]: { 0: Abilities.PROTEAN }, [Species.CHIKORITA]: { 0: Abilities.THICK_FAT }, + [Species.BAYLEEF]: { 0: Abilities.THICK_FAT }, + [Species.MEGANIUM]: { 0: Abilities.THICK_FAT }, [Species.CYNDAQUIL]: { 0: Abilities.DROUGHT }, + [Species.QUILAVA]: { 0: Abilities.DROUGHT }, + [Species.TYPHLOSION]: { 0: Abilities.DROUGHT }, + [Species.HISUI_TYPHLOSION]: { 0: Abilities.DROUGHT }, [Species.TOTODILE]: { 0: Abilities.TOUGH_CLAWS }, + [Species.CROCONAW]: { 0: Abilities.TOUGH_CLAWS }, + [Species.FERALIGATR]: { 0: Abilities.TOUGH_CLAWS }, [Species.SENTRET]: { 0: Abilities.PICKUP }, + [Species.FURRET]: { 0: Abilities.PICKUP }, [Species.HOOTHOOT]: { 0: Abilities.AERILATE }, + [Species.NOCTOWL]: { 0: Abilities.AERILATE }, [Species.LEDYBA]: { 0: Abilities.PRANKSTER }, + [Species.LEDIAN]: { 0: Abilities.PRANKSTER }, [Species.SPINARAK]: { 0: Abilities.PRANKSTER }, + [Species.ARIADOS]: { 0: Abilities.PRANKSTER }, [Species.CHINCHOU]: { 0: Abilities.REGENERATOR }, - [Species.PICHU]: { 0: Abilities.ELECTRIC_SURGE }, - [Species.CLEFFA]: { 0: Abilities.ANALYTIC }, + [Species.LANTURN]: { 0: Abilities.REGENERATOR }, + [Species.PICHU]: { 0: Abilities.ELECTRIC_SURGE, 1: Abilities.STURDY }, + [Species.PIKACHU]: { 0: Abilities.ELECTRIC_SURGE, 1: Abilities.STURDY, 2: Abilities.COSTAR, 3: Abilities.IRON_FIST, 4: Abilities.QUEENLY_MAJESTY, 5: Abilities.MISTY_SURGE, 6: Abilities.TINTED_LENS, 7: Abilities.LIBERO, 8: Abilities.THICK_FAT }, + [Species.RAICHU]: { 0: Abilities.ELECTRIC_SURGE }, + [Species.ALOLA_RAICHU]: { 0: Abilities.ELECTRIC_SURGE }, + [Species.CLEFFA]: { 0: Abilities.PRANKSTER }, + [Species.CLEFAIRY]: { 0: Abilities.PRANKSTER }, + [Species.CLEFABLE]: { 0: Abilities.ANALYTIC }, [Species.IGGLYBUFF]: { 0: Abilities.HUGE_POWER }, + [Species.JIGGLYPUFF]: { 0: Abilities.HUGE_POWER }, + [Species.WIGGLYTUFF]: { 0: Abilities.HUGE_POWER }, [Species.TOGEPI]: { 0: Abilities.PIXILATE }, - [Species.NATU]: { 0: Abilities.SHEER_FORCE }, + [Species.TOGETIC]: { 0: Abilities.PIXILATE }, + [Species.TOGEKISS]: { 0: Abilities.PIXILATE }, + [Species.NATU]: { 0: Abilities.TINTED_LENS }, + [Species.XATU]: { 0: Abilities.SHEER_FORCE }, [Species.MAREEP]: { 0: Abilities.ELECTROMORPHOSIS }, - [Species.HOPPIP]: { 0: Abilities.FLUFFY }, + [Species.FLAAFFY]: { 0: Abilities.ELECTROMORPHOSIS }, + [Species.AMPHAROS]: { 0: Abilities.ELECTROMORPHOSIS, 1: Abilities.ELECTROMORPHOSIS }, + [Species.HOPPIP]: { 0: Abilities.WIND_RIDER }, + [Species.SKIPLOOM]: { 0: Abilities.WIND_RIDER }, + [Species.JUMPLUFF]: { 0: Abilities.FLUFFY }, [Species.AIPOM]: { 0: Abilities.SCRAPPY }, + [Species.AMBIPOM]: { 0: Abilities.SCRAPPY }, [Species.SUNKERN]: { 0: Abilities.DROUGHT }, - [Species.YANMA]: { 0: Abilities.SHEER_FORCE }, - [Species.WOOPER]: { 0: Abilities.COMATOSE }, + [Species.SUNFLORA]: { 0: Abilities.DROUGHT }, + [Species.YANMA]: { 0: Abilities.TECHNICIAN }, + [Species.YANMEGA]: { 0: Abilities.SHEER_FORCE }, + [Species.WOOPER]: { 0: Abilities.WATER_VEIL }, + [Species.QUAGSIRE]: { 0: Abilities.COMATOSE }, [Species.MURKROW]: { 0: Abilities.DARK_AURA }, + [Species.HONCHKROW]: { 0: Abilities.DARK_AURA }, [Species.MISDREAVUS]: { 0: Abilities.BEADS_OF_RUIN }, - [Species.UNOWN]: { 0: Abilities.PICKUP }, + [Species.MISMAGIUS]: { 0: Abilities.BEADS_OF_RUIN }, + [Species.UNOWN]: { 0: Abilities.ADAPTABILITY, 1: Abilities.BEAST_BOOST, 2: Abilities.CONTRARY, 3: Abilities.DAZZLING, 4: Abilities.EMERGENCY_EXIT, 5: Abilities.FRIEND_GUARD, 6: Abilities.GOOD_AS_GOLD, 7: Abilities.HONEY_GATHER, 8: Abilities.IMPOSTER, 9: Abilities.JUSTIFIED, 10: Abilities.KLUTZ, 11: Abilities.LIBERO, 12: Abilities.MOODY, 13: Abilities.NEUTRALIZING_GAS, 14: Abilities.OPPORTUNIST, 15: Abilities.PICKUP, 16: Abilities.QUICK_DRAW, 17: Abilities.RUN_AWAY, 18: Abilities.SIMPLE, 19: Abilities.TRACE, 20: Abilities.UNNERVE, 21: Abilities.VICTORY_STAR, 22: Abilities.WANDERING_SPIRIT, 23: Abilities.FAIRY_AURA, 24: Abilities.DARK_AURA, 25: Abilities.AURA_BREAK, 26: Abilities.PURE_POWER, 27: Abilities.UNAWARE }, [Species.GIRAFARIG]: { 0: Abilities.PARENTAL_BOND }, - [Species.PINECO]: { 0: Abilities.IRON_BARBS }, + [Species.FARIGIRAF]: { 0: Abilities.PARENTAL_BOND }, + [Species.PINECO]: { 0: Abilities.ROUGH_SKIN }, + [Species.FORRETRESS]: { 0: Abilities.IRON_BARBS }, [Species.DUNSPARCE]: { 0: Abilities.UNAWARE }, - [Species.GLIGAR]: { 0: Abilities.TOXIC_BOOST }, + [Species.DUDUNSPARCE]: { 0: Abilities.UNAWARE }, + [Species.GLIGAR]: { 0: Abilities.POISON_TOUCH }, + [Species.GLISCOR]: { 0: Abilities.TOXIC_BOOST }, [Species.SNUBBULL]: { 0: Abilities.PIXILATE }, + [Species.GRANBULL]: { 0: Abilities.PIXILATE }, [Species.QWILFISH]: { 0: Abilities.TOXIC_DEBRIS }, [Species.SHUCKLE]: { 0: Abilities.HARVEST }, - [Species.HERACROSS]: { 0: Abilities.TECHNICIAN }, + [Species.HERACROSS]: { 0: Abilities.TECHNICIAN, 1: Abilities.TECHNICIAN }, [Species.SNEASEL]: { 0: Abilities.TOUGH_CLAWS }, - [Species.TEDDIURSA]: { 0: Abilities.THICK_FAT }, - [Species.SLUGMA]: { 0: Abilities.DESOLATE_LAND }, - [Species.SWINUB]: { 0: Abilities.SLUSH_RUSH }, + [Species.WEAVILE]: { 0: Abilities.TOUGH_CLAWS }, + [Species.TEDDIURSA]: { 0: Abilities.RUN_AWAY }, + [Species.URSARING]: { 0: Abilities.THICK_FAT }, + [Species.URSALUNA]: { 0: Abilities.THICK_FAT }, + [Species.SLUGMA]: { 0: Abilities.DROUGHT }, + [Species.MAGCARGO]: { 0: Abilities.DESOLATE_LAND }, + [Species.SWINUB]: { 0: Abilities.UNAWARE }, + [Species.PILOSWINE]: { 0: Abilities.UNAWARE }, + [Species.MAMOSWINE]: { 0: Abilities.SLUSH_RUSH }, [Species.CORSOLA]: { 0: Abilities.STORM_DRAIN }, [Species.REMORAID]: { 0: Abilities.SIMPLE }, + [Species.OCTILLERY]: { 0: Abilities.SIMPLE }, [Species.DELIBIRD]: { 0: Abilities.HUGE_POWER }, [Species.SKARMORY]: { 0: Abilities.LIGHTNING_ROD }, - [Species.HOUNDOUR]: { 0: Abilities.LIGHTNING_ROD }, - [Species.PHANPY]: { 0: Abilities.SPEED_BOOST }, + [Species.HOUNDOUR]: { 0: Abilities.BALL_FETCH }, + [Species.HOUNDOOM]: { 0: Abilities.LIGHTNING_ROD, 1: Abilities.LIGHTNING_ROD }, + [Species.PHANPY]: { 0: Abilities.STURDY }, + [Species.DONPHAN]: { 0: Abilities.SPEED_BOOST }, [Species.STANTLER]: { 0: Abilities.SPEED_BOOST }, + [Species.WYRDEER]: { 0: Abilities.SPEED_BOOST }, [Species.SMEARGLE]: { 0: Abilities.PRANKSTER }, - [Species.TYROGUE]: { 0: Abilities.MOXIE }, + [Species.TYROGUE]: { 0: Abilities.DEFIANT }, + [Species.HITMONLEE]: { 0: Abilities.SHEER_FORCE }, + [Species.HITMONCHAN]: { 0: Abilities.MOXIE }, + [Species.HITMONTOP]: { 0: Abilities.SPEED_BOOST }, [Species.SMOOCHUM]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.JYNX]: { 0: Abilities.PSYCHIC_SURGE }, [Species.ELEKID]: { 0: Abilities.SHEER_FORCE }, + [Species.ELECTABUZZ]: { 0: Abilities.SHEER_FORCE }, + [Species.ELECTIVIRE]: { 0: Abilities.SHEER_FORCE }, [Species.MAGBY]: { 0: Abilities.SHEER_FORCE }, + [Species.MAGMAR]: { 0: Abilities.SHEER_FORCE }, + [Species.MAGMORTAR]: { 0: Abilities.SHEER_FORCE }, [Species.MILTANK]: { 0: Abilities.STAMINA }, [Species.RAIKOU]: { 0: Abilities.BEAST_BOOST }, [Species.ENTEI]: { 0: Abilities.BEAST_BOOST }, [Species.SUICUNE]: { 0: Abilities.BEAST_BOOST }, - [Species.LARVITAR]: { 0: Abilities.SOLID_ROCK }, + [Species.LARVITAR]: { 0: Abilities.SOLID_ROCK, 1: Abilities.SOLID_ROCK }, [Species.LUGIA]: { 0: Abilities.DELTA_STREAM }, [Species.HO_OH]: { 0: Abilities.MAGIC_GUARD }, [Species.CELEBI]: { 0: Abilities.PSYCHIC_SURGE }, [Species.TREECKO]: { 0: Abilities.TINTED_LENS }, + [Species.GROVYLE]: { 0: Abilities.TINTED_LENS }, + [Species.SCEPTILE]: { 0: Abilities.TINTED_LENS, 1: Abilities.TINTED_LENS }, [Species.TORCHIC]: { 0: Abilities.DEFIANT }, - [Species.MUDKIP]: { 0: Abilities.DRIZZLE }, + [Species.COMBUSKEN]: { 0: Abilities.DEFIANT }, + [Species.BLAZIKEN]: { 0: Abilities.DEFIANT, 1: Abilities.DEFIANT }, + [Species.MUDKIP]: { 0: Abilities.REGENERATOR }, + [Species.MARSHTOMP]: { 0: Abilities.REGENERATOR }, + [Species.SWAMPERT]: { 0: Abilities.REGENERATOR, 1: Abilities.DRIZZLE }, [Species.POOCHYENA]: { 0: Abilities.TOUGH_CLAWS }, + [Species.MIGHTYENA]: { 0: Abilities.TOUGH_CLAWS }, [Species.ZIGZAGOON]: { 0: Abilities.RUN_AWAY }, - [Species.WURMPLE]: { 0: Abilities.SIMPLE }, + [Species.LINOONE]: { 0: Abilities.RUN_AWAY }, + [Species.WURMPLE]: { 0: Abilities.GLUTTONY }, + [Species.SILCOON]: { 0: Abilities.STURDY }, + [Species.BEAUTIFLY]: { 0: Abilities.SIMPLE }, + [Species.CASCOON]: { 0: Abilities.STURDY }, + [Species.DUSTOX]: { 0: Abilities.SIMPLE }, [Species.LOTAD]: { 0: Abilities.DRIZZLE }, - [Species.SEEDOT]: { 0: Abilities.SHARPNESS }, + [Species.LOMBRE]: { 0: Abilities.DRIZZLE }, + [Species.LUDICOLO]: { 0: Abilities.DRIZZLE }, + [Species.SEEDOT]: { 0: Abilities.STURDY }, + [Species.NUZLEAF]: { 0: Abilities.SHARPNESS }, + [Species.SHIFTRY]: { 0: Abilities.SHARPNESS }, [Species.TAILLOW]: { 0: Abilities.AERILATE }, - [Species.WINGULL]: { 0: Abilities.SWIFT_SWIM }, - [Species.RALTS]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.SWELLOW]: { 0: Abilities.AERILATE }, + [Species.WINGULL]: { 0: Abilities.DRIZZLE }, + [Species.PELIPPER]: { 0: Abilities.SWIFT_SWIM }, + [Species.RALTS]: { 0: Abilities.NEUROFORCE }, + [Species.KIRLIA]: { 0: Abilities.NEUROFORCE }, + [Species.GARDEVOIR]: { 0: Abilities.NEUROFORCE, 1: Abilities.PSYCHIC_SURGE }, + [Species.GALLADE]: { 0: Abilities.NEUROFORCE, 1: Abilities.SHARPNESS }, [Species.SURSKIT]: { 0: Abilities.WATER_BUBBLE }, + [Species.MASQUERAIN]: { 0: Abilities.WATER_BUBBLE }, [Species.SHROOMISH]: { 0: Abilities.GUTS }, + [Species.BRELOOM]: { 0: Abilities.GUTS }, [Species.SLAKOTH]: { 0: Abilities.GUTS }, - [Species.NINCADA]: { 0: Abilities.MAGIC_GUARD }, + [Species.VIGOROTH]: { 0: Abilities.GUTS }, + [Species.SLAKING]: { 0: Abilities.GUTS }, + [Species.NINCADA]: { 0: Abilities.PICKUP }, + [Species.NINJASK]: { 0: Abilities.TECHNICIAN }, + [Species.SHEDINJA]: { 0: Abilities.MAGIC_GUARD }, [Species.WHISMUR]: { 0: Abilities.PUNK_ROCK }, + [Species.LOUDRED]: { 0: Abilities.PUNK_ROCK }, + [Species.EXPLOUD]: { 0: Abilities.PUNK_ROCK }, [Species.MAKUHITA]: { 0: Abilities.STAMINA }, + [Species.HARIYAMA]: { 0: Abilities.STAMINA }, [Species.AZURILL]: { 0: Abilities.MISTY_SURGE }, - [Species.NOSEPASS]: { 0: Abilities.LEVITATE }, + [Species.MARILL]: { 0: Abilities.MISTY_SURGE }, + [Species.AZUMARILL]: { 0: Abilities.MISTY_SURGE }, + [Species.NOSEPASS]: { 0: Abilities.SOLID_ROCK }, + [Species.PROBOPASS]: { 0: Abilities.LEVITATE }, [Species.SKITTY]: { 0: Abilities.SCRAPPY }, - [Species.SABLEYE]: { 0: Abilities.UNNERVE }, - [Species.MAWILE]: { 0: Abilities.UNNERVE }, + [Species.DELCATTY]: { 0: Abilities.SCRAPPY }, + [Species.SABLEYE]: { 0: Abilities.UNNERVE, 1: Abilities.UNNERVE }, + [Species.MAWILE]: { 0: Abilities.ADAPTABILITY, 1: Abilities.INTIMIDATE }, [Species.ARON]: { 0: Abilities.EARTH_EATER }, + [Species.LAIRON]: { 0: Abilities.EARTH_EATER }, + [Species.AGGRON]: { 0: Abilities.EARTH_EATER, 1: Abilities.ROCKY_PAYLOAD }, [Species.MEDITITE]: { 0: Abilities.MINDS_EYE }, - [Species.ELECTRIKE]: { 0: Abilities.FLASH_FIRE }, + [Species.MEDICHAM]: { 0: Abilities.MINDS_EYE, 1: Abilities.MINDS_EYE }, + [Species.ELECTRIKE]: { 0: Abilities.BALL_FETCH }, + [Species.MANECTRIC]: { 0: Abilities.FLASH_FIRE, 1: Abilities.FLASH_FIRE }, [Species.PLUSLE]: { 0: Abilities.POWER_SPOT }, [Species.MINUN]: { 0: Abilities.POWER_SPOT }, [Species.VOLBEAT]: { 0: Abilities.HONEY_GATHER }, [Species.ILLUMISE]: { 0: Abilities.HONEY_GATHER }, [Species.GULPIN]: { 0: Abilities.EARTH_EATER }, + [Species.SWALOT]: { 0: Abilities.EARTH_EATER }, [Species.CARVANHA]: { 0: Abilities.SHEER_FORCE }, + [Species.SHARPEDO]: { 0: Abilities.SHEER_FORCE, 1: Abilities.SPEED_BOOST }, [Species.WAILMER]: { 0: Abilities.LEVITATE }, - [Species.NUMEL]: { 0: Abilities.FUR_COAT }, + [Species.WAILORD]: { 0: Abilities.LEVITATE }, + [Species.NUMEL]: { 0: Abilities.SOLID_ROCK }, + [Species.CAMERUPT]: { 0: Abilities.FUR_COAT, 1: Abilities.STAMINA }, [Species.TORKOAL]: { 0: Abilities.ANALYTIC }, [Species.SPOINK]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.GRUMPIG]: { 0: Abilities.PSYCHIC_SURGE }, [Species.SPINDA]: { 0: Abilities.SIMPLE }, [Species.TRAPINCH]: { 0: Abilities.ADAPTABILITY }, + [Species.VIBRAVA]: { 0: Abilities.ADAPTABILITY }, + [Species.FLYGON]: { 0: Abilities.ADAPTABILITY }, [Species.CACNEA]: { 0: Abilities.SAND_RUSH }, + [Species.CACTURNE]: { 0: Abilities.SAND_RUSH }, [Species.SWABLU]: { 0: Abilities.FLUFFY }, + [Species.ALTARIA]: { 0: Abilities.FLUFFY, 1: Abilities.FLUFFY }, [Species.ZANGOOSE]: { 0: Abilities.POISON_HEAL }, [Species.SEVIPER]: { 0: Abilities.MULTISCALE }, [Species.LUNATONE]: { 0: Abilities.SHADOW_SHIELD }, [Species.SOLROCK]: { 0: Abilities.DROUGHT }, [Species.BARBOACH]: { 0: Abilities.SIMPLE }, + [Species.WHISCASH]: { 0: Abilities.SIMPLE }, [Species.CORPHISH]: { 0: Abilities.TOUGH_CLAWS }, + [Species.CRAWDAUNT]: { 0: Abilities.TOUGH_CLAWS }, [Species.BALTOY]: { 0: Abilities.WELL_BAKED_BODY }, + [Species.CLAYDOL]: { 0: Abilities.WELL_BAKED_BODY }, [Species.LILEEP]: { 0: Abilities.SEED_SOWER }, + [Species.CRADILY]: { 0: Abilities.SEED_SOWER }, [Species.ANORITH]: { 0: Abilities.WATER_ABSORB }, - [Species.FEEBAS]: { 0: Abilities.MAGIC_GUARD }, - [Species.CASTFORM]: { 0: Abilities.ADAPTABILITY }, + [Species.ARMALDO]: { 0: Abilities.WATER_ABSORB }, + [Species.FEEBAS]: { 0: Abilities.MULTISCALE }, + [Species.MILOTIC]: { 0: Abilities.MAGIC_GUARD }, + [Species.CASTFORM]: { 0: Abilities.ADAPTABILITY, 1: Abilities.ADAPTABILITY, 2: Abilities.ADAPTABILITY, 3: Abilities.ADAPTABILITY }, [Species.KECLEON]: { 0: Abilities.ADAPTABILITY }, [Species.SHUPPET]: { 0: Abilities.SHADOW_SHIELD }, + [Species.BANETTE]: { 0: Abilities.SHADOW_SHIELD, 1: Abilities.SHADOW_SHIELD }, [Species.DUSKULL]: { 0: Abilities.UNNERVE }, + [Species.DUSCLOPS]: { 0: Abilities.UNNERVE }, + [Species.DUSKNOIR]: { 0: Abilities.UNNERVE }, [Species.TROPIUS]: { 0: Abilities.RIPEN }, - [Species.ABSOL]: { 0: Abilities.SHARPNESS }, + [Species.ABSOL]: { 0: Abilities.SHARPNESS, 1: Abilities.SHARPNESS }, [Species.WYNAUT]: { 0: Abilities.STURDY }, + [Species.WOBBUFFET]: { 0: Abilities.STURDY }, [Species.SNORUNT]: { 0: Abilities.SNOW_WARNING }, + [Species.GLALIE]: { 0: Abilities.SNOW_WARNING, 1: Abilities.SNOW_WARNING }, + [Species.FROSLASS]: { 0: Abilities.SNOW_WARNING }, [Species.SPHEAL]: { 0: Abilities.UNAWARE }, - [Species.CLAMPERL]: { 0: Abilities.ARENA_TRAP }, + [Species.SEALEO]: { 0: Abilities.UNAWARE }, + [Species.WALREIN]: { 0: Abilities.UNAWARE }, + [Species.CLAMPERL]: { 0: Abilities.DAUNTLESS_SHIELD }, + [Species.GOREBYSS]: { 0: Abilities.ARENA_TRAP }, + [Species.HUNTAIL]: { 0: Abilities.ARENA_TRAP }, [Species.RELICANTH]: { 0: Abilities.PRIMORDIAL_SEA }, [Species.LUVDISC]: { 0: Abilities.MULTISCALE }, - [Species.BAGON]: { 0: Abilities.MOLD_BREAKER }, + [Species.BAGON]: { 0: Abilities.INTIMIDATE }, + [Species.SHELGON]: { 0: Abilities.ANGER_SHELL }, + [Species.SALAMENCE]: { 0: Abilities.GALE_WINGS, 1: Abilities.ROCK_HEAD }, [Species.BELDUM]: { 0: Abilities.LEVITATE }, + [Species.METANG]: { 0: Abilities.LEVITATE }, + [Species.METAGROSS]: { 0: Abilities.LEVITATE, 1: Abilities.FULL_METAL_BODY }, [Species.REGIROCK]: { 0: Abilities.SAND_STREAM }, [Species.REGICE]: { 0: Abilities.SNOW_WARNING }, [Species.REGISTEEL]: { 0: Abilities.STEELY_SPIRIT }, - [Species.LATIAS]: { 0: Abilities.PRISM_ARMOR }, - [Species.LATIOS]: { 0: Abilities.TINTED_LENS }, - [Species.KYOGRE]: { 0: Abilities.MOLD_BREAKER }, - [Species.GROUDON]: { 0: Abilities.TURBOBLAZE }, - [Species.RAYQUAZA]: { 0: Abilities.UNNERVE }, + [Species.LATIAS]: { 0: Abilities.SPEED_BOOST, 1: Abilities.PRISM_ARMOR }, + [Species.LATIOS]: { 0: Abilities.SPEED_BOOST, 1: Abilities.TINTED_LENS }, + [Species.KYOGRE]: { 0: Abilities.MOLD_BREAKER, 1: Abilities.TERAVOLT }, + [Species.GROUDON]: { 0: Abilities.MOLD_BREAKER, 1: Abilities.TURBOBLAZE }, + [Species.RAYQUAZA]: { 0: Abilities.UNNERVE, 1: Abilities.UNNERVE }, [Species.JIRACHI]: { 0: Abilities.COMATOSE }, - [Species.DEOXYS]: { 0: Abilities.PROTEAN }, + [Species.DEOXYS]: { 0: Abilities.PROTEAN, 1: Abilities.ADAPTABILITY, 2: Abilities.REGENERATOR, 3: Abilities.SHADOW_SHIELD }, - [Species.TURTWIG]: { 0: Abilities.THICK_FAT }, - [Species.CHIMCHAR]: { 0: Abilities.BEAST_BOOST }, - [Species.PIPLUP]: { 0: Abilities.DRIZZLE }, + [Species.TURTWIG]: { 0: Abilities.SOLID_ROCK }, + [Species.GROTLE]: { 0: Abilities.SOLID_ROCK }, + [Species.TORTERRA]: { 0: Abilities.THICK_FAT }, + [Species.CHIMCHAR]: { 0: Abilities.UNNERVE }, + [Species.MONFERNO]: { 0: Abilities.UNNERVE }, + [Species.INFERNAPE]: { 0: Abilities.BEAST_BOOST }, + [Species.PIPLUP]: { 0: Abilities.CUTE_CHARM }, + [Species.PRINPLUP]: { 0: Abilities.DRIZZLE }, + [Species.EMPOLEON]: { 0: Abilities.DRIZZLE }, [Species.STARLY]: { 0: Abilities.ROCK_HEAD }, + [Species.STARAVIA]: { 0: Abilities.ROCK_HEAD }, + [Species.STARAPTOR]: { 0: Abilities.ROCK_HEAD }, [Species.BIDOOF]: { 0: Abilities.SAP_SIPPER }, - [Species.KRICKETOT]: { 0: Abilities.SHARPNESS }, + [Species.BIBAREL]: { 0: Abilities.SAP_SIPPER }, + [Species.KRICKETOT]: { 0: Abilities.HONEY_GATHER }, + [Species.KRICKETUNE]: { 0: Abilities.SHARPNESS }, [Species.SHINX]: { 0: Abilities.SPEED_BOOST }, - [Species.BUDEW]: { 0: Abilities.GRASSY_SURGE }, + [Species.LUXIO]: { 0: Abilities.SPEED_BOOST }, + [Species.LUXRAY]: { 0: Abilities.SPEED_BOOST }, + [Species.BUDEW]: { 0: Abilities.SEED_SOWER }, + [Species.ROSELIA]: { 0: Abilities.GRASSY_SURGE }, + [Species.ROSERADE]: { 0: Abilities.GRASSY_SURGE }, [Species.CRANIDOS]: { 0: Abilities.ROCK_HEAD }, + [Species.RAMPARDOS]: { 0: Abilities.ROCK_HEAD }, [Species.SHIELDON]: { 0: Abilities.EARTH_EATER }, - [Species.BURMY]: { 0: Abilities.STURDY }, - [Species.COMBEE]: { 0: Abilities.INTIMIDATE }, + [Species.BASTIODON]: { 0: Abilities.EARTH_EATER }, + [Species.BURMY]: { 0: Abilities.STURDY, 1: Abilities.STURDY, 2: Abilities.STURDY }, + [Species.WORMADAM]: { 0: Abilities.STURDY, 1: Abilities.STURDY, 2: Abilities.STURDY }, + [Species.MOTHIM]: { 0: Abilities.SPEED_BOOST }, + [Species.COMBEE]: { 0: Abilities.RUN_AWAY }, + [Species.VESPIQUEN]: { 0: Abilities.INTIMIDATE }, [Species.PACHIRISU]: { 0: Abilities.HONEY_GATHER }, [Species.BUIZEL]: { 0: Abilities.MOXIE }, - [Species.CHERUBI]: { 0: Abilities.ORICHALCUM_PULSE }, - [Species.SHELLOS]: { 0: Abilities.REGENERATOR }, + [Species.FLOATZEL]: { 0: Abilities.MOXIE }, + [Species.CHERUBI]: { 0: Abilities.DROUGHT }, + [Species.CHERRIM]: { 0: Abilities.ORICHALCUM_PULSE, 1: Abilities.ORICHALCUM_PULSE }, + [Species.SHELLOS]: { 0: Abilities.REGENERATOR, 1: Abilities.REGENERATOR }, + [Species.GASTRODON]: { 0: Abilities.REGENERATOR, 1: Abilities.REGENERATOR }, [Species.DRIFLOON]: { 0: Abilities.MAGIC_GUARD }, + [Species.DRIFBLIM]: { 0: Abilities.MAGIC_GUARD }, [Species.BUNEARY]: { 0: Abilities.ADAPTABILITY }, + [Species.LOPUNNY]: { 0: Abilities.ADAPTABILITY, 1: Abilities.ADAPTABILITY }, [Species.GLAMEOW]: { 0: Abilities.INTIMIDATE }, + [Species.PURUGLY]: { 0: Abilities.INTIMIDATE }, [Species.CHINGLING]: { 0: Abilities.PUNK_ROCK }, + [Species.CHIMECHO]: { 0: Abilities.PUNK_ROCK }, [Species.STUNKY]: { 0: Abilities.NEUTRALIZING_GAS }, + [Species.SKUNTANK]: { 0: Abilities.NEUTRALIZING_GAS }, [Species.BRONZOR]: { 0: Abilities.MIRROR_ARMOR }, + [Species.BRONZONG]: { 0: Abilities.MIRROR_ARMOR }, [Species.BONSLY]: { 0: Abilities.SAP_SIPPER }, + [Species.SUDOWOODO]: { 0: Abilities.SAP_SIPPER }, [Species.MIME_JR]: { 0: Abilities.PRANKSTER }, - [Species.HAPPINY]: { 0: Abilities.FUR_COAT }, + [Species.MR_MIME]: { 0: Abilities.PRANKSTER }, + [Species.GALAR_MR_MIME]: { 0: Abilities.PRANKSTER }, + [Species.MR_RIME]: { 0: Abilities.PRANKSTER }, + [Species.HAPPINY]: { 0: Abilities.HOSPITALITY }, + [Species.CHANSEY]: { 0: Abilities.FRIEND_GUARD }, + [Species.BLISSEY]: { 0: Abilities.FUR_COAT }, [Species.CHATOT]: { 0: Abilities.PUNK_ROCK }, [Species.SPIRITOMB]: { 0: Abilities.VESSEL_OF_RUIN }, - [Species.GIBLE]: { 0: Abilities.SAND_STREAM }, - [Species.MUNCHLAX]: { 0: Abilities.RIPEN }, + [Species.GIBLE]: { 0: Abilities.ARENA_TRAP }, + [Species.GABITE]: { 0: Abilities.ARENA_TRAP }, + [Species.GARCHOMP]: { 0: Abilities.ARENA_TRAP, 1: Abilities.SAND_RUSH }, + [Species.MUNCHLAX]: { 0: Abilities.CHEEK_POUCH }, + [Species.SNORLAX]: { 0: Abilities.CHEEK_POUCH, 1: Abilities.RIPEN }, [Species.RIOLU]: { 0: Abilities.MINDS_EYE }, + [Species.LUCARIO]: { 0: Abilities.MINDS_EYE, 1: Abilities.MINDS_EYE }, [Species.HIPPOPOTAS]: { 0: Abilities.UNAWARE }, + [Species.HIPPOWDON]: { 0: Abilities.UNAWARE }, [Species.SKORUPI]: { 0: Abilities.SUPER_LUCK }, + [Species.DRAPION]: { 0: Abilities.SUPER_LUCK }, [Species.CROAGUNK]: { 0: Abilities.MOXIE }, + [Species.TOXICROAK]: { 0: Abilities.MOXIE }, [Species.CARNIVINE]: { 0: Abilities.ARENA_TRAP }, [Species.FINNEON]: { 0: Abilities.WATER_BUBBLE }, + [Species.LUMINEON]: { 0: Abilities.WATER_BUBBLE }, [Species.MANTYKE]: { 0: Abilities.UNAWARE }, - [Species.SNOVER]: { 0: Abilities.GRASSY_SURGE }, - [Species.ROTOM]: { 0: Abilities.HADRON_ENGINE }, + [Species.MANTINE]: { 0: Abilities.UNAWARE }, + [Species.SNOVER]: { 0: Abilities.SLUSH_RUSH }, + [Species.ABOMASNOW]: { 0: Abilities.SLUSH_RUSH, 1: Abilities.SEED_SOWER }, + [Species.ROTOM]: { 0: Abilities.HADRON_ENGINE, 1: Abilities.HADRON_ENGINE, 2: Abilities.HADRON_ENGINE, 3: Abilities.HADRON_ENGINE, 4: Abilities.HADRON_ENGINE, 5: Abilities.HADRON_ENGINE }, [Species.UXIE]: { 0: Abilities.UNNERVE }, [Species.MESPRIT]: { 0: Abilities.MOODY }, [Species.AZELF]: { 0: Abilities.NEUROFORCE }, - [Species.DIALGA]: { 0: Abilities.BERSERK }, - [Species.PALKIA]: { 0: Abilities.BERSERK }, + [Species.DIALGA]: { 0: Abilities.BERSERK, 1: Abilities.BERSERK }, + [Species.PALKIA]: { 0: Abilities.BERSERK, 1: Abilities.BERSERK }, [Species.HEATRAN]: { 0: Abilities.EARTH_EATER }, [Species.REGIGIGAS]: { 0: Abilities.SCRAPPY }, - [Species.GIRATINA]: { 0: Abilities.SHADOW_SHIELD }, + [Species.GIRATINA]: { 0: Abilities.SHADOW_SHIELD, 1: Abilities.SHADOW_SHIELD }, [Species.CRESSELIA]: { 0: Abilities.SHADOW_SHIELD }, [Species.PHIONE]: { 0: Abilities.SIMPLE }, [Species.MANAPHY]: { 0: Abilities.PRIMORDIAL_SEA }, [Species.DARKRAI]: { 0: Abilities.UNNERVE }, - [Species.SHAYMIN]: { 0: Abilities.WIND_RIDER }, - [Species.ARCEUS]: { 0: Abilities.ADAPTABILITY }, + [Species.SHAYMIN]: { 0: Abilities.GRASSY_SURGE, 1: Abilities.DELTA_STREAM }, + [Species.ARCEUS]: { 0: Abilities.ADAPTABILITY, 1: Abilities.ADAPTABILITY, 2: Abilities.ADAPTABILITY, 3: Abilities.ADAPTABILITY, 4: Abilities.ADAPTABILITY, 5: Abilities.ADAPTABILITY, 6: Abilities.ADAPTABILITY, 7: Abilities.ADAPTABILITY, 8: Abilities.ADAPTABILITY, 9: Abilities.ADAPTABILITY, 10: Abilities.ADAPTABILITY, 11: Abilities.ADAPTABILITY, 12: Abilities.ADAPTABILITY, 13: Abilities.ADAPTABILITY, 14: Abilities.ADAPTABILITY, 15: Abilities.ADAPTABILITY, 16: Abilities.ADAPTABILITY, 17: Abilities.ADAPTABILITY }, [Species.VICTINI]: { 0: Abilities.SHEER_FORCE }, [Species.SNIVY]: { 0: Abilities.MULTISCALE }, - [Species.TEPIG]: { 0: Abilities.ROCK_HEAD }, - [Species.OSHAWOTT]: { 0: Abilities.INTREPID_SWORD }, + [Species.SERVINE]: { 0: Abilities.MULTISCALE }, + [Species.SERPERIOR]: { 0: Abilities.MULTISCALE }, + [Species.TEPIG]: { 0: Abilities.GLUTTONY }, + [Species.PIGNITE]: { 0: Abilities.ROCK_HEAD }, + [Species.EMBOAR]: { 0: Abilities.ROCK_HEAD }, + [Species.OSHAWOTT]: { 0: Abilities.LONG_REACH }, + [Species.DEWOTT]: { 0: Abilities.LONG_REACH }, + [Species.SAMUROTT]: { 0: Abilities.LIGHTNING_ROD }, + [Species.HISUI_SAMUROTT]: { 0: Abilities.MOLD_BREAKER }, [Species.PATRAT]: { 0: Abilities.NO_GUARD }, - [Species.LILLIPUP]: { 0: Abilities.FUR_COAT }, + [Species.WATCHOG]: { 0: Abilities.NO_GUARD }, + [Species.LILLIPUP]: { 0: Abilities.BALL_FETCH }, + [Species.HERDIER]: { 0: Abilities.FUR_COAT }, + [Species.STOUTLAND]: { 0: Abilities.FUR_COAT }, [Species.PURRLOIN]: { 0: Abilities.PICKUP }, + [Species.LIEPARD]: { 0: Abilities.PICKUP }, [Species.PANSAGE]: { 0: Abilities.WELL_BAKED_BODY }, + [Species.SIMISAGE]: { 0: Abilities.WELL_BAKED_BODY }, [Species.PANSEAR]: { 0: Abilities.WATER_ABSORB }, + [Species.SIMISEAR]: { 0: Abilities.WATER_ABSORB }, [Species.PANPOUR]: { 0: Abilities.SAP_SIPPER }, + [Species.SIMIPOUR]: { 0: Abilities.SAP_SIPPER }, [Species.MUNNA]: { 0: Abilities.NEUTRALIZING_GAS }, + [Species.MUSHARNA]: { 0: Abilities.NEUTRALIZING_GAS }, [Species.PIDOVE]: { 0: Abilities.SNIPER }, + [Species.TRANQUILL]: { 0: Abilities.SNIPER }, + [Species.UNFEZANT]: { 0: Abilities.SNIPER }, [Species.BLITZLE]: { 0: Abilities.ELECTRIC_SURGE }, + [Species.ZEBSTRIKA]: { 0: Abilities.ELECTRIC_SURGE }, [Species.ROGGENROLA]: { 0: Abilities.SOLID_ROCK }, + [Species.BOLDORE]: { 0: Abilities.SOLID_ROCK }, + [Species.GIGALITH]: { 0: Abilities.SOLID_ROCK }, [Species.WOOBAT]: { 0: Abilities.OPPORTUNIST }, + [Species.SWOOBAT]: { 0: Abilities.OPPORTUNIST }, [Species.DRILBUR]: { 0: Abilities.STURDY }, - [Species.AUDINO]: { 0: Abilities.FRIEND_GUARD }, + [Species.EXCADRILL]: { 0: Abilities.STURDY }, + [Species.AUDINO]: { 0: Abilities.FRIEND_GUARD, 1: Abilities.FAIRY_AURA }, [Species.TIMBURR]: { 0: Abilities.ROCKY_PAYLOAD }, + [Species.GURDURR]: { 0: Abilities.ROCKY_PAYLOAD }, + [Species.CONKELDURR]: { 0: Abilities.ROCKY_PAYLOAD }, [Species.TYMPOLE]: { 0: Abilities.POISON_HEAL }, + [Species.PALPITOAD]: { 0: Abilities.POISON_HEAL }, + [Species.SEISMITOAD]: { 0: Abilities.POISON_HEAL }, [Species.THROH]: { 0: Abilities.STAMINA }, [Species.SAWK]: { 0: Abilities.SCRAPPY }, - [Species.SEWADDLE]: { 0: Abilities.SHARPNESS }, + [Species.SEWADDLE]: { 0: Abilities.SHIELD_DUST }, + [Species.SWADLOON]: { 0: Abilities.SHIELD_DUST }, + [Species.LEAVANNY]: { 0: Abilities.SHARPNESS }, [Species.VENIPEDE]: { 0: Abilities.STAMINA }, + [Species.WHIRLIPEDE]: { 0: Abilities.STAMINA }, + [Species.SCOLIPEDE]: { 0: Abilities.STAMINA }, [Species.COTTONEE]: { 0: Abilities.FLUFFY }, + [Species.WHIMSICOTT]: { 0: Abilities.FLUFFY }, [Species.PETILIL]: { 0: Abilities.FLOWER_VEIL }, - [Species.BASCULIN]: { 0: Abilities.SUPREME_OVERLORD }, + [Species.LILLIGANT]: { 0: Abilities.GRASSY_SURGE }, + [Species.HISUI_LILLIGANT]: { 0: Abilities.FLOWER_VEIL }, + [Species.BASCULIN]: { 0: Abilities.ROCK_HEAD, 1: Abilities.RECKLESS, 2: Abilities.SUPREME_OVERLORD }, + [Species.BASCULEGION]: { 0: Abilities.SUPREME_OVERLORD, 1: Abilities.SUPREME_OVERLORD }, [Species.SANDILE]: { 0: Abilities.TOUGH_CLAWS }, + [Species.KROKOROK]: { 0: Abilities.TOUGH_CLAWS }, + [Species.KROOKODILE]: { 0: Abilities.TOUGH_CLAWS }, [Species.DARUMAKA]: { 0: Abilities.GORILLA_TACTICS }, + [Species.DARMANITAN]: { 0: Abilities.GORILLA_TACTICS, 1: Abilities.SOLID_ROCK }, [Species.MARACTUS]: { 0: Abilities.WELL_BAKED_BODY }, [Species.DWEBBLE]: { 0: Abilities.ROCKY_PAYLOAD }, + [Species.CRUSTLE]: { 0: Abilities.ROCKY_PAYLOAD }, [Species.SCRAGGY]: { 0: Abilities.PROTEAN }, + [Species.SCRAFTY]: { 0: Abilities.PROTEAN }, [Species.SIGILYPH]: { 0: Abilities.FLARE_BOOST }, [Species.YAMASK]: { 0: Abilities.PURIFYING_SALT }, + [Species.COFAGRIGUS]: { 0: Abilities.PURIFYING_SALT }, [Species.TIRTOUGA]: { 0: Abilities.WATER_ABSORB }, + [Species.CARRACOSTA]: { 0: Abilities.WATER_ABSORB }, [Species.ARCHEN]: { 0: Abilities.MULTISCALE }, + [Species.ARCHEOPS]: { 0: Abilities.MULTISCALE }, [Species.TRUBBISH]: { 0: Abilities.NEUTRALIZING_GAS }, + [Species.GARBODOR]: { 0: Abilities.NEUTRALIZING_GAS, 1: Abilities.NEUTRALIZING_GAS }, [Species.ZORUA]: { 0: Abilities.DARK_AURA }, + [Species.ZOROARK]: { 0: Abilities.DARK_AURA }, [Species.MINCCINO]: { 0: Abilities.FUR_COAT }, + [Species.CINCCINO]: { 0: Abilities.FUR_COAT }, [Species.GOTHITA]: { 0: Abilities.UNNERVE }, + [Species.GOTHORITA]: { 0: Abilities.UNNERVE }, + [Species.GOTHITELLE]: { 0: Abilities.UNNERVE }, [Species.SOLOSIS]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.DUOSION]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.REUNICLUS]: { 0: Abilities.PSYCHIC_SURGE }, [Species.DUCKLETT]: { 0: Abilities.DRIZZLE }, + [Species.SWANNA]: { 0: Abilities.DRIZZLE }, [Species.VANILLITE]: { 0: Abilities.SLUSH_RUSH }, - [Species.DEERLING]: { 0: Abilities.FUR_COAT }, + [Species.VANILLISH]: { 0: Abilities.SLUSH_RUSH }, + [Species.VANILLUXE]: { 0: Abilities.SLUSH_RUSH }, + [Species.DEERLING]: { 0: Abilities.FLOWER_VEIL, 1: Abilities.CUD_CHEW, 2: Abilities.HARVEST, 3: Abilities.FUR_COAT }, + [Species.SAWSBUCK]: { 0: Abilities.FLOWER_VEIL, 1: Abilities.CUD_CHEW, 2: Abilities.HARVEST, 3: Abilities.FUR_COAT }, [Species.EMOLGA]: { 0: Abilities.SERENE_GRACE }, [Species.KARRABLAST]: { 0: Abilities.QUICK_DRAW }, - [Species.FOONGUS]: { 0: Abilities.THICK_FAT }, + [Species.ESCAVALIER]: { 0: Abilities.QUICK_DRAW }, + [Species.FOONGUS]: { 0: Abilities.MYCELIUM_MIGHT }, + [Species.AMOONGUSS]: { 0: Abilities.THICK_FAT }, [Species.FRILLISH]: { 0: Abilities.POISON_HEAL }, + [Species.JELLICENT]: { 0: Abilities.POISON_HEAL }, [Species.ALOMOMOLA]: { 0: Abilities.MULTISCALE }, [Species.JOLTIK]: { 0: Abilities.TRANSISTOR }, + [Species.GALVANTULA]: { 0: Abilities.TRANSISTOR }, [Species.FERROSEED]: { 0: Abilities.ROUGH_SKIN }, + [Species.FERROTHORN]: { 0: Abilities.ROUGH_SKIN }, [Species.KLINK]: { 0: Abilities.STEELY_SPIRIT }, + [Species.KLANG]: { 0: Abilities.STEELY_SPIRIT }, + [Species.KLINKLANG]: { 0: Abilities.STEELY_SPIRIT }, [Species.TYNAMO]: { 0: Abilities.POISON_HEAL }, + [Species.EELEKTRIK]: { 0: Abilities.POISON_HEAL }, + [Species.EELEKTROSS]: { 0: Abilities.POISON_HEAL }, [Species.ELGYEM]: { 0: Abilities.BEADS_OF_RUIN }, + [Species.BEHEEYEM]: { 0: Abilities.BEADS_OF_RUIN }, [Species.LITWICK]: { 0: Abilities.SHADOW_TAG }, + [Species.LAMPENT]: { 0: Abilities.SHADOW_TAG }, + [Species.CHANDELURE]: { 0: Abilities.SHADOW_TAG }, [Species.AXEW]: { 0: Abilities.DRAGONS_MAW }, + [Species.FRAXURE]: { 0: Abilities.DRAGONS_MAW }, + [Species.HAXORUS]: { 0: Abilities.DRAGONS_MAW }, [Species.CUBCHOO]: { 0: Abilities.FUR_COAT }, + [Species.BEARTIC]: { 0: Abilities.FUR_COAT }, [Species.CRYOGONAL]: { 0: Abilities.SNOW_WARNING }, - [Species.SHELMET]: { 0: Abilities.PROTEAN }, + [Species.SHELMET]: { 0: Abilities.STAMINA }, + [Species.ACCELGOR]: { 0: Abilities.PROTEAN }, [Species.STUNFISK]: { 0: Abilities.STORM_DRAIN }, [Species.MIENFOO]: { 0: Abilities.NO_GUARD }, + [Species.MIENSHAO]: { 0: Abilities.NO_GUARD }, [Species.DRUDDIGON]: { 0: Abilities.INTIMIDATE }, [Species.GOLETT]: { 0: Abilities.SHADOW_SHIELD }, + [Species.GOLURK]: { 0: Abilities.SHADOW_SHIELD }, [Species.PAWNIARD]: { 0: Abilities.SWORD_OF_RUIN }, + [Species.BISHARP]: { 0: Abilities.SWORD_OF_RUIN }, + [Species.KINGAMBIT]: { 0: Abilities.SWORD_OF_RUIN }, [Species.BOUFFALANT]: { 0: Abilities.ROCK_HEAD }, [Species.RUFFLET]: { 0: Abilities.SPEED_BOOST }, + [Species.BRAVIARY]: { 0: Abilities.SPEED_BOOST }, + [Species.HISUI_BRAVIARY]: { 0: Abilities.SPEED_BOOST }, [Species.VULLABY]: { 0: Abilities.THICK_FAT }, + [Species.MANDIBUZZ]: { 0: Abilities.THICK_FAT }, [Species.HEATMOR]: { 0: Abilities.CONTRARY }, [Species.DURANT]: { 0: Abilities.COMPOUND_EYES }, - [Species.DEINO]: { 0: Abilities.PARENTAL_BOND }, - [Species.LARVESTA]: { 0: Abilities.DROUGHT }, + [Species.DEINO]: { 0: Abilities.NO_GUARD }, + [Species.ZWEILOUS]: { 0: Abilities.NO_GUARD }, + [Species.HYDREIGON]: { 0: Abilities.PARENTAL_BOND }, + [Species.LARVESTA]: { 0: Abilities.FLASH_FIRE }, + [Species.VOLCARONA]: { 0: Abilities.DROUGHT }, [Species.COBALION]: { 0: Abilities.INTREPID_SWORD }, [Species.TERRAKION]: { 0: Abilities.ROCKY_PAYLOAD }, [Species.VIRIZION]: { 0: Abilities.SHARPNESS }, - [Species.TORNADUS]: { 0: Abilities.DRIZZLE }, - [Species.THUNDURUS]: { 0: Abilities.DRIZZLE }, + [Species.TORNADUS]: { 0: Abilities.DRIZZLE, 1: Abilities.DRIZZLE }, + [Species.THUNDURUS]: { 0: Abilities.DRIZZLE, 1: Abilities.DRIZZLE }, [Species.RESHIRAM]: { 0: Abilities.ORICHALCUM_PULSE }, [Species.ZEKROM]: { 0: Abilities.HADRON_ENGINE }, - [Species.LANDORUS]: { 0: Abilities.STORM_DRAIN }, - [Species.KYUREM]: { 0: Abilities.SNOW_WARNING }, - [Species.KELDEO]: { 0: Abilities.GRIM_NEIGH }, - [Species.MELOETTA]: { 0: Abilities.MINDS_EYE }, - [Species.GENESECT]: { 0: Abilities.PROTEAN }, + [Species.LANDORUS]: { 0: Abilities.STORM_DRAIN, 1: Abilities.STORM_DRAIN }, + [Species.KYUREM]: { 0: Abilities.SNOW_WARNING, 1: Abilities.HADRON_ENGINE, 2: Abilities.ORICHALCUM_PULSE }, + [Species.KELDEO]: { 0: Abilities.GRIM_NEIGH, 1: Abilities.GRIM_NEIGH }, + [Species.MELOETTA]: { 0: Abilities.PUNK_ROCK, 1: Abilities.SCRAPPY }, + [Species.GENESECT]: { 0: Abilities.PROTEAN, 1: Abilities.PROTEAN, 2: Abilities.PROTEAN, 3: Abilities.PROTEAN, 4: Abilities.PROTEAN }, - [Species.CHESPIN]: { 0: Abilities.DAUNTLESS_SHIELD }, - [Species.FENNEKIN]: { 0: Abilities.PSYCHIC_SURGE }, - [Species.FROAKIE]: { 0: Abilities.STAKEOUT }, - [Species.BUNNELBY]: { 0: Abilities.THICK_FAT }, - [Species.FLETCHLING]: { 0: Abilities.MAGIC_GUARD }, - [Species.SCATTERBUG]: { 0: Abilities.PRANKSTER }, + [Species.CHESPIN]: { 0: Abilities.ROUGH_SKIN }, + [Species.QUILLADIN]: { 0: Abilities.DAUNTLESS_SHIELD }, + [Species.CHESNAUGHT]: { 0: Abilities.DAUNTLESS_SHIELD }, + [Species.FENNEKIN]: { 0: Abilities.FLUFFY }, + [Species.BRAIXEN]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.DELPHOX]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.FROAKIE]: { 0: Abilities.STAKEOUT, 1: Abilities.STAKEOUT }, + [Species.FROGADIER]: { 0: Abilities.STAKEOUT, 1: Abilities.STAKEOUT }, + [Species.GRENINJA]: { 0: Abilities.STAKEOUT, 1: Abilities.STAKEOUT }, + [Species.BUNNELBY]: { 0: Abilities.INNER_FOCUS }, + [Species.DIGGERSBY]: { 0: Abilities.THICK_FAT }, + [Species.FLETCHLING]: { 0: Abilities.FLAME_BODY }, + [Species.FLETCHINDER]: { 0: Abilities.MAGIC_GUARD }, + [Species.TALONFLAME]: { 0: Abilities.MAGIC_GUARD }, + [Species.SCATTERBUG]: { 0: Abilities.SHIELD_DUST }, + [Species.SPEWPA]: { 0: Abilities.SHIELD_DUST }, + [Species.VIVILLON]: { 0: Abilities.PRANKSTER }, [Species.LITLEO]: { 0: Abilities.BEAST_BOOST }, + [Species.PYROAR]: { 0: Abilities.BEAST_BOOST }, [Species.FLABEBE]: { 0: Abilities.GRASSY_SURGE }, + [Species.FLOETTE]: { 0: Abilities.GRASSY_SURGE }, + [Species.FLORGES]: { 0: Abilities.GRASSY_SURGE }, [Species.SKIDDO]: { 0: Abilities.SEED_SOWER }, - [Species.PANCHAM]: { 0: Abilities.FUR_COAT }, + [Species.GOGOAT]: { 0: Abilities.SEED_SOWER }, + [Species.PANCHAM]: { 0: Abilities.TECHNICIAN }, + [Species.PANGORO]: { 0: Abilities.FUR_COAT }, [Species.FURFROU]: { 0: Abilities.FLUFFY }, - [Species.ESPURR]: { 0: Abilities.FUR_COAT }, + [Species.ESPURR]: { 0: Abilities.PRANKSTER }, + [Species.MEOWSTIC]: { 0: Abilities.FUR_COAT, 1: Abilities.NEUROFORCE }, [Species.HONEDGE]: { 0: Abilities.SHARPNESS }, + [Species.DOUBLADE]: { 0: Abilities.SHARPNESS }, + [Species.AEGISLASH]: { 0: Abilities.SHARPNESS }, [Species.SPRITZEE]: { 0: Abilities.FUR_COAT }, + [Species.AROMATISSE]: { 0: Abilities.FUR_COAT }, [Species.SWIRLIX]: { 0: Abilities.RIPEN }, - [Species.INKAY]: { 0: Abilities.UNNERVE }, + [Species.SLURPUFF]: { 0: Abilities.RIPEN }, + [Species.INKAY]: { 0: Abilities.SHADOW_SHIELD }, + [Species.MALAMAR]: { 0: Abilities.SHADOW_SHIELD }, [Species.BINACLE]: { 0: Abilities.SAP_SIPPER }, - [Species.SKRELP]: { 0: Abilities.DRAGONS_MAW }, + [Species.BARBARACLE]: { 0: Abilities.SAP_SIPPER }, + [Species.SKRELP]: { 0: Abilities.WATER_BUBBLE }, + [Species.DRAGALGE]: { 0: Abilities.DRAGONS_MAW }, [Species.CLAUNCHER]: { 0: Abilities.PROTEAN }, + [Species.CLAWITZER]: { 0: Abilities.PROTEAN }, [Species.HELIOPTILE]: { 0: Abilities.PROTEAN }, + [Species.HELIOLISK]: { 0: Abilities.PROTEAN }, [Species.TYRUNT]: { 0: Abilities.RECKLESS }, + [Species.TYRANTRUM]: { 0: Abilities.RECKLESS }, [Species.AMAURA]: { 0: Abilities.ICE_SCALES }, + [Species.AURORUS]: { 0: Abilities.ICE_SCALES }, [Species.HAWLUCHA]: { 0: Abilities.MOXIE }, [Species.DEDENNE]: { 0: Abilities.PIXILATE }, [Species.CARBINK]: { 0: Abilities.SOLID_ROCK }, [Species.GOOMY]: { 0: Abilities.REGENERATOR }, + [Species.SLIGGOO]: { 0: Abilities.POISON_HEAL }, + [Species.GOODRA]: { 0: Abilities.POISON_HEAL }, + [Species.HISUI_SLIGGOO]: { 0: Abilities.REGENERATOR }, + [Species.HISUI_GOODRA]: { 0: Abilities.REGENERATOR }, [Species.KLEFKI]: { 0: Abilities.LEVITATE }, [Species.PHANTUMP]: { 0: Abilities.SHADOW_TAG }, - [Species.PUMPKABOO]: { 0: Abilities.WELL_BAKED_BODY }, + [Species.TREVENANT]: { 0: Abilities.SHADOW_TAG }, + [Species.PUMPKABOO]: { 0: Abilities.WELL_BAKED_BODY, 1: Abilities.ADAPTABILITY, 2: Abilities.PRANKSTER, 3: Abilities.SEED_SOWER }, + [Species.GOURGEIST]: { 0: Abilities.WELL_BAKED_BODY, 1: Abilities.ADAPTABILITY, 2: Abilities.PRANKSTER, 3: Abilities.SEED_SOWER }, [Species.BERGMITE]: { 0: Abilities.ICE_SCALES }, - [Species.NOIBAT]: { 0: Abilities.PUNK_ROCK }, + [Species.AVALUGG]: { 0: Abilities.ICE_SCALES }, + [Species.HISUI_AVALUGG]: { 0: Abilities.ICE_SCALES }, + [Species.NOIBAT]: { 0: Abilities.CHEEK_POUCH }, + [Species.NOIVERN]: { 0: Abilities.PUNK_ROCK }, [Species.XERNEAS]: { 0: Abilities.HARVEST }, [Species.YVELTAL]: { 0: Abilities.SOUL_HEART }, - [Species.ZYGARDE]: { 0: Abilities.ADAPTABILITY }, - [Species.DIANCIE]: { 0: Abilities.PRISM_ARMOR }, - [Species.HOOPA]: { 0: Abilities.OPPORTUNIST }, + [Species.ZYGARDE]: { 0: Abilities.UNNERVE, 1: Abilities.MOXIE, 2: Abilities.UNNERVE, 3: Abilities.MOXIE, 4: Abilities.ADAPTABILITY }, + [Species.DIANCIE]: { 0: Abilities.SOLID_ROCK, 1: Abilities.PRISM_ARMOR }, + [Species.HOOPA]: { 0: Abilities.OPPORTUNIST, 1: Abilities.OPPORTUNIST }, [Species.VOLCANION]: { 0: Abilities.NEUTRALIZING_GAS }, [Species.ETERNAL_FLOETTE]: { 0: Abilities.MAGIC_GUARD }, [Species.ROWLET]: { 0: Abilities.SNIPER }, + [Species.DARTRIX]: { 0: Abilities.SNIPER }, + [Species.DECIDUEYE]: { 0: Abilities.SNIPER }, + [Species.HISUI_DECIDUEYE]: { 0: Abilities.SNIPER }, [Species.LITTEN]: { 0: Abilities.OPPORTUNIST }, + [Species.TORRACAT]: { 0: Abilities.OPPORTUNIST }, + [Species.INCINEROAR]: { 0: Abilities.OPPORTUNIST }, [Species.POPPLIO]: { 0: Abilities.PUNK_ROCK }, + [Species.BRIONNE]: { 0: Abilities.PUNK_ROCK }, + [Species.PRIMARINA]: { 0: Abilities.PUNK_ROCK }, [Species.PIKIPEK]: { 0: Abilities.TECHNICIAN }, + [Species.TRUMBEAK]: { 0: Abilities.TECHNICIAN }, + [Species.TOUCANNON]: { 0: Abilities.TECHNICIAN }, [Species.YUNGOOS]: { 0: Abilities.TOUGH_CLAWS }, - [Species.GRUBBIN]: { 0: Abilities.SPEED_BOOST }, + [Species.GUMSHOOS]: { 0: Abilities.TOUGH_CLAWS }, + [Species.GRUBBIN]: { 0: Abilities.SHIELD_DUST }, + [Species.CHARJABUG]: { 0: Abilities.POWER_SPOT }, + [Species.VIKAVOLT]: { 0: Abilities.SPEED_BOOST }, [Species.CRABRAWLER]: { 0: Abilities.WATER_BUBBLE }, - [Species.ORICORIO]: { 0: Abilities.ADAPTABILITY }, - [Species.CUTIEFLY]: { 0: Abilities.TINTED_LENS }, - [Species.ROCKRUFF]: { 0: Abilities.ROCKY_PAYLOAD }, - [Species.WISHIWASHI]: { 0: Abilities.REGENERATOR }, + [Species.CRABOMINABLE]: { 0: Abilities.WATER_BUBBLE }, + [Species.ORICORIO]: { 0: Abilities.ADAPTABILITY, 1: Abilities.ADAPTABILITY, 2: Abilities.ADAPTABILITY, 3: Abilities.ADAPTABILITY }, + [Species.CUTIEFLY]: { 0: Abilities.PICKUP }, + [Species.RIBOMBEE]: { 0: Abilities.TINTED_LENS }, + [Species.ROCKRUFF]: { 0: Abilities.PICKUP, 1: Abilities.PICKUP }, + [Species.LYCANROC]: { 0: Abilities.STURDY, 1: Abilities.INTIMIDATE, 2: Abilities.STAKEOUT }, + [Species.WISHIWASHI]: { 0: Abilities.REGENERATOR, 1: Abilities.REGENERATOR }, [Species.MAREANIE]: { 0: Abilities.TOXIC_DEBRIS }, + [Species.TOXAPEX]: { 0: Abilities.TOXIC_DEBRIS }, [Species.MUDBRAY]: { 0: Abilities.SAP_SIPPER }, + [Species.MUDSDALE]: { 0: Abilities.SAP_SIPPER }, [Species.DEWPIDER]: { 0: Abilities.TINTED_LENS }, + [Species.ARAQUANID]: { 0: Abilities.TINTED_LENS }, [Species.FOMANTIS]: { 0: Abilities.SHARPNESS }, + [Species.LURANTIS]: { 0: Abilities.SHARPNESS }, [Species.MORELULL]: { 0: Abilities.TRIAGE }, + [Species.SHIINOTIC]: { 0: Abilities.TRIAGE }, [Species.SALANDIT]: { 0: Abilities.DRAGONS_MAW }, + [Species.SALAZZLE]: { 0: Abilities.DRAGONS_MAW }, [Species.STUFFUL]: { 0: Abilities.SCRAPPY }, - [Species.BOUNSWEET]: { 0: Abilities.MOXIE }, + [Species.BEWEAR]: { 0: Abilities.SCRAPPY }, + [Species.BOUNSWEET]: { 0: Abilities.SIMPLE }, + [Species.STEENEE]: { 0: Abilities.SIMPLE }, + [Species.TSAREENA]: { 0: Abilities.MOXIE }, [Species.COMFEY]: { 0: Abilities.FRIEND_GUARD }, [Species.ORANGURU]: { 0: Abilities.POWER_SPOT }, [Species.PASSIMIAN]: { 0: Abilities.LIBERO }, [Species.WIMPOD]: { 0: Abilities.REGENERATOR }, + [Species.GOLISOPOD]: { 0: Abilities.REGENERATOR }, [Species.SANDYGAST]: { 0: Abilities.SAND_SPIT }, + [Species.PALOSSAND]: { 0: Abilities.SAND_SPIT }, [Species.PYUKUMUKU]: { 0: Abilities.PURIFYING_SALT }, - [Species.TYPE_NULL]: { 0: Abilities.ADAPTABILITY }, - [Species.MINIOR]: { 0: Abilities.STURDY }, + [Species.TYPE_NULL]: { 0: Abilities.CLEAR_BODY }, + [Species.SILVALLY]: { 0: Abilities.ADAPTABILITY, 1: Abilities.ADAPTABILITY, 2: Abilities.ADAPTABILITY, 3: Abilities.ADAPTABILITY, 4: Abilities.ADAPTABILITY, 5: Abilities.ADAPTABILITY, 6: Abilities.ADAPTABILITY, 7: Abilities.ADAPTABILITY, 8: Abilities.ADAPTABILITY, 9: Abilities.ADAPTABILITY, 10: Abilities.ADAPTABILITY, 11: Abilities.ADAPTABILITY, 12: Abilities.ADAPTABILITY, 13: Abilities.ADAPTABILITY, 14: Abilities.ADAPTABILITY, 15: Abilities.ADAPTABILITY, 16: Abilities.ADAPTABILITY, 17: Abilities.ADAPTABILITY }, + [Species.MINIOR]: { 0: Abilities.STURDY, 1: Abilities.STURDY, 2: Abilities.STURDY, 3: Abilities.STURDY, 4: Abilities.STURDY, 5: Abilities.STURDY, 6: Abilities.STURDY, 7: Abilities.AERILATE, 8: Abilities.AERILATE, 9: Abilities.AERILATE, 10: Abilities.AERILATE, 11: Abilities.AERILATE, 12: Abilities.AERILATE, 13: Abilities.AERILATE }, [Species.KOMALA]: { 0: Abilities.GUTS }, [Species.TURTONATOR]: { 0: Abilities.DAUNTLESS_SHIELD }, [Species.TOGEDEMARU]: { 0: Abilities.ROUGH_SKIN }, - [Species.MIMIKYU]: { 0: Abilities.TOUGH_CLAWS }, + [Species.MIMIKYU]: { 0: Abilities.TOUGH_CLAWS, 1: Abilities.TOUGH_CLAWS }, [Species.BRUXISH]: { 0: Abilities.MULTISCALE }, [Species.DRAMPA]: { 0: Abilities.THICK_FAT }, [Species.DHELMISE]: { 0: Abilities.WATER_BUBBLE }, [Species.JANGMO_O]: { 0: Abilities.DAUNTLESS_SHIELD }, + [Species.HAKAMO_O]: { 0: Abilities.DAUNTLESS_SHIELD }, + [Species.KOMMO_O]: { 0: Abilities.DAUNTLESS_SHIELD }, [Species.TAPU_KOKO]: { 0: Abilities.DAUNTLESS_SHIELD }, [Species.TAPU_LELE]: { 0: Abilities.BERSERK }, [Species.TAPU_BULU]: { 0: Abilities.FLOWER_VEIL }, [Species.TAPU_FINI]: { 0: Abilities.FAIRY_AURA }, - [Species.COSMOG]: { 0: Abilities.BEAST_BOOST }, + [Species.COSMOG]: { 0: Abilities.FRIEND_GUARD }, + [Species.COSMOEM]: { 0: Abilities.POWER_SPOT }, + [Species.SOLGALEO]: { 0: Abilities.BEAST_BOOST }, + [Species.LUNALA]: { 0: Abilities.BEAST_BOOST }, [Species.NIHILEGO]: { 0: Abilities.LEVITATE }, [Species.BUZZWOLE]: { 0: Abilities.MOXIE }, [Species.PHEROMOSA]: { 0: Abilities.TINTED_LENS }, @@ -430,125 +836,223 @@ export const starterPassiveAbilities: StarterPassiveAbilities = { [Species.CELESTEELA]: { 0: Abilities.HEATPROOF }, [Species.KARTANA]: { 0: Abilities.LONG_REACH }, [Species.GUZZLORD]: { 0: Abilities.POISON_HEAL }, - [Species.NECROZMA]: { 0: Abilities.BEAST_BOOST }, - [Species.MAGEARNA]: { 0: Abilities.STEELY_SPIRIT }, + [Species.NECROZMA]: { 0: Abilities.BEAST_BOOST, 1: Abilities.FULL_METAL_BODY, 2: Abilities.SHADOW_SHIELD, 3: Abilities.PRISM_ARMOR }, + [Species.MAGEARNA]: { 0: Abilities.STEELY_SPIRIT, 1: Abilities.STEELY_SPIRIT }, [Species.MARSHADOW]: { 0: Abilities.IRON_FIST }, [Species.POIPOLE]: { 0: Abilities.LEVITATE }, + [Species.NAGANADEL]: { 0: Abilities.LEVITATE }, [Species.STAKATAKA]: { 0: Abilities.SOLID_ROCK }, [Species.BLACEPHALON]: { 0: Abilities.MAGIC_GUARD }, [Species.ZERAORA]: { 0: Abilities.TOUGH_CLAWS }, [Species.MELTAN]: { 0: Abilities.HEATPROOF }, + [Species.MELMETAL]: { 0: Abilities.HEATPROOF, 1: Abilities.FULL_METAL_BODY }, [Species.ALOLA_RATTATA]: { 0: Abilities.ADAPTABILITY }, + [Species.ALOLA_RATICATE]: { 0: Abilities.ADAPTABILITY }, [Species.ALOLA_SANDSHREW]: { 0: Abilities.ICE_SCALES }, - [Species.ALOLA_VULPIX]: { 0: Abilities.SHEER_FORCE }, + [Species.ALOLA_VULPIX]: { 0: Abilities.ICE_BODY }, + [Species.ALOLA_NINETALES]: { 0: Abilities.ICE_BODY }, [Species.ALOLA_DIGLETT]: { 0: Abilities.STURDY }, + [Species.ALOLA_DUGTRIO]: { 0: Abilities.STURDY }, [Species.ALOLA_MEOWTH]: { 0: Abilities.DARK_AURA }, + [Species.ALOLA_PERSIAN]: { 0: Abilities.DARK_AURA }, [Species.ALOLA_GEODUDE]: { 0: Abilities.DRY_SKIN }, + [Species.ALOLA_GRAVELER]: { 0: Abilities.DRY_SKIN }, + [Species.ALOLA_GOLEM]: { 0: Abilities.DRY_SKIN }, [Species.ALOLA_GRIMER]: { 0: Abilities.TOXIC_DEBRIS }, + [Species.ALOLA_MUK]: { 0: Abilities.TOXIC_DEBRIS }, [Species.GROOKEY]: { 0: Abilities.GRASS_PELT }, + [Species.THWACKEY]: { 0: Abilities.GRASS_PELT }, + [Species.RILLABOOM]: { 0: Abilities.GRASS_PELT, 1: Abilities.GRASS_PELT }, [Species.SCORBUNNY]: { 0: Abilities.NO_GUARD }, + [Species.RABOOT]: { 0: Abilities.NO_GUARD }, + [Species.CINDERACE]: { 0: Abilities.NO_GUARD, 1: Abilities.NO_GUARD }, [Species.SOBBLE]: { 0: Abilities.SUPER_LUCK }, + [Species.DRIZZILE]: { 0: Abilities.SUPER_LUCK }, + [Species.INTELEON]: { 0: Abilities.SUPER_LUCK, 1: Abilities.SUPER_LUCK }, [Species.SKWOVET]: { 0: Abilities.HARVEST }, - [Species.ROOKIDEE]: { 0: Abilities.IRON_BARBS }, - [Species.BLIPBUG]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.GREEDENT]: { 0: Abilities.HARVEST }, + [Species.ROOKIDEE]: { 0: Abilities.DEFIANT }, + [Species.CORVISQUIRE]: { 0: Abilities.DEFIANT }, + [Species.CORVIKNIGHT]: { 0: Abilities.IRON_BARBS, 1: Abilities.IRON_BARBS }, + [Species.BLIPBUG]: { 0: Abilities.RUN_AWAY }, + [Species.DOTTLER]: { 0: Abilities.PSYCHIC_SURGE }, + [Species.ORBEETLE]: { 0: Abilities.PSYCHIC_SURGE, 1: Abilities.PSYCHIC_SURGE }, [Species.NICKIT]: { 0: Abilities.MAGICIAN }, - [Species.GOSSIFLEUR]: { 0: Abilities.GRASSY_SURGE }, + [Species.THIEVUL]: { 0: Abilities.MAGICIAN }, + [Species.GOSSIFLEUR]: { 0: Abilities.SEED_SOWER }, + [Species.ELDEGOSS]: { 0: Abilities.GRASSY_SURGE }, [Species.WOOLOO]: { 0: Abilities.SCRAPPY }, - [Species.CHEWTLE]: { 0: Abilities.ROCKY_PAYLOAD }, - [Species.YAMPER]: { 0: Abilities.SHEER_FORCE }, + [Species.CHEWTLE]: { 0: Abilities.SOLID_ROCK }, + [Species.DREDNAW]: { 0: Abilities.SOLID_ROCK, 1: Abilities.SOLID_ROCK }, + [Species.YAMPER]: { 0: Abilities.PICKUP }, + [Species.BOLTUND]: { 0: Abilities.SHEER_FORCE }, [Species.ROLYCOLY]: { 0: Abilities.SOLID_ROCK }, - [Species.APPLIN]: { 0: Abilities.DRAGONS_MAW }, + [Species.CARKOL]: { 0: Abilities.SOLID_ROCK }, + [Species.COALOSSAL]: { 0: Abilities.SOLID_ROCK, 1: Abilities.SOLID_ROCK }, + [Species.APPLIN]: { 0: Abilities.STURDY }, + [Species.FLAPPLE]: { 0: Abilities.NO_GUARD, 1: Abilities.NO_GUARD }, + [Species.APPLETUN]: { 0: Abilities.WELL_BAKED_BODY, 1: Abilities.WELL_BAKED_BODY }, + [Species.DIPPLIN]: { 0: Abilities.FILTER }, + [Species.HYDRAPPLE]: { 0: Abilities.PARENTAL_BOND }, [Species.SILICOBRA]: { 0: Abilities.SAND_RUSH }, - [Species.CRAMORANT]: { 0: Abilities.LIGHTNING_ROD }, - [Species.ARROKUDA]: { 0: Abilities.INTIMIDATE }, + [Species.SANDACONDA]: { 0: Abilities.SAND_RUSH, 1: Abilities.SAND_RUSH }, + [Species.CRAMORANT]: { 0: Abilities.LIGHTNING_ROD, 1: Abilities.LIGHTNING_ROD, 2: Abilities.LIGHTNING_ROD }, + [Species.ARROKUDA]: { 0: Abilities.SPEED_BOOST }, + [Species.BARRASKEWDA]: { 0: Abilities.INTIMIDATE }, [Species.TOXEL]: { 0: Abilities.ELECTRIC_SURGE }, - [Species.SIZZLIPEDE]: { 0: Abilities.SPEED_BOOST }, + [Species.TOXTRICITY]: { 0: Abilities.ELECTRIC_SURGE, 1: Abilities.ELECTRIC_SURGE, 2: Abilities.ELECTRIC_SURGE }, + [Species.SIZZLIPEDE]: { 0: Abilities.HUSTLE }, + [Species.CENTISKORCH]: { 0: Abilities.HUSTLE, 1: Abilities.HUSTLE }, [Species.CLOBBOPUS]: { 0: Abilities.WATER_BUBBLE }, - [Species.SINISTEA]: { 0: Abilities.SHADOW_SHIELD }, + [Species.GRAPPLOCT]: { 0: Abilities.WATER_BUBBLE }, + [Species.SINISTEA]: { 0: Abilities.SHADOW_SHIELD, 1: Abilities.SHADOW_SHIELD }, + [Species.POLTEAGEIST]: { 0: Abilities.SHADOW_SHIELD, 1: Abilities.SHADOW_SHIELD }, [Species.HATENNA]: { 0: Abilities.FAIRY_AURA }, + [Species.HATTREM]: { 0: Abilities.FAIRY_AURA }, + [Species.HATTERENE]: { 0: Abilities.FAIRY_AURA, 1: Abilities.FAIRY_AURA }, [Species.IMPIDIMP]: { 0: Abilities.INTIMIDATE }, + [Species.MORGREM]: { 0: Abilities.INTIMIDATE }, + [Species.GRIMMSNARL]: { 0: Abilities.INTIMIDATE, 1: Abilities.INTIMIDATE }, [Species.MILCERY]: { 0: Abilities.REGENERATOR }, - [Species.FALINKS]: { 0: Abilities.PARENTAL_BOND }, + [Species.ALCREMIE]: { 0: Abilities.REGENERATOR }, + [Species.FALINKS]: { 0: Abilities.DAUNTLESS_SHIELD }, [Species.PINCURCHIN]: { 0: Abilities.ELECTROMORPHOSIS }, [Species.SNOM]: { 0: Abilities.SNOW_WARNING }, + [Species.FROSMOTH]: { 0: Abilities.SNOW_WARNING }, [Species.STONJOURNER]: { 0: Abilities.STURDY }, - [Species.EISCUE]: { 0: Abilities.ICE_SCALES }, - [Species.INDEEDEE]: { 0: Abilities.FRIEND_GUARD }, - [Species.MORPEKO]: { 0: Abilities.MOODY }, + [Species.EISCUE]: { 0: Abilities.ICE_SCALES, 1: Abilities.ICE_SCALES }, + [Species.INDEEDEE]: { 0: Abilities.HOSPITALITY, 1: Abilities.FRIEND_GUARD }, + [Species.MORPEKO]: { 0: Abilities.MOODY, 1: Abilities.MOODY }, [Species.CUFANT]: { 0: Abilities.EARTH_EATER }, + [Species.COPPERAJAH]: { 0: Abilities.EARTH_EATER, 1: Abilities.EARTH_EATER }, [Species.DRACOZOLT]: { 0: Abilities.NO_GUARD }, [Species.ARCTOZOLT]: { 0: Abilities.WATER_ABSORB }, [Species.DRACOVISH]: { 0: Abilities.SWIFT_SWIM }, [Species.ARCTOVISH]: { 0: Abilities.STRONG_JAW }, - [Species.DURALUDON]: { 0: Abilities.STEELWORKER }, - [Species.DREEPY]: { 0: Abilities.PARENTAL_BOND }, - [Species.ZACIAN]: { 0: Abilities.UNNERVE }, - [Species.ZAMAZENTA]: { 0: Abilities.UNNERVE }, - [Species.ETERNATUS]: { 0: Abilities.NEUTRALIZING_GAS }, + [Species.DURALUDON]: { 0: Abilities.FILTER, 1: Abilities.UNAWARE }, + [Species.ARCHALUDON]: { 0: Abilities.TRANSISTOR }, + [Species.DREEPY]: { 0: Abilities.TECHNICIAN }, + [Species.DRAKLOAK]: { 0: Abilities.PARENTAL_BOND }, + [Species.DRAGAPULT]: { 0: Abilities.PARENTAL_BOND }, + [Species.ZACIAN]: { 0: Abilities.UNNERVE, 1: Abilities.UNNERVE }, + [Species.ZAMAZENTA]: { 0: Abilities.UNNERVE, 1: Abilities.UNNERVE }, + [Species.ETERNATUS]: { 0: Abilities.NEUTRALIZING_GAS, 1: Abilities.NEUTRALIZING_GAS }, [Species.KUBFU]: { 0: Abilities.IRON_FIST }, - [Species.ZARUDE]: { 0: Abilities.TOUGH_CLAWS }, + [Species.URSHIFU]: { 0: Abilities.IRON_FIST, 1: Abilities.IRON_FIST, 2: Abilities.IRON_FIST, 3: Abilities.IRON_FIST }, + [Species.ZARUDE]: { 0: Abilities.TOUGH_CLAWS, 1: Abilities.TOUGH_CLAWS }, [Species.REGIELEKI]: { 0: Abilities.ELECTRIC_SURGE }, [Species.REGIDRAGO]: { 0: Abilities.MULTISCALE }, [Species.GLASTRIER]: { 0: Abilities.FILTER }, - [Species.SPECTRIER]: { 0: Abilities.SHADOW_SHIELD }, - [Species.CALYREX]: { 0: Abilities.HARVEST }, - [Species.ENAMORUS]: { 0: Abilities.FAIRY_AURA }, + [Species.SPECTRIER]: { 0: Abilities.MOLD_BREAKER }, + [Species.CALYREX]: { 0: Abilities.HARVEST, 1: Abilities.FILTER, 2: Abilities.MOLD_BREAKER }, + [Species.ENAMORUS]: { 0: Abilities.FAIRY_AURA, 1: Abilities.FAIRY_AURA }, [Species.GALAR_MEOWTH]: { 0: Abilities.UNBURDEN }, + [Species.PERRSERKER]: { 0: Abilities.UNBURDEN }, [Species.GALAR_PONYTA]: { 0: Abilities.CHILLING_NEIGH }, - [Species.GALAR_SLOWPOKE]: { 0: Abilities.UNAWARE }, - [Species.GALAR_FARFETCHD]: { 0: Abilities.INTREPID_SWORD }, + [Species.GALAR_RAPIDASH]: { 0: Abilities.CHILLING_NEIGH }, + [Species.GALAR_SLOWPOKE]: { 0: Abilities.OBLIVIOUS }, + [Species.GALAR_SLOWBRO]: { 0: Abilities.NEUROFORCE }, + [Species.GALAR_SLOWKING]: { 0: Abilities.INTIMIDATE }, + [Species.GALAR_FARFETCHD]: { 0: Abilities.STAKEOUT }, + [Species.SIRFETCHD]: { 0: Abilities.INTREPID_SWORD }, [Species.GALAR_ARTICUNO]: { 0: Abilities.SERENE_GRACE }, [Species.GALAR_ZAPDOS]: { 0: Abilities.TOUGH_CLAWS }, [Species.GALAR_MOLTRES]: { 0: Abilities.DARK_AURA }, [Species.GALAR_CORSOLA]: { 0: Abilities.SHADOW_SHIELD }, + [Species.CURSOLA]: { 0: Abilities.SHADOW_SHIELD }, [Species.GALAR_ZIGZAGOON]: { 0: Abilities.POISON_HEAL }, + [Species.GALAR_LINOONE]: { 0: Abilities.POISON_HEAL }, + [Species.OBSTAGOON]: { 0: Abilities.POISON_HEAL }, [Species.GALAR_DARUMAKA]: { 0: Abilities.FLASH_FIRE }, + [Species.GALAR_DARMANITAN]: { 0: Abilities.FLASH_FIRE, 1: Abilities.FLASH_FIRE }, [Species.GALAR_YAMASK]: { 0: Abilities.TABLETS_OF_RUIN }, + [Species.RUNERIGUS]: { 0: Abilities.TABLETS_OF_RUIN }, [Species.GALAR_STUNFISK]: { 0: Abilities.ARENA_TRAP }, [Species.HISUI_GROWLITHE]: { 0: Abilities.RECKLESS }, + [Species.HISUI_ARCANINE]: { 0: Abilities.RECKLESS }, [Species.HISUI_VOLTORB]: { 0: Abilities.TRANSISTOR }, + [Species.HISUI_ELECTRODE]: { 0: Abilities.TRANSISTOR }, [Species.HISUI_QWILFISH]: { 0: Abilities.MERCILESS }, + [Species.OVERQWIL]: { 0: Abilities.MERCILESS }, [Species.HISUI_SNEASEL]: { 0: Abilities.SCRAPPY }, + [Species.SNEASLER]: { 0: Abilities.SCRAPPY }, [Species.HISUI_ZORUA]: { 0: Abilities.ADAPTABILITY }, + [Species.HISUI_ZOROARK]: { 0: Abilities.ADAPTABILITY }, - [Species.SPRIGATITO]: { 0: Abilities.MAGICIAN }, - [Species.FUECOCO]: { 0: Abilities.PUNK_ROCK }, - [Species.QUAXLY]: { 0: Abilities.OPPORTUNIST }, + [Species.SPRIGATITO]: { 0: Abilities.PICKUP }, + [Species.FLORAGATO]: { 0: Abilities.MAGICIAN }, + [Species.MEOWSCARADA]: { 0: Abilities.MAGICIAN }, + [Species.FUECOCO]: { 0: Abilities.GLUTTONY }, + [Species.CROCALOR]: { 0: Abilities.GLUTTONY }, + [Species.SKELEDIRGE]: { 0: Abilities.GLUTTONY }, + [Species.QUAXLY]: { 0: Abilities.DANCER }, + [Species.QUAXWELL]: { 0: Abilities.OPPORTUNIST }, + [Species.QUAQUAVAL]: { 0: Abilities.OPPORTUNIST }, [Species.LECHONK]: { 0: Abilities.SIMPLE }, + [Species.OINKOLOGNE]: { 0: Abilities.SIMPLE, 1: Abilities.SIMPLE }, [Species.TAROUNTULA]: { 0: Abilities.HONEY_GATHER }, - [Species.NYMBLE]: { 0: Abilities.GUTS }, + [Species.SPIDOPS]: { 0: Abilities.HONEY_GATHER }, + [Species.NYMBLE]: { 0: Abilities.HUSTLE }, + [Species.LOKIX]: { 0: Abilities.GUTS }, [Species.PAWMI]: { 0: Abilities.TRANSISTOR }, - [Species.TANDEMAUS]: { 0: Abilities.SCRAPPY }, + [Species.PAWMO]: { 0: Abilities.TRANSISTOR }, + [Species.PAWMOT]: { 0: Abilities.TRANSISTOR }, + [Species.TANDEMAUS]: { 0: Abilities.FRIEND_GUARD }, + [Species.MAUSHOLD]: { 0: Abilities.SCRAPPY, 1: Abilities.SCRAPPY }, [Species.FIDOUGH]: { 0: Abilities.WATER_ABSORB }, + [Species.DACHSBUN]: { 0: Abilities.WATER_ABSORB }, [Species.SMOLIV]: { 0: Abilities.RIPEN }, - [Species.SQUAWKABILLY]: { 0: Abilities.MOXIE }, + [Species.DOLLIV]: { 0: Abilities.RIPEN }, + [Species.ARBOLIVA]: { 0: Abilities.RIPEN }, + [Species.SQUAWKABILLY]: { 0: Abilities.MOXIE, 1: Abilities.MOXIE, 2: Abilities.MOXIE, 3: Abilities.MOXIE }, [Species.NACLI]: { 0: Abilities.SOLID_ROCK }, - [Species.CHARCADET]: { 0: Abilities.PRISM_ARMOR }, - [Species.TADBULB]: { 0: Abilities.STAMINA }, + [Species.NACLSTACK]: { 0: Abilities.SOLID_ROCK }, + [Species.GARGANACL]: { 0: Abilities.SOLID_ROCK }, + [Species.CHARCADET]: { 0: Abilities.BATTLE_ARMOR }, + [Species.ARMAROUGE]: { 0: Abilities.PRISM_ARMOR }, + [Species.CERULEDGE]: { 0: Abilities.PRISM_ARMOR }, + [Species.TADBULB]: { 0: Abilities.LEVITATE }, + [Species.BELLIBOLT]: { 0: Abilities.STAMINA }, [Species.WATTREL]: { 0: Abilities.SHEER_FORCE }, + [Species.KILOWATTREL]: { 0: Abilities.SHEER_FORCE }, [Species.MASCHIFF]: { 0: Abilities.STRONG_JAW }, + [Species.MABOSSTIFF]: { 0: Abilities.STRONG_JAW }, [Species.SHROODLE]: { 0: Abilities.CORROSION }, - [Species.BRAMBLIN]: { 0: Abilities.SHADOW_SHIELD }, - [Species.TOEDSCOOL]: { 0: Abilities.PRANKSTER }, + [Species.GRAFAIAI]: { 0: Abilities.CORROSION }, + [Species.BRAMBLIN]: { 0: Abilities.WANDERING_SPIRIT }, + [Species.BRAMBLEGHAST]: { 0: Abilities.SHADOW_SHIELD }, + [Species.TOEDSCOOL]: { 0: Abilities.RUN_AWAY }, + [Species.TOEDSCRUEL]: { 0: Abilities.PRANKSTER }, [Species.KLAWF]: { 0: Abilities.WATER_ABSORB }, - [Species.CAPSAKID]: { 0: Abilities.PARENTAL_BOND }, + [Species.CAPSAKID]: { 0: Abilities.FLOWER_GIFT }, + [Species.SCOVILLAIN]: { 0: Abilities.PARENTAL_BOND }, [Species.RELLOR]: { 0: Abilities.PRANKSTER }, + [Species.RABSCA]: { 0: Abilities.PRANKSTER }, [Species.FLITTLE]: { 0: Abilities.DAZZLING }, + [Species.ESPATHRA]: { 0: Abilities.DAZZLING }, [Species.TINKATINK]: { 0: Abilities.STEELWORKER }, + [Species.TINKATUFF]: { 0: Abilities.STEELWORKER }, + [Species.TINKATON]: { 0: Abilities.STEELWORKER }, [Species.WIGLETT]: { 0: Abilities.STURDY }, + [Species.WUGTRIO]: { 0: Abilities.STURDY }, [Species.BOMBIRDIER]: { 0: Abilities.UNBURDEN }, - [Species.FINIZEN]: { 0: Abilities.IRON_FIST }, + [Species.FINIZEN]: { 0: Abilities.SWIFT_SWIM }, + [Species.PALAFIN]: { 0: Abilities.EMERGENCY_EXIT, 1: Abilities.IRON_FIST }, [Species.VAROOM]: { 0: Abilities.LEVITATE }, + [Species.REVAVROOM]: { 0: Abilities.LEVITATE, 1: Abilities.LEVITATE, 2: Abilities.LEVITATE, 3: Abilities.LEVITATE, 4: Abilities.LEVITATE, 5: Abilities.LEVITATE }, [Species.CYCLIZAR]: { 0: Abilities.PROTEAN }, [Species.ORTHWORM]: { 0: Abilities.REGENERATOR }, - [Species.GLIMMET]: { 0: Abilities.TERA_SHELL }, + [Species.GLIMMET]: { 0: Abilities.STURDY }, + [Species.GLIMMORA]: { 0: Abilities.TERA_SHELL }, [Species.GREAVARD]: { 0: Abilities.UNAWARE }, + [Species.HOUNDSTONE]: { 0: Abilities.UNAWARE }, [Species.FLAMIGO]: { 0: Abilities.MOXIE }, [Species.CETODDLE]: { 0: Abilities.REFRIGERATE }, + [Species.CETITAN]: { 0: Abilities.REFRIGERATE }, [Species.VELUZA]: { 0: Abilities.SUPER_LUCK }, [Species.DONDOZO]: { 0: Abilities.DRAGONS_MAW }, - [Species.TATSUGIRI]: { 0: Abilities.FLUFFY }, + [Species.TATSUGIRI]: { 0: Abilities.FLUFFY, 1: Abilities.FLUFFY, 2: Abilities.FLUFFY }, [Species.GREAT_TUSK]: { 0: Abilities.INTIMIDATE }, [Species.SCREAM_TAIL]: { 0: Abilities.UNAWARE }, [Species.BRUTE_BONNET]: { 0: Abilities.CHLOROPHYLL }, @@ -562,29 +1066,34 @@ export const starterPassiveAbilities: StarterPassiveAbilities = { [Species.IRON_MOTH]: { 0: Abilities.LEVITATE }, [Species.IRON_THORNS]: { 0: Abilities.SAND_STREAM }, [Species.FRIGIBAX]: { 0: Abilities.INTIMIDATE }, - [Species.GIMMIGHOUL]: { 0: Abilities.HONEY_GATHER }, + [Species.ARCTIBAX]: { 0: Abilities.INTIMIDATE }, + [Species.BAXCALIBUR]: { 0: Abilities.INTIMIDATE }, + [Species.GIMMIGHOUL]: { 0: Abilities.HONEY_GATHER, 1: Abilities.HONEY_GATHER }, + [Species.GHOLDENGO]: { 0: Abilities.HONEY_GATHER }, [Species.WO_CHIEN]: { 0: Abilities.VESSEL_OF_RUIN }, [Species.CHIEN_PAO]: { 0: Abilities.INTIMIDATE }, [Species.TING_LU]: { 0: Abilities.STAMINA }, [Species.CHI_YU]: { 0: Abilities.BERSERK }, [Species.ROARING_MOON]: { 0: Abilities.INTIMIDATE }, [Species.IRON_VALIANT]: { 0: Abilities.NEUROFORCE }, - [Species.KORAIDON]: { 0: Abilities.OPPORTUNIST }, - [Species.MIRAIDON]: { 0: Abilities.OPPORTUNIST }, + [Species.KORAIDON]: { 0: Abilities.THERMAL_EXCHANGE }, + [Species.MIRAIDON]: { 0: Abilities.COMPOUND_EYES }, [Species.WALKING_WAKE]: { 0: Abilities.BEAST_BOOST }, [Species.IRON_LEAVES]: { 0: Abilities.SHARPNESS }, - [Species.POLTCHAGEIST]: { 0: Abilities.TRIAGE }, + [Species.POLTCHAGEIST]: { 0: Abilities.TRIAGE, 1: Abilities.TRIAGE }, + [Species.SINISTCHA]: { 0: Abilities.TRIAGE, 1: Abilities.TRIAGE }, [Species.OKIDOGI]: { 0: Abilities.DARK_AURA }, [Species.MUNKIDORI]: { 0: Abilities.MAGICIAN }, [Species.FEZANDIPITI]: { 0: Abilities.PIXILATE }, - [Species.OGERPON]: { 0: Abilities.OPPORTUNIST }, + [Species.OGERPON]: { 0: Abilities.OPPORTUNIST, 1: Abilities.SUPER_LUCK, 2: Abilities.FLASH_FIRE, 3: Abilities.MAGIC_GUARD, 4: Abilities.OPPORTUNIST, 5: Abilities.SUPER_LUCK, 6: Abilities.FLASH_FIRE, 7: Abilities.MAGIC_GUARD }, [Species.GOUGING_FIRE]: { 0: Abilities.BEAST_BOOST }, [Species.RAGING_BOLT]: { 0: Abilities.BEAST_BOOST }, [Species.IRON_BOULDER]: { 0: Abilities.SHARPNESS }, [Species.IRON_CROWN]: { 0: Abilities.SHARPNESS }, - [Species.TERAPAGOS]: { 0: Abilities.SHIELD_DUST }, + [Species.TERAPAGOS]: { 0: Abilities.SHIELD_DUST, 1: Abilities.SHIELD_DUST, 2: Abilities.SHIELD_DUST }, [Species.PECHARUNT]: { 0: Abilities.TOXIC_CHAIN }, - [Species.PALDEA_TAUROS]: { 0: Abilities.ADAPTABILITY }, - [Species.PALDEA_WOOPER]: { 0: Abilities.THICK_FAT }, + [Species.PALDEA_TAUROS]: { 0: Abilities.STAMINA, 1: Abilities.ADAPTABILITY, 2: Abilities.ADAPTABILITY }, + [Species.PALDEA_WOOPER]: { 0: Abilities.POISON_TOUCH }, + [Species.CLODSIRE]: { 0: Abilities.THICK_FAT }, [Species.BLOODMOON_URSALUNA]: { 0: Abilities.BERSERK } }; diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index c34bc229bd7..e49bd049cd6 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -179,7 +179,7 @@ class TimeOfDayEvolutionCondition extends SpeciesEvolutionCondition { class MoveEvolutionCondition extends SpeciesEvolutionCondition { public move: Moves; constructor(move: Moves) { - super(p => p.moveset.filter(m => m?.moveId === move).length > 0); + super(p => p.moveset.filter(m => m.moveId === move).length > 0); this.move = move; const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) }); @@ -282,7 +282,7 @@ class TyrogueEvolutionCondition extends SpeciesEvolutionCondition { public move: Moves; constructor(move: Moves) { super(p => - p.getMoveset(true).find(m => m && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(m?.moveId))?.moveId === move); + p.getMoveset(true).find(m => m && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(m.moveId))?.moveId === move); this.move = move; const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) }); @@ -303,11 +303,11 @@ class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition { public timesOfDay: TimeOfDay[]; constructor(move: Moves, tod: "day" | "night") { if (tod === "day") { - super(p => p.moveset.filter(m => m?.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)); + super(p => p.moveset.filter(m => m.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)); this.move = move; this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ]; } else if (tod === "night") { - super(p => p.moveset.filter(m => m?.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)); + super(p => p.moveset.filter(m => m.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)); this.move = move; this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]; } else { @@ -332,7 +332,7 @@ class DunsparceEvolutionCondition extends SpeciesEvolutionCondition { constructor() { super(p => { let ret = false; - if (p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0) { + if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) { globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); } return ret; @@ -1540,13 +1540,13 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.AIPOM]: [ - new SpeciesEvolution(Species.AMBIPOM, 32, null, new MoveEvolutionCondition(Moves.DOUBLE_HIT), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.AMBIPOM, 32, null, new MoveEvolutionCondition(Moves.DOUBLE_HIT), SpeciesWildEvolutionDelay.LONG) ], [Species.SUNKERN]: [ new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.YANMA]: [ - new SpeciesEvolution(Species.YANMEGA, 33, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.YANMEGA, 33, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG) ], [Species.MURKROW]: [ new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1555,11 +1555,11 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.GIRAFARIG]: [ - new SpeciesEvolution(Species.FARIGIRAF, 32, null, new MoveEvolutionCondition(Moves.TWIN_BEAM), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.FARIGIRAF, 32, null, new MoveEvolutionCondition(Moves.TWIN_BEAM), SpeciesWildEvolutionDelay.LONG) ], [Species.DUNSPARCE]: [ new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new DunsparceEvolutionCondition(), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "two-segment", 32, null, new MoveEvolutionCondition(Moves.HYPER_DRILL), SpeciesWildEvolutionDelay.LONG) + new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "two-segment", 32, null, new MoveEvolutionCondition(Moves.HYPER_DRILL), SpeciesWildEvolutionDelay.LONG) ], [Species.GLIGAR]: [ new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new TimeOfDayEvolutionCondition("night") /* Razor fang at night*/, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1571,10 +1571,10 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna ], [Species.PILOSWINE]: [ - new SpeciesEvolution(Species.MAMOSWINE, 1, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.MAMOSWINE, 1, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.STANTLER]: [ - new SpeciesEvolution(Species.WYRDEER, 25, null, new MoveEvolutionCondition(Moves.PSYSHIELD_BASH), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.WYRDEER, 25, null, new MoveEvolutionCondition(Moves.PSYSHIELD_BASH), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.LOMBRE]: [ new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) @@ -1592,7 +1592,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.BONSLY]: [ - new SpeciesEvolution(Species.SUDOWOODO, 1, null, new MoveEvolutionCondition(Moves.MIMIC), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.SUDOWOODO, 1, null, new MoveEvolutionCondition(Moves.MIMIC), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.MIME_JR]: [ new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "night"), SpeciesWildEvolutionDelay.MEDIUM), @@ -1651,10 +1651,10 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new TimeOfDayEvolutionCondition("night")) ], [Species.STEENEE]: [ - new SpeciesEvolution(Species.TSAREENA, 28, null, new MoveEvolutionCondition(Moves.STOMP), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.TSAREENA, 28, null, new MoveEvolutionCondition(Moves.STOMP), SpeciesWildEvolutionDelay.LONG) ], [Species.POIPOLE]: [ - new SpeciesEvolution(Species.NAGANADEL, 1, null, new MoveEvolutionCondition(Moves.DRAGON_PULSE), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.NAGANADEL, 1, null, new MoveEvolutionCondition(Moves.DRAGON_PULSE), SpeciesWildEvolutionDelay.LONG) ], [Species.ALOLA_SANDSHREW]: [ new SpeciesEvolution(Species.ALOLA_SANDSLASH, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) @@ -1720,7 +1720,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.HISUI_ELECTRODE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.HISUI_QWILFISH]: [ - new SpeciesEvolution(Species.OVERQWIL, 28, null, new MoveEvolutionCondition(Moves.BARB_BARRAGE), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.OVERQWIL, 28, null, new MoveEvolutionCondition(Moves.BARB_BARRAGE), SpeciesWildEvolutionDelay.LONG) ], [Species.HISUI_SNEASEL]: [ new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new TimeOfDayEvolutionCondition("day") /* Razor claw at day*/, SpeciesWildEvolutionDelay.VERY_LONG) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 43a7072fd12..b139faaeb88 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -757,7 +757,7 @@ export class ConfusedTag extends BattlerTag { ((((2 * pokemon.level) / 5 + 2) * 40 * atk) / def / 50 + 2) * (pokemon.randSeedIntRange(85, 100) / 100), ); globalScene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself")); - pokemon.damageAndUpdate(damage); + pokemon.damageAndUpdate(damage, { result: HitResult.CONFUSION }); pokemon.battleData.hitCount++; (globalScene.getCurrentPhase() as MovePhase).cancel(); } @@ -818,7 +818,7 @@ export class DestinyBondTag extends BattlerTag { pokemonNameWithAffix2: getPokemonNameWithAffix(pokemon), }), ); - pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, false, true); + pokemon.damageAndUpdate(pokemon.hp, { result: HitResult.INDIRECT_KO, ignoreSegments: true }); return false; } } @@ -952,7 +952,7 @@ export class SeedTag extends BattlerTag { new CommonAnimPhase(source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED), ); - const damage = pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8)); + const damage = pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT }); const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr, false); globalScene.unshiftPhase( new PokemonHealPhase( @@ -1029,7 +1029,7 @@ export class PowderTag extends BattlerTag { const cancelDamage = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelDamage); if (!cancelDamage.value) { - pokemon.damageAndUpdate(Math.floor(pokemon.getMaxHp() / 4), HitResult.OTHER); + pokemon.damageAndUpdate(Math.floor(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT }); } // "When the flame touched the powder\non the Pokémon, it exploded!" @@ -1082,7 +1082,7 @@ export class NightmareTag extends BattlerTag { applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (!cancelled.value) { - pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT }); } } @@ -1174,13 +1174,13 @@ export class EncoreTag extends MoveRestrictionBattlerTag { const movePhase = globalScene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon); if (movePhase) { - const movesetMove = pokemon.getMoveset().find(m => m!.moveId === this.moveId); // TODO: is this bang correct? + const movesetMove = pokemon.getMoveset().find(m => m.moveId === this.moveId); if (movesetMove) { const lastMove = pokemon.getLastXMoves(1)[0]; globalScene.tryReplacePhase( m => m instanceof MovePhase && m.pokemon === pokemon, - new MovePhase(pokemon, lastMove.targets!, movesetMove), - ); // TODO: is this bang correct? + new MovePhase(pokemon, lastMove.targets ?? [], movesetMove), + ); } } } @@ -1191,7 +1191,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag { */ override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { if (lapseType === BattlerTagLapseType.CUSTOM) { - const encoredMove = pokemon.getMoveset().find(m => m?.moveId === this.moveId); + const encoredMove = pokemon.getMoveset().find(m => m.moveId === this.moveId); if (encoredMove && encoredMove?.getPpRatio() > 0) { return true; } @@ -1440,7 +1440,7 @@ export abstract class DamagingTrapTag extends TrappedTag { applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (!cancelled.value) { - pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT }); } } @@ -1644,7 +1644,9 @@ 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(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); + attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), { + result: HitResult.INDIRECT, + }); } } } @@ -1810,7 +1812,7 @@ export class PerishSongTag extends BattlerTag { }), ); } else { - pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, true, true); + pokemon.damageAndUpdate(pokemon.hp, { result: HitResult.INDIRECT_KO, ignoreSegments: true }); } return ret; @@ -1922,10 +1924,6 @@ export class SlowStartTag extends AbilityBattlerTag { i18next.t("battlerTags:slowStartOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), }), - null, - false, - null, - true, ); } @@ -1974,7 +1972,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag { let highestStat: EffectiveStat; EFFECTIVE_STATS.map(s => - pokemon.getEffectiveStat(s, undefined, undefined, undefined, undefined, undefined, undefined, true), + pokemon.getEffectiveStat(s, undefined, undefined, undefined, undefined, undefined, undefined, undefined, true), ).reduce((highestValue: number, value: number, i: number) => { if (value > highestValue) { highestStat = EFFECTIVE_STATS[i]; @@ -2153,6 +2151,21 @@ export class TypeBoostTag extends BattlerTag { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); } + + override onAdd(pokemon: Pokemon): void { + globalScene.queueMessage( + i18next.t("abilityTriggers:typeImmunityPowerBoost", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + typeName: i18next.t(`pokemonInfo:Type.${PokemonType[this.boostedType]}`), + }), + ); + } + + override onOverlap(pokemon: Pokemon): void { + globalScene.queueMessage( + i18next.t("abilityTriggers:moveImmunity", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), + ); + } } export class CritBoostTag extends BattlerTag { @@ -2244,7 +2257,9 @@ export class SaltCuredTag extends BattlerTag { if (!cancelled.value) { const pokemonSteelOrWater = pokemon.isOfType(PokemonType.STEEL) || pokemon.isOfType(PokemonType.WATER); - pokemon.damageAndUpdate(toDmgValue(pokemonSteelOrWater ? pokemon.getMaxHp() / 4 : pokemon.getMaxHp() / 8)); + pokemon.damageAndUpdate(toDmgValue(pokemonSteelOrWater ? pokemon.getMaxHp() / 4 : pokemon.getMaxHp() / 8), { + result: HitResult.INDIRECT, + }); globalScene.queueMessage( i18next.t("battlerTags:saltCuredLapse", { @@ -2292,7 +2307,7 @@ export class CursedTag extends BattlerTag { applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (!cancelled.value) { - pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4), { result: HitResult.INDIRECT }); globalScene.queueMessage( i18next.t("battlerTags:cursedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), @@ -2615,7 +2630,7 @@ export class GulpMissileTag extends BattlerTag { applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled); if (!cancelled.value) { - attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), HitResult.OTHER); + attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), { result: HitResult.INDIRECT }); } if (this.tagType === BattlerTagType.GULP_MISSILE_ARROKUDA) { @@ -3188,7 +3203,7 @@ export class ImprisonTag extends MoveRestrictionBattlerTag { public override isMoveRestricted(move: Moves, _user: Pokemon): boolean { const source = this.getSourcePokemon(); if (source) { - const sourceMoveset = source.getMoveset().map(m => m!.moveId); + const sourceMoveset = source.getMoveset().map(m => m.moveId); return sourceMoveset?.includes(move) && source.isActive(true); } return false; @@ -3358,7 +3373,7 @@ export class GrudgeTag extends BattlerTag { if (lapseType === BattlerTagLapseType.CUSTOM && sourcePokemon) { if (sourcePokemon.isActive() && pokemon.isOpponent(sourcePokemon)) { const lastMove = pokemon.turnData.attacksReceived[0]; - const lastMoveData = sourcePokemon.getMoveset().find(m => m?.moveId === lastMove.move); + const lastMoveData = sourcePokemon.getMoveset().find(m => m.moveId === lastMove.move); if (lastMoveData && lastMove.move !== Moves.STRUGGLE) { lastMoveData.ppUsed = lastMoveData.getMovePp(); globalScene.queueMessage( diff --git a/src/data/berry.ts b/src/data/berry.ts index ed8ae8d2b62..13820b1277b 100644 --- a/src/data/berry.ts +++ b/src/data/berry.ts @@ -65,7 +65,7 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate { return (pokemon: Pokemon) => { const threshold = new Utils.NumberHolder(0.25); applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); - return !!pokemon.getMoveset().find(m => !m?.getPpRatio()); + return !!pokemon.getMoveset().find(m => !m.getPpRatio()); }; } } @@ -147,9 +147,9 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { 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? + const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()) + ? pokemon.getMoveset().find(m => !m.getPpRatio()) + : pokemon.getMoveset().find(m => m.getPpRatio() < 1); if (ppRestoreMove !== undefined) { ppRestoreMove!.ppUsed = Math.max(ppRestoreMove!.ppUsed - 10, 0); globalScene.queueMessage( diff --git a/src/data/challenge.ts b/src/data/challenge.ts index b9d817836c3..1387732a773 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -18,9 +18,10 @@ import { TrainerType } from "#enums/trainer-type"; import { Nature } from "#enums/nature"; import type { Moves } from "#enums/moves"; import { TypeColor, TypeShadow } from "#enums/color"; -import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; -import { pokemonFormChanges } from "#app/data/pokemon-forms"; import { ModifierTier } from "#app/modifier/modifier-tier"; +import { globalScene } from "#app/global-scene"; +import { pokemonFormChanges } from "./pokemon-forms"; +import { pokemonEvolutions } from "./balance/pokemon-evolutions"; /** A constant for the default max cost of the starting party before a run */ const DEFAULT_PARTY_MAX_COST = 10; @@ -285,15 +286,9 @@ export abstract class Challenge { * @param _pokemon {@link PokemonSpecies} The pokemon to check the validity of. * @param _valid {@link Utils.BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed. * @param _dexAttr {@link DexAttrProps} The dex attributes of the pokemon. - * @param _soft {@link boolean} If true, allow it if it could become a valid pokemon. * @returns {@link boolean} Whether this function did anything. */ - applyStarterChoice( - _pokemon: PokemonSpecies, - _valid: Utils.BooleanHolder, - _dexAttr: DexAttrProps, - _soft = false, - ): boolean { + applyStarterChoice(_pokemon: PokemonSpecies, _valid: Utils.BooleanHolder, _dexAttr: DexAttrProps): boolean { return false; } @@ -445,27 +440,8 @@ export class SingleGenerationChallenge extends Challenge { super(Challenges.SINGLE_GENERATION, 9); } - applyStarterChoice( - pokemon: PokemonSpecies, - valid: Utils.BooleanHolder, - _dexAttr: DexAttrProps, - soft = false, - ): boolean { - const generations = [pokemon.generation]; - if (soft) { - const speciesToCheck = [pokemon.speciesId]; - while (speciesToCheck.length) { - const checking = speciesToCheck.pop(); - if (checking && pokemonEvolutions.hasOwnProperty(checking)) { - pokemonEvolutions[checking].forEach(e => { - speciesToCheck.push(e.speciesId); - generations.push(getPokemonSpecies(e.speciesId).generation); - }); - } - } - } - - if (!generations.includes(this.value)) { + applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean { + if (pokemon.generation !== this.value) { valid.value = false; return true; } @@ -474,7 +450,7 @@ export class SingleGenerationChallenge extends Challenge { applyPokemonInBattle(pokemon: Pokemon, valid: Utils.BooleanHolder): boolean { const baseGeneration = getPokemonSpecies(pokemon.species.speciesId).generation; - const fusionGeneration = pokemon.isFusion() ? getPokemonSpecies(pokemon.fusionSpecies!.speciesId).generation : 0; // TODO: is the bang on fusionSpecies correct? + const fusionGeneration = pokemon.isFusion() ? getPokemonSpecies(pokemon.fusionSpecies!.speciesId).generation : 0; if ( pokemon.isPlayer() && (baseGeneration !== this.value || (pokemon.isFusion() && fusionGeneration !== this.value)) @@ -739,41 +715,14 @@ export class SingleTypeChallenge extends Challenge { { species: Species.CASTFORM, type: PokemonType.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]; constructor() { super(Challenges.SINGLE_TYPE, 18); } - override applyStarterChoice( - pokemon: PokemonSpecies, - valid: Utils.BooleanHolder, - dexAttr: DexAttrProps, - soft = false, - ): boolean { + override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps): boolean { const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex); const types = [speciesForm.type1, speciesForm.type2]; - if (soft && !SingleTypeChallenge.SPECIES_OVERRIDES.includes(pokemon.speciesId)) { - const speciesToCheck = [pokemon.speciesId]; - while (speciesToCheck.length) { - const checking = speciesToCheck.pop(); - if (checking && pokemonEvolutions.hasOwnProperty(checking)) { - pokemonEvolutions[checking].forEach(e => { - speciesToCheck.push(e.speciesId); - types.push(getPokemonSpecies(e.speciesId).type1, getPokemonSpecies(e.speciesId).type2); - }); - } - if (checking && pokemonFormChanges.hasOwnProperty(checking)) { - pokemonFormChanges[checking].forEach(f1 => { - getPokemonSpecies(checking).forms.forEach(f2 => { - if (f1.formKey === f2.formKey) { - types.push(f2.type1, f2.type2); - } - }); - }); - } - } - } if (!types.includes(this.value - 1)) { valid.value = false; return true; @@ -1030,7 +979,6 @@ export class LowerStarterPointsChallenge extends Challenge { * @param pokemon {@link PokemonSpecies} The pokemon to check the validity of. * @param valid {@link Utils.BooleanHolder} A BooleanHolder, the value gets set to false if the pokemon isn't allowed. * @param dexAttr {@link DexAttrProps} The dex attributes of the pokemon. - * @param soft {@link boolean} If true, allow it if it could become a valid pokemon. * @returns True if any challenge was successfully applied. */ export function applyChallenges( @@ -1039,7 +987,6 @@ export function applyChallenges( pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, - soft: boolean, ): boolean; /** * Apply all challenges that modify available total starter points. @@ -1222,7 +1169,7 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType if (c.value !== 0) { switch (challengeType) { case ChallengeType.STARTER_CHOICE: - ret ||= c.applyStarterChoice(args[0], args[1], args[2], args[3]); + ret ||= c.applyStarterChoice(args[0], args[1], args[2]); break; case ChallengeType.STARTER_POINTS: ret ||= c.applyStarterPoints(args[0]); @@ -1305,3 +1252,87 @@ export function initChallenges() { new FlipStatChallenge(), ); } + +/** + * Apply all challenges to the given starter (and form) to check its validity. + * Differs from {@linkcode checkSpeciesValidForChallenge} which only checks form changes. + * @param species - The {@linkcode PokemonSpecies} to check the validity of. + * @param dexAttr - The {@linkcode DexAttrProps | dex attributes} of the species, including its form index. + * @param soft - If `true`, allow it if it could become valid through evolution or form change. + * @returns `true` if the species is considered valid. + */ +export function checkStarterValidForChallenge(species: PokemonSpecies, props: DexAttrProps, soft: boolean) { + if (!soft) { + const isValidForChallenge = new Utils.BooleanHolder(true); + applyChallenges(globalScene.gameMode, ChallengeType.STARTER_CHOICE, species, isValidForChallenge, props); + return isValidForChallenge.value; + } + // We check the validity of every evolution and form change, and require that at least one is valid + const speciesToCheck = [species.speciesId]; + while (speciesToCheck.length) { + const checking = speciesToCheck.pop(); + // Linter complains if we don't handle this + if (!checking) { + return false; + } + const checkingSpecies = getPokemonSpecies(checking); + if (checkSpeciesValidForChallenge(checkingSpecies, props, true)) { + return true; + } + if (checking && pokemonEvolutions.hasOwnProperty(checking)) { + pokemonEvolutions[checking].forEach(e => { + // Form check to deal with cases such as Basculin -> Basculegion + // TODO: does this miss anything if checking forms of a stage 2 Pokémon? + if (!e?.preFormKey || e.preFormKey === species.forms[props.formIndex].formKey) { + speciesToCheck.push(e.speciesId); + } + }); + } + } + return false; +} + +/** + * Apply all challenges to the given species (and form) to check its validity. + * Differs from {@linkcode checkStarterValidForChallenge} which also checks evolutions. + * @param species - The {@linkcode PokemonSpecies} to check the validity of. + * @param dexAttr - The {@linkcode DexAttrProps | dex attributes} of the species, including its form index. + * @param soft - If `true`, allow it if it could become valid through a form change. + * @returns `true` if the species is considered valid. + */ +function checkSpeciesValidForChallenge(species: PokemonSpecies, props: DexAttrProps, soft: boolean) { + const isValidForChallenge = new Utils.BooleanHolder(true); + applyChallenges(globalScene.gameMode, ChallengeType.STARTER_CHOICE, species, isValidForChallenge, props); + if (!soft || !pokemonFormChanges.hasOwnProperty(species.speciesId)) { + return isValidForChallenge.value; + } + // If the form in props is valid, return true before checking other form changes + if (soft && isValidForChallenge.value) { + return true; + } + pokemonFormChanges[species.speciesId].forEach(f1 => { + // Exclude form changes that require the mon to be on the field to begin with, + // such as Castform + if (!("item" in f1)) { + return; + } + species.forms.forEach((f2, formIndex) => { + if (f1.formKey === f2.formKey) { + const formProps = { ...props }; + formProps.formIndex = formIndex; + const isFormValidForChallenge = new Utils.BooleanHolder(true); + applyChallenges( + globalScene.gameMode, + ChallengeType.STARTER_CHOICE, + species, + isFormValidForChallenge, + formProps, + ); + if (isFormValidForChallenge.value) { + return true; + } + } + }); + }); + return false; +} diff --git a/src/data/dialogue.ts b/src/data/dialogue.ts index 208e269bd9c..fa640e92b00 100644 --- a/src/data/dialogue.ts +++ b/src/data/dialogue.ts @@ -1,6 +1,6 @@ import { BattleSpec } from "#enums/battle-spec"; import { TrainerType } from "#enums/trainer-type"; -import { trainerConfigs } from "./trainer-config"; +import { trainerConfigs } from "./trainers/trainer-config"; export interface TrainerTypeMessages { encounter?: string | string[]; @@ -312,6 +312,113 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { victory: ["dialogue:sailor.victory.1", "dialogue:sailor.victory.2", "dialogue:sailor.victory.3"], }, ], + [TrainerType.CLERK]: [ + { + encounter: ["dialogue:clerk.encounter.1", "dialogue:clerk.encounter.2", "dialogue:clerk.encounter.3"], + victory: ["dialogue:clerk.victory.1", "dialogue:clerk.victory.2", "dialogue:clerk.victory.3"], + }, + { + encounter: [ + "dialogue:clerk_female.encounter.1", + "dialogue:clerk_female.encounter.2", + "dialogue:clerk_female.encounter.3", + ], + victory: [ + "dialogue:clerk_female.victory.1", + "dialogue:clerk_female.victory.2", + "dialogue:clerk_female.victory.3", + ], + }, + ], + [TrainerType.HOOLIGANS]: [ + { + encounter: ["dialogue:hooligans.encounter.1", "dialogue:hooligans.encounter.2"], + victory: ["dialogue:hooligans.victory.1", "dialogue:hooligans.victory.2"], + }, + ], + [TrainerType.MUSICIAN]: [ + { + encounter: [ + "dialogue:musician.encounter.1", + "dialogue:musician.encounter.2", + "dialogue:musician.encounter.3", + "dialogue:musician.encounter.4", + ], + victory: ["dialogue:musician.victory.1", "dialogue:musician.victory.2", "dialogue:musician.victory.3"], + }, + ], + [TrainerType.PILOT]: [ + { + encounter: [ + "dialogue:pilot.encounter.1", + "dialogue:pilot.encounter.2", + "dialogue:pilot.encounter.3", + "dialogue:pilot.encounter.4", + ], + victory: [ + "dialogue:pilot.victory.1", + "dialogue:pilot.victory.2", + "dialogue:pilot.victory.3", + "dialogue:pilot.victory.4", + ], + }, + ], + [TrainerType.POKEFAN]: [ + { + encounter: ["dialogue:pokefan.encounter.1", "dialogue:pokefan.encounter.2", "dialogue:pokefan.encounter.3"], + victory: ["dialogue:pokefan.victory.1", "dialogue:pokefan.victory.2", "dialogue:pokefan.victory.3"], + }, + { + encounter: [ + "dialogue:pokefan_female.encounter.1", + "dialogue:pokefan_female.encounter.2", + "dialogue:pokefan_female.encounter.3", + ], + victory: [ + "dialogue:pokefan_female.victory.1", + "dialogue:pokefan_female.victory.2", + "dialogue:pokefan_female.victory.3", + ], + }, + ], + [TrainerType.RICH]: [ + { + encounter: ["dialogue:rich.encounter.1", "dialogue:rich.encounter.2", "dialogue:rich.encounter.3"], + victory: ["dialogue:rich.victory.1", "dialogue:rich.victory.2", "dialogue:rich.victory.3"], + }, + { + encounter: [ + "dialogue:rich_female.encounter.1", + "dialogue:rich_female.encounter.2", + "dialogue:rich_female.encounter.3", + ], + victory: ["dialogue:rich_female.victory.1", "dialogue:rich_female.victory.2", "dialogue:rich_female.victory.3"], + }, + ], + [TrainerType.RICH_KID]: [ + { + encounter: ["dialogue:rich_kid.encounter.1", "dialogue:rich_kid.encounter.2", "dialogue:rich_kid.encounter.3"], + victory: [ + "dialogue:rich_kid.victory.1", + "dialogue:rich_kid.victory.2", + "dialogue:rich_kid.victory.3", + "dialogue:rich_kid.victory.4", + ], + }, + { + encounter: [ + "dialogue:rich_kid_female.encounter.1", + "dialogue:rich_kid_female.encounter.2", + "dialogue:rich_kid_female.encounter.3", + ], + victory: [ + "dialogue:rich_kid_female.victory.1", + "dialogue:rich_kid_female.victory.2", + "dialogue:rich_kid_female.victory.3", + "dialogue:rich_kid_female.victory.4", + ], + }, + ], [TrainerType.ROCKET_GRUNT]: [ { encounter: [ diff --git a/src/data/moves/invalid-moves.ts b/src/data/moves/invalid-moves.ts index 50f815b9e58..5cd45de7939 100644 --- a/src/data/moves/invalid-moves.ts +++ b/src/data/moves/invalid-moves.ts @@ -3,144 +3,46 @@ import { Moves } from "#enums/moves"; /** Set of moves that cannot be called by {@linkcode Moves.METRONOME Metronome} */ export const invalidMetronomeMoves: ReadonlySet = new Set([ Moves.AFTER_YOU, - Moves.APPLE_ACID, - Moves.ARMOR_CANNON, Moves.ASSIST, - Moves.ASTRAL_BARRAGE, - Moves.AURA_WHEEL, Moves.BANEFUL_BUNKER, Moves.BEAK_BLAST, - Moves.BEHEMOTH_BASH, - Moves.BEHEMOTH_BLADE, Moves.BELCH, Moves.BESTOW, - Moves.BLAZING_TORQUE, - Moves.BODY_PRESS, - Moves.BRANCH_POKE, - Moves.BREAKING_SWIPE, - Moves.CELEBRATE, - Moves.CHATTER, - Moves.CHILLING_WATER, - Moves.CHILLY_RECEPTION, - Moves.CLANGOROUS_SOUL, - Moves.COLLISION_COURSE, - Moves.COMBAT_TORQUE, Moves.COMEUPPANCE, Moves.COPYCAT, Moves.COUNTER, - Moves.COVET, Moves.CRAFTY_SHIELD, - Moves.DECORATE, Moves.DESTINY_BOND, Moves.DETECT, - Moves.DIAMOND_STORM, - Moves.DOODLE, - Moves.DOUBLE_IRON_BASH, - Moves.DOUBLE_SHOCK, - Moves.DRAGON_ASCENT, - Moves.DRAGON_ENERGY, - Moves.DRUM_BEATING, - Moves.DYNAMAX_CANNON, - Moves.ELECTRO_DRIFT, Moves.ENDURE, - Moves.ETERNABEAM, - Moves.FALSE_SURRENDER, Moves.FEINT, - Moves.FIERY_WRATH, - Moves.FILLET_AWAY, - Moves.FLEUR_CANNON, Moves.FOCUS_PUNCH, Moves.FOLLOW_ME, - Moves.FREEZE_SHOCK, - Moves.FREEZING_GLARE, - Moves.GLACIAL_LANCE, - Moves.GRAV_APPLE, Moves.HELPING_HAND, - Moves.HOLD_HANDS, - Moves.HYPER_DRILL, - Moves.HYPERSPACE_FURY, - Moves.HYPERSPACE_HOLE, - Moves.ICE_BURN, Moves.INSTRUCT, - Moves.JET_PUNCH, - Moves.JUNGLE_HEALING, Moves.KINGS_SHIELD, - Moves.LIFE_DEW, - Moves.LIGHT_OF_RUIN, - Moves.MAKE_IT_RAIN, - Moves.MAGICAL_TORQUE, Moves.MAT_BLOCK, Moves.ME_FIRST, - Moves.METEOR_ASSAULT, Moves.METRONOME, Moves.MIMIC, - Moves.MIND_BLOWN, Moves.MIRROR_COAT, Moves.MIRROR_MOVE, - Moves.MOONGEIST_BEAM, - Moves.NATURE_POWER, - Moves.NATURES_MADNESS, - Moves.NOXIOUS_TORQUE, Moves.OBSTRUCT, - Moves.ORDER_UP, - Moves.ORIGIN_PULSE, - Moves.OVERDRIVE, - Moves.PHOTON_GEYSER, - Moves.PLASMA_FISTS, - Moves.POPULATION_BOMB, - Moves.POUNCE, - Moves.POWER_SHIFT, - Moves.PRECIPICE_BLADES, Moves.PROTECT, - Moves.PYRO_BALL, Moves.QUASH, Moves.QUICK_GUARD, - Moves.RAGE_FIST, Moves.RAGE_POWDER, - Moves.RAGING_BULL, - Moves.RAGING_FURY, - Moves.RELIC_SONG, Moves.REVIVAL_BLESSING, - Moves.RUINATION, - Moves.SALT_CURE, - Moves.SECRET_SWORD, - Moves.SHED_TAIL, Moves.SHELL_TRAP, Moves.SILK_TRAP, Moves.SKETCH, Moves.SLEEP_TALK, - Moves.SNAP_TRAP, - Moves.SNARL, Moves.SNATCH, Moves.SNORE, - Moves.SNOWSCAPE, - Moves.SPECTRAL_THIEF, - Moves.SPICY_EXTRACT, Moves.SPIKY_SHIELD, - Moves.SPIRIT_BREAK, Moves.SPOTLIGHT, - Moves.STEAM_ERUPTION, - Moves.STEEL_BEAM, - Moves.STRANGE_STEAM, Moves.STRUGGLE, - Moves.SUNSTEEL_STRIKE, - Moves.SURGING_STRIKES, - Moves.SWITCHEROO, - Moves.TECHNO_BLAST, - Moves.TERA_STARSTORM, - Moves.THIEF, - Moves.THOUSAND_ARROWS, - Moves.THOUSAND_WAVES, - Moves.THUNDER_CAGE, - Moves.THUNDEROUS_KICK, - Moves.TIDY_UP, - Moves.TRAILBLAZE, Moves.TRANSFORM, - Moves.TRICK, - Moves.TWIN_BEAM, - Moves.V_CREATE, - Moves.WICKED_BLOW, - Moves.WICKED_TORQUE, Moves.WIDE_GUARD, ]); @@ -157,7 +59,6 @@ export const invalidAssistMoves: ReadonlySet = new Set([ Moves.CIRCLE_THROW, Moves.COPYCAT, Moves.COUNTER, - Moves.COVET, Moves.DESTINY_BOND, Moves.DETECT, Moves.DIG, @@ -192,7 +93,6 @@ export const invalidAssistMoves: ReadonlySet = new Set([ Moves.SPOTLIGHT, Moves.STRUGGLE, Moves.SWITCHEROO, - Moves.THIEF, Moves.TRANSFORM, Moves.TRICK, Moves.WHIRLWIND, @@ -208,7 +108,6 @@ export const invalidSleepTalkMoves: ReadonlySet = new Set([ Moves.COPYCAT, Moves.DIG, Moves.DIVE, - Moves.DYNAMAX_CANNON, Moves.FREEZE_SHOCK, Moves.FLY, Moves.FOCUS_PUNCH, @@ -238,15 +137,12 @@ export const invalidCopycatMoves: ReadonlySet = new Set([ Moves.ASSIST, Moves.BANEFUL_BUNKER, Moves.BEAK_BLAST, - Moves.BEHEMOTH_BASH, - Moves.BEHEMOTH_BLADE, Moves.BESTOW, Moves.CELEBRATE, Moves.CHATTER, Moves.CIRCLE_THROW, Moves.COPYCAT, Moves.COUNTER, - Moves.COVET, Moves.DESTINY_BOND, Moves.DETECT, Moves.DRAGON_TAIL, @@ -274,8 +170,73 @@ export const invalidCopycatMoves: ReadonlySet = new Set([ Moves.SPOTLIGHT, Moves.STRUGGLE, Moves.SWITCHEROO, - Moves.THIEF, Moves.TRANSFORM, Moves.TRICK, Moves.WHIRLWIND, ]); + +export const invalidMirrorMoveMoves: ReadonlySet = new Set([ + Moves.ACUPRESSURE, + Moves.AFTER_YOU, + Moves.AROMATIC_MIST, + Moves.BEAK_BLAST, + Moves.BELCH, + Moves.CHILLY_RECEPTION, + Moves.COACHING, + Moves.CONVERSION_2, + Moves.COUNTER, + Moves.CRAFTY_SHIELD, + Moves.CURSE, + Moves.DECORATE, + Moves.DOODLE, + Moves.DOOM_DESIRE, + Moves.DRAGON_CHEER, + Moves.ELECTRIC_TERRAIN, + Moves.FINAL_GAMBIT, + Moves.FLORAL_HEALING, + Moves.FLOWER_SHIELD, + Moves.FOCUS_PUNCH, + Moves.FUTURE_SIGHT, + Moves.GEAR_UP, + Moves.GRASSY_TERRAIN, + Moves.GRAVITY, + Moves.GUARD_SPLIT, + Moves.HAIL, + Moves.HAZE, + Moves.HEAL_PULSE, + Moves.HELPING_HAND, + Moves.HOLD_HANDS, + Moves.INSTRUCT, + Moves.ION_DELUGE, + Moves.MAGNETIC_FLUX, + Moves.MAT_BLOCK, + Moves.ME_FIRST, + Moves.MIMIC, + Moves.MIRROR_COAT, + Moves.MIRROR_MOVE, + Moves.MIST, + Moves.MISTY_TERRAIN, + Moves.MUD_SPORT, + Moves.PERISH_SONG, + Moves.POWER_SPLIT, + Moves.PSYCH_UP, + Moves.PSYCHIC_TERRAIN, + Moves.PURIFY, + Moves.QUICK_GUARD, + Moves.RAIN_DANCE, + Moves.REFLECT_TYPE, + Moves.ROLE_PLAY, + Moves.ROTOTILLER, + Moves.SANDSTORM, + Moves.SHELL_TRAP, + Moves.SKETCH, + Moves.SNOWSCAPE, + Moves.SPIT_UP, + Moves.SPOTLIGHT, + Moves.STRUGGLE, + Moves.SUNNY_DAY, + Moves.TEATIME, + Moves.TRANSFORM, + Moves.WATER_SPORT, + Moves.WIDE_GUARD, +]); diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index b40f35191f5..6d7a2da091c 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -16,6 +16,7 @@ import type { AttackMoveResult, TurnMove } from "../../field/pokemon"; import type Pokemon from "../../field/pokemon"; import { EnemyPokemon, + FieldPosition, HitResult, MoveResult, PlayerPokemon, @@ -125,7 +126,7 @@ import { MoveTarget } from "#enums/MoveTarget"; import { MoveFlags } from "#enums/MoveFlags"; import { MoveEffectTrigger } from "#enums/MoveEffectTrigger"; import { MultiHitType } from "#enums/MultiHitType"; -import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidSleepTalkMoves } from "./invalid-moves"; +import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves"; type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean; type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean; @@ -904,7 +905,7 @@ export default class Move implements Localizable { SacrificialAttrOnHit ]; - // ...and cannot enhance these specific moves. + // ...and cannot enhance these specific moves const exceptMoves: Moves[] = [ Moves.FLING, Moves.UPROAR, @@ -913,10 +914,14 @@ export default class Move implements Localizable { Moves.ENDEAVOR ]; + // ...and cannot enhance Pollen Puff when targeting an ally. + const exceptPollenPuffAlly: boolean = this.id === Moves.POLLEN_PUFF && targets.includes(user.getAlly().getBattlerIndex()) + return (!restrictSpread || !isMultiTarget) && !this.isChargingMove() && !exceptAttrs.some(attr => this.hasAttr(attr)) && !exceptMoves.some(id => this.id === id) + && !exceptPollenPuffAlly && this.category !== MoveCategory.STATUS; } } @@ -1232,7 +1237,7 @@ export class MoveEffectAttr extends MoveAttr { getMoveChance(user: Pokemon, target: Pokemon, move: Move, selfEffect?: Boolean, showAbility?: Boolean): number { const moveChance = new Utils.NumberHolder(this.effectChanceOverride ?? move.chance); - applyAbAttrs(MoveEffectChanceMultiplierAbAttr, user, null, false, moveChance, move, target, selfEffect, showAbility); + applyAbAttrs(MoveEffectChanceMultiplierAbAttr, user, null, !showAbility, moveChance, move); if ((!move.hasAttr(FlinchAttr) || moveChance.value <= move.chance) && !move.hasAttr(SecretPowerAttr)) { const userSide = user.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; @@ -1240,7 +1245,7 @@ export class MoveEffectAttr extends MoveAttr { } if (!selfEffect) { - applyPreDefendAbAttrs(IgnoreMoveEffectsAbAttr, target, user, null, null, false, moveChance); + applyPreDefendAbAttrs(IgnoreMoveEffectsAbAttr, target, user, null, null, !showAbility, moveChance); } return moveChance.value; } @@ -1579,10 +1584,6 @@ export class SurviveDamageAttr extends ModifiedDamageAttr { return Math.min(damage, target.hp - 1); } - getCondition(): MoveConditionFunc { - return (user, target, move) => target.hp > 1; - } - getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { return target.hp > 1 ? 0 : -20; } @@ -1646,7 +1647,7 @@ export class RecoilAttr extends MoveEffectAttr { return false; } - user.damageAndUpdate(recoilDamage, HitResult.OTHER, false, true, true); + user.damageAndUpdate(recoilDamage, { result: HitResult.INDIRECT, ignoreSegments: true }); globalScene.queueMessage(i18next.t("moveTriggers:hitWithRecoil", { pokemonName: getPokemonNameWithAffix(user) })); user.turnData.damageTaken += recoilDamage; @@ -1678,7 +1679,7 @@ export class SacrificialAttr extends MoveEffectAttr { * @returns true if the function succeeds **/ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - user.damageAndUpdate(user.hp, HitResult.OTHER, false, true, true); + user.damageAndUpdate(user.hp, { result: HitResult.INDIRECT, ignoreSegments: true }); user.turnData.damageTaken += user.hp; return true; @@ -1716,7 +1717,7 @@ export class SacrificialAttrOnHit extends MoveEffectAttr { return false; } - user.damageAndUpdate(user.hp, HitResult.OTHER, false, true, true); + user.damageAndUpdate(user.hp, { result: HitResult.INDIRECT, ignoreSegments: true }); user.turnData.damageTaken += user.hp; return true; @@ -1758,7 +1759,7 @@ 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.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), { result: HitResult.INDIRECT, ignoreSegments: true }); globalScene.queueMessage(i18next.t("moveTriggers:cutHpPowerUpMove", { pokemonName: getPokemonNameWithAffix(user) })); // Queue recoil message } return true; @@ -1805,7 +1806,7 @@ export class AddSubstituteAttr extends MoveEffectAttr { } const damageTaken = this.roundUp ? Math.ceil(user.getMaxHp() * this.hpCost) : Math.floor(user.getMaxHp() * this.hpCost); - user.damageAndUpdate(damageTaken, HitResult.OTHER, false, true, true); + user.damageAndUpdate(damageTaken, { result: HitResult.INDIRECT, ignoreSegments: true, ignoreFaintPhase: true }); user.addTag(BattlerTagType.SUBSTITUTE, 0, move.id, user.id); return true; } @@ -1880,14 +1881,14 @@ export class HealAttr extends MoveEffectAttr { */ export class PartyStatusCureAttr extends MoveEffectAttr { /** Message to display after using move */ - private message: string; + private message: string | null; /** Skips mons with this ability, ie. Soundproof */ private abilityCondition: Abilities; constructor(message: string | null, abilityCondition: Abilities) { super(); - this.message = message!; // TODO: is this bang correct? + this.message = message; this.abilityCondition = abilityCondition; } @@ -1955,7 +1956,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())), { result: HitResult.INDIRECT }); return true; } @@ -2102,10 +2103,10 @@ export class BoostHealAttr extends HealAttr { /** The lambda expression to check against when boosting the healing value */ private condition?: MoveConditionFunc; - constructor(normalHealRatio?: number, boostedHealRatio?: number, showAnim?: boolean, selfTarget?: boolean, condition?: MoveConditionFunc) { + constructor(normalHealRatio: number = 0.5, boostedHealRatio: number = 2 / 3, showAnim?: boolean, selfTarget?: boolean, condition?: MoveConditionFunc) { super(normalHealRatio, showAnim, selfTarget); - this.normalHealRatio = normalHealRatio!; // TODO: is this bang correct? - this.boostedHealRatio = boostedHealRatio!; // TODO: is this bang correct? + this.normalHealRatio = normalHealRatio; + this.boostedHealRatio = boostedHealRatio; this.condition = condition; } @@ -2844,7 +2845,7 @@ export class WeatherChangeAttr extends MoveEffectAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - return globalScene.arena.trySetWeather(this.weatherType, true); + return globalScene.arena.trySetWeather(this.weatherType, user); } getCondition(): MoveConditionFunc { @@ -2863,7 +2864,7 @@ export class ClearWeatherAttr extends MoveEffectAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { if (globalScene.arena.weather?.weatherType === this.weatherType) { - return globalScene.arena.trySetWeather(WeatherType.NONE, true); + return globalScene.arena.trySetWeather(WeatherType.NONE, user); } return false; @@ -2880,7 +2881,7 @@ export class TerrainChangeAttr extends MoveEffectAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - return globalScene.arena.trySetTerrain(this.terrainType, true, true); + return globalScene.arena.trySetTerrain(this.terrainType, true, user); } getCondition(): MoveConditionFunc { @@ -2899,7 +2900,7 @@ export class ClearTerrainAttr extends MoveEffectAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - return globalScene.arena.trySetTerrain(TerrainType.NONE, true, true); + return globalScene.arena.trySetTerrain(TerrainType.NONE, true, user); } } @@ -3367,14 +3368,14 @@ export class SecretPowerAttr extends MoveEffectAttr { export class PostVictoryStatStageChangeAttr extends MoveAttr { private stats: BattleStat[]; private stages: number; - private condition: MoveConditionFunc | null; + private condition?: MoveConditionFunc; private showMessage: boolean; constructor(stats: BattleStat[], stages: number, selfTarget?: boolean, condition?: MoveConditionFunc, showMessage: boolean = true, firstHitOnly: boolean = false) { super(); this.stats = stats; this.stages = stages; - this.condition = condition!; // TODO: is this bang correct? + this.condition = condition; this.showMessage = showMessage; } applyPostVictory(user: Pokemon, target: Pokemon, move: Move): void { @@ -3428,9 +3429,8 @@ export class CutHpStatStageBoostAttr extends StatStageChangeAttr { this.cutRatio = cutRatio; this.messageCallback = messageCallback; } - override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / this.cutRatio), HitResult.OTHER, false, true); + user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / this.cutRatio), { result: HitResult.INDIRECT }); user.updateInfo(); const ret = super.apply(user, target, move, args); if (this.messageCallback) { @@ -3647,7 +3647,7 @@ export class LessPPMorePowerAttr extends VariablePowerAttr { */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const ppMax = move.pp; - const ppUsed = user.moveset.find((m) => m?.moveId === move.id)?.ppUsed!; // TODO: is the bang correct? + const ppUsed = user.moveset.find((m) => m.moveId === move.id)?.ppUsed ?? 0; let ppRemains = ppMax - ppUsed; /** Reduce to 0 to avoid negative numbers if user has 1PP before attack and target has Ability.PRESSURE */ @@ -3773,7 +3773,13 @@ export abstract class ConsecutiveUsePowerMultiplierAttr extends MovePowerMultipl let count = 0; let turnMove: TurnMove | undefined; - while (((turnMove = moveHistory.shift())?.move === move.id || (comboMoves.length && comboMoves.includes(turnMove?.move!))) && (!resetOnFail || turnMove?.result === MoveResult.SUCCESS)) { // TODO: is this bang correct? + while ( + ( + (turnMove = moveHistory.shift())?.move === move.id + || (comboMoves.length && comboMoves.includes(turnMove?.move ?? Moves.NONE)) + ) + && (!resetOnFail || turnMove?.result === MoveResult.SUCCESS) + ) { if (count < (limit - 1)) { count++; } else if (resetOnLimit) { @@ -4359,8 +4365,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 { @@ -4786,8 +4792,8 @@ export class ShellSideArmCategoryAttr extends VariableMoveCategoryAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const category = (args[0] as Utils.NumberHolder); - const predictedPhysDmg = target.getBaseDamage(user, move, MoveCategory.PHYSICAL, true, true); - const predictedSpecDmg = target.getBaseDamage(user, move, MoveCategory.SPECIAL, true, true); + const predictedPhysDmg = target.getBaseDamage(user, move, MoveCategory.PHYSICAL, true, true, true, true); + const predictedSpecDmg = target.getBaseDamage(user, move, MoveCategory.SPECIAL, true, true, true, true); if (predictedPhysDmg > predictedSpecDmg) { category.value = MoveCategory.PHYSICAL; @@ -5322,7 +5328,7 @@ const crashDamageFunc = (user: Pokemon, move: Move) => { return false; } - user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), HitResult.OTHER, false, true); + user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), { result: HitResult.INDIRECT }); globalScene.queueMessage(i18next.t("moveTriggers:keptGoingAndCrashed", { pokemonName: getPokemonNameWithAffix(user) })); user.turnData.damageTaken += Utils.toDmgValue(user.getMaxHp() / 2); @@ -5455,7 +5461,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr { : null; } - getTagTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number | void { + getTagTargetBenefitScore(): number { switch (this.tagType) { case BattlerTagType.RECHARGING: case BattlerTagType.PERISH_SONG: @@ -5500,6 +5506,9 @@ export class AddBattlerTagAttr extends MoveEffectAttr { case BattlerTagType.CRIT_BOOST: case BattlerTagType.ALWAYS_CRIT: return 5; + default: + console.warn(`BattlerTag ${BattlerTagType[this.tagType]} is missing a score!`); + return 0; } } @@ -5508,7 +5517,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr { if (moveChance < 0) { moveChance = 100; } - return Math.floor(this.getTagTargetBenefitScore(user, target, move)! * (moveChance / 100)); // TODO: is the bang correct? + return Math.floor(this.getTagTargetBenefitScore() * (moveChance / 100)); } } @@ -5536,6 +5545,31 @@ export class LeechSeedAttr extends AddBattlerTagAttr { } } +/** + * Adds the appropriate battler tag for Smack Down and Thousand arrows + * @extends AddBattlerTagAttr + */ +export class FallDownAttr extends AddBattlerTagAttr { + constructor() { + super(BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true); + } + + /** + * Adds Grounded Tag to the target and checks if fallDown message should be displayed + * @param user the {@linkcode Pokemon} using the move + * @param target the {@linkcode Pokemon} targeted by the move + * @param move the {@linkcode Move} invoking this effect + * @param args n/a + * @returns `true` if the effect successfully applies; `false` otherwise + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (!target.isGrounded()) { + globalScene.queueMessage(i18next.t("moveTriggers:fallDown", { targetPokemonName: getPokemonNameWithAffix(target) })); + } + return super.apply(user, target, move, args); + } +} + /** * Adds the appropriate battler tag for Gulp Missile when Surf or Dive is used. * @extends MoveEffectAttr @@ -5618,7 +5652,7 @@ export class CurseAttr extends MoveEffectAttr { return false; } const curseRecoilDamage = Math.max(1, Math.floor(user.getMaxHp() / 2)); - user.damageAndUpdate(curseRecoilDamage, HitResult.OTHER, false, true, true); + user.damageAndUpdate(curseRecoilDamage, { result: HitResult.INDIRECT, ignoreSegments: true }); globalScene.queueMessage( i18next.t("battlerTags:cursedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(user), @@ -5738,7 +5772,7 @@ export class ProtectAttr extends AddBattlerTagAttr { while (moveHistory.length) { turnMove = moveHistory.shift(); - if (!allMoves[turnMove?.move!].hasAttr(ProtectAttr) || turnMove?.result !== MoveResult.SUCCESS) { // TODO: is the bang correct? + if (!allMoves[turnMove?.move ?? Moves.NONE].hasAttr(ProtectAttr) || turnMove?.result !== MoveResult.SUCCESS) { break; } timesUsed++; @@ -6127,9 +6161,16 @@ export class RevivalBlessingAttr extends MoveEffectAttr { if (globalScene.currentBattle.double && globalScene.getEnemyParty().length > 1) { const allyPokemon = user.getAlly(); - if (slotIndex <= 1) { - globalScene.unshiftPhase(new SwitchSummonPhase(SwitchType.SWITCH, pokemon.getFieldIndex(), slotIndex, false, false)); - } else if (allyPokemon.isFainted()) { + // Handle cases where revived pokemon needs to get switched in on same turn + if (allyPokemon.isFainted() || allyPokemon === pokemon) { + // Enemy switch phase should be removed and replaced with the revived pkmn switching in + globalScene.tryRemovePhase((phase: SwitchSummonPhase) => phase instanceof SwitchSummonPhase && phase.getPokemon() === pokemon); + // If the pokemon being revived was alive earlier in the turn, cancel its move + // (revived pokemon can't move in the turn they're brought back) + globalScene.findPhase((phase: MovePhase) => phase.pokemon === pokemon)?.cancel(); + if (user.fieldPosition === FieldPosition.CENTER) { + user.setFieldPosition(FieldPosition.LEFT); + } globalScene.unshiftPhase(new SwitchSummonPhase(SwitchType.SWITCH, allyPokemon.getFieldIndex(), slotIndex, false, false)); } } @@ -6407,7 +6448,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { export class ChillyReceptionAttr extends ForceSwitchOutAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - globalScene.arena.trySetWeather(WeatherType.SNOW, true); + globalScene.arena.trySetWeather(WeatherType.SNOW, user); return super.apply(user, target, move, args); } @@ -6650,7 +6691,7 @@ export class FirstMoveTypeAttr extends MoveEffectAttr { return false; } - const firstMoveType = target.getMoveset()[0]?.getMove().type!; // TODO: is this bang correct? + const firstMoveType = target.getMoveset()[0].getMove().type; user.summonData.types = [ firstMoveType ]; globalScene.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: i18next.t(`pokemonInfo:Type.${PokemonType[firstMoveType]}`) })); @@ -6935,7 +6976,8 @@ export class CopyMoveAttr extends CallMoveAttr { getCondition(): MoveConditionFunc { return (user, target, move) => { if (this.mirrorMove) { - return target.getMoveHistory().length !== 0; + const lastMove = target.getLastXMoves()[0]?.move; + return !!lastMove && !this.invalidMoves.has(lastMove); } else { const lastMove = globalScene.currentBattle.lastMove; return lastMove !== undefined && !this.invalidMoves.has(lastMove); @@ -6966,7 +7008,7 @@ export class RepeatMoveAttr extends MoveEffectAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { // get the last move used (excluding status based failures) as well as the corresponding moveset slot const lastMove = target.getLastXMoves(-1).find(m => m.move !== Moves.NONE)!; - const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move)!; + const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move)!; // If the last move used can hit more than one target or has variable targets, // re-compute the targets for the attack // (mainly for alternating double/single battle shenanigans) @@ -7000,7 +7042,7 @@ export class RepeatMoveAttr extends MoveEffectAttr { getCondition(): MoveConditionFunc { return (user, target, move) => { const lastMove = target.getLastXMoves(-1).find(m => m.move !== Moves.NONE); - const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove?.move); + const movesetMove = target.getMoveset().find(m => m.moveId === lastMove?.move); const uninstructableMoves = [ // Locking/Continually Executed moves Moves.OUTRAGE, @@ -7095,19 +7137,19 @@ export class ReducePpMoveAttr extends MoveEffectAttr { * * @param user {@linkcode Pokemon} that used the attack * @param target {@linkcode Pokemon} targeted by the attack - * @param move {@linkcode Move} being used + * @param move N/A * @param args N/A - * @returns {boolean} true + * @returns `true` */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { // Null checks can be skipped due to condition function - const lastMove = target.getLastXMoves().find(() => true); - const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove?.move); - 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 lastMove = target.getLastXMoves()[0]; + const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move)!; + const lastPpUsed = movesetMove.ppUsed; + movesetMove.ppUsed = Math.min((lastPpUsed) + this.reduction, movesetMove.getMovePp()); - const message = i18next.t("battle:ppReduced", { targetName: getPokemonNameWithAffix(target), moveName: movesetMove?.getName(), reduction: (movesetMove?.ppUsed!) - lastPpUsed }); // TODO: is the bang correct? - globalScene.eventTarget.dispatchEvent(new MoveUsedEvent(target?.id, movesetMove?.getMove()!, movesetMove?.ppUsed!)); // TODO: are these bangs correct? + const message = i18next.t("battle:ppReduced", { targetName: getPokemonNameWithAffix(target), moveName: movesetMove.getName(), reduction: (movesetMove.ppUsed) - lastPpUsed }); + globalScene.eventTarget.dispatchEvent(new MoveUsedEvent(target.id, movesetMove.getMove(), movesetMove.ppUsed)); globalScene.queueMessage(message); return true; @@ -7115,9 +7157,9 @@ export class ReducePpMoveAttr extends MoveEffectAttr { getCondition(): MoveConditionFunc { return (user, target, move) => { - const lastMove = target.getLastXMoves().find(() => true); + const lastMove = target.getLastXMoves()[0]; if (lastMove) { - const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move); + const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move); return !!movesetMove?.getPpRatio(); } return false; @@ -7125,9 +7167,9 @@ export class ReducePpMoveAttr extends MoveEffectAttr { } getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { - const lastMove = target.getLastXMoves().find(() => true); + const lastMove = target.getLastXMoves()[0]; if (lastMove) { - const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move); + const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move); if (movesetMove) { const maxPp = movesetMove.getMovePp(); const ppLeft = maxPp - movesetMove.ppUsed; @@ -7164,7 +7206,7 @@ export class AttackReducePpMoveAttr extends ReducePpMoveAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const lastMove = target.getLastXMoves().find(() => true); if (lastMove) { - const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move); + const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move); if (Boolean(movesetMove?.getPpRatio())) { super.apply(user, target, move, args); } @@ -7210,7 +7252,7 @@ export class MovesetCopyMoveAttr extends OverrideMoveEffectAttr { const copiedMove = allMoves[targetMoves[0].move]; - const thisMoveIndex = user.getMoveset().findIndex(m => m?.moveId === move.id); + const thisMoveIndex = user.getMoveset().findIndex(m => m.moveId === move.id); if (thisMoveIndex === -1) { return false; @@ -7262,7 +7304,7 @@ export class SketchAttr extends MoveEffectAttr { } const sketchedMove = allMoves[targetMove.move]; - const sketchIndex = user.getMoveset().findIndex(m => m?.moveId === move.id); + const sketchIndex = user.getMoveset().findIndex(m => m.moveId === move.id); if (sketchIndex === -1) { return false; } @@ -7301,7 +7343,7 @@ export class SketchAttr extends MoveEffectAttr { return false; } - if (user.getMoveset().find(m => m?.moveId === targetMove.move)) { + if (user.getMoveset().find(m => m.moveId === targetMove.move)) { return false; } @@ -7751,7 +7793,7 @@ export class LastResortAttr extends MoveAttr { getCondition(): MoveConditionFunc { return (user: Pokemon, target: Pokemon, move: Move) => { const uniqueUsedMoveIds = new Set(); - const movesetMoveIds = user.getMoveset().map(m => m?.moveId); + const movesetMoveIds = user.getMoveset().map(m => m.moveId); user.getMoveHistory().map(m => { if (m.move !== move.id && movesetMoveIds.find(mm => mm === m.move)) { uniqueUsedMoveIds.add(m.move); @@ -8531,7 +8573,7 @@ export function initMoves() { new SelfStatusMove(Moves.METRONOME, PokemonType.NORMAL, -1, 10, -1, 0, 1) .attr(RandomMoveAttr, invalidMetronomeMoves), new StatusMove(Moves.MIRROR_MOVE, PokemonType.FLYING, -1, 20, -1, 0, 1) - .attr(CopyMoveAttr, true), + .attr(CopyMoveAttr, true, invalidMirrorMoveMoves), new AttackMove(Moves.SELF_DESTRUCT, PokemonType.NORMAL, MoveCategory.PHYSICAL, 200, 100, 5, -1, 0, 1) .attr(SacrificialAttr) .makesContact(false) @@ -9147,7 +9189,17 @@ export function initMoves() { .attr(FlinchAttr), new AttackMove(Moves.WEATHER_BALL, PokemonType.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(globalScene.arena.weather?.weatherType!) && !globalScene.arena.weather?.isEffectSuppressed() ? 2 : 1) // TODO: is this bang correct? + .attr(MovePowerMultiplierAttr, (user, target, move) => { + const weather = globalScene.arena.weather; + if (!weather) { + return 1; + } + const weatherTypes = [ WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN ]; + if (weatherTypes.includes(weather.weatherType) && !weather.isEffectSuppressed()) { + return 2; + } + return 1; + }) .ballBombMove(), new StatusMove(Moves.AROMATHERAPY, PokemonType.GRASS, -1, 5, -1, 0, 3) .attr(PartyStatusCureAttr, i18next.t("moveTriggers:soothingAromaWaftedThroughArea"), Abilities.SAP_SIPPER) @@ -9387,7 +9439,13 @@ export function initMoves() { .attr(AbilityChangeAttr, Abilities.INSOMNIA) .reflectable(), new AttackMove(Moves.SUCKER_PUNCH, PokemonType.DARK, MoveCategory.PHYSICAL, 70, 100, 5, -1, 1, 4) - .condition((user, target, move) => globalScene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[globalScene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS), // TODO: is this bang correct? + .condition((user, target, move) => { + const turnCommand = globalScene.currentBattle.turnCommands[target.getBattlerIndex()]; + if (!turnCommand || !turnCommand.move) { + return false; + } + return (turnCommand.command === Command.FIGHT && !target.turnData.acted && allMoves[turnCommand.move.move].category !== MoveCategory.STATUS); + }), new StatusMove(Moves.TOXIC_SPIKES, PokemonType.POISON, -1, 20, -1, 0, 4) .attr(AddArenaTrapTagAttr, ArenaTagType.TOXIC_SPIKES) .target(MoveTarget.ENEMY_SIDE) @@ -9640,7 +9698,7 @@ export function initMoves() { .target(MoveTarget.BOTH_SIDES) .unimplemented(), new AttackMove(Moves.SMACK_DOWN, PokemonType.ROCK, MoveCategory.PHYSICAL, 50, 100, 15, 100, 0, 5) - .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true) + .attr(FallDownAttr) .attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED) .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ]) .attr(HitsTagAttr, BattlerTagType.FLYING) @@ -10091,7 +10149,7 @@ export function initMoves() { .triageMove(), new AttackMove(Moves.THOUSAND_ARROWS, PokemonType.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) .attr(NeutralDamageAgainstFlyingTypeMultiplierAttr) - .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true) + .attr(FallDownAttr) .attr(HitsTagAttr, BattlerTagType.FLYING) .attr(HitsTagAttr, BattlerTagType.FLOATING) .attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED) @@ -10282,8 +10340,12 @@ export function initMoves() { .ignoresSubstitute(), new AttackMove(Moves.SMART_STRIKE, PokemonType.STEEL, MoveCategory.PHYSICAL, 70, -1, 10, -1, 0, 7), new StatusMove(Moves.PURIFY, PokemonType.POISON, -1, 20, -1, 0, 7) - .condition( - (user: Pokemon, target: Pokemon, move: Move) => isNonVolatileStatusEffect(target.status?.effect!)) // TODO: is this bang correct? + .condition((user, target, move) => { + if (!target.status) { + return false; + } + return isNonVolatileStatusEffect(target.status.effect); + }) .attr(HealAttr, 0.5) .attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects()) .triageMove() @@ -11002,7 +11064,13 @@ export function initMoves() { .slicingMove(), new AttackMove(Moves.HYDRO_STEAM, PokemonType.WATER, MoveCategory.SPECIAL, 80, 100, 15, -1, 0, 9) .attr(IgnoreWeatherTypeDebuffAttr, WeatherType.SUNNY) - .attr(MovePowerMultiplierAttr, (user, target, move) => [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(globalScene.arena.weather?.weatherType!) && !globalScene.arena.weather?.isEffectSuppressed() ? 1.5 : 1), // TODO: is this bang correct? + .attr(MovePowerMultiplierAttr, (user, target, move) => { + const weather = globalScene.arena.weather; + if (!weather) { + return 1; + } + return [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(weather.weatherType) && !weather.isEffectSuppressed() ? 1.5 : 1; + }), new AttackMove(Moves.RUINATION, PokemonType.DARK, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 9) .attr(TargetHalfHpDamageAttr), new AttackMove(Moves.COLLISION_COURSE, PokemonType.FIGHTING, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 9) @@ -11117,7 +11185,13 @@ export function initMoves() { .attr(ProtectAttr, BattlerTagType.BURNING_BULWARK) .condition(failIfLastCondition), new AttackMove(Moves.THUNDERCLAP, PokemonType.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, -1, 1, 9) - .condition((user, target, move) => globalScene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[globalScene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS), // TODO: is this bang correct? + .condition((user, target, move) => { + const turnCommand = globalScene.currentBattle.turnCommands[target.getBattlerIndex()]; + if (!turnCommand || !turnCommand.move) { + return false; + } + return (turnCommand.command === Command.FIGHT && !target.turnData.acted && allMoves[turnCommand.move.move].category !== MoveCategory.STATUS); + }), new AttackMove(Moves.MIGHTY_CLEAVE, PokemonType.ROCK, MoveCategory.PHYSICAL, 95, 100, 5, -1, 0, 9) .slicingMove() .ignoresProtect(), 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 6cea85346b3..a49157f8e88 100644 --- a/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts +++ b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts @@ -6,7 +6,7 @@ import { setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { trainerConfigs } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter"; diff --git a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts index ca44782691d..85f40a41e51 100644 --- a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts +++ b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts @@ -31,7 +31,7 @@ import { catchPokemon, getHighestLevelPlayerPokemon, } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { PokeballType } from "#enums/pokeball"; import type HeldModifierConfig from "#app/interfaces/held-modifier-config"; import type { BerryType } from "#enums/berry-type"; 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 15cba1fa103..1e4c9a3b957 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -9,13 +9,10 @@ import { setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { - getRandomPartyMemberFunc, - trainerConfigs, - TrainerPartyCompoundTemplate, - TrainerPartyTemplate, - TrainerSlot, -} from "#app/data/trainer-config"; +import { getRandomPartyMemberFunc, trainerConfigs } from "#app/data/trainers/trainer-config"; +import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate"; +import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; +import { TrainerSlot } from "#enums/trainer-slot"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { PartyMemberStrength } from "#enums/party-member-strength"; import { globalScene } from "#app/global-scene"; diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index 2b499d938cd..eca99fc0c13 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -8,7 +8,9 @@ import { setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { trainerConfigs, TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; +import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate"; +import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { ModifierTier } from "#app/modifier/modifier-tier"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { ModifierPoolType, modifierTypes } from "#app/modifier/modifier-type"; diff --git a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts index 91f168371cf..75527e1f8c1 100644 --- a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts +++ b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts @@ -20,7 +20,7 @@ import { STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER, } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { getPokemonSpecies } from "#app/data/pokemon-species"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import type { PlayerPokemon } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; import { EnemyPokemon, PokemonMove } from "#app/field/pokemon"; diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index d9bd6983d97..6118fe3d0de 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -140,7 +140,8 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w // Load animations/sfx for Volcarona moves loadCustomMovesForEncounter([Moves.FIRE_SPIN, Moves.QUIVER_DANCE]); - globalScene.arena.trySetWeather(WeatherType.SUNNY, true); + const pokemon = globalScene.getEnemyPokemon(); + globalScene.arena.trySetWeather(WeatherType.SUNNY, pokemon); encounter.setDialogueToken("volcaronaName", getPokemonSpecies(Species.VOLCARONA).getName()); 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 c95810b94d0..282c6c149ff 100644 --- a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts +++ b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts @@ -10,7 +10,7 @@ import { globalScene } from "#app/global-scene"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import type { PlayerPokemon } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; import { FieldPosition } from "#app/field/pokemon"; 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 a81392941ba..c13501c4511 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -3,7 +3,7 @@ import { selectPokemonForOption, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { MusicPreference } from "#app/system/settings/settings"; import type { ModifierTypeOption } from "#app/modifier/modifier-type"; @@ -23,7 +23,7 @@ import { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species"; import { getTypeRgb } from "#app/data/type"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; -import { NumberHolder, isNullOrUndefined, randInt, randSeedInt, randSeedShuffle } from "#app/utils"; +import { NumberHolder, isNullOrUndefined, randInt, randSeedInt, randSeedShuffle, randSeedItem } from "#app/utils"; import type { PlayerPokemon } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; import { EnemyPokemon, PokemonMove } from "#app/field/pokemon"; @@ -41,11 +41,11 @@ import { Gender, getGenderSymbol } from "#app/data/gender"; import { getNatureName } from "#app/data/nature"; import { getPokeballAtlasKey, getPokeballTintColor } from "#app/data/pokeball"; import { getEncounterText, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; -import { trainerNamePools } from "#app/data/trainer-names"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; import { addPokemonDataToDexAndValidateAchievements } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import type { PokeballType } from "#enums/pokeball"; import { doShinySparkleAnim } from "#app/field/anims"; +import { TrainerType } from "#enums/trainer-type"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounters/globalTradeSystem"; @@ -306,7 +306,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil if (eggMoves) { // Cannot gen the rare egg move, only 1 of the first 3 common moves const eggMove = eggMoves[randSeedInt(3)]; - if (!tradePokemon.moveset.some(m => m?.moveId === eggMove)) { + if (!tradePokemon.moveset.some(m => m.moveId === eggMove)) { if (tradePokemon.moveset.length < 4) { tradePokemon.moveset.push(new PokemonMove(eggMove)); } else { @@ -982,15 +982,14 @@ function doTradeReceivedSequence( } function generateRandomTraderName() { - const length = Object.keys(trainerNamePools).length; + const length = TrainerType.YOUNGSTER - TrainerType.ACE_TRAINER + 1; // +1 avoids TrainerType.UNKNOWN - let trainerTypePool = trainerNamePools[randInt(length) + 1]; - while (!trainerTypePool) { - trainerTypePool = trainerNamePools[randInt(length) + 1]; - } + const trainerTypePool = i18next.t("trainersCommon:" + TrainerType[randInt(length) + 1], { returnObjects: true }); // Some trainers have 2 gendered pools, some do not - const genderedPool = trainerTypePool[randInt(trainerTypePool.length)]; - const trainerNameString = Array.isArray(genderedPool) ? genderedPool[randInt(genderedPool.length)] : genderedPool; + const gender = randInt(2) === 0 ? "MALE" : "FEMALE"; + const trainerNameString = randSeedItem( + Object.values(trainerTypePool.hasOwnProperty(gender) ? trainerTypePool[gender] : trainerTypePool), + ) as string; // Some names have an '&' symbol and need to be trimmed to a single name instead of a double name const trainerNames = trainerNameString.split(" & "); return trainerNames[randInt(trainerNames.length)]; diff --git a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts index bf60e982b15..11924f93df4 100644 --- a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts @@ -3,12 +3,10 @@ import { initBattleWithEnemyConfig, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { - trainerConfigs, - TrainerPartyCompoundTemplate, - TrainerPartyTemplate, - trainerPartyTemplates, -} from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; +import { trainerPartyTemplates } from "#app/data/trainers/TrainerPartyTemplate"; +import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate"; +import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { modifierTypes } from "#app/modifier/modifier-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; diff --git a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts index f231e4abdb8..8c45fde3079 100644 --- a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts +++ b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts @@ -10,7 +10,7 @@ import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounte import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter"; import type MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { HiddenAbilityRateBoosterModifier, IvScannerModifier } from "#app/modifier/modifier"; import type { EnemyPokemon } from "#app/field/pokemon"; import { PokeballType } from "#enums/pokeball"; diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts index c7220192caa..806a89a7131 100644 --- a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -24,7 +24,7 @@ import { Biome } from "#enums/biome"; import { getBiomeKey } from "#app/field/arena"; import { PokemonType } from "#enums/pokemon-type"; import { getPartyLuckValue, modifierTypes } from "#app/modifier/modifier-type"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { BattlerTagType } from "#enums/battler-tag-type"; import { getPokemonNameWithAffix } from "#app/messages"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; 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 2b29046f738..c189e341089 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 @@ -4,7 +4,7 @@ import { initBattleWithEnemyConfig, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { trainerConfigs } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; import { randSeedShuffle } from "#app/utils"; @@ -30,7 +30,6 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode import { modifierTypes } from "#app/modifier/modifier-type"; import { PokemonType } from "#enums/pokemon-type"; import { getPokeballTintColor } from "#app/data/pokeball"; -import type { PokemonHeldItemModifier } from "#app/modifier/modifier"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounters/theExpertPokemonBreeder"; diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 758e3fabd76..22ec52e976c 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -41,7 +41,8 @@ import { TrainerType } from "#enums/trainer-type"; import PokemonData from "#app/system/pokemon-data"; import { Nature } from "#enums/nature"; import type HeldModifierConfig from "#app/interfaces/held-modifier-config"; -import { trainerConfigs, TrainerPartyTemplate } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; +import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { PartyMemberStrength } from "#enums/party-member-strength"; /** i18n namespace for encounter */ @@ -781,7 +782,7 @@ async function addEggMoveToNewPokemonMoveset( let randomEggMoveIndex = eggMoveIndices.pop(); let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null; let retries = 0; - while (retries < 3 && (!randomEggMove || newPokemon.moveset.some(m => m?.moveId === randomEggMove))) { + while (retries < 3 && (!randomEggMove || newPokemon.moveset.some(m => m.moveId === randomEggMove))) { // If Pokemon already knows this move, roll for another egg move randomEggMoveIndex = eggMoveIndices.pop(); randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null; @@ -789,7 +790,7 @@ async function addEggMoveToNewPokemonMoveset( } if (randomEggMove) { - if (!newPokemon.moveset.some(m => m?.moveId === randomEggMove)) { + if (!newPokemon.moveset.some(m => m.moveId === randomEggMove)) { if (newPokemon.moveset.length < 4) { newPokemon.moveset.push(new PokemonMove(randomEggMove)); } else { @@ -820,16 +821,13 @@ async function addEggMoveToNewPokemonMoveset( */ function addFavoredMoveToNewPokemonMoveset( newPokemon: PlayerPokemon, - newPokemonGeneratedMoveset: (PokemonMove | null)[], + newPokemonGeneratedMoveset: PokemonMove[], newEggMoveIndex: number | null, ) { let favoredMove: PokemonMove | null = null; for (const move of newPokemonGeneratedMoveset) { // Needs to match first type, second type will be replaced - if ( - move?.getMove().type === newPokemon.getTypes()[0] && - !newPokemon.moveset.some(m => m?.moveId === move?.moveId) - ) { + if (move?.getMove().type === newPokemon.getTypes()[0] && !newPokemon.moveset.some(m => m.moveId === move.moveId)) { favoredMove = move; break; } @@ -839,7 +837,7 @@ function addFavoredMoveToNewPokemonMoveset( if (!favoredMove) { for (const move of newPokemonGeneratedMoveset) { // Needs to match first type, second type will be replaced - if (!newPokemon.moveset.some(m => m?.moveId === move?.moveId)) { + if (!newPokemon.moveset.some(m => m.moveId === move.moveId)) { favoredMove = move; break; } diff --git a/src/data/mystery-encounters/mystery-encounter-requirements.ts b/src/data/mystery-encounters/mystery-encounter-requirements.ts index e9398547740..f9aedf2c1a7 100644 --- a/src/data/mystery-encounters/mystery-encounter-requirements.ts +++ b/src/data/mystery-encounters/mystery-encounter-requirements.ts @@ -576,19 +576,19 @@ export class MoveRequirement extends EncounterPokemonRequirement { return partyPokemon.filter( pokemon => (!this.excludeDisallowedPokemon || pokemon.isAllowedInBattle()) && - pokemon.moveset.some(move => move?.moveId && this.requiredMoves.includes(move.moveId)), + pokemon.moveset.some(move => move.moveId && this.requiredMoves.includes(move.moveId)), ); } // 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.excludeDisallowedPokemon || pokemon.isAllowedInBattle()) && - !pokemon.moveset.some(move => move?.moveId && this.requiredMoves.includes(move.moveId)), + !pokemon.moveset.some(move => move.moveId && this.requiredMoves.includes(move.moveId)), ); } override getDialogueToken(pokemon?: PlayerPokemon): [string, string] { - const includedMoves = pokemon?.moveset.filter(move => move?.moveId && this.requiredMoves.includes(move.moveId)); + 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()]; } @@ -626,7 +626,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement { return partyPokemon.filter( pokemon => this.requiredMoves.filter(learnableMove => - pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m?.moveId === tm)).includes(learnableMove), + pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m.moveId === tm)).includes(learnableMove), ).length > 0, ); } @@ -634,14 +634,14 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement { return partyPokemon.filter( pokemon => this.requiredMoves.filter(learnableMove => - pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m?.moveId === tm)).includes(learnableMove), + pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m.moveId === tm)).includes(learnableMove), ).length === 0, ); } override getDialogueToken(pokemon?: PlayerPokemon): [string, string] { const includedCompatMoves = this.requiredMoves.filter(reqMove => - pokemon?.compatibleTms.filter(tm => !pokemon.moveset.find(m => m?.moveId === tm)).includes(reqMove), + pokemon?.compatibleTms.filter(tm => !pokemon.moveset.find(m => m.moveId === tm)).includes(reqMove), ); if (includedCompatMoves.length > 0) { return ["compatibleMove", Moves[includedCompatMoves[0]]]; diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts index 354f69d0ca3..5dd952b2bce 100644 --- a/src/data/mystery-encounters/mystery-encounters.ts +++ b/src/data/mystery-encounters/mystery-encounters.ts @@ -332,7 +332,6 @@ export function initMysteryEncounters() { }); // Add ANY biome encounters to biome map - // eslint-disable-next-line let _encounterBiomeTableLog = ""; mysteryEncountersByBiome.forEach((biomeEncounters, biome) => { anyBiomeEncounters.forEach(encounter => { diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index d37ac340a7c..5c6acf43e26 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -43,8 +43,9 @@ import type { Moves } from "#enums/moves"; import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; import { MysteryEncounterMode } from "#enums/mystery-encounter-mode"; import { Status } from "#app/data/status-effect"; -import type { TrainerConfig } from "#app/data/trainer-config"; -import { trainerConfigs, TrainerSlot } from "#app/data/trainer-config"; +import type { TrainerConfig } from "#app/data/trainers/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import type PokemonSpecies from "#app/data/pokemon-species"; import type { IEggOptions } from "#app/data/egg"; import { Egg } from "#app/data/egg"; diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index 275078dbace..a4787e819b8 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -741,6 +741,26 @@ export async function catchPokemon( false, ); }, + () => { + const attributes = { + shiny: pokemon.shiny, + variant: pokemon.variant, + form: pokemon.formIndex, + female: pokemon.gender === Gender.FEMALE, + }; + globalScene.ui.setOverlayMode( + Mode.POKEDEX_PAGE, + pokemon.species, + pokemon.formIndex, + attributes, + null, + () => { + globalScene.ui.setMode(Mode.MESSAGE).then(() => { + promptRelease(); + }); + }, + ); + }, () => { globalScene.ui.setMode( Mode.PARTY, diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index 4636e68d6d6..63e166c7fc4 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -363,7 +363,7 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge } canChange(pokemon: Pokemon): boolean { - return !!pokemon.moveset.filter(m => m?.moveId === this.move).length === this.known; + return !!pokemon.moveset.filter(m => m.moveId === this.move).length === this.known; } } diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index d172173e9df..15c60d28969 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -1383,7 +1383,7 @@ export function initSpecies() { new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", PokemonType.GRASS, PokemonType.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", "", PokemonType.GRASS, PokemonType.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, PokemonType.GRASS, PokemonType.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, PokemonType.GRASS, PokemonType.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.NONE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, PokemonType.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.NONE, Abilities.EFFECT_SPORE, 625, 120, 122, 90, 108, 105, 80, 45, 50, 263, true), ), new PokemonSpecies(Species.CHARMANDER, 1, false, false, false, "Lizard Pokémon", PokemonType.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", PokemonType.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), @@ -1391,20 +1391,20 @@ export function initSpecies() { new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.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, PokemonType.FIRE, PokemonType.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, PokemonType.FIRE, PokemonType.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, PokemonType.FIRE, PokemonType.FLYING, 28, 999.9, Abilities.BERSERK, Abilities.NONE, Abilities.BERSERK, 634, 118, 84, 93, 139, 100, 100, 45, 50, 267), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, PokemonType.FLYING, 28, 999.9, Abilities.BERSERK, Abilities.NONE, Abilities.BERSERK, 634, 118, 99, 88, 134, 95, 100, 45, 50, 267), ), new PokemonSpecies(Species.SQUIRTLE, 1, false, false, false, "Tiny Turtle Pokémon", PokemonType.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", PokemonType.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", PokemonType.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", "", PokemonType.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, PokemonType.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, PokemonType.WATER, PokemonType.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.NONE, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.NONE, Abilities.SHELL_ARMOR, 630, 119, 108, 125, 105, 110, 63, 45, 50, 265), ), new PokemonSpecies(Species.CATERPIE, 1, false, false, false, "Worm Pokémon", PokemonType.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", PokemonType.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", PokemonType.BUG, PokemonType.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", "", PokemonType.BUG, PokemonType.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, PokemonType.BUG, PokemonType.FLYING, 17, 999.9, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.COMPOUND_EYES, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.BUG, PokemonType.FLYING, 17, 999.9, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.COMPOUND_EYES, 495, 80, 40, 75, 120, 95, 85, 45, 50, 198, true), ), new PokemonSpecies(Species.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", PokemonType.BUG, PokemonType.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", PokemonType.BUG, PokemonType.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), @@ -1485,7 +1485,7 @@ export function initSpecies() { new PokemonSpecies(Species.MACHOKE, 1, false, false, false, "Superpower Pokémon", PokemonType.FIGHTING, null, 1.5, 70.5, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 405, 80, 100, 70, 50, 60, 45, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false), new PokemonSpecies(Species.MACHAMP, 1, false, false, false, "Superpower Pokémon", PokemonType.FIGHTING, null, 1.6, 130, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, GrowthRate.MEDIUM_SLOW, 75, false, true, new PokemonForm("Normal", "", PokemonType.FIGHTING, null, 1.6, 130, Abilities.GUTS, Abilities.NO_GUARD, Abilities.STEADFAST, 505, 90, 130, 80, 65, 85, 55, 45, 50, 253, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIGHTING, null, 25, 999.9, Abilities.GUTS, Abilities.GUTS, Abilities.GUTS, 605, 115, 170, 95, 65, 95, 65, 45, 50, 253), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIGHTING, null, 25, 999.9, Abilities.GUTS, Abilities.GUTS, Abilities.GUTS, 605, 120, 170, 85, 75, 90, 65, 45, 50, 253), ), new PokemonSpecies(Species.BELLSPROUT, 1, false, false, false, "Flower Pokémon", PokemonType.GRASS, PokemonType.POISON, 0.7, 4, Abilities.CHLOROPHYLL, Abilities.NONE, Abilities.GLUTTONY, 300, 50, 75, 35, 70, 30, 40, 255, 70, 60, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.WEEPINBELL, 1, false, false, false, "Flycatcher Pokémon", PokemonType.GRASS, PokemonType.POISON, 1, 6.4, Abilities.CHLOROPHYLL, Abilities.NONE, Abilities.GLUTTONY, 390, 65, 90, 50, 85, 45, 55, 120, 70, 137, GrowthRate.MEDIUM_SLOW, 50, false), @@ -1526,7 +1526,7 @@ export function initSpecies() { new PokemonSpecies(Species.KRABBY, 1, false, false, false, "River Crab Pokémon", PokemonType.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", PokemonType.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", "", PokemonType.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, PokemonType.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 PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, null, 19, 999.9, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, 575, 92, 145, 140, 60, 65, 73, 60, 50, 166), ), new PokemonSpecies(Species.VOLTORB, 1, false, false, false, "Ball Pokémon", PokemonType.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", PokemonType.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), @@ -1570,13 +1570,13 @@ export function initSpecies() { ), new PokemonSpecies(Species.LAPRAS, 1, false, false, false, "Transport Pokémon", PokemonType.WATER, PokemonType.ICE, 2.5, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, GrowthRate.SLOW, 50, false, true, new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.ICE, 2.5, 220, Abilities.WATER_ABSORB, Abilities.SHELL_ARMOR, Abilities.HYDRATION, 535, 130, 85, 80, 85, 95, 60, 45, 50, 187, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.ICE, 24, 999.9, Abilities.SHIELD_DUST, Abilities.SHIELD_DUST, Abilities.SHIELD_DUST, 635, 170, 85, 85, 105, 130, 60, 45, 50, 187), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.ICE, 24, 999.9, Abilities.SHIELD_DUST, Abilities.SHIELD_DUST, Abilities.SHIELD_DUST, 635, 170, 97, 85, 107, 111, 65, 45, 50, 187), ), new PokemonSpecies(Species.DITTO, 1, false, false, false, "Transform Pokémon", PokemonType.NORMAL, null, 0.3, 4, Abilities.LIMBER, Abilities.NONE, Abilities.IMPOSTER, 288, 48, 48, 48, 48, 48, 48, 35, 50, 101, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.EEVEE, 1, false, false, false, "Evolution Pokémon", PokemonType.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, GrowthRate.MEDIUM_FAST, 87.5, false, true, new PokemonForm("Normal", "", PokemonType.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 325, 55, 55, 50, 45, 65, 55, 45, 50, 65, false, null, true), new PokemonForm("Partner", "partner", PokemonType.NORMAL, null, 0.3, 6.5, Abilities.RUN_AWAY, Abilities.ADAPTABILITY, Abilities.ANTICIPATION, 435, 65, 75, 70, 65, 85, 75, 45, 50, 65, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 18, 999.9, Abilities.PROTEAN, Abilities.PROTEAN, Abilities.PROTEAN, 535, 110, 90, 70, 95, 85, 85, 45, 50, 65), //+100 BST from Partner Form + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 18, 999.9, Abilities.PROTEAN, Abilities.PROTEAN, Abilities.PROTEAN, 535, 110, 95, 70, 90, 85, 85, 45, 50, 65), //+100 BST from Partner Form ), new PokemonSpecies(Species.VAPOREON, 1, false, false, false, "Bubble Jet Pokémon", PokemonType.WATER, null, 1, 29, Abilities.WATER_ABSORB, Abilities.NONE, Abilities.HYDRATION, 525, 130, 65, 60, 110, 95, 65, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), new PokemonSpecies(Species.JOLTEON, 1, false, false, false, "Lightning Pokémon", PokemonType.ELECTRIC, null, 0.8, 24.5, Abilities.VOLT_ABSORB, Abilities.NONE, Abilities.QUICK_FEET, 525, 65, 65, 60, 110, 95, 130, 45, 50, 184, GrowthRate.MEDIUM_FAST, 87.5, false), @@ -1592,7 +1592,7 @@ export function initSpecies() { ), new PokemonSpecies(Species.SNORLAX, 1, false, false, false, "Sleeping Pokémon", PokemonType.NORMAL, null, 2.1, 460, Abilities.IMMUNITY, Abilities.THICK_FAT, Abilities.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, GrowthRate.SLOW, 87.5, false, true, new PokemonForm("Normal", "", PokemonType.NORMAL, null, 2.1, 460, Abilities.IMMUNITY, Abilities.THICK_FAT, Abilities.GLUTTONY, 540, 160, 110, 65, 65, 110, 30, 25, 50, 189, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 35, 999.9, Abilities.HARVEST, Abilities.HARVEST, Abilities.HARVEST, 640, 200, 135, 80, 80, 125, 20, 25, 50, 189), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.NORMAL, null, 35, 999.9, Abilities.HARVEST, Abilities.HARVEST, Abilities.HARVEST, 640, 210, 135, 70, 90, 115, 20, 25, 50, 189), ), new PokemonSpecies(Species.ARTICUNO, 1, true, false, false, "Freeze Pokémon", PokemonType.ICE, PokemonType.FLYING, 1.7, 55.4, Abilities.PRESSURE, Abilities.NONE, Abilities.SNOW_CLOAK, 580, 90, 85, 100, 95, 125, 85, 3, 35, 290, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.ZAPDOS, 1, true, false, false, "Electric Pokémon", PokemonType.ELECTRIC, PokemonType.FLYING, 1.6, 52.6, Abilities.PRESSURE, Abilities.NONE, Abilities.STATIC, 580, 90, 90, 85, 125, 90, 100, 3, 35, 290, GrowthRate.SLOW, null, false), @@ -2086,7 +2086,7 @@ export function initSpecies() { new PokemonSpecies(Species.PORYGON_Z, 4, false, false, false, "Virtual Pokémon", PokemonType.NORMAL, null, 0.9, 34, Abilities.ADAPTABILITY, Abilities.DOWNLOAD, Abilities.ANALYTIC, 535, 85, 80, 70, 135, 75, 90, 30, 50, 268, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.GALLADE, 4, false, false, false, "Blade Pokémon", PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 52, Abilities.STEADFAST, Abilities.SHARPNESS, Abilities.JUSTIFIED, 518, 68, 125, 65, 65, 115, 80, 45, 35, 259, GrowthRate.SLOW, 100, false, true, new PokemonForm("Normal", "", PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 52, Abilities.STEADFAST, Abilities.SHARPNESS, Abilities.JUSTIFIED, 518, 68, 125, 65, 65, 115, 80, 45, 35, 259, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 56.4, Abilities.SHARPNESS, Abilities.SHARPNESS, Abilities.SHARPNESS, 618, 68, 165, 95, 65, 115, 110, 45, 35, 259), + new PokemonForm("Mega", SpeciesFormKey.MEGA, PokemonType.PSYCHIC, PokemonType.FIGHTING, 1.6, 56.4, Abilities.INNER_FOCUS, Abilities.INNER_FOCUS, Abilities.INNER_FOCUS, 618, 68, 165, 95, 65, 115, 110, 45, 35, 259), ), new PokemonSpecies(Species.PROBOPASS, 4, false, false, false, "Compass Pokémon", PokemonType.ROCK, PokemonType.STEEL, 1.4, 340, Abilities.STURDY, Abilities.MAGNET_PULL, Abilities.SAND_FORCE, 525, 60, 55, 145, 75, 150, 40, 60, 70, 184, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DUSKNOIR, 4, false, false, false, "Gripper Pokémon", PokemonType.GHOST, null, 2.2, 106.6, Abilities.PRESSURE, Abilities.NONE, Abilities.FRISK, 525, 45, 100, 135, 65, 135, 45, 45, 35, 263, GrowthRate.FAST, 50, false), @@ -2232,7 +2232,7 @@ export function initSpecies() { new PokemonSpecies(Species.TRUBBISH, 5, false, false, false, "Trash Bag Pokémon", PokemonType.POISON, null, 0.6, 31, Abilities.STENCH, Abilities.STICKY_HOLD, Abilities.AFTERMATH, 329, 50, 50, 62, 40, 62, 65, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GARBODOR, 5, false, false, false, "Trash Heap Pokémon", PokemonType.POISON, null, 1.9, 107.3, Abilities.STENCH, Abilities.WEAK_ARMOR, Abilities.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", PokemonType.POISON, null, 1.9, 107.3, Abilities.STENCH, Abilities.WEAK_ARMOR, Abilities.AFTERMATH, 474, 80, 95, 82, 60, 82, 75, 60, 50, 166, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.POISON, PokemonType.STEEL, 21, 999.9, Abilities.TOXIC_DEBRIS, Abilities.TOXIC_DEBRIS, Abilities.TOXIC_DEBRIS, 574, 135, 125, 102, 57, 102, 53, 60, 50, 166), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.POISON, PokemonType.STEEL, 21, 999.9, Abilities.TOXIC_DEBRIS, Abilities.TOXIC_DEBRIS, Abilities.TOXIC_DEBRIS, 574, 115, 121, 102, 81, 102, 53, 60, 50, 166), ), new PokemonSpecies(Species.ZORUA, 5, false, false, false, "Tricky Fox Pokémon", PokemonType.DARK, null, 0.7, 12.5, Abilities.ILLUSION, Abilities.NONE, Abilities.NONE, 330, 40, 65, 40, 80, 40, 65, 75, 50, 66, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.ZOROARK, 5, false, false, false, "Illusion Fox Pokémon", PokemonType.DARK, null, 1.6, 81.1, Abilities.ILLUSION, Abilities.NONE, Abilities.NONE, 510, 60, 105, 60, 120, 60, 105, 45, 50, 179, GrowthRate.MEDIUM_SLOW, 87.5, false), @@ -2357,16 +2357,16 @@ export function initSpecies() { new PokemonSpecies(Species.DELPHOX, 6, false, false, false, "Fox Pokémon", PokemonType.FIRE, PokemonType.PSYCHIC, 1.5, 39, Abilities.BLAZE, Abilities.NONE, Abilities.MAGICIAN, 534, 75, 69, 72, 114, 100, 104, 45, 70, 267, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.FROAKIE, 6, false, false, false, "Bubble Frog Pokémon", PokemonType.WATER, null, 0.3, 7, Abilities.TORRENT, Abilities.NONE, Abilities.PROTEAN, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, GrowthRate.MEDIUM_SLOW, 87.5, false, false, new PokemonForm("Normal", "", PokemonType.WATER, null, 0.3, 7, Abilities.TORRENT, Abilities.NONE, Abilities.PROTEAN, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, false, null, true), - new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, null, 0.3, 7, Abilities.TORRENT, Abilities.NONE, Abilities.PROTEAN, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, false, "", true), + new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, null, 0.3, 7, Abilities.TORRENT, Abilities.NONE, Abilities.NONE, 314, 41, 56, 40, 62, 44, 71, 45, 70, 63, false, "", true), ), new PokemonSpecies(Species.FROGADIER, 6, false, false, false, "Bubble Frog Pokémon", PokemonType.WATER, null, 0.6, 10.9, Abilities.TORRENT, Abilities.NONE, Abilities.PROTEAN, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, GrowthRate.MEDIUM_SLOW, 87.5, false, false, new PokemonForm("Normal", "", PokemonType.WATER, null, 0.6, 10.9, Abilities.TORRENT, Abilities.NONE, Abilities.PROTEAN, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, false, null, true), - new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, null, 0.6, 10.9, Abilities.TORRENT, Abilities.NONE, Abilities.PROTEAN, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, false, "", true), + new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, null, 0.6, 10.9, Abilities.TORRENT, Abilities.NONE, Abilities.NONE, 405, 54, 63, 52, 83, 56, 97, 45, 70, 142, false, "", true), ), new PokemonSpecies(Species.GRENINJA, 6, false, false, false, "Ninja Pokémon", PokemonType.WATER, PokemonType.DARK, 1.5, 40, Abilities.TORRENT, Abilities.NONE, Abilities.PROTEAN, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, false, new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.DARK, 1.5, 40, Abilities.TORRENT, Abilities.NONE, Abilities.PROTEAN, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, false, null, true), new PokemonForm("Battle Bond", "battle-bond", PokemonType.WATER, PokemonType.DARK, 1.5, 40, Abilities.BATTLE_BOND, Abilities.NONE, Abilities.BATTLE_BOND, 530, 72, 95, 67, 103, 71, 122, 45, 70, 265, false, "", true), - new PokemonForm("Ash", "ash", PokemonType.WATER, PokemonType.DARK, 1.5, 40, Abilities.BATTLE_BOND, Abilities.NONE, Abilities.BATTLE_BOND, 640, 72, 145, 67, 153, 71, 132, 45, 70, 265), + new PokemonForm("Ash", "ash", PokemonType.WATER, PokemonType.DARK, 1.5, 40, Abilities.BATTLE_BOND, Abilities.NONE, Abilities.NONE, 640, 72, 145, 67, 153, 71, 132, 45, 70, 265), ), new PokemonSpecies(Species.BUNNELBY, 6, false, false, false, "Digging Pokémon", PokemonType.NORMAL, null, 0.4, 5, Abilities.PICKUP, Abilities.CHEEK_POUCH, Abilities.HUGE_POWER, 237, 38, 36, 38, 32, 36, 57, 255, 50, 47, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DIGGERSBY, 6, false, false, false, "Digging Pokémon", PokemonType.NORMAL, PokemonType.GROUND, 1, 42.4, Abilities.PICKUP, Abilities.CHEEK_POUCH, Abilities.HUGE_POWER, 423, 85, 56, 77, 50, 77, 78, 127, 50, 148, GrowthRate.MEDIUM_FAST, 50, false), @@ -2707,25 +2707,25 @@ export function initSpecies() { new PokemonSpecies(Species.MELTAN, 7, false, false, true, "Hex Nut Pokémon", PokemonType.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", PokemonType.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", "", PokemonType.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, PokemonType.STEEL, null, 25, 999.9, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 700, 175, 165, 155, 85, 75, 45, 3, 0, 300), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.STEEL, null, 25, 999.9, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 700, 170, 158, 158, 95, 75, 44, 3, 0, 300), ), new PokemonSpecies(Species.GROOKEY, 8, false, false, false, "Chimp Pokémon", PokemonType.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", PokemonType.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", PokemonType.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", "", PokemonType.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, PokemonType.GRASS, null, 28, 999.9, Abilities.GRASSY_SURGE, Abilities.NONE, Abilities.GRASSY_SURGE, 630, 125, 150, 105, 85, 85, 80, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GRASS, null, 28, 999.9, Abilities.GRASSY_SURGE, Abilities.NONE, Abilities.GRASSY_SURGE, 630, 125, 140, 105, 90, 85, 85, 45, 50, 265), ), new PokemonSpecies(Species.SCORBUNNY, 8, false, false, false, "Rabbit Pokémon", PokemonType.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", PokemonType.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", PokemonType.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", "", PokemonType.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, PokemonType.FIRE, null, 27, 999.9, Abilities.LIBERO, Abilities.NONE, Abilities.LIBERO, 630, 100, 146, 80, 90, 80, 134, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, null, 27, 999.9, Abilities.LIBERO, Abilities.NONE, Abilities.LIBERO, 630, 100, 141, 80, 95, 80, 134, 45, 50, 265), ), new PokemonSpecies(Species.SOBBLE, 8, false, false, false, "Water Lizard Pokémon", PokemonType.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", PokemonType.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", PokemonType.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", "", PokemonType.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, PokemonType.WATER, null, 40, 999.9, Abilities.SNIPER, Abilities.NONE, Abilities.SNIPER, 630, 95, 97, 77, 147, 77, 137, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, null, 40, 999.9, Abilities.SNIPER, Abilities.NONE, Abilities.SNIPER, 630, 95, 117, 67, 147, 67, 137, 45, 50, 265), ), new PokemonSpecies(Species.SKWOVET, 8, false, false, false, "Cheeky Pokémon", PokemonType.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", PokemonType.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), @@ -2733,13 +2733,13 @@ export function initSpecies() { new PokemonSpecies(Species.CORVISQUIRE, 8, false, false, false, "Raven Pokémon", PokemonType.FLYING, null, 0.8, 16, Abilities.KEEN_EYE, Abilities.UNNERVE, Abilities.BIG_PECKS, 365, 68, 67, 55, 43, 55, 77, 120, 50, 128, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.CORVIKNIGHT, 8, false, false, false, "Raven Pokémon", PokemonType.FLYING, PokemonType.STEEL, 2.2, 75, Abilities.PRESSURE, Abilities.UNNERVE, Abilities.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, GrowthRate.MEDIUM_SLOW, 50, false, true, new PokemonForm("Normal", "", PokemonType.FLYING, PokemonType.STEEL, 2.2, 75, Abilities.PRESSURE, Abilities.UNNERVE, Abilities.MIRROR_ARMOR, 495, 98, 87, 105, 53, 85, 67, 45, 50, 248, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FLYING, PokemonType.STEEL, 14, 999.9, Abilities.MIRROR_ARMOR, Abilities.MIRROR_ARMOR, Abilities.MIRROR_ARMOR, 595, 128, 102, 140, 53, 95, 77, 45, 50, 248), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FLYING, PokemonType.STEEL, 14, 999.9, Abilities.MIRROR_ARMOR, Abilities.MIRROR_ARMOR, Abilities.MIRROR_ARMOR, 595, 118, 112, 135, 63, 90, 77, 45, 50, 248), ), new PokemonSpecies(Species.BLIPBUG, 8, false, false, false, "Larva Pokémon", PokemonType.BUG, null, 0.4, 8, Abilities.SWARM, Abilities.COMPOUND_EYES, Abilities.TELEPATHY, 180, 25, 20, 20, 25, 45, 45, 255, 50, 36, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DOTTLER, 8, false, false, false, "Radome Pokémon", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 19.5, Abilities.SWARM, Abilities.COMPOUND_EYES, Abilities.TELEPATHY, 335, 50, 35, 80, 50, 90, 30, 120, 50, 117, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.ORBEETLE, 8, false, false, false, "Seven Spot Pokémon", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 40.8, Abilities.SWARM, Abilities.FRISK, Abilities.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", PokemonType.BUG, PokemonType.PSYCHIC, 0.4, 40.8, Abilities.SWARM, Abilities.FRISK, Abilities.TELEPATHY, 505, 60, 45, 110, 80, 120, 90, 45, 50, 253, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.BUG, PokemonType.PSYCHIC, 14, 999.9, Abilities.TRACE, Abilities.TRACE, Abilities.TRACE, 605, 90, 45, 130, 110, 140, 90, 45, 50, 253), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.BUG, PokemonType.PSYCHIC, 14, 999.9, Abilities.TRACE, Abilities.TRACE, Abilities.TRACE, 605, 75, 50, 140, 100, 150, 90, 45, 50, 253), ), new PokemonSpecies(Species.NICKIT, 8, false, false, false, "Fox Pokémon", PokemonType.DARK, null, 0.6, 8.9, Abilities.RUN_AWAY, Abilities.UNBURDEN, Abilities.STAKEOUT, 245, 40, 28, 28, 47, 52, 50, 255, 50, 49, GrowthRate.FAST, 50, false), new PokemonSpecies(Species.THIEVUL, 8, false, false, false, "Fox Pokémon", PokemonType.DARK, null, 1.2, 19.9, Abilities.RUN_AWAY, Abilities.UNBURDEN, Abilities.STAKEOUT, 455, 70, 58, 58, 87, 92, 90, 127, 50, 159, GrowthRate.FAST, 50, false), @@ -2750,7 +2750,7 @@ export function initSpecies() { new PokemonSpecies(Species.CHEWTLE, 8, false, false, false, "Snapping Pokémon", PokemonType.WATER, null, 0.3, 8.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 284, 50, 64, 50, 38, 38, 44, 255, 50, 57, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DREDNAW, 8, false, false, false, "Bite Pokémon", PokemonType.WATER, PokemonType.ROCK, 1, 115.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", PokemonType.WATER, PokemonType.ROCK, 1, 115.5, Abilities.STRONG_JAW, Abilities.SHELL_ARMOR, Abilities.SWIFT_SWIM, 485, 90, 115, 90, 48, 68, 74, 75, 50, 170, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.ROCK, 24, 999.9, Abilities.STRONG_JAW, Abilities.STRONG_JAW, Abilities.STRONG_JAW, 585, 115, 145, 115, 43, 83, 84, 75, 50, 170), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.WATER, PokemonType.ROCK, 24, 999.9, Abilities.STRONG_JAW, Abilities.STRONG_JAW, Abilities.STRONG_JAW, 585, 115, 137, 115, 61, 83, 74, 75, 50, 170), ), new PokemonSpecies(Species.YAMPER, 8, false, false, false, "Puppy Pokémon", PokemonType.ELECTRIC, null, 0.3, 13.5, Abilities.BALL_FETCH, Abilities.NONE, Abilities.RATTLED, 270, 59, 45, 50, 40, 50, 26, 255, 50, 54, GrowthRate.FAST, 50, false), new PokemonSpecies(Species.BOLTUND, 8, false, false, false, "Dog Pokémon", PokemonType.ELECTRIC, null, 1, 34, Abilities.STRONG_JAW, Abilities.NONE, Abilities.COMPETITIVE, 490, 69, 90, 60, 90, 60, 121, 45, 50, 172, GrowthRate.FAST, 50, false), @@ -2758,7 +2758,7 @@ export function initSpecies() { new PokemonSpecies(Species.CARKOL, 8, false, false, false, "Coal Pokémon", PokemonType.ROCK, PokemonType.FIRE, 1.1, 78, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 410, 80, 60, 90, 60, 70, 50, 120, 50, 144, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.COALOSSAL, 8, false, false, false, "Coal Pokémon", PokemonType.ROCK, PokemonType.FIRE, 2.8, 310.5, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, GrowthRate.MEDIUM_SLOW, 50, false, true, new PokemonForm("Normal", "", PokemonType.ROCK, PokemonType.FIRE, 2.8, 310.5, Abilities.STEAM_ENGINE, Abilities.FLAME_BODY, Abilities.FLASH_FIRE, 510, 110, 80, 120, 80, 90, 30, 45, 50, 255, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.ROCK, PokemonType.FIRE, 42, 999.9, Abilities.STEAM_ENGINE, Abilities.STEAM_ENGINE, Abilities.STEAM_ENGINE, 610, 140, 95, 130, 95, 110, 40, 45, 50, 255), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.ROCK, PokemonType.FIRE, 42, 999.9, Abilities.STEAM_ENGINE, Abilities.STEAM_ENGINE, Abilities.STEAM_ENGINE, 610, 140, 100, 132, 95, 100, 43, 45, 50, 255), ), new PokemonSpecies(Species.APPLIN, 8, false, false, false, "Apple Core Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.2, 0.5, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.BULLETPROOF, 260, 40, 40, 80, 40, 40, 20, 255, 50, 52, GrowthRate.ERRATIC, 50, false), new PokemonSpecies(Species.FLAPPLE, 8, false, false, false, "Apple Wing Pokémon", PokemonType.GRASS, PokemonType.DRAGON, 0.3, 1, Abilities.RIPEN, Abilities.GLUTTONY, Abilities.HUSTLE, 485, 70, 110, 80, 95, 60, 70, 45, 50, 170, GrowthRate.ERRATIC, 50, false, true, @@ -2772,7 +2772,7 @@ export function initSpecies() { new PokemonSpecies(Species.SILICOBRA, 8, false, false, false, "Sand Snake Pokémon", PokemonType.GROUND, null, 2.2, 7.6, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 315, 52, 57, 75, 35, 50, 46, 255, 50, 63, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.SANDACONDA, 8, false, false, false, "Sand Snake Pokémon", PokemonType.GROUND, null, 3.8, 65.5, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", PokemonType.GROUND, null, 3.8, 65.5, Abilities.SAND_SPIT, Abilities.SHED_SKIN, Abilities.SAND_VEIL, 510, 72, 107, 125, 65, 70, 71, 120, 50, 179, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GROUND, null, 22, 999.9, Abilities.SAND_SPIT, Abilities.SAND_SPIT, Abilities.SAND_SPIT, 610, 117, 137, 140, 55, 80, 81, 120, 50, 179), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.GROUND, null, 22, 999.9, Abilities.SAND_SPIT, Abilities.SAND_SPIT, Abilities.SAND_SPIT, 610, 102, 137, 140, 70, 80, 81, 120, 50, 179), ), new PokemonSpecies(Species.CRAMORANT, 8, false, false, false, "Gulp Pokémon", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, Abilities.GULP_MISSILE, Abilities.NONE, Abilities.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, false, new PokemonForm("Normal", "", PokemonType.FLYING, PokemonType.WATER, 0.8, 18, Abilities.GULP_MISSILE, Abilities.NONE, Abilities.NONE, 475, 70, 85, 55, 85, 95, 85, 45, 50, 166, false, null, true), @@ -2790,7 +2790,7 @@ export function initSpecies() { new PokemonSpecies(Species.SIZZLIPEDE, 8, false, false, false, "Radiator Pokémon", PokemonType.FIRE, PokemonType.BUG, 0.7, 1, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 305, 50, 65, 45, 50, 50, 45, 190, 50, 61, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.CENTISKORCH, 8, false, false, false, "Radiator Pokémon", PokemonType.FIRE, PokemonType.BUG, 3, 120, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", PokemonType.FIRE, PokemonType.BUG, 3, 120, Abilities.FLASH_FIRE, Abilities.WHITE_SMOKE, Abilities.FLAME_BODY, 525, 100, 115, 65, 90, 90, 65, 75, 50, 184, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, PokemonType.BUG, 75, 999.9, Abilities.FLASH_FIRE, Abilities.FLASH_FIRE, Abilities.FLASH_FIRE, 625, 140, 145, 75, 90, 100, 75, 75, 50, 184), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.FIRE, PokemonType.BUG, 75, 999.9, Abilities.FLASH_FIRE, Abilities.FLASH_FIRE, Abilities.FLASH_FIRE, 625, 130, 125, 75, 94, 100, 101, 75, 50, 184), ), new PokemonSpecies(Species.CLOBBOPUS, 8, false, false, false, "Tantrum Pokémon", PokemonType.FIGHTING, null, 0.6, 4, Abilities.LIMBER, Abilities.NONE, Abilities.TECHNICIAN, 310, 50, 68, 60, 50, 50, 32, 180, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.GRAPPLOCT, 8, false, false, false, "Jujitsu Pokémon", PokemonType.FIGHTING, null, 1.6, 39, Abilities.LIMBER, Abilities.NONE, Abilities.TECHNICIAN, 480, 80, 118, 90, 70, 80, 42, 45, 50, 168, GrowthRate.MEDIUM_SLOW, 50, false), @@ -2853,7 +2853,7 @@ export function initSpecies() { new PokemonSpecies(Species.CUFANT, 8, false, false, false, "Copperderm Pokémon", PokemonType.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", PokemonType.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", "", PokemonType.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, PokemonType.STEEL, PokemonType.GROUND, 23, 999.9, Abilities.MOLD_BREAKER, Abilities.NONE, Abilities.MOLD_BREAKER, 600, 167, 155, 89, 80, 89, 20, 90, 50, 175), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, PokemonType.STEEL, PokemonType.GROUND, 23, 999.9, Abilities.MOLD_BREAKER, Abilities.NONE, Abilities.MOLD_BREAKER, 600, 177, 155, 79, 90, 79, 20, 90, 50, 175), ), new PokemonSpecies(Species.DRACOZOLT, 8, false, false, false, "Fossil Pokémon", PokemonType.ELECTRIC, PokemonType.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", PokemonType.ELECTRIC, PokemonType.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), @@ -2882,8 +2882,8 @@ export function initSpecies() { new PokemonSpecies(Species.URSHIFU, 8, true, false, false, "Wushu Pokémon", PokemonType.FIGHTING, PokemonType.DARK, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, GrowthRate.SLOW, 87.5, false, true, new PokemonForm("Single Strike Style", "single-strike", PokemonType.FIGHTING, PokemonType.DARK, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, "", true), new PokemonForm("Rapid Strike Style", "rapid-strike", PokemonType.FIGHTING, PokemonType.WATER, 1.9, 105, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 550, 100, 130, 100, 63, 60, 97, 3, 50, 275, false, null, true), - new PokemonForm("G-Max Single Strike Style", SpeciesFormKey.GIGANTAMAX_SINGLE, PokemonType.FIGHTING, PokemonType.DARK, 29, 999.9, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 650, 125, 150, 115, 73, 70, 117, 3, 50, 275), - new PokemonForm("G-Max Rapid Strike Style", SpeciesFormKey.GIGANTAMAX_RAPID, PokemonType.FIGHTING, PokemonType.WATER, 26, 999.9, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 650, 125, 150, 115, 73, 70, 117, 3, 50, 275), + new PokemonForm("G-Max Single Strike Style", SpeciesFormKey.GIGANTAMAX_SINGLE, PokemonType.FIGHTING, PokemonType.DARK, 29, 999.9, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 650, 125, 145, 115, 83, 70, 112, 3, 50, 275), + new PokemonForm("G-Max Rapid Strike Style", SpeciesFormKey.GIGANTAMAX_RAPID, PokemonType.FIGHTING, PokemonType.WATER, 26, 999.9, Abilities.UNSEEN_FIST, Abilities.NONE, Abilities.NONE, 650, 125, 145, 115, 83, 70, 112, 3, 50, 275), ), new PokemonSpecies(Species.ZARUDE, 8, false, false, true, "Rogue Monkey Pokémon", PokemonType.DARK, PokemonType.GRASS, 1.8, 70, Abilities.LEAF_GUARD, Abilities.NONE, Abilities.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, GrowthRate.SLOW, null, false, false, new PokemonForm("Normal", "", PokemonType.DARK, PokemonType.GRASS, 1.8, 70, Abilities.LEAF_GUARD, Abilities.NONE, Abilities.NONE, 600, 105, 120, 105, 70, 95, 105, 3, 0, 300, false, null, true), diff --git a/src/data/splash-messages.ts b/src/data/splash-messages.ts index 9fd71d9d95b..3223bbb019e 100644 --- a/src/data/splash-messages.ts +++ b/src/data/splash-messages.ts @@ -44,14 +44,17 @@ interface Season { //#region Constants /** The weight multiplier for the battles-won splash message */ -const BATTLES_WON_WEIGHT_MULTIPLIER = 10; +const BATTLES_WON_WEIGHT_MULTIPLIER = 15; +/** The weight multiplier for the Pokémon names splash message */ +const POKEMON_NAMES_WEIGHT_MULTIPLIER = 10; /** The weight multiplier for the seasonal splash messages */ -const SEASONAL_WEIGHT_MULTIPLIER = 10; +const SEASONAL_WEIGHT_MULTIPLIER = 15; //#region Common Messages const commonSplashMessages = [ ...Array(BATTLES_WON_WEIGHT_MULTIPLIER).fill("battlesWon"), + ...Array(POKEMON_NAMES_WEIGHT_MULTIPLIER).fill("underratedPokemon"), "joinTheDiscord", "infiniteLevels", "everythingIsStackable", @@ -78,7 +81,7 @@ const commonSplashMessages = [ "mostlyConsistentSeeds", "achievementPointsDontDoAnything", "nothingBeatsAJellyFilledDonut", - "dontTalkAboutTheTinkatonIncident", + "dontTalkAboutThePokemonIncident", "alsoTryPokengine", "alsoTryEmeraldRogue", "alsoTryRadicalRed", @@ -176,16 +179,113 @@ const commonSplashMessages = [ "timeForYourDeliDelivery", "goodFirstImpression", "iPreferRarerCandies", + "pocketRoguelite", + "porygonDidNothingWrong", + "critMattered", + "pickupNotRequired", + "stayHydrated", + "alsoTryCobblemon", + "alsoTryPokeDoku", + "mySleepStyleIsDoesnt", + "makeYourOwnWorldChampDifference", + "yoChampInTheMaking", + "notLiableForDecisionAnxiety", + "theAirIsTastyHere", + "continue", + "startANewRunToday", + "neverGiveUp", + "theresAlwaysNextTime", + "oneTwoThreeAndPoof", + "yourPokemonOnlyGoToLevelOneHundred", + "theBattlesWillBeLegendary", + "levelCurveBetterThanJohto", + "alsoTryShowering", + "wellStillBeHere", + "weHopeToSeeYouAgain", + "aHealthyTeamCanMeanGreaterRewards", + "aWildPokemonAppeared", + "isThisThingOn", + "needsMoreTesting", + "whoChecksStatChanges", + "whenTwoTrainersEyesMeet", + "notOfficiallyOnSteam", + "fiftyFifty", + "metaNotIncluded", + "bornToBeAWinner", + "onARollout", + "itsAlwaysNightDeepInTheAbyss", + "folksThisIsInsane", ]; //#region Seasonal Messages const seasonalSplashMessages: Season[] = [ + { + name: "New Year's", + start: "01-01", + end: "01-15", + messages: ["newYears.happyNewYear", "newYears.andAHappyNewYear"], + }, + { + name: "Valentines", + start: "02-07", + end: "02-21", + messages: [ + "valentines.happyValentines", + "valentines.fullOfLove", + "valentines.applinForYou", + "valentines.thePowerOfLoveIsThreeThirtyBST", + "valentines.haveAHeartScale", + "valentines.i<3You", + ], + }, + { + name: "April Fools", + start: "04-01", + end: "04-03", + messages: [ + "aprilFools.battlesOne", + "aprilFools.aprilFools", + "aprilFools.removedPokemon", + "aprilFools.helloKyleAmber", + "aprilFools.gotcha", + "aprilFools.alsoTryPokerogueTwo", + "aprilFools.nowWithSameScumCountermeasures", + "aprilFools.neverGonnaGiveYouGoodRolls", + "aprilFools.youBumblingBuffoon", + "aprilFools.doubleShinyOddsForTrainersOnly", + "aprilFools.nowWithZMoves", + "aprilFools.newLightType", + "aprilFools.removedMegas", + "aprilFools.nerfedYourFavorites", + "aprilFools.grrr", + "aprilFools.enabledEternatusPassiveGoodLuck", + "aprilFools.theDarkestDaySoundsLikeAFutureProblem", + "aprilFools.tmShopWhen", + "aprilFools.whoIsFinn", + "aprilFools.watchOutForShadowPokemon", + "aprilFools.nowWithDarkTypeLuxray", + "aprilFools.onlyOnPokerogueNetAGAIN", + "aprilFools.noFreeVouchers", + "aprilFools.altffourAchievementPoints", + "aprilFools.rokePogue", + "aprilFools.readMe", + "aprilFools.winningNotIncluded", + "aprilFools.timeForYourSoloUnownRun", + "aprilFools.nowARealTimeStrategyGame", + "aprilFools.nowWithQuickTimeEncounters", + "aprilFools.timeYourInputsForHigherCatchrate", + "aprilFools.certifiedButtonSimulator", + "aprilFools.iHopeYouGetSuckerPunched", + ], + }, { name: "Halloween", - start: "09-15", + start: "10-15", end: "10-31", messages: [ + "halloween.happyHalloween", + "halloween.boo", "halloween.pumpkabooAbout", "halloween.mayContainSpiders", "halloween.spookyScarySkeledirge", @@ -194,23 +294,28 @@ const seasonalSplashMessages: Season[] = [ ], }, { - name: "XMAS", + name: "Winter Holiday", start: "12-01", - end: "12-26", + end: "12-31", messages: [ - "xmas.happyHolidays", - "xmas.unaffilicatedWithDelibirdServices", - "xmas.delibirdSeason", - "xmas.diamondsFromTheSky", - "xmas.holidayStylePikachuNotIncluded", + "winterHoliday.happyHolidays", + "winterHoliday.unaffilicatedWithDelibirdServices", + "winterHoliday.delibirdSeason", + "winterHoliday.diamondsFromTheSky", + "winterHoliday.holidayStylePikachuNotIncluded", + "winterHoliday.delibirdDirectlyToYourHouse", + "winterHoliday.haveAnIceDay", + "winterHoliday.spinTheClaydol", + "winterHoliday.beGoodForGoodnessSake", + "winterHoliday.moomooMilkAndLavaCookies", + "winterHoliday.iNeedAYacheBerry", + "winterHoliday.getJolly", + "winterHoliday.tisTheSeasonToBeSpeSpa", + "winterHoliday.deckTheHalls", + "winterHoliday.saveScummingGetsYouOnTheNaughtyList", + "winterHoliday.badTrainersGetRolycoly", ], }, - { - name: "New Year's", - start: "01-01", - end: "01-31", - messages: ["newYears.happyNewYear"], - }, ]; //#endregion diff --git a/src/data/trainer-names.ts b/src/data/trainer-names.ts index c72356d88ae..26cea19070f 100644 --- a/src/data/trainer-names.ts +++ b/src/data/trainer-names.ts @@ -74,2651 +74,6 @@ const trainerNameConfigs: TrainerNameConfigs = { [TrainerType.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant("Lass"), }; -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", - ], -}; - // function used in a commented code // biome-ignore lint/correctness/noUnusedVariables: TODO make this into a script instead of having it be in src/data... function fetchAndPopulateTrainerNames( diff --git a/src/data/trainers/TrainerPartyTemplate.ts b/src/data/trainers/TrainerPartyTemplate.ts new file mode 100644 index 00000000000..adbaacc6b55 --- /dev/null +++ b/src/data/trainers/TrainerPartyTemplate.ts @@ -0,0 +1,255 @@ +import { startingWave } from "#app/battle-scene"; +import { globalScene } from "#app/global-scene"; +import { PartyMemberStrength } from "#enums/party-member-strength"; + +export class TrainerPartyTemplate { + public size: number; + public strength: PartyMemberStrength; + public sameSpecies: boolean; + public balanced: boolean; + + constructor(size: number, strength: PartyMemberStrength, sameSpecies?: boolean, balanced?: boolean) { + this.size = size; + this.strength = strength; + this.sameSpecies = !!sameSpecies; + this.balanced = !!balanced; + } + + getStrength(_index: number): PartyMemberStrength { + return this.strength; + } + + isSameSpecies(_index: number): boolean { + return this.sameSpecies; + } + + isBalanced(_index: number): boolean { + return this.balanced; + } +} + +export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate { + public templates: TrainerPartyTemplate[]; + + constructor(...templates: TrainerPartyTemplate[]) { + super( + templates.reduce((total: number, template: TrainerPartyTemplate) => { + total += template.size; + return total; + }, 0), + PartyMemberStrength.AVERAGE, + ); + this.templates = templates; + } + + getStrength(index: number): PartyMemberStrength { + let t = 0; + for (const template of this.templates) { + if (t + template.size > index) { + return template.getStrength(index - t); + } + t += template.size; + } + + return super.getStrength(index); + } + + isSameSpecies(index: number): boolean { + let t = 0; + for (const template of this.templates) { + if (t + template.size > index) { + return template.isSameSpecies(index - t); + } + t += template.size; + } + + return super.isSameSpecies(index); + } + + isBalanced(index: number): boolean { + let t = 0; + for (const template of this.templates) { + if (t + template.size > index) { + return template.isBalanced(index - t); + } + t += template.size; + } + + return super.isBalanced(index); + } +} + +export const trainerPartyTemplates = { + ONE_WEAK_ONE_STRONG: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.WEAK), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + ), + ONE_AVG: new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + ONE_AVG_ONE_STRONG: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + ), + ONE_STRONG: new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + ONE_STRONGER: new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), + TWO_WEAKER: new TrainerPartyTemplate(2, PartyMemberStrength.WEAKER), + TWO_WEAK: new TrainerPartyTemplate(2, PartyMemberStrength.WEAK), + TWO_WEAK_ONE_AVG: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.WEAK), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + ), + TWO_WEAK_SAME_ONE_AVG: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + ), + TWO_WEAK_SAME_TWO_WEAK_SAME: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true), + new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true), + ), + TWO_WEAK_ONE_STRONG: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.WEAK), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + ), + TWO_AVG: new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE), + TWO_AVG_ONE_STRONG: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + ), + TWO_AVG_SAME_ONE_AVG: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + ), + TWO_AVG_SAME_ONE_STRONG: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + ), + TWO_AVG_SAME_TWO_AVG_SAME: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true), + new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true), + ), + TWO_STRONG: new TrainerPartyTemplate(2, PartyMemberStrength.STRONG), + THREE_WEAK: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK), + THREE_WEAK_SAME: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK, true), + THREE_AVG: new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), + THREE_AVG_SAME: new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, true), + THREE_WEAK_BALANCED: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK, false, true), + FOUR_WEAKER: new TrainerPartyTemplate(4, PartyMemberStrength.WEAKER), + FOUR_WEAKER_SAME: new TrainerPartyTemplate(4, PartyMemberStrength.WEAKER, true), + FOUR_WEAK: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK), + FOUR_WEAK_SAME: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK, true), + FOUR_WEAK_BALANCED: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK, false, true), + FIVE_WEAKER: new TrainerPartyTemplate(5, PartyMemberStrength.WEAKER), + FIVE_WEAK: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK), + FIVE_WEAK_BALANCED: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK, false, true), + SIX_WEAKER: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER), + SIX_WEAKER_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER, true), + SIX_WEAK_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, true), + SIX_WEAK_BALANCED: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, false, true), + + GYM_LEADER_1: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + ), + GYM_LEADER_2: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), + ), + GYM_LEADER_3: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), + ), + GYM_LEADER_4: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), + ), + GYM_LEADER_5: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(2, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), + ), + + ELITE_FOUR: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(3, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), + ), + + CHAMPION: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(4, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(2, PartyMemberStrength.STRONGER, false, true), + ), + + RIVAL: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + ), + RIVAL_2: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true), + ), + RIVAL_3: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE, false, true), + new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true), + ), + RIVAL_4: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, false, true), + new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true), + ), + RIVAL_5: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + ), + RIVAL_6: new TrainerPartyCompoundTemplate( + new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), + new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), + new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true), + new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), + ), +}; + +/** + * The function to get variable strength grunts + * @returns the correct TrainerPartyTemplate + */ +export function getEvilGruntPartyTemplate(): TrainerPartyTemplate { + const waveIndex = globalScene.currentBattle?.waveIndex; + if (waveIndex < 40) { + return trainerPartyTemplates.TWO_AVG; + } + if (waveIndex < 63) { + return trainerPartyTemplates.THREE_AVG; + } + if (waveIndex < 65) { + return trainerPartyTemplates.TWO_AVG_ONE_STRONG; + } + if (waveIndex < 112) { + return trainerPartyTemplates.GYM_LEADER_4; // 3avg 1 strong 1 stronger + } + return trainerPartyTemplates.GYM_LEADER_5; // 3 avg 2 strong 1 stronger +} + +export function getWavePartyTemplate(...templates: TrainerPartyTemplate[]) { + const { currentBattle, gameMode } = globalScene; + const wave = gameMode.getWaveForDifficulty(currentBattle?.waveIndex || startingWave, true); + const templateIndex = Math.ceil((wave - 20) / 30); + return templates[Phaser.Math.Clamp(templateIndex, 0, templates.length - 1)]; +} + +export function getGymLeaderPartyTemplate() { + return getWavePartyTemplate( + trainerPartyTemplates.GYM_LEADER_1, + trainerPartyTemplates.GYM_LEADER_2, + trainerPartyTemplates.GYM_LEADER_3, + trainerPartyTemplates.GYM_LEADER_4, + trainerPartyTemplates.GYM_LEADER_5, + ); +} diff --git a/src/data/trainers/evil-admin-trainer-pools.ts b/src/data/trainers/evil-admin-trainer-pools.ts new file mode 100644 index 00000000000..ecbd5952143 --- /dev/null +++ b/src/data/trainers/evil-admin-trainer-pools.ts @@ -0,0 +1,436 @@ +import type { TrainerTierPools } from "#app/data/trainers/typedefs"; +import { TrainerPoolTier } from "#enums/trainer-pool-tier"; +import { Species } from "#enums/species"; + +/** Team Rocket's admin trainer pool. */ +const ROCKET: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.RATICATE, + Species.ARBOK, + Species.VILEPLUME, + Species.ARCANINE, + Species.GENGAR, + Species.HYPNO, + Species.ELECTRODE, + Species.EXEGGUTOR, + Species.CUBONE, + Species.KOFFING, + Species.GYARADOS, + Species.CROBAT, + Species.STEELIX, + Species.HOUNDOOM, + Species.HONCHKROW, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.OMASTAR, + Species.KABUTOPS, + Species.MAGNEZONE, + Species.ELECTIVIRE, + Species.MAGMORTAR, + Species.PORYGON_Z, + Species.ANNIHILAPE, + Species.ALOLA_SANDSLASH, + Species.ALOLA_PERSIAN, + Species.ALOLA_GOLEM, + Species.ALOLA_MUK, + Species.PALDEA_TAUROS, + ], + [TrainerPoolTier.RARE]: [Species.DRAGONITE, Species.TYRANITAR], +}; + +/** Team Magma's admin trainer pool */ +const MAGMA: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.ARCANINE, + Species.MAGCARGO, + Species.HOUNDOOM, + Species.TORKOAL, + Species.SOLROCK, + Species.CLAYDOL, + Species.HIPPOWDON, + Species.MAGMORTAR, + Species.GLISCOR, + Species.COALOSSAL, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.AGGRON, + Species.FLYGON, + Species.CRADILY, + Species.ARMALDO, + Species.RHYPERIOR, + Species.TURTONATOR, + Species.SANDACONDA, + Species.TOEDSCRUEL, + Species.HISUI_ARCANINE, + ], + [TrainerPoolTier.RARE]: [Species.CHARCADET, Species.SCOVILLAIN], +}; + +const AQUA: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.TENTACRUEL, + Species.LANTURN, + Species.AZUMARILL, + Species.QUAGSIRE, + Species.OCTILLERY, + Species.LUDICOLO, + Species.PELIPPER, + Species.WAILORD, + Species.WHISCASH, + Species.CRAWDAUNT, + Species.WALREIN, + Species.CLAMPERL, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.QUAGSIRE, + Species.MANTINE, + Species.KINGDRA, + Species.MILOTIC, + Species.DRAGALGE, + Species.DHELMISE, + Species.BARRASKEWDA, + Species.GRAPPLOCT, + Species.OVERQWIL, + ], + [TrainerPoolTier.RARE]: [Species.BASCULEGION, Species.DONDOZO], +}; + +const GALACTIC: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.ELECTRODE, + Species.GYARADOS, + Species.CROBAT, + Species.HONCHKROW, + Species.BRONZONG, + Species.DRAPION, + Species.LICKILICKY, + Species.TANGROWTH, + Species.ELECTIVIRE, + Species.MAGMORTAR, + Species.YANMEGA, + Species.MAMOSWINE, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.ALAKAZAM, + Species.WEAVILE, + Species.GLISCOR, + Species.DUSKNOIR, + Species.ROTOM, + Species.OVERQWIL, + Species.HISUI_ARCANINE, + Species.HISUI_ELECTRODE, + ], + [TrainerPoolTier.RARE]: [Species.SPIRITOMB, Species.URSALUNA, Species.SNEASLER, Species.HISUI_LILLIGANT], +}; + +const PLASMA_ZINZOLIN: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.GIGALITH, + Species.CONKELDURR, + Species.SEISMITOAD, + Species.KROOKODILE, + Species.DARMANITAN, + Species.COFAGRIGUS, + Species.VANILLUXE, + Species.AMOONGUSS, + Species.JELLICENT, + Species.GALVANTULA, + Species.FERROTHORN, + Species.BEARTIC, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.EXCADRILL, + Species.SIGILYPH, + Species.ZOROARK, + Species.KLINKLANG, + Species.EELEKTROSS, + Species.MIENSHAO, + Species.GOLURK, + Species.BISHARP, + Species.MANDIBUZZ, + Species.DURANT, + Species.GALAR_DARMANITAN, + ], + [TrainerPoolTier.RARE]: [Species.HAXORUS, Species.HYDREIGON, Species.HISUI_ZOROARK, Species.HISUI_BRAVIARY], +}; + +const PLASMA_COLRESS: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.MUK, + Species.ELECTRODE, + Species.BRONZONG, + Species.MAGNEZONE, + Species.PORYGON_Z, + Species.MUSHARNA, + Species.REUNICLUS, + Species.GALVANTULA, + Species.FERROTHORN, + Species.EELEKTROSS, + Species.BEHEEYEM, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.METAGROSS, + Species.ROTOM, + Species.CARRACOSTA, + Species.ARCHEOPS, + Species.GOLURK, + Species.DURANT, + Species.VIKAVOLT, + Species.ORBEETLE, + Species.REVAVROOM, + Species.ALOLA_MUK, + Species.HISUI_ELECTRODE, + ], + [TrainerPoolTier.RARE]: [Species.ELECTIVIRE, Species.MAGMORTAR, Species.BISHARP, Species.ARCHALUDON], +}; + +const FLARE: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.MANECTRIC, + Species.DRAPION, + Species.LIEPARD, + Species.AMOONGUSS, + Species.DIGGERSBY, + Species.TALONFLAME, + Species.PYROAR, + Species.PANGORO, + Species.MEOWSTIC, + Species.MALAMAR, + Species.CLAWITZER, + Species.HELIOLISK, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.HOUNDOOM, + Species.WEAVILE, + Species.CHANDELURE, + Species.AEGISLASH, + Species.BARBARACLE, + Species.DRAGALGE, + Species.GOODRA, + Species.TREVENANT, + Species.GOURGEIST, + ], + [TrainerPoolTier.RARE]: [Species.NOIVERN, Species.HISUI_GOODRA, Species.HISUI_AVALUGG], +}; + +const AETHER: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.ALAKAZAM, + Species.SLOWBRO, + Species.EXEGGUTOR, + Species.XATU, + Species.CLAYDOL, + Species.BEHEEYEM, + Species.ORANGURU, + Species.BRUXISH, + Species.ORBEETLE, + Species.FARIGIRAF, + Species.ALOLA_RAICHU, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.KIRLIA, + Species.MEDICHAM, + Species.METAGROSS, + Species.MALAMAR, + Species.HATTERENE, + Species.MR_RIME, + Species.GALAR_SLOWKING, + ], + [TrainerPoolTier.RARE]: [Species.PORYGON_Z, Species.ARMAROUGE, Species.HISUI_BRAVIARY], +}; + +const SKULL: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.NIDOQUEEN, + Species.GENGAR, + Species.KOFFING, + Species.CROBAT, + Species.ROSERADE, + Species.SKUNTANK, + Species.TOXICROAK, + Species.SCOLIPEDE, + Species.TOXAPEX, + Species.LURANTIS, + Species.ALOLA_MUK, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.DRAPION, + Species.MANDIBUZZ, + Species.OVERQWIL, + Species.GLIMMORA, + Species.CLODSIRE, + Species.GALAR_SLOWBRO, + ], + [TrainerPoolTier.RARE]: [Species.DRAGALGE, Species.SNEASLER], +}; + +const MACRO_COSMOS: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.NINETALES, + Species.BELLOSSOM, + Species.MILOTIC, + Species.FROSLASS, + Species.GOTHITELLE, + Species.JELLICENT, + Species.SALAZZLE, + Species.TSAREENA, + Species.POLTEAGEIST, + Species.HATTERENE, + Species.GALAR_RAPIDASH, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.TOGEKISS, + Species.MANDIBUZZ, + Species.TOXAPEX, + Species.APPLETUN, + Species.CURSOLA, + Species.ALOLA_NINETALES, + ], + [TrainerPoolTier.RARE]: [Species.TINKATON, Species.HISUI_LILLIGANT], +}; + +const STAR_DARK: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.SHIFTRY, + Species.CACTURNE, + Species.HONCHKROW, + Species.SKUNTANK, + Species.KROOKODILE, + Species.OBSTAGOON, + Species.LOKIX, + Species.MABOSSTIFF, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.UMBREON, + Species.CRAWDAUNT, + Species.WEAVILE, + Species.ZOROARK, + Species.MALAMAR, + Species.BOMBIRDIER, + ], + [TrainerPoolTier.RARE]: [Species.HYDREIGON, Species.MEOWSCARADA], +}; + +const STAR_FIRE: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.ARCANINE, + Species.HOUNDOOM, + Species.CAMERUPT, + Species.CHANDELURE, + Species.TALONFLAME, + Species.PYROAR, + Species.COALOSSAL, + Species.SCOVILLAIN, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.RAPIDASH, + Species.FLAREON, + Species.TORKOAL, + Species.MAGMORTAR, + Species.SALAZZLE, + Species.TURTONATOR, + ], + [TrainerPoolTier.RARE]: [Species.VOLCARONA, Species.SKELEDIRGE], +}; + +const STAR_POISON: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.MUK, + Species.CROBAT, + Species.SKUNTANK, + Species.AMOONGUSS, + Species.TOXAPEX, + Species.TOXTRICITY, + Species.GRAFAIAI, + Species.CLODSIRE, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.GENGAR, + Species.SEVIPER, + Species.DRAGALGE, + Species.OVERQWIL, + Species.ALOLA_MUK, + Species.GALAR_SLOWBRO, + ], + [TrainerPoolTier.RARE]: [Species.GLIMMORA, Species.VENUSAUR], +}; + +const STAR_FAIRY: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.CLEFABLE, + Species.WIGGLYTUFF, + Species.AZUMARILL, + Species.WHIMSICOTT, + Species.FLORGES, + Species.HATTERENE, + Species.GRIMMSNARL, + Species.TINKATON, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.TOGEKISS, + Species.GARDEVOIR, + Species.SYLVEON, + Species.KLEFKI, + Species.MIMIKYU, + Species.ALOLA_NINETALES, + ], + [TrainerPoolTier.RARE]: [Species.GALAR_RAPIDASH, Species.PRIMARINA], +}; + +const STAR_FIGHTING: TrainerTierPools = { + [TrainerPoolTier.COMMON]: [ + Species.BRELOOM, + Species.HARIYAMA, + Species.MEDICHAM, + Species.TOXICROAK, + Species.SCRAFTY, + Species.MIENSHAO, + Species.PAWMOT, + Species.PALDEA_TAUROS, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.LUCARIO, + Species.CONKELDURR, + Species.HAWLUCHA, + Species.PASSIMIAN, + Species.FALINKS, + Species.FLAMIGO, + ], + [TrainerPoolTier.RARE]: [Species.KOMMO_O, Species.QUAQUAVAL], +}; + +export type EvilTeam = + | "rocket" + | "magma" + | "aqua" + | "galactic" + | "plasma_zinzolin" + | "plasma_colress" + | "flare" + | "aether" + | "skull" + | "macro_cosmos" + | "star_dark" + | "star_fire" + | "star_poison" + | "star_fairy" + | "star_fighting"; + +/** Trainer pools for each evil admin team */ +export const evilAdminTrainerPools: Record = { + rocket: ROCKET, + magma: MAGMA, + aqua: AQUA, + galactic: GALACTIC, + plasma_zinzolin: PLASMA_ZINZOLIN, + plasma_colress: PLASMA_COLRESS, + flare: FLARE, + aether: AETHER, + macro_cosmos: MACRO_COSMOS, + skull: SKULL, + star_dark: STAR_DARK, + star_fire: STAR_FIRE, + star_poison: STAR_POISON, + star_fairy: STAR_FAIRY, + star_fighting: STAR_FIGHTING, +}; diff --git a/src/data/trainer-config.ts b/src/data/trainers/trainer-config.ts similarity index 88% rename from src/data/trainer-config.ts rename to src/data/trainers/trainer-config.ts index 3884aa05b13..f23027ffee8 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainers/trainer-config.ts @@ -1,28 +1,53 @@ -import { startingWave } from "#app/battle-scene"; import { globalScene } from "#app/global-scene"; -import type { ModifierTypeFunc } from "#app/modifier/modifier-type"; import { modifierTypes } from "#app/modifier/modifier-type"; -import type { EnemyPokemon } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon"; import * as Utils from "#app/utils"; -import { PokeballType } from "#enums/pokeball"; import { pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; -import type { PokemonSpeciesFilter } from "#app/data/pokemon-species"; -import type PokemonSpecies from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import { tmSpecies } from "#app/data/balance/tms"; -import { PokemonType } from "#enums/pokemon-type"; import { doubleBattleDialogue } from "#app/data/dialogue"; -import type { PersistentModifier } from "#app/modifier/modifier"; import { TrainerVariant } from "#app/field/trainer"; import { getIsInitialized, initI18n } from "#app/plugins/i18n"; import i18next from "i18next"; -import { Moves } from "#enums/moves"; +import { Gender } from "#app/data/gender"; +import { signatureSpecies } from "../balance/signature-species"; +import { + getEvilGruntPartyTemplate, + getGymLeaderPartyTemplate, + getWavePartyTemplate, + TrainerPartyCompoundTemplate, + TrainerPartyTemplate, + trainerPartyTemplates, +} from "./TrainerPartyTemplate"; +import { evilAdminTrainerPools } from "./evil-admin-trainer-pools"; + +// Enum imports import { PartyMemberStrength } from "#enums/party-member-strength"; import { Species } from "#enums/species"; +import { PokeballType } from "#enums/pokeball"; +import { PokemonType } from "#enums/pokemon-type"; +import { Moves } from "#enums/moves"; +import { Abilities } from "#enums/abilities"; +import { TeraAIMode } from "#enums/tera-ai-mode"; +import { TrainerPoolTier } from "#enums/trainer-pool-tier"; +import { TrainerSlot } from "#enums/trainer-slot"; import { TrainerType } from "#enums/trainer-type"; -import { Gender } from "#app/data/gender"; -import { signatureSpecies } from "./balance/signature-species"; + +// Type imports +import type { PokemonSpeciesFilter } from "#app/data/pokemon-species"; +import type PokemonSpecies from "#app/data/pokemon-species"; +import type { ModifierTypeFunc } from "#app/modifier/modifier-type"; +import type { EnemyPokemon } from "#app/field/pokemon"; +import type { EvilTeam } from "./evil-admin-trainer-pools"; +import type { + PartyMemberFunc, + GenModifiersFunc, + GenAIFunc, + PartyTemplateFunc, + TrainerTierPools, + TrainerConfigs, + PartyMemberFuncs, +} from "./typedefs"; /** Minimum BST for Pokemon generated onto the Elite Four's teams */ const ELITE_FOUR_MINIMUM_BST = 460; @@ -30,253 +55,6 @@ const ELITE_FOUR_MINIMUM_BST = 460; /** The wave at which (non-Paldean) Gym Leaders start having Tera mons*/ const GYM_LEADER_TERA_WAVE = 100; -export enum TrainerPoolTier { - COMMON, - UNCOMMON, - RARE, - SUPER_RARE, - ULTRA_RARE, -} - -export interface TrainerTierPools { - [key: number]: Species[]; -} - -export enum TrainerSlot { - NONE, - TRAINER, - TRAINER_PARTNER, -} - -export class TrainerPartyTemplate { - public size: number; - public strength: PartyMemberStrength; - public sameSpecies: boolean; - public balanced: boolean; - - constructor(size: number, strength: PartyMemberStrength, sameSpecies?: boolean, balanced?: boolean) { - this.size = size; - this.strength = strength; - this.sameSpecies = !!sameSpecies; - this.balanced = !!balanced; - } - - getStrength(_index: number): PartyMemberStrength { - return this.strength; - } - - isSameSpecies(_index: number): boolean { - return this.sameSpecies; - } - - isBalanced(_index: number): boolean { - return this.balanced; - } -} - -export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate { - public templates: TrainerPartyTemplate[]; - - constructor(...templates: TrainerPartyTemplate[]) { - super( - templates.reduce((total: number, template: TrainerPartyTemplate) => { - total += template.size; - return total; - }, 0), - PartyMemberStrength.AVERAGE, - ); - this.templates = templates; - } - - getStrength(index: number): PartyMemberStrength { - let t = 0; - for (const template of this.templates) { - if (t + template.size > index) { - return template.getStrength(index - t); - } - t += template.size; - } - - return super.getStrength(index); - } - - isSameSpecies(index: number): boolean { - let t = 0; - for (const template of this.templates) { - if (t + template.size > index) { - return template.isSameSpecies(index - t); - } - t += template.size; - } - - return super.isSameSpecies(index); - } - - isBalanced(index: number): boolean { - let t = 0; - for (const template of this.templates) { - if (t + template.size > index) { - return template.isBalanced(index - t); - } - t += template.size; - } - - return super.isBalanced(index); - } -} - -export const trainerPartyTemplates = { - ONE_WEAK_ONE_STRONG: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.WEAK), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - ), - ONE_AVG: new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - ONE_AVG_ONE_STRONG: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - ), - ONE_STRONG: new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - ONE_STRONGER: new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), - TWO_WEAKER: new TrainerPartyTemplate(2, PartyMemberStrength.WEAKER), - TWO_WEAK: new TrainerPartyTemplate(2, PartyMemberStrength.WEAK), - TWO_WEAK_ONE_AVG: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.WEAK), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - ), - TWO_WEAK_SAME_ONE_AVG: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - ), - TWO_WEAK_SAME_TWO_WEAK_SAME: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true), - new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true), - ), - TWO_WEAK_ONE_STRONG: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.WEAK), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - ), - TWO_AVG: new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE), - TWO_AVG_ONE_STRONG: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - ), - TWO_AVG_SAME_ONE_AVG: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - ), - TWO_AVG_SAME_ONE_STRONG: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - ), - TWO_AVG_SAME_TWO_AVG_SAME: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true), - new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true), - ), - TWO_STRONG: new TrainerPartyTemplate(2, PartyMemberStrength.STRONG), - THREE_WEAK: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK), - THREE_WEAK_SAME: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK, true), - THREE_AVG: new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), - THREE_AVG_SAME: new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, true), - THREE_WEAK_BALANCED: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK, false, true), - FOUR_WEAKER: new TrainerPartyTemplate(4, PartyMemberStrength.WEAKER), - FOUR_WEAKER_SAME: new TrainerPartyTemplate(4, PartyMemberStrength.WEAKER, true), - FOUR_WEAK: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK), - FOUR_WEAK_SAME: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK, true), - FOUR_WEAK_BALANCED: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK, false, true), - FIVE_WEAKER: new TrainerPartyTemplate(5, PartyMemberStrength.WEAKER), - FIVE_WEAK: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK), - FIVE_WEAK_BALANCED: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK, false, true), - SIX_WEAKER: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER), - SIX_WEAKER_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER, true), - SIX_WEAK_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, true), - SIX_WEAK_BALANCED: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, false, true), - - GYM_LEADER_1: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - ), - GYM_LEADER_2: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), - ), - GYM_LEADER_3: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), - ), - GYM_LEADER_4: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), - ), - GYM_LEADER_5: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(2, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), - ), - - ELITE_FOUR: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(3, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), - ), - - CHAMPION: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(4, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(2, PartyMemberStrength.STRONGER, false, true), - ), - - RIVAL: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - ), - RIVAL_2: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true), - ), - RIVAL_3: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE, false, true), - new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true), - ), - RIVAL_4: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, false, true), - new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true), - ), - RIVAL_5: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - ), - RIVAL_6: new TrainerPartyCompoundTemplate( - new TrainerPartyTemplate(1, PartyMemberStrength.STRONG), - new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), - new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true), - new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER), - ), -}; - -type PartyTemplateFunc = () => TrainerPartyTemplate; -type PartyMemberFunc = (level: number, strength: PartyMemberStrength) => EnemyPokemon; -type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[]; -type GenAIFunc = (party: EnemyPokemon[]) => void; - -export interface PartyMemberFuncs { - [key: number]: PartyMemberFunc; -} - -export enum TeraAIMode { - NO_TERA, - INSTANT_TERA, - SMART_TERA, -} - /** * Stores data and helper functions about a trainers AI options. */ @@ -758,430 +536,6 @@ export class TrainerConfig { return this; } - /** - * Returns the pool of species for an evil team admin - * @param team - The evil team the admin belongs to. - * @returns {TrainerTierPools} - */ - speciesPoolPerEvilTeamAdmin(team): TrainerTierPools { - team = team.toLowerCase(); - switch (team) { - case "rocket": { - return { - [TrainerPoolTier.COMMON]: [ - Species.RATICATE, - Species.ARBOK, - Species.VILEPLUME, - Species.ARCANINE, - Species.GENGAR, - Species.HYPNO, - Species.ELECTRODE, - Species.EXEGGUTOR, - Species.CUBONE, - Species.KOFFING, - Species.GYARADOS, - Species.CROBAT, - Species.STEELIX, - Species.HOUNDOOM, - Species.HONCHKROW, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.OMASTAR, - Species.KABUTOPS, - Species.MAGNEZONE, - Species.ELECTIVIRE, - Species.MAGMORTAR, - Species.PORYGON_Z, - Species.ANNIHILAPE, - Species.ALOLA_SANDSLASH, - Species.ALOLA_PERSIAN, - Species.ALOLA_GOLEM, - Species.ALOLA_MUK, - Species.PALDEA_TAUROS, - ], - [TrainerPoolTier.RARE]: [Species.DRAGONITE, Species.TYRANITAR], - }; - } - case "magma": { - return { - [TrainerPoolTier.COMMON]: [ - Species.ARCANINE, - Species.MAGCARGO, - Species.HOUNDOOM, - Species.TORKOAL, - Species.SOLROCK, - Species.CLAYDOL, - Species.HIPPOWDON, - Species.MAGMORTAR, - Species.GLISCOR, - Species.COALOSSAL, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.AGGRON, - Species.FLYGON, - Species.CRADILY, - Species.ARMALDO, - Species.RHYPERIOR, - Species.TURTONATOR, - Species.SANDACONDA, - Species.TOEDSCRUEL, - Species.HISUI_ARCANINE, - ], - [TrainerPoolTier.RARE]: [Species.CHARCADET, Species.SCOVILLAIN], - }; - } - case "aqua": { - return { - [TrainerPoolTier.COMMON]: [ - Species.TENTACRUEL, - Species.LANTURN, - Species.AZUMARILL, - Species.QUAGSIRE, - Species.OCTILLERY, - Species.LUDICOLO, - Species.PELIPPER, - Species.WAILORD, - Species.WHISCASH, - Species.CRAWDAUNT, - Species.WALREIN, - Species.CLAMPERL, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.QUAGSIRE, - Species.MANTINE, - Species.KINGDRA, - Species.MILOTIC, - Species.DRAGALGE, - Species.DHELMISE, - Species.BARRASKEWDA, - Species.GRAPPLOCT, - Species.OVERQWIL, - ], - [TrainerPoolTier.RARE]: [Species.BASCULEGION, Species.DONDOZO], - }; - } - case "galactic": { - return { - [TrainerPoolTier.COMMON]: [ - Species.ELECTRODE, - Species.GYARADOS, - Species.CROBAT, - Species.HONCHKROW, - Species.BRONZONG, - Species.DRAPION, - Species.LICKILICKY, - Species.TANGROWTH, - Species.ELECTIVIRE, - Species.MAGMORTAR, - Species.YANMEGA, - Species.MAMOSWINE, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.ALAKAZAM, - Species.WEAVILE, - Species.GLISCOR, - Species.DUSKNOIR, - Species.ROTOM, - Species.OVERQWIL, - Species.HISUI_ARCANINE, - Species.HISUI_ELECTRODE, - ], - [TrainerPoolTier.RARE]: [Species.SPIRITOMB, Species.URSALUNA, Species.SNEASLER, Species.HISUI_LILLIGANT], - }; - } - case "plasma": { - return { - [TrainerPoolTier.COMMON]: [ - Species.GIGALITH, - Species.CONKELDURR, - Species.SEISMITOAD, - Species.KROOKODILE, - Species.DARMANITAN, - Species.COFAGRIGUS, - Species.VANILLUXE, - Species.AMOONGUSS, - Species.JELLICENT, - Species.GALVANTULA, - Species.FERROTHORN, - Species.BEARTIC, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.EXCADRILL, - Species.SIGILYPH, - Species.ZOROARK, - Species.KLINKLANG, - Species.EELEKTROSS, - Species.MIENSHAO, - Species.GOLURK, - Species.BISHARP, - Species.MANDIBUZZ, - Species.DURANT, - Species.GALAR_DARMANITAN, - ], - [TrainerPoolTier.RARE]: [Species.HAXORUS, Species.HYDREIGON, Species.HISUI_ZOROARK, Species.HISUI_BRAVIARY], - }; - } - case "plasma_2": { - return { - [TrainerPoolTier.COMMON]: [ - Species.MUK, - Species.ELECTRODE, - Species.BRONZONG, - Species.MAGNEZONE, - Species.PORYGON_Z, - Species.MUSHARNA, - Species.REUNICLUS, - Species.GALVANTULA, - Species.FERROTHORN, - Species.EELEKTROSS, - Species.BEHEEYEM, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.METAGROSS, - Species.ROTOM, - Species.CARRACOSTA, - Species.ARCHEOPS, - Species.GOLURK, - Species.DURANT, - Species.VIKAVOLT, - Species.ORBEETLE, - Species.REVAVROOM, - Species.ALOLA_MUK, - Species.HISUI_ELECTRODE, - ], - [TrainerPoolTier.RARE]: [Species.ELECTIVIRE, Species.MAGMORTAR, Species.BISHARP, Species.ARCHALUDON], - }; - } - case "flare": { - return { - [TrainerPoolTier.COMMON]: [ - Species.MANECTRIC, - Species.DRAPION, - Species.LIEPARD, - Species.AMOONGUSS, - Species.DIGGERSBY, - Species.TALONFLAME, - Species.PYROAR, - Species.PANGORO, - Species.MEOWSTIC, - Species.MALAMAR, - Species.CLAWITZER, - Species.HELIOLISK, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.HOUNDOOM, - Species.WEAVILE, - Species.CHANDELURE, - Species.AEGISLASH, - Species.BARBARACLE, - Species.DRAGALGE, - Species.GOODRA, - Species.TREVENANT, - Species.GOURGEIST, - ], - [TrainerPoolTier.RARE]: [Species.NOIVERN, Species.HISUI_GOODRA, Species.HISUI_AVALUGG], - }; - } - case "aether": { - return { - [TrainerPoolTier.COMMON]: [ - Species.ALAKAZAM, - Species.SLOWBRO, - Species.EXEGGUTOR, - Species.XATU, - Species.CLAYDOL, - Species.BEHEEYEM, - Species.ORANGURU, - Species.BRUXISH, - Species.ORBEETLE, - Species.FARIGIRAF, - Species.ALOLA_RAICHU, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.KIRLIA, - Species.MEDICHAM, - Species.METAGROSS, - Species.MALAMAR, - Species.HATTERENE, - Species.MR_RIME, - Species.GALAR_SLOWKING, - ], - [TrainerPoolTier.RARE]: [Species.PORYGON_Z, Species.ARMAROUGE, Species.HISUI_BRAVIARY], - }; - } - case "skull": { - return { - [TrainerPoolTier.COMMON]: [ - Species.NIDOQUEEN, - Species.GENGAR, - Species.KOFFING, - Species.CROBAT, - Species.ROSERADE, - Species.SKUNTANK, - Species.TOXICROAK, - Species.SCOLIPEDE, - Species.TOXAPEX, - Species.LURANTIS, - Species.ALOLA_MUK, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.DRAPION, - Species.MANDIBUZZ, - Species.OVERQWIL, - Species.GLIMMORA, - Species.CLODSIRE, - Species.GALAR_SLOWBRO, - ], - [TrainerPoolTier.RARE]: [Species.DRAGALGE, Species.SNEASLER], - }; - } - case "macro": { - return { - [TrainerPoolTier.COMMON]: [ - Species.NINETALES, - Species.BELLOSSOM, - Species.MILOTIC, - Species.FROSLASS, - Species.GOTHITELLE, - Species.JELLICENT, - Species.SALAZZLE, - Species.TSAREENA, - Species.POLTEAGEIST, - Species.HATTERENE, - Species.GALAR_RAPIDASH, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.TOGEKISS, - Species.MANDIBUZZ, - Species.TOXAPEX, - Species.APPLETUN, - Species.CURSOLA, - Species.ALOLA_NINETALES, - ], - [TrainerPoolTier.RARE]: [Species.TINKATON, Species.HISUI_LILLIGANT], - }; - } - case "star_1": { - return { - [TrainerPoolTier.COMMON]: [ - Species.SHIFTRY, - Species.CACTURNE, - Species.HONCHKROW, - Species.SKUNTANK, - Species.KROOKODILE, - Species.OBSTAGOON, - Species.LOKIX, - Species.MABOSSTIFF, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.UMBREON, - Species.CRAWDAUNT, - Species.WEAVILE, - Species.ZOROARK, - Species.MALAMAR, - Species.BOMBIRDIER, - ], - [TrainerPoolTier.RARE]: [Species.HYDREIGON, Species.MEOWSCARADA], - }; - } - case "star_2": { - return { - [TrainerPoolTier.COMMON]: [ - Species.ARCANINE, - Species.HOUNDOOM, - Species.CAMERUPT, - Species.CHANDELURE, - Species.TALONFLAME, - Species.PYROAR, - Species.COALOSSAL, - Species.SCOVILLAIN, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.RAPIDASH, - Species.FLAREON, - Species.TORKOAL, - Species.MAGMORTAR, - Species.SALAZZLE, - Species.TURTONATOR, - ], - [TrainerPoolTier.RARE]: [Species.VOLCARONA, Species.SKELEDIRGE], - }; - } - case "star_3": { - return { - [TrainerPoolTier.COMMON]: [ - Species.MUK, - Species.CROBAT, - Species.SKUNTANK, - Species.AMOONGUSS, - Species.TOXAPEX, - Species.TOXTRICITY, - Species.GRAFAIAI, - Species.CLODSIRE, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.GENGAR, - Species.SEVIPER, - Species.DRAGALGE, - Species.OVERQWIL, - Species.ALOLA_MUK, - Species.GALAR_SLOWBRO, - ], - [TrainerPoolTier.RARE]: [Species.GLIMMORA, Species.VENUSAUR], - }; - } - case "star_4": { - return { - [TrainerPoolTier.COMMON]: [ - Species.CLEFABLE, - Species.WIGGLYTUFF, - Species.AZUMARILL, - Species.WHIMSICOTT, - Species.FLORGES, - Species.HATTERENE, - Species.GRIMMSNARL, - Species.TINKATON, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.TOGEKISS, - Species.GARDEVOIR, - Species.SYLVEON, - Species.KLEFKI, - Species.MIMIKYU, - Species.ALOLA_NINETALES, - ], - [TrainerPoolTier.RARE]: [Species.GALAR_RAPIDASH, Species.PRIMARINA], - }; - } - case "star_5": { - return { - [TrainerPoolTier.COMMON]: [ - Species.BRELOOM, - Species.HARIYAMA, - Species.MEDICHAM, - Species.TOXICROAK, - Species.SCRAFTY, - Species.MIENSHAO, - Species.PAWMOT, - Species.PALDEA_TAUROS, - ], - [TrainerPoolTier.UNCOMMON]: [ - Species.LUCARIO, - Species.CONKELDURR, - Species.HAWLUCHA, - Species.PASSIMIAN, - Species.FALINKS, - Species.FLAMIGO, - ], - [TrainerPoolTier.RARE]: [Species.KOMMO_O, Species.QUAQUAVAL], - }; - } - } - - console.warn(`Evil team admin for ${team} not found. Returning empty species pools.`); - return []; - } - /** * Initializes the trainer configuration for an evil team admin. * @param title The title of the evil team admin. @@ -1192,7 +546,7 @@ export class TrainerConfig { * **/ initForEvilTeamAdmin( title: string, - poolName: string, + poolName: EvilTeam, signatureSpecies: (Species | Species[])[], specialtyType?: PokemonType, ): TrainerConfig { @@ -1207,7 +561,7 @@ export class TrainerConfig { this.setPartyTemplates(trainerPartyTemplates.RIVAL_5); // Set the species pools for the evil team admin. - this.speciesPools = this.speciesPoolPerEvilTeamAdmin(poolName); + this.speciesPools = evilAdminTrainerPools[poolName]; signatureSpecies.forEach((speciesPool, s) => { if (!Array.isArray(speciesPool)) { @@ -1636,56 +990,6 @@ export class TrainerConfig { let t = 0; -interface TrainerConfigs { - [key: number]: TrainerConfig; -} - -/** - * The function to get variable strength grunts - * @returns the correct TrainerPartyTemplate - */ -function getEvilGruntPartyTemplate(): TrainerPartyTemplate { - const waveIndex = globalScene.currentBattle?.waveIndex; - if (waveIndex < 40) { - return trainerPartyTemplates.TWO_AVG; - } - if (waveIndex < 63) { - return trainerPartyTemplates.THREE_AVG; - } - if (waveIndex < 65) { - return trainerPartyTemplates.TWO_AVG_ONE_STRONG; - } - if (waveIndex < 112) { - return trainerPartyTemplates.GYM_LEADER_4; // 3avg 1 strong 1 stronger - } - return trainerPartyTemplates.GYM_LEADER_5; // 3 avg 2 strong 1 stronger -} - -function getWavePartyTemplate(...templates: TrainerPartyTemplate[]) { - return templates[ - Math.min( - Math.max( - Math.ceil( - (globalScene.gameMode.getWaveForDifficulty(globalScene.currentBattle?.waveIndex || startingWave, true) - 20) / - 30, - ), - 0, - ), - templates.length - 1, - ) - ]; -} - -function getGymLeaderPartyTemplate() { - return getWavePartyTemplate( - trainerPartyTemplates.GYM_LEADER_1, - trainerPartyTemplates.GYM_LEADER_2, - trainerPartyTemplates.GYM_LEADER_3, - trainerPartyTemplates.GYM_LEADER_4, - trainerPartyTemplates.GYM_LEADER_5, - ); -} - /** * Randomly selects one of the `Species` from `speciesPool`, determines its evolution, level, and strength. * Then adds Pokemon to globalScene. @@ -1811,12 +1115,92 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.BAKER]: new TrainerConfig(++t) .setEncounterBgm(TrainerType.CLERK) .setMoneyMultiplier(1.35) - .setSpeciesFilter(s => s.isOfType(PokemonType.GRASS) || s.isOfType(PokemonType.FIRE)), - [TrainerType.BEAUTY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY), + .setSpeciesFilter( + s => + [s.ability1, s.ability2, s.abilityHidden].some( + a => + !!a && + [ + Abilities.WHITE_SMOKE, + Abilities.GLUTTONY, + Abilities.HONEY_GATHER, + Abilities.HARVEST, + Abilities.CHEEK_POUCH, + Abilities.SWEET_VEIL, + Abilities.RIPEN, + Abilities.PURIFYING_SALT, + Abilities.WELL_BAKED_BODY, + Abilities.SUPERSWEET_SYRUP, + Abilities.HOSPITALITY, + ].includes(a), + ) || + s + .getLevelMoves() + .some(plm => + [Moves.SOFT_BOILED, Moves.SPORE, Moves.MILK_DRINK, Moves.OVERHEAT, Moves.TEATIME].includes(plm[1]), + ), + ), // Mons with baking related abilities or who learn Overheat, Teatime, Milk Drink, Spore, or Soft-Boiled by level + [TrainerType.BEAUTY]: new TrainerConfig(++t) + .setMoneyMultiplier(1.55) + .setEncounterBgm(TrainerType.PARASOL_LADY) + .setPartyTemplates( + trainerPartyTemplates.TWO_AVG_SAME_ONE_AVG, + trainerPartyTemplates.TWO_AVG_SAME_ONE_STRONG, + trainerPartyTemplates.THREE_AVG_SAME, + trainerPartyTemplates.THREE_AVG, + trainerPartyTemplates.FOUR_WEAK, + trainerPartyTemplates.ONE_STRONG, + ) + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [ + Species.MEOWTH, + Species.GOLDEEN, + Species.MAREEP, + Species.MARILL, + Species.SKITTY, + Species.GLAMEOW, + Species.PURRLOIN, + ], + [TrainerPoolTier.UNCOMMON]: [ + Species.SMOOCHUM, + Species.ROSELIA, + Species.LUVDISC, + Species.BLITZLE, + Species.SEWADDLE, + Species.PETILIL, + Species.MINCCINO, + Species.GOTHITA, + Species.SPRITZEE, + Species.FLITTLE, + ], + [TrainerPoolTier.RARE]: [ + Species.FEEBAS, + Species.FURFROU, + Species.SALANDIT, + Species.BRUXISH, + Species.HATENNA, + Species.SNOM, + Species.ALOLA_VULPIX, + ], + [TrainerPoolTier.SUPER_RARE]: [Species.CLAMPERL, Species.AMAURA, Species.SYLVEON, Species.GOOMY, Species.POPPLIO], + }), [TrainerType.BIKER]: new TrainerConfig(++t) .setMoneyMultiplier(1.4) .setEncounterBgm(TrainerType.ROUGHNECK) - .setSpeciesFilter(s => s.isOfType(PokemonType.POISON)), + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [Species.EKANS, Species.KOFFING, Species.CROAGUNK, Species.VENIPEDE, Species.SCRAGGY], + [TrainerPoolTier.UNCOMMON]: [ + Species.GRIMER, + Species.VOLTORB, + Species.TEDDIURSA, + Species.MAGBY, + Species.SKORUPI, + Species.SANDILE, + Species.PAWNIARD, + Species.SHROODLE, + ], + [TrainerPoolTier.RARE]: [Species.VAROOM, Species.CYCLIZAR], + }), [TrainerType.BLACK_BELT]: new TrainerConfig(++t) .setHasGenders("Battle Girl", TrainerType.PSYCHIC) .setHasDouble("Crush Kin") @@ -1918,9 +1302,15 @@ export const trainerConfigs: TrainerConfigs = { .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.COMMON]: [Species.DODUO, Species.PICHU, Species.TAILLOW, Species.STARLY, Species.PONYTA], + [TrainerPoolTier.UNCOMMON]: [ + Species.ELECTRIKE, + Species.SHINX, + Species.BLITZLE, + Species.DUCKLETT, + Species.WATTREL, + ], + [TrainerPoolTier.RARE]: [Species.YANMA, Species.NINJASK, Species.WHIRLIPEDE, Species.EMOLGA, Species.SKIDDO], [TrainerPoolTier.SUPER_RARE]: [Species.ACCELGOR, Species.DREEPY], }), [TrainerType.DANCER]: new TrainerConfig(++t) @@ -1936,7 +1326,7 @@ export const trainerConfigs: TrainerConfigs = { [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.SUPER_RARE]: [Species.QUAXLY, Species.JANGMO_O], }), [TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setMoneyMultiplier(1.45).setEncounterBgm(TrainerType.CLERK), [TrainerType.DOCTOR]: new TrainerConfig(++t) @@ -2054,7 +1444,15 @@ export const trainerConfigs: TrainerConfigs = { }), [TrainerType.HOOLIGANS]: new TrainerConfig(++t) .setDoubleOnly() + .setMoneyMultiplier(1.5) .setEncounterBgm(TrainerType.ROUGHNECK) + .setPartyTemplateFunc(() => + getWavePartyTemplate( + trainerPartyTemplates.TWO_WEAK, + trainerPartyTemplates.TWO_AVG, + trainerPartyTemplates.ONE_AVG_ONE_STRONG, + ), + ) .setSpeciesFilter(s => s.isOfType(PokemonType.POISON) || s.isOfType(PokemonType.DARK)), [TrainerType.HOOPSTER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.INFIELDER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), @@ -2062,7 +1460,14 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.LINEBACKER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.MAID]: new TrainerConfig(++t).setMoneyMultiplier(1.6).setEncounterBgm(TrainerType.RICH), [TrainerType.MUSICIAN]: new TrainerConfig(++t) - .setEncounterBgm(TrainerType.ROUGHNECK) + .setMoneyMultiplier(1.1) + .setEncounterBgm(TrainerType.POKEFAN) + .setPartyTemplates( + trainerPartyTemplates.FOUR_WEAKER, + trainerPartyTemplates.THREE_WEAK, + trainerPartyTemplates.TWO_WEAK_ONE_AVG, + trainerPartyTemplates.TWO_AVG, + ) .setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.SING)), [TrainerType.HEX_MANIAC]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) @@ -2074,7 +1479,7 @@ export const trainerConfigs: TrainerConfigs = { trainerPartyTemplates.THREE_AVG, trainerPartyTemplates.TWO_STRONG, ) - .setSpeciesFilter(s => s.isOfType(PokemonType.GHOST)), + .setSpeciesFilter(s => s.isOfType(PokemonType.GHOST) || s.isOfType(PokemonType.PSYCHIC)), [TrainerType.NURSERY_AIDE]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm("lass"), [TrainerType.OFFICER]: new TrainerConfig(++t) .setMoneyMultiplier(1.55) @@ -2104,9 +1509,37 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.PARASOL_LADY]: new TrainerConfig(++t) .setMoneyMultiplier(1.55) .setEncounterBgm(TrainerType.PARASOL_LADY) - .setSpeciesFilter(s => s.isOfType(PokemonType.WATER)), + .setPartyTemplates( + trainerPartyTemplates.TWO_AVG_SAME_ONE_AVG, + trainerPartyTemplates.TWO_AVG_SAME_ONE_STRONG, + trainerPartyTemplates.TWO_AVG, + trainerPartyTemplates.FOUR_WEAK, + trainerPartyTemplates.ONE_STRONG, + ) + .setSpeciesFilter( + s => + [s.ability1, s.ability2, s.abilityHidden].some( + a => + !!a && + [ + Abilities.DRIZZLE, + Abilities.SWIFT_SWIM, + Abilities.HYDRATION, + Abilities.RAIN_DISH, + Abilities.DRY_SKIN, + Abilities.WIND_POWER, + ].includes(a), + ) || s.getLevelMoves().some(plm => plm[1] === Moves.RAIN_DANCE), + ), // Mons with rain abilities or who learn Rain Dance by level [TrainerType.PILOT]: new TrainerConfig(++t) + .setMoneyMultiplier(1.75) .setEncounterBgm(TrainerType.CLERK) + .setPartyTemplates( + trainerPartyTemplates.THREE_WEAK, + trainerPartyTemplates.TWO_WEAK_ONE_AVG, + trainerPartyTemplates.TWO_AVG, + trainerPartyTemplates.THREE_AVG, + ) .setSpeciesFilter(s => tmSpecies[Moves.FLY].indexOf(s.speciesId) > -1), [TrainerType.POKEFAN]: new TrainerConfig(++t) .setMoneyMultiplier(1.4) @@ -2122,7 +1555,8 @@ export const trainerConfigs: TrainerConfigs = { trainerPartyTemplates.FOUR_WEAK_SAME, trainerPartyTemplates.FIVE_WEAK, trainerPartyTemplates.SIX_WEAKER_SAME, - ), + ) + .setSpeciesFilter(s => tmSpecies[Moves.HELPING_HAND].indexOf(s.speciesId) > -1), [TrainerType.PRESCHOOLER]: new TrainerConfig(++t) .setMoneyMultiplier(0.2) .setEncounterBgm(TrainerType.YOUNGSTER) @@ -2244,16 +1678,29 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.SUPER_RARE]: [Species.LARVESTA], }), [TrainerType.RICH]: new TrainerConfig(++t) - .setMoneyMultiplier(5) + .setMoneyMultiplier(3.25) .setName("Gentleman") .setHasGenders("Madame") - .setHasDouble("Rich Couple"), + .setHasDouble("Rich Couple") + .setPartyTemplates( + trainerPartyTemplates.THREE_WEAK, + trainerPartyTemplates.FOUR_WEAK, + trainerPartyTemplates.TWO_WEAK_ONE_AVG, + trainerPartyTemplates.THREE_AVG, + ) + .setSpeciesFilter(s => s.isOfType(PokemonType.NORMAL) || s.isOfType(PokemonType.ELECTRIC)), [TrainerType.RICH_KID]: new TrainerConfig(++t) - .setMoneyMultiplier(3.75) + .setMoneyMultiplier(2.5) .setName("Rich Boy") .setHasGenders("Lady") .setHasDouble("Rich Kids") - .setEncounterBgm(TrainerType.RICH), + .setEncounterBgm(TrainerType.RICH) + .setPartyTemplates( + trainerPartyTemplates.FOUR_WEAKER, + trainerPartyTemplates.THREE_WEAK_SAME, + trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, + ) + .setSpeciesFilter(s => s.baseTotal <= 460), [TrainerType.ROUGHNECK]: new TrainerConfig(++t) .setMoneyMultiplier(1.4) .setEncounterBgm(TrainerType.ROUGHNECK) @@ -2734,7 +2181,7 @@ export const trainerConfigs: TrainerConfigs = { }), [TrainerType.ZINZOLIN]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) - .initForEvilTeamAdmin("plasma_sage", "plasma", [Species.CRYOGONAL]) + .initForEvilTeamAdmin("plasma_sage", "plasma_zinzolin", [Species.CRYOGONAL]) .setEncounterBgm(TrainerType.PLASMA_GRUNT) .setBattleBgm("battle_plasma_grunt") .setMixedBattleBgm("battle_plasma_grunt") @@ -2742,7 +2189,7 @@ export const trainerConfigs: TrainerConfigs = { .setPartyTemplateFunc(() => getEvilGruntPartyTemplate()), [TrainerType.COLRESS]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) - .initForEvilTeamAdmin("plasma_boss", "plasma_2", [Species.KLINKLANG]) + .initForEvilTeamAdmin("plasma_boss", "plasma_colress", [Species.KLINKLANG]) .setEncounterBgm(TrainerType.PLASMA_GRUNT) .setBattleBgm("battle_colress") .setMixedBattleBgm("battle_colress") @@ -2961,7 +2408,7 @@ export const trainerConfigs: TrainerConfigs = { }), [TrainerType.OLEANA]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) - .initForEvilTeamAdmin("macro_admin", "macro", [Species.GARBODOR]) + .initForEvilTeamAdmin("macro_admin", "macro_cosmos", [Species.GARBODOR]) .setEncounterBgm(TrainerType.PLASMA_GRUNT) .setBattleBgm("battle_plasma_grunt") .setMixedBattleBgm("battle_oleana") @@ -3028,7 +2475,7 @@ export const trainerConfigs: TrainerConfigs = { }), [TrainerType.GIACOMO]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) - .initForEvilTeamAdmin("star_admin", "star_1", [Species.KINGAMBIT], PokemonType.DARK) + .initForEvilTeamAdmin("star_admin", "star_dark", [Species.KINGAMBIT], PokemonType.DARK) .setEncounterBgm(TrainerType.PLASMA_GRUNT) .setBattleBgm("battle_plasma_grunt") .setMixedBattleBgm("battle_star_admin") @@ -3048,7 +2495,7 @@ export const trainerConfigs: TrainerConfigs = { ), [TrainerType.MELA]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) - .initForEvilTeamAdmin("star_admin", "star_2", [Species.ARMAROUGE], PokemonType.FIRE) + .initForEvilTeamAdmin("star_admin", "star_fire", [Species.ARMAROUGE], PokemonType.FIRE) .setEncounterBgm(TrainerType.PLASMA_GRUNT) .setBattleBgm("battle_plasma_grunt") .setMixedBattleBgm("battle_star_admin") @@ -3068,7 +2515,7 @@ export const trainerConfigs: TrainerConfigs = { ), [TrainerType.ATTICUS]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) - .initForEvilTeamAdmin("star_admin", "star_3", [Species.REVAVROOM], PokemonType.POISON) + .initForEvilTeamAdmin("star_admin", "star_poison", [Species.REVAVROOM], PokemonType.POISON) .setEncounterBgm(TrainerType.PLASMA_GRUNT) .setBattleBgm("battle_plasma_grunt") .setMixedBattleBgm("battle_star_admin") @@ -3088,7 +2535,7 @@ export const trainerConfigs: TrainerConfigs = { ), [TrainerType.ORTEGA]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) - .initForEvilTeamAdmin("star_admin", "star_4", [Species.DACHSBUN], PokemonType.FAIRY) + .initForEvilTeamAdmin("star_admin", "star_fairy", [Species.DACHSBUN], PokemonType.FAIRY) .setEncounterBgm(TrainerType.PLASMA_GRUNT) .setBattleBgm("battle_plasma_grunt") .setMixedBattleBgm("battle_star_admin") @@ -3108,7 +2555,7 @@ export const trainerConfigs: TrainerConfigs = { ), [TrainerType.ERI]: new TrainerConfig(++t) .setMoneyMultiplier(1.5) - .initForEvilTeamAdmin("star_admin", "star_5", [Species.ANNIHILAPE], PokemonType.FIGHTING) + .initForEvilTeamAdmin("star_admin", "star_fighting", [Species.ANNIHILAPE], PokemonType.FIGHTING) .setEncounterBgm(TrainerType.PLASMA_GRUNT) .setBattleBgm("battle_plasma_grunt") .setMixedBattleBgm("battle_star_admin") diff --git a/src/data/trainers/typedefs.ts b/src/data/trainers/typedefs.ts new file mode 100644 index 00000000000..c6d286e961e --- /dev/null +++ b/src/data/trainers/typedefs.ts @@ -0,0 +1,22 @@ +import type { EnemyPokemon } from "#app/field/pokemon"; +import type { PersistentModifier } from "#app/modifier/modifier"; +import type { PartyMemberStrength } from "#enums/party-member-strength"; +import type { Species } from "#enums/species"; +import type { TrainerConfig } from "./trainer-config"; +import type { TrainerPartyTemplate } from "./TrainerPartyTemplate"; + +export type PartyTemplateFunc = () => TrainerPartyTemplate; +export type PartyMemberFunc = (level: number, strength: PartyMemberStrength) => EnemyPokemon; +export type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[]; +export type GenAIFunc = (party: EnemyPokemon[]) => void; + +export interface TrainerTierPools { + [key: number]: Species[]; +} +export interface TrainerConfigs { + [key: number]: TrainerConfig; +} + +export interface PartyMemberFuncs { + [key: number]: PartyMemberFunc; +} diff --git a/src/enums/tera-ai-mode.ts b/src/enums/tera-ai-mode.ts new file mode 100644 index 00000000000..35d4e4f3420 --- /dev/null +++ b/src/enums/tera-ai-mode.ts @@ -0,0 +1,5 @@ +export enum TeraAIMode { + NO_TERA, + INSTANT_TERA, + SMART_TERA +} diff --git a/src/enums/trainer-pool-tier.ts b/src/enums/trainer-pool-tier.ts new file mode 100644 index 00000000000..da6355d021b --- /dev/null +++ b/src/enums/trainer-pool-tier.ts @@ -0,0 +1,7 @@ +export enum TrainerPoolTier { + COMMON, + UNCOMMON, + RARE, + SUPER_RARE, + ULTRA_RARE +} diff --git a/src/enums/trainer-slot.ts b/src/enums/trainer-slot.ts new file mode 100644 index 00000000000..2dfa468f74c --- /dev/null +++ b/src/enums/trainer-slot.ts @@ -0,0 +1,5 @@ +export enum TrainerSlot { + NONE, + TRAINER, + TRAINER_PARTNER +} diff --git a/src/field/arena.ts b/src/field/arena.ts index 997b80b3237..4f243789567 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -42,6 +42,7 @@ import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrig import { CommonAnimPhase } from "#app/phases/common-anim-phase"; import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; import { WeatherType } from "#enums/weather-type"; +import { FieldEffectModifier } from "#app/modifier/modifier"; export class Arena { public biomeType: Biome; @@ -311,10 +312,10 @@ export class Arena { /** * Attempts to set a new weather to the battle * @param weather {@linkcode WeatherType} new {@linkcode WeatherType} to set - * @param hasPokemonSource boolean if the new weather is from a pokemon + * @param user {@linkcode Pokemon} that caused the weather effect * @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use */ - trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean { + trySetWeather(weather: WeatherType, user?: Pokemon): boolean { if (Overrides.WEATHER_OVERRIDE) { return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE); } @@ -336,7 +337,14 @@ export class Arena { return false; } - this.weather = weather ? new Weather(weather, hasPokemonSource ? 5 : 0) : null; + const weatherDuration = new Utils.NumberHolder(0); + + if (!Utils.isNullOrUndefined(user)) { + weatherDuration.value = 5; + globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, weatherDuration); + } + + this.weather = weather ? new Weather(weather, weatherDuration.value) : null; this.eventTarget.dispatchEvent( new WeatherChangedEvent(oldWeatherType, this.weather?.weatherType!, this.weather?.turnsLeft!), ); // TODO: is this bang correct? @@ -398,14 +406,29 @@ export class Arena { return !(this.terrain?.terrainType === (terrain || undefined)); } - trySetTerrain(terrain: TerrainType, hasPokemonSource: boolean, ignoreAnim = false): boolean { + /** + * Attempts to set a new terrain effect to the battle + * @param terrain {@linkcode TerrainType} new {@linkcode TerrainType} to set + * @param ignoreAnim boolean if the terrain animation should be ignored + * @param user {@linkcode Pokemon} that caused the terrain effect + * @returns true if new terrain set, false if no terrain provided or attempting to set the same terrain as currently in use + */ + trySetTerrain(terrain: TerrainType, ignoreAnim = false, user?: Pokemon): boolean { if (!this.canSetTerrain(terrain)) { return false; } const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE; - this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null; + const terrainDuration = new Utils.NumberHolder(0); + + if (!Utils.isNullOrUndefined(user)) { + terrainDuration.value = 5; + globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, terrainDuration); + } + + this.terrain = terrain ? new Terrain(terrain, terrainDuration.value) : null; + this.eventTarget.dispatchEvent( new TerrainChangedEvent(oldTerrainType, this.terrain?.terrainType!, this.terrain?.turnsLeft!), ); // TODO: are those bangs correct? @@ -673,7 +696,7 @@ export class Arena { ): boolean { const existingTag = this.getTagOnSide(tagType, side); if (existingTag) { - existingTag.onOverlap(this); + existingTag.onOverlap(this, globalScene.getPokemonById(sourceId)); if (existingTag instanceof ArenaTrapTag) { const { tagType, side, turnCount, layers, maxLayers } = existingTag as ArenaTrapTag; @@ -802,9 +825,9 @@ export class Arena { resetArenaEffects(): void { // Don't reset weather if a Biome's permanent weather is active if (this.weather?.turnsLeft !== 0) { - this.trySetWeather(WeatherType.NONE, false); + this.trySetWeather(WeatherType.NONE); } - this.trySetTerrain(TerrainType.NONE, false, true); + this.trySetTerrain(TerrainType.NONE, true); this.resetPlayerFaintCount(); this.removeAllTags(); } diff --git a/src/field/damage-number-handler.ts b/src/field/damage-number-handler.ts index 63da641a114..9e0010a0c10 100644 --- a/src/field/damage-number-handler.ts +++ b/src/field/damage-number-handler.ts @@ -46,6 +46,7 @@ export default class DamageNumberHandler { case HitResult.NOT_VERY_EFFECTIVE: [textColor, shadowColor] = ["#f08030", "#c03028"]; break; + case HitResult.INDIRECT_KO: case HitResult.ONE_HIT_KO: [textColor, shadowColor] = ["#a040a0", "#483850"]; break; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 890c6bab0d6..aba13b2e51b 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -192,6 +192,9 @@ import { applyPreLeaveFieldAbAttrs, applyOnLoseAbAttrs, PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr, + applyAllyStatMultiplierAbAttrs, + AllyStatMultiplierAbAttr, + MoveAbilityBypassAbAttr, } from "#app/data/ability"; import type PokemonData from "#app/system/pokemon-data"; import { BattlerIndex } from "#app/battle"; @@ -222,7 +225,7 @@ import { SpeciesFormChangeStatusEffectTrigger, } from "#app/data/pokemon-forms"; import { TerrainType } from "#app/data/terrain"; -import type { TrainerSlot } from "#app/data/trainer-config"; +import type { TrainerSlot } from "#enums/trainer-slot"; import Overrides from "#app/overrides"; import i18next from "i18next"; import { speciesEggMoves } from "#app/data/balance/egg-moves"; @@ -260,6 +263,7 @@ import { import { Nature } from "#enums/nature"; import { StatusEffect } from "#enums/status-effect"; import { doShinySparkleAnim } from "#app/field/anims"; +import { MoveFlags } from "#enums/MoveFlags"; export enum LearnMoveSituation { MISC, @@ -296,7 +300,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public stats: number[]; public ivs: number[]; public nature: Nature; - public moveset: (PokemonMove | null)[]; + public moveset: PokemonMove[]; public status: Status | null; public friendship: number; public metLevel: number; @@ -694,7 +698,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { loadAssets(ignoreOverride = true): Promise { return new Promise(resolve => { - const moveIds = this.getMoveset().map(m => m!.getMove().id); // TODO: is this bang correct? + const moveIds = this.getMoveset().map(m => m.getMove().id); Promise.allSettled(moveIds.map(m => initMoveAnim(m))).then(() => { loadMoveAnimAssets(moveIds); this.getSpeciesForm().loadAssets( @@ -1389,6 +1393,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param move the {@linkcode Move} being used * @param ignoreAbility determines whether this Pokemon's abilities should be ignored during the stat calculation * @param ignoreOppAbility during an attack, determines whether the opposing Pokemon's abilities should be ignored during the stat calculation. + * @param ignoreAllyAbility during an attack, determines whether the ally Pokemon's abilities should be ignored during the stat calculation. * @param isCritical determines whether a critical hit has occurred or not (`false` by default) * @param simulated if `true`, nullifies any effects that produce any changes to game state from triggering * @param ignoreHeldItems determines whether this Pokemon's held items should be ignored during the stat calculation, default `false` @@ -1400,6 +1405,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { move?: Move, ignoreAbility = false, ignoreOppAbility = false, + ignoreAllyAbility = false, isCritical = false, simulated = true, ignoreHeldItems = false, @@ -1441,6 +1447,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { ); } + const ally = this.getAlly(); + if (ally) { + applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, stat, statValue, simulated, this, move?.hasFlag(MoveFlags.IGNORE_ABILITIES) || ignoreAllyAbility); + } + let ret = statValue.value * this.getStatStageMultiplier( @@ -1751,7 +1762,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { abstract isBoss(): boolean; - getMoveset(ignoreOverride?: boolean): (PokemonMove | null)[] { + getMoveset(ignoreOverride?: boolean): PokemonMove[] { const ret = !ignoreOverride && this.summonData?.moveset ? this.summonData.moveset @@ -1826,9 +1837,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { .filter(m => !levelMoves.includes(m)) .concat(levelMoves); } - levelMoves = levelMoves.filter( - lm => !this.moveset.some(m => m?.moveId === lm), - ); + levelMoves = levelMoves.filter(lm => !this.moveset.some(m => m.moveId === lm)); return levelMoves; } @@ -2942,7 +2951,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } setMove(moveIndex: number, moveId: Moves): void { - const move = moveId ? new PokemonMove(moveId) : null; + if (moveId === Moves.NONE) { + return; + } + const move = new PokemonMove(moveId); this.moveset[moveIndex] = move; if (this.summonData?.moveset) { this.summonData.moveset[moveIndex] = move; @@ -3487,14 +3499,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // Other damaging moves 2x weight if 0-1 damaging moves, 0.5x if 2, 0.125x if 3. These weights get 20x if STAB. // Status moves remain unchanged on weight, this encourages 1-2 movePool = baseWeights - .filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)) + .filter(m => !this.moveset.some(mo => m[0] === mo.moveId)) .map(m => { let ret: number; if ( this.moveset.some( mo => - mo?.getMove().category !== MoveCategory.STATUS && - mo?.getMove().type === allMoves[m[0]].type, + mo.getMove().category !== MoveCategory.STATUS && + mo.getMove().type === allMoves[m[0]].type, ) ) { ret = Math.ceil(Math.sqrt(m[1])); @@ -3504,7 +3516,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { Math.max( Math.pow( 4, - this.moveset.filter(mo => (mo?.getMove().power ?? 0) > 1) + this.moveset.filter(mo => (mo.getMove().power ?? 0) > 1) .length, ) / 8, 0.5, @@ -3518,9 +3530,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { }); } else { // Non-trainer pokemon just use normal weights - movePool = baseWeights.filter( - m => !this.moveset.some(mo => m[0] === mo?.moveId), - ); + movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo.moveId)); } const totalWeight = movePool.reduce((v, m) => v + m[1], 0); let rand = Utils.randSeedInt(totalWeight); @@ -3890,6 +3900,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { evasionMultiplier, ); + const ally = this.getAlly(); + if (ally) { + const ignore = this.hasAbilityWithAttr(MoveAbilityBypassAbAttr) || sourceMove.hasFlag(MoveFlags.IGNORE_ABILITIES); + applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, Stat.ACC, accuracyMultiplier, false, this, ignore); + applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, Stat.EVA, evasionMultiplier, false, this, ignore); + } + return accuracyMultiplier.value / evasionMultiplier.value; } @@ -3901,6 +3918,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param moveCategory the move's {@linkcode MoveCategory} after variable-category effects are applied. * @param ignoreAbility if `true`, ignores this Pokemon's defensive ability effects (defaults to `false`). * @param ignoreSourceAbility if `true`, ignore's the attacking Pokemon's ability effects (defaults to `false`). + * @param ignoreAllyAbility if `true`, ignores the ally Pokemon's ability effects (defaults to `false`). + * @param ignoreSourceAllyAbility if `true`, ignores the attacking Pokemon's ally's ability effects (defaults to `false`). * @param isCritical if `true`, calculates effective stats as if the hit were critical (defaults to `false`). * @param simulated if `true`, suppresses changes to game state during calculation (defaults to `true`). * @returns The move's base damage against this Pokemon when used by the source Pokemon. @@ -3911,6 +3930,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { moveCategory: MoveCategory, ignoreAbility = false, ignoreSourceAbility = false, + ignoreAllyAbility = false, + ignoreSourceAllyAbility = false, isCritical = false, simulated = true, ): number { @@ -3933,6 +3954,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { undefined, ignoreSourceAbility, ignoreAbility, + ignoreAllyAbility, isCritical, simulated, ), @@ -3950,6 +3972,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { move, ignoreAbility, ignoreSourceAbility, + ignoreSourceAllyAbility, isCritical, simulated, ), @@ -3984,6 +4007,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param move {@linkcode Pokemon} the move used in the attack * @param ignoreAbility If `true`, ignores this Pokemon's defensive ability effects * @param ignoreSourceAbility If `true`, ignores the attacking Pokemon's ability effects + * @param ignoreAllyAbility If `true`, ignores the ally Pokemon's ability effects + * @param ignoreSourceAllyAbility If `true`, ignores the ability effects of the attacking pokemon's ally * @param isCritical If `true`, calculates damage for a critical hit. * @param simulated If `true`, suppresses changes to game state during the calculation. * @returns a {@linkcode DamageCalculationResult} object with three fields: @@ -3996,6 +4021,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { move: Move, ignoreAbility = false, ignoreSourceAbility = false, + ignoreAllyAbility = false, + ignoreSourceAllyAbility = false, isCritical = false, simulated = true, ): DamageCalculationResult { @@ -4105,6 +4132,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { moveCategory, ignoreAbility, ignoreSourceAbility, + ignoreAllyAbility, + ignoreSourceAllyAbility, isCritical, simulated, ); @@ -4430,7 +4459,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { cancelled, result, damage: dmg, - } = this.getAttackDamage(source, move, false, false, isCritical, false); + } = this.getAttackDamage(source, move, false, false, false, false, isCritical, false); const typeBoost = source.findTag( t => @@ -4465,11 +4494,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return result; } - // In case of fatal damage, this tag would have gotten cleared before we could lapse it. - const destinyTag = this.getTag(BattlerTagType.DESTINY_BOND); - const grudgeTag = this.getTag(BattlerTagType.GRUDGE); - - const isOneHitKo = result === HitResult.ONE_HIT_KO; + // In case of fatal damage, this tag would have gotten cleared before we could lapse it. + const destinyTag = this.getTag(BattlerTagType.DESTINY_BOND); + const grudgeTag = this.getTag(BattlerTagType.GRUDGE); if (dmg) { this.lapseTags(BattlerTagLapseType.HIT); @@ -4484,19 +4511,17 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { globalScene.applyModifiers(EnemyEndureChanceModifier, false, this); } - /** - * We explicitly require to ignore the faint phase here, as we want to show the messages - * about the critical hit and the super effective/not very effective messages before the faint phase. - */ - const damage = this.damageAndUpdate( - isBlockedBySubstitute ? 0 : dmg, - result as DamageResult, - isCritical, - isOneHitKo, - isOneHitKo, - true, - source, - ); + /** + * We explicitly require to ignore the faint phase here, as we want to show the messages + * about the critical hit and the super effective/not very effective messages before the faint phase. + */ + const damage = this.damageAndUpdate(isBlockedBySubstitute ? 0 : dmg, + { + result: result as DamageResult, + isCritical, + ignoreFaintPhase: true, + source + }); if (damage > 0) { if (source.isPlayer()) { @@ -4557,7 +4582,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { globalScene.unshiftPhase( new FaintPhase( this.getBattlerIndex(), - isOneHitKo, + false, destinyTag, grudgeTag, source, @@ -4635,28 +4660,37 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** * Called by apply(), given the damage, adds a new DamagePhase and actually updates HP values, etc. + * Checks for 'Indirect' HitResults to account for Endure/Reviver Seed applying correctly * @param damage integer - passed to damage() * @param result an enum if it's super effective, not very, etc. - * @param critical boolean if move is a critical hit + * @param isCritical boolean if move is a critical hit * @param ignoreSegments boolean, passed to damage() and not used currently * @param preventEndure boolean, ignore endure properties of pokemon, passed to damage() * @param ignoreFaintPhase boolean to ignore adding a FaintPhase, passsed to damage() * @returns integer of damage done */ - damageAndUpdate( - damage: number, - result?: DamageResult, - critical = false, - ignoreSegments = false, - preventEndure = false, - ignoreFaintPhase = false, - source?: Pokemon, + damageAndUpdate(damage: number, + { + result = HitResult.EFFECTIVE, + isCritical = false, + ignoreSegments = false, + ignoreFaintPhase = false, + source = undefined, + }: + { + result?: DamageResult, + isCritical?: boolean, + ignoreSegments?: boolean, + ignoreFaintPhase?: boolean, + source?: Pokemon, + } = {} ): number { + const isIndirectDamage = [ HitResult.INDIRECT, HitResult.INDIRECT_KO ].includes(result); const damagePhase = new DamageAnimPhase( - this.getBattlerIndex(), - damage, - result as DamageResult, - critical, + this.getBattlerIndex(), + damage, + result as DamageResult, + isCritical ); globalScene.unshiftPhase(damagePhase); if (this.switchOutStatus && source) { @@ -4665,7 +4699,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { damage = this.damage( damage, ignoreSegments, - preventEndure, + isIndirectDamage, ignoreFaintPhase, ); // Damage amount may have changed, but needed to be queued before calling damage function @@ -5575,7 +5609,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } this.resetBattleSummonData(); if (this.summonDataPrimer) { - for (const k of Object.keys(this.summonData)) { + for (const k of Object.keys(this.summonDataPrimer)) { if (this.summonDataPrimer[k]) { this.summonData[k] = this.summonDataPrimer[k]; } @@ -6847,18 +6881,7 @@ export class PlayerPokemon extends Pokemon { copyMoveset(): PokemonMove[] { const newMoveset: PokemonMove[] = []; 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, - ), - ); - } + newMoveset.push(new PokemonMove(move.moveId, 0, move.ppUp, move.virtual, move.maxPpOverride)); }); return newMoveset; @@ -7045,17 +7068,8 @@ export class EnemyPokemon extends Pokemon { if (moveQueue.length !== 0) { const queuedMove = moveQueue[0]; if (queuedMove) { - const moveIndex = this.getMoveset().findIndex( - m => m?.moveId === queuedMove.move, - ); - if ( - (moveIndex > -1 && - this.getMoveset()[moveIndex]!.isUsable( - this, - queuedMove.ignorePP, - )) || - queuedMove.virtual - ) { + const moveIndex = this.getMoveset().findIndex(m => m.moveId === queuedMove.move); + if ((moveIndex > -1 && this.getMoveset()[moveIndex].isUsable(this, queuedMove.ignorePP)) || queuedMove.virtual) { return queuedMove; } else { this.getMoveQueue().shift(); @@ -7065,20 +7079,17 @@ export class EnemyPokemon extends Pokemon { } // Filter out any moves this Pokemon cannot use - let movePool = this.getMoveset().filter(m => m?.isUsable(this)); + let movePool = this.getMoveset().filter(m => m.isUsable(this)); // If no moves are left, use Struggle. Otherwise, continue with move selection if (movePool.length) { // If there's only 1 move in the move pool, use it. if (movePool.length === 1) { - return { - move: movePool[0]!.moveId, - targets: this.getNextTargets(movePool[0]!.moveId), - }; // TODO: are the bangs correct? + return { move: movePool[0].moveId, targets: this.getNextTargets(movePool[0].moveId) }; } // If a move is forced because of Encore, use it. const encoreTag = this.getTag(EncoreTag) as EncoreTag; if (encoreTag) { - const encoreMove = movePool.find(m => m?.moveId === encoreTag.moveId); + const encoreMove = movePool.find(m => m.moveId === encoreTag.moveId); if (encoreMove) { return { move: encoreMove.moveId, @@ -7088,8 +7099,7 @@ export class EnemyPokemon extends Pokemon { } switch (this.aiType) { case AiType.RANDOM: // No enemy should spawn with this AI type in-game - const moveId = - movePool[globalScene.randBattleSeedInt(movePool.length)]!.moveId; // TODO: is the bang correct? + const moveId = movePool[globalScene.randBattleSeedInt(movePool.length)].moveId; return { move: moveId, targets: this.getNextTargets(moveId) }; case AiType.SMART_RANDOM: case AiType.SMART: @@ -7134,6 +7144,8 @@ export class EnemyPokemon extends Pokemon { move, !p.battleData.abilityRevealed, false, + !p.getAlly()?.battleData.abilityRevealed, + false, isCritical, ).damage >= p.hp ); @@ -7151,11 +7163,9 @@ export class EnemyPokemon extends Pokemon { * 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? + const moveTargets = Object.fromEntries(movePool.map(m => [ m.moveId, this.getNextTargets(m.moveId) ])); for (const m in movePool) { - const pokemonMove = movePool[m]!; // TODO: is the bang correct? + const pokemonMove = movePool[m]; const move = pokemonMove.getMove(); let moveScore = moveScores[m]; @@ -7264,16 +7274,8 @@ export class EnemyPokemon extends Pokemon { 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())); + return { move: sortedMovePool[r]!.moveId, targets: moveTargets[sortedMovePool[r]!.moveId] }; } } @@ -7632,7 +7634,7 @@ export class PokemonSummonData { public gender: Gender; public fusionGender: Gender; public stats: number[] = [0, 0, 0, 0, 0, 0]; - public moveset: (PokemonMove | null)[]; + public moveset: PokemonMove[]; // If not initialized this value will not be populated from save data. public types: PokemonType[] = []; public addedType: PokemonType | null = null; @@ -7711,8 +7713,10 @@ export enum HitResult { HEAL, FAIL, MISS, - OTHER, + INDIRECT, IMMUNE, + CONFUSION, + INDIRECT_KO, } export type DamageResult = @@ -7720,7 +7724,9 @@ export type DamageResult = | HitResult.SUPER_EFFECTIVE | HitResult.NOT_VERY_EFFECTIVE | HitResult.ONE_HIT_KO - | HitResult.OTHER; + | HitResult.CONFUSION + | HitResult.INDIRECT_KO + | HitResult.INDIRECT; /** Interface containing the results of a damage calculation for a given move */ export interface DamageCalculationResult { diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 98919ebfa93..c52957eef75 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -2,19 +2,17 @@ import { globalScene } from "#app/global-scene"; import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; import type PokemonSpecies from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species"; -import type { TrainerConfig, TrainerPartyTemplate } from "#app/data/trainer-config"; -import { - TrainerPartyCompoundTemplate, - TrainerPoolTier, - TrainerSlot, - trainerConfigs, - trainerPartyTemplates, - TeraAIMode, -} from "#app/data/trainer-config"; +import type { TrainerConfig } from "#app/data/trainers/trainer-config"; +import type { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; +import { trainerPartyTemplates } from "#app/data/trainers/TrainerPartyTemplate"; +import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate"; +import { TrainerSlot } from "#enums/trainer-slot"; +import { TrainerPoolTier } from "#enums/trainer-pool-tier"; +import { TeraAIMode } from "#enums/tera-ai-mode"; import type { EnemyPokemon } from "#app/field/pokemon"; import * as Utils from "#app/utils"; import type { PersistentModifier } from "#app/modifier/modifier"; -import { trainerNamePools } from "#app/data/trainer-names"; import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag"; import { getIsInitialized, initI18n } from "#app/plugins/i18n"; import i18next from "i18next"; @@ -61,11 +59,17 @@ export default class Trainer extends Phaser.GameObjects.Container { : Utils.randSeedWeightedItem(this.config.partyTemplates.map((_, i) => i)), this.config.partyTemplates.length - 1, ); - if (trainerNamePools.hasOwnProperty(trainerType)) { - const namePool = trainerNamePools[trainerType]; + if (i18next.exists("trainersCommon:" + TrainerType[trainerType], { returnObjects: true })) { + const namePool = i18next.t("trainersCommon:" + TrainerType[trainerType], { returnObjects: true }); this.name = name || - Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[variant === TrainerVariant.FEMALE ? 1 : 0] : namePool); + Utils.randSeedItem( + Object.values( + namePool.hasOwnProperty("MALE") + ? namePool[variant === TrainerVariant.FEMALE ? "FEMALE" : "MALE"] + : namePool, + ), + ); if (variant === TrainerVariant.DOUBLE) { if (this.config.doubleOnly) { if (partnerName) { @@ -74,7 +78,9 @@ export default class Trainer extends Phaser.GameObjects.Container { [this.name, this.partnerName] = this.name.split(" & "); } } else { - this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool); + this.partnerName = + partnerName || + Utils.randSeedItem(Object.values(namePool.hasOwnProperty("FEMALE") ? namePool["FEMALE"] : namePool)); } } } diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 295dc318db4..7f05634db48 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -250,7 +250,7 @@ export class LoadingScene extends SceneBase { this.loadAtlas("statuses", ""); this.loadAtlas("types", ""); } - const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"]; + const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN", "zh-TW", "ca-ES"]; if (lang && availableLangs.includes(lang)) { this.loadImage(`pkmnday2025event-${lang}`, "events"); } else { diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 3d2e67b0dc3..f9770e9c6cc 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -97,6 +97,7 @@ import { type PersistentModifier, TempExtraModifierModifier, CriticalCatchChanceBoosterModifier, + FieldEffectModifier, } from "#app/modifier/modifier"; import { ModifierTier } from "#app/modifier/modifier-tier"; import Overrides from "#app/overrides"; @@ -627,7 +628,7 @@ export class PokemonAllMovePpRestoreModifierType extends PokemonModifierType { iconImage, (_type, args) => new PokemonAllMovePpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints), (pokemon: PlayerPokemon) => { - if (!pokemon.getMoveset().filter(m => m?.ppUsed).length) { + if (!pokemon.getMoveset().filter(m => m.ppUsed).length) { return PartyUiHandler.NoEffectMessage; } return null; @@ -1170,7 +1171,7 @@ export class TmModifierType extends PokemonModifierType { (pokemon: PlayerPokemon) => { if ( pokemon.compatibleTms.indexOf(moveId) === -1 || - pokemon.getMoveset().filter(m => m?.moveId === moveId).length + pokemon.getMoveset().filter(m => m.moveId === moveId).length ) { return PartyUiHandler.NoEffectMessage; } @@ -1333,7 +1334,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator { const attackMoveTypes = party.flatMap(p => p .getMoveset() - .map(m => m?.getMove()) + .map(m => m.getMove()) .filter(m => m instanceof AttackMove) .map(m => m.type), ); @@ -1468,7 +1469,7 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator { const speciesId = p.getSpeciesForm(true).speciesId; const fusionSpeciesId = p.isFusion() ? p.getFusionSpeciesForm(true).speciesId : null; // TODO: Use commented boolean when Fling is implemented - const hasFling = false; /* p.getMoveset(true).some(m => m?.moveId === Moves.FLING) */ + const hasFling = false; /* p.getMoveset(true).some(m => m.moveId === Moves.FLING) */ for (const i in values) { const checkedSpecies = values[i].species; @@ -1529,7 +1530,7 @@ class TmModifierTypeGenerator extends ModifierTypeGenerator { const partyMemberCompatibleTms = party.map(p => { const previousLevelMoves = p.getLearnableLevelMoves(); return (p as PlayerPokemon).compatibleTms.filter( - tm => !p.moveset.find(m => m?.moveId === tm) && !previousLevelMoves.find(lm => lm === tm), + tm => !p.moveset.find(m => m.moveId === tm) && !previousLevelMoves.find(lm => lm === tm), ); }); const tierUniqueCompatibleTms = partyMemberCompatibleTms @@ -1998,6 +1999,13 @@ export const modifierTypes = { return new PokemonNatureChangeModifierType(randSeedInt(getEnumValues(Nature).length) as Nature); }), + MYSTICAL_ROCK: () => + new PokemonHeldItemModifierType( + "modifierType:ModifierType.MYSTICAL_ROCK", + "mystical_rock", + (type, args) => new FieldEffectModifier(type, (args[0] as Pokemon).id), + ), + TERA_SHARD: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in PokemonType) { @@ -2433,7 +2441,7 @@ const modifierPool: ModifierPool = { !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA) && p .getMoveset() - .filter(m => m?.ppUsed && m.getMovePp() - m.ppUsed <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)) + .filter(m => m.ppUsed && m.getMovePp() - m.ppUsed <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)) .length, ).length, 3, @@ -2452,7 +2460,7 @@ const modifierPool: ModifierPool = { !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA) && p .getMoveset() - .filter(m => m?.ppUsed && m.getMovePp() - m.ppUsed <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)) + .filter(m => m.ppUsed && m.getMovePp() - m.ppUsed <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)) .length, ).length, 3, @@ -2574,7 +2582,7 @@ const modifierPool: ModifierPool = { !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA) && p .getMoveset() - .filter(m => m?.ppUsed && m.getMovePp() - m.ppUsed <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)) + .filter(m => m.ppUsed && m.getMovePp() - m.ppUsed <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)) .length, ).length, 3, @@ -2593,7 +2601,7 @@ const modifierPool: ModifierPool = { !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA) && p .getMoveset() - .filter(m => m?.ppUsed && m.getMovePp() - m.ppUsed <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)) + .filter(m => m.ppUsed && m.getMovePp() - m.ppUsed <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)) .length, ).length, 3, @@ -2810,6 +2818,47 @@ const modifierPool: ModifierPool = { }, 10, ), + new WeightedModifierType( + modifierTypes.MYSTICAL_ROCK, + (party: Pokemon[]) => { + return party.some(p => { + const moveset = p.getMoveset(true).map(m => m.moveId); + + const hasAbility = [ + Abilities.DRIZZLE, + Abilities.ORICHALCUM_PULSE, + Abilities.DRIZZLE, + Abilities.SAND_STREAM, + Abilities.SAND_SPIT, + Abilities.SNOW_WARNING, + Abilities.ELECTRIC_SURGE, + Abilities.HADRON_ENGINE, + Abilities.PSYCHIC_SURGE, + Abilities.GRASSY_SURGE, + Abilities.SEED_SOWER, + Abilities.MISTY_SURGE, + ].some(a => p.hasAbility(a, false, true)); + + const hasMoves = [ + Moves.SUNNY_DAY, + Moves.RAIN_DANCE, + Moves.SANDSTORM, + Moves.SNOWSCAPE, + Moves.HAIL, + Moves.CHILLY_RECEPTION, + Moves.ELECTRIC_TERRAIN, + Moves.PSYCHIC_TERRAIN, + Moves.GRASSY_TERRAIN, + Moves.MISTY_TERRAIN, + ].some(m => moveset.includes(m)); + + return hasAbility || hasMoves; + }) + ? 10 + : 0; + }, + 10, + ), new WeightedModifierType(modifierTypes.REVIVER_SEED, 4), new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)), new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9), diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index a084474ddac..7c9207bbea5 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -5,8 +5,7 @@ import { allMoves } from "#app/data/moves/move"; import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball"; import { type FormChangeItem, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms"; import { getStatusEffectHealText } from "#app/data/status-effect"; -import type { PlayerPokemon } from "#app/field/pokemon"; -import Pokemon from "#app/field/pokemon"; +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"; @@ -2015,6 +2014,38 @@ export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier { } } +/** + * Modifier used for held items, namely Mystical Rock, that extend the + * duration of weather and terrain effects. + * @extends PokemonHeldItemModifier + * @see {@linkcode apply} + */ +export class FieldEffectModifier extends PokemonHeldItemModifier { + /** + * Provides two more turns per stack to any weather or terrain effect caused + * by the holder. + * @param pokemon {@linkcode Pokemon} that holds the held item + * @param fieldDuration {@linkcode NumberHolder} that stores the current field effect duration + * @returns `true` if the field effect extension was applied successfully + */ + override apply(_pokemon: Pokemon, fieldDuration: NumberHolder): boolean { + fieldDuration.value += 2 * this.stackCount; + return true; + } + + override matchType(modifier: Modifier): boolean { + return modifier instanceof FieldEffectModifier; + } + + override clone(): FieldEffectModifier { + return new FieldEffectModifier(this.type, this.pokemonId, this.stackCount); + } + + override getMaxHeldItemCount(_pokemon?: Pokemon): number { + return 2; + } +} + export abstract class ConsumablePokemonModifier extends ConsumableModifier { public pokemonId: number; diff --git a/src/overrides.ts b/src/overrides.ts index 882a634ff90..3a9a54e740b 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -254,6 +254,11 @@ class DefaultOverrides { * Note that, for all items in the array, `count` is not used. */ readonly ITEM_REWARD_OVERRIDE: ModifierOverride[] = []; + + /** + * If `true`, disable all non-scripted opponent trainer encounters. + */ + readonly DISABLE_STANDARD_TRAINERS_OVERRIDE: boolean = false; } export const defaultOverrides = new DefaultOverrides(); diff --git a/src/phases/attempt-capture-phase.ts b/src/phases/attempt-capture-phase.ts index 6b905c2a07f..6e2a2d29af4 100644 --- a/src/phases/attempt-capture-phase.ts +++ b/src/phases/attempt-capture-phase.ts @@ -24,6 +24,7 @@ import type { PokeballType } from "#enums/pokeball"; import { StatusEffect } from "#enums/status-effect"; import i18next from "i18next"; import { globalScene } from "#app/global-scene"; +import { Gender } from "#app/data/gender"; export class AttemptCapturePhase extends PokemonPhase { private pokeballType: PokeballType; @@ -321,6 +322,26 @@ export class AttemptCapturePhase extends PokemonPhase { false, ); }, + () => { + const attributes = { + shiny: pokemon.shiny, + variant: pokemon.variant, + form: pokemon.formIndex, + female: pokemon.gender === Gender.FEMALE, + }; + globalScene.ui.setOverlayMode( + Mode.POKEDEX_PAGE, + pokemon.species, + pokemon.formIndex, + attributes, + null, + () => { + globalScene.ui.setMode(Mode.MESSAGE).then(() => { + promptRelease(); + }); + }, + ); + }, () => { globalScene.ui.setMode( Mode.PARTY, diff --git a/src/phases/attempt-run-phase.ts b/src/phases/attempt-run-phase.ts index c9c0e23dabb..dab5b8789da 100644 --- a/src/phases/attempt-run-phase.ts +++ b/src/phases/attempt-run-phase.ts @@ -1,4 +1,4 @@ -import { applyAbAttrs, RunSuccessAbAttr } from "#app/data/ability"; +import { applyAbAttrs, applyPreLeaveFieldAbAttrs, PreLeaveFieldAbAttr, RunSuccessAbAttr } from "#app/data/ability"; import { Stat } from "#app/enums/stat"; import { StatusEffect } from "#app/enums/status-effect"; import type { PlayerPokemon, EnemyPokemon } from "#app/field/pokemon"; @@ -29,6 +29,8 @@ export class AttemptRunPhase extends PokemonPhase { applyAbAttrs(RunSuccessAbAttr, playerPokemon, null, false, escapeChance); if (playerPokemon.randSeedInt(100) < escapeChance.value && !this.forceFailEscape) { + enemyField.forEach(enemyPokemon => applyPreLeaveFieldAbAttrs(PreLeaveFieldAbAttr, enemyPokemon)); + globalScene.playSound("se/flee"); globalScene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500); diff --git a/src/phases/battle-phase.ts b/src/phases/battle-phase.ts index 3fc2b9c0467..72bcc85bc62 100644 --- a/src/phases/battle-phase.ts +++ b/src/phases/battle-phase.ts @@ -1,5 +1,5 @@ import { globalScene } from "#app/global-scene"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { Phase } from "#app/phase"; export class BattlePhase extends Phase { diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 055d52e7a8b..8691ac453ca 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -104,15 +104,14 @@ export class CommandPhase extends FieldPhase { moveQueue[0] && moveQueue[0].move && !moveQueue[0].virtual && - (!playerPokemon.getMoveset().find(m => m?.moveId === moveQueue[0].move) || + (!playerPokemon.getMoveset().find(m => m.moveId === moveQueue[0].move) || !playerPokemon .getMoveset() - [playerPokemon.getMoveset().findIndex(m => m?.moveId === moveQueue[0].move)]!.isUsable( + [playerPokemon.getMoveset().findIndex(m => m.moveId === moveQueue[0].move)].isUsable( playerPokemon, moveQueue[0].ignorePP, )) ) { - // TODO: is the bang correct? moveQueue.shift(); } @@ -121,12 +120,11 @@ export class CommandPhase extends FieldPhase { if (!queuedMove.move) { this.handleCommand(Command.FIGHT, -1); } else { - const moveIndex = playerPokemon.getMoveset().findIndex(m => m?.moveId === queuedMove.move); + const moveIndex = playerPokemon.getMoveset().findIndex(m => m.moveId === queuedMove.move); if ( - (moveIndex > -1 && playerPokemon.getMoveset()[moveIndex]!.isUsable(playerPokemon, queuedMove.ignorePP)) || + (moveIndex > -1 && playerPokemon.getMoveset()[moveIndex].isUsable(playerPokemon, queuedMove.ignorePP)) || queuedMove.virtual ) { - // TODO: is the bang correct? this.handleCommand(Command.FIGHT, moveIndex, queuedMove.ignorePP, queuedMove); } else { globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex); @@ -157,7 +155,7 @@ export class CommandPhase extends FieldPhase { if ( cursor === -1 || playerPokemon.trySelectMove(cursor, args[0] as boolean) || - (useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m?.isUsable(playerPokemon)).length) + (useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length) ) { let moveId: Moves; if (useStruggle) { @@ -165,7 +163,7 @@ export class CommandPhase extends FieldPhase { } else if (turnMove !== undefined) { moveId = turnMove.move; } else if (cursor > -1) { - moveId = playerPokemon.getMoveset()[cursor]!.moveId; + moveId = playerPokemon.getMoveset()[cursor].moveId; } else { moveId = Moves.NONE; } @@ -195,10 +193,14 @@ export class CommandPhase extends FieldPhase { if (moveTargets.targets.length > 1 && moveTargets.multiple) { globalScene.unshiftPhase(new SelectTargetPhase(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) { - turnCommand.move!.targets = playerPokemon.getMoveQueue()[0].targets; //TODO: is the bang correct here? + if (turnCommand.move && (moveTargets.targets.length <= 1 || moveTargets.multiple)) { + turnCommand.move.targets = moveTargets.targets; + } else if ( + turnCommand.move && + playerPokemon.getTag(BattlerTagType.CHARGING) && + playerPokemon.getMoveQueue().length >= 1 + ) { + turnCommand.move.targets = playerPokemon.getMoveQueue()[0].targets; } else { globalScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex)); } @@ -206,7 +208,7 @@ export class CommandPhase extends FieldPhase { globalScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand; success = true; } else if (cursor < playerPokemon.getMoveset().length) { - const move = playerPokemon.getMoveset()[cursor]!; //TODO: is this bang correct? + const move = playerPokemon.getMoveset()[cursor]; globalScene.ui.setMode(Mode.MESSAGE); // Decides between a Disabled, Not Implemented, or No PP translation message diff --git a/src/phases/damage-anim-phase.ts b/src/phases/damage-anim-phase.ts index e31fe8c9475..703cd3d160e 100644 --- a/src/phases/damage-anim-phase.ts +++ b/src/phases/damage-anim-phase.ts @@ -21,7 +21,7 @@ export class DamageAnimPhase extends PokemonPhase { start() { super.start(); - if (this.damageResult === HitResult.ONE_HIT_KO) { + if (this.damageResult === HitResult.ONE_HIT_KO || this.damageResult === HitResult.INDIRECT_KO) { if (globalScene.moveAnimations) { globalScene.toggleInvert(true); } @@ -42,9 +42,11 @@ export class DamageAnimPhase extends PokemonPhase { applyDamage() { switch (this.damageResult) { case HitResult.EFFECTIVE: + case HitResult.CONFUSION: globalScene.playSound("se/hit"); break; case HitResult.SUPER_EFFECTIVE: + case HitResult.INDIRECT_KO: case HitResult.ONE_HIT_KO: globalScene.playSound("se/hit_strong"); break; @@ -57,7 +59,7 @@ export class DamageAnimPhase extends PokemonPhase { globalScene.damageNumberHandler.add(this.getPokemon(), this.amount, this.damageResult, this.critical); } - if (this.damageResult !== HitResult.OTHER && this.amount > 0) { + if (this.damageResult !== HitResult.INDIRECT && this.amount > 0) { const flashTimer = globalScene.time.addEvent({ delay: 100, repeat: 5, diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 5decab522b5..ad2bf689e38 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -7,7 +7,7 @@ import { getCharVariantFromDialogue } from "#app/data/dialogue"; import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { doTrainerExclamation } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { getGoldenBugNetSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { getRandomWeatherType } from "#app/data/weather"; import { EncounterPhaseEvent } from "#app/events/battle-scene"; import type Pokemon from "#app/field/pokemon"; @@ -684,7 +684,7 @@ export class EncounterPhase extends BattlePhase { */ trySetWeatherIfNewBiome(): void { if (!this.loaded) { - globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena), false); + globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena)); } } } diff --git a/src/phases/faint-phase.ts b/src/phases/faint-phase.ts index 7fc7a517853..dfc0e0653a5 100644 --- a/src/phases/faint-phase.ts +++ b/src/phases/faint-phase.ts @@ -258,7 +258,7 @@ export class FaintPhase extends PokemonPhase { } else { // Final boss' HP threshold has been bypassed; cancel faint and force check for 2nd phase enemy.hp++; - globalScene.unshiftPhase(new DamageAnimPhase(enemy.getBattlerIndex(), 0, HitResult.OTHER)); + globalScene.unshiftPhase(new DamageAnimPhase(enemy.getBattlerIndex(), 0, HitResult.INDIRECT)); this.end(); } return true; diff --git a/src/phases/game-over-modifier-reward-phase.ts b/src/phases/game-over-modifier-reward-phase.ts index f3f2aebd67d..d0a39a4031a 100644 --- a/src/phases/game-over-modifier-reward-phase.ts +++ b/src/phases/game-over-modifier-reward-phase.ts @@ -1,5 +1,4 @@ import { globalScene } from "#app/global-scene"; -import type { ModifierTypeFunc } from "#app/modifier/modifier-type"; import { Mode } from "#app/ui/ui"; import i18next from "i18next"; import { ModifierRewardPhase } from "./modifier-reward-phase"; diff --git a/src/phases/game-over-phase.ts b/src/phases/game-over-phase.ts index af948ad0632..2090592367d 100644 --- a/src/phases/game-over-phase.ts +++ b/src/phases/game-over-phase.ts @@ -5,7 +5,7 @@ import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { getCharVariantFromDialogue } from "#app/data/dialogue"; import type PokemonSpecies from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species"; -import { trainerConfigs } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; import type Pokemon from "#app/field/pokemon"; import { modifierTypes } from "#app/modifier/modifier-type"; import { BattlePhase } from "#app/phases/battle-phase"; diff --git a/src/phases/learn-move-phase.ts b/src/phases/learn-move-phase.ts index 7bed71b3363..4107a9cf087 100644 --- a/src/phases/learn-move-phase.ts +++ b/src/phases/learn-move-phase.ts @@ -49,7 +49,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { const currentMoveset = pokemon.getMoveset(); // The game first checks if the Pokemon already has the move and ends the phase if it does. - const hasMoveAlready = currentMoveset.some(m => m?.moveId === move.id) && this.moveId !== Moves.SKETCH; + const hasMoveAlready = currentMoveset.some(m => m.moveId === move.id) && this.moveId !== Moves.SKETCH; if (hasMoveAlready) { return this.end(); } diff --git a/src/phases/message-phase.ts b/src/phases/message-phase.ts index f671307d86a..cff7249fcfa 100644 --- a/src/phases/message-phase.ts +++ b/src/phases/message-phase.ts @@ -28,17 +28,28 @@ export class MessagePhase extends Phase { super.start(); if (this.text.indexOf("$") > -1) { + const pokename: string[] = []; + const repname = ["#POKEMON1", "#POKEMON2"]; + for (let p = 0; p < globalScene.getPlayerField().length; p++) { + pokename.push(globalScene.getPlayerField()[p].getNameToRender()); + this.text = this.text.split(pokename[p]).join(repname[p]); + } const pageIndex = this.text.indexOf("$"); - globalScene.unshiftPhase( - new MessagePhase( - this.text.slice(pageIndex + 1), - this.callbackDelay, - this.prompt, - this.promptDelay, - this.speaker, - ), - ); - this.text = this.text.slice(0, pageIndex).trim(); + for (let p = 0; p < globalScene.getPlayerField().length; p++) { + this.text = this.text.split(repname[p]).join(pokename[p]); + } + if (pageIndex !== -1) { + globalScene.unshiftPhase( + new MessagePhase( + this.text.slice(pageIndex + 1), + this.callbackDelay, + this.prompt, + this.promptDelay, + this.speaker, + ), + ); + this.text = this.text.slice(0, pageIndex).trim(); + } } if (this.speaker) { diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index ad1b2dcffff..22c2a4c8c64 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -652,7 +652,7 @@ export class MoveEffectPhase extends PokemonPhase { this.applyOnHitEffects(user, target, firstHit, lastHit, firstTarget); this.applyOnGetHitAbEffects(user, target, hitResult); applyPostAttackAbAttrs(PostAttackAbAttr, user, target, this.move.getMove(), hitResult); - if (this.move.getMove() instanceof AttackMove) { + if (this.move.getMove() instanceof AttackMove && hitResult !== HitResult.STATUS) { globalScene.applyModifiers(ContactHeldItemTransferChanceModifier, this.player, user, target); } } diff --git a/src/phases/move-end-phase.ts b/src/phases/move-end-phase.ts index 4716370cc4e..46e266a32b7 100644 --- a/src/phases/move-end-phase.ts +++ b/src/phases/move-end-phase.ts @@ -1,5 +1,4 @@ import { globalScene } from "#app/global-scene"; -import type { BattlerIndex } from "#app/battle"; import { BattlerTagLapseType } from "#app/data/battler-tags"; import { PokemonPhase } from "./pokemon-phase"; diff --git a/src/phases/mystery-encounter-phases.ts b/src/phases/mystery-encounter-phases.ts index 26012df191d..eb187617e69 100644 --- a/src/phases/mystery-encounter-phases.ts +++ b/src/phases/mystery-encounter-phases.ts @@ -22,7 +22,7 @@ import { globalScene } from "#app/global-scene"; import { getCharVariantFromDialogue } from "../data/dialogue"; import type { OptionSelectSettings } from "../data/mystery-encounters/utils/encounter-phase-utils"; import { transitionMysteryEncounterIntroVisuals } from "../data/mystery-encounters/utils/encounter-phase-utils"; -import { TrainerSlot } from "../data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { IvScannerModifier } from "../modifier/modifier"; import { Phase } from "../phase"; import { Mode } from "../ui/ui"; diff --git a/src/phases/new-biome-encounter-phase.ts b/src/phases/new-biome-encounter-phase.ts index ed768742aac..bb1fe54fe9f 100644 --- a/src/phases/new-biome-encounter-phase.ts +++ b/src/phases/new-biome-encounter-phase.ts @@ -45,6 +45,6 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase { * Set biome weather. */ trySetWeatherIfNewBiome(): void { - globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena), false); + globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena)); } } diff --git a/src/phases/party-heal-phase.ts b/src/phases/party-heal-phase.ts index d95400a3f48..a9b24309e24 100644 --- a/src/phases/party-heal-phase.ts +++ b/src/phases/party-heal-phase.ts @@ -23,7 +23,7 @@ export class PartyHealPhase extends BattlePhase { pokemon.hp = pokemon.getMaxHp(); pokemon.resetStatus(); for (const move of pokemon.moveset) { - move!.ppUsed = 0; // TODO: is this bang correct? + move.ppUsed = 0; } pokemon.updateInfo(true); } diff --git a/src/phases/pokemon-heal-phase.ts b/src/phases/pokemon-heal-phase.ts index ab49def5a3d..ecfe99389eb 100644 --- a/src/phases/pokemon-heal-phase.ts +++ b/src/phases/pokemon-heal-phase.ts @@ -3,7 +3,6 @@ import type { BattlerIndex } from "#app/battle"; import { CommonAnim } from "#app/data/battle-anims"; import { getStatusEffectHealText } from "#app/data/status-effect"; import { StatusEffect } from "#app/enums/status-effect"; -import type { DamageResult } from "#app/field/pokemon"; import { HitResult } from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; import { HealingBoosterModifier } from "#app/modifier/modifier"; @@ -79,7 +78,7 @@ export class PokemonHealPhase extends CommonAnimPhase { } const healAmount = new Utils.NumberHolder(Math.floor(this.hpHealed * hpRestoreMultiplier.value)); if (healAmount.value < 0) { - pokemon.damageAndUpdate(healAmount.value * -1, HitResult.HEAL as DamageResult); + pokemon.damageAndUpdate(healAmount.value * -1, { result: HitResult.INDIRECT }); healAmount.value = 0; } // Prevent healing to full if specified (in case of healing tokens so Sturdy doesn't cause a softlock) diff --git a/src/phases/post-summon-phase.ts b/src/phases/post-summon-phase.ts index a7aa9389505..45b0a0f65ce 100644 --- a/src/phases/post-summon-phase.ts +++ b/src/phases/post-summon-phase.ts @@ -1,5 +1,4 @@ import { globalScene } from "#app/global-scene"; -import type { BattlerIndex } from "#app/battle"; import { applyAbAttrs, applyPostSummonAbAttrs, CommanderAbAttr, PostSummonAbAttr } from "#app/data/ability"; import { ArenaTrapTag } from "#app/data/arena-tag"; import { StatusEffect } from "#app/enums/status-effect"; diff --git a/src/phases/summon-phase.ts b/src/phases/summon-phase.ts index 31cd2645e68..621c8c8c2a9 100644 --- a/src/phases/summon-phase.ts +++ b/src/phases/summon-phase.ts @@ -1,7 +1,7 @@ import { BattleType } from "#app/battle"; import { getPokeballAtlasKey, getPokeballTintColor } from "#app/data/pokeball"; import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { PlayerGender } from "#app/enums/player-gender"; import { addPokeballOpenParticles } from "#app/field/anims"; import type Pokemon from "#app/field/pokemon"; @@ -195,6 +195,10 @@ export class SummonPhase extends PartyMemberPokemonPhase { pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 }); pokemon.getSprite().clearTint(); pokemon.resetSummonData(); + // necessary to stay transformed during wild waves + if (pokemon.summonData?.speciesForm) { + pokemon.loadAssets(false); + } globalScene.time.delayedCall(1000, () => this.end()); }, }); diff --git a/src/phases/switch-summon-phase.ts b/src/phases/switch-summon-phase.ts index 48bcd0c4ebd..16868bf9bc0 100644 --- a/src/phases/switch-summon-phase.ts +++ b/src/phases/switch-summon-phase.ts @@ -3,7 +3,7 @@ import { applyPreSwitchOutAbAttrs, PostDamageForceSwitchAbAttr, PreSwitchOutAbAt import { allMoves, ForceSwitchOutAttr } from "#app/data/moves/move"; import { getPokeballTintColor } from "#app/data/pokeball"; import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import type Pokemon from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; import { SwitchEffectTransferModifier } from "#app/modifier/modifier"; diff --git a/src/phases/trainer-message-test-phase.ts b/src/phases/trainer-message-test-phase.ts index fa3f553cdd6..23c2c86361c 100644 --- a/src/phases/trainer-message-test-phase.ts +++ b/src/phases/trainer-message-test-phase.ts @@ -1,5 +1,5 @@ import { globalScene } from "#app/global-scene"; -import { trainerConfigs } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; import type { TrainerType } from "#app/enums/trainer-type"; import { BattlePhase } from "./battle-phase"; import { TestMessagePhase } from "./test-message-phase"; diff --git a/src/phases/trainer-victory-phase.ts b/src/phases/trainer-victory-phase.ts index 024c1e3f837..f7b2eb2bb66 100644 --- a/src/phases/trainer-victory-phase.ts +++ b/src/phases/trainer-victory-phase.ts @@ -7,7 +7,7 @@ import * as Utils from "#app/utils"; import { BattlePhase } from "./battle-phase"; import { ModifierRewardPhase } from "./modifier-reward-phase"; import { MoneyRewardPhase } from "./money-reward-phase"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { globalScene } from "#app/global-scene"; import { Biome } from "#app/enums/biome"; import { achvs } from "#app/system/achv"; diff --git a/src/phases/turn-end-phase.ts b/src/phases/turn-end-phase.ts index c55f6d69a58..836647fbfb4 100644 --- a/src/phases/turn-end-phase.ts +++ b/src/phases/turn-end-phase.ts @@ -68,12 +68,12 @@ export class TurnEndPhase extends FieldPhase { globalScene.arena.lapseTags(); if (globalScene.arena.weather && !globalScene.arena.weather.lapse()) { - globalScene.arena.trySetWeather(WeatherType.NONE, false); + globalScene.arena.trySetWeather(WeatherType.NONE); globalScene.arena.triggerWeatherBasedFormChangesToNormal(); } if (globalScene.arena.terrain && !globalScene.arena.terrain.lapse()) { - globalScene.arena.trySetTerrain(TerrainType.NONE, false); + globalScene.arena.trySetTerrain(TerrainType.NONE); } this.end(); diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index 6065a0caf6e..34dd7df3e89 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -178,7 +178,7 @@ export class TurnStartPhase extends FieldPhase { continue; } const move = - pokemon.getMoveset().find(m => m?.moveId === queuedMove.move && m?.ppUsed < m?.getMovePp()) || + pokemon.getMoveset().find(m => m.moveId === queuedMove.move && m.ppUsed < m.getMovePp()) || new PokemonMove(queuedMove.move); if (move.getMove().hasAttr(MoveHeaderAttr)) { globalScene.unshiftPhase(new MoveHeaderPhase(pokemon, move)); diff --git a/src/phases/weather-effect-phase.ts b/src/phases/weather-effect-phase.ts index 9199b7996bc..d7a1f193029 100644 --- a/src/phases/weather-effect-phase.ts +++ b/src/phases/weather-effect-phase.ts @@ -66,7 +66,7 @@ export class WeatherEffectPhase extends CommonAnimPhase { const damage = Utils.toDmgValue(pokemon.getMaxHp() / 16); globalScene.queueMessage(getWeatherDamageMessage(this.weather?.weatherType!, pokemon)!); // TODO: are those bangs correct? - pokemon.damageAndUpdate(damage, HitResult.EFFECTIVE, false, false, true); + pokemon.damageAndUpdate(damage, { result: HitResult.INDIRECT, ignoreSegments: true }); }; this.executeForAll((pokemon: Pokemon) => { diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index 92b0e15dbb9..008bd03dc9e 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -237,6 +237,7 @@ export async function initI18n(): Promise { "terrain", "titles", "trainerClasses", + "trainersCommon", "trainerNames", "tutorial", "voucher", diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 82ad2276fef..3a098a55a56 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -17,7 +17,7 @@ import { Unlockables } from "#app/system/unlockables"; import { GameModes, getGameMode } from "#app/game-mode"; import { BattleType } from "#app/battle"; import TrainerData from "#app/system/trainer-data"; -import { trainerConfigs } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; import { resetSettings, setSetting, SettingKeys } from "#app/system/settings/settings"; import { achvs } from "#app/system/achv"; import EggData from "#app/system/egg-data"; @@ -98,12 +98,13 @@ export function getDataTypeKey(dataType: GameDataType, slotId = 0): string { switch (dataType) { case GameDataType.SYSTEM: return "data"; - case GameDataType.SESSION: + case GameDataType.SESSION: { let ret = "sessionData"; if (slotId) { ret += slotId; } return ret; + } case GameDataType.SETTINGS: return "settings"; case GameDataType.TUTORIALS: @@ -201,39 +202,6 @@ export interface DexEntry { ivs: number[]; } -export const DexAttr = { - NON_SHINY: 1n, - SHINY: 2n, - MALE: 4n, - FEMALE: 8n, - DEFAULT_VARIANT: 16n, - VARIANT_2: 32n, - VARIANT_3: 64n, - DEFAULT_FORM: 128n, -}; - -export interface DexAttrProps { - shiny: boolean; - female: boolean; - variant: Variant; - formIndex: number; -} - -export const AbilityAttr = { - ABILITY_1: 1, - ABILITY_2: 2, - ABILITY_HIDDEN: 4, -}; - -export type RunHistoryData = Record; - -export interface RunEntry { - entry: SessionSaveData; - isVictory: boolean; - /*Automatically set to false at the moment - implementation TBD*/ - isFavorite: boolean; -} - export type StarterMoveset = [Moves] | [Moves, Moves] | [Moves, Moves, Moves] | [Moves, Moves, Moves, Moves]; export interface StarterFormMoveData { @@ -260,6 +228,39 @@ export interface StarterPreferences { [key: number]: StarterAttributes; } +export interface DexAttrProps { + shiny: boolean; + female: boolean; + variant: Variant; + formIndex: number; +} + +export type RunHistoryData = Record; + +export interface RunEntry { + entry: SessionSaveData; + isVictory: boolean; + /*Automatically set to false at the moment - implementation TBD*/ + isFavorite: boolean; +} + +export const DexAttr = { + NON_SHINY: 1n, + SHINY: 2n, + MALE: 4n, + FEMALE: 8n, + DEFAULT_VARIANT: 16n, + VARIANT_2: 32n, + VARIANT_3: 64n, + DEFAULT_FORM: 128n, +}; + +export const AbilityAttr = { + ABILITY_1: 1, + ABILITY_2: 2, + ABILITY_HIDDEN: 4, +}; + // the latest data saved/loaded for the Starter Preferences. Required to reduce read/writes. Initialize as "{}", since this is the default value and no data needs to be stored if present. // if they ever add private static variables, move this into StarterPrefs const StarterPrefers_DEFAULT: string = "{}"; @@ -1553,16 +1554,18 @@ export class GameData { try { dataName = GameDataType[dataType].toLowerCase(); switch (dataType) { - case GameDataType.SYSTEM: + case GameDataType.SYSTEM: { dataStr = this.convertSystemDataStr(dataStr); const systemData = this.parseSystemData(dataStr); valid = !!systemData.dexData && !!systemData.timestamp; break; - case GameDataType.SESSION: + } + case GameDataType.SESSION: { const sessionData = this.parseSessionData(dataStr); valid = !!sessionData.party && !!sessionData.enemyParty && !!sessionData.timestamp; break; - case GameDataType.RUN_HISTORY: + } + case GameDataType.RUN_HISTORY: { const data = JSON.parse(dataStr); const keys = Object.keys(data); dataName = i18next.t("menuUiHandler:RUN_HISTORY").toLowerCase(); @@ -1572,6 +1575,7 @@ export class GameData { ["isFavorite", "isVictory", "entry"].every(v => entryKeys.includes(v)) && entryKeys.length === 3; }); break; + } case GameDataType.SETTINGS: case GameDataType.TUTORIALS: valid = true; diff --git a/src/system/game-speed.ts b/src/system/game-speed.ts index e2156c03728..d9c48664f80 100644 --- a/src/system/game-speed.ts +++ b/src/system/game-speed.ts @@ -5,8 +5,8 @@ import type BattleScene from "#app/battle-scene"; import { globalScene } from "#app/global-scene"; import * as Utils from "../utils"; -type FadeIn = typeof FadeIn; -type FadeOut = typeof FadeOut; +type FadeInType = typeof FadeIn; +type FadeOutType = typeof FadeOut; export function initGameSpeed() { const thisArg = this as BattleScene; @@ -101,7 +101,7 @@ export function initGameSpeed() { const originalFadeOut = SoundFade.fadeOut; SoundFade.fadeOut = ((_scene: Phaser.Scene, sound: Phaser.Sound.BaseSound, duration: number, destroy?: boolean) => - originalFadeOut(globalScene, sound, transformValue(duration), destroy)) as FadeOut; + originalFadeOut(globalScene, sound, transformValue(duration), destroy)) as FadeOutType; const originalFadeIn = SoundFade.fadeIn; SoundFade.fadeIn = (( @@ -110,5 +110,5 @@ export function initGameSpeed() { duration: number, endVolume?: number, startVolume?: number, - ) => originalFadeIn(globalScene, sound, transformValue(duration), endVolume, startVolume)) as FadeIn; + ) => originalFadeIn(globalScene, sound, transformValue(duration), endVolume, startVolume)) as FadeInType; } diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 4e694bc1189..957d43797a1 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -3,10 +3,10 @@ import { globalScene } from "#app/global-scene"; import type { Gender } from "../data/gender"; import type { Nature } from "#enums/nature"; import type { PokeballType } from "#enums/pokeball"; -import { getPokemonSpecies } from "../data/pokemon-species"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "../data/pokemon-species"; import { Status } from "../data/status-effect"; import Pokemon, { EnemyPokemon, PokemonMove, PokemonSummonData } from "../field/pokemon"; -import { TrainerSlot } from "../data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import type { Variant } from "#app/data/variant"; import { loadBattlerTag } from "../data/battler-tags"; import type { Biome } from "#enums/biome"; @@ -34,7 +34,7 @@ export default class PokemonData { public stats: number[]; public ivs: number[]; public nature: Nature; - public moveset: (PokemonMove | null)[]; + public moveset: PokemonMove[]; public status: Status | null; public friendship: number; public metLevel: number; @@ -63,6 +63,7 @@ export default class PokemonData { public bossSegments?: number; public summonData: PokemonSummonData; + public summonDataSpeciesFormIndex: number; /** Data that can customize a Pokemon in non-standard ways from its Species */ public customPokemonData: CustomPokemonData; @@ -145,8 +146,9 @@ export default class PokemonData { this.moveset = sourcePokemon.moveset; if (!forHistory) { this.status = sourcePokemon.status; - if (this.player) { + if (this.player && sourcePokemon.summonData) { this.summonData = sourcePokemon.summonData; + this.summonDataSpeciesFormIndex = this.getSummonDataSpeciesFormIndex(); } } } else { @@ -170,6 +172,8 @@ export default class PokemonData { this.summonData.ability = source.summonData.ability; this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m)); this.summonData.types = source.summonData.types; + this.summonData.speciesForm = source.summonData.speciesForm; + this.summonDataSpeciesFormIndex = source.summonDataSpeciesFormIndex; if (source.summonData.tags) { this.summonData.tags = source.summonData.tags?.map(t => loadBattlerTag(t)); @@ -213,8 +217,28 @@ export default class PokemonData { this, ); if (this.summonData) { + // when loading from saved session, recover summonData.speciesFrom and form index species object + // used to stay transformed on reload session + if (this.summonData.speciesForm) { + this.summonData.speciesForm = getPokemonSpeciesForm( + this.summonData.speciesForm.speciesId, + this.summonDataSpeciesFormIndex, + ); + } ret.primeSummonData(this.summonData); } return ret; } + + /** + * Method to save summon data species form index + * Necessary in case the pokemon is transformed + * to reload the correct form + */ + getSummonDataSpeciesFormIndex(): number { + if (this.summonData.speciesForm) { + return this.summonData.speciesForm.formIndex; + } + return 0; + } } diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 1a7279d371c..2db72dfecda 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -948,10 +948,10 @@ export function setSetting(setting: string, value: number): boolean { label: "日本語", handler: () => changeLocaleHandler("ja"), }, - // { - // label: "Català", - // handler: () => changeLocaleHandler("ca-ES") - // }, + { + label: "Català", + handler: () => changeLocaleHandler("ca-ES"), + }, { label: i18next.t("settings:back"), handler: () => cancelHandler(), diff --git a/src/system/voucher.ts b/src/system/voucher.ts index 39294bccf13..ce10560c3e2 100644 --- a/src/system/voucher.ts +++ b/src/system/voucher.ts @@ -3,7 +3,7 @@ import { AchvTier, achvs, getAchievementDescription } from "./achv"; import type { PlayerGender } from "#enums/player-gender"; import { TrainerType } from "#enums/trainer-type"; import type { ConditionFn } from "#app/@types/common"; -import { trainerConfigs } from "#app/data/trainer-config"; +import { trainerConfigs } from "#app/data/trainers/trainer-config"; export enum VoucherType { REGULAR, diff --git a/src/ui/confirm-ui-handler.ts b/src/ui/confirm-ui-handler.ts index a8710b0ab01..eb7018051b7 100644 --- a/src/ui/confirm-ui-handler.ts +++ b/src/ui/confirm-ui-handler.ts @@ -21,11 +21,12 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler { show(args: any[]): boolean { if ( - args.length === 4 && + args.length === 5 && args[0] instanceof Function && args[1] instanceof Function && args[2] instanceof Function && - args[3] === "fullParty" + args[3] instanceof Function && + args[4] === "fullParty" ) { const config: OptionSelectConfig = { options: [ @@ -37,29 +38,36 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler { }, }, { - label: i18next.t("menu:yes"), + label: i18next.t("partyUiHandler:POKEDEX"), handler: () => { args[1](); return true; }, }, { - label: i18next.t("menu:no"), + label: i18next.t("menu:yes"), handler: () => { args[2](); return true; }, }, + { + label: i18next.t("menu:no"), + handler: () => { + args[3](); + return true; + }, + }, ], - delay: args.length >= 8 && args[7] !== null ? (args[7] as number) : 0, + delay: args.length >= 9 && args[8] !== null ? (args[8] as number) : 0, }; super.show([config]); - this.switchCheck = args.length >= 5 && args[4] !== null && (args[4] as boolean); + this.switchCheck = args.length >= 6 && args[5] !== null && (args[5] as boolean); - const xOffset = args.length >= 6 && args[5] !== null ? (args[5] as number) : 0; - const yOffset = args.length >= 7 && args[6] !== null ? (args[6] as number) : 0; + const xOffset = args.length >= 7 && args[6] !== null ? (args[6] as number) : 0; + const yOffset = args.length >= 8 && args[7] !== null ? (args[7] as number) : 0; this.optionSelectContainer.setPosition(globalScene.game.canvas.width / 6 - 1 + xOffset, -48 + yOffset); diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index a4f02e13303..9f76e85f228 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -243,7 +243,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { const hasMove = cursor < moveset.length; if (hasMove) { - const pokemonMove = moveset[cursor]!; // TODO: is the bang correct? + const pokemonMove = moveset[cursor]; const moveType = pokemon.getMoveType(pokemonMove.getMove()); const textureKey = Utils.getLocalizedSpriteKey("types"); this.typeIcon.setTexture(textureKey, PokemonType[moveType].toLowerCase()).setScale(0.8); diff --git a/src/ui/message-ui-handler.ts b/src/ui/message-ui-handler.ts index 50522152021..e927793e0ab 100644 --- a/src/ui/message-ui-handler.ts +++ b/src/ui/message-ui-handler.ts @@ -76,6 +76,12 @@ export default abstract class MessageUiHandler extends AwaitableUiHandler { const fadeMap = new Map(); const actionPattern = /@(c|d|s|f)\{(.*?)\}/; let actionMatch: RegExpExecArray | null; + const pokename: string[] = []; + const repname = ["#POKEMON1", "#POKEMON2"]; + for (let p = 0; p < globalScene.getPlayerField().length; p++) { + pokename.push(globalScene.getPlayerField()[p].getNameToRender()); + text = text.split(pokename[p]).join(repname[p]); + } while ((actionMatch = actionPattern.exec(text))) { switch (actionMatch[1]) { case "c": @@ -94,6 +100,9 @@ export default abstract class MessageUiHandler extends AwaitableUiHandler { text = text.slice(0, actionMatch.index) + text.slice(actionMatch.index + actionMatch[2].length + 4); } + for (let p = 0; p < globalScene.getPlayerField().length; p++) { + text = text.split(repname[p]).join(pokename[p]); + } if (text) { // Predetermine overflow line breaks to avoid words breaking while displaying const textWords = text.split(" "); diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 21e5f9077f4..3c04692ea31 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -478,7 +478,7 @@ export default class PartyUiHandler extends MessageUiHandler { filterResult = this.FilterChallengeLegal(pokemon); } if (filterResult === null && this.partyUiMode === PartyUiMode.MOVE_MODIFIER) { - filterResult = this.moveSelectFilter(pokemon.moveset[this.optionsCursor]!); // TODO: is this bang correct? + filterResult = this.moveSelectFilter(pokemon.moveset[this.optionsCursor]); } } else { filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)( @@ -574,9 +574,7 @@ export default class PartyUiHandler extends MessageUiHandler { form: pokemon.formIndex, female: pokemon.gender === Gender.FEMALE, }; - ui.setOverlayMode(Mode.POKEDEX_PAGE, pokemon.species, pokemon.formIndex, attributes).then(() => - this.clearOptions(), - ); + ui.setOverlayMode(Mode.POKEDEX_PAGE, pokemon.species, attributes).then(() => this.clearOptions()); return true; } else if (option === PartyOption.UNPAUSE_EVOLUTION) { this.clearOptions(); @@ -1184,7 +1182,7 @@ export default class PartyUiHandler extends MessageUiHandler { 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? + const move = pokemon.moveset[option - PartyOption.MOVE_1]; if (this.showMovePp) { const maxPP = move.getMovePp(); const currPP = maxPP - move.ppUsed; @@ -1649,7 +1647,7 @@ class PartySlot extends Phaser.GameObjects.Container { this.slotHpText.setVisible(false); let slotTmText: string; - if (this.pokemon.getMoveset().filter(m => m?.moveId === tmMoveId).length > 0) { + if (this.pokemon.getMoveset().filter(m => m.moveId === tmMoveId).length > 0) { slotTmText = i18next.t("partyUiHandler:learned"); } else if (this.pokemon.compatibleTms.indexOf(tmMoveId) === -1) { slotTmText = i18next.t("partyUiHandler:notAble"); diff --git a/src/ui/pokedex-page-ui-handler.ts b/src/ui/pokedex-page-ui-handler.ts index 74921f13683..24812f62044 100644 --- a/src/ui/pokedex-page-ui-handler.ts +++ b/src/ui/pokedex-page-ui-handler.ts @@ -20,20 +20,18 @@ import { allSpecies, getPokemonSpecies, getPokemonSpeciesForm, normalForm } from import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters"; import { starterPassiveAbilities } from "#app/data/balance/passives"; import { PokemonType } from "#enums/pokemon-type"; -import { GameModes } from "#app/game-mode"; import type { DexEntry, StarterAttributes } from "#app/system/game-data"; import { AbilityAttr, DexAttr } from "#app/system/game-data"; import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; import MessageUiHandler from "#app/ui/message-ui-handler"; import { StatsContainer } from "#app/ui/stats-container"; -import { TextStyle, addTextObject, getTextStyleOptions } from "#app/ui/text"; +import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor, getTextStyleOptions } from "#app/ui/text"; import { Mode } from "#app/ui/ui"; import { addWindow } from "#app/ui/ui-theme"; import { Egg } from "#app/data/egg"; import Overrides from "#app/overrides"; import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; import { Passive as PassiveAttr } from "#enums/passive"; -import * as Challenge from "#app/data/challenge"; import MoveInfoOverlay from "#app/ui/move-info-overlay"; import PokedexInfoOverlay from "#app/ui/pokedex-info-overlay"; import { getEggTierForSpecies } from "#app/data/egg"; @@ -51,7 +49,6 @@ import { BooleanHolder, getLocalizedSpriteKey, isNullOrUndefined, - NumberHolder, padInt, rgbHexToRgba, toReadableString, @@ -66,6 +63,7 @@ import { TimeOfDay } from "#app/enums/time-of-day"; import type { Abilities } from "#app/enums/abilities"; import { BaseStatsOverlay } from "#app/ui/base-stats-overlay"; import { globalScene } from "#app/global-scene"; +import type BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodetext/BBCodeText"; interface LanguageSetting { starterInfoTextSize: string; @@ -242,6 +240,9 @@ export default class PokedexPageUiHandler extends MessageUiHandler { private starterAttributes: StarterAttributes; private savedStarterAttributes: StarterAttributes; + private previousSpecies: PokemonSpecies[]; + private previousStarterAttributes: StarterAttributes[]; + protected blockInput = false; protected blockInputOverlay = false; @@ -250,7 +251,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { // Menu private menuContainer: Phaser.GameObjects.Container; private menuBg: Phaser.GameObjects.NineSlice; - protected optionSelectText: Phaser.GameObjects.Text; + protected optionSelectText: BBCodeText; private menuOptions: MenuOptions[]; protected scale = 0.1666666667; private menuDescriptions: string[]; @@ -261,6 +262,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { private unlockedVariants: boolean[]; private canUseCandies: boolean; + private exitCallback; constructor() { super(Mode.POKEDEX_PAGE); @@ -592,14 +594,13 @@ export default class PokedexPageUiHandler extends MessageUiHandler { this.menuOptions = Utils.getEnumKeys(MenuOptions).map(m => Number.parseInt(MenuOptions[m]) as MenuOptions); - this.optionSelectText = addTextObject( + this.optionSelectText = addBBCodeTextObject( 0, 0, this.menuOptions.map(o => `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`).join("\n"), TextStyle.WINDOW, - { maxLines: this.menuOptions.length }, + { maxLines: this.menuOptions.length, lineSpacing: 12 }, ); - this.optionSelectText.setLineSpacing(12); this.menuDescriptions = [ i18next.t("pokedexUiHandler:showBaseStats"), @@ -622,7 +623,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { ); this.menuBg.setOrigin(0, 0); - this.optionSelectText.setPositionRelative(this.menuBg, 10 + 24 * this.scale, 6); + this.optionSelectText.setPosition(this.menuBg.x + 10 + 24 * this.scale, this.menuBg.y + 6); this.menuContainer.add(this.menuBg); @@ -656,6 +657,9 @@ export default class PokedexPageUiHandler extends MessageUiHandler { // Filter bar sits above everything, except the message box this.starterSelectContainer.bringToTop(this.starterSelectMessageBoxContainer); + + this.previousSpecies = []; + this.previousStarterAttributes = []; } show(args: any[]): boolean { @@ -668,16 +672,20 @@ export default class PokedexPageUiHandler extends MessageUiHandler { return false; } this.species = args[0]; - this.formIndex = args[1] ?? 0; - this.savedStarterAttributes = args[2] ?? { + this.savedStarterAttributes = args[1] ?? { shiny: false, female: true, variant: 0, form: 0, }; - this.filteredIndices = args[3] ?? null; + this.formIndex = this.savedStarterAttributes.form ?? 0; + this.filteredIndices = args[2] ?? null; this.starterSetup(); + if (args[4] instanceof Function) { + this.exitCallback = args[4]; + } + this.moveInfoOverlay.clear(); // clear this when removing a menu; the cancel button doesn't seem to trigger this automatically on controllers this.infoOverlay.clear(); @@ -696,11 +704,39 @@ export default class PokedexPageUiHandler extends MessageUiHandler { this.setSpecies(); this.updateInstructions(); + this.optionSelectText.setText(this.getMenuText()); + this.setCursor(0); return true; } + getMenuText(): string { + const isSeen = this.isSeen(); + const isStarterCaught = !!this.isCaught(this.getStarterSpecies(this.species)); + + return this.menuOptions + .map(o => { + const label = `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`; + const isDark = + !isSeen || + (!isStarterCaught && (o === MenuOptions.TOGGLE_IVS || o === MenuOptions.NATURES)) || + (this.tmMoves.length < 1 && o === MenuOptions.TM_MOVES); + const color = getTextColor( + isDark ? TextStyle.SHADOW_TEXT : TextStyle.SETTINGS_VALUE, + false, + globalScene.uiTheme, + ); + const shadow = getTextColor( + isDark ? TextStyle.SHADOW_TEXT : TextStyle.SETTINGS_VALUE, + true, + globalScene.uiTheme, + ); + return `[shadow=${shadow}][color=${color}]${label}[/color][/shadow]`; + }) + .join("\n"); + } + starterSetup(): void { this.evolutions = []; this.prevolutions = []; @@ -896,6 +932,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { return (dexEntry?.caughtAttr ?? 0n) & (starterDexEntry?.caughtAttr ?? 0n) & species.getFullUnlocksData(); } + /** * Check whether a given form is caught for a given species. * All forms that can be reached through a form change during battle are considered caught and show up in the dex as such. @@ -920,6 +957,14 @@ export default class PokedexPageUiHandler extends MessageUiHandler { return isFormCaught; } + isSeen(): boolean { + if (this.speciesStarterDexEntry?.seenAttr) { + return true; + } + const starterCaughtAttr = this.isCaught(this.getStarterSpecies(this.species)); + return !!starterCaughtAttr; + } + /** * Get the starter attributes for the given PokemonSpecies, after sanitizing them. * If somehow a preference is set for a form, variant, gender, ability or nature @@ -1068,6 +1113,8 @@ export default class PokedexPageUiHandler extends MessageUiHandler { const isCaught = this.isCaught(); const isFormCaught = this.isFormCaught(); + const isSeen = this.isSeen(); + const isStarterCaught = !!this.isCaught(this.getStarterSpecies(this.species)); if (this.blockInputOverlay) { if (button === Button.CANCEL || button === Button.ACTION) { @@ -1091,8 +1138,26 @@ export default class PokedexPageUiHandler extends MessageUiHandler { if (this.statsMode) { this.toggleStatsMode(false); success = true; + } else if (this.previousSpecies.length > 0) { + this.blockInput = true; + ui.setModeWithoutClear(Mode.OPTION_SELECT).then(() => { + const species = this.previousSpecies.pop(); + const starterAttributes = this.previousStarterAttributes.pop(); + this.moveInfoOverlay.clear(); + this.clearText(); + ui.setModeForceTransition(Mode.POKEDEX_PAGE, species, starterAttributes); + success = true; + }); + this.blockInput = false; } else { - this.getUi().revertMode(); + ui.revertMode().then(() => { + console.log("exitCallback", this.exitCallback); + if (this.exitCallback instanceof Function) { + const exitCallback = this.exitCallback; + this.exitCallback = null; + exitCallback(); + } + }); success = true; } } else { @@ -1103,7 +1168,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { if (button === Button.ACTION) { switch (this.cursor) { case MenuOptions.BASE_STATS: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1123,7 +1188,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.LEVEL_MOVES: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1181,7 +1246,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.EGG_MOVES: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1248,7 +1313,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.TM_MOVES: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else if (this.tmMoves.length < 1) { ui.showText(i18next.t("pokedexUiHandler:noTmMoves")); @@ -1299,7 +1364,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.ABILITIES: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1387,7 +1452,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.BIOMES: - if (!(isCaught || this.speciesStarterDexEntry?.seenAttr)) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1466,7 +1531,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.EVOLUTIONS: - if (!isCaught || !isFormCaught) { + if (!isSeen) { error = true; } else { this.blockInput = true; @@ -1507,6 +1572,8 @@ export default class PokedexPageUiHandler extends MessageUiHandler { ? (preSpecies ?? this.species).getFormNameToDisplay(preFormIndex, true) : (preSpecies ?? this.species).getExpandedSpeciesName(), handler: () => { + this.previousSpecies.push(this.species); + this.previousStarterAttributes.push({ ...this.savedStarterAttributes }); const newSpecies = allSpecies.find( species => species.speciesId === pokemonPrevolutions[pre.speciesId], ); @@ -1522,7 +1589,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { this.savedStarterAttributes.form = newFormIndex; this.moveInfoOverlay.clear(); this.clearText(); - ui.setMode(Mode.POKEDEX_PAGE, newSpecies, newFormIndex, this.savedStarterAttributes); + ui.setMode(Mode.POKEDEX_PAGE, newSpecies, this.savedStarterAttributes); return true; }, onHover: () => this.showText(conditionText), @@ -1558,11 +1625,13 @@ export default class PokedexPageUiHandler extends MessageUiHandler { : (evoSpecies ?? this.species).getExpandedSpeciesName(), style: isCaughtEvo && isFormCaughtEvo ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT, handler: () => { + this.previousSpecies.push(this.species); + this.previousStarterAttributes.push({ ...this.savedStarterAttributes }); this.starterAttributes.form = newFormIndex; this.savedStarterAttributes.form = newFormIndex; this.moveInfoOverlay.clear(); this.clearText(); - ui.setMode(Mode.POKEDEX_PAGE, evoSpecies, newFormIndex, this.savedStarterAttributes); + ui.setMode(Mode.POKEDEX_PAGE, evoSpecies, this.savedStarterAttributes); return true; }, onHover: () => this.showText(conditionText), @@ -1598,6 +1667,8 @@ export default class PokedexPageUiHandler extends MessageUiHandler { label: label, style: isFormCaught ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT, handler: () => { + this.previousSpecies.push(this.species); + this.previousStarterAttributes.push({ ...this.savedStarterAttributes }); const newSpecies = this.species; const newFormIndex = this.species.forms.find(f => f.formKey === bf.formKey)?.formIndex; this.starterAttributes.form = newFormIndex; @@ -1607,7 +1678,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler { ui.setMode( Mode.POKEDEX_PAGE, newSpecies, - newFormIndex, this.savedStarterAttributes, this.filteredIndices, ); @@ -1645,7 +1715,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.TOGGLE_IVS: - if (!isCaught || !isFormCaught) { + if (!isStarterCaught) { error = true; } else { this.toggleStatsMode(); @@ -1655,7 +1725,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case MenuOptions.NATURES: - if (!isCaught || !isFormCaught) { + if (!isStarterCaught) { error = true; } else { this.blockInput = true; @@ -1958,6 +2028,11 @@ export default class PokedexPageUiHandler extends MessageUiHandler { case Button.LEFT: this.blockInput = true; ui.setModeWithoutClear(Mode.OPTION_SELECT).then(() => { + // Always go back to first selection after scrolling around + if (this.previousSpecies.length === 0) { + this.previousSpecies.push(this.species); + this.previousStarterAttributes.push({ ...this.savedStarterAttributes }); + } let newSpecies: PokemonSpecies; if (this.filteredIndices) { const index = this.filteredIndices.findIndex(id => id === this.species.speciesId); @@ -1979,7 +2054,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler { ui.setModeForceTransition( Mode.POKEDEX_PAGE, newSpecies, - newFormIndex, this.savedStarterAttributes, this.filteredIndices, ); @@ -1988,6 +2062,11 @@ export default class PokedexPageUiHandler extends MessageUiHandler { break; case Button.RIGHT: ui.setModeWithoutClear(Mode.OPTION_SELECT).then(() => { + // Always go back to first selection after scrolling around + if (this.previousSpecies.length === 0) { + this.previousSpecies.push(this.species); + this.previousStarterAttributes.push({ ...this.savedStarterAttributes }); + } let newSpecies: PokemonSpecies; if (this.filteredIndices) { const index = this.filteredIndices.findIndex(id => id === this.species.speciesId); @@ -2009,7 +2088,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler { ui.setModeForceTransition( Mode.POKEDEX_PAGE, newSpecies, - newFormIndex, this.savedStarterAttributes, this.filteredIndices, ); @@ -2128,22 +2206,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler { } } - getValueLimit(): number { - const valueLimit = new NumberHolder(0); - switch (globalScene.gameMode.modeId) { - case GameModes.ENDLESS: - case GameModes.SPLICED_ENDLESS: - valueLimit.value = 15; - break; - default: - valueLimit.value = 10; - } - - Challenge.applyChallenges(globalScene.gameMode, Challenge.ChallengeType.STARTER_POINTS, valueLimit); - - return valueLimit.value; - } - setCursor(cursor: number): boolean { const ret = super.setCursor(cursor); @@ -2368,8 +2430,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler { } if (species) { - const dexEntry = globalScene.gameData.dexData[species.speciesId]; - const caughtAttr = this.isCaught(species); if (!caughtAttr) { @@ -2390,7 +2450,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { } const isFormCaught = this.isFormCaught(); - const isFormSeen = dexEntry ? (dexEntry.seenAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n : false; + const isFormSeen = this.isSeen(); this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default? this.pokemonNumberText.setColor(this.getTextColor(shiny ? TextStyle.SUMMARY_GOLD : TextStyle.SUMMARY, false)); diff --git a/src/ui/pokedex-ui-handler.ts b/src/ui/pokedex-ui-handler.ts index f4cb9f51c16..230b1bcb42b 100644 --- a/src/ui/pokedex-ui-handler.ts +++ b/src/ui/pokedex-ui-handler.ts @@ -12,7 +12,7 @@ import { getStarterValueFriendshipCap, speciesStarterCosts, POKERUS_STARTER_COUN import { catchableSpecies } from "#app/data/balance/biomes"; import { PokemonType } from "#enums/pokemon-type"; import type { DexAttrProps, DexEntry, StarterAttributes, StarterPreferences } from "#app/system/game-data"; -import { AbilityAttr, DexAttr, loadStarterPreferences, saveStarterPreferences } from "#app/system/game-data"; +import { AbilityAttr, DexAttr, loadStarterPreferences } from "#app/system/game-data"; import MessageUiHandler from "#app/ui/message-ui-handler"; import PokemonIconAnimHandler, { PokemonIconAnimMode } from "#app/ui/pokemon-icon-anim-handler"; import { TextStyle, addTextObject } from "#app/ui/text"; @@ -37,11 +37,10 @@ import { addWindow } from "./ui-theme"; import type { OptionSelectConfig } from "./abstact-option-select-ui-handler"; import { FilterText, FilterTextRow } from "./filter-text"; import { allAbilities } from "#app/data/ability"; -import type { PassiveAbilities } from "#app/data/balance/passives"; import { starterPassiveAbilities } from "#app/data/balance/passives"; import { allMoves } from "#app/data/moves/move"; import { speciesTmMoves } from "#app/data/balance/tms"; -import { pokemonStarters } from "#app/data/balance/pokemon-evolutions"; +import { pokemonPrevolutions, pokemonStarters } from "#app/data/balance/pokemon-evolutions"; import { Biome } from "#enums/biome"; import { globalScene } from "#app/global-scene"; @@ -782,6 +781,15 @@ export default class PokedexUiHandler extends MessageUiHandler { this.starterSelectMessageBoxContainer.setVisible(!!text?.length); } + isSeen(species: PokemonSpecies, dexEntry: DexEntry): boolean { + if (dexEntry?.seenAttr) { + return true; + } + + const starterDexEntry = globalScene.gameData.dexData[this.getStarterSpeciesId(species.speciesId)]; + return !!starterDexEntry?.caughtAttr; + } + /** * Determines if 'Icon' based upgrade notifications should be shown * @returns true if upgrade notifications are enabled and set to display an 'Icon' @@ -1125,7 +1133,7 @@ export default class PokedexUiHandler extends MessageUiHandler { } else if (this.showingTray) { if (button === Button.ACTION) { const formIndex = this.trayForms[this.trayCursor].formIndex; - ui.setOverlayMode(Mode.POKEDEX_PAGE, this.lastSpecies, formIndex, { form: formIndex }, this.filteredIndices); + ui.setOverlayMode(Mode.POKEDEX_PAGE, this.lastSpecies, { form: formIndex }, this.filteredIndices); success = true; } else { const numberOfForms = this.trayContainers.length; @@ -1174,7 +1182,7 @@ export default class PokedexUiHandler extends MessageUiHandler { } } else { if (button === Button.ACTION) { - ui.setOverlayMode(Mode.POKEDEX_PAGE, this.lastSpecies, 0, null, this.filteredIndices); + ui.setOverlayMode(Mode.POKEDEX_PAGE, this.lastSpecies, null, this.filteredIndices); success = true; } else { switch (button) { @@ -1365,7 +1373,7 @@ export default class PokedexUiHandler extends MessageUiHandler { const levelMoves = pokemonSpeciesLevelMoves[species.speciesId].map(m => allMoves[m[1]].name); // This always gets egg moves from the starter const eggMoves = speciesEggMoves[starterId]?.map(m => allMoves[m].name) ?? []; - const tmMoves = speciesTmMoves[starterId]?.map(m => allMoves[Array.isArray(m) ? m[1] : m].name) ?? []; + const tmMoves = speciesTmMoves[species.speciesId]?.map(m => allMoves[Array.isArray(m) ? m[1] : m].name) ?? []; const selectedMove1 = this.filterText.getValue(FilterTextRow.MOVE_1); const selectedMove2 = this.filterText.getValue(FilterTextRow.MOVE_2); @@ -1404,7 +1412,12 @@ export default class PokedexUiHandler extends MessageUiHandler { // Ability filter const abilities = [species.ability1, species.ability2, species.abilityHidden].map(a => allAbilities[a].name); - const passives = starterPassiveAbilities[starterId] ?? ({} as PassiveAbilities); + const passiveId = starterPassiveAbilities.hasOwnProperty(species.speciesId) + ? species.speciesId + : starterPassiveAbilities.hasOwnProperty(starterId) + ? starterId + : pokemonPrevolutions[starterId]; + const passives = starterPassiveAbilities[passiveId]; const selectedAbility1 = this.filterText.getValue(FilterTextRow.ABILITY_1); const fitsFormAbility1 = species.forms.some(form => @@ -1736,42 +1749,32 @@ export default class PokedexUiHandler extends MessageUiHandler { if (caughtAttr & data.species.getFullUnlocksData() || globalScene.dexForDevs) { container.icon.clearTint(); - } else if (dexEntry.seenAttr) { + } else if (this.isSeen(data.species, dexEntry)) { container.icon.setTint(0x808080); } else { container.icon.setTint(0); } - if (data.eggMove1) { - container.eggMove1Icon.setVisible(true); - } else { - container.eggMove1Icon.setVisible(false); - } - if (data.eggMove2) { - container.eggMove2Icon.setVisible(true); - } else { - container.eggMove2Icon.setVisible(false); - } - if (data.tmMove1) { - container.tmMove1Icon.setVisible(true); - } else { - container.tmMove1Icon.setVisible(false); - } - if (data.tmMove2) { - container.tmMove2Icon.setVisible(true); - } else { - container.tmMove2Icon.setVisible(false); - } - if (data.passive1) { - container.passive1Icon.setVisible(true); - } else { - container.passive1Icon.setVisible(false); - } - if (data.passive2) { - container.passive2Icon.setVisible(true); - } else { - container.passive2Icon.setVisible(false); - } + const pairs: [boolean | undefined, Phaser.GameObjects.Image][] = [ + [data.eggMove1, container.eggMove1Icon], + [data.eggMove2, container.eggMove2Icon], + [data.tmMove1, container.tmMove1Icon], + [data.tmMove2, container.tmMove2Icon], + [data.passive1, container.passive1Icon], + [data.passive2, container.passive2Icon], + ]; + + pairs.forEach(([unlocked, icon]) => { + if (unlocked) { + icon.setVisible(true); + icon.clearTint(); + } else if (unlocked === false) { + icon.setVisible(true); + icon.setTint(0x808080); + } else { + icon.setVisible(false); + } + }); if (this.showDecorations) { if (this.pokerusSpecies.includes(data.species)) { @@ -1937,13 +1940,11 @@ export default class PokedexUiHandler extends MessageUiHandler { const props = this.getSanitizedProps(globalScene.gameData.getSpeciesDexAttrProps(this.lastSpecies, dexAttr)); this.trayContainers = []; + const isFormSeen = this.isSeen(species, dexEntry); this.trayForms.map((f, index) => { const isFormCaught = dexEntry ? (dexEntry.caughtAttr & species.getFullUnlocksData() & globalScene.gameData.getFormAttr(f.formIndex ?? 0)) > 0n : false; - const isFormSeen = dexEntry - ? (dexEntry.seenAttr & globalScene.gameData.getFormAttr(f.formIndex ?? 0)) > 0n - : false; const formContainer = new PokedexMonContainer(species, { formIndex: f.formIndex, female: props.female, @@ -2153,7 +2154,7 @@ export default class PokedexUiHandler extends MessageUiHandler { } const isFormCaught = dexEntry ? (caughtAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n : false; - const isFormSeen = dexEntry ? (dexEntry.seenAttr & globalScene.gameData.getFormAttr(formIndex ?? 0)) > 0n : false; + const isFormSeen = this.isSeen(species, dexEntry); const assetLoadCancelled = new BooleanHolder(false); this.assetLoadCancelled = assetLoadCancelled; diff --git a/src/ui/pokemon-info-container.ts b/src/ui/pokemon-info-container.ts index 64c743ec88d..56201f38748 100644 --- a/src/ui/pokemon-info-container.ts +++ b/src/ui/pokemon-info-container.ts @@ -458,7 +458,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { makeRoomForConfirmUi(speedMultiplier = 1, fromCatch = false): Promise { const xPosition = fromCatch - ? this.initialX - this.infoWindowWidth - 65 + ? this.initialX - this.infoWindowWidth - 67 : this.initialX - this.infoWindowWidth - ConfirmUiHandler.windowWidth; return new Promise(resolve => { globalScene.tweens.add({ diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index ccc56f38368..c1e2b2ac568 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -80,6 +80,7 @@ import { PLAYER_PARTY_MAX_SIZE } from "#app/constants"; import { achvs } from "#app/system/achv"; import * as Utils from "../utils"; import type { GameObjects } from "phaser"; +import { checkStarterValidForChallenge } from "#app/data/challenge"; export type StarterSelectCallback = (starters: Starter[]) => void; @@ -149,7 +150,7 @@ const languageSettings: { [key: string]: LanguageSetting } = { instructionTextSize: "38px", }, "ca-ES": { - starterInfoTextSize: "56px", + starterInfoTextSize: "52px", instructionTextSize: "38px", }, }; @@ -1760,21 +1761,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const species = starter.species; const [isDupe] = this.isInParty(species); const starterCost = globalScene.gameData.getSpeciesStarterValue(species.speciesId); - const isValidForChallenge = new BooleanHolder(true); - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, + const isValidForChallenge = checkStarterValidForChallenge( species, - isValidForChallenge, globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), this.isPartyValid(), ); const isCaught = globalScene.gameData.dexData[species.speciesId].caughtAttr; return ( - !isDupe && - isValidForChallenge.value && - currentPartyValue + starterCost <= this.getValueLimit() && - isCaught + !isDupe && isValidForChallenge && currentPartyValue + starterCost <= this.getValueLimit() && isCaught ); }); if (validStarters.length === 0) { @@ -1861,16 +1855,11 @@ 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); const isPartyValid = this.isPartyValid(); - const isValidForChallenge = new BooleanHolder(true); - - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, + const isValidForChallenge = checkStarterValidForChallenge( this.lastSpecies, - isValidForChallenge, globalScene.gameData.getSpeciesDexAttrProps( this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId), @@ -1888,11 +1877,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const newCost = globalScene.gameData.getSpeciesStarterValue(this.lastSpecies.speciesId); if ( !isDupe && - isValidForChallenge.value && + isValidForChallenge && currentPartyValue + newCost <= this.getValueLimit() && this.starterSpecies.length < PLAYER_PARTY_MAX_SIZE ) { - // this checks to make sure the pokemon doesn't exist in your party, it's valid for the challenge and that it won't go over the cost limit; if it meets all these criteria it will add it to your party options = [ { label: i18next.t("starterSelectUiHandler:addToParty"), @@ -1902,7 +1890,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { globalScene.gameData.getSpeciesStarterValue(this.lastSpecies.speciesId), true, ); - if (!isDupe && isValidForChallenge.value && isOverValueLimit) { + if (!isDupe && isValidForChallenge && isOverValueLimit) { const cursorObj = this.starterCursorObjs[this.starterSpecies.length]; cursorObj.setVisible(true); cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y); @@ -2336,7 +2324,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { form: starterAttributes.form, female: starterAttributes.female, }; - ui.setOverlayMode(Mode.POKEDEX_PAGE, this.lastSpecies, starterAttributes.form, attributes); + ui.setOverlayMode(Mode.POKEDEX_PAGE, this.lastSpecies, attributes); }); return true; }, @@ -2993,32 +2981,27 @@ export default class StarterSelectUiHandler extends MessageUiHandler { /* Here we are making a fake form index dex props for challenges * Since some pokemon rely on forms to be valid (i.e. blaze tauros for fire challenges), we make a fake form and dex props to use in the challenge */ + if (!species.forms[i].isStarterSelectable) { + continue; + } const tempFormProps = BigInt(Math.pow(2, i)) * DexAttr.DEFAULT_FORM; - const isValidForChallenge = new BooleanHolder(true); - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, + const isValidForChallenge = checkStarterValidForChallenge( container.species, - isValidForChallenge, globalScene.gameData.getSpeciesDexAttrProps(species, tempFormProps), true, ); - allFormsValid = allFormsValid || isValidForChallenge.value; + allFormsValid = allFormsValid || isValidForChallenge; } } else { - const isValidForChallenge = new BooleanHolder(true); - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, + const isValidForChallenge = checkStarterValidForChallenge( container.species, - isValidForChallenge, globalScene.gameData.getSpeciesDexAttrProps( species, globalScene.gameData.getSpeciesDefaultDexAttr(container.species, false, true), ), true, ); - allFormsValid = isValidForChallenge.value; + allFormsValid = isValidForChallenge; } if (allFormsValid) { this.validStarterContainers.push(container); @@ -3851,15 +3834,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonSprite.setVisible(!this.statsMode); } - const isValidForChallenge = new BooleanHolder(true); - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, - species, - isValidForChallenge, - globalScene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), - !!this.starterSpecies.length, - ); const currentFilteredContainer = this.filteredStarterContainers.find( p => p.species.speciesId === species.speciesId, ); @@ -4233,20 +4207,15 @@ export default class StarterSelectUiHandler extends MessageUiHandler { globalScene.time.delayedCall(fixedInt(500), () => this.tryUpdateValue()); return false; } - let isPartyValid: boolean = this.isPartyValid(); // this checks to see if the party is valid + let isPartyValid: boolean = this.isPartyValid(); if (addingToParty) { - // this does a check to see if the pokemon being added is valid; if so, it will update the isPartyValid boolean - const isNewPokemonValid = new BooleanHolder(true); const species = this.filteredStarterContainers[this.cursor].species; - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, + const isNewPokemonValid = checkStarterValidForChallenge( species, - isNewPokemonValid, globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), false, ); - isPartyValid = isPartyValid || isNewPokemonValid.value; + isPartyValid = isPartyValid || isNewPokemonValid; } /** @@ -4270,12 +4239,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { * If speciesStarterDexEntry?.caughtAttr is true, this species registered in stater. * we change to can AddParty value to true since the user has enough cost to choose this pokemon and this pokemon registered too. */ - const isValidForChallenge = new BooleanHolder(true); - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, + const isValidForChallenge = checkStarterValidForChallenge( this.allSpecies[s], - isValidForChallenge, globalScene.gameData.getSpeciesDexAttrProps( this.allSpecies[s], this.getCurrentDexProps(this.allSpecies[s].speciesId), @@ -4283,7 +4248,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { isPartyValid, ); - const canBeChosen = remainValue >= speciesStarterValue && isValidForChallenge.value; + const canBeChosen = remainValue >= speciesStarterValue && isValidForChallenge; const isPokemonInParty = this.isInParty(this.allSpecies[s])[0]; // this will get the valud of isDupe from isInParty. This will let us see if the pokemon in question is in our party already so we don't grey out the sprites if they're invalid @@ -4417,17 +4382,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler { isPartyValid(): boolean { let canStart = false; for (let s = 0; s < this.starterSpecies.length; s++) { - const isValidForChallenge = new BooleanHolder(true); const species = this.starterSpecies[s]; - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, + const isValidForChallenge = checkStarterValidForChallenge( species, - isValidForChallenge, globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), false, ); - canStart = canStart || isValidForChallenge.value; + canStart = canStart || isValidForChallenge; } return canStart; } @@ -4592,4 +4553,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler { icon.setFrame(species.getIconId(female, formIndex, false, variant)); } } + + /** + * Clears this UI's starter preferences. + * + * Designed to be used for unit tests that utilize this UI. + */ + clearStarterPreferences() { + this.starterPreferences = {}; + } } diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index d42572cfef4..9b209ded57a 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -1208,7 +1208,7 @@ export default class SummaryUiHandler extends UiHandler { } if (this.moveCursor < 4 && this.pokemon && this.moveCursor < this.pokemon.moveset.length) { - return this.pokemon.moveset[this.moveCursor]!.getMove(); // TODO: is this bang correct? + return this.pokemon.moveset[this.moveCursor].getMove(); } if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.moveCursor === 4) { return this.newMove; diff --git a/src/ui/title-ui-handler.ts b/src/ui/title-ui-handler.ts index 2f797bb4bfb..a9fdf22ec57 100644 --- a/src/ui/title-ui-handler.ts +++ b/src/ui/title-ui-handler.ts @@ -8,10 +8,13 @@ import { TimedEventDisplay } from "#app/timed-event-manager"; import { version } from "../../package.json"; import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import { globalScene } from "#app/global-scene"; +import type { Species } from "#enums/species"; +import { getPokemonSpecies } from "#app/data/pokemon-species"; +import { PlayerGender } from "#enums/player-gender"; export default class TitleUiHandler extends OptionSelectUiHandler { /** If the stats can not be retrieved, use this fallback value */ - private static readonly BATTLES_WON_FALLBACK: number = -99999999; + private static readonly BATTLES_WON_FALLBACK: number = -1; private titleContainer: Phaser.GameObjects.Container; private playerCountLabel: Phaser.GameObjects.Text; @@ -98,6 +101,29 @@ export default class TitleUiHandler extends OptionSelectUiHandler { }); } + /** Used solely to display a random Pokémon name in a splash message. */ + randomPokemon(): void { + const rand = Utils.randInt(1025, 1); + const pokemon = getPokemonSpecies(rand as Species); + if ( + this.splashMessage === "splashMessages:underratedPokemon" || + this.splashMessage === "splashMessages:dontTalkAboutThePokemonIncident" || + this.splashMessage === "splashMessages:aWildPokemonAppeared" || + this.splashMessage === "splashMessages:aprilFools.removedPokemon" + ) { + this.splashMessageText.setText(i18next.t(this.splashMessage, { pokemonName: pokemon.name })); + } + } + + /** Used for a specific April Fools splash message. */ + genderSplash(): void { + if (this.splashMessage === "splashMessages:aprilFools.helloKyleAmber") { + globalScene.gameData.gender === PlayerGender.MALE + ? this.splashMessageText.setText(i18next.t(this.splashMessage, { name: i18next.t("trainerNames:player_m") })) + : this.splashMessageText.setText(i18next.t(this.splashMessage, { name: i18next.t("trainerNames:player_f") })); + } + } + show(args: any[]): boolean { const ret = super.show(args); @@ -121,6 +147,9 @@ export default class TitleUiHandler extends OptionSelectUiHandler { this.eventDisplay.show(); } + this.randomPokemon(); + this.genderSplash(); + this.updateTitleStats(); this.titleStatsTimer = setInterval(() => { diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 7c202e9210d..6605e5ef730 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -328,17 +328,28 @@ export default class UI extends Phaser.GameObjects.Container { prompt?: boolean | null, promptDelay?: number | null, ): void { + const pokename: string[] = []; + const repname = ["#POKEMON1", "#POKEMON2"]; + for (let p = 0; p < globalScene.getPlayerField().length; p++) { + pokename.push(globalScene.getPlayerField()[p].getNameToRender()); + text = text.split(pokename[p]).join(repname[p]); + } if (prompt && text.indexOf("$") > -1) { const messagePages = text.split(/\$/g).map(m => m.trim()); // biome-ignore lint/complexity/useOptionalChain: optional chain would change this to be null instead of undefined. let showMessageAndCallback = () => callback && callback(); for (let p = messagePages.length - 1; p >= 0; p--) { const originalFunc = showMessageAndCallback; + messagePages[p] = messagePages[p].split(repname[0]).join(pokename[0]); + messagePages[p] = messagePages[p].split(repname[1]).join(pokename[1]); showMessageAndCallback = () => this.showText(messagePages[p], null, originalFunc, null, true); } showMessageAndCallback(); } else { const handler = this.getHandler(); + for (let p = 0; p < globalScene.getPlayerField().length; p++) { + text = text.split(repname[p]).join(pokename[p]); + } if (handler instanceof MessageUiHandler) { (handler as MessageUiHandler).showText(text, delay, callback, callbackDelay, prompt, promptDelay); } else { diff --git a/src/utils.ts b/src/utils.ts index 7d3dea0247e..fbca8410feb 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -464,6 +464,7 @@ export function hasAllLocalizedSprites(lang?: string): boolean { case "pt-BR": case "ko": case "ja": + case "ca-ES": return true; default: return false; diff --git a/test/abilities/desolate-land.test.ts b/test/abilities/desolate-land.test.ts index 67d9ac1cdf5..bb0b152418d 100644 --- a/test/abilities/desolate-land.test.ts +++ b/test/abilities/desolate-land.test.ts @@ -1,5 +1,7 @@ import { PokeballType } from "#app/enums/pokeball"; import { WeatherType } from "#app/enums/weather-type"; +import type { CommandPhase } from "#app/phases/command-phase"; +import { Command } from "#app/ui/command-ui-handler"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; @@ -131,4 +133,18 @@ describe("Abilities - Desolate Land", () => { expect(game.scene.arena.weather?.weatherType).not.toBe(WeatherType.HARSH_SUN); }); + + it("should lift after fleeing from a wild pokemon", async () => { + game.override.enemyAbility(Abilities.DESOLATE_LAND).ability(Abilities.BALL_FETCH); + await game.classicMode.startBattle([Species.MAGIKARP]); + expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN); + + vi.spyOn(game.scene.getPlayerPokemon()!, "randSeedInt").mockReturnValue(0); + + const commandPhase = game.scene.getCurrentPhase() as CommandPhase; + commandPhase.handleCommand(Command.RUN, 0); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.arena.weather?.weatherType).not.toBe(WeatherType.HARSH_SUN); + }); }); diff --git a/test/abilities/flower_gift.test.ts b/test/abilities/flower_gift.test.ts index fff509a1f00..5c3fd246b7a 100644 --- a/test/abilities/flower_gift.test.ts +++ b/test/abilities/flower_gift.test.ts @@ -1,12 +1,14 @@ import { BattlerIndex } from "#app/battle"; +import { allAbilities } from "#app/data/ability"; import { Abilities } from "#app/enums/abilities"; import { Stat } from "#app/enums/stat"; import { WeatherType } from "#app/enums/weather-type"; +import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/testUtils/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("Abilities - Flower Gift", () => { let phaserGame: Phaser.Game; @@ -28,6 +30,64 @@ describe("Abilities - Flower Gift", () => { expect(game.scene.getPlayerPokemon()?.formIndex).toBe(OVERCAST_FORM); }; + /** + * Tests damage dealt by a move used against a target before and after Flower Gift is activated. + * @param game The game manager instance + * @param move The move that should be used + * @param allyAttacker True if the ally is attacking the enemy, false if the enemy is attacking the ally + * @param ability The ability that the ally pokemon should have + * @param enemyAbility The ability that the enemy pokemon should have + * + * @returns Two numbers, the first being the damage done to the target without flower gift active, the second being the damage done with flower gift active + */ + const testDamageDealt = async ( + game: GameManager, + move: Moves, + allyAttacker: boolean, + allyAbility = Abilities.BALL_FETCH, + enemyAbility = Abilities.BALL_FETCH, + ): Promise<[number, number]> => { + game.override.battleType("double"); + game.override.moveset([Moves.SPLASH, Moves.SUNNY_DAY, move, Moves.HEAL_PULSE]); + game.override.enemyMoveset([Moves.SPLASH, Moves.HEAL_PULSE]); + const target_index = allyAttacker ? BattlerIndex.ENEMY : BattlerIndex.PLAYER_2; + const attacker_index = allyAttacker ? BattlerIndex.PLAYER_2 : BattlerIndex.ENEMY; + const ally_move = allyAttacker ? move : Moves.SPLASH; + const enemy_move = allyAttacker ? Moves.SPLASH : move; + const ally_target = allyAttacker ? BattlerIndex.ENEMY : null; + + await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]); + const target = allyAttacker ? game.scene.getEnemyField()[0] : game.scene.getPlayerField()[1]; + const initialHp = target.getMaxHp(); + + // Override the ability for the target and attacker only + vi.spyOn(game.scene.getPlayerField()[1], "getAbility").mockReturnValue(allAbilities[allyAbility]); + vi.spyOn(game.scene.getEnemyField()[0], "getAbility").mockReturnValue(allAbilities[enemyAbility]); + + // turn 1 + game.move.select(Moves.SUNNY_DAY, 0); + game.move.select(ally_move, 1, ally_target); + await game.forceEnemyMove(enemy_move, BattlerIndex.PLAYER_2); + await game.forceEnemyMove(Moves.SPLASH); + // Ensure sunny day is used last. + await game.setTurnOrder([attacker_index, target_index, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]); + await game.phaseInterceptor.to(TurnEndPhase); + const damageWithoutGift = initialHp - target.hp; + + target.hp = initialHp; + + // turn 2. Make target use recover to reset hp calculation. + game.move.select(Moves.SPLASH, 0, target_index); + game.move.select(ally_move, 1, ally_target); + await game.forceEnemyMove(enemy_move, BattlerIndex.PLAYER_2); + await game.forceEnemyMove(Moves.SPLASH); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, target_index, attacker_index]); + await game.phaseInterceptor.to(TurnEndPhase); + const damageWithGift = initialHp - target.hp; + + return [damageWithoutGift, damageWithGift]; + }; + beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, @@ -41,23 +101,24 @@ 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.SUNSTEEL_STRIKE, Moves.SUNNY_DAY, Moves.MUD_SLAP]) .enemySpecies(Species.MAGIKARP) .enemyMoveset(Moves.SPLASH) - .enemyAbility(Abilities.BALL_FETCH); + .enemyAbility(Abilities.BALL_FETCH) + .enemyLevel(100) + .startingLevel(100); }); - // 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]); - const [cherrim] = game.scene.getPlayerField(); + const [cherrim, magikarp] = game.scene.getPlayerField(); const cherrimAtkStat = cherrim.getEffectiveStat(Stat.ATK); const cherrimSpDefStat = cherrim.getEffectiveStat(Stat.SPDEF); - // const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK);; - // const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF); + const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK); + const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF); game.move.select(Moves.SUNNY_DAY, 0); game.move.select(Moves.SPLASH, 1); @@ -68,8 +129,34 @@ describe("Abilities - Flower Gift", () => { expect(cherrim.formIndex).toBe(SUNSHINE_FORM); expect(cherrim.getEffectiveStat(Stat.ATK)).toBe(Math.floor(cherrimAtkStat * 1.5)); expect(cherrim.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(cherrimSpDefStat * 1.5)); - // expect(magikarp.getEffectiveStat(Stat.ATK)).toBe(Math.floor(magikarpAtkStat * 1.5)); - // expect(magikarp.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(magikarpSpDefStat * 1.5)); + expect(magikarp.getEffectiveStat(Stat.ATK)).toBe(Math.floor(magikarpAtkStat * 1.5)); + expect(magikarp.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(magikarpSpDefStat * 1.5)); + }); + + it("should not increase the damage of an ally using an ability ignoring move", async () => { + const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, Moves.SUNSTEEL_STRIKE, true); + expect(damageWithGift).toBe(damageWithoutGift); + }); + + it("should not increase the damage of a mold breaker ally", async () => { + const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, Moves.TACKLE, true, Abilities.MOLD_BREAKER); + expect(damageWithGift).toBe(damageWithoutGift); + }); + + it("should decrease the damage an ally takes from a special attack", async () => { + const [damageWithoutGift, damageWithGift] = await testDamageDealt(game, Moves.MUD_SLAP, false); + expect(damageWithGift).toBeLessThan(damageWithoutGift); + }); + + it("should not decrease the damage an ally takes from a mold breaker enemy using a special attack", async () => { + const [damageWithoutGift, damageWithGift] = await testDamageDealt( + game, + Moves.MUD_SLAP, + false, + Abilities.BALL_FETCH, + Abilities.MOLD_BREAKER, + ); + expect(damageWithGift).toBe(damageWithoutGift); }); it("changes the Pokemon's form during Harsh Sunlight", async () => { @@ -92,6 +179,7 @@ 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.moveset([Moves.SKILL_SWAP]); await game.classicMode.startBattle([Species.CHERRIM]); diff --git a/test/abilities/forecast.test.ts b/test/abilities/forecast.test.ts index bdc32604bba..642b490da72 100644 --- a/test/abilities/forecast.test.ts +++ b/test/abilities/forecast.test.ts @@ -181,7 +181,7 @@ describe("Abilities - Forecast", () => { expect(castform.formIndex).toBe(SNOWY_FORM); - game.scene.arena.trySetWeather(WeatherType.FOG, false); + game.scene.arena.trySetWeather(WeatherType.FOG); game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH, 1); await game.phaseInterceptor.to("TurnStartPhase"); diff --git a/test/abilities/imposter.test.ts b/test/abilities/imposter.test.ts index b4469cd9042..2c7302d04b7 100644 --- a/test/abilities/imposter.test.ts +++ b/test/abilities/imposter.test.ts @@ -127,4 +127,63 @@ describe("Abilities - Imposter", () => { expect(game.scene.getEnemyPokemon()?.getStatStage(Stat.ATK)).toBe(-1); }); + + it("should persist transformed attributes across reloads", async () => { + game.override.moveset([Moves.ABSORB]); + + await game.classicMode.startBattle([Species.DITTO]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.toNextWave(); + + expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase"); + expect(game.scene.currentBattle.waveIndex).toBe(2); + + await game.reload.reloadSession(); + + const playerReloaded = game.scene.getPlayerPokemon()!; + const playerMoveset = player.getMoveset(); + + expect(playerReloaded.getSpeciesForm().speciesId).toBe(enemy.getSpeciesForm().speciesId); + expect(playerReloaded.getAbility()).toBe(enemy.getAbility()); + expect(playerReloaded.getGender()).toBe(enemy.getGender()); + + expect(playerReloaded.getStat(Stat.HP, false)).not.toBe(enemy.getStat(Stat.HP)); + for (const s of EFFECTIVE_STATS) { + expect(playerReloaded.getStat(s, false)).toBe(enemy.getStat(s, false)); + } + + expect(playerMoveset.length).toEqual(1); + expect(playerMoveset[0]?.moveId).toEqual(Moves.SPLASH); + }); + + it("should stay transformed with the correct form after reload", async () => { + game.override.moveset([Moves.ABSORB]); + game.override.enemySpecies(Species.UNOWN); + await game.classicMode.startBattle([Species.DITTO]); + + const enemy = game.scene.getEnemyPokemon()!; + + // change form + enemy.species.forms[5]; + enemy.species.formIndex = 5; + + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.toNextWave(); + + expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase"); + expect(game.scene.currentBattle.waveIndex).toBe(2); + + await game.reload.reloadSession(); + + const playerReloaded = game.scene.getPlayerPokemon()!; + + expect(playerReloaded.getSpeciesForm().speciesId).toBe(enemy.getSpeciesForm().speciesId); + expect(playerReloaded.getSpeciesForm().formIndex).toBe(enemy.getSpeciesForm().formIndex); + }); }); diff --git a/test/abilities/lightningrod.test.ts b/test/abilities/lightningrod.test.ts index 1ca6c6b1e89..986899353ff 100644 --- a/test/abilities/lightningrod.test.ts +++ b/test/abilities/lightningrod.test.ts @@ -24,7 +24,7 @@ describe("Abilities - Lightningrod", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([ Moves.SPLASH, Moves.SHOCK_WAVE ]) + .moveset([Moves.SPLASH, Moves.SHOCK_WAVE]) .ability(Abilities.BALL_FETCH) .battleType("double") .disableCrits() @@ -34,7 +34,7 @@ describe("Abilities - Lightningrod", () => { }); it("should redirect electric type moves", async () => { - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -49,8 +49,8 @@ describe("Abilities - Lightningrod", () => { }); it("should not redirect non-electric type moves", async () => { - game.override.moveset([ Moves.SPLASH, Moves.AERIAL_ACE ]); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + game.override.moveset([Moves.SPLASH, Moves.AERIAL_ACE]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -65,7 +65,7 @@ describe("Abilities - Lightningrod", () => { }); it("should boost the user's spatk without damaging", async () => { - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy2 = game.scene.getEnemyField()[1]; @@ -81,7 +81,7 @@ describe("Abilities - Lightningrod", () => { it("should not redirect moves changed from electric type via ability", async () => { game.override.ability(Abilities.NORMALIZE); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -96,9 +96,8 @@ describe("Abilities - Lightningrod", () => { }); it("should redirect moves changed to electric type via ability", async () => { - game.override.ability(Abilities.GALVANIZE) - .moveset(Moves.TACKLE); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + game.override.ability(Abilities.GALVANIZE).moveset(Moves.TACKLE); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; diff --git a/test/abilities/neutralizing_gas.test.ts b/test/abilities/neutralizing_gas.test.ts index 08ab884d806..a10a246d855 100644 --- a/test/abilities/neutralizing_gas.test.ts +++ b/test/abilities/neutralizing_gas.test.ts @@ -1,4 +1,6 @@ import { BattlerIndex } from "#app/battle"; +import type { CommandPhase } from "#app/phases/command-phase"; +import { Command } from "#app/ui/command-ui-handler"; import { PostSummonWeatherChangeAbAttr } from "#app/data/ability"; import { Abilities } from "#enums/abilities"; import { ArenaTagType } from "#enums/arena-tag-type"; @@ -157,12 +159,23 @@ describe("Abilities - Neutralizing Gas", () => { expect(game.scene.arena.getTag(ArenaTagType.NEUTRALIZING_GAS)).toBeUndefined(); }); + it("should deactivate after fleeing from a wild pokemon", async () => { + game.override.enemyAbility(Abilities.NEUTRALIZING_GAS).ability(Abilities.BALL_FETCH); + await game.classicMode.startBattle([Species.MAGIKARP]); + expect(game.scene.arena.getTag(ArenaTagType.NEUTRALIZING_GAS)).toBeDefined(); + + vi.spyOn(game.scene.getPlayerPokemon()!, "randSeedInt").mockReturnValue(0); + + const commandPhase = game.scene.getCurrentPhase() as CommandPhase; + commandPhase.handleCommand(Command.RUN, 0); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.arena.getTag(ArenaTagType.NEUTRALIZING_GAS)).toBeUndefined(); + }); + it("should not activate abilities of pokemon no longer on the field", async () => { - game.override - .battleType("single") - .ability(Abilities.NEUTRALIZING_GAS) - .enemyAbility(Abilities.DELTA_STREAM); - await game.classicMode.startBattle([ Species.MAGIKARP ]); + game.override.battleType("single").ability(Abilities.NEUTRALIZING_GAS).enemyAbility(Abilities.DELTA_STREAM); + await game.classicMode.startBattle([Species.MAGIKARP]); const enemy = game.scene.getEnemyPokemon()!; const weatherChangeAttr = enemy.getAbilityAttrs(PostSummonWeatherChangeAbAttr, false)[0]; diff --git a/test/abilities/parental_bond.test.ts b/test/abilities/parental_bond.test.ts index 2aa24e78d6e..d4bf544e8c7 100644 --- a/test/abilities/parental_bond.test.ts +++ b/test/abilities/parental_bond.test.ts @@ -9,6 +9,7 @@ import { StatusEffect } from "#enums/status-effect"; import GameManager from "#test/testUtils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { BattlerIndex } from "#app/battle"; describe("Abilities - Parental Bond", () => { let phaserGame: Phaser.Game; @@ -426,4 +427,21 @@ describe("Abilities - Parental Bond", () => { // TODO: Update hit count to 1 once Future Sight is fixed to not activate abilities if user is off the field expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(2); }); + + it("should not allow Pollen Puff to heal ally more than once", async () => { + game.override.battleType("double").moveset([Moves.POLLEN_PUFF, Moves.ENDURE]); + await game.classicMode.startBattle([Species.BULBASAUR, Species.OMANYTE]); + + const [, rightPokemon] = game.scene.getPlayerField(); + + rightPokemon.damageAndUpdate(rightPokemon.hp - 1); + + game.move.select(Moves.POLLEN_PUFF, 0, BattlerIndex.PLAYER_2); + game.move.select(Moves.ENDURE, 1); + + await game.toNextTurn(); + + // Pollen Puff heals with a ratio of 0.5, as long as Pollen Puff triggers only once the pokemon will always be <= (0.5 * Max HP) + 1 + expect(rightPokemon.hp).toBeLessThanOrEqual(0.5 * rightPokemon.getMaxHp() + 1); + }); }); diff --git a/test/abilities/protosynthesis.test.ts b/test/abilities/protosynthesis.test.ts index d0ae46cd951..882474b7cef 100644 --- a/test/abilities/protosynthesis.test.ts +++ b/test/abilities/protosynthesis.test.ts @@ -46,16 +46,56 @@ describe("Abilities - Protosynthesis", () => { // Nature of starting mon is randomized. We need to fix it to a neutral nature for the automated test. mew.setNature(Nature.HARDY); const enemy = game.scene.getEnemyPokemon()!; - const def_before_boost = mew.getEffectiveStat(Stat.DEF, undefined, undefined, false, undefined, false, false, true); - const atk_before_boost = mew.getEffectiveStat(Stat.ATK, undefined, undefined, false, undefined, false, false, true); + const def_before_boost = mew.getEffectiveStat( + Stat.DEF, + undefined, + undefined, + false, + undefined, + undefined, + false, + false, + true, + ); + const atk_before_boost = mew.getEffectiveStat( + Stat.ATK, + undefined, + undefined, + false, + undefined, + undefined, + false, + false, + true, + ); const initialHp = enemy.hp; game.move.select(Moves.TACKLE); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.toNextTurn(); const unboosted_dmg = initialHp - enemy.hp; enemy.hp = initialHp; - const def_after_boost = mew.getEffectiveStat(Stat.DEF, undefined, undefined, false, undefined, false, false, true); - const atk_after_boost = mew.getEffectiveStat(Stat.ATK, undefined, undefined, false, undefined, false, false, true); + const def_after_boost = mew.getEffectiveStat( + Stat.DEF, + undefined, + undefined, + false, + undefined, + undefined, + false, + false, + true, + ); + const atk_after_boost = mew.getEffectiveStat( + Stat.ATK, + undefined, + undefined, + false, + undefined, + undefined, + false, + false, + true, + ); game.move.select(Moves.TACKLE); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.toNextTurn(); diff --git a/test/abilities/steely_spirit.test.ts b/test/abilities/steely_spirit.test.ts index 9b4d32efcae..b180ff8919e 100644 --- a/test/abilities/steely_spirit.test.ts +++ b/test/abilities/steely_spirit.test.ts @@ -12,7 +12,8 @@ describe("Abilities - Steely Spirit", () => { let game: GameManager; const steelySpiritMultiplier = 1.5; const moveToCheck = Moves.IRON_HEAD; - const ironHeadPower = allMoves[moveToCheck].power; + + let ironHeadPower: number; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -25,6 +26,7 @@ describe("Abilities - Steely Spirit", () => { }); beforeEach(() => { + ironHeadPower = allMoves[moveToCheck].power; game = new GameManager(phaserGame); game.override.battleType("double"); game.override.enemySpecies(Species.SHUCKLE); diff --git a/test/abilities/storm_drain.test.ts b/test/abilities/storm_drain.test.ts index e2a7b3e212e..58ff477fa43 100644 --- a/test/abilities/storm_drain.test.ts +++ b/test/abilities/storm_drain.test.ts @@ -24,7 +24,7 @@ describe("Abilities - Storm Drain", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([ Moves.SPLASH, Moves.WATER_GUN ]) + .moveset([Moves.SPLASH, Moves.WATER_GUN]) .ability(Abilities.BALL_FETCH) .battleType("double") .disableCrits() @@ -34,7 +34,7 @@ describe("Abilities - Storm Drain", () => { }); it("should redirect water type moves", async () => { - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -49,8 +49,8 @@ describe("Abilities - Storm Drain", () => { }); it("should not redirect non-water type moves", async () => { - game.override.moveset([ Moves.SPLASH, Moves.AERIAL_ACE ]); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + game.override.moveset([Moves.SPLASH, Moves.AERIAL_ACE]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -65,7 +65,7 @@ describe("Abilities - Storm Drain", () => { }); it("should boost the user's spatk without damaging", async () => { - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy2 = game.scene.getEnemyField()[1]; @@ -81,7 +81,7 @@ describe("Abilities - Storm Drain", () => { it("should not redirect moves changed from water type via ability", async () => { game.override.ability(Abilities.NORMALIZE); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -96,9 +96,8 @@ describe("Abilities - Storm Drain", () => { }); it("should redirect moves changed to water type via ability", async () => { - game.override.ability(Abilities.LIQUID_VOICE) - .moveset(Moves.PSYCHIC_NOISE); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + game.override.ability(Abilities.LIQUID_VOICE).moveset(Moves.PSYCHIC_NOISE); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; diff --git a/test/abilities/supreme_overlord.test.ts b/test/abilities/supreme_overlord.test.ts index b70acbd8d17..a71bf0a9354 100644 --- a/test/abilities/supreme_overlord.test.ts +++ b/test/abilities/supreme_overlord.test.ts @@ -1,4 +1,5 @@ import { Moves } from "#app/enums/moves"; +import type Move from "#app/data/moves/move"; import { Abilities } from "#enums/abilities"; import { Species } from "#enums/species"; import { BattlerIndex } from "#app/battle"; @@ -12,8 +13,8 @@ describe("Abilities - Supreme Overlord", () => { let phaserGame: Phaser.Game; let game: GameManager; - const move = allMoves[Moves.TACKLE]; - const basePower = move.power; + let move: Move; + let basePower: number; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -26,6 +27,8 @@ describe("Abilities - Supreme Overlord", () => { }); beforeEach(() => { + move = allMoves[Moves.TACKLE]; + basePower = move.power; game = new GameManager(phaserGame); game.override .battleType("single") diff --git a/test/abilities/unseen_fist.test.ts b/test/abilities/unseen_fist.test.ts index 73ae25ff3b0..459bb00628c 100644 --- a/test/abilities/unseen_fist.test.ts +++ b/test/abilities/unseen_fist.test.ts @@ -32,22 +32,22 @@ describe("Abilities - Unseen Fist", () => { game.override.enemyLevel(100); }); - it("should cause a contact move to ignore Protect", () => - testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, true)); + it("should cause a contact move to ignore Protect", async () => + await testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, true)); - it("should not cause a non-contact move to ignore Protect", () => - testUnseenFistHitResult(game, Moves.ABSORB, Moves.PROTECT, false)); + it("should not cause a non-contact move to ignore Protect", async () => + await testUnseenFistHitResult(game, Moves.ABSORB, Moves.PROTECT, false)); it("should not apply if the source has Long Reach", async () => { game.override.passiveAbility(Abilities.LONG_REACH); await testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, false); }); - it("should cause a contact move to ignore Wide Guard", () => - testUnseenFistHitResult(game, Moves.BREAKING_SWIPE, Moves.WIDE_GUARD, true)); + it("should cause a contact move to ignore Wide Guard", async () => + await testUnseenFistHitResult(game, Moves.BREAKING_SWIPE, Moves.WIDE_GUARD, true)); - it("should not cause a non-contact move to ignore Wide Guard", () => - testUnseenFistHitResult(game, Moves.BULLDOZE, Moves.WIDE_GUARD, false)); + it("should not cause a non-contact move to ignore Wide Guard", async () => + await testUnseenFistHitResult(game, Moves.BULLDOZE, Moves.WIDE_GUARD, false)); it("should cause a contact move to ignore Protect, but not Substitute", async () => { game.override.enemyLevel(1); diff --git a/test/abilities/victory_star.test.ts b/test/abilities/victory_star.test.ts new file mode 100644 index 00000000000..92db522871a --- /dev/null +++ b/test/abilities/victory_star.test.ts @@ -0,0 +1,60 @@ +import { BattlerIndex } from "#app/battle"; +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/testUtils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Abilities - Victory Star", () => { + 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.SPLASH]) + .battleType("double") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should increase the accuracy of its user", async () => { + await game.classicMode.startBattle([Species.VICTINI, Species.MAGIKARP]); + + const user = game.scene.getPlayerField()[0]; + + vi.spyOn(user, "getAccuracyMultiplier"); + game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.SPLASH, 1); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(user.getAccuracyMultiplier).toHaveReturnedWith(1.1); + }); + + it("should increase the accuracy of its user's ally", async () => { + await game.classicMode.startBattle([Species.MAGIKARP, Species.VICTINI]); + + const ally = game.scene.getPlayerField()[0]; + vi.spyOn(ally, "getAccuracyMultiplier"); + + game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY); + game.move.select(Moves.SPLASH, 1); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(ally.getAccuracyMultiplier).toHaveReturnedWith(1.1); + }); +}); diff --git a/test/abilities/wonder_skin.test.ts b/test/abilities/wonder_skin.test.ts index f2cb0faed72..18d5be36aef 100644 --- a/test/abilities/wonder_skin.test.ts +++ b/test/abilities/wonder_skin.test.ts @@ -1,4 +1,3 @@ -import { allAbilities } from "#app/data/ability"; import { allMoves } from "#app/data/moves/move"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { Abilities } from "#enums/abilities"; @@ -56,16 +55,21 @@ describe("Abilities - Wonder Skin", () => { expect(moveToCheck.calculateBattleAccuracy).toHaveReturnedWith(100); }); - const bypassAbilities = [Abilities.MOLD_BREAKER, Abilities.TERAVOLT, Abilities.TURBOBLAZE]; + const bypassAbilities = [ + [Abilities.MOLD_BREAKER, "Mold Breaker"], + [Abilities.TERAVOLT, "Teravolt"], + [Abilities.TURBOBLAZE, "Turboblaze"], + ]; bypassAbilities.forEach(ability => { - it(`does not affect pokemon with ${allAbilities[ability].name}`, async () => { + it(`does not affect pokemon with ${ability[1]}`, async () => { const moveToCheck = allMoves[Moves.CHARM]; - game.override.ability(ability); + // @ts-ignore ts doesn't know that ability[0] is an ability and not a string... + game.override.ability(ability[0]); vi.spyOn(moveToCheck, "calculateBattleAccuracy"); - await game.startBattle([Species.PIKACHU]); + await game.classicMode.startBattle([Species.PIKACHU]); game.move.select(Moves.CHARM); await game.phaseInterceptor.to(MoveEffectPhase); diff --git a/test/achievements/achievement.test.ts b/test/achievements/achievement.test.ts index 26d33adb00a..5c53e38e208 100644 --- a/test/achievements/achievement.test.ts +++ b/test/achievements/achievement.test.ts @@ -14,7 +14,7 @@ import { NumberHolder } from "#app/utils"; import GameManager from "#test/testUtils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import BattleScene from "#app/battle-scene"; +import type BattleScene from "#app/battle-scene"; describe("check some Achievement related stuff", () => { it("should check Achievement creation", () => { @@ -77,6 +77,25 @@ describe("Achv", () => { }); describe("MoneyAchv", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + let scene: BattleScene; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + scene = game.scene; + }); + it("should create an instance of MoneyAchv", () => { const moneyAchv = new MoneyAchv("", "Test Money Achievement", 10000, "money_icon", 10); expect(moneyAchv).toBeInstanceOf(MoneyAchv); @@ -85,7 +104,6 @@ describe("MoneyAchv", () => { it("should validate the achievement based on the money amount", () => { const moneyAchv = new MoneyAchv("", "Test Money Achievement", 10000, "money_icon", 10); - const scene = new BattleScene(); scene.money = 5000; expect(moneyAchv.validate([])).toBe(false); diff --git a/test/battlerTags/substitute.test.ts b/test/battlerTags/substitute.test.ts index e80453d2933..fca3dc5ef7e 100644 --- a/test/battlerTags/substitute.test.ts +++ b/test/battlerTags/substitute.test.ts @@ -1,22 +1,40 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import type { PokemonTurnData, TurnMove, PokemonMove } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; import { MoveResult } from "#app/field/pokemon"; -import BattleScene from "#app/battle-scene"; +import type BattleScene from "#app/battle-scene"; import { BattlerTagLapseType, BindTag, SubstituteTag } from "#app/data/battler-tags"; import { Moves } from "#app/enums/moves"; import { PokemonAnimType } from "#app/enums/pokemon-anim-type"; import * as messages from "#app/messages"; import { allMoves } from "#app/data/moves/move"; import type { MoveEffectPhase } from "#app/phases/move-effect-phase"; +import GameManager from "#test/testUtils/gameManager"; describe("BattlerTag - SubstituteTag", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + }); + let mockPokemon: Pokemon; describe("onAdd behavior", () => { beforeEach(() => { mockPokemon = { - scene: new BattleScene(), + scene: game.scene, hp: 101, id: 0, getMaxHp: vi.fn().mockReturnValue(101) as Pokemon["getMaxHp"], @@ -77,7 +95,7 @@ describe("BattlerTag - SubstituteTag", () => { describe("onRemove behavior", () => { beforeEach(() => { mockPokemon = { - scene: new BattleScene(), + scene: game.scene, hp: 101, id: 0, isFainted: vi.fn().mockReturnValue(false) as Pokemon["isFainted"], @@ -109,7 +127,7 @@ describe("BattlerTag - SubstituteTag", () => { describe("lapse behavior", () => { beforeEach(() => { mockPokemon = { - scene: new BattleScene(), + scene: game.scene, hp: 101, id: 0, turnData: { acted: true } as PokemonTurnData, diff --git a/test/data/splash_messages.test.ts b/test/data/splash_messages.test.ts index 8ae13366670..773b2715825 100644 --- a/test/data/splash_messages.test.ts +++ b/test/data/splash_messages.test.ts @@ -7,10 +7,10 @@ describe("Data - Splash Messages", () => { expect(getSplashMessages().length).toBeGreaterThanOrEqual(15); }); - // make sure to adjust this test if the weight it changed! - it("should add contain 10 `battlesWon` splash messages", () => { + // Make sure to adjust this test if the weight is changed! + it("should add contain 15 `battlesWon` splash messages", () => { const battlesWonMessages = getSplashMessages().filter(message => message === "splashMessages:battlesWon"); - expect(battlesWonMessages).toHaveLength(10); + expect(battlesWonMessages).toHaveLength(15); }); describe("Seasonal", () => { @@ -22,16 +22,24 @@ describe("Data - Splash Messages", () => { vi.useRealTimers(); // reset system time }); - it("should contain halloween messages from Sep 15 to Oct 31", () => { - testSeason(new Date("2024-09-15"), new Date("2024-10-31"), "halloween"); + it("should contain new years messages from Jan 1 to Jan 15", () => { + testSeason(new Date("2025-01-01"), new Date("2025-01-15"), "newYears"); }); - it("should contain xmas messages from Dec 1 to Dec 26", () => { - testSeason(new Date("2024-12-01"), new Date("2024-12-26"), "xmas"); + it("should contain valentines messages from Feb 7 to Feb 21", () => { + testSeason(new Date("2025-02-07"), new Date("2025-02-21"), "valentines"); }); - it("should contain new years messages frm Jan 1 to Jan 31", () => { - testSeason(new Date("2024-01-01"), new Date("2024-01-31"), "newYears"); + it("should contain april fools messages from April 1 to April 3", () => { + testSeason(new Date("2025-04-01"), new Date("2025-04-03"), "aprilFools"); + }); + + it("should contain halloween messages from Oct 15 to Oct 31", () => { + testSeason(new Date("2025-10-15"), new Date("2025-10-31"), "halloween"); + }); + + it("should contain winter holiday messages from Dec 1 to Dec 31", () => { + testSeason(new Date("2025-12-01"), new Date("2025-12-31"), "winterHoliday"); }); }); }); diff --git a/test/data/status_effect.test.ts b/test/data/status_effect.test.ts index 61dafc1c9b8..0fd2daa308b 100644 --- a/test/data/status_effect.test.ts +++ b/test/data/status_effect.test.ts @@ -13,17 +13,12 @@ import { Species } from "#enums/species"; import { StatusEffect } from "#enums/status-effect"; import GameManager from "#test/testUtils/gameManager"; import { mockI18next } from "#test/testUtils/testUtils"; -import i18next from "i18next"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const pokemonName = "PKM"; const sourceText = "SOURCE"; describe("Status Effect Messages", () => { - beforeAll(async () => { - await i18next.init(); - }); - describe("NONE", () => { const statusEffect = StatusEffect.NONE; @@ -31,7 +26,6 @@ describe("Status Effect Messages", () => { mockI18next(); const text = getStatusEffectObtainText(statusEffect, pokemonName); - console.log("text:", text); expect(text).toBe(""); const emptySourceText = getStatusEffectObtainText(statusEffect, pokemonName, ""); diff --git a/test/items/grip_claw.test.ts b/test/items/grip_claw.test.ts index 1d169006116..aa7c23ca43d 100644 --- a/test/items/grip_claw.test.ts +++ b/test/items/grip_claw.test.ts @@ -98,6 +98,31 @@ describe("Items - Grip Claw", () => { expect(enemy1HeldItemCountsAfter).toBe(enemy1HeldItemCount); expect(enemy2HeldItemCountsAfter).toBe(enemy2HeldItemCount); }); + + it("should not allow Pollen Puff to steal items when healing ally", async () => { + game.override + .battleType("double") + .moveset([Moves.POLLEN_PUFF, Moves.ENDURE]) + .startingHeldItems([ + { name: "GRIP_CLAW", count: 1 }, + { name: "BERRY", type: BerryType.LUM, count: 1 }, + ]); + await game.classicMode.startBattle([Species.BULBASAUR, Species.OMANYTE]); + + const [leftPokemon, rightPokemon] = game.scene.getPlayerField(); + + const gripClaw = leftPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier; + vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100); + + const heldItemCountBefore = getHeldItemCount(rightPokemon); + + game.move.select(Moves.POLLEN_PUFF, 0, BattlerIndex.PLAYER_2); + game.move.select(Moves.ENDURE, 1); + + await game.toNextTurn(); + + expect(getHeldItemCount(rightPokemon)).toBe(heldItemCountBefore); + }); }); /* diff --git a/test/items/multi_lens.test.ts b/test/items/multi_lens.test.ts index 90e73ae88ea..176e8213f55 100644 --- a/test/items/multi_lens.test.ts +++ b/test/items/multi_lens.test.ts @@ -211,4 +211,21 @@ describe("Items - Multi Lens", () => { // TODO: Update hit count to 1 once Future Sight is fixed to not activate held items if user is off the field expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(2); }); + + it("should not allow Pollen Puff to heal ally more than once", async () => { + game.override.battleType("double").moveset([Moves.POLLEN_PUFF, Moves.ENDURE]); + await game.classicMode.startBattle([Species.BULBASAUR, Species.OMANYTE]); + + const [, rightPokemon] = game.scene.getPlayerField(); + + rightPokemon.damageAndUpdate(rightPokemon.hp - 1); + + game.move.select(Moves.POLLEN_PUFF, 0, BattlerIndex.PLAYER_2); + game.move.select(Moves.ENDURE, 1); + + await game.toNextTurn(); + + // Pollen Puff heals with a ratio of 0.5, as long as Pollen Puff triggers only once the pokemon will always be <= (0.5 * Max HP) + 1 + expect(rightPokemon.hp).toBeLessThanOrEqual(0.5 * rightPokemon.getMaxHp() + 1); + }); }); diff --git a/test/items/mystical_rock.test.ts b/test/items/mystical_rock.test.ts new file mode 100644 index 00000000000..0558bc21fe1 --- /dev/null +++ b/test/items/mystical_rock.test.ts @@ -0,0 +1,60 @@ +import { globalScene } from "#app/global-scene"; +import { Moves } from "#enums/moves"; +import { Abilities } from "#enums/abilities"; +import { Species } from "#enums/species"; +import GameManager from "#test/testUtils/gameManager"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Items - Mystical Rock", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phase.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override + .enemySpecies(Species.SHUCKLE) + .enemyMoveset(Moves.SPLASH) + .enemyAbility(Abilities.BALL_FETCH) + .moveset([Moves.SUNNY_DAY, Moves.GRASSY_TERRAIN]) + .startingHeldItems([{ name: "MYSTICAL_ROCK", count: 2 }]) + .battleType("single"); + }); + + it("should increase weather duration by +2 turns per stack", async () => { + await game.classicMode.startBattle([Species.GASTLY]); + + game.move.select(Moves.SUNNY_DAY); + + await game.phaseInterceptor.to("MoveEndPhase"); + + const weather = globalScene.arena.weather; + + expect(weather).toBeDefined(); + expect(weather!.turnsLeft).to.equal(9); + }); + + it("should increase terrain duration by +2 turns per stack", async () => { + await game.classicMode.startBattle([Species.GASTLY]); + + game.move.select(Moves.GRASSY_TERRAIN); + + await game.phaseInterceptor.to("MoveEndPhase"); + + const terrain = globalScene.arena.terrain; + + expect(terrain).toBeDefined(); + expect(terrain!.turnsLeft).to.equal(9); + }); +}); diff --git a/test/items/reviver_seed.test.ts b/test/items/reviver_seed.test.ts new file mode 100644 index 00000000000..c06f354a94a --- /dev/null +++ b/test/items/reviver_seed.test.ts @@ -0,0 +1,153 @@ +import { BattlerIndex } from "#app/battle"; +import { allMoves } from "#app/data/moves/move"; +import { BattlerTagType } from "#app/enums/battler-tag-type"; +import type { PokemonInstantReviveModifier } from "#app/modifier/modifier"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/testUtils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Items - Reviver Seed", () => { + 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, Moves.TACKLE, Moves.ENDURE]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .startingHeldItems([{ name: "REVIVER_SEED" }]) + .enemyHeldItems([{ name: "REVIVER_SEED" }]) + .enemyMoveset(Moves.SPLASH); + vi.spyOn(allMoves[Moves.SHEER_COLD], "accuracy", "get").mockReturnValue(100); + vi.spyOn(allMoves[Moves.LEECH_SEED], "accuracy", "get").mockReturnValue(100); + vi.spyOn(allMoves[Moves.WHIRLPOOL], "accuracy", "get").mockReturnValue(100); + vi.spyOn(allMoves[Moves.WILL_O_WISP], "accuracy", "get").mockReturnValue(100); + }); + + it.each([ + { moveType: "Special Move", move: Moves.WATER_GUN }, + { moveType: "Physical Move", move: Moves.TACKLE }, + { moveType: "Fixed Damage Move", move: Moves.SEISMIC_TOSS }, + { moveType: "Final Gambit", move: Moves.FINAL_GAMBIT }, + { moveType: "Counter", move: Moves.COUNTER }, + { moveType: "OHKO", move: Moves.SHEER_COLD }, + ])("should activate the holder's reviver seed from a $moveType", async ({ move }) => { + game.override.enemyLevel(100).startingLevel(1).enemyMoveset(move); + await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); + const player = game.scene.getPlayerPokemon()!; + player.damageAndUpdate(player.hp - 1); + + const reviverSeed = player.getHeldItems()[0] as PokemonInstantReviveModifier; + vi.spyOn(reviverSeed, "apply"); + + game.move.select(Moves.TACKLE); + await game.phaseInterceptor.to("BerryPhase"); + + expect(player.isFainted()).toBeFalsy(); + }); + + it("should activate the holder's reviver seed from confusion self-hit", async () => { + game.override.enemyLevel(1).startingLevel(100).enemyMoveset(Moves.SPLASH); + await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); + const player = game.scene.getPlayerPokemon()!; + player.damageAndUpdate(player.hp - 1); + player.addTag(BattlerTagType.CONFUSED, 3); + + const reviverSeed = player.getHeldItems()[0] as PokemonInstantReviveModifier; + vi.spyOn(reviverSeed, "apply"); + + vi.spyOn(player, "randSeedInt").mockReturnValue(0); // Force confusion self-hit + game.move.select(Moves.TACKLE); + await game.phaseInterceptor.to("BerryPhase"); + + expect(player.isFainted()).toBeFalsy(); + }); + + // Damaging opponents tests + it.each([ + { moveType: "Damaging Move Chip Damage", move: Moves.SALT_CURE }, + { moveType: "Chip Damage", move: Moves.LEECH_SEED }, + { moveType: "Trapping Chip Damage", move: Moves.WHIRLPOOL }, + { moveType: "Status Effect Damage", move: Moves.WILL_O_WISP }, + { moveType: "Weather", move: Moves.SANDSTORM }, + ])("should not activate the holder's reviver seed from $moveType", async ({ move }) => { + game.override + .enemyLevel(1) + .startingLevel(100) + .enemySpecies(Species.MAGIKARP) + .moveset(move) + .enemyMoveset(Moves.ENDURE); + await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); + const enemy = game.scene.getEnemyPokemon()!; + enemy.damageAndUpdate(enemy.hp - 1); + + game.move.select(move); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(enemy.isFainted()).toBeTruthy(); + }); + + // Self-damage tests + it.each([ + { moveType: "Recoil", move: Moves.DOUBLE_EDGE }, + { moveType: "Self-KO", move: Moves.EXPLOSION }, + { moveType: "Self-Deduction", move: Moves.CURSE }, + { moveType: "Liquid Ooze", move: Moves.GIGA_DRAIN }, + ])("should not activate the holder's reviver seed from $moveType", async ({ move }) => { + game.override + .enemyLevel(100) + .startingLevel(1) + .enemySpecies(Species.MAGIKARP) + .moveset(move) + .enemyAbility(Abilities.LIQUID_OOZE) + .enemyMoveset(Moves.SPLASH); + await game.classicMode.startBattle([Species.GASTLY, Species.FEEBAS]); + const player = game.scene.getPlayerPokemon()!; + player.damageAndUpdate(player.hp - 1); + + const playerSeed = player.getHeldItems()[0] as PokemonInstantReviveModifier; + vi.spyOn(playerSeed, "apply"); + + game.move.select(move); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(player.isFainted()).toBeTruthy(); + }); + + it("should not activate the holder's reviver seed from Destiny Bond fainting", async () => { + game.override + .enemyLevel(100) + .startingLevel(1) + .enemySpecies(Species.MAGIKARP) + .moveset(Moves.DESTINY_BOND) + .startingHeldItems([]) // reset held items to nothing so user doesn't revive and not trigger Destiny Bond + .enemyMoveset(Moves.TACKLE); + await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); + const player = game.scene.getPlayerPokemon()!; + player.damageAndUpdate(player.hp - 1); + const enemy = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.DESTINY_BOND); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(enemy.isFainted()).toBeTruthy(); + }); +}); diff --git a/test/moves/chilly_reception.test.ts b/test/moves/chilly_reception.test.ts index f90aaf6bb02..39342a921b6 100644 --- a/test/moves/chilly_reception.test.ts +++ b/test/moves/chilly_reception.test.ts @@ -27,8 +27,8 @@ describe("Moves - Chilly Reception", () => { .battleType("single") .moveset([Moves.CHILLY_RECEPTION, Moves.SNOWSCAPE]) .enemyMoveset(Array(4).fill(Moves.SPLASH)) - .enemyAbility(Abilities.NONE) - .ability(Abilities.NONE); + .enemyAbility(Abilities.BALL_FETCH) + .ability(Abilities.BALL_FETCH); }); it("should still change the weather if user can't switch out", async () => { @@ -72,7 +72,6 @@ describe("Moves - Chilly Reception", () => { game.override .battleType("single") .enemyMoveset([Moves.CHILLY_RECEPTION, Moves.TACKLE]) - .enemyAbility(Abilities.NONE) .moveset(Array(4).fill(Moves.SPLASH)); await game.classicMode.startBattle([Species.SLOWKING, Species.MEOWTH]); @@ -89,7 +88,6 @@ describe("Moves - Chilly Reception", () => { .battleType("single") .startingWave(8) .enemyMoveset(Array(4).fill(Moves.CHILLY_RECEPTION)) - .enemyAbility(Abilities.NONE) .enemySpecies(Species.MAGIKARP) .moveset([Moves.SPLASH, Moves.THUNDERBOLT]); diff --git a/test/moves/copycat.test.ts b/test/moves/copycat.test.ts index c7242f0940e..0d9b0951f89 100644 --- a/test/moves/copycat.test.ts +++ b/test/moves/copycat.test.ts @@ -13,7 +13,7 @@ describe("Moves - Copycat", () => { let phaserGame: Phaser.Game; let game: GameManager; - const randomMoveAttr = allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0]; + let randomMoveAttr: RandomMoveAttr; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -26,6 +26,7 @@ describe("Moves - Copycat", () => { }); beforeEach(() => { + randomMoveAttr = allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0]; game = new GameManager(phaserGame); game.override .moveset([Moves.COPYCAT, Moves.SPIKY_SHIELD, Moves.SWORDS_DANCE, Moves.SPLASH]) diff --git a/test/moves/dive.test.ts b/test/moves/dive.test.ts index 8d7b0f9dd00..d7b53701a25 100644 --- a/test/moves/dive.test.ts +++ b/test/moves/dive.test.ts @@ -120,7 +120,7 @@ describe("Moves - Dive", () => { await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnStartPhase", false); - game.scene.arena.trySetWeather(WeatherType.HARSH_SUN, false); + game.scene.arena.trySetWeather(WeatherType.HARSH_SUN); await game.phaseInterceptor.to("MoveEndPhase"); expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); diff --git a/test/moves/dynamax_cannon.test.ts b/test/moves/dynamax_cannon.test.ts index 0ff0712710d..9cf3106b9c1 100644 --- a/test/moves/dynamax_cannon.test.ts +++ b/test/moves/dynamax_cannon.test.ts @@ -3,6 +3,7 @@ import { allMoves } from "#app/data/moves/move"; import { DamageAnimPhase } from "#app/phases/damage-anim-phase"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { Moves } from "#enums/moves"; +import type Move from "#app/data/moves/move"; import { Species } from "#enums/species"; import GameManager from "#test/testUtils/gameManager"; import Phaser from "phaser"; @@ -12,7 +13,7 @@ describe("Moves - Dynamax Cannon", () => { let phaserGame: Phaser.Game; let game: GameManager; - const dynamaxCannon = allMoves[Moves.DYNAMAX_CANNON]; + let dynamaxCannon: Move; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -25,6 +26,7 @@ describe("Moves - Dynamax Cannon", () => { }); beforeEach(() => { + dynamaxCannon = allMoves[Moves.DYNAMAX_CANNON]; game = new GameManager(phaserGame); game.override.moveset([dynamaxCannon.id]); diff --git a/test/moves/effectiveness.test.ts b/test/moves/effectiveness.test.ts index dc55392f8bf..fb03f1c10a0 100644 --- a/test/moves/effectiveness.test.ts +++ b/test/moves/effectiveness.test.ts @@ -1,6 +1,6 @@ import { allMoves } from "#app/data/moves/move"; import { getPokemonSpecies } from "#app/data/pokemon-species"; -import { TrainerSlot } from "#app/data/trainer-config"; +import { TrainerSlot } from "#enums/trainer-slot"; import { PokemonType } from "#enums/pokemon-type"; import { Abilities } from "#app/enums/abilities"; import { Moves } from "#app/enums/moves"; diff --git a/test/moves/endure.test.ts b/test/moves/endure.test.ts index 8151128479d..8fbb2272ece 100644 --- a/test/moves/endure.test.ts +++ b/test/moves/endure.test.ts @@ -22,7 +22,7 @@ describe("Moves - Endure", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.THUNDER, Moves.BULLET_SEED, Moves.TOXIC]) + .moveset([Moves.THUNDER, Moves.BULLET_SEED, Moves.TOXIC, Moves.SHEER_COLD]) .ability(Abilities.SKILL_LINK) .startingLevel(100) .battleType("single") @@ -50,16 +50,37 @@ describe("Moves - Endure", () => { expect(game.scene.getEnemyPokemon()!.hp).toBe(1); }); - it("shouldn't prevent fainting from indirect damage", async () => { - game.override.enemyLevel(100); - await game.classicMode.startBattle([Species.ARCEUS]); - + it("should let the pokemon survive against OHKO moves", async () => { + await game.classicMode.startBattle([Species.MAGIKARP]); const enemy = game.scene.getEnemyPokemon()!; - enemy.hp = 2; - game.move.select(Moves.TOXIC); - await game.phaseInterceptor.to("VictoryPhase"); + game.move.select(Moves.SHEER_COLD); + await game.phaseInterceptor.to("TurnEndPhase"); - expect(enemy.isFainted()).toBe(true); + expect(enemy.isFainted()).toBeFalsy(); + }); + + // comprehensive indirect damage test copied from Reviver Seed test + it.each([ + { moveType: "Damaging Move Chip Damage", move: Moves.SALT_CURE }, + { moveType: "Chip Damage", move: Moves.LEECH_SEED }, + { moveType: "Trapping Chip Damage", move: Moves.WHIRLPOOL }, + { moveType: "Status Effect Damage", move: Moves.TOXIC }, + { moveType: "Weather", move: Moves.SANDSTORM }, + ])("should not prevent fainting from $moveType", async ({ move }) => { + game.override + .enemyLevel(1) + .startingLevel(100) + .enemySpecies(Species.MAGIKARP) + .moveset(move) + .enemyMoveset(Moves.ENDURE); + await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); + const enemy = game.scene.getEnemyPokemon()!; + enemy.damageAndUpdate(enemy.hp - 1); + + game.move.select(move); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(enemy.isFainted()).toBeTruthy(); }); }); diff --git a/test/moves/false_swipe.test.ts b/test/moves/false_swipe.test.ts new file mode 100644 index 00000000000..4fb5b81ef67 --- /dev/null +++ b/test/moves/false_swipe.test.ts @@ -0,0 +1,53 @@ +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/testUtils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - False Swipe", () => { + 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.FALSE_SWIPE]) + .ability(Abilities.BALL_FETCH) + .startingLevel(1000) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should reduce the target to 1 HP", async () => { + await game.classicMode.startBattle([Species.MILOTIC]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.FALSE_SWIPE); + await game.toNextTurn(); + game.move.select(Moves.FALSE_SWIPE); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy.hp).toBe(1); + const falseSwipeHistory = player + .getMoveHistory() + .every(turnMove => turnMove.move === Moves.FALSE_SWIPE && turnMove.result === MoveResult.SUCCESS); + expect(falseSwipeHistory).toBe(true); + }); +}); diff --git a/test/moves/fusion_flare_bolt.test.ts b/test/moves/fusion_flare_bolt.test.ts index 9a379cb4588..c340aeea63f 100644 --- a/test/moves/fusion_flare_bolt.test.ts +++ b/test/moves/fusion_flare_bolt.test.ts @@ -1,6 +1,7 @@ import { Stat } from "#enums/stat"; import { BattlerIndex } from "#app/battle"; import { allMoves } from "#app/data/moves/move"; +import type Move from "#app/data/moves/move"; import { DamageAnimPhase } from "#app/phases/damage-anim-phase"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { MoveEndPhase } from "#app/phases/move-end-phase"; @@ -15,8 +16,8 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { let phaserGame: Phaser.Game; let game: GameManager; - const fusionFlare = allMoves[Moves.FUSION_FLARE]; - const fusionBolt = allMoves[Moves.FUSION_BOLT]; + let fusionFlare: Move; + let fusionBolt: Move; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -29,6 +30,8 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { }); beforeEach(() => { + fusionFlare = allMoves[Moves.FUSION_FLARE]; + fusionBolt = allMoves[Moves.FUSION_BOLT]; game = new GameManager(phaserGame); game.override.moveset([fusionFlare.id, fusionBolt.id]); game.override.startingLevel(1); @@ -45,7 +48,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { }); it("FUSION_FLARE should double power of subsequent FUSION_BOLT", async () => { - await game.startBattle([Species.ZEKROM, Species.ZEKROM]); + await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]); game.move.select(fusionFlare.id, 0, BattlerIndex.ENEMY); game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY); @@ -65,7 +68,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { }, 20000); it("FUSION_BOLT should double power of subsequent FUSION_FLARE", async () => { - await game.startBattle([Species.ZEKROM, Species.ZEKROM]); + await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]); game.move.select(fusionBolt.id, 0, BattlerIndex.ENEMY); game.move.select(fusionFlare.id, 1, BattlerIndex.ENEMY); @@ -85,7 +88,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { }, 20000); it("FUSION_FLARE should double power of subsequent FUSION_BOLT if a move failed in between", async () => { - await game.startBattle([Species.ZEKROM, Species.ZEKROM]); + await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]); game.move.select(fusionFlare.id, 0, BattlerIndex.PLAYER); game.move.select(fusionBolt.id, 1, BattlerIndex.PLAYER); @@ -111,7 +114,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { 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]); - await game.startBattle([Species.ZEKROM, Species.ZEKROM]); + await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]); game.move.select(fusionFlare.id, 0, BattlerIndex.ENEMY); game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY); @@ -156,7 +159,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { 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]); - await game.startBattle([Species.ZEKROM, Species.ZEKROM]); + await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]); const party = game.scene.getPlayerParty(); const enemyParty = game.scene.getEnemyParty(); @@ -210,7 +213,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { 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]); - await game.startBattle([Species.ZEKROM, Species.ZEKROM]); + await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]); const party = game.scene.getPlayerParty(); const enemyParty = game.scene.getEnemyParty(); diff --git a/test/moves/grudge.test.ts b/test/moves/grudge.test.ts index ebd062a76ee..161fa38edd2 100644 --- a/test/moves/grudge.test.ts +++ b/test/moves/grudge.test.ts @@ -41,7 +41,7 @@ describe("Moves - Grudge", () => { await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.phaseInterceptor.to("BerryPhase"); - const playerMove = playerPokemon?.getMoveset().find(m => m?.moveId === Moves.EMBER); + const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === Moves.EMBER); expect(playerMove?.getPpRatio()).toBe(0); }); @@ -60,7 +60,7 @@ describe("Moves - Grudge", () => { await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.phaseInterceptor.to("BerryPhase"); - const playerMove = playerPokemon?.getMoveset().find(m => m?.moveId === Moves.EMBER); + const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === Moves.EMBER); expect(playerMove?.getPpRatio()).toBe(0); }); @@ -84,7 +84,7 @@ describe("Moves - Grudge", () => { expect(enemyPokemon?.isFainted()).toBe(true); - const playerMove = playerPokemon?.getMoveset().find(m => m?.moveId === Moves.FALSE_SWIPE); + const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === Moves.FALSE_SWIPE); expect(playerMove?.getPpRatio()).toBeGreaterThan(0); }); }); diff --git a/test/moves/hard_press.test.ts b/test/moves/hard_press.test.ts index 1bb6adc8e90..8891f0bf0e2 100644 --- a/test/moves/hard_press.test.ts +++ b/test/moves/hard_press.test.ts @@ -6,12 +6,13 @@ import { Species } from "#enums/species"; import GameManager from "#test/testUtils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import type Move from "#app/data/moves/move"; describe("Moves - Hard Press", () => { let phaserGame: Phaser.Game; let game: GameManager; - const moveToCheck = allMoves[Moves.HARD_PRESS]; + let moveToCheck: Move; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -24,6 +25,7 @@ describe("Moves - Hard Press", () => { }); beforeEach(() => { + moveToCheck = allMoves[Moves.HARD_PRESS]; game = new GameManager(phaserGame); game.override.battleType("single"); game.override.ability(Abilities.BALL_FETCH); diff --git a/test/moves/last_respects.test.ts b/test/moves/last_respects.test.ts index 57752cea1af..ccab8a43415 100644 --- a/test/moves/last_respects.test.ts +++ b/test/moves/last_respects.test.ts @@ -4,6 +4,7 @@ import { Species } from "#enums/species"; import { Abilities } from "#enums/abilities"; import GameManager from "#test/testUtils/gameManager"; import { allMoves } from "#app/data/moves/move"; +import type Move from "#app/data/moves/move"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -12,8 +13,8 @@ describe("Moves - Last Respects", () => { let phaserGame: Phaser.Game; let game: GameManager; - const move = allMoves[Moves.LAST_RESPECTS]; - const basePower = move.power; + let move: Move; + let basePower: number; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -27,6 +28,8 @@ describe("Moves - Last Respects", () => { beforeEach(() => { game = new GameManager(phaserGame); + move = allMoves[Moves.LAST_RESPECTS]; + basePower = move.power; game.override .battleType("single") .disableCrits() diff --git a/test/moves/metronome.test.ts b/test/moves/metronome.test.ts index 15790777ed3..80f32a3a6fb 100644 --- a/test/moves/metronome.test.ts +++ b/test/moves/metronome.test.ts @@ -13,7 +13,7 @@ describe("Moves - Metronome", () => { let phaserGame: Phaser.Game; let game: GameManager; - const randomMoveAttr = allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0]; + let randomMoveAttr: RandomMoveAttr; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -26,6 +26,7 @@ describe("Moves - Metronome", () => { }); beforeEach(() => { + randomMoveAttr = allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0]; game = new GameManager(phaserGame); game.override .moveset([Moves.METRONOME, Moves.SPLASH]) diff --git a/test/moves/rage_fist.test.ts b/test/moves/rage_fist.test.ts index 8bcb212d60e..f44901c5aba 100644 --- a/test/moves/rage_fist.test.ts +++ b/test/moves/rage_fist.test.ts @@ -3,6 +3,7 @@ import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { allMoves } from "#app/data/moves/move"; +import type Move from "#app/data/moves/move"; import GameManager from "#test/testUtils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -10,7 +11,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite describe("Moves - Rage Fist", () => { let phaserGame: Phaser.Game; let game: GameManager; - const move = allMoves[Moves.RAGE_FIST]; + let move: Move; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -23,6 +24,7 @@ describe("Moves - Rage Fist", () => { }); beforeEach(() => { + move = allMoves[Moves.RAGE_FIST]; game = new GameManager(phaserGame); game.override .battleType("single") diff --git a/test/moves/retaliate.test.ts b/test/moves/retaliate.test.ts index 5cc0b08ccc6..e916c9ffeaa 100644 --- a/test/moves/retaliate.test.ts +++ b/test/moves/retaliate.test.ts @@ -4,12 +4,13 @@ import GameManager from "#test/testUtils/gameManager"; import { Species } from "#enums/species"; import { Moves } from "#enums/moves"; import { allMoves } from "#app/data/moves/move"; +import type Move from "#app/data/moves/move"; describe("Moves - Retaliate", () => { let phaserGame: Phaser.Game; let game: GameManager; - const retaliate = allMoves[Moves.RETALIATE]; + let retaliate: Move; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -22,6 +23,7 @@ describe("Moves - Retaliate", () => { }); beforeEach(() => { + retaliate = allMoves[Moves.RETALIATE]; game = new GameManager(phaserGame); game.override .battleType("single") diff --git a/test/moves/revival_blessing.test.ts b/test/moves/revival_blessing.test.ts index 187b5e62e76..87be20f60ad 100644 --- a/test/moves/revival_blessing.test.ts +++ b/test/moves/revival_blessing.test.ts @@ -114,4 +114,21 @@ describe("Moves - Revival Blessing", () => { expect(feebas.hp).toBe(toDmgValue(0.5 * feebas.getMaxHp())); expect(game.scene.getPlayerField()[0]).toBe(feebas); }); + + it("should not summon multiple pokemon to the same slot when reviving the enemy ally in doubles", async () => { + game.override.battleType("double").enemyMoveset([Moves.REVIVAL_BLESSING]).moveset([Moves.SPLASH]).startingWave(25); // 2nd rival battle - must have 3+ pokemon + await game.classicMode.startBattle([Species.ARCEUS, Species.GIRATINA]); + + const enemyFainting = game.scene.getEnemyField()[0]; + + game.move.select(Moves.SPLASH, 0); + game.move.select(Moves.SPLASH, 1); + await game.killPokemon(enemyFainting); + + await game.phaseInterceptor.to("BerryPhase"); + await game.toNextTurn(); + // If there are incorrectly two switch phases into this slot, the fainted pokemon will end up in slot 3 + // Make sure it's still in slot 1 + expect(game.scene.getEnemyParty()[0]).toBe(enemyFainting); + }); }); diff --git a/test/moves/shell_side_arm.test.ts b/test/moves/shell_side_arm.test.ts index 47da5e1c2f7..a5b065b76cb 100644 --- a/test/moves/shell_side_arm.test.ts +++ b/test/moves/shell_side_arm.test.ts @@ -1,5 +1,6 @@ import { BattlerIndex } from "#app/battle"; import { allMoves, ShellSideArmCategoryAttr } from "#app/data/moves/move"; +import type Move from "#app/data/moves/move"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; @@ -10,8 +11,8 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite describe("Moves - Shell Side Arm", () => { let phaserGame: Phaser.Game; let game: GameManager; - const shellSideArm = allMoves[Moves.SHELL_SIDE_ARM]; - const shellSideArmAttr = shellSideArm.getAttrs(ShellSideArmCategoryAttr)[0]; + let shellSideArm: Move; + let shellSideArmAttr: ShellSideArmCategoryAttr; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -24,6 +25,8 @@ describe("Moves - Shell Side Arm", () => { }); beforeEach(() => { + shellSideArm = allMoves[Moves.SHELL_SIDE_ARM]; + shellSideArmAttr = shellSideArm.getAttrs(ShellSideArmCategoryAttr)[0]; game = new GameManager(phaserGame); game.override .moveset([Moves.SHELL_SIDE_ARM, Moves.SPLASH]) diff --git a/test/moves/spit_up.test.ts b/test/moves/spit_up.test.ts index d986ae4d141..d71647bda52 100644 --- a/test/moves/spit_up.test.ts +++ b/test/moves/spit_up.test.ts @@ -7,6 +7,7 @@ import { MoveResult } from "#app/field/pokemon"; import GameManager from "#test/testUtils/gameManager"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; +import type Move from "#app/data/moves/move"; import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -17,7 +18,7 @@ describe("Moves - Spit Up", () => { let phaserGame: Phaser.Game; let game: GameManager; - const spitUp = allMoves[Moves.SPIT_UP]; + let spitUp: Move; beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS }); @@ -28,6 +29,7 @@ describe("Moves - Spit Up", () => { }); beforeEach(() => { + spitUp = allMoves[Moves.SPIT_UP]; game = new GameManager(phaserGame); game.override.battleType("single"); diff --git a/test/moves/tailwind.test.ts b/test/moves/tailwind.test.ts index 24a7fa25061..591b94408ce 100644 --- a/test/moves/tailwind.test.ts +++ b/test/moves/tailwind.test.ts @@ -1,9 +1,9 @@ -import { Stat } from "#enums/stat"; import { ArenaTagSide } from "#app/data/arena-tag"; import { ArenaTagType } from "#app/enums/arena-tag-type"; -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/testUtils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -24,13 +24,16 @@ 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.enemyMoveset(Moves.SPLASH); + game.override + .battleType("double") + .moveset([Moves.TAILWIND, Moves.SPLASH]) + .enemyMoveset(Moves.SPLASH) + .enemyAbility(Abilities.BALL_FETCH) + .ability(Abilities.BALL_FETCH); }); it("doubles the Speed stat of the Pokemons on its side", async () => { - await game.startBattle([Species.MAGIKARP, Species.MEOWTH]); + await game.classicMode.startBattle([Species.MAGIKARP, Species.MEOWTH]); const magikarp = game.scene.getPlayerField()[0]; const meowth = game.scene.getPlayerField()[1]; @@ -43,7 +46,7 @@ describe("Moves - Tailwind", () => { game.move.select(Moves.TAILWIND); game.move.select(Moves.SPLASH, 1); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(magikarp.getEffectiveStat(Stat.SPD)).toBe(magikarpSpd * 2); expect(meowth.getEffectiveStat(Stat.SPD)).toBe(meowthSpd * 2); @@ -53,7 +56,7 @@ describe("Moves - Tailwind", () => { it("lasts for 4 turns", async () => { game.override.battleType("single"); - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([Species.MAGIKARP]); game.move.select(Moves.TAILWIND); await game.toNextTurn(); @@ -76,7 +79,7 @@ describe("Moves - Tailwind", () => { it("does not affect the opposing side", async () => { game.override.battleType("single"); - await game.startBattle([Species.MAGIKARP]); + await game.classicMode.startBattle([Species.MAGIKARP]); const ally = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; @@ -91,7 +94,7 @@ describe("Moves - Tailwind", () => { game.move.select(Moves.TAILWIND); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(ally.getEffectiveStat(Stat.SPD)).toBe(allySpd * 2); expect(enemy.getEffectiveStat(Stat.SPD)).equal(enemySpd); diff --git a/test/moves/tera_blast.test.ts b/test/moves/tera_blast.test.ts index dffe39f4d87..c1a2b999fa0 100644 --- a/test/moves/tera_blast.test.ts +++ b/test/moves/tera_blast.test.ts @@ -1,6 +1,7 @@ import { BattlerIndex } from "#app/battle"; import { Stat } from "#enums/stat"; import { allMoves, TeraMoveCategoryAttr } from "#app/data/moves/move"; +import type Move from "#app/data/moves/move"; import { PokemonType } from "#enums/pokemon-type"; import { Abilities } from "#app/enums/abilities"; import { HitResult } from "#app/field/pokemon"; @@ -13,13 +14,16 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite describe("Moves - Tera Blast", () => { let phaserGame: Phaser.Game; let game: GameManager; - const moveToCheck = allMoves[Moves.TERA_BLAST]; - const teraBlastAttr = moveToCheck.getAttrs(TeraMoveCategoryAttr)[0]; + + let moveToCheck: Move; + let teraBlastAttr: TeraMoveCategoryAttr; beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, }); + moveToCheck = allMoves[Moves.TERA_BLAST]; + teraBlastAttr = moveToCheck.getAttrs(TeraMoveCategoryAttr)[0]; }); afterEach(() => { diff --git a/test/moves/transform.test.ts b/test/moves/transform.test.ts index 5140202a383..d37decf28f4 100644 --- a/test/moves/transform.test.ts +++ b/test/moves/transform.test.ts @@ -6,6 +6,7 @@ import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { Moves } from "#enums/moves"; import { Stat, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat"; import { Abilities } from "#enums/abilities"; +import { BattlerIndex } from "#app/battle"; // TODO: Add more tests once Transform is fully implemented describe("Moves - Transform", () => { @@ -58,7 +59,7 @@ describe("Moves - Transform", () => { } const playerMoveset = player.getMoveset(); - const enemyMoveset = player.getMoveset(); + const enemyMoveset = enemy.getMoveset(); expect(playerMoveset.length).toBe(enemyMoveset.length); for (let i = 0; i < playerMoveset.length && i < enemyMoveset.length; i++) { @@ -127,4 +128,71 @@ describe("Moves - Transform", () => { expect(game.scene.getEnemyPokemon()?.getStatStage(Stat.ATK)).toBe(-1); }); + + it("should persist transformed attributes across reloads", async () => { + game.override.enemyMoveset([]).moveset([]); + + await game.classicMode.startBattle([Species.DITTO]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + game.move.changeMoveset(player, Moves.TRANSFORM); + game.move.changeMoveset(enemy, Moves.MEMENTO); + + game.move.select(Moves.TRANSFORM); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toNextWave(); + + expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase"); + expect(game.scene.currentBattle.waveIndex).toBe(2); + + await game.reload.reloadSession(); + + const playerReloaded = game.scene.getPlayerPokemon()!; + const playerMoveset = player.getMoveset(); + + expect(playerReloaded.getSpeciesForm().speciesId).toBe(enemy.getSpeciesForm().speciesId); + expect(playerReloaded.getAbility()).toBe(enemy.getAbility()); + expect(playerReloaded.getGender()).toBe(enemy.getGender()); + + expect(playerReloaded.getStat(Stat.HP, false)).not.toBe(enemy.getStat(Stat.HP)); + for (const s of EFFECTIVE_STATS) { + expect(playerReloaded.getStat(s, false)).toBe(enemy.getStat(s, false)); + } + + expect(playerMoveset.length).toEqual(1); + expect(playerMoveset[0]?.moveId).toEqual(Moves.MEMENTO); + }); + + it("should stay transformed with the correct form after reload", async () => { + game.override.enemyMoveset([]).moveset([]); + game.override.enemySpecies(Species.DARMANITAN); + + await game.classicMode.startBattle([Species.DITTO]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + // change form + enemy.species.forms[1]; + enemy.species.formIndex = 1; + + game.move.changeMoveset(player, Moves.TRANSFORM); + game.move.changeMoveset(enemy, Moves.MEMENTO); + + game.move.select(Moves.TRANSFORM); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toNextWave(); + + expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase"); + expect(game.scene.currentBattle.waveIndex).toBe(2); + + await game.reload.reloadSession(); + + const playerReloaded = game.scene.getPlayerPokemon()!; + + expect(playerReloaded.getSpeciesForm().speciesId).toBe(enemy.getSpeciesForm().speciesId); + expect(playerReloaded.getSpeciesForm().formIndex).toBe(enemy.getSpeciesForm().formIndex); + }); }); diff --git a/test/moves/triple_arrows.test.ts b/test/moves/triple_arrows.test.ts index c1114b69b99..eb434b25815 100644 --- a/test/moves/triple_arrows.test.ts +++ b/test/moves/triple_arrows.test.ts @@ -1,6 +1,7 @@ import { allMoves, FlinchAttr, StatStageChangeAttr } from "#app/data/moves/move"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; +import type Move from "#app/data/moves/move"; import { Species } from "#enums/species"; import GameManager from "#test/testUtils/gameManager"; import Phaser from "phaser"; @@ -9,14 +10,17 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite 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]; + let tripleArrows: Move; + let flinchAttr: FlinchAttr; + let defDropAttr: StatStageChangeAttr; beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, }); + tripleArrows = allMoves[Moves.TRIPLE_ARROWS]; + flinchAttr = tripleArrows.getAttrs(FlinchAttr)[0]; + defDropAttr = tripleArrows.getAttrs(StatStageChangeAttr)[0]; }); afterEach(() => { diff --git a/test/mystery-encounter/encounter-test-utils.ts b/test/mystery-encounter/encounter-test-utils.ts index 19ec364618e..8c54e0dd606 100644 --- a/test/mystery-encounter/encounter-test-utils.ts +++ b/test/mystery-encounter/encounter-test-utils.ts @@ -48,16 +48,6 @@ export async function runMysteryEncounterToEnd( ); if (isBattle) { - game.onNextPrompt( - "DamageAnimPhase", - Mode.MESSAGE, - () => { - game.setMode(Mode.MESSAGE); - game.endPhase(); - }, - () => game.isCurrentPhase(CommandPhase), - ); - game.onNextPrompt( "CheckSwitchPhase", Mode.CONFIRM, diff --git a/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts b/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts index 3e1588f3a72..e00ce03333c 100644 --- a/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts +++ b/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts @@ -136,7 +136,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); expect(enemyField.length).toBe(1); expect(enemyField[0].species.speciesId).toBe(Species.GREEDENT); - const moveset = enemyField[0].moveset.map(m => m?.moveId); + 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]); @@ -259,7 +259,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(partyCountBefore + 1).toBe(partyCountAfter); const greedent = scene.getPlayerParty()[scene.getPlayerParty().length - 1]; expect(greedent.species.speciesId).toBe(Species.GREEDENT); - const moveset = greedent.moveset.map(m => m?.moveId); + 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]); }); diff --git a/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts b/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts index a4c1052463c..77cd65e51b9 100644 --- a/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts +++ b/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts @@ -112,7 +112,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { 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]); - const moveset = enemyField[0].moveset.map(m => m?.moveId); + const moveset = enemyField[0].moveset.map(m => m.moveId); expect(moveset.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy(); const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); @@ -208,7 +208,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { expect(partyCountBefore + 1).toBe(partyCountAfter); const oricorio = scene.getPlayerParty()[scene.getPlayerParty().length - 1]; expect(oricorio.species.speciesId).toBe(Species.ORICORIO); - const moveset = oricorio.moveset.map(m => m?.moveId); + const moveset = oricorio.moveset.map(m => m.moveId); expect(moveset?.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy(); expect(moveset?.some(m => m === Moves.DRAGON_DANCE)).toBeTruthy(); }); diff --git a/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts b/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts index 8e825dc2c9b..f620cbd6c36 100644 --- a/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts +++ b/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts @@ -16,7 +16,9 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { MysteriousChallengersEncounter } from "#app/data/mystery-encounters/encounters/mysterious-challengers-encounter"; -import { TrainerConfig, TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#app/data/trainer-config"; +import { TrainerConfig } from "#app/data/trainers/trainer-config"; +import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate"; +import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { PartyMemberStrength } from "#enums/party-member-strength"; import { MysteryEncounterMode } from "#enums/mystery-encounter-mode"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; diff --git a/test/phases/phases.test.ts b/test/phases/phases.test.ts index 4aabeb55b9e..96225c9151c 100644 --- a/test/phases/phases.test.ts +++ b/test/phases/phases.test.ts @@ -31,7 +31,7 @@ describe("Phases", () => { it("should start the login phase", async () => { const loginPhase = new LoginPhase(); scene.unshiftPhase(loginPhase); - await game.phaseInterceptor.run(LoginPhase); + await game.phaseInterceptor.to(LoginPhase); expect(scene.ui.getMode()).to.equal(Mode.MESSAGE); }); }); @@ -40,7 +40,7 @@ describe("Phases", () => { it("should start the title phase", async () => { const titlePhase = new TitlePhase(); scene.unshiftPhase(titlePhase); - await game.phaseInterceptor.run(TitlePhase); + await game.phaseInterceptor.to(TitlePhase); expect(scene.ui.getMode()).to.equal(Mode.TITLE); }); }); @@ -49,7 +49,7 @@ describe("Phases", () => { it("should start the unavailable phase", async () => { const unavailablePhase = new UnavailablePhase(); scene.unshiftPhase(unavailablePhase); - await game.phaseInterceptor.run(UnavailablePhase); + await game.phaseInterceptor.to(UnavailablePhase); expect(scene.ui.getMode()).to.equal(Mode.UNAVAILABLE); }, 20000); }); diff --git a/test/phases/select-modifier-phase.test.ts b/test/phases/select-modifier-phase.test.ts index bb3d5debc7c..d352acea77a 100644 --- a/test/phases/select-modifier-phase.test.ts +++ b/test/phases/select-modifier-phase.test.ts @@ -48,8 +48,8 @@ describe("SelectModifierPhase", () => { it("should start a select modifier phase", async () => { initSceneWithoutEncounterPhase(scene, [Species.ABRA, Species.VOLCARONA]); const selectModifierPhase = new SelectModifierPhase(); - scene.pushPhase(selectModifierPhase); - await game.phaseInterceptor.run(SelectModifierPhase); + scene.unshiftPhase(selectModifierPhase); + await game.phaseInterceptor.to(SelectModifierPhase); expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); }); diff --git a/test/plugins/api/pokerogue-account-api.test.ts b/test/plugins/api/pokerogue-account-api.test.ts index 9ec98b6a59f..e7e1b2d52b0 100644 --- a/test/plugins/api/pokerogue-account-api.test.ts +++ b/test/plugins/api/pokerogue-account-api.test.ts @@ -4,11 +4,17 @@ import { PokerogueAccountApi } from "#app/plugins/api/pokerogue-account-api"; import { getApiBaseUrl } from "#test/testUtils/testUtils"; import * as Utils from "#app/utils"; import { http, HttpResponse } from "msw"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; +import type { SetupServerApi } from "msw/node"; const apiBase = getApiBaseUrl(); const accountApi = new PokerogueAccountApi(apiBase); -const { server } = global; +let server: SetupServerApi; + +beforeAll(async () => { + server = await initServerForApiTests(); +}); afterEach(() => { server.resetHandlers(); diff --git a/test/plugins/api/pokerogue-admin-api.test.ts b/test/plugins/api/pokerogue-admin-api.test.ts index 0ce727b88da..08c4cf0dc45 100644 --- a/test/plugins/api/pokerogue-admin-api.test.ts +++ b/test/plugins/api/pokerogue-admin-api.test.ts @@ -9,11 +9,17 @@ import type { import { PokerogueAdminApi } from "#app/plugins/api/pokerogue-admin-api"; import { getApiBaseUrl } from "#test/testUtils/testUtils"; import { http, HttpResponse } from "msw"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; +import type { SetupServerApi } from "msw/node"; const apiBase = getApiBaseUrl(); const adminApi = new PokerogueAdminApi(apiBase); -const { server } = global; +let server: SetupServerApi; + +beforeAll(async () => { + server = await initServerForApiTests(); +}); afterEach(() => { server.resetHandlers(); diff --git a/test/plugins/api/pokerogue-api.test.ts b/test/plugins/api/pokerogue-api.test.ts index 241453866a5..c53a38e23ab 100644 --- a/test/plugins/api/pokerogue-api.test.ts +++ b/test/plugins/api/pokerogue-api.test.ts @@ -2,10 +2,16 @@ import type { TitleStatsResponse } from "#app/@types/PokerogueApi"; import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import { getApiBaseUrl } from "#test/testUtils/testUtils"; import { http, HttpResponse } from "msw"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; +import type { SetupServerApi } from "msw/node"; const apiBase = getApiBaseUrl(); -const { server } = global; +let server: SetupServerApi; + +beforeAll(async () => { + server = await initServerForApiTests(); +}); afterEach(() => { server.resetHandlers(); diff --git a/test/plugins/api/pokerogue-daily-api.test.ts b/test/plugins/api/pokerogue-daily-api.test.ts index 95d938e6625..563e6d09009 100644 --- a/test/plugins/api/pokerogue-daily-api.test.ts +++ b/test/plugins/api/pokerogue-daily-api.test.ts @@ -3,11 +3,17 @@ import { PokerogueDailyApi } from "#app/plugins/api/pokerogue-daily-api"; import { getApiBaseUrl } from "#test/testUtils/testUtils"; import { ScoreboardCategory, type RankingEntry } from "#app/ui/daily-run-scoreboard"; import { http, HttpResponse } from "msw"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; +import type { SetupServerApi } from "msw/node"; const apiBase = getApiBaseUrl(); const dailyApi = new PokerogueDailyApi(apiBase); -const { server } = global; +let server: SetupServerApi; + +beforeAll(async () => { + server = await initServerForApiTests(); +}); afterEach(() => { server.resetHandlers(); diff --git a/test/plugins/api/pokerogue-savedata-api.test.ts b/test/plugins/api/pokerogue-savedata-api.test.ts index 47eafa0a933..481ba62c19d 100644 --- a/test/plugins/api/pokerogue-savedata-api.test.ts +++ b/test/plugins/api/pokerogue-savedata-api.test.ts @@ -2,11 +2,17 @@ import type { UpdateAllSavedataRequest } from "#app/@types/PokerogueSavedataApi" import { PokerogueSavedataApi } from "#app/plugins/api/pokerogue-savedata-api"; import { getApiBaseUrl } from "#test/testUtils/testUtils"; import { http, HttpResponse } from "msw"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; +import type { SetupServerApi } from "msw/node"; const apiBase = getApiBaseUrl(); const savedataApi = new PokerogueSavedataApi(apiBase); -const { server } = global; +let server: SetupServerApi; + +beforeAll(async () => { + server = await initServerForApiTests(); +}); afterEach(() => { server.resetHandlers(); diff --git a/test/plugins/api/pokerogue-session-savedata-api.test.ts b/test/plugins/api/pokerogue-session-savedata-api.test.ts index 67abc9c9336..d4c235ac51a 100644 --- a/test/plugins/api/pokerogue-session-savedata-api.test.ts +++ b/test/plugins/api/pokerogue-session-savedata-api.test.ts @@ -10,11 +10,17 @@ import { PokerogueSessionSavedataApi } from "#app/plugins/api/pokerogue-session- import type { SessionSaveData } from "#app/system/game-data"; import { getApiBaseUrl } from "#test/testUtils/testUtils"; import { http, HttpResponse } from "msw"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; +import type { SetupServerApi } from "msw/node"; const apiBase = getApiBaseUrl(); const sessionSavedataApi = new PokerogueSessionSavedataApi(apiBase); -const { server } = global; + +let server: SetupServerApi; +beforeAll(async () => { + server = await initServerForApiTests(); +}); afterEach(() => { server.resetHandlers(); diff --git a/test/plugins/api/pokerogue-system-savedata-api.test.ts b/test/plugins/api/pokerogue-system-savedata-api.test.ts index 81d863049f0..0c69ab8f922 100644 --- a/test/plugins/api/pokerogue-system-savedata-api.test.ts +++ b/test/plugins/api/pokerogue-system-savedata-api.test.ts @@ -6,13 +6,20 @@ import type { } from "#app/@types/PokerogueSystemSavedataApi"; import { PokerogueSystemSavedataApi } from "#app/plugins/api/pokerogue-system-savedata-api"; import type { SystemSaveData } from "#app/system/game-data"; +import { initServerForApiTests } from "#test/testUtils/testFileInitialization"; import { getApiBaseUrl } from "#test/testUtils/testUtils"; import { http, HttpResponse } from "msw"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import type { SetupServerApi } from "msw/node"; const apiBase = getApiBaseUrl(); const systemSavedataApi = new PokerogueSystemSavedataApi(getApiBaseUrl()); -const { server } = global; + +let server: SetupServerApi; + +beforeAll(async () => { + server = await initServerForApiTests(); +}); afterEach(() => { server.resetHandlers(); diff --git a/test/pre.test.ts b/test/pre.test.ts deleted file mode 100644 index 6ed29dce481..00000000000 --- a/test/pre.test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Overrides, { defaultOverrides } from "#app/overrides"; -import { expect, test } from "vitest"; - -test("Overrides are default values", () => { - expect(Overrides).toEqual(defaultOverrides); -}); diff --git a/test/testUtils/gameManager.ts b/test/testUtils/gameManager.ts index 0ebc83cae31..390e71af126 100644 --- a/test/testUtils/gameManager.ts +++ b/test/testUtils/gameManager.ts @@ -55,6 +55,9 @@ import TextInterceptor from "#test/testUtils/TextInterceptor"; import { AES, enc } from "crypto-js"; import fs from "node:fs"; import { expect, vi } from "vitest"; +import { globalScene } from "#app/global-scene"; +import type StarterSelectUiHandler from "#app/ui/starter-select-ui-handler"; +import { MockFetch } from "#test/testUtils/mocks/mockFetch"; /** * Class to manage the game state and transitions between phases. @@ -84,10 +87,34 @@ export default class GameManager { ErrorInterceptor.getInstance().clear(); BattleScene.prototype.randBattleSeedInt = (range, min = 0) => min + range - 1; // This simulates a max roll this.gameWrapper = new GameWrapper(phaserGame, bypassLogin); - this.scene = new BattleScene(); + + let firstTimeScene = false; + + if (globalScene) { + this.scene = globalScene; + } else { + this.scene = new BattleScene(); + this.gameWrapper.setScene(this.scene); + firstTimeScene = true; + } + this.phaseInterceptor = new PhaseInterceptor(this.scene); + + if (!firstTimeScene) { + this.scene.reset(false, true); + (this.scene.ui.handlers[Mode.STARTER_SELECT] as StarterSelectUiHandler).clearStarterPreferences(); + this.scene.clearAllPhases(); + + // Must be run after phase interceptor has been initialized. + + this.scene.pushPhase(new LoginPhase()); + this.scene.pushPhase(new TitlePhase()); + this.scene.shiftPhase(); + + this.gameWrapper.scene = this.scene; + } + this.textInterceptor = new TextInterceptor(this.scene); - this.gameWrapper.setScene(this.scene); this.override = new OverridesHelper(this); this.move = new MoveHelper(this); this.classicMode = new ClassicModeHelper(this); @@ -96,9 +123,12 @@ export default class GameManager { this.settings = new SettingsHelper(this); this.reload = new ReloadHelper(this); this.modifiers = new ModifierHelper(this); + this.override.sanitizeOverrides(); // Disables Mystery Encounters on all tests (can be overridden at test level) this.override.mysteryEncounterChance(0); + + global.fetch = vi.fn(MockFetch) as any; } /** @@ -292,7 +322,7 @@ export default class GameManager { const move = (this.scene.getCurrentPhase() as SelectTargetPhase) .getPokemon() .getMoveset() - [movePosition]!.getMove(); // TODO: is the bang correct? + [movePosition].getMove(); if (!move.isMultiTarget()) { handler.setCursor(targetIndex !== undefined ? targetIndex : BattlerIndex.ENEMY); } diff --git a/test/testUtils/gameManagerUtils.ts b/test/testUtils/gameManagerUtils.ts index ae6c11f5efa..11636bd66b4 100644 --- a/test/testUtils/gameManagerUtils.ts +++ b/test/testUtils/gameManagerUtils.ts @@ -99,7 +99,7 @@ export function waitUntil(truth): Promise { export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: Moves): number { const playerPokemon = scene.getPlayerField()[pokemonIndex]; const moveSet = playerPokemon.getMoveset(); - const index = moveSet.findIndex(m => m?.moveId === move && m?.ppUsed < m?.getMovePp()); + 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/test/testUtils/gameWrapper.ts b/test/testUtils/gameWrapper.ts index 6af36f22d24..388861e01c4 100644 --- a/test/testUtils/gameWrapper.ts +++ b/test/testUtils/gameWrapper.ts @@ -1,44 +1,26 @@ -/* eslint-disable */ -// @ts-nocheck +// @ts-nocheck - TODO: remove this import BattleScene, * as battleScene from "#app/battle-scene"; import { MoveAnim } from "#app/data/battle-anims"; import Pokemon from "#app/field/pokemon"; import * as Utils from "#app/utils"; import { blobToString } from "#test/testUtils/gameManagerUtils"; import { MockClock } from "#test/testUtils/mocks/mockClock"; -import mockConsoleLog from "#test/testUtils/mocks/mockConsoleLog"; import { MockFetch } from "#test/testUtils/mocks/mockFetch"; import MockLoader from "#test/testUtils/mocks/mockLoader"; -import mockLocalStorage from "#test/testUtils/mocks/mockLocalStorage"; -import MockImage from "#test/testUtils/mocks/mocksContainer/mockImage"; import MockTextureManager from "#test/testUtils/mocks/mockTextureManager"; import fs from "node:fs"; import Phaser from "phaser"; -import InputText from "phaser3-rex-plugins/plugins/inputtext"; -import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; import { vi } from "vitest"; +import { version } from "../../package.json"; import { MockGameObjectCreator } from "./mocks/mockGameObjectCreator"; +import { MockTimedEventManager } from "./mocks/mockTimedEventManager"; import InputManager = Phaser.Input.InputManager; import KeyboardManager = Phaser.Input.Keyboard.KeyboardManager; 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"; -import { MockTimedEventManager } from "./mocks/mockTimedEventManager"; -Object.defineProperty(window, "localStorage", { - value: mockLocalStorage(), -}); -Object.defineProperty(window, "console", { - value: mockConsoleLog(false), -}); - -BBCodeText.prototype.destroy = () => null; -BBCodeText.prototype.resize = () => null; -InputText.prototype.setElement = () => null; -InputText.prototype.resize = () => null; -Phaser.GameObjects.Image = MockImage; window.URL.createObjectURL = (blob: Blob) => { blobToString(blob).then((data: string) => { localStorage.setItem("toExport", data); @@ -53,25 +35,6 @@ window.matchMedia = () => ({ matches: false, }); -/** - * Sets this object's position relative to another object with a given offset - * @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of - * @param x The relative x position - * @param y The relative y position - */ -const setPositionRelative = function (guideObject: any, x: number, y: number) { - const offsetX = guideObject.width * (-0.5 + (0.5 - guideObject.originX)); - const offsetY = guideObject.height * (-0.5 + (0.5 - guideObject.originY)); - this.setPosition(guideObject.x + offsetX + x, guideObject.y + offsetY + y); -}; - -Phaser.GameObjects.Container.prototype.setPositionRelative = setPositionRelative; -Phaser.GameObjects.Sprite.prototype.setPositionRelative = setPositionRelative; -Phaser.GameObjects.Image.prototype.setPositionRelative = setPositionRelative; -Phaser.GameObjects.NineSlice.prototype.setPositionRelative = setPositionRelative; -Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative; -Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative; - export default class GameWrapper { public game: Phaser.Game; public scene: BattleScene; diff --git a/test/testUtils/helpers/overridesHelper.ts b/test/testUtils/helpers/overridesHelper.ts index e69e05bce45..9bb0369a31a 100644 --- a/test/testUtils/helpers/overridesHelper.ts +++ b/test/testUtils/helpers/overridesHelper.ts @@ -1,12 +1,9 @@ import type { Variant } from "#app/data/variant"; import { Weather } from "#app/data/weather"; import { Abilities } from "#app/enums/abilities"; -import * as GameMode from "#app/game-mode"; -import type { GameModes } from "#app/game-mode"; -import { getGameMode } from "#app/game-mode"; import type { ModifierOverride } from "#app/modifier/modifier-type"; import type { BattleStyle } from "#app/overrides"; -import Overrides from "#app/overrides"; +import Overrides, { defaultOverrides } from "#app/overrides"; import type { Unlockables } from "#app/system/unlockables"; import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; @@ -15,8 +12,9 @@ import type { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { Species } from "#enums/species"; import { StatusEffect } from "#enums/status-effect"; import type { WeatherType } from "#enums/weather-type"; -import { vi } from "vitest"; +import { expect, vi } from "vitest"; import { GameManagerHelper } from "./gameManagerHelper"; +import { shiftCharCodes } from "#app/utils"; /** * Helper to handle overrides in tests @@ -226,12 +224,7 @@ export class OverridesHelper extends GameManagerHelper { * @returns `this` */ public disableTrainerWaves(): this { - const realFn = getGameMode; - vi.spyOn(GameMode, "getGameMode").mockImplementation((gameMode: GameModes) => { - const mode = realFn(gameMode); - mode.hasTrainers = false; - return mode; - }); + vi.spyOn(Overrides, "DISABLE_STANDARD_TRAINERS_OVERRIDE", "get").mockReturnValue(true); this.log("Standard trainer waves are disabled!"); return this; } @@ -263,11 +256,8 @@ export class OverridesHelper extends GameManagerHelper { * @returns `this` */ public seed(seed: string): this { - vi.spyOn(this.game.scene, "resetSeed").mockImplementation(() => { - this.game.scene.waveSeed = seed; - Phaser.Math.RND.sow([seed]); - this.game.scene.rngCounter = 0; - }); + // Shift the seed here with a negative wave number, to compensate for `resetSeed()` shifting the seed itself. + this.game.scene.setSeed(shiftCharCodes(seed, (this.game.scene.currentBattle?.waveIndex ?? 0) * -1)); this.game.scene.resetSeed(); this.log(`Seed set to "${seed}"!`); return this; @@ -539,4 +529,14 @@ export class OverridesHelper extends GameManagerHelper { private log(...params: any[]) { console.log("Overrides:", ...params); } + + public sanitizeOverrides(): void { + for (const key of Object.keys(defaultOverrides)) { + if (Overrides[key] !== defaultOverrides[key]) { + vi.spyOn(Overrides, key as any, "get").mockReturnValue(defaultOverrides[key]); + } + } + expect(Overrides).toEqual(defaultOverrides); + this.log("Sanitizing all overrides!"); + } } diff --git a/test/testUtils/listenersManager.ts b/test/testUtils/listenersManager.ts new file mode 100644 index 00000000000..da624aa8a56 --- /dev/null +++ b/test/testUtils/listenersManager.ts @@ -0,0 +1,41 @@ +import { expect } from "vitest"; + +/** + * Whether or not it is currently the first time running this manager. + */ +let firstTime = true; + +/** + * The list of listeners that were present during the first time this manager is run. + * These initial listeners are needed throughout the entire test suite, so we never remove them. + */ +const initialListeners: NodeJS.MessageListener[] = []; + +/** + * The current listener that is only needed for the current test file. + * We plan to delete it during the next test file, when it is no longer needed. + */ +let currentListener: NodeJS.MessageListener | null; + +export function manageListeners() { + if (firstTime) { + initialListeners.push(...process.listeners("message")); + } else { + expect(process.listeners("message").length).toBeLessThan(7); + + // Remove the listener that was used during the previous test file + if (currentListener) { + process.removeListener("message", currentListener); + currentListener = null; + } + + // Find the new listener that is being used for the current test file + process.listeners("message").forEach(fn => { + if (!initialListeners.includes(fn)) { + currentListener = fn; + } + }); + } + + firstTime = false; +} diff --git a/test/testUtils/mocks/mockConsoleLog.ts b/test/testUtils/mocks/mockConsoleLog.ts index 808b6ea4d4d..f54d41fea3e 100644 --- a/test/testUtils/mocks/mockConsoleLog.ts +++ b/test/testUtils/mocks/mockConsoleLog.ts @@ -1,82 +1,80 @@ -const MockConsoleLog = (_logDisabled = false, _phaseText = false) => { - let logs: any[] = []; - const logDisabled: boolean = _logDisabled; - const phaseText: boolean = _phaseText; - const originalLog = console.log; - const originalError = console.error; - const originalDebug = console.debug; - const originalWarn = console.warn; - const notified: any[] = []; +const originalLog = console.log; +const originalError = console.error; +const originalDebug = console.debug; +const originalWarn = console.warn; - 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) { - const argsStr = this.getStr(args); - logs.push(argsStr); - if (logDisabled && !phaseText) { - return; - } - if ((phaseText && !whitelist.some(b => argsStr.includes(b))) || blacklist.some(b => argsStr.includes(b))) { - return; - } - originalLog(args); - }, - error(...args) { - const argsStr = this.getStr(args); - logs.push(argsStr); - originalError(args); // Appelle le console.error originel - }, - debug(...args) { - const argsStr = this.getStr(args); - logs.push(argsStr); - if (logDisabled && !phaseText) { - return; - } - if (!whitelist.some(b => argsStr.includes(b)) || blacklist.some(b => argsStr.includes(b))) { - return; - } - originalDebug(args); - }, - warn(...args) { - const argsStr = this.getStr(args); - logs.push(args); - if (logDisabled && !phaseText) { - return; - } - if (!whitelist.some(b => argsStr.includes(b)) || blacklist.some(b => argsStr.includes(b))) { - return; - } - originalWarn(args); - }, - notify(msg) { - originalLog(msg); - notified.push(msg); - }, - getLogs() { - return logs; - }, - clearLogs() { - logs = []; - }, - getStr(...args) { - return args - .map(arg => { - if (typeof arg === "object" && arg !== null) { - // Handle objects including arrays - return JSON.stringify(arg, (_key, value) => (typeof value === "bigint" ? value.toString() : value)); - } - if (typeof arg === "bigint") { - // Handle BigInt values - return arg.toString(); - } - // Handle all other types +export class MockConsoleLog { + constructor( + private logDisabled = false, + private phaseText = false, + ) {} + private logs: any[] = []; + private notified: any[] = []; + + public log(...args) { + const argsStr = this.getStr(args); + this.logs.push(argsStr); + if (this.logDisabled && !this.phaseText) { + return; + } + if ((this.phaseText && !whitelist.some(b => argsStr.includes(b))) || blacklist.some(b => argsStr.includes(b))) { + return; + } + originalLog(args); + } + public error(...args) { + const argsStr = this.getStr(args); + this.logs.push(argsStr); + originalError(args); // Appelle le console.error originel + } + public debug(...args) { + const argsStr = this.getStr(args); + this.logs.push(argsStr); + if (this.logDisabled && !this.phaseText) { + return; + } + if (!whitelist.some(b => argsStr.includes(b)) || blacklist.some(b => argsStr.includes(b))) { + return; + } + originalDebug(args); + } + warn(...args) { + const argsStr = this.getStr(args); + this.logs.push(args); + if (this.logDisabled && !this.phaseText) { + return; + } + if (!whitelist.some(b => argsStr.includes(b)) || blacklist.some(b => argsStr.includes(b))) { + return; + } + originalWarn(args); + } + notify(msg) { + originalLog(msg); + this.notified.push(msg); + } + getLogs() { + return this.logs; + } + clearLogs() { + this.logs = []; + } + getStr(...args) { + return args + .map(arg => { + if (typeof arg === "object" && arg !== null) { + // Handle objects including arrays + return JSON.stringify(arg, (_key, value) => (typeof value === "bigint" ? value.toString() : value)); + } + if (typeof arg === "bigint") { + // Handle BigInt values return arg.toString(); - }) - .join(";"); - }, - }; -}; - -export default MockConsoleLog; + } + return arg.toString(); + }) + .join(";"); + } +} diff --git a/test/testUtils/mocks/mockContextCanvas.ts b/test/testUtils/mocks/mockContextCanvas.ts new file mode 100644 index 00000000000..a69f039c5e9 --- /dev/null +++ b/test/testUtils/mocks/mockContextCanvas.ts @@ -0,0 +1,26 @@ +/** + * A minimal stub object to mock HTMLCanvasElement + */ +export const mockCanvas: any = { + width: 0, + getContext() { + return mockContext; + }, +}; +/** + * A minimal stub object to mock CanvasRenderingContext2D + */ +export const mockContext: any = { + font: "", + measureText: () => { + return {}; + }, + save: () => {}, + scale: () => {}, + clearRect: () => {}, + fillRect: () => {}, + fillText: () => {}, + getImageData: () => {}, + canvas: mockCanvas, + restore: () => {}, +}; diff --git a/test/testUtils/mocks/mockLocalStorage.ts b/test/testUtils/mocks/mockLocalStorage.ts index 235aa76f664..6b336841ad6 100644 --- a/test/testUtils/mocks/mockLocalStorage.ts +++ b/test/testUtils/mocks/mockLocalStorage.ts @@ -1,4 +1,4 @@ -const mockLocalStorage = () => { +export const mockLocalStorage = () => { let store = {} as Storage; return { @@ -23,5 +23,3 @@ const mockLocalStorage = () => { }, }; }; - -export default mockLocalStorage; diff --git a/test/testUtils/mocks/mockTextureManager.ts b/test/testUtils/mocks/mockTextureManager.ts index fe249c5a5f7..585ee0a674a 100644 --- a/test/testUtils/mocks/mockTextureManager.ts +++ b/test/testUtils/mocks/mockTextureManager.ts @@ -1,5 +1,5 @@ import MockContainer from "#test/testUtils/mocks/mocksContainer/mockContainer"; -import MockImage from "#test/testUtils/mocks/mocksContainer/mockImage"; +import { MockImage } from "#test/testUtils/mocks/mocksContainer/mockImage"; import MockNineslice from "#test/testUtils/mocks/mocksContainer/mockNineslice"; import MockPolygon from "#test/testUtils/mocks/mocksContainer/mockPolygon"; import MockRectangle from "#test/testUtils/mocks/mocksContainer/mockRectangle"; diff --git a/test/testUtils/mocks/mocksContainer/mockContainer.ts b/test/testUtils/mocks/mocksContainer/mockContainer.ts index 0a792c6fc79..5e739fbe3cc 100644 --- a/test/testUtils/mocks/mocksContainer/mockContainer.ts +++ b/test/testUtils/mocks/mocksContainer/mockContainer.ts @@ -215,4 +215,10 @@ export default class MockContainer implements MockGameObject { } disableInteractive = () => null; + + each(method) { + for (const item of this.list) { + method(item); + } + } } diff --git a/test/testUtils/mocks/mocksContainer/mockImage.ts b/test/testUtils/mocks/mocksContainer/mockImage.ts index 768fcfeb765..d20b4663771 100644 --- a/test/testUtils/mocks/mocksContainer/mockImage.ts +++ b/test/testUtils/mocks/mocksContainer/mockImage.ts @@ -1,6 +1,6 @@ import MockContainer from "#test/testUtils/mocks/mocksContainer/mockContainer"; -export default class MockImage extends MockContainer { +export class MockImage extends MockContainer { private texture; constructor(textureManager, x, y, texture) { diff --git a/test/testUtils/mocks/mocksContainer/mockRectangle.ts b/test/testUtils/mocks/mocksContainer/mockRectangle.ts index eec431d8ada..7bdf343759d 100644 --- a/test/testUtils/mocks/mocksContainer/mockRectangle.ts +++ b/test/testUtils/mocks/mocksContainer/mockRectangle.ts @@ -72,4 +72,6 @@ export default class MockRectangle implements MockGameObject { setScale(_scale) { // return this.phaserText.setScale(scale); } + + off() {} } diff --git a/test/testUtils/testFileInitialization.ts b/test/testUtils/testFileInitialization.ts new file mode 100644 index 00000000000..2b41f3aa29a --- /dev/null +++ b/test/testUtils/testFileInitialization.ts @@ -0,0 +1,117 @@ +import { SESSION_ID_COOKIE_NAME } from "#app/constants"; +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/moves/move"; +import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters"; +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 { setCookie } from "#app/utils"; +import { blobToString } from "#test/testUtils/gameManagerUtils"; +import { MockConsoleLog } from "#test/testUtils/mocks/mockConsoleLog"; +import { mockContext } from "#test/testUtils/mocks/mockContextCanvas"; +import { mockLocalStorage } from "#test/testUtils/mocks/mockLocalStorage"; +import { MockImage } from "#test/testUtils/mocks/mocksContainer/mockImage"; +import Phaser from "phaser"; +import InputText from "phaser3-rex-plugins/plugins/inputtext"; +import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; +import { manageListeners } from "./listenersManager"; + +let wasInitialized = false; +/** + * An initialization function that is run at the beginning of every test file (via `beforeAll()`). + */ +export function initTestFile() { + // Set the timezone to UTC for tests. + process.env.TZ = "UTC"; + + Object.defineProperty(window, "localStorage", { + value: mockLocalStorage(), + }); + Object.defineProperty(window, "console", { + value: new MockConsoleLog(false), + }); + Object.defineProperty(document, "fonts", { + writable: true, + value: { + add: () => {}, + }, + }); + + BBCodeText.prototype.destroy = () => null; + // @ts-ignore + BBCodeText.prototype.resize = () => null; + InputText.prototype.setElement = () => null as any; + InputText.prototype.resize = () => null as any; + Phaser.GameObjects.Image = MockImage as any; + window.URL.createObjectURL = (blob: Blob) => { + blobToString(blob).then((data: string) => { + localStorage.setItem("toExport", data); + }); + return null as any; + }; + navigator.getGamepads = () => []; + setCookie(SESSION_ID_COOKIE_NAME, "fake_token"); + + window.matchMedia = () => + ({ + matches: false, + }) as any; + + /** + * Sets this object's position relative to another object with a given offset + * @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of + * @param x The relative x position + * @param y The relative y position + */ + const setPositionRelative = function (guideObject: any, x: number, y: number) { + const offsetX = guideObject.width * (-0.5 + (0.5 - guideObject.originX)); + const offsetY = guideObject.height * (-0.5 + (0.5 - guideObject.originY)); + this.setPosition(guideObject.x + offsetX + x, guideObject.y + offsetY + y); + }; + + Phaser.GameObjects.Container.prototype.setPositionRelative = setPositionRelative; + Phaser.GameObjects.Sprite.prototype.setPositionRelative = setPositionRelative; + Phaser.GameObjects.Image.prototype.setPositionRelative = setPositionRelative; + Phaser.GameObjects.NineSlice.prototype.setPositionRelative = setPositionRelative; + Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative; + Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative; + HTMLCanvasElement.prototype.getContext = () => mockContext; + + // Initialize all of these things if and only if they have not been initialized yet + // initSpecies(); + if (!wasInitialized) { + wasInitialized = true; + initVouchers(); + initAchievements(); + initStatsKeys(); + initPokemonPrevolutions(); + initBiomes(); + initEggMoves(); + initPokemonForms(); + initSpecies(); + initMoves(); + initAbilities(); + initLoggedInUser(); + initMysteryEncounters(); + } + + manageListeners(); +} + +/** + * Closes the current mock server and initializes a new mock server. + * This is run at the beginning of every API test file. + */ +export async function initServerForApiTests() { + global.server?.close(); + const { setupServer } = await import("msw/node"); + global.server = setupServer(); + global.server.listen({ onUnhandledRequest: "error" }); + return global.server; +} diff --git a/test/vitest.setup.ts b/test/vitest.setup.ts index 44175049042..93b439e540f 100644 --- a/test/vitest.setup.ts +++ b/test/vitest.setup.ts @@ -1,31 +1,17 @@ import "vitest-canvas-mock"; - -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/moves/move"; -import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters"; -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 { afterAll, beforeAll, vi } from "vitest"; +import { initTestFile } from "./testUtils/testFileInitialization"; + /** Set the timezone to UTC for tests. */ -process.env.TZ = "UTC"; /** Mock the override import to always return default values, ignoring any custom overrides. */ vi.mock("#app/overrides", async importOriginal => { - // eslint-disable-next-line @typescript-eslint/consistent-type-imports const { defaultOverrides } = await importOriginal(); return { default: defaultOverrides, defaultOverrides, - // eslint-disable-next-line @typescript-eslint/consistent-type-imports } satisfies typeof import("#app/overrides"); }); @@ -63,28 +49,10 @@ vi.mock("i18next", async importOriginal => { return await importOriginal(); }); -initVouchers(); -initAchievements(); -initStatsKeys(); -initPokemonPrevolutions(); -initBiomes(); -initEggMoves(); -initPokemonForms(); -initSpecies(); -initMoves(); -initAbilities(); -initLoggedInUser(); -initMysteryEncounters(); - global.testFailed = false; beforeAll(() => { - Object.defineProperty(document, "fonts", { - writable: true, - value: { - add: () => {}, - }, - }); + initTestFile(); }); afterAll(() => { diff --git a/vitest.config.ts b/vitest.config.ts index b52c16ec00c..c781bde97ed 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,20 +1,31 @@ import { defineProject } from "vitest/config"; import { defaultConfig } from "./vite.config"; +import { BaseSequencer, type TestSpecification } from "vitest/node"; + +function getTestOrder(testName: string): number { + if (testName.includes("battle-scene.test.ts")) { + return 1; + } + if (testName.includes("inputs.test.ts")) { + return 2; + } + return 3; +} export default defineProject(({ mode }) => ({ ...defaultConfig, test: { testTimeout: 20000, setupFiles: ["./test/fontFace.setup.ts", "./test/vitest.setup.ts"], - server: { - deps: { - inline: ["vitest-canvas-mock"], - //@ts-ignore - optimizer: { - web: { - include: ["vitest-canvas-mock"], - }, - }, + sequence: { + sequencer: class CustomSequencer extends BaseSequencer { + async sort(files: TestSpecification[]) { + // use default sorting at first. + files = await super.sort(files); + // Except, forcibly reorder + + return files.sort((a, b) => getTestOrder(a.moduleId) - getTestOrder(b.moduleId)); + } }, }, environment: "jsdom" as const, @@ -34,7 +45,6 @@ export default defineProject(({ mode }) => ({ }, name: "main", include: ["./test/**/*.{test,spec}.ts"], - exclude: ["./test/pre.test.ts"], }, esbuild: { pure: mode === "production" ? ["console.log"] : [],