diff --git a/package-lock.json b/package-lock.json index 00942ee3312..316306e3299 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "inquirer": "^11.0.2", "jsdom": "^24.0.0", "lefthook": "^1.6.12", + "msw": "^2.4.9", "phaser3spectorjs": "^0.0.8", "typedoc": "^0.26.4", "typescript": "^5.5.3", @@ -486,6 +487,37 @@ "node": ">=6.9.0" } }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", + "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cookie": "^0.5.0" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dev": true, + "license": "ISC", + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@bundled-es-modules/tough-cookie": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/tough-cookie": "^4.0.5", + "tough-cookie": "^4.1.4" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -1461,6 +1493,24 @@ "integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==", "license": "Apache-2.0" }, + "node_modules/@mswjs/interceptors": { + "version": "0.35.8", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.35.8.tgz", + "integrity": "sha512-PFfqpHplKa7KMdoQdj5td03uG05VK2Ng1dG0sP4pT9h0dGSX2v9txYt/AnrzPb/vAmfyBBC0NQV7VaBEX+efgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1499,6 +1549,31 @@ "node": ">= 8" } }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true, + "license": "MIT" + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1777,6 +1852,13 @@ "eslint": ">=8.40.0" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/eslint": { "version": "8.56.11", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz", @@ -1842,6 +1924,13 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/statuses": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", + "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -2622,6 +2711,16 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cross-fetch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", @@ -3740,6 +3839,16 @@ "dev": true, "license": "MIT" }, + "node_modules/graphql": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", + "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3797,6 +3906,13 @@ "node": ">= 0.4" } }, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -4072,6 +4188,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true, + "license": "MIT" + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4805,6 +4928,90 @@ "dev": true, "license": "MIT" }, + "node_modules/msw": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.4.9.tgz", + "integrity": "sha512-1m8xccT6ipN4PTqLinPwmzhxQREuxaEJYdx4nIbggxP8aM7r1e71vE7RtOUSQoAm1LydjGfZKy7370XD/tsuYg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@bundled-es-modules/tough-cookie": "^0.1.6", + "@inquirer/confirm": "^3.0.0", + "@mswjs/interceptors": "^0.35.8", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.3.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.8.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw/node_modules/@inquirer/confirm": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.2.0.tgz", + "integrity": "sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/msw/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/msw/node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mustache": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", @@ -4983,6 +5190,13 @@ "node": ">=0.10.0" } }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "dev": true, + "license": "MIT" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5105,6 +5319,13 @@ "dev": true, "license": "ISC" }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -5667,6 +5888,16 @@ "dev": true, "license": "MIT" }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", @@ -5674,6 +5905,13 @@ "dev": true, "license": "MIT" }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true, + "license": "MIT" + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", diff --git a/package.json b/package.json index 2109604c969..37418014d93 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "inquirer": "^11.0.2", "jsdom": "^24.0.0", "lefthook": "^1.6.12", + "msw": "^2.4.9", "phaser3spectorjs": "^0.0.8", "typedoc": "^0.26.4", "typescript": "^5.5.3", diff --git a/public/images/trainer/bug_type_superfan.json b/public/images/trainer/bug_type_superfan.json index 74dca3583d5..6a77fe69912 100644 --- a/public/images/trainer/bug_type_superfan.json +++ b/public/images/trainer/bug_type_superfan.json @@ -4,1458 +4,30 @@ "image": "bug_type_superfan.png", "format": "RGBA8888", "size": { - "w": 224, - "h": 224 + "w": 71, + "h": 71 }, "scale": 1, "frames": [ - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 52, - "h": 85 - }, - "frame": { - "x": 1, - "y": 1, - "w": 52, - "h": 85 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 5, - "y": 1, - "w": 52, - "h": 85 - }, - "frame": { - "x": 1, - "y": 1, - "w": 52, - "h": 85 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 60, - "h": 75 - }, - "frame": { - "x": 55, - "y": 1, - "w": 60, - "h": 75 - } - }, { "filename": "0001.png", "rotated": false, "trimmed": true, "sourceSize": { "w": 80, - "h": 86 + "h": 80 }, "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 + "x": 4, + "y": 9, + "w": 71, + "h": 71 }, "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 6, - "y": 18, - "w": 65, - "h": 68 - }, - "frame": { - "x": 117, - "y": 1, - "w": 65, - "h": 68 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, + "x": 0, "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 46, - "h": 86 - }, - "frame": { - "x": 1, - "y": 88, - "w": 46, - "h": 86 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 19, - "w": 66, - "h": 67 - }, - "frame": { - "x": 49, - "y": 88, - "w": 66, - "h": 67 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 19, - "w": 66, - "h": 67 - }, - "frame": { - "x": 49, - "y": 88, - "w": 66, - "h": 67 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 49, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 49, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 8, - "y": 20, - "w": 65, - "h": 66 - }, - "frame": { - "x": 116, - "y": 157, - "w": 65, - "h": 66 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 7, - "y": 19, - "w": 65, - "h": 67 - }, - "frame": { - "x": 117, - "y": 71, - "w": 65, - "h": 67 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 80, - "h": 86 - }, - "spriteSourceSize": { - "x": 7, - "y": 19, - "w": 65, - "h": 67 - }, - "frame": { - "x": 117, - "y": 71, - "w": 65, - "h": 67 + "w": 71, + "h": 71 } } ] @@ -1464,6 +36,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:442c13442d70348845d7f5fcdfc121b3:3b8402aa64ee8990e64c7f03ffffbc55:568199339797fd79d11ae8d741953c1c$" + "smartupdate": "$TexturePacker:SmartUpdate:d051332055512f245ae68e912a28cd81:4926ba3fd9fe432bb535d13f4df1df4e:621aca0914900a3b9e235ebf0431ce2b$" } } diff --git a/public/images/trainer/bug_type_superfan.png b/public/images/trainer/bug_type_superfan.png index 59316fe6ed8..0d2fd7a68ae 100644 Binary files a/public/images/trainer/bug_type_superfan.png and b/public/images/trainer/bug_type_superfan.png differ diff --git a/src/@types/pokerogue-api.ts b/src/@types/pokerogue-api.ts new file mode 100644 index 00000000000..892869968bb --- /dev/null +++ b/src/@types/pokerogue-api.ts @@ -0,0 +1,9 @@ +/** + * Pokerogue API response for path: `/savedata/session/clear` + */ +export interface PokerogueApiClearSessionData { + /** Contains the error message if any occured */ + error?: string; + /** Is `true` if the request was successfully processed */ + success?: boolean; +} diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 6b53ffd6a7f..ff0ca47bcac 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1201,7 +1201,7 @@ export default class BattleScene extends SceneBase { // Check for mystery encounter // Can only occur in place of a standard (non-boss) wild battle, waves 10-180 - if (this.isWaveMysteryEncounter(newBattleType, newWaveIndex, mysteryEncounterType) || newBattleType === BattleType.MYSTERY_ENCOUNTER || !isNullOrUndefined(mysteryEncounterType)) { + if (this.isWaveMysteryEncounter(newBattleType, newWaveIndex, mysteryEncounterType) || newBattleType === BattleType.MYSTERY_ENCOUNTER) { newBattleType = BattleType.MYSTERY_ENCOUNTER; // Reset base spawn weight this.mysteryEncounterSaveData.encounterSpawnChance = BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT; @@ -3002,7 +3002,7 @@ export default class BattleScene extends SceneBase { if (participantIds.size > 0) { if (this.currentBattle.battleType === BattleType.TRAINER || this.currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) { expValue = Math.floor(expValue * 1.5); - } else if (this.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.currentBattle.mysteryEncounter) { + } else if (this.currentBattle.isBattleMysteryEncounter() && this.currentBattle.mysteryEncounter) { expValue = Math.floor(expValue * this.currentBattle.mysteryEncounter.expMultiplier); } for (const partyMember of nonFaintedPartyMembers) { @@ -3102,9 +3102,10 @@ export default class BattleScene extends SceneBase { // If total number of encounters is lower than expected for the run, slightly favor a new encounter spawn (reverse as well) // Reduces occurrence of runs with total encounters significantly different from AVERAGE_ENCOUNTERS_PER_RUN_TARGET + // Favored rate changes can never exceed 50%. So if base rate is 15/256 and favored rate would add 200/256, result will be (15 + 128)/256 const expectedEncountersByFloor = AVERAGE_ENCOUNTERS_PER_RUN_TARGET / (highestMysteryEncounterWave - lowestMysteryEncounterWave) * (waveIndex - lowestMysteryEncounterWave); const currentRunDiffFromAvg = expectedEncountersByFloor - encounteredEvents.length; - const favoredEncounterRate = sessionEncounterRate + currentRunDiffFromAvg * ANTI_VARIANCE_WEIGHT_MODIFIER; + const favoredEncounterRate = sessionEncounterRate + Math.min(currentRunDiffFromAvg * ANTI_VARIANCE_WEIGHT_MODIFIER, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT / 2); const successRate = isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_RATE_OVERRIDE) ? favoredEncounterRate : Overrides.MYSTERY_ENCOUNTER_RATE_OVERRIDE!; diff --git a/src/battle.ts b/src/battle.ts index f9c16d0189d..778d2467803 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -213,7 +213,7 @@ export default class Battle { getBgmOverride(scene: BattleScene): string | null { const battlers = this.enemyParty.slice(0, this.getBattlerCount()); - if (this.battleType === BattleType.MYSTERY_ENCOUNTER && this.mysteryEncounter?.encounterMode === MysteryEncounterMode.DEFAULT) { + if (this.isBattleMysteryEncounter() && this.mysteryEncounter?.encounterMode === MysteryEncounterMode.DEFAULT) { // Music is overridden for MEs during ME onInit() // Should not use any BGM overrides before swapping from DEFAULT mode return null; @@ -409,6 +409,13 @@ export default class Battle { scene.rngSeedOverride = tempSeedOverride; return ret; } + + /** + * Returns if the battle is of type {@linkcode BattleType.MYSTERY_ENCOUNTER} + */ + isBattleMysteryEncounter(): boolean { + return this.battleType === BattleType.MYSTERY_ENCOUNTER; + } } export class FixedBattle extends Battle { diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 1afbfc932dc..4cdaef7b1b3 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -527,18 +527,19 @@ interface monotypeOverride { */ export class SingleTypeChallenge extends Challenge { private static TYPE_OVERRIDES: monotypeOverride[] = [ - {species: Species.MELOETTA, type: Type.PSYCHIC, fusion: true}, {species: Species.CASTFORM, type: Type.NORMAL, fusion: false}, ]; + // TODO: Find a solution for all Pokemon with this ssui issue, including Basculin and Burmy + private static SPECIES_OVERRIDES: Species[] = [Species.MELOETTA]; constructor() { super(Challenges.SINGLE_TYPE, 18); } - applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { + override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean { const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex); const types = [speciesForm.type1, speciesForm.type2]; - if (soft) { + if (soft && !SingleTypeChallenge.SPECIES_OVERRIDES.includes(pokemon.speciesId)) { const speciesToCheck = [pokemon.speciesId]; while (speciesToCheck.length) { const checking = speciesToCheck.pop(); diff --git a/src/data/egg-moves.ts b/src/data/egg-moves.ts index 3e58f993df2..813ade94020 100644 --- a/src/data/egg-moves.ts +++ b/src/data/egg-moves.ts @@ -5,12 +5,12 @@ import { Species } from "#enums/species"; export const speciesEggMoves = { - [Species.BULBASAUR]: [ Moves.SAPPY_SEED, Moves.SLUDGE_WAVE, Moves.EARTH_POWER, Moves.MATCHA_GOTCHA ], + [Species.BULBASAUR]: [ Moves.SAPPY_SEED, Moves.MALIGNANT_CHAIN, Moves.EARTH_POWER, Moves.MATCHA_GOTCHA ], [Species.CHARMANDER]: [ Moves.DRAGON_DANCE, Moves.BITTER_BLADE, Moves.EARTH_POWER, Moves.OBLIVION_WING ], [Species.SQUIRTLE]: [ Moves.FREEZE_DRY, Moves.SHORE_UP, Moves.BOUNCY_BUBBLE, Moves.ORIGIN_PULSE ], [Species.CATERPIE]: [ Moves.SANDSEAR_STORM, Moves.SILK_TRAP, Moves.TWIN_BEAM, Moves.BLEAKWIND_STORM ], - [Species.WEEDLE]: [ Moves.THOUSAND_ARROWS, Moves.SWORDS_DANCE, Moves.ATTACK_ORDER, Moves.NOXIOUS_TORQUE ], - [Species.PIDGEY]: [ Moves.WILDBOLT_STORM, Moves.SANDSEAR_STORM, Moves.CALM_MIND, Moves.BOOMBURST ], + [Species.WEEDLE]: [ Moves.THOUSAND_ARROWS, Moves.NOXIOUS_TORQUE, Moves.ATTACK_ORDER, Moves.VICTORY_DANCE ], + [Species.PIDGEY]: [ Moves.WILDBOLT_STORM, Moves.SANDSEAR_STORM, Moves.NASTY_PLOT, Moves.BOOMBURST ], [Species.RATTATA]: [ Moves.HYPER_FANG, Moves.PSYCHIC_FANGS, Moves.FIRE_FANG, Moves.EXTREME_SPEED ], [Species.SPEAROW]: [ Moves.FLOATY_FALL, Moves.EXTREME_SPEED, Moves.TIDY_UP, Moves.TRIPLE_ARROWS ], [Species.EKANS]: [ Moves.NOXIOUS_TORQUE, Moves.DRAGON_DANCE, Moves.SLACK_OFF, Moves.SHED_TAIL ], @@ -21,46 +21,46 @@ export const speciesEggMoves = { [Species.ZUBAT]: [ Moves.FLOATY_FALL, Moves.DIRE_CLAW, Moves.SWORDS_DANCE, Moves.COLLISION_COURSE ], [Species.ODDISH]: [ Moves.SLUDGE_BOMB, Moves.FIERY_DANCE, Moves.STRENGTH_SAP, Moves.SPORE ], [Species.PARAS]: [ Moves.LEECH_LIFE, Moves.HORN_LEECH, Moves.CRABHAMMER, Moves.SAPPY_SEED ], - [Species.VENONAT]: [ Moves.SLUDGE_BOMB, Moves.MOONLIGHT, Moves.EARTH_POWER, Moves.MYSTICAL_POWER ], + [Species.VENONAT]: [ Moves.SLUDGE_BOMB, Moves.TOXIC_THREAD, Moves.EARTH_POWER, Moves.STORED_POWER ], [Species.DIGLETT]: [ Moves.TRIPLE_DIVE, Moves.SWORDS_DANCE, Moves.TRIPLE_AXEL, Moves.HEADLONG_RUSH ], - [Species.MEOWTH]: [ Moves.COVET, Moves.SWORDS_DANCE, Moves.DOUBLE_KICK, Moves.TAIL_SLAP ], - [Species.PSYDUCK]: [ Moves.SPLISHY_SPLASH, Moves.AQUA_STEP, Moves.AURA_SPHERE, Moves.MYSTICAL_POWER ], - [Species.MANKEY]: [ Moves.DRAIN_PUNCH, Moves.PLAY_ROUGH, Moves.METEOR_MASH, Moves.NO_RETREAT ], + [Species.MEOWTH]: [ Moves.HEART_STAMP, Moves.SWORDS_DANCE, Moves.SIZZLY_SLIDE, Moves.TAIL_SLAP ], + [Species.PSYDUCK]: [ Moves.FROST_BREATH, Moves.AQUA_STEP, Moves.MYSTICAL_POWER, Moves.BOUNCY_BUBBLE ], + [Species.MANKEY]: [ Moves.DRAIN_PUNCH, Moves.SLACK_OFF, Moves.METEOR_MASH, Moves.NO_RETREAT ], [Species.GROWLITHE]: [ Moves.ZING_ZAP, Moves.PARTING_SHOT, Moves.MORNING_SUN, Moves.SACRED_FIRE ], [Species.POLIWAG]: [ Moves.SLACK_OFF, Moves.WILDBOLT_STORM, Moves.DRAIN_PUNCH, Moves.SURGING_STRIKES ], - [Species.ABRA]: [ Moves.AURA_SPHERE, Moves.BADDY_BAD, Moves.THUNDERBOLT, Moves.PSYSTRIKE ], + [Species.ABRA]: [ Moves.AURA_SPHERE, Moves.BADDY_BAD, Moves.ICE_BEAM, Moves.PSYSTRIKE ], [Species.MACHOP]: [ Moves.COMBAT_TORQUE, Moves.METEOR_MASH, Moves.MOUNTAIN_GALE, Moves.FISSURE ], [Species.BELLSPROUT]: [ Moves.SOLAR_BLADE, Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.VICTORY_DANCE ], [Species.TENTACOOL]: [ Moves.BANEFUL_BUNKER, Moves.STRENGTH_SAP, Moves.BOUNCY_BUBBLE, Moves.MALIGNANT_CHAIN ], - [Species.GEODUDE]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.SHORE_UP, Moves.HEAD_SMASH ], + [Species.GEODUDE]: [ Moves.FLARE_BLITZ, Moves.HEAD_SMASH, Moves.SHORE_UP, Moves.SHELL_SMASH ], [Species.PONYTA]: [ Moves.HIGH_HORSEPOWER, Moves.FIRE_LASH, Moves.SWORDS_DANCE, Moves.VOLT_TACKLE ], [Species.SLOWPOKE]: [ Moves.BOUNCY_BUBBLE, Moves.FLAMETHROWER, Moves.MYSTICAL_POWER, Moves.SHED_TAIL ], - [Species.MAGNEMITE]: [ Moves.PARABOLIC_CHARGE, Moves.BODY_PRESS, Moves.ICE_BEAM, Moves.THUNDERCLAP ], - [Species.FARFETCHD]: [ Moves.IVY_CUDGEL, Moves.TRIPLE_ARROWS, Moves.ROOST, Moves.VICTORY_DANCE ], + [Species.MAGNEMITE]: [ Moves.PARABOLIC_CHARGE, Moves.FLAMETHROWER, Moves.ICE_BEAM, Moves.THUNDERCLAP ], + [Species.FARFETCHD]: [ Moves.IVY_CUDGEL, Moves.TRIPLE_ARROWS, Moves.DRILL_RUN, Moves.VICTORY_DANCE ], [Species.DODUO]: [ Moves.TRIPLE_AXEL, Moves.MULTI_ATTACK, Moves.FLOATY_FALL, Moves.TRIPLE_ARROWS ], [Species.SEEL]: [ Moves.FREEZE_DRY, Moves.BOUNCY_BUBBLE, Moves.SLACK_OFF, Moves.STEAM_ERUPTION ], [Species.GRIMER]: [ Moves.SUCKER_PUNCH, Moves.CURSE, Moves.STRENGTH_SAP, Moves.NOXIOUS_TORQUE ], [Species.SHELLDER]: [ Moves.ROCK_BLAST, Moves.WATER_SHURIKEN, Moves.BANEFUL_BUNKER, Moves.BONE_RUSH ], [Species.GASTLY]: [ Moves.SLUDGE_BOMB, Moves.AURA_SPHERE, Moves.NASTY_PLOT, Moves.ASTRAL_BARRAGE ], - [Species.ONIX]: [ Moves.SHORE_UP, Moves.BODY_PRESS, Moves.HEAVY_SLAM, Moves.DIAMOND_STORM ], + [Species.ONIX]: [ Moves.SHORE_UP, Moves.THOUSAND_WAVES, Moves.COIL, Moves.DIAMOND_STORM ], [Species.DROWZEE]: [ Moves.BADDY_BAD, Moves.STRENGTH_SAP, Moves.LUMINA_CRASH, Moves.DARK_VOID ], - [Species.KRABBY]: [ Moves.FIRE_LASH, Moves.PLAY_ROUGH, Moves.IVY_CUDGEL, Moves.SHELL_SMASH ], - [Species.VOLTORB]: [ Moves.NASTY_PLOT, Moves.OVERHEAT, Moves.FROST_BREATH, Moves.ELECTRO_DRIFT ], + [Species.KRABBY]: [ Moves.DIRE_CLAW, Moves.JET_PUNCH, Moves.IVY_CUDGEL, Moves.SHELL_SMASH ], + [Species.VOLTORB]: [ Moves.NASTY_PLOT, Moves.FUSION_FLARE, Moves.FROST_BREATH, Moves.ELECTRO_DRIFT ], [Species.EXEGGCUTE]: [ Moves.FICKLE_BEAM, Moves.APPLE_ACID, Moves.TRICK_ROOM, Moves.LUMINA_CRASH ], [Species.CUBONE]: [ Moves.HEAD_SMASH, Moves.WOOD_HAMMER, Moves.SHADOW_SNEAK, Moves.BITTER_BLADE ], - [Species.LICKITUNG]: [ Moves.BODY_SLAM, Moves.FIRE_LASH, Moves.GRAV_APPLE, Moves.MILK_DRINK ], + [Species.LICKITUNG]: [ Moves.CRUSH_GRIP, Moves.FIRE_LASH, Moves.SLACK_OFF, Moves.MAGICAL_TORQUE ], [Species.KOFFING]: [ Moves.SCALD, Moves.RECOVER, Moves.BODY_PRESS, Moves.MALIGNANT_CHAIN ], [Species.RHYHORN]: [ Moves.SHORE_UP, Moves.ICE_HAMMER, Moves.ACCELEROCK, Moves.HEAD_SMASH ], [Species.TANGELA]: [ Moves.STRENGTH_SAP, Moves.SNAP_TRAP, Moves.PARTING_SHOT, Moves.SAPPY_SEED ], [Species.KANGASKHAN]: [ Moves.POWER_UP_PUNCH, Moves.TRAILBLAZE, Moves.FACADE, Moves.SEISMIC_TOSS ], [Species.HORSEA]: [ Moves.SNIPE_SHOT, Moves.FROST_BREATH, Moves.HURRICANE, Moves.SPACIAL_REND ], - [Species.GOLDEEN]: [ Moves.DRILL_RUN, Moves.FLIP_TURN, Moves.DRAGON_DANCE, Moves.FISHIOUS_REND ], + [Species.GOLDEEN]: [ Moves.GLACIAL_LANCE, Moves.SUPERCELL_SLAM, Moves.DRAGON_DANCE, Moves.FISHIOUS_REND ], [Species.STARYU]: [ Moves.CALM_MIND, Moves.BOUNCY_BUBBLE, Moves.MOONBLAST, Moves.MYSTICAL_POWER ], [Species.SCYTHER]: [ Moves.MIGHTY_CLEAVE, Moves.BUG_BITE, Moves.STORM_THROW, Moves.DOUBLE_IRON_BASH ], - [Species.PINSIR]: [ Moves.EARTHQUAKE, Moves.LEECH_LIFE, Moves.CLOSE_COMBAT, Moves.EXTREME_SPEED ], - [Species.TAUROS]: [ Moves.HIGH_HORSEPOWER, Moves.BLAZING_TORQUE, Moves.LIQUIDATION, Moves.COMBAT_TORQUE ], + [Species.PINSIR]: [ Moves.HEADLONG_RUSH, Moves.LEECH_LIFE, Moves.CRUSH_GRIP, Moves.EXTREME_SPEED ], + [Species.TAUROS]: [ Moves.HIGH_HORSEPOWER, Moves.FIRE_LASH, Moves.LIQUIDATION, Moves.COMBAT_TORQUE ], [Species.MAGIKARP]: [ Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.DRAGON_ASCENT, Moves.SURGING_STRIKES ], - [Species.LAPRAS]: [ Moves.RECOVER, Moves.FREEZE_DRY, Moves.SHELL_SMASH, Moves.STEAM_ERUPTION ], + [Species.LAPRAS]: [ Moves.RECOVER, Moves.FREEZE_DRY, Moves.SCALD, Moves.SHELL_SMASH ], [Species.DITTO]: [ Moves.MIMIC, Moves.SKETCH, Moves.METRONOME, Moves.IMPRISON ], [Species.EEVEE]: [ Moves.WISH, Moves.NO_RETREAT, Moves.ZIPPY_ZAP, Moves.BOOMBURST ], [Species.PORYGON]: [ Moves.THUNDERCLAP, Moves.AURA_SPHERE, Moves.FLAMETHROWER, Moves.TECHNO_BLAST ], @@ -68,56 +68,56 @@ export const speciesEggMoves = { [Species.KABUTO]: [ Moves.CEASELESS_EDGE, Moves.HIGH_HORSEPOWER, Moves.TRIPLE_DIVE, Moves.MIGHTY_CLEAVE ], [Species.AERODACTYL]: [ Moves.FLOATY_FALL, Moves.FLARE_BLITZ, Moves.SWORDS_DANCE, Moves.MIGHTY_CLEAVE ], [Species.ARTICUNO]: [ Moves.EARTH_POWER, Moves.CALM_MIND, Moves.AURORA_VEIL, Moves.AEROBLAST ], - [Species.ZAPDOS]: [ Moves.WEATHER_BALL, Moves.CALM_MIND, Moves.SANDSEAR_STORM, Moves.ELECTRO_SHOT ], + [Species.ZAPDOS]: [ Moves.BLEAKWIND_STORM, Moves.CALM_MIND, Moves.SANDSEAR_STORM, Moves.ELECTRO_SHOT ], [Species.MOLTRES]: [ Moves.SCORCHING_SANDS, Moves.CALM_MIND, Moves.AEROBLAST, Moves.TORCH_SONG ], [Species.DRATINI]: [ Moves.DRAGON_HAMMER, Moves.CRUSH_GRIP, Moves.FIRE_LASH, Moves.GIGATON_HAMMER ], [Species.MEWTWO]: [ Moves.METEOR_MASH, Moves.MOONBLAST, Moves.THUNDEROUS_KICK, Moves.PHOTON_GEYSER ], [Species.MEW]: [ Moves.PHOTON_GEYSER, Moves.MOONBLAST, Moves.ASTRAL_BARRAGE, Moves.SHELL_SMASH ], [Species.CHIKORITA]: [ Moves.SAPPY_SEED, Moves.STONE_AXE, Moves.DRAGON_DANCE, Moves.SPORE ], - [Species.CYNDAQUIL]: [ Moves.NASTY_PLOT, Moves.SCORCHING_SANDS, Moves.FIERY_DANCE, Moves.ELECTRO_DRIFT ], + [Species.CYNDAQUIL]: [ Moves.NASTY_PLOT, Moves.EARTH_POWER, Moves.FIERY_DANCE, Moves.ELECTRO_DRIFT ], [Species.TOTODILE]: [ Moves.THUNDER_PUNCH, Moves.DRAGON_DANCE, Moves.TRIPLE_AXEL, Moves.FISHIOUS_REND ], - [Species.SENTRET]: [ Moves.TIDY_UP, Moves.THIEF, Moves.NUZZLE, Moves.EXTREME_SPEED ], + [Species.SENTRET]: [ Moves.TIDY_UP, Moves.FAKE_OUT, Moves.NUZZLE, Moves.EXTREME_SPEED ], [Species.HOOTHOOT]: [ Moves.CALM_MIND, Moves.ESPER_WING, Moves.AEROBLAST, Moves.BOOMBURST ], [Species.LEDYBA]: [ Moves.POLLEN_PUFF, Moves.THIEF, Moves.PARTING_SHOT, Moves.SPORE ], [Species.SPINARAK]: [ Moves.PARTING_SHOT, Moves.ATTACK_ORDER, Moves.GASTRO_ACID, Moves.STRENGTH_SAP ], [Species.CHINCHOU]: [ Moves.THUNDERCLAP, Moves.BOUNCY_BUBBLE, Moves.THUNDER_CAGE, Moves.TAIL_GLOW ], - [Species.PICHU]: [ Moves.RISING_VOLTAGE, Moves.SPLISHY_SPLASH, Moves.FLOATY_FALL, Moves.THUNDERCLAP ], + [Species.PICHU]: [ Moves.MOONBLAST, Moves.WAVE_CRASH, Moves.AIR_SLASH, Moves.AURA_WHEEL ], [Species.CLEFFA]: [ Moves.CALM_MIND, Moves.EARTH_POWER, Moves.WISH, Moves.LIGHT_OF_RUIN ], [Species.IGGLYBUFF]: [ Moves.DRAIN_PUNCH, Moves.GRAV_APPLE, Moves.SOFT_BOILED, Moves.EXTREME_SPEED ], [Species.TOGEPI]: [ Moves.SCORCHING_SANDS, Moves.ROOST, Moves.RELIC_SONG, Moves.FIERY_DANCE ], - [Species.NATU]: [ Moves.AEROBLAST, Moves.ROOST, Moves.CALM_MIND, Moves.LUMINA_CRASH ], + [Species.NATU]: [ Moves.AEROBLAST, Moves.ROOST, Moves.MOONBLAST, Moves.LUMINA_CRASH ], [Species.MAREEP]: [ Moves.ICE_BEAM, Moves.PARABOLIC_CHARGE, Moves.CORE_ENFORCER, Moves.TAIL_GLOW ], [Species.HOPPIP]: [ Moves.FLOATY_FALL, Moves.STRENGTH_SAP, Moves.SAPPY_SEED, Moves.SPORE ], [Species.AIPOM]: [ Moves.TIDY_UP, Moves.STORM_THROW, Moves.FAKE_OUT, Moves.POPULATION_BOMB ], - [Species.SUNKERN]: [ Moves.SPORE, Moves.SAPPY_SEED, Moves.FIERY_DANCE, Moves.HYDRO_STEAM ], + [Species.SUNKERN]: [ Moves.SPORE, Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.HYDRO_STEAM ], [Species.YANMA]: [ Moves.NASTY_PLOT, Moves.EARTH_POWER, Moves.HEAT_WAVE, Moves.BLEAKWIND_STORM ], [Species.WOOPER]: [ Moves.SIZZLY_SLIDE, Moves.RECOVER, Moves.CURSE, Moves.SURGING_STRIKES ], [Species.MURKROW]: [ Moves.TRIPLE_ARROWS, Moves.FLOATY_FALL, Moves.TIDY_UP, Moves.WICKED_BLOW ], [Species.MISDREAVUS]: [ Moves.TAKE_HEART, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.ASTRAL_BARRAGE ], [Species.UNOWN]: [ Moves.NATURE_POWER, Moves.COSMIC_POWER, Moves.ANCIENT_POWER, Moves.MYSTICAL_POWER ], [Species.GIRAFARIG]: [ Moves.MYSTICAL_POWER, Moves.NIGHT_DAZE, Moves.RECOVER, Moves.BOOMBURST ], - [Species.PINECO]: [ Moves.METAL_BURST, Moves.LUNGE, Moves.BODY_PRESS, Moves.SHORE_UP ], - [Species.DUNSPARCE]: [ Moves.BODY_SLAM, Moves.MAGICAL_TORQUE, Moves.BLAZING_TORQUE, Moves.EXTREME_SPEED ], + [Species.PINECO]: [ Moves.METAL_BURST, Moves.SHORE_UP, Moves.BODY_PRESS, Moves.DIAMOND_STORM ], + [Species.DUNSPARCE]: [ Moves.WICKED_TORQUE, Moves.MAGICAL_TORQUE, Moves.BLAZING_TORQUE, Moves.EXTREME_SPEED ], [Species.GLIGAR]: [ Moves.FLOATY_FALL, Moves.THOUSAND_WAVES, Moves.ROOST, Moves.MIGHTY_CLEAVE ], [Species.SNUBBULL]: [ Moves.FACADE, Moves.EARTHQUAKE, Moves.SWORDS_DANCE, Moves.EXTREME_SPEED ], [Species.QWILFISH]: [ Moves.BARB_BARRAGE, Moves.BANEFUL_BUNKER, Moves.KNOCK_OFF, Moves.FISHIOUS_REND ], [Species.SHUCKLE]: [ Moves.STUFF_CHEEKS, Moves.HEAL_ORDER, Moves.BODY_PRESS, Moves.SALT_CURE ], [Species.HERACROSS]: [ Moves.ROCK_BLAST, Moves.FIRST_IMPRESSION, Moves.ICICLE_SPEAR, Moves.DRAGON_DANCE ], [Species.SNEASEL]: [ Moves.DIRE_CLAW, Moves.STORM_THROW, Moves.TRIPLE_AXEL, Moves.WICKED_BLOW ], - [Species.TEDDIURSA]: [ Moves.MOUNTAIN_GALE, Moves.RAGING_BULL, Moves.SLACK_OFF, Moves.PRECIPICE_BLADES ], + [Species.TEDDIURSA]: [ Moves.MOUNTAIN_GALE, Moves.FAKE_OUT, Moves.SLACK_OFF, Moves.PRECIPICE_BLADES ], [Species.SLUGMA]: [ Moves.BURNING_BULWARK, Moves.POWER_GEM, Moves.SOLAR_BEAM, Moves.MAGMA_STORM ], [Species.SWINUB]: [ Moves.SLACK_OFF, Moves.LANDS_WRATH, Moves.MIGHTY_CLEAVE, Moves.GLACIAL_LANCE ], [Species.CORSOLA]: [ Moves.SCALD, Moves.FREEZE_DRY, Moves.STRENGTH_SAP, Moves.SALT_CURE ], [Species.REMORAID]: [ Moves.WATER_SHURIKEN, Moves.TAKE_HEART, Moves.SHELL_SIDE_ARM, Moves.BOUNCY_BUBBLE ], - [Species.DELIBIRD]: [ Moves.DRILL_RUN, Moves.FLOATY_FALL, Moves.VICTORY_DANCE, Moves.GLACIAL_LANCE ], + [Species.DELIBIRD]: [ Moves.BONEMERANG, Moves.FLOATY_FALL, Moves.VICTORY_DANCE, Moves.GLACIAL_LANCE ], [Species.SKARMORY]: [ Moves.ROOST, Moves.BODY_PRESS, Moves.SPIKY_SHIELD, Moves.BEAK_BLAST ], - [Species.HOUNDOUR]: [ Moves.HEAT_WAVE, Moves.FIERY_WRATH, Moves.SOLAR_BEAM, Moves.HYDRO_STEAM ], + [Species.HOUNDOUR]: [ Moves.MOONLIGHT, Moves.FIERY_WRATH, Moves.SECRET_SWORD, Moves.HYDRO_STEAM ], [Species.PHANPY]: [ Moves.SHORE_UP, Moves.SWORDS_DANCE, Moves.ICICLE_CRASH, Moves.COLLISION_COURSE ], - [Species.STANTLER]: [ Moves.THUNDEROUS_KICK, Moves.HYPER_VOICE, Moves.BULK_UP, Moves.PHOTON_GEYSER ], + [Species.STANTLER]: [ Moves.THUNDEROUS_KICK, Moves.PHOTON_GEYSER, Moves.SWORDS_DANCE, Moves.BOOMBURST ], [Species.SMEARGLE]: [ Moves.CONVERSION, Moves.BURNING_BULWARK, Moves.SALT_CURE, Moves.DARK_VOID ], [Species.TYROGUE]: [ Moves.VICTORY_DANCE, Moves.THUNDEROUS_KICK, Moves.METEOR_MASH, Moves.WICKED_BLOW ], [Species.SMOOCHUM]: [ Moves.EXPANDING_FORCE, Moves.AURA_SPHERE, Moves.FREEZE_DRY, Moves.QUIVER_DANCE ], - [Species.ELEKID]: [ Moves.BLAZING_TORQUE, Moves.TIDY_UP, Moves.MOUNTAIN_GALE, Moves.ZIPPY_ZAP ], + [Species.ELEKID]: [ Moves.FIRE_LASH, Moves.ZING_ZAP, Moves.MOUNTAIN_GALE, Moves.SHIFT_GEAR ], [Species.MAGBY]: [ Moves.THUNDERCLAP, Moves.EARTH_POWER, Moves.ARMOR_CANNON, Moves.FLEUR_CANNON ], [Species.MILTANK]: [ Moves.BODY_PRESS, Moves.BULK_UP, Moves.YAWN, Moves.SIZZLY_SLIDE ], [Species.RAIKOU]: [ Moves.PARABOLIC_CHARGE, Moves.NASTY_PLOT, Moves.FROST_BREATH, Moves.ELECTRO_DRIFT ], @@ -125,10 +125,10 @@ export const speciesEggMoves = { [Species.SUICUNE]: [ Moves.RECOVER, Moves.NASTY_PLOT, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], [Species.LARVITAR]: [ Moves.DRAGON_DANCE, Moves.MOUNTAIN_GALE, Moves.SHORE_UP, Moves.DIAMOND_STORM ], [Species.LUGIA]: [ Moves.NASTY_PLOT, Moves.LUMINA_CRASH, Moves.AURA_SPHERE, Moves.OBLIVION_WING ], - [Species.HO_OH]: [ Moves.FLOATY_FALL, Moves.PRECIPICE_BLADES, Moves.REVIVAL_BLESSING, Moves.BOLT_BEAK ], + [Species.HO_OH]: [ Moves.BRAVE_BIRD, Moves.DRAGON_DANCE, Moves.REVIVAL_BLESSING, Moves.BOLT_BEAK ], [Species.CELEBI]: [ Moves.PHOTON_GEYSER, Moves.MATCHA_GOTCHA, Moves.REVIVAL_BLESSING, Moves.QUIVER_DANCE ], [Species.TREECKO]: [ Moves.NASTY_PLOT, Moves.APPLE_ACID, Moves.SECRET_SWORD, Moves.DRAGON_ENERGY ], - [Species.TORCHIC]: [ Moves.HIGH_JUMP_KICK, Moves.SUPERCELL_SLAM, Moves.KNOCK_OFF, Moves.V_CREATE ], + [Species.TORCHIC]: [ Moves.HIGH_JUMP_KICK, Moves.SUPERCELL_SLAM, Moves.BURNING_BULWARK, Moves.V_CREATE ], [Species.MUDKIP]: [ Moves.SHORE_UP, Moves.MOUNTAIN_GALE, Moves.BULK_UP, Moves.SURGING_STRIKES ], [Species.POOCHYENA]: [ Moves.JAW_LOCK, Moves.CLOSE_COMBAT, Moves.DIRE_CLAW, Moves.NO_RETREAT ], [Species.ZIGZAGOON]: [ Moves.EXTREME_SPEED, Moves.NUZZLE, Moves.HIGH_HORSEPOWER, Moves.TIDY_UP ], @@ -154,7 +154,7 @@ export const speciesEggMoves = { [Species.ELECTRIKE]: [ Moves.RISING_VOLTAGE, Moves.FLAMETHROWER, Moves.NASTY_PLOT, Moves.ICE_BEAM ], [Species.PLUSLE]: [ Moves.FLAMETHROWER, Moves.GLITZY_GLOW, Moves.SPLISHY_SPLASH, Moves.TAIL_GLOW ], [Species.MINUN]: [ Moves.ICE_BEAM, Moves.BADDY_BAD, Moves.SPARKLY_SWIRL, Moves.TAIL_GLOW ], - [Species.VOLBEAT]: [ Moves.BATON_PASS, Moves.LUNGE, Moves.DECORATE, Moves.VICTORY_DANCE ], + [Species.VOLBEAT]: [ Moves.BATON_PASS, Moves.STICKY_WEB, Moves.DECORATE, Moves.VICTORY_DANCE ], [Species.ILLUMISE]: [ Moves.PARTING_SHOT, Moves.GLITZY_GLOW, Moves.POWDER, Moves.QUIVER_DANCE ], [Species.GULPIN]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.CALM_MIND, Moves.MALIGNANT_CHAIN ], [Species.CARVANHA]: [ Moves.THUNDER_FANG, Moves.SWORDS_DANCE, Moves.OBSTRUCT, Moves.SURGING_STRIKES ], @@ -168,7 +168,7 @@ export const speciesEggMoves = { [Species.SWABLU]: [ Moves.ROOST, Moves.NASTY_PLOT, Moves.FLOATY_FALL, Moves.BOOMBURST ], [Species.ZANGOOSE]: [ Moves.FACADE, Moves.HIGH_HORSEPOWER, Moves.EXTREME_SPEED, Moves.TIDY_UP ], [Species.SEVIPER]: [ Moves.ICE_BEAM, Moves.BITTER_BLADE, Moves.SUCKER_PUNCH, Moves.NO_RETREAT ], - [Species.LUNATONE]: [ Moves.POWER_GEM, Moves.NIGHT_DAZE, Moves.SHELL_SMASH, Moves.LUMINA_CRASH ], + [Species.LUNATONE]: [ Moves.POWER_GEM, Moves.MOONGEIST_BEAM, Moves.SHELL_SMASH, Moves.LUMINA_CRASH ], [Species.SOLROCK]: [ Moves.PSYSHIELD_BASH, Moves.MIGHTY_CLEAVE, Moves.SHELL_SMASH, Moves.SACRED_FIRE ], [Species.BARBOACH]: [ Moves.DRAGON_DANCE, Moves.ZING_ZAP, Moves.ICE_SPINNER, Moves.SURGING_STRIKES ], [Species.CORPHISH]: [ Moves.CEASELESS_EDGE, Moves.JET_PUNCH, Moves.SUCKER_PUNCH, Moves.SHELL_SMASH ], @@ -177,7 +177,7 @@ export const speciesEggMoves = { [Species.ANORITH]: [ Moves.FIRST_IMPRESSION, Moves.LEECH_LIFE, Moves.DRAGON_DANCE, Moves.MIGHTY_CLEAVE ], [Species.FEEBAS]: [ Moves.CALM_MIND, Moves.FREEZE_DRY, Moves.MOONBLAST, Moves.STEAM_ERUPTION ], [Species.CASTFORM]: [ Moves.BOOMBURST, Moves.HYDRO_STEAM, Moves.ERUPTION, Moves.QUIVER_DANCE ], - [Species.KECLEON]: [ Moves.DRAIN_PUNCH, Moves.DRAGON_DANCE, Moves.EXTREME_SPEED, Moves.MULTI_ATTACK ], + [Species.KECLEON]: [ Moves.ZIPPY_ZAP, Moves.COIL, Moves.EXTREME_SPEED, Moves.MULTI_ATTACK ], [Species.SHUPPET]: [ Moves.STORM_THROW, Moves.TIDY_UP, Moves.PARTING_SHOT, Moves.SPECTRAL_THIEF ], [Species.DUSKULL]: [ Moves.BULK_UP, Moves.DRAIN_PUNCH, Moves.STRENGTH_SAP, Moves.RAGE_FIST ], [Species.TROPIUS]: [ Moves.STUFF_CHEEKS, Moves.EARTH_POWER, Moves.APPLE_ACID, Moves.SAPPY_SEED ], @@ -189,13 +189,13 @@ export const speciesEggMoves = { [Species.RELICANTH]: [ Moves.DRAGON_DANCE, Moves.SHORE_UP, Moves.WAVE_CRASH, Moves.DIAMOND_STORM ], [Species.LUVDISC]: [ Moves.BATON_PASS, Moves.HEART_SWAP, Moves.GLITZY_GLOW, Moves.REVIVAL_BLESSING ], [Species.BAGON]: [ Moves.FLOATY_FALL, Moves.FIRE_LASH, Moves.DRAGON_DANCE, Moves.GLAIVE_RUSH ], - [Species.BELDUM]: [ Moves.HIGH_HORSEPOWER, Moves.RECOVER, Moves.TRIPLE_AXEL, Moves.SHIFT_GEAR ], + [Species.BELDUM]: [ Moves.HEADLONG_RUSH, Moves.DRAIN_PUNCH, Moves.TRIPLE_AXEL, Moves.SHIFT_GEAR ], [Species.REGIROCK]: [ Moves.STONE_AXE, Moves.BODY_PRESS, Moves.SHORE_UP, Moves.SALT_CURE ], [Species.REGICE]: [ Moves.EARTH_POWER, Moves.TAKE_HEART, Moves.RECOVER, Moves.FREEZE_DRY ], [Species.REGISTEEL]: [ Moves.BODY_PRESS, Moves.SIZZLY_SLIDE, Moves.RECOVER, Moves.GIGATON_HAMMER ], [Species.LATIAS]: [ Moves.CORE_ENFORCER, Moves.FUSION_FLARE, Moves.SPARKLY_SWIRL, Moves.MYSTICAL_POWER ], [Species.LATIOS]: [ Moves.CORE_ENFORCER, Moves.BLUE_FLARE, Moves.NASTY_PLOT, Moves.TACHYON_CUTTER ], - [Species.KYOGRE]: [ Moves.BOUNCY_BUBBLE, Moves.HURRICANE, Moves.FREEZE_DRY, Moves.ELECTRO_SHOT ], + [Species.KYOGRE]: [ Moves.RECOVER, Moves.HURRICANE, Moves.FLIP_TURN, Moves.WILDBOLT_STORM ], [Species.GROUDON]: [ Moves.STONE_AXE, Moves.SOLAR_BLADE, Moves.MORNING_SUN, Moves.SACRED_FIRE ], [Species.RAYQUAZA]: [ Moves.V_CREATE, Moves.DRAGON_DARTS, Moves.CORE_ENFORCER, Moves.OBLIVION_WING ], [Species.JIRACHI]: [ Moves.TACHYON_CUTTER, Moves.TRIPLE_ARROWS, Moves.ROCK_SLIDE, Moves.SHELL_SMASH ], @@ -206,7 +206,7 @@ export const speciesEggMoves = { [Species.STARLY]: [ Moves.SWORDS_DANCE, Moves.HEAD_CHARGE, Moves.FLARE_BLITZ, Moves.EXTREME_SPEED ], [Species.BIDOOF]: [ Moves.EXTREME_SPEED, Moves.COSMIC_POWER, Moves.POWER_TRIP, Moves.AQUA_STEP ], [Species.KRICKETOT]: [ Moves.BONEMERANG, Moves.VICTORY_DANCE, Moves.STONE_AXE, Moves.POPULATION_BOMB ], - [Species.SHINX]: [ Moves.FIRE_LASH, Moves.TRIPLE_AXEL, Moves.FACADE, Moves.BOLT_STRIKE ], + [Species.SHINX]: [ Moves.FIRE_LASH, Moves.TRIPLE_AXEL, Moves.ZIPPY_ZAP, Moves.BOLT_STRIKE ], [Species.BUDEW]: [ Moves.FIERY_DANCE, Moves.ACID_SPRAY, Moves.BOUNCY_BUBBLE, Moves.QUIVER_DANCE ], [Species.CRANIDOS]: [ Moves.VOLT_TACKLE, Moves.ACCELEROCK, Moves.FLARE_BLITZ, Moves.SHIFT_GEAR ], [Species.SHIELDON]: [ Moves.SHORE_UP, Moves.BODY_PRESS, Moves.KINGS_SHIELD, Moves.DIAMOND_STORM ], @@ -223,7 +223,7 @@ export const speciesEggMoves = { [Species.STUNKY]: [ Moves.CEASELESS_EDGE, Moves.KNOCK_OFF, Moves.RECOVER, Moves.DIRE_CLAW ], [Species.BRONZOR]: [ Moves.RECOVER, Moves.TACHYON_CUTTER, Moves.GLARE, Moves.LUMINA_CRASH ], [Species.BONSLY]: [ Moves.ACCELEROCK, Moves.SWORDS_DANCE, Moves.STRENGTH_SAP, Moves.SAPPY_SEED ], - [Species.MIME_JR]: [ Moves.CALM_MIND, Moves.MOONBLAST, Moves.SIZZLY_SLIDE, Moves.LUMINA_CRASH ], + [Species.MIME_JR]: [ Moves.CHILLY_RECEPTION, Moves.MOONBLAST, Moves.FROST_BREATH, Moves.LUMINA_CRASH ], [Species.HAPPINY]: [ Moves.COTTON_GUARD, Moves.SEISMIC_TOSS, Moves.SIZZLY_SLIDE, Moves.REVIVAL_BLESSING ], [Species.CHATOT]: [ Moves.SPARKLING_ARIA, Moves.TORCH_SONG, Moves.BATON_PASS, Moves.BOOMBURST ], [Species.SPIRITOMB]: [ Moves.PARTING_SHOT, Moves.BADDY_BAD, Moves.STRENGTH_SAP, Moves.SPECTRAL_THIEF ], @@ -232,7 +232,7 @@ export const speciesEggMoves = { [Species.RIOLU]: [ Moves.THUNDEROUS_KICK, Moves.TACHYON_CUTTER, Moves.TRIPLE_AXEL, Moves.DOUBLE_IRON_BASH ], [Species.HIPPOPOTAS]: [ Moves.SHORE_UP, Moves.STONE_AXE, Moves.BULK_UP, Moves.SALT_CURE ], [Species.SKORUPI]: [ Moves.COIL, Moves.DIRE_CLAW, Moves.CRABHAMMER, Moves.WICKED_BLOW ], - [Species.CROAGUNK]: [ Moves.DIRE_CLAW, Moves.ICE_PUNCH, Moves.THUNDEROUS_KICK, Moves.VICTORY_DANCE ], + [Species.CROAGUNK]: [ Moves.DIRE_CLAW, Moves.ICE_SPINNER, Moves.THUNDEROUS_KICK, Moves.VICTORY_DANCE ], [Species.CARNIVINE]: [ Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.COIL, Moves.SAPPY_SEED ], [Species.FINNEON]: [ Moves.QUIVER_DANCE, Moves.BOUNCY_BUBBLE, Moves.FREEZE_DRY, Moves.ORIGIN_PULSE ], [Species.MANTYKE]: [ Moves.SPLISHY_SPLASH, Moves.FREEZY_FROST, Moves.NASTY_PLOT, Moves.OBLIVION_WING ], @@ -243,7 +243,7 @@ export const speciesEggMoves = { [Species.AZELF]: [ Moves.PSYSTRIKE, Moves.ICE_BEAM, Moves.MOONBLAST, Moves.TAIL_GLOW ], [Species.DIALGA]: [ Moves.CORE_ENFORCER, Moves.TAKE_HEART, Moves.RECOVER, Moves.MAKE_IT_RAIN ], [Species.PALKIA]: [ Moves.RECOVER, Moves.TAKE_HEART, Moves.FREEZE_DRY, Moves.ORIGIN_PULSE ], - [Species.HEATRAN]: [ Moves.TORCH_SONG, Moves.RECOVER, Moves.TACHYON_CUTTER, Moves.MATCHA_GOTCHA ], + [Species.HEATRAN]: [ Moves.MATCHA_GOTCHA, Moves.RECOVER, Moves.TACHYON_CUTTER, Moves.TORCH_SONG ], [Species.REGIGIGAS]: [ Moves.SKILL_SWAP, Moves.RECOVER, Moves.EXTREME_SPEED, Moves.GIGATON_HAMMER ], [Species.GIRATINA]: [ Moves.DRAGON_DANCE, Moves.GLAIVE_RUSH, Moves.RECOVER, Moves.SPECTRAL_THIEF ], [Species.CRESSELIA]: [ Moves.COSMIC_POWER, Moves.SECRET_SWORD, Moves.SIZZLY_SLIDE, Moves.LUMINA_CRASH ], @@ -274,18 +274,18 @@ export const speciesEggMoves = { [Species.THROH]: [ Moves.MACH_PUNCH, Moves.SLACK_OFF, Moves.METEOR_MASH, Moves.RAGE_FIST ], [Species.SAWK]: [ Moves.DRAIN_PUNCH, Moves.SUCKER_PUNCH, Moves.METEOR_MASH, Moves.VICTORY_DANCE ], [Species.SEWADDLE]: [ Moves.STONE_AXE, Moves.PSYCHO_CUT, Moves.BITTER_BLADE, Moves.VICTORY_DANCE ], - [Species.VENIPEDE]: [ Moves.SWORDS_DANCE, Moves.LEECH_LIFE, Moves.NOXIOUS_TORQUE, Moves.POWER_TRIP ], + [Species.VENIPEDE]: [ Moves.BANEFUL_BUNKER, Moves.LEECH_LIFE, Moves.NOXIOUS_TORQUE, Moves.POWER_TRIP ], [Species.COTTONEE]: [ Moves.POLLEN_PUFF, Moves.PARTING_SHOT, Moves.SLEEP_POWDER, Moves.SEED_FLARE ], [Species.PETILIL]: [ Moves.THUNDEROUS_KICK, Moves.SPARKLING_ARIA, Moves.FIERY_DANCE, Moves.FLOWER_TRICK ], [Species.BASCULIN]: [ Moves.LAST_RESPECTS, Moves.CLOSE_COMBAT, Moves.SPLISHY_SPLASH, Moves.NO_RETREAT ], [Species.SANDILE]: [ Moves.DIRE_CLAW, Moves.HIGH_HORSEPOWER, Moves.FIRE_LASH, Moves.WICKED_BLOW ], [Species.DARUMAKA]: [ Moves.DRAIN_PUNCH, Moves.ZIPPY_ZAP, Moves.EARTHQUAKE, Moves.PYRO_BALL ], - [Species.MARACTUS]: [ Moves.SCORCHING_SANDS, Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.SEED_FLARE ], + [Species.MARACTUS]: [ Moves.EARTH_POWER, Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.SEED_FLARE ], [Species.DWEBBLE]: [ Moves.CRABHAMMER, Moves.STONE_AXE, Moves.LEECH_LIFE, Moves.MIGHTY_CLEAVE ], - [Species.SCRAGGY]: [ Moves.SUCKER_PUNCH, Moves.BULLET_PUNCH, Moves.DRAGON_DANCE, Moves.COLLISION_COURSE ], + [Species.SCRAGGY]: [ Moves.SUCKER_PUNCH, Moves.BULLET_PUNCH, Moves.NOXIOUS_TORQUE, Moves.VICTORY_DANCE ], [Species.SIGILYPH]: [ Moves.MOONBLAST, Moves.CALM_MIND, Moves.FREEZING_GLARE, Moves.OBLIVION_WING ], - [Species.YAMASK]: [ Moves.STRENGTH_SAP, Moves.INFERNAL_PARADE, Moves.AURA_SPHERE, Moves.ASTRAL_BARRAGE ], - [Species.TIRTOUGA]: [ Moves.ICE_SPINNER, Moves.LIQUIDATION, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE ], + [Species.YAMASK]: [ Moves.STRENGTH_SAP, Moves.GLARE, Moves.AURA_SPHERE, Moves.ASTRAL_BARRAGE ], + [Species.TIRTOUGA]: [ Moves.ICE_SPINNER, Moves.AQUA_STEP, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE ], [Species.ARCHEN]: [ Moves.ROOST, Moves.EARTHQUAKE, Moves.FLOATY_FALL, Moves.MIGHTY_CLEAVE ], [Species.TRUBBISH]: [ Moves.COIL, Moves.RECOVER, Moves.DIRE_CLAW, Moves.GIGATON_HAMMER ], [Species.ZORUA]: [ Moves.FLAMETHROWER, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.FIERY_WRATH ], @@ -295,19 +295,19 @@ export const speciesEggMoves = { [Species.DUCKLETT]: [ Moves.SPLISHY_SPLASH, Moves.EARTH_POWER, Moves.WILDBOLT_STORM, Moves.QUIVER_DANCE ], [Species.VANILLITE]: [ Moves.EARTH_POWER, Moves.AURORA_VEIL, Moves.CALM_MIND, Moves.SPARKLY_SWIRL ], [Species.DEERLING]: [ Moves.TIDY_UP, Moves.FLOWER_TRICK, Moves.BODY_SLAM, Moves.COMBAT_TORQUE ], - [Species.EMOLGA]: [ Moves.TRIPLE_AXEL, Moves.SPLISHY_SPLASH, Moves.TAILWIND, Moves.ZIPPY_ZAP ], - [Species.KARRABLAST]: [ Moves.LEECH_LIFE, Moves.HEAL_ORDER, Moves.HIGH_HORSEPOWER, Moves.DOUBLE_IRON_BASH ], + [Species.EMOLGA]: [ Moves.TRIPLE_AXEL, Moves.SPLISHY_SPLASH, Moves.FLOATY_FALL, Moves.AURA_WHEEL ], + [Species.KARRABLAST]: [ Moves.LEECH_LIFE, Moves.BITTER_BLADE, Moves.HIGH_HORSEPOWER, Moves.DOUBLE_IRON_BASH ], [Species.FOONGUS]: [ Moves.POLLEN_PUFF, Moves.PARTING_SHOT, Moves.FOUL_PLAY, Moves.SAPPY_SEED ], - [Species.FRILLISH]: [ Moves.STRENGTH_SAP, Moves.INFERNAL_PARADE, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], - [Species.ALOMOMOLA]: [ Moves.FLIP_TURN, Moves.HEART_SWAP, Moves.TOXIC, Moves.GLITZY_GLOW ], - [Species.JOLTIK]: [ Moves.THUNDER, Moves.PARABOLIC_CHARGE, Moves.EARTH_POWER, Moves.QUIVER_DANCE ], + [Species.FRILLISH]: [ Moves.STRENGTH_SAP, Moves.BUZZY_BUZZ, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], + [Species.ALOMOMOLA]: [ Moves.FLIP_TURN, Moves.HEART_SWAP, Moves.GLITZY_GLOW, Moves.REVIVAL_BLESSING ], + [Species.JOLTIK]: [ Moves.WILDBOLT_STORM, Moves.PARABOLIC_CHARGE, Moves.EARTH_POWER, Moves.QUIVER_DANCE ], [Species.FERROSEED]: [ Moves.STRENGTH_SAP, Moves.BODY_PRESS, Moves.SPIKY_SHIELD, Moves.SAPPY_SEED ], [Species.KLINK]: [ Moves.TRIPLE_AXEL, Moves.HIGH_HORSEPOWER, Moves.FUSION_BOLT, Moves.DOUBLE_IRON_BASH ], - [Species.TYNAMO]: [ Moves.SCALD, Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.PLASMA_FISTS ], - [Species.ELGYEM]: [ Moves.LUSTER_PURGE, Moves.TRICK_ROOM, Moves.AURA_SPHERE, Moves.TAIL_GLOW ], + [Species.TYNAMO]: [ Moves.SCALD, Moves.STRENGTH_SAP, Moves.FIRE_LASH, Moves.AURA_WHEEL ], + [Species.ELGYEM]: [ Moves.LUSTER_PURGE, Moves.BADDY_BAD, Moves.AURA_SPHERE, Moves.TAIL_GLOW ], [Species.LITWICK]: [ Moves.FIERY_DANCE, Moves.EARTH_POWER, Moves.MOONBLAST, Moves.ASTRAL_BARRAGE ], [Species.AXEW]: [ Moves.STONE_AXE, Moves.DIRE_CLAW, Moves.BITTER_BLADE, Moves.GLAIVE_RUSH ], - [Species.CUBCHOO]: [ Moves.TRIPLE_AXEL, Moves.LIQUIDATION, Moves.SWORDS_DANCE, Moves.COLLISION_COURSE ], + [Species.CUBCHOO]: [ Moves.MOUNTAIN_GALE, Moves.AQUA_STEP, Moves.ICE_SHARD, Moves.COLLISION_COURSE ], [Species.CRYOGONAL]: [ Moves.FREEZING_GLARE, Moves.AURORA_VEIL, Moves.NASTY_PLOT, Moves.ORIGIN_PULSE ], [Species.SHELMET]: [ Moves.POWER_GEM, Moves.NASTY_PLOT, Moves.EARTH_POWER, Moves.STEAM_ERUPTION ], [Species.STUNFISK]: [ Moves.BANEFUL_BUNKER, Moves.SANDSEAR_STORM, Moves.STRENGTH_SAP, Moves.THUNDERCLAP ], @@ -315,24 +315,24 @@ export const speciesEggMoves = { [Species.DRUDDIGON]: [ Moves.FIRE_LASH, Moves.ROOST, Moves.DRAGON_DARTS, Moves.CLANGOROUS_SOUL ], [Species.GOLETT]: [ Moves.SHIFT_GEAR, Moves.DRAIN_PUNCH, Moves.HEADLONG_RUSH, Moves.RAGE_FIST ], [Species.PAWNIARD]: [ Moves.SUCKER_PUNCH, Moves.CEASELESS_EDGE, Moves.BITTER_BLADE, Moves.LAST_RESPECTS ], - [Species.BOUFFALANT]: [ Moves.SLACK_OFF, Moves.JUMP_KICK, Moves.HEAD_SMASH, Moves.FLARE_BLITZ ], + [Species.BOUFFALANT]: [ Moves.SLACK_OFF, Moves.HIGH_JUMP_KICK, Moves.HEAD_SMASH, Moves.FLARE_BLITZ ], [Species.RUFFLET]: [ Moves.FLOATY_FALL, Moves.AURA_SPHERE, Moves.NO_RETREAT, Moves.BOLT_BEAK ], [Species.VULLABY]: [ Moves.FOUL_PLAY, Moves.BODY_PRESS, Moves.ROOST, Moves.RUINATION ], [Species.HEATMOR]: [ Moves.EARTH_POWER, Moves.OVERHEAT, Moves.THUNDERBOLT, Moves.V_CREATE ], [Species.DURANT]: [ Moves.HIGH_HORSEPOWER, Moves.FIRST_IMPRESSION, Moves.SWORDS_DANCE, Moves.BEHEMOTH_BASH ], [Species.DEINO]: [ Moves.FIERY_WRATH, Moves.ESPER_WING, Moves.SLUDGE_BOMB, Moves.FICKLE_BEAM ], [Species.LARVESTA]: [ Moves.THUNDERBOLT, Moves.MATCHA_GOTCHA, Moves.EARTH_POWER, Moves.TORCH_SONG ], - [Species.COBALION]: [ Moves.BEHEMOTH_BLADE, Moves.BODY_PRESS, Moves.CEASELESS_EDGE, Moves.VICTORY_DANCE ], + [Species.COBALION]: [ Moves.BEHEMOTH_BLADE, Moves.MIGHTY_CLEAVE, Moves.CEASELESS_EDGE, Moves.VICTORY_DANCE ], [Species.TERRAKION]: [ Moves.MIGHTY_CLEAVE, Moves.HEADLONG_RUSH, Moves.CEASELESS_EDGE, Moves.VICTORY_DANCE ], [Species.VIRIZION]: [ Moves.PSYBLADE, Moves.SAPPY_SEED, Moves.CEASELESS_EDGE, Moves.VICTORY_DANCE ], [Species.TORNADUS]: [ Moves.EARTH_POWER, Moves.PARTING_SHOT, Moves.ICE_BEAM, Moves.OBLIVION_WING ], [Species.THUNDURUS]: [ Moves.EARTH_POWER, Moves.HURRICANE, Moves.FROST_BREATH, Moves.ELECTRO_SHOT ], - [Species.RESHIRAM]: [ Moves.MORNING_SUN, Moves.TAKE_HEART, Moves.FICKLE_BEAM, Moves.ERUPTION ], - [Species.ZEKROM]: [ Moves.DRAGON_DANCE, Moves.THUNDEROUS_KICK, Moves.DRAGON_HAMMER, Moves.BOLT_BEAK ], + [Species.RESHIRAM]: [ Moves.ENERGY_BALL, Moves.TAKE_HEART, Moves.FICKLE_BEAM, Moves.ERUPTION ], + [Species.ZEKROM]: [ Moves.TRIPLE_AXEL, Moves.THUNDEROUS_KICK, Moves.DRAGON_HAMMER, Moves.BOLT_BEAK ], [Species.LANDORUS]: [ Moves.STONE_AXE, Moves.FLOATY_FALL, Moves.ROOST, Moves.BLEAKWIND_STORM ], - [Species.KYUREM]: [ Moves.DRAGON_DARTS, Moves.CORE_ENFORCER, Moves.NO_RETREAT, Moves.GLACIAL_LANCE ], + [Species.KYUREM]: [ Moves.DRAGON_DARTS, Moves.GLACIAL_LANCE, Moves.NO_RETREAT, Moves.DRAGON_ENERGY ], [Species.KELDEO]: [ Moves.BOUNCY_BUBBLE, Moves.THUNDERBOLT, Moves.FREEZE_DRY, Moves.STEAM_ERUPTION ], - [Species.MELOETTA]: [ Moves.VICTORY_DANCE, Moves.QUIVER_DANCE, Moves.TRIPLE_ARROWS, Moves.TORCH_SONG ], + [Species.MELOETTA]: [ Moves.BODY_SLAM, Moves.TORCH_SONG, Moves.TRIPLE_ARROWS, Moves.BOOMBURST ], [Species.GENESECT]: [ Moves.EXTREME_SPEED, Moves.U_TURN, Moves.TACHYON_CUTTER, Moves.TAIL_GLOW ], [Species.CHESPIN]: [ Moves.BODY_PRESS, Moves.SYNTHESIS, Moves.CEASELESS_EDGE, Moves.SAPPY_SEED ], [Species.FENNEKIN]: [ Moves.EXPANDING_FORCE, Moves.MOONBLAST, Moves.THUNDERBOLT, Moves.TORCH_SONG ], @@ -344,13 +344,13 @@ export const speciesEggMoves = { [Species.FLABEBE]: [ Moves.GLITZY_GLOW, Moves.MYSTICAL_FIRE, Moves.TAKE_HEART, Moves.SEED_FLARE ], [Species.SKIDDO]: [ Moves.HIGH_HORSEPOWER, Moves.GRASSY_GLIDE, Moves.STONE_AXE, Moves.SAPPY_SEED ], [Species.PANCHAM]: [ Moves.DRAIN_PUNCH, Moves.SUCKER_PUNCH, Moves.METEOR_MASH, Moves.WICKED_BLOW ], - [Species.FURFROU]: [ Moves.TIDY_UP, Moves.SLACK_OFF, Moves.COVET, Moves.MULTI_ATTACK ], - [Species.ESPURR]: [ Moves.GLARE, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.PSYSTRIKE ], + [Species.FURFROU]: [ Moves.TIDY_UP, Moves.SLACK_OFF, Moves.COMBAT_TORQUE, Moves.MULTI_ATTACK ], + [Species.ESPURR]: [ Moves.LUSTER_PURGE, Moves.MOONBLAST, Moves.AURA_SPHERE, Moves.DARK_VOID ], [Species.HONEDGE]: [ Moves.TACHYON_CUTTER, Moves.SHADOW_BONE, Moves.BITTER_BLADE, Moves.BEHEMOTH_BLADE ], - [Species.SPRITZEE]: [ Moves.TRICK_ROOM, Moves.FOUL_PLAY, Moves.WISH, Moves.REVIVAL_BLESSING ], + [Species.SPRITZEE]: [ Moves.SPEED_SWAP, Moves.TORCH_SONG, Moves.ROOST, Moves.REVIVAL_BLESSING ], [Species.SWIRLIX]: [ Moves.BELLY_DRUM, Moves.HEADLONG_RUSH, Moves.MAGICAL_TORQUE, Moves.REVIVAL_BLESSING ], [Species.INKAY]: [ Moves.POWER_TRIP, Moves.SPIN_OUT, Moves.RECOVER, Moves.PSYCHO_BOOST ], - [Species.BINACLE]: [ Moves.TRIPLE_AXEL, Moves.ACCELEROCK, Moves.DIRE_CLAW, Moves.MIGHTY_CLEAVE ], + [Species.BINACLE]: [ Moves.TRIPLE_AXEL, Moves.CRABHAMMER, Moves.DIRE_CLAW, Moves.MIGHTY_CLEAVE ], [Species.SKRELP]: [ Moves.STRENGTH_SAP, Moves.TRICK_ROOM, Moves.CALM_MIND, Moves.CORE_ENFORCER ], [Species.CLAUNCHER]: [ Moves.SHELL_SMASH, Moves.ARMOR_CANNON, Moves.WATER_SHURIKEN, Moves.ORIGIN_PULSE ], [Species.HELIOPTILE]: [ Moves.WEATHER_BALL, Moves.HYDRO_STEAM, Moves.EARTH_POWER, Moves.BOOMBURST ], @@ -360,15 +360,15 @@ export const speciesEggMoves = { [Species.DEDENNE]: [ Moves.BOOMBURST, Moves.FAKE_OUT, Moves.NASTY_PLOT, Moves.REVIVAL_BLESSING ], [Species.CARBINK]: [ Moves.BODY_PRESS, Moves.SHORE_UP, Moves.SPARKLY_SWIRL, Moves.DIAMOND_STORM ], [Species.GOOMY]: [ Moves.SCALD, Moves.RECOVER, Moves.CALM_MIND, Moves.MAKE_IT_RAIN ], - [Species.KLEFKI]: [ Moves.HEAL_BELL, Moves.ENCORE, Moves.TOPSY_TURVY, Moves.INSTRUCT ], + [Species.KLEFKI]: [ Moves.HEAL_BELL, Moves.ENCORE, Moves.INSTRUCT, Moves.TOPSY_TURVY ], [Species.PHANTUMP]: [ Moves.RAGE_FIST, Moves.TRICK_ROOM, Moves.SYNTHESIS, Moves.SAPPY_SEED ], [Species.PUMPKABOO]: [ Moves.SPIRIT_SHACKLE, Moves.FIRE_LASH, Moves.DIRE_CLAW, Moves.SAPPY_SEED ], [Species.BERGMITE]: [ Moves.STONE_AXE, Moves.METAL_BURST, Moves.BODY_PRESS, Moves.GLACIAL_LANCE ], [Species.NOIBAT]: [ Moves.AEROBLAST, Moves.OVERDRIVE, Moves.NASTY_PLOT, Moves.CLANGING_SCALES ], - [Species.XERNEAS]: [ Moves.SEARING_SHOT, Moves.LUMINA_CRASH, Moves.STRENGTH_SAP, Moves.TAIL_GLOW ], + [Species.XERNEAS]: [ Moves.EARTH_POWER, Moves.SPRINGTIDE_STORM, Moves.STRENGTH_SAP, Moves.TAIL_GLOW ], [Species.YVELTAL]: [ Moves.SHELL_SIDE_ARM, Moves.POWER_TRIP, Moves.FIERY_WRATH, Moves.CLANGOROUS_SOUL ], [Species.ZYGARDE]: [ Moves.DRAGON_DARTS, Moves.HEAL_ORDER, Moves.CLANGOROUS_SOUL, Moves.DOUBLE_IRON_BASH ], - [Species.DIANCIE]: [ Moves.MAGICAL_TORQUE, Moves.BODY_PRESS, Moves.SHORE_UP, Moves.GEOMANCY ], + [Species.DIANCIE]: [ Moves.MAGICAL_TORQUE, Moves.AURA_SPHERE, Moves.SHORE_UP, Moves.GEOMANCY ], [Species.HOOPA]: [ Moves.PHOTON_GEYSER, Moves.SECRET_SWORD, Moves.FIERY_WRATH, Moves.SHELL_SMASH ], [Species.VOLCANION]: [ Moves.HYDRO_STEAM, Moves.CALM_MIND, Moves.ENERGY_BALL, Moves.MAGMA_STORM ], [Species.ROWLET]: [ Moves.THOUSAND_ARROWS, Moves.SHADOW_BONE, Moves.FIRST_IMPRESSION, Moves.VICTORY_DANCE ], @@ -379,7 +379,7 @@ export const speciesEggMoves = { [Species.GRUBBIN]: [ Moves.ICE_BEAM, Moves.EARTH_POWER, Moves.THUNDERCLAP, Moves.QUIVER_DANCE ], [Species.CRABRAWLER]: [ Moves.JET_PUNCH, Moves.SHORE_UP, Moves.SUCKER_PUNCH, Moves.SURGING_STRIKES ], [Species.ORICORIO]: [ Moves.QUIVER_DANCE, Moves.FIERY_DANCE, Moves.THUNDERCLAP, Moves.OBLIVION_WING ], - [Species.CUTIEFLY]: [ Moves.STICKY_WEB, Moves.MOONBLAST, Moves.HEAT_WAVE, Moves.SPORE ], + [Species.CUTIEFLY]: [ Moves.STICKY_WEB, Moves.SLEEP_POWDER, Moves.HEAT_WAVE, Moves.SPARKLY_SWIRL ], [Species.ROCKRUFF]: [ Moves.HIGH_HORSEPOWER, Moves.TIDY_UP, Moves.ICE_SPINNER, Moves.MIGHTY_CLEAVE ], [Species.WISHIWASHI]: [ Moves.HEAL_ORDER, Moves.ICE_SPINNER, Moves.DRAGON_DANCE, Moves.JET_PUNCH ], [Species.MAREANIE]: [ Moves.CEASELESS_EDGE, Moves.SIZZLY_SLIDE, Moves.BODY_PRESS, Moves.LEECH_SEED ], @@ -394,31 +394,31 @@ export const speciesEggMoves = { [Species.ORANGURU]: [ Moves.JUNGLE_HEALING, Moves.YAWN, Moves.FOLLOW_ME, Moves.LUMINA_CRASH ], [Species.PASSIMIAN]: [ Moves.FAKE_OUT, Moves.SUCKER_PUNCH, Moves.ZING_ZAP, Moves.PYRO_BALL ], [Species.WIMPOD]: [ Moves.TRIPLE_AXEL, Moves.OBSTRUCT, Moves.JET_PUNCH, Moves.SURGING_STRIKES ], - [Species.SANDYGAST]: [ Moves.SCORCHING_SANDS, Moves.SPLISHY_SPLASH, Moves.TAKE_HEART, Moves.SALT_CURE ], + [Species.SANDYGAST]: [ Moves.SANDSEAR_STORM, Moves.SPLISHY_SPLASH, Moves.TAKE_HEART, Moves.SALT_CURE ], [Species.PYUKUMUKU]: [ Moves.COMEUPPANCE, Moves.BANEFUL_BUNKER, Moves.TOXIC_SPIKES, Moves.SALT_CURE ], [Species.TYPE_NULL]: [ Moves.DIRE_CLAW, Moves.RECOVER, Moves.EXTREME_SPEED, Moves.SHELL_SMASH ], [Species.MINIOR]: [ Moves.EARTH_POWER, Moves.FLOATY_FALL, Moves.ZING_ZAP, Moves.DIAMOND_STORM ], [Species.KOMALA]: [ Moves.SLACK_OFF, Moves.EXTREME_SPEED, Moves.KNOCK_OFF, Moves.COLLISION_COURSE ], [Species.TURTONATOR]: [ Moves.BURNING_BULWARK, Moves.MORNING_SUN, Moves.BODY_PRESS, Moves.CORE_ENFORCER ], - [Species.TOGEDEMARU]: [ Moves.FAKE_OUT, Moves.METAL_BURST, Moves.METEOR_MASH, Moves.BOLT_STRIKE ], + [Species.TOGEDEMARU]: [ Moves.FAKE_OUT, Moves.METAL_BURST, Moves.METEOR_MASH, Moves.AURA_WHEEL ], [Species.MIMIKYU]: [ Moves.SPIRIT_BREAK, Moves.TIDY_UP, Moves.BITTER_BLADE, Moves.SPECTRAL_THIEF ], [Species.BRUXISH]: [ Moves.PLAY_ROUGH, Moves.FIRE_FANG, Moves.DRAGON_DANCE, Moves.SURGING_STRIKES ], [Species.DRAMPA]: [ Moves.SLACK_OFF, Moves.TRICK_ROOM, Moves.CORE_ENFORCER, Moves.BOOMBURST ], [Species.DHELMISE]: [ Moves.SHADOW_BONE, Moves.STRENGTH_SAP, Moves.LIQUIDATION, Moves.SAPPY_SEED ], [Species.JANGMO_O]: [ Moves.BODY_PRESS, Moves.SHELL_SIDE_ARM, Moves.SECRET_SWORD, Moves.GLAIVE_RUSH ], - [Species.TAPU_KOKO]: [ Moves.MAGICAL_TORQUE, Moves.TRIPLE_AXEL, Moves.RISING_VOLTAGE, Moves.PLASMA_FISTS ], + [Species.TAPU_KOKO]: [ Moves.MAGICAL_TORQUE, Moves.TRIPLE_AXEL, Moves.RISING_VOLTAGE, Moves.BOLT_STRIKE ], [Species.TAPU_LELE]: [ Moves.MOONLIGHT, Moves.NASTY_PLOT, Moves.HEAT_WAVE, Moves.EXPANDING_FORCE ], [Species.TAPU_BULU]: [ Moves.SAPPY_SEED, Moves.DRAIN_PUNCH, Moves.MAGICAL_TORQUE, Moves.VICTORY_DANCE ], [Species.TAPU_FINI]: [ Moves.AURA_SPHERE, Moves.EARTH_POWER, Moves.RECOVER, Moves.QUIVER_DANCE ], [Species.COSMOG]: [ Moves.PHOTON_GEYSER, Moves.PRECIPICE_BLADES, Moves.SACRED_FIRE, Moves.ASTRAL_BARRAGE ], [Species.NIHILEGO]: [ Moves.STRENGTH_SAP, Moves.MALIGNANT_CHAIN, Moves.EARTH_POWER, Moves.QUIVER_DANCE ], [Species.BUZZWOLE]: [ Moves.FIRST_IMPRESSION, Moves.COMBAT_TORQUE, Moves.ROCK_WRECKER, Moves.DOUBLE_IRON_BASH ], - [Species.PHEROMOSA]: [ Moves.AURA_SPHERE, Moves.MAKE_IT_RAIN, Moves.ATTACK_ORDER, Moves.DIAMOND_STORM ], + [Species.PHEROMOSA]: [ Moves.SECRET_SWORD, Moves.MAKE_IT_RAIN, Moves.ATTACK_ORDER, Moves.DIAMOND_STORM ], [Species.XURKITREE]: [ Moves.FLAMETHROWER, Moves.GIGA_DRAIN, Moves.TAIL_GLOW, Moves.THUNDERCLAP ], [Species.CELESTEELA]: [ Moves.RECOVER, Moves.BUZZY_BUZZ, Moves.SANDSEAR_STORM, Moves.OBLIVION_WING ], [Species.KARTANA]: [ Moves.MIGHTY_CLEAVE, Moves.PSYBLADE, Moves.BITTER_BLADE, Moves.BEHEMOTH_BLADE ], [Species.GUZZLORD]: [ Moves.SUCKER_PUNCH, Moves.COMEUPPANCE, Moves.SLACK_OFF, Moves.SHED_TAIL ], - [Species.NECROZMA]: [ Moves.CLANGOROUS_SOUL, Moves.SACRED_FIRE, Moves.ASTRAL_BARRAGE, Moves.DYNAMAX_CANNON ], + [Species.NECROZMA]: [ Moves.DYNAMAX_CANNON, Moves.SACRED_FIRE, Moves.ASTRAL_BARRAGE, Moves.CLANGOROUS_SOUL ], [Species.MAGEARNA]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.MOONBLAST, Moves.MAKE_IT_RAIN ], [Species.MARSHADOW]: [ Moves.POWER_UP_PUNCH, Moves.TRIPLE_AXEL, Moves.METEOR_MASH, Moves.STORM_THROW ], [Species.POIPOLE]: [ Moves.CORE_ENFORCER, Moves.ICE_BEAM, Moves.SEARING_SHOT, Moves.MALIGNANT_CHAIN ], @@ -428,11 +428,11 @@ export const speciesEggMoves = { [Species.MELTAN]: [ Moves.BULLET_PUNCH, Moves.DRAIN_PUNCH, Moves.BULK_UP, Moves.PLASMA_FISTS ], [Species.GROOKEY]: [ Moves.HIGH_HORSEPOWER, Moves.CLANGOROUS_SOUL, Moves.GRASSY_GLIDE, Moves.SAPPY_SEED ], [Species.SCORBUNNY]: [ Moves.EXTREME_SPEED, Moves.HIGH_JUMP_KICK, Moves.TRIPLE_AXEL, Moves.BOLT_STRIKE ], - [Species.SOBBLE]: [ Moves.AEROBLAST, Moves.FROST_BREATH, Moves.SCORCHING_SANDS, Moves.NASTY_PLOT ], - [Species.SKWOVET]: [ Moves.KNOCK_OFF, Moves.SLACK_OFF, Moves.BODY_PRESS, Moves.POPULATION_BOMB ], + [Species.SOBBLE]: [ Moves.AEROBLAST, Moves.FROST_BREATH, Moves.ENERGY_BALL, Moves.NASTY_PLOT ], + [Species.SKWOVET]: [ Moves.SUCKER_PUNCH, Moves.SLACK_OFF, Moves.COIL, Moves.POPULATION_BOMB ], [Species.ROOKIDEE]: [ Moves.ROOST, Moves.BODY_PRESS, Moves.KINGS_SHIELD, Moves.BEHEMOTH_BASH ], - [Species.BLIPBUG]: [ Moves.HEAL_ORDER, Moves.EXPANDING_FORCE, Moves.SPORE, Moves.TAIL_GLOW ], - [Species.NICKIT]: [ Moves.BADDY_BAD, Moves.BURNING_JEALOUSY, Moves.SPARKLY_SWIRL, Moves.FIERY_WRATH ], + [Species.BLIPBUG]: [ Moves.HEAL_ORDER, Moves.LUSTER_PURGE, Moves.SLEEP_POWDER, Moves.TAIL_GLOW ], + [Species.NICKIT]: [ Moves.BADDY_BAD, Moves.FLAMETHROWER, Moves.SPARKLY_SWIRL, Moves.MAKE_IT_RAIN ], [Species.GOSSIFLEUR]: [ Moves.TAILWIND, Moves.STRENGTH_SAP, Moves.SAPPY_SEED, Moves.SEED_FLARE ], [Species.WOOLOO]: [ Moves.PSYSHIELD_BASH, Moves.MILK_DRINK, Moves.BODY_PRESS, Moves.MULTI_ATTACK ], [Species.CHEWTLE]: [ Moves.ICE_FANG, Moves.ACCELEROCK, Moves.SHELL_SMASH, Moves.FISHIOUS_REND ], @@ -446,25 +446,25 @@ export const speciesEggMoves = { [Species.SIZZLIPEDE]: [ Moves.BURNING_BULWARK, Moves.ZING_ZAP, Moves.FIRST_IMPRESSION, Moves.BITTER_BLADE ], [Species.CLOBBOPUS]: [ Moves.STORM_THROW, Moves.JET_PUNCH, Moves.MACH_PUNCH, Moves.SURGING_STRIKES ], [Species.SINISTEA]: [ Moves.SCALD, Moves.TAKE_HEART, Moves.SPARKLY_SWIRL, Moves.MATCHA_GOTCHA ], - [Species.HATENNA]: [ Moves.RECOVER, Moves.MOONBLAST, Moves.BUZZY_BUZZ, Moves.SEARING_SHOT ], + [Species.HATENNA]: [ Moves.RECOVER, Moves.MOONBLAST, Moves.BUZZY_BUZZ, Moves.TORCH_SONG ], [Species.IMPIDIMP]: [ Moves.ENCORE, Moves.PARTING_SHOT, Moves.TOPSY_TURVY, Moves.WICKED_BLOW ], [Species.MILCERY]: [ Moves.MOONBLAST, Moves.CHILLY_RECEPTION, Moves.EARTH_POWER, Moves.GEOMANCY ], [Species.FALINKS]: [ Moves.COMBAT_TORQUE, Moves.PSYSHIELD_BASH, Moves.HEAL_ORDER, Moves.POPULATION_BOMB ], [Species.PINCURCHIN]: [ Moves.TRICK_ROOM, Moves.RISING_VOLTAGE, Moves.STRENGTH_SAP, Moves.THUNDERCLAP ], - [Species.SNOM]: [ Moves.MOONBLAST, Moves.SURF, Moves.EARTH_POWER, Moves.FIERY_DANCE ], + [Species.SNOM]: [ Moves.FROST_BREATH, Moves.HEAL_ORDER, Moves.EARTH_POWER, Moves.SPORE ], [Species.STONJOURNER]: [ Moves.BODY_PRESS, Moves.HELPING_HAND, Moves.ACCELEROCK, Moves.DIAMOND_STORM ], [Species.EISCUE]: [ Moves.TRIPLE_AXEL, Moves.AQUA_STEP, Moves.SHELL_SMASH, Moves.GLACIAL_LANCE ], [Species.INDEEDEE]: [ Moves.MATCHA_GOTCHA, Moves.EXPANDING_FORCE, Moves.MOONBLAST, Moves.REVIVAL_BLESSING ], [Species.MORPEKO]: [ Moves.TRIPLE_AXEL, Moves.OBSTRUCT, Moves.SWORDS_DANCE, Moves.COLLISION_COURSE ], [Species.CUFANT]: [ Moves.LIQUIDATION, Moves.CURSE, Moves.COMBAT_TORQUE, Moves.GIGATON_HAMMER ], - [Species.DRACOZOLT]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.FIRE_LASH, Moves.DRAGON_DANCE ], + [Species.DRACOZOLT]: [ Moves.TRIPLE_AXEL, Moves.SCALE_SHOT, Moves.FIRE_LASH, Moves.DRAGON_DANCE ], [Species.ARCTOZOLT]: [ Moves.MOUNTAIN_GALE, Moves.AQUA_STEP, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ], [Species.DRACOVISH]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.THUNDER_FANG, Moves.DRAGON_DANCE ], [Species.ARCTOVISH]: [ Moves.ICE_FANG, Moves.THUNDER_FANG, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ], [Species.DURALUDON]: [ Moves.CORE_ENFORCER, Moves.BODY_PRESS, Moves.RECOVER, Moves.TACHYON_CUTTER ], - [Species.DREEPY]: [ Moves.SHADOW_BONE, Moves.POWER_UP_PUNCH, Moves.BLAZING_TORQUE, Moves.GLAIVE_RUSH ], + [Species.DREEPY]: [ Moves.SHADOW_BONE, Moves.NASTY_PLOT, Moves.FIRE_LASH, Moves.COLLISION_COURSE ], [Species.ZACIAN]: [ Moves.MAGICAL_TORQUE, Moves.MIGHTY_CLEAVE, Moves.BITTER_BLADE, Moves.PRECIPICE_BLADES ], - [Species.ZAMAZENTA]: [ Moves.PSYSHIELD_BASH, Moves.BODY_PRESS, Moves.SLACK_OFF, Moves.VICTORY_DANCE ], + [Species.ZAMAZENTA]: [ Moves.BULK_UP, Moves.BODY_PRESS, Moves.SLACK_OFF, Moves.DIAMOND_STORM ], [Species.ETERNATUS]: [ Moves.BODY_PRESS, Moves.NASTY_PLOT, Moves.MALIGNANT_CHAIN, Moves.DRAGON_ENERGY ], [Species.KUBFU]: [ Moves.METEOR_MASH, Moves.DRAIN_PUNCH, Moves.JET_PUNCH, Moves.DRAGON_DANCE ], [Species.ZARUDE]: [ Moves.SAPPY_SEED, Moves.MIGHTY_CLEAVE, Moves.WICKED_BLOW, Moves.VICTORY_DANCE ], @@ -482,7 +482,7 @@ export const speciesEggMoves = { [Species.NYMBLE]: [ Moves.KNOCK_OFF, Moves.FELL_STINGER, Moves.ATTACK_ORDER, Moves.WICKED_BLOW ], [Species.PAWMI]: [ Moves.DRAIN_PUNCH, Moves.ICE_PUNCH, Moves.MACH_PUNCH, Moves.PLASMA_FISTS ], [Species.TANDEMAUS]: [ Moves.BATON_PASS, Moves.THIEF, Moves.SIZZLY_SLIDE, Moves.REVIVAL_BLESSING ], - [Species.FIDOUGH]: [ Moves.WISH, Moves.BODY_PRESS, Moves.SIZZLY_SLIDE, Moves.TIDY_UP ], + [Species.FIDOUGH]: [ Moves.SOFT_BOILED, Moves.HIGH_HORSEPOWER, Moves.SIZZLY_SLIDE, Moves.TIDY_UP ], [Species.SMOLIV]: [ Moves.STRENGTH_SAP, Moves.EARTH_POWER, Moves.CALM_MIND, Moves.BOOMBURST ], [Species.SQUAWKABILLY]: [ Moves.PARTING_SHOT, Moves.EARTHQUAKE, Moves.FLARE_BLITZ, Moves.EXTREME_SPEED ], [Species.NACLI]: [ Moves.BODY_PRESS, Moves.TOXIC, Moves.CURSE, Moves.DIAMOND_STORM ], @@ -492,7 +492,7 @@ export const speciesEggMoves = { [Species.MASCHIFF]: [ Moves.PARTING_SHOT, Moves.CLOSE_COMBAT, Moves.PSYCHIC_FANGS, Moves.NO_RETREAT ], [Species.SHROODLE]: [ Moves.GASTRO_ACID, Moves.PARTING_SHOT, Moves.TOXIC, Moves.SKETCH ], [Species.BRAMBLIN]: [ Moves.TAILWIND, Moves.STRENGTH_SAP, Moves.FLOWER_TRICK, Moves.LAST_RESPECTS ], - [Species.TOEDSCOOL]: [ Moves.STRENGTH_SAP, Moves.TOPSY_TURVY, Moves.PARTING_SHOT, Moves.SAPPY_SEED ], + [Species.TOEDSCOOL]: [ Moves.STRENGTH_SAP, Moves.TOPSY_TURVY, Moves.SAPPY_SEED, Moves.TAIL_GLOW ], [Species.KLAWF]: [ Moves.CRABHAMMER, Moves.SHORE_UP, Moves.MIGHTY_CLEAVE, Moves.SHELL_SMASH ], [Species.CAPSAKID]: [ Moves.STRENGTH_SAP, Moves.APPLE_ACID, Moves.FROST_BREATH, Moves.TORCH_SONG ], [Species.RELLOR]: [ Moves.HEAL_BLOCK, Moves.RECOVER, Moves.HEAT_WAVE, Moves.LUMINA_CRASH ], @@ -509,7 +509,7 @@ export const speciesEggMoves = { [Species.FLAMIGO]: [ Moves.THUNDEROUS_KICK, Moves.TRIPLE_AXEL, Moves.FLOATY_FALL, Moves.VICTORY_DANCE ], [Species.CETODDLE]: [ Moves.MOUNTAIN_GALE, Moves.HIGH_HORSEPOWER, Moves.RECOVER, Moves.DRAGON_DANCE ], [Species.VELUZA]: [ Moves.PSYBLADE, Moves.FLIP_TURN, Moves.ICE_SPINNER, Moves.BITTER_BLADE ], - [Species.DONDOZO]: [ Moves.SOFT_BOILED, Moves.ICE_SPINNER, Moves.TOXIC, Moves.SALT_CURE ], + [Species.DONDOZO]: [ Moves.SOFT_BOILED, Moves.SIZZLY_SLIDE, Moves.TOXIC, Moves.SALT_CURE ], [Species.TATSUGIRI]: [ Moves.ICE_BEAM, Moves.FILLET_AWAY, Moves.CORE_ENFORCER, Moves.STEAM_ERUPTION ], [Species.GREAT_TUSK]: [ Moves.STONE_AXE, Moves.MORNING_SUN, Moves.COLLISION_COURSE, Moves.SHIFT_GEAR ], [Species.SCREAM_TAIL]: [ Moves.TORCH_SONG, Moves.GLITZY_GLOW, Moves.MOONLIGHT, Moves.SPARKLY_SWIRL ], @@ -521,7 +521,7 @@ export const speciesEggMoves = { [Species.IRON_BUNDLE]: [ Moves.EARTH_POWER, Moves.BOUNCY_BUBBLE, Moves.NASTY_PLOT, Moves.STEAM_ERUPTION ], [Species.IRON_HANDS]: [ Moves.DRAIN_PUNCH, Moves.BULK_UP, Moves.PLASMA_FISTS, Moves.ICE_HAMMER ], [Species.IRON_JUGULIS]: [ Moves.FIERY_WRATH, Moves.ROOST, Moves.NASTY_PLOT, Moves.OBLIVION_WING ], - [Species.IRON_MOTH]: [ Moves.EARTH_POWER, Moves.SEARING_SHOT, Moves.QUIVER_DANCE, Moves.MALIGNANT_CHAIN ], + [Species.IRON_MOTH]: [ Moves.EARTH_POWER, Moves.SEARING_SHOT, Moves.MALIGNANT_CHAIN, Moves.QUIVER_DANCE ], [Species.IRON_THORNS]: [ Moves.DIAMOND_STORM, Moves.SHORE_UP, Moves.SHIFT_GEAR, Moves.PLASMA_FISTS ], [Species.FRIGIBAX]: [ Moves.DRAGON_DARTS, Moves.DRAGON_DANCE, Moves.EARTHQUAKE, Moves.GLACIAL_LANCE ], [Species.GIMMIGHOUL]: [ Moves.HAPPY_HOUR, Moves.AURA_SPHERE, Moves.SURF, Moves.ASTRAL_BARRAGE ], @@ -540,7 +540,7 @@ export const speciesEggMoves = { [Species.MUNKIDORI]: [ Moves.PSYSTRIKE, Moves.HEAT_WAVE, Moves.EARTH_POWER, Moves.MALIGNANT_CHAIN ], [Species.FEZANDIPITI]: [ Moves.BARB_BARRAGE, Moves.VICTORY_DANCE, Moves.TRIPLE_AXEL, Moves.MAGICAL_TORQUE ], [Species.OGERPON]: [ Moves.FLOWER_TRICK, Moves.BONEMERANG, Moves.TRIPLE_AXEL, Moves.GIGATON_HAMMER ], - [Species.GOUGING_FIRE]: [ Moves.SUPERCELL_SLAM, Moves.BULK_UP, Moves.SACRED_FIRE, Moves.GLAIVE_RUSH ], + [Species.GOUGING_FIRE]: [ Moves.EXTREME_SPEED, Moves.BULK_UP, Moves.SACRED_FIRE, Moves.GLAIVE_RUSH ], [Species.RAGING_BOLT]: [ Moves.NASTY_PLOT, Moves.FLAMETHROWER, Moves.MORNING_SUN, Moves.ELECTRO_DRIFT ], [Species.IRON_BOULDER]: [ Moves.PSYBLADE, Moves.KOWTOW_CLEAVE, Moves.STONE_AXE, Moves.BITTER_BLADE ], [Species.IRON_CROWN]: [ Moves.NASTY_PLOT, Moves.SECRET_SWORD, Moves.PSYSTRIKE, Moves.ELECTRO_DRIFT ], @@ -566,7 +566,7 @@ export const speciesEggMoves = { [Species.GALAR_DARUMAKA]: [ Moves.ICE_SPINNER, Moves.ENDURE, Moves.DRAIN_PUNCH, Moves.V_CREATE ], [Species.GALAR_YAMASK]: [ Moves.STRENGTH_SAP, Moves.DIRE_CLAW, Moves.THOUSAND_WAVES, Moves.SPECTRAL_THIEF ], [Species.GALAR_STUNFISK]: [ Moves.SPIKY_SHIELD, Moves.THOUSAND_ARROWS, Moves.STRENGTH_SAP, Moves.DOUBLE_IRON_BASH ], - [Species.HISUI_GROWLITHE]: [ Moves.WOOD_HAMMER, Moves.HEAD_SMASH, Moves.MORNING_SUN, Moves.DRAGON_DANCE ], + [Species.HISUI_GROWLITHE]: [ Moves.WAVE_CRASH, Moves.HEAD_SMASH, Moves.VOLT_TACKLE, Moves.DRAGON_DANCE ], [Species.HISUI_VOLTORB]: [ Moves.FROST_BREATH, Moves.NASTY_PLOT, Moves.APPLE_ACID, Moves.ELECTRO_DRIFT ], [Species.HISUI_QWILFISH]: [ Moves.CEASELESS_EDGE, Moves.KNOCK_OFF, Moves.STRENGTH_SAP, Moves.FISHIOUS_REND ], [Species.HISUI_SNEASEL]: [ Moves.THUNDEROUS_KICK, Moves.KNOCK_OFF, Moves.TRIPLE_AXEL, Moves.VICTORY_DANCE ], diff --git a/src/data/move.ts b/src/data/move.ts index 5320501cc0d..74ecead73fa 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5290,6 +5290,11 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { return false; } + if (!player && user.scene.currentBattle.isBattleMysteryEncounter() && !user.scene.currentBattle.mysteryEncounter?.fleeAllowed) { + // Don't allow wild opponents to be force switched during MEs with flee disabled + return false; + } + const blockedByAbility = new Utils.BooleanHolder(false); applyAbAttrs(ForceSwitchOutImmunityAbAttr, target, blockedByAbility); return !blockedByAbility.value; @@ -8080,7 +8085,7 @@ export function initMoves() { .makesContact(false), new SelfStatusMove(Moves.DEFEND_ORDER, Type.BUG, -1, 10, -1, 0, 4) .attr(StatStageChangeAttr, [ Stat.DEF, Stat.SPDEF ], 1, true), - new SelfStatusMove(Moves.HEAL_ORDER, Type.BUG, -1, 10, -1, 0, 4) + new SelfStatusMove(Moves.HEAL_ORDER, Type.BUG, -1, 5, -1, 0, 4) .attr(HealAttr, 0.5) .triageMove(), new AttackMove(Moves.HEAD_SMASH, Type.ROCK, MoveCategory.PHYSICAL, 150, 80, 5, -1, 0, 4) diff --git a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts index efcd41054ea..432a0b778da 100644 --- a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts +++ b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts @@ -24,6 +24,7 @@ import { BerryType } from "#enums/berry-type"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { Stat } from "#enums/stat"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; +import i18next from "i18next"; /** the i18n namespace for this encounter */ const namespace = "mysteryEncounter:absoluteAvarice"; @@ -38,6 +39,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = .withEncounterTier(MysteryEncounterTier.GREAT) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn + .withFleeAllowed(false) .withIntroSpriteConfigs([ { // This sprite has the shadow @@ -262,15 +264,13 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = // Provides 1x Reviver Seed to each party member at end of battle const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED); + encounter.setDialogueToken("foodReward", revSeed?.name ?? i18next.t("modifierType:ModifierType.REVIVER_SEED.name")); const givePartyPokemonReviverSeeds = () => { const party = scene.getParty(); party.forEach(p => { const heldItems = p.getHeldItems(); if (revSeed && !heldItems.some(item => item instanceof PokemonInstantReviveModifier)) { const seedModifier = revSeed.newModifier(p); - if (seedModifier) { - encounter.setDialogueToken("foodReward", seedModifier.type.name); - } scene.addModifier(seedModifier, false, false, false, true); } }); diff --git a/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts index 919cd1df5ca..8746c387545 100644 --- a/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts +++ b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts @@ -70,7 +70,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; const pokemon = getHighestStatTotalPlayerPokemon(scene, true, true); - const baseSpecies = pokemon.getSpeciesForm().getRootSpeciesId(true); + const baseSpecies = pokemon.getSpeciesForm().getRootSpeciesId(); const starterValue: number = speciesStarters[baseSpecies] ?? 1; const multiplier = Math.max(MONEY_MAXIMUM_MULTIPLIER / 10 * starterValue, MONEY_MINIMUM_MULTIPLIER); const price = scene.getWaveMoneyAmount(multiplier); diff --git a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts index a112355b033..a7f8d62c233 100644 --- a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts +++ b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts @@ -46,6 +46,7 @@ export const BerriesAboundEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withCatchAllowed(true) .withHideWildIntroMessage(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { 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 35858b2e6db..827b2c12478 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -49,6 +49,7 @@ import MoveInfoOverlay from "#app/ui/move-info-overlay"; import { allMoves } from "#app/data/move"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; +import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounter:bugTypeSuperfan"; @@ -177,9 +178,14 @@ const MISC_TUTOR_MOVES = [ Moves.U_TURN ]; +/** + * Wave breakpoints that determine how strong to make the Bug-Type Superfan's team + */ +const WAVE_LEVEL_BREAKPOINTS = [30, 50, 70, 100, 120, 140, 160]; + /** * Bug Type Superfan encounter. - * @see {@link https://github.com/pagefaultgames/pokerogue/issues/3810 | GitHub Issue #3810} + * @see {@link https://github.com/pagefaultgames/pokerogue/issues/3820 | GitHub Issue #3820} * @see For biome requirements check {@linkcode mysteryEncountersByBiome} */ export const BugTypeSuperfanEncounter: MysteryEncounter = @@ -216,11 +222,46 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = female: true, }); + let beedrillKeys: { spriteKey: string, fileRoot: string }, butterfreeKeys: { spriteKey: string, fileRoot: string }; + if (scene.currentBattle.waveIndex < WAVE_LEVEL_BREAKPOINTS[3]) { + beedrillKeys = getSpriteKeysFromSpecies(Species.BEEDRILL, false); + butterfreeKeys = getSpriteKeysFromSpecies(Species.BUTTERFREE, false); + } else { + // Mega Beedrill/Gmax Butterfree + beedrillKeys = getSpriteKeysFromSpecies(Species.BEEDRILL, false, 1); + butterfreeKeys = getSpriteKeysFromSpecies(Species.BUTTERFREE, false, 1); + } + encounter.spriteConfigs = [ + { + spriteKey: beedrillKeys.spriteKey, + fileRoot: beedrillKeys.fileRoot, + hasShadow: true, + repeat: true, + isPokemon: true, + x: -30, + tint: 0.15, + y: -4, + yShadow: -4 + }, + { + spriteKey: butterfreeKeys.spriteKey, + fileRoot: butterfreeKeys.fileRoot, + hasShadow: true, + repeat: true, + isPokemon: true, + x: 30, + tint: 0.15, + y: -4, + yShadow: -4 + }, { spriteKey: spriteKey, fileRoot: "trainer", hasShadow: true, + x: 4, + y: 7, + yShadow: 7 }, ]; @@ -330,6 +371,10 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = if (formChangeModifier) { specialOptions.push(formChangeModifier); } + const rareFormChangeModifier = generateModifierTypeOption(scene, modifierTypes.RARE_FORM_CHANGE_ITEM); + if (rareFormChangeModifier) { + specialOptions.push(rareFormChangeModifier); + } if (specialOptions.length > 0) { modifierOptions.push(specialOptions[randSeedInt(specialOptions.length)]); } @@ -445,29 +490,29 @@ function getTrainerConfigForWave(waveIndex: number) { const config = trainerConfigs[TrainerType.BUG_TYPE_SUPERFAN].clone(); config.name = i18next.t("trainerNames:bug_type_superfan"); - const pool3Copy = POOL_3_POKEMON.slice(0); - randSeedShuffle(pool3Copy); + let pool3Copy = POOL_3_POKEMON.slice(0); + pool3Copy = randSeedShuffle(pool3Copy); const pool3Mon = pool3Copy.pop()!; - if (waveIndex < 30) { + if (waveIndex < WAVE_LEVEL_BREAKPOINTS[0]) { // Use default template (2 AVG) config .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true)); - } else if (waveIndex < 50) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[1]) { config .setPartyTemplates(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true)); - } else if (waveIndex < 70) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[2]) { config .setPartyTemplates(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true)) .setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)); - } else if (waveIndex < 100) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[3]) { config .setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true)) @@ -475,7 +520,7 @@ function getTrainerConfigForWave(waveIndex: number) { .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true)) .setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)) .setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)); - } else if (waveIndex < 120) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[4]) { config .setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE)) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => { @@ -497,8 +542,8 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateName(); } })); - } else if (waveIndex < 140) { - randSeedShuffle(pool3Copy); + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[5]) { + pool3Copy = randSeedShuffle(pool3Copy); const pool3Mon2 = pool3Copy.pop()!; config .setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE)) @@ -527,7 +572,7 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateName(); } })); - } else if (waveIndex < 160) { + } else if (waveIndex < WAVE_LEVEL_BREAKPOINTS[6]) { config .setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG))) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => { @@ -550,6 +595,8 @@ function getTrainerConfigForWave(waveIndex: number) { })) .setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_4_POKEMON, TrainerSlot.TRAINER, true)); } else { + pool3Copy = randSeedShuffle(pool3Copy); + const pool3Mon2 = pool3Copy.pop()!; config .setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG))) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => { @@ -571,9 +618,9 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateName(); } })) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { - if (!isNullOrUndefined(pool3Mon.formIndex)) { - p.formIndex = pool3Mon.formIndex; + .setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => { + if (!isNullOrUndefined(pool3Mon2.formIndex)) { + p.formIndex = pool3Mon2.formIndex; p.generateAndPopulateMoveset(); p.generateName(); } @@ -629,27 +676,7 @@ function doBugTypeMoveTutor(scene: BattleScene): Promise { moveInfoOverlay.setVisible(false); } - // TODO: add menu to confirm player doesn't want to teach a move - // while (!result && !forceExit) { - // // Didn't teach a move, ask the player to confirm they don't want to teach a move - // await showEncounterDialogue(scene, `${namespace}.confirm_no_teach`, `${namespace}.speaker`); - // const confirm = await new Promise(confirmResolve => { - // scene.ui.setMode(Mode.CONFIRM, () => confirmResolve(true), () => confirmResolve(false)); - // }); - // scene.ui.clearText(); - // await scene.ui.setMode(Mode.MESSAGE); - // if (confirm) { - // // No teach, break out of loop - // forceExit = true; - // } else { - // // Re-show learn menu - // result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel); - // if (!result) { - // moveInfoOverlay.active = false; - // moveInfoOverlay.setVisible(false); - // } - // } - // } + // TODO: add menu to confirm player doesn't want to teach a move? // Option select complete, handle if they are learning a move if (result && result.selectedOptionIndex < moveOptions.length) { diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index e1e681e95dd..7e846b42ea4 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -336,8 +336,8 @@ export const ClowningAroundEncounter: MysteryEncounter = .filter(move => move && !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS) .map(move => move!.getMove().type); if (priorityTypes?.length > 0) { - priorityTypes = [...new Set(priorityTypes)]; - randSeedShuffle(priorityTypes); + priorityTypes = [...new Set(priorityTypes)].sort(); + priorityTypes = randSeedShuffle(priorityTypes); } const newTypes = [originalTypes[0]]; @@ -494,9 +494,13 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem } for (let i = 0; i < numItems; i++) { + if (pool.length === 0) { + // Stop generating new items if somehow runs out of items to spawn + return; + } const randIndex = randSeedInt(pool.length); const newItemType = pool[randIndex]; - let newMod; + let newMod: PokemonHeldItemModifierType; if (tier === "Berries") { newMod = generateModifierType(scene, modifierTypes.BERRY, [newItemType[0]]) as PokemonHeldItemModifierType; } else { diff --git a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts index 1ceb14a7372..a99395726c8 100644 --- a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts +++ b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts @@ -90,6 +90,7 @@ export const DancingLessonsEncounter: MysteryEncounter = .withHideWildIntroMessage(true) .withAutoHideIntroVisuals(false) .withCatchAllowed(true) + .withFleeAllowed(false) .withOnVisualsStart((scene: BattleScene) => { const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, scene.getEnemyPokemon()!, scene.getParty()[0]); danceAnim.play(scene); diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index 13f9d926345..6775aee6b30 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -46,6 +46,7 @@ export const FieryFalloutEncounter: MysteryEncounter = .withIntroSpriteConfigs([]) // Set in onInit() .withAnimations(EncounterAnim.MAGMA_BG, EncounterAnim.MAGMA_SPOUT) .withAutoHideIntroVisuals(false) + .withFleeAllowed(false) .withIntroDialogue([ { text: `${namespace}.intro`, diff --git a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts index 349984f1958..b3afdaf5f17 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -44,6 +44,7 @@ export const FightOrFlightEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withCatchAllowed(true) .withHideWildIntroMessage(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { 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 a144aa88299..1d8bf42528b 100644 --- a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts +++ b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts @@ -44,6 +44,7 @@ export const FunAndGamesEncounter: MysteryEncounter = .withSkipEnemyBattleTurns(true) // Will skip COMMAND selection menu and go straight to FIGHT (move select) menu .withSkipToFightInput(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: "fun_and_games_game", diff --git a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts index bfccc46ee0f..fe61766a888 100644 --- a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts +++ b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts @@ -34,6 +34,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withCatchAllowed(true) .withHideWildIntroMessage(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: Species.SNORLAX.toString(), diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts index abea725f113..386f4170156 100644 --- a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -42,6 +42,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter = .withSceneRequirement(new MoneyRequirement(0, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost .withAutoHideIntroVisuals(false) .withCatchAllowed(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: "teleporting_hijinks_teleporter", 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 91aeea79111..e41b3ab03ef 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 @@ -437,8 +437,7 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig { } function getSpeciesFromPool(speciesPool: (Species | BreederSpeciesEvolution)[][], waveIndex: number): Species { - const poolCopy = speciesPool.slice(0); - randSeedShuffle(poolCopy); + const poolCopy = randSeedShuffle(speciesPool.slice(0)); const speciesEvolutions = poolCopy.pop()!.slice(0); let speciesObject = speciesEvolutions.pop()!; while (speciesObject instanceof BreederSpeciesEvolution && speciesObject.evolution > waveIndex) { @@ -452,7 +451,7 @@ function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number] // 1 point for every 20 points below 680 BST the pokemon is, (max 18, min 1) const pointsFromBst = Math.min(Math.max(Math.floor((680 - bst) / 20), 1), 18); - const rootSpecies = pokemon.species.getRootSpeciesId(true); + const rootSpecies = pokemon.species.getRootSpeciesId(); let pointsFromStarterTier = 0; // 2 points for every 1 below 7 that the pokemon's starter tier is (max 12, min 0) if (speciesStarters.hasOwnProperty(rootSpecies)) { diff --git a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts index 56328695128..10537cbe200 100644 --- a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts @@ -39,6 +39,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = .withMaxAllowedEncounters(1) .withHideWildIntroMessage(true) .withAutoHideIntroVisuals(false) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: "berry_juice", diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index 33864c00143..ea59b8003f5 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -101,7 +101,7 @@ export const TrainingSessionEncounter: MysteryEncounter = encounter.setDialogueToken("stat1", "-"); encounter.setDialogueToken("stat2", "-"); // Add the pokemon back to party with IV boost - const ivIndexes: any[] = []; + let ivIndexes: any[] = []; playerPokemon.ivs.forEach((iv, index) => { if (iv < 31) { ivIndexes.push({ iv: iv, index: index }); @@ -117,7 +117,7 @@ export const TrainingSessionEncounter: MysteryEncounter = // 25-27 starting IV caps in 2 encounters let improvedCount = 0; while (ivIndexes.length > 0 && improvedCount < 2) { - randSeedShuffle(ivIndexes); + ivIndexes = randSeedShuffle(ivIndexes); const ivToChange = ivIndexes.pop(); let newVal = ivToChange.iv; if (improvedCount === 0) { @@ -145,10 +145,7 @@ export const TrainingSessionEncounter: MysteryEncounter = if (improvedCount > 0) { playerPokemon.calculateStats(); - scene.gameData.updateSpeciesDexIvs( - playerPokemon.species.getRootSpeciesId(true), - playerPokemon.ivs - ); + scene.gameData.updateSpeciesDexIvs(playerPokemon.species.getRootSpeciesId(true), playerPokemon.ivs); scene.gameData.setPokemonCaught(playerPokemon, false); } @@ -322,27 +319,23 @@ export const TrainingSessionEncounter: MysteryEncounter = queueEncounterMessage(scene, `${namespace}.option.3.finished`); // Add the pokemon back to party with ability change const abilityIndex = encounter.misc.abilityIndex; + if (!!playerPokemon.getFusionSpeciesForm()) { playerPokemon.fusionAbilityIndex = abilityIndex; - if (!isNullOrUndefined(playerPokemon.fusionSpecies?.speciesId) && speciesStarters.hasOwnProperty(playerPokemon.fusionSpecies.speciesId)) { - scene.gameData.starterData[playerPokemon.fusionSpecies.speciesId] - .abilityAttr |= - abilityIndex !== 1 || playerPokemon.fusionSpecies.ability2 - ? Math.pow(2, playerPokemon.fusionAbilityIndex) - : AbilityAttr.ABILITY_HIDDEN; + + // Only update the fusion's dex data if the Pokemon is already caught in dex (ignore rentals) + const rootFusionSpecies = playerPokemon.fusionSpecies?.getRootSpeciesId(); + if (!isNullOrUndefined(rootFusionSpecies) + && speciesStarters.hasOwnProperty(rootFusionSpecies) + && !!scene.gameData.dexData[rootFusionSpecies].caughtAttr) { + scene.gameData.starterData[rootFusionSpecies].abilityAttr |= playerPokemon.fusionAbilityIndex !== 1 || playerPokemon.fusionSpecies?.ability2 + ? 1 << playerPokemon.fusionAbilityIndex + : AbilityAttr.ABILITY_HIDDEN; } } else { playerPokemon.abilityIndex = abilityIndex; - if (speciesStarters.hasOwnProperty(playerPokemon.species.speciesId)) { - scene.gameData.starterData[playerPokemon.species.speciesId] - .abilityAttr |= - abilityIndex !== 1 || playerPokemon.species.ability2 - ? Math.pow(2, playerPokemon.abilityIndex) - : AbilityAttr.ABILITY_HIDDEN; - } } - playerPokemon.getAbility(); playerPokemon.calculateStats(); scene.gameData.setPokemonCaught(playerPokemon, false); diff --git a/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts b/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts index 98aa90c0818..4b2333297c0 100644 --- a/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts +++ b/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts @@ -36,6 +36,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = .withEncounterTier(MysteryEncounterTier.ULTRA) .withSceneWaveRangeRequirement(60, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1]) .withMaxAllowedEncounters(1) + .withFleeAllowed(false) .withIntroSpriteConfigs([ { spriteKey: Species.GARBODOR.toString() + "-gigantamax", diff --git a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts index 24298a633df..14ba7895434 100644 --- a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts +++ b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts @@ -38,6 +38,7 @@ export const UncommonBreedEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) .withCatchAllowed(true) .withHideWildIntroMessage(true) + .withFleeAllowed(false) .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { @@ -59,17 +60,18 @@ export const UncommonBreedEncounter: MysteryEncounter = const eggMoveIndex = randSeedInt(4); const randomEggMove: Moves = eggMoves[eggMoveIndex]; encounter.misc = { - eggMove: randomEggMove + eggMove: randomEggMove, + pokemon: pokemon }; if (pokemon.moveset.length < 4) { pokemon.moveset.push(new PokemonMove(randomEggMove)); } else { pokemon.moveset[0] = new PokemonMove(randomEggMove); } + } else { + encounter.misc.pokemon = pokemon; } - encounter.misc.pokemon = pokemon; - // Defense/Spd buffs below wave 50, +1 to all stats otherwise const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ? [Stat.DEF, Stat.SPDEF, Stat.SPD] : diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 8fa60774a72..71e8491df69 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -368,7 +368,7 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon const newEggMoveIndex = await addEggMoveToNewPokemonMoveset(scene, newPokemon, speciesRootForm); // Try to add a favored STAB move (might fail if Pokemon already knows a bunch of moves from newPokemonGeneratedMoveset) - addFavoredMoveToNewPokemonMoveset(scene, newPokemon, newPokemonGeneratedMoveset, newEggMoveIndex); + addFavoredMoveToNewPokemonMoveset(newPokemon, newPokemonGeneratedMoveset, newEggMoveIndex); // Randomize the second type of the pokemon // If the pokemon does not normally have a second type, it will gain 1 @@ -553,8 +553,7 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla let eggMoveIndex: null | number = null; const eggMoves = newPokemon.getEggMoves()?.slice(0); if (eggMoves) { - const eggMoveIndices = [0, 1, 2, 3]; - randSeedShuffle(eggMoveIndices); + const eggMoveIndices = randSeedShuffle([0, 1, 2, 3]); let randomEggMoveIndex = eggMoveIndices.pop(); let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null; let retries = 0; @@ -587,12 +586,11 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla /** * Returns index of the new egg move within the Pokemon's moveset (not the index of the move in `speciesEggMoves`) - * @param scene * @param newPokemon * @param newPokemonGeneratedMoveset * @param newEggMoveIndex */ -function addFavoredMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: PlayerPokemon, newPokemonGeneratedMoveset: (PokemonMove | null)[], newEggMoveIndex: number | null) { +function addFavoredMoveToNewPokemonMoveset(newPokemon: PlayerPokemon, newPokemonGeneratedMoveset: (PokemonMove | null)[], newEggMoveIndex: number | null) { let favoredMove: PokemonMove | null = null; for (const move of newPokemonGeneratedMoveset) { // Needs to match first type, second type will be replaced @@ -614,11 +612,15 @@ function addFavoredMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Playe } // Finally, assign favored move to random index that isn't the new egg move index if (favoredMove) { - let favoredMoveIndex = randSeedInt(4); - while (newEggMoveIndex !== null && favoredMoveIndex === newEggMoveIndex) { - favoredMoveIndex = randSeedInt(4); - } + if (newPokemon.moveset.length < 4) { + newPokemon.moveset.push(favoredMove); + } else { + let favoredMoveIndex = randSeedInt(4); + while (newEggMoveIndex !== null && favoredMoveIndex === newEggMoveIndex) { + favoredMoveIndex = randSeedInt(4); + } - newPokemon.moveset[favoredMoveIndex] = favoredMove; + newPokemon.moveset[favoredMoveIndex] = favoredMove; + } } } diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index ea04241e663..ca02c8bdfd6 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -832,7 +832,7 @@ export function transitionMysteryEncounterIntroVisuals(scene: BattleScene, hide: */ export function handleMysteryEncounterBattleStartEffects(scene: BattleScene) { const encounter = scene.currentBattle.mysteryEncounter; - if (scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && encounter && encounter.encounterMode !== MysteryEncounterMode.NO_BATTLE && !encounter.startOfBattleEffectsComplete) { + if (scene.currentBattle.isBattleMysteryEncounter() && encounter && encounter.encounterMode !== MysteryEncounterMode.NO_BATTLE && !encounter.startOfBattleEffectsComplete) { const effects = encounter.startOfBattleEffects; effects.forEach(effect => { let source; @@ -871,7 +871,7 @@ export function handleMysteryEncounterBattleStartEffects(scene: BattleScene) { */ export function handleMysteryEncounterTurnStartEffects(scene: BattleScene): boolean { const encounter = scene.currentBattle.mysteryEncounter; - if (scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && encounter && encounter.onTurnStart) { + if (scene.currentBattle.isBattleMysteryEncounter() && encounter && encounter.onTurnStart) { return encounter.onTurnStart(scene); } diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index d7e596af879..c9b30415299 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -210,10 +210,10 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu .map(s => [parseInt(s) as Species, speciesStarters[s] as number]) .filter(s => { const pokemonSpecies = getPokemonSpecies(s[0]); - return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0]) + return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0])) && (allowSubLegendary || !pokemonSpecies.subLegendary) && (allowLegendary || !pokemonSpecies.legendary) - && (allowMythical || !pokemonSpecies.mythical)); + && (allowMythical || !pokemonSpecies.mythical); }) .map(s => [getPokemonSpecies(s[0]), s[1]]); @@ -757,9 +757,10 @@ const GOLDEN_BUG_NET_SPECIES_POOL: [Species, number][] = [ ]; /** - * Will randomly return one of the species from GOLDEN_BUG_NET_SPECIES_POOL, based on their weights + * Will randomly return one of the species from GOLDEN_BUG_NET_SPECIES_POOL, based on their weights. + * Will also check for and evolve pokemon based on level. */ -export function getGoldenBugNetSpecies(): PokemonSpecies { +export function getGoldenBugNetSpecies(level: number): PokemonSpecies { const totalWeight = GOLDEN_BUG_NET_SPECIES_POOL.reduce((a, b) => a + b[1], 0); const roll = randSeedInt(totalWeight); @@ -767,7 +768,8 @@ export function getGoldenBugNetSpecies(): PokemonSpecies { for (const speciesWeightPair of GOLDEN_BUG_NET_SPECIES_POOL) { w += speciesWeightPair[1]; if (roll < w) { - return getPokemonSpecies(speciesWeightPair[0]); + const initialSpecies = getPokemonSpecies(speciesWeightPair[0]); + return getPokemonSpecies(initialSpecies.getSpeciesForLevel(level, true)); } } diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index b8ddd826035..94dbba958b5 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -762,6 +762,13 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali } } + //TODO: Adjust templates and delays so we don't have to hardcode it + /* TEMPORARY! (Most) Trainers shouldn't be using unevolved Pokemon by the third gym leader / wave 80. Exceptions to this include Breeders, whose large teams are balanced by the use of weaker pokemon */ + if (currentWave >= 80 && forTrainer && strength > PartyMemberStrength.WEAKER) { + evolutionChance = 1; + noEvolutionChance = 0; + } + if (evolutionChance > 0) { if (isRegionalEvolution) { evolutionChance /= (evolutionSpecies.isRareRegional() ? 16 : 4); @@ -944,7 +951,7 @@ export function initSpecies() { new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true, new PokemonForm("Normal", "", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GRASS, Type.POISON, 2.4, 155.5, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.CHLOROPHYLL, Abilities.CHLOROPHYLL, Abilities.CHLOROPHYLL, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), ), new PokemonSpecies(Species.CHARMANDER, 1, false, false, false, "Lizard Pokémon", Type.FIRE, null, 0.6, 8.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.CHARMELEON, 1, false, false, false, "Flame Pokémon", Type.FIRE, null, 1.1, 19, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), @@ -959,7 +966,7 @@ export function initSpecies() { new PokemonSpecies(Species.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.WATER, null, 1.6, 101.1, Abilities.MEGA_LAUNCHER, Abilities.NONE, Abilities.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 630, 119, 83, 130, 115, 115, 68, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265), ), new PokemonSpecies(Species.CATERPIE, 1, false, false, false, "Worm Pokémon", Type.BUG, null, 0.3, 2.9, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false), @@ -1131,7 +1138,7 @@ export function initSpecies() { ), new PokemonSpecies(Species.LAPRAS, 1, false, false, false, "Transport Pokémon", Type.WATER, Type.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", "", Type.WATER, Type.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, Type.WATER, Type.ICE, 24, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 635, 170, 85, 95, 115, 110, 60, 45, 50, 187), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.ICE, 24, 999.9, Abilities.SHIELD_DUST, Abilities.SHIELD_DUST, Abilities.SHIELD_DUST, 635, 170, 85, 85, 105, 130, 60, 45, 50, 187), ), new PokemonSpecies(Species.DITTO, 1, false, false, false, "Transform Pokémon", Type.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", Type.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, @@ -1492,9 +1499,9 @@ export function initSpecies() { new PokemonForm("Normal", "", Type.DRAGON, Type.FLYING, 1.5, 102.6, Abilities.INTIMIDATE, Abilities.NONE, Abilities.MOXIE, 600, 95, 135, 80, 110, 80, 100, 45, 35, 300, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.DRAGON, Type.FLYING, 1.8, 112.6, Abilities.AERILATE, Abilities.NONE, Abilities.AERILATE, 700, 95, 145, 130, 120, 90, 120, 45, 35, 300), ), - new PokemonSpecies(Species.BELDUM, 3, false, false, false, "Iron Ball Pokémon", Type.STEEL, Type.PSYCHIC, 0.6, 95.2, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 300, 40, 55, 80, 35, 60, 30, 3, 35, 60, GrowthRate.SLOW, null, false), - new PokemonSpecies(Species.METANG, 3, false, false, false, "Iron Claw Pokémon", Type.STEEL, Type.PSYCHIC, 1.2, 202.5, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 420, 60, 75, 100, 55, 80, 50, 3, 35, 147, GrowthRate.SLOW, null, false), - new PokemonSpecies(Species.METAGROSS, 3, false, false, false, "Iron Leg Pokémon", Type.STEEL, Type.PSYCHIC, 1.6, 550, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 3, 35, 300, GrowthRate.SLOW, null, false, true, + new PokemonSpecies(Species.BELDUM, 3, false, false, false, "Iron Ball Pokémon", Type.STEEL, Type.PSYCHIC, 0.6, 95.2, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 300, 40, 55, 80, 35, 60, 30, 45, 35, 60, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Frigibax + new PokemonSpecies(Species.METANG, 3, false, false, false, "Iron Claw Pokémon", Type.STEEL, Type.PSYCHIC, 1.2, 202.5, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 420, 60, 75, 100, 55, 80, 50, 25, 35, 147, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Arctibax + new PokemonSpecies(Species.METAGROSS, 3, false, false, false, "Iron Leg Pokémon", Type.STEEL, Type.PSYCHIC, 1.6, 550, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 10, 35, 300, GrowthRate.SLOW, null, false, true, //Custom Catchrate, matching Baxcalibur new PokemonForm("Normal", "", Type.STEEL, Type.PSYCHIC, 1.6, 550, Abilities.CLEAR_BODY, Abilities.NONE, Abilities.LIGHT_METAL, 600, 80, 135, 130, 95, 90, 70, 3, 35, 300, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.STEEL, Type.PSYCHIC, 2.5, 942.9, Abilities.TOUGH_CLAWS, Abilities.NONE, Abilities.TOUGH_CLAWS, 700, 80, 145, 150, 105, 110, 110, 3, 35, 300), ), @@ -1745,7 +1752,7 @@ export function initSpecies() { new PokemonSpecies(Species.EXCADRILL, 5, false, false, false, "Subterrene Pokémon", Type.GROUND, Type.STEEL, 0.7, 40.4, Abilities.SAND_RUSH, Abilities.SAND_FORCE, Abilities.MOLD_BREAKER, 508, 110, 135, 60, 50, 65, 88, 60, 50, 178, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.AUDINO, 5, false, false, false, "Hearing Pokémon", Type.NORMAL, null, 1.1, 31, Abilities.HEALER, Abilities.REGENERATOR, Abilities.KLUTZ, 445, 103, 60, 86, 60, 86, 50, 255, 50, 390, GrowthRate.FAST, 50, false, true, new PokemonForm("Normal", "", Type.NORMAL, null, 1.1, 31, Abilities.HEALER, Abilities.REGENERATOR, Abilities.KLUTZ, 445, 103, 60, 86, 60, 86, 50, 255, 50, 390, false, null, true), - new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.NORMAL, Type.FAIRY, 1.5, 32, Abilities.HEALER, Abilities.HEALER, Abilities.HEALER, 545, 103, 60, 126, 80, 126, 50, 255, 50, 390), + new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.NORMAL, Type.FAIRY, 1.5, 32, Abilities.REGENERATOR, Abilities.REGENERATOR, Abilities.REGENERATOR, 545, 103, 60, 126, 80, 126, 50, 255, 50, 390), //Custom Ability, base form Hidden Ability ), new PokemonSpecies(Species.TIMBURR, 5, false, false, false, "Muscular Pokémon", Type.FIGHTING, null, 0.6, 12.5, Abilities.GUTS, Abilities.SHEER_FORCE, Abilities.IRON_FIST, 305, 75, 80, 55, 25, 35, 35, 180, 70, 61, GrowthRate.MEDIUM_SLOW, 75, false), new PokemonSpecies(Species.GURDURR, 5, false, false, false, "Muscular Pokémon", Type.FIGHTING, null, 1.2, 40, Abilities.GUTS, Abilities.SHEER_FORCE, Abilities.IRON_FIST, 405, 85, 105, 85, 40, 50, 40, 90, 50, 142, GrowthRate.MEDIUM_SLOW, 75, false), @@ -2617,8 +2624,8 @@ export function initSpecies() { new PokemonForm("Aquatic Mode", "aquatic-mode", Type.ELECTRIC, Type.DRAGON, 2.8, 240, Abilities.HADRON_ENGINE, Abilities.NONE, Abilities.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, false, null, true), new PokemonForm("Glide Mode", "glide-mode", Type.ELECTRIC, Type.DRAGON, 2.8, 240, Abilities.HADRON_ENGINE, Abilities.NONE, Abilities.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, false, null, true), ), - new PokemonSpecies(Species.WALKING_WAKE, 9, false, false, false, "Paradox Pokémon", Type.WATER, Type.DRAGON, 3.5, 280, Abilities.PROTOSYNTHESIS, Abilities.NONE, Abilities.NONE, 590, 99, 83, 91, 125, 83, 109, 5, 0, 295, GrowthRate.SLOW, null, false), - new PokemonSpecies(Species.IRON_LEAVES, 9, false, false, false, "Paradox Pokémon", Type.GRASS, Type.PSYCHIC, 1.5, 125, Abilities.QUARK_DRIVE, Abilities.NONE, Abilities.NONE, 590, 90, 130, 88, 70, 108, 104, 5, 0, 295, GrowthRate.SLOW, null, false), + new PokemonSpecies(Species.WALKING_WAKE, 9, false, false, false, "Paradox Pokémon", Type.WATER, Type.DRAGON, 3.5, 280, Abilities.PROTOSYNTHESIS, Abilities.NONE, Abilities.NONE, 590, 99, 83, 91, 125, 83, 109, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Gouging Fire and Raging Bolt + new PokemonSpecies(Species.IRON_LEAVES, 9, false, false, false, "Paradox Pokémon", Type.GRASS, Type.PSYCHIC, 1.5, 125, Abilities.QUARK_DRIVE, Abilities.NONE, Abilities.NONE, 590, 90, 130, 88, 70, 108, 104, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Iron Boulder and Iron Crown new PokemonSpecies(Species.DIPPLIN, 9, false, false, false, "Candy Apple Pokémon", Type.GRASS, Type.DRAGON, 0.4, 9.7, Abilities.SUPERSWEET_SYRUP, Abilities.GLUTTONY, Abilities.STICKY_HOLD, 485, 80, 80, 110, 95, 80, 40, 45, 50, 170, GrowthRate.ERRATIC, 50, false), new PokemonSpecies(Species.POLTCHAGEIST, 9, false, false, false, "Matcha Pokémon", Type.GRASS, Type.GHOST, 0.1, 1.1, Abilities.HOSPITALITY, Abilities.NONE, Abilities.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, GrowthRate.SLOW, null, false, false, new PokemonForm("Counterfeit Form", "counterfeit", Type.GRASS, Type.GHOST, 0.1, 1.1, Abilities.HOSPITALITY, Abilities.NONE, Abilities.HEATPROOF, 308, 40, 45, 45, 74, 54, 50, 120, 50, 62, false, null, true), @@ -2671,7 +2678,7 @@ export function initSpecies() { new PokemonSpecies(Species.ALOLA_MUK, 7, false, false, false, "Sludge Pokémon", Type.POISON, Type.DARK, 1, 52, Abilities.POISON_TOUCH, Abilities.GLUTTONY, Abilities.POWER_OF_ALCHEMY, 500, 105, 105, 75, 65, 100, 50, 75, 70, 175, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.ALOLA_EXEGGUTOR, 7, false, false, false, "Coconut Pokémon", Type.GRASS, Type.DRAGON, 10.9, 415.6, Abilities.FRISK, Abilities.NONE, Abilities.HARVEST, 530, 95, 105, 85, 125, 75, 45, 45, 50, 186, GrowthRate.SLOW, 50, false), new PokemonSpecies(Species.ALOLA_MAROWAK, 7, false, false, false, "Bone Keeper Pokémon", Type.FIRE, Type.GHOST, 1, 34, Abilities.CURSED_BODY, Abilities.LIGHTNING_ROD, Abilities.ROCK_HEAD, 425, 60, 80, 110, 50, 80, 45, 75, 50, 149, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(Species.ETERNAL_FLOETTE, 6, false, false, false, "Single Bloom Pokémon", Type.FAIRY, null, 0.2, 0.9, Abilities.FLOWER_VEIL, Abilities.NONE, Abilities.SYMBIOSIS, 551, 74, 65, 67, 125, 128, 92, 120, 70, 130, GrowthRate.MEDIUM_FAST, 0, false), + new PokemonSpecies(Species.ETERNAL_FLOETTE, 6, true, false, false, "Single Bloom Pokémon", Type.FAIRY, null, 0.2, 0.9, Abilities.FLOWER_VEIL, Abilities.NONE, Abilities.SYMBIOSIS, 551, 74, 65, 67, 125, 128, 92, 120, 70, 130, GrowthRate.MEDIUM_FAST, 0, false), //Marked as Sub-Legend, for casing purposes new PokemonSpecies(Species.GALAR_MEOWTH, 8, false, false, false, "Scratch Cat Pokémon", Type.STEEL, null, 0.4, 7.5, Abilities.PICKUP, Abilities.TOUGH_CLAWS, Abilities.UNNERVE, 290, 50, 65, 55, 40, 40, 40, 255, 50, 58, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GALAR_PONYTA, 8, false, false, false, "Fire Horse Pokémon", Type.PSYCHIC, null, 0.8, 24, Abilities.RUN_AWAY, Abilities.PASTEL_VEIL, Abilities.ANTICIPATION, 410, 50, 85, 55, 65, 65, 90, 190, 50, 82, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GALAR_RAPIDASH, 8, false, false, false, "Fire Horse Pokémon", Type.PSYCHIC, Type.FAIRY, 1.7, 80, Abilities.RUN_AWAY, Abilities.PASTEL_VEIL, Abilities.ANTICIPATION, 500, 65, 100, 70, 80, 80, 105, 60, 50, 175, GrowthRate.MEDIUM_FAST, 50, false), @@ -2716,7 +2723,7 @@ export function initSpecies() { new PokemonForm("Aqua Breed", "aqua", Type.FIGHTING, Type.WATER, 1.4, 110, Abilities.INTIMIDATE, Abilities.ANGER_POINT, Abilities.CUD_CHEW, 490, 75, 110, 105, 30, 70, 100, 45, 50, 172, false, null, true), ), new PokemonSpecies(Species.PALDEA_WOOPER, 9, false, false, false, "Water Fish Pokémon", Type.POISON, Type.GROUND, 0.4, 11, Abilities.POISON_POINT, Abilities.WATER_ABSORB, Abilities.UNAWARE, 210, 55, 45, 45, 25, 25, 15, 255, 50, 42, GrowthRate.MEDIUM_FAST, 50, false), - new PokemonSpecies(Species.BLOODMOON_URSALUNA, 9, false, false, false, "Peat Pokémon", Type.GROUND, Type.NORMAL, 2.7, 333, Abilities.MINDS_EYE, Abilities.NONE, Abilities.NONE, 555, 113, 70, 120, 135, 65, 52, 75, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), + new PokemonSpecies(Species.BLOODMOON_URSALUNA, 9, true, false, false, "Peat Pokémon", Type.GROUND, Type.NORMAL, 2.7, 333, Abilities.MINDS_EYE, Abilities.NONE, Abilities.NONE, 555, 113, 70, 120, 135, 65, 52, 75, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), //Marked as Sub-Legend, for casing purposes ); } @@ -2985,7 +2992,7 @@ export const speciesStarters = { [Species.CRESSELIA]: 6, [Species.PHIONE]: 4, [Species.MANAPHY]: 7, - [Species.DARKRAI]: 6, + [Species.DARKRAI]: 7, [Species.SHAYMIN]: 6, [Species.ARCEUS]: 9, @@ -3069,7 +3076,7 @@ export const speciesStarters = { [Species.LANDORUS]: 7, [Species.KYUREM]: 8, [Species.KELDEO]: 6, - [Species.MELOETTA]: 6, + [Species.MELOETTA]: 7, [Species.GENESECT]: 6, [Species.CHESPIN]: 3, @@ -3150,7 +3157,7 @@ export const speciesStarters = { [Species.TAPU_LELE]: 6, [Species.TAPU_BULU]: 6, [Species.TAPU_FINI]: 6, - [Species.COSMOG]: 6, + [Species.COSMOG]: 7, [Species.NIHILEGO]: 6, [Species.BUZZWOLE]: 6, [Species.PHEROMOSA]: 7, @@ -3383,7 +3390,7 @@ export const starterPassiveAbilities = { [Species.SQUIRTLE]: Abilities.STURDY, [Species.CATERPIE]: Abilities.MAGICIAN, [Species.WEEDLE]: Abilities.TINTED_LENS, - [Species.PIDGEY]: Abilities.FLARE_BOOST, + [Species.PIDGEY]: Abilities.SHEER_FORCE, [Species.RATTATA]: Abilities.STRONG_JAW, [Species.SPEAROW]: Abilities.MOXIE, [Species.EKANS]: Abilities.REGENERATOR, @@ -3417,11 +3424,11 @@ export const starterPassiveAbilities = { [Species.GASTLY]: Abilities.SHADOW_SHIELD, [Species.ONIX]: Abilities.ROCKY_PAYLOAD, [Species.DROWZEE]: Abilities.MAGICIAN, - [Species.KRABBY]: Abilities.UNBURDEN, + [Species.KRABBY]: Abilities.THERMAL_EXCHANGE, [Species.VOLTORB]: Abilities.TRANSISTOR, [Species.EXEGGCUTE]: Abilities.RIPEN, [Species.CUBONE]: Abilities.PARENTAL_BOND, - [Species.LICKITUNG]: Abilities.THICK_FAT, + [Species.LICKITUNG]: Abilities.CHEEK_POUCH, [Species.KOFFING]: Abilities.PARENTAL_BOND, [Species.RHYHORN]: Abilities.FILTER, [Species.TANGELA]: Abilities.SEED_SOWER, @@ -3486,7 +3493,7 @@ export const starterPassiveAbilities = { [Species.SKARMORY]: Abilities.LIGHTNING_ROD, [Species.HOUNDOUR]: Abilities.DROUGHT, [Species.PHANPY]: Abilities.SPEED_BOOST, - [Species.STANTLER]: Abilities.ANALYTIC, + [Species.STANTLER]: Abilities.SPEED_BOOST, [Species.SMEARGLE]: Abilities.PRANKSTER, [Species.TYROGUE]: Abilities.MOXIE, [Species.SMOOCHUM]: Abilities.PSYCHIC_SURGE, @@ -3617,7 +3624,7 @@ export const starterPassiveAbilities = { [Species.DIALGA]: Abilities.LEVITATE, [Species.PALKIA]: Abilities.SPEED_BOOST, [Species.HEATRAN]: Abilities.EARTH_EATER, - [Species.REGIGIGAS]: Abilities.MINDS_EYE, + [Species.REGIGIGAS]: Abilities.SCRAPPY, [Species.GIRATINA]: Abilities.SHADOW_SHIELD, [Species.CRESSELIA]: Abilities.SHADOW_SHIELD, [Species.PHIONE]: Abilities.SIMPLE, @@ -3671,7 +3678,7 @@ export const starterPassiveAbilities = { [Species.EMOLGA]: Abilities.TRANSISTOR, [Species.KARRABLAST]: Abilities.QUICK_DRAW, [Species.FOONGUS]: Abilities.THICK_FAT, - [Species.FRILLISH]: Abilities.UNAWARE, + [Species.FRILLISH]: Abilities.POISON_HEAL, [Species.ALOMOMOLA]: Abilities.MULTISCALE, [Species.JOLTIK]: Abilities.TRANSISTOR, [Species.FERROSEED]: Abilities.ROUGH_SKIN, @@ -3745,7 +3752,7 @@ export const starterPassiveAbilities = { [Species.HOOPA]: Abilities.OPPORTUNIST, [Species.VOLCANION]: Abilities.FILTER, [Species.ROWLET]: Abilities.SNIPER, - [Species.LITTEN]: Abilities.FUR_COAT, + [Species.LITTEN]: Abilities.OPPORTUNIST, [Species.POPPLIO]: Abilities.PUNK_ROCK, [Species.PIKIPEK]: Abilities.TECHNICIAN, [Species.YUNGOOS]: Abilities.TOUGH_CLAWS, @@ -3899,7 +3906,7 @@ export const starterPassiveAbilities = { [Species.FRIGIBAX]: Abilities.SNOW_WARNING, [Species.GIMMIGHOUL]: Abilities.HONEY_GATHER, [Species.WO_CHIEN]: Abilities.VESSEL_OF_RUIN, - [Species.CHIEN_PAO]: Abilities.SNOW_WARNING, + [Species.CHIEN_PAO]: Abilities.INTIMIDATE, [Species.TING_LU]: Abilities.STAMINA, [Species.CHI_YU]: Abilities.BERSERK, [Species.ROARING_MOON]: Abilities.TOUGH_CLAWS, diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index fda4d2226c0..07525e92157 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -952,32 +952,35 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const baseStats = this.calculateBaseStats(); // Using base stats, calculate and store stats one by one for (const s of PERMANENT_STATS) { - let value = Math.floor(((2 * baseStats[s] + this.ivs[s]) * this.level) * 0.01); + const statHolder = new Utils.IntegerHolder(Math.floor(((2 * baseStats[s] + this.ivs[s]) * this.level) * 0.01)); if (s === Stat.HP) { - value = value + this.level + 10; + statHolder.value = statHolder.value + this.level + 10; + this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder); if (this.hasAbility(Abilities.WONDER_GUARD, false, true)) { - value = 1; + statHolder.value = 1; } - if (this.hp > value || this.hp === undefined) { - this.hp = value; + if (this.hp > statHolder.value || this.hp === undefined) { + this.hp = statHolder.value; } else if (this.hp) { const lastMaxHp = this.getMaxHp(); - if (lastMaxHp && value > lastMaxHp) { - this.hp += value - lastMaxHp; + if (lastMaxHp && statHolder.value > lastMaxHp) { + this.hp += statHolder.value - lastMaxHp; } } } else { - value += 5; + statHolder.value += 5; const natureStatMultiplier = new Utils.NumberHolder(getNatureStatMultiplier(this.getNature(), s)); this.scene.applyModifier(PokemonNatureWeightModifier, this.isPlayer(), this, natureStatMultiplier); if (natureStatMultiplier.value !== 1) { - value = Math.max(Math[natureStatMultiplier.value > 1 ? "ceil" : "floor"](value * natureStatMultiplier.value), 1); + statHolder.value = Math.max(Math[natureStatMultiplier.value > 1 ? "ceil" : "floor"](statHolder.value * natureStatMultiplier.value), 1); } + this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder); } - this.setStat(s, value); + statHolder.value = Utils.clampInt(statHolder.value, 1, Number.MAX_SAFE_INTEGER); + + this.setStat(s, statHolder.value); } - this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, this.stats); } calculateBaseStats(): number[] { @@ -1801,7 +1804,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns list of egg moves */ getEggMoves() : Moves[] | undefined { - return speciesEggMoves[this.getSpeciesForm().getRootSpeciesId(true)]; + return speciesEggMoves[this.getSpeciesForm().getRootSpeciesId()]; } setMove(moveIndex: integer, moveId: Moves): void { diff --git a/src/locales/de/battler-tags.json b/src/locales/de/battler-tags.json index f4b9d71eb49..3a2f1b84e49 100644 --- a/src/locales/de/battler-tags.json +++ b/src/locales/de/battler-tags.json @@ -75,5 +75,5 @@ "substituteOnAdd": "Ein Delegator von {{pokemonNameWithAffix}} ist erschienen!", "substituteOnHit": "Der Delegator steckt den Schlag für {{pokemonNameWithAffix}} ein!", "substituteOnRemove": "Der Delegator von {{pokemonNameWithAffix}} hört auf zu wirken!", - "autotomizeOnAdd": "{{pokemonNameWIthAffix}} ist leichter geworden!" + "autotomizeOnAdd": "{{pokemonNameWithAffix}} ist leichter geworden!" } diff --git a/src/locales/en/mystery-encounters/safari-zone-dialogue.json b/src/locales/en/mystery-encounters/safari-zone-dialogue.json index b96e3b5beb8..c1e4dd30852 100644 --- a/src/locales/en/mystery-encounters/safari-zone-dialogue.json +++ b/src/locales/en/mystery-encounters/safari-zone-dialogue.json @@ -1,7 +1,7 @@ { "intro": "It's a safari zone!", "title": "The Safari Zone", - "description": "There are all kinds of rare and special Pokémon that can be found here!\nIf you choose to enter, you'll have a time limit of @[TOOLTIP_TITLE]{{{numEncounters}} wild encounters} where you can try to catch these special Pokémon.\n\nBeware, though. These Pokémon may flee before you're able to catch them!", + "description": "There are all kinds of rare and special Pokémon that can be found here!\nIf you choose to enter, you'll have a time limit of@[TOOLTIP_TITLE]{ {{numEncounters}} wild encounters} where you can try to catch these special Pokémon.\n\nBeware, though. These Pokémon may flee before you're able to catch them!", "query": "Would you like to enter?", "option": { "1": { diff --git a/src/locales/es/mystery-encounters/department-store-sale-dialogue.json b/src/locales/es/mystery-encounters/department-store-sale-dialogue.json index e17d57b8c3c..f3f64a9ed57 100644 --- a/src/locales/es/mystery-encounters/department-store-sale-dialogue.json +++ b/src/locales/es/mystery-encounters/department-store-sale-dialogue.json @@ -1,7 +1,7 @@ { "intro": "Es una señora con un montón de bolsas de compras.", "speaker": "Compradora", - "intro_dialogue": "¡Hola! ¿También estás aquí por las increíbles rebajas? Hay un cupón especial que puedes canjear por un artículo gratis durante la venta. ¡Tengo uno extra. ¡Aquí tienes!", + "intro_dialogue": "¡Hola! ¿También estás aquí por las increíbles rebajas?$Hay un cupón especial que puedes canjear por un artículo gratis durante la venta. ¡Tengo uno extra. ¡Aquí tienes!", "title": "¡Rebajas en el Centro Comercial!", "description": "¡Hay mercancía en todas direcciones! Parece que hay 4 mostradores donde puedes canjear el cupón por varios artículos. ¡Las posibilidades son infinitas!", "query": "¿A qué mostrador irás?", @@ -24,4 +24,4 @@ } }, "outro": "¡Qué chollo! Deberías comprar allí más a menudo." -} \ No newline at end of file +} diff --git a/src/locales/es/trainer-names.json b/src/locales/es/trainer-names.json index 14e31638d9c..2e76c24be9f 100644 --- a/src/locales/es/trainer-names.json +++ b/src/locales/es/trainer-names.json @@ -180,5 +180,5 @@ "vicky": "Vicky", "vito": "Vito", "bug_type_superfan": "Superfan de los Pokémon Bicho", - "expert_pokemon_breeder": "Criaokémon Experta" + "expert_pokemon_breeder": "Criapokémon Experta" } diff --git a/src/locales/zh_CN/mystery-encounters/mysterious-chest-dialogue.json b/src/locales/zh_CN/mystery-encounters/mysterious-chest-dialogue.json index ff01386ca59..b26c5d38c03 100644 --- a/src/locales/zh_CN/mystery-encounters/mysterious-chest-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/mysterious-chest-dialogue.json @@ -12,7 +12,7 @@ "good": "一些不错的工具和物品!", "great": "一些很稀有的工具和物品!!", "amazing": "哇!金色传说!", - "bad": "哦不!@d{32}\n这个箱子实际上是一个伪装的{{gimmighoul Name}}!$你的{{pokeName}}跳到了你面前\n但为了保护你被打倒了!" + "bad": "哦不!@d{32}\n这个箱子实际上是一个伪装的{{gimmighoulName}}!$你的{{pokeName}}跳到了你面前\n但为了保护你被打倒了!" }, "2": { "label": "有诈,走了", diff --git a/src/locales/zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json b/src/locales/zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json index 359376eca3d..9412426d794 100644 --- a/src/locales/zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/shady-vitamin-dealer-dialogue.json @@ -20,7 +20,7 @@ "tooltip": "(-)无奖励", "selected": "呵呵,没想到你竟然是个懦夫。" }, - "selected": "那人递给你两瓶东西后\n然后很快就消失了。${{selected Pokemon}}获得了{{boost}}和{{boost 2}}提升!" + "selected": "那人递给你两瓶东西后\n然后很快就消失了。${{selectedPokemon}}获得了{{boost1}}和{{boost2}}提升!" }, "cheap_side_effects": "但是药物有一些副作用!$你的{{selectedPokemon}}受到一些伤害,\n并且它的性格变为{{newNature}}!", "no_bad_effects": "看来药物完全没有副作用!" diff --git a/src/locales/zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json b/src/locales/zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json index ee3109e3a1f..8ab03382477 100644 --- a/src/locales/zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/slumbering-snorlax-dialogue.json @@ -13,7 +13,7 @@ "label": "干等", "tooltip": "(-)漫长的等待\n(+)回复队伍", "selected": ".@d{32}.@d{32}.@d{32}$您等待了好一段时间,但是\n{{snorlaxName}}的哈欠让你的队伍昏昏欲睡…………", - "rest_result": "当你们醒来时,{{snorlax Name}}已无处可寻。\n但你所有的宝可梦都痊愈了!" + "rest_result": "当你们醒来时,{{snorlaxName}}已无处可寻。\n但你所有的宝可梦都痊愈了!" }, "3": { "label": "偷摸", diff --git a/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json b/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json index dab52bef1db..7bb6229d330 100644 --- a/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json +++ b/src/locales/zh_CN/mystery-encounters/training-session-dialogue.json @@ -27,7 +27,7 @@ "tooltip": "(-)无奖励", "selected": "你无暇训练\n该动身了。" }, - "selected": "{{selected Pokemon}}穿过空地来到你面前……" + "selected": "{{selectedPokemon}}穿过空地来到你面前……" }, "outro": "这次训练成果不错!" } diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 6c998105c1d..cf9cf78225e 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1,4 +1,5 @@ import * as ModifierTypes from "./modifier-type"; +import { ModifierType, modifierTypes } from "./modifier-type"; import BattleScene from "../battle-scene"; import { getLevelTotalExp } from "../data/exp"; import { MAX_PER_TYPE_POKEBALLS, PokeballType } from "../data/pokeball"; @@ -12,16 +13,15 @@ import * as Utils from "../utils"; import { getBerryEffectFunc, getBerryPredicate } from "../data/berry"; import { BattlerTagType } from "#enums/battler-tag-type"; import { BerryType } from "#enums/berry-type"; -import { StatusEffect, getStatusEffectHealText } from "../data/status-effect"; +import { getStatusEffectHealText, StatusEffect } from "#app/data/status-effect"; import { achvs } from "../system/achv"; import { VoucherType } from "../system/voucher"; import { FormChangeItem, SpeciesFormChangeItemTrigger, SpeciesFormChangeLapseTeraTrigger, SpeciesFormChangeTeraTrigger } from "../data/pokemon-forms"; import { Nature } from "#app/data/nature"; import Overrides from "#app/overrides"; -import { ModifierType, modifierTypes } from "./modifier-type"; import { Command } from "#app/ui/command-ui-handler"; import { Species } from "#enums/species"; -import { Stat, type PermanentStat, type TempBattleStat, BATTLE_STATS, TEMP_BATTLE_STATS } from "#app/enums/stat"; +import { BATTLE_STATS, type PermanentStat, Stat, TEMP_BATTLE_STATS, type TempBattleStat } from "#app/enums/stat"; import i18next from "i18next"; import { allMoves } from "#app/data/move"; @@ -882,7 +882,7 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { private statModifier: integer; public isTransferable: boolean = false; - constructor(type: ModifierTypes.PokemonBaseStatTotalModifierType, pokemonId: integer, statModifier: integer, stackCount?: integer) { + constructor(type: ModifierTypes.PokemonBaseStatTotalModifierType, pokemonId: number, statModifier: number, stackCount?: integer) { super(type, pokemonId, stackCount); this.statModifier = statModifier; } @@ -927,11 +927,11 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { * Currently used by Old Gateau item */ export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier { - private statModifier: integer; + private statModifier: number; private stats: Stat[]; public isTransferable: boolean = false; - constructor (type: ModifierType, pokemonId: integer, statModifier: integer, stats: Stat[], stackCount?: integer) { + constructor (type: ModifierType, pokemonId: number, statModifier: number, stats: Stat[], stackCount?: number) { super(type, pokemonId, stackCount); this.statModifier = statModifier; @@ -947,7 +947,7 @@ export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier { } override getArgs(): any[] { - return super.getArgs().concat(this.statModifier, this.stats); + return [ ...super.getArgs(), this.statModifier, this.stats ]; } override shouldApply(args: any[]): boolean { @@ -989,8 +989,8 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { return modifier instanceof PokemonIncrementingStatModifier; } - clone(): PersistentModifier { - return new PokemonIncrementingStatModifier(this.type, this.pokemonId); + clone(): PokemonIncrementingStatModifier { + return new PokemonIncrementingStatModifier(this.type, this.pokemonId, this.stackCount); } getArgs(): any[] { @@ -998,21 +998,26 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { } shouldApply(args: any[]): boolean { - return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array; + return super.shouldApply(args) && args.length === 3 && args[2] instanceof Utils.IntegerHolder; } apply(args: any[]): boolean { - // Modifies the passed in stats[] array by +1 per stack for HP, +2 per stack for other stats + // Modifies the passed in stat integer holder by +1 per stack for HP, +2 per stack for other stats // If the Macho Brace is at max stacks (50), adds additional 5% to total HP and 10% to other stats - args[1].forEach((v, i) => { - const isHp = i === 0; - let mult = 1; + const isHp = args[1] === Stat.HP; + const statHolder = args[2] as Utils.IntegerHolder; + + if (isHp) { + statHolder.value += this.stackCount; if (this.stackCount === this.getMaxHeldItemCount()) { - mult = isHp ? 1.05 : 1.1; + statHolder.value = Math.floor(statHolder.value * 1.05); } - const newVal = Math.floor((v + this.stackCount * (isHp ? 1 : 2)) * mult); - args[1][i] = Math.min(Math.max(newVal, 1), 999999); - }); + } else { + statHolder.value += 2 * this.stackCount; + if (this.stackCount === this.getMaxHeldItemCount()) { + statHolder.value = Math.floor(statHolder.value * 1.1); + } + } return true; } diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 66e39cf98a5..a374f885d3f 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -70,7 +70,7 @@ export class CommandPhase extends FieldPhase { } } } else { - if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.scene.currentBattle.mysteryEncounter?.skipToFightInput) { + if (this.scene.currentBattle.isBattleMysteryEncounter() && this.scene.currentBattle.mysteryEncounter?.skipToFightInput) { this.scene.ui.clearText(); this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex); } else { @@ -141,7 +141,7 @@ export class CommandPhase extends FieldPhase { this.scene.ui.showText("", 0); this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); }, null, true); - } else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && !this.scene.currentBattle.mysteryEncounter!.catchAllowed) { + } else if (this.scene.currentBattle.isBattleMysteryEncounter() && !this.scene.currentBattle.mysteryEncounter!.catchAllowed) { this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.showText(i18next.t("battle:noPokeballMysteryEncounter"), null, () => { diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 25b4398025f..798ee3dca3c 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -34,6 +34,7 @@ import { doTrainerExclamation } from "#app/data/mystery-encounters/utils/encount import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; import { getGoldenBugNetSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { Biome } from "#enums/biome"; export class EncounterPhase extends BattlePhase { private loaded: boolean; @@ -63,7 +64,7 @@ export class EncounterPhase extends BattlePhase { const battle = this.scene.currentBattle; // Generate and Init Mystery Encounter - if (battle.battleType === BattleType.MYSTERY_ENCOUNTER && !battle.mysteryEncounter) { + if (battle.isBattleMysteryEncounter() && !battle.mysteryEncounter) { this.scene.executeWithSeedOffset(() => { const currentSessionEncounterType = battle.mysteryEncounterType; battle.mysteryEncounter = this.scene.getMysteryEncounter(currentSessionEncounterType); @@ -79,7 +80,7 @@ export class EncounterPhase extends BattlePhase { mysteryEncounter.onInit(this.scene); } mysteryEncounter.populateDialogueTokensFromRequirements(this.scene); - }, this.scene.currentBattle.waveIndex); + }, battle.waveIndex); // Add any special encounter animations to load if (mysteryEncounter.encounterAnimations && mysteryEncounter.encounterAnimations.length > 0) { @@ -94,7 +95,7 @@ export class EncounterPhase extends BattlePhase { let totalBst = 0; battle.enemyLevels?.every((level, e) => { - if (battle.battleType === BattleType.MYSTERY_ENCOUNTER) { + if (battle.isBattleMysteryEncounter()) { // Skip enemy loading for MEs, those are loaded elsewhere return false; } @@ -103,9 +104,12 @@ export class EncounterPhase extends BattlePhase { battle.enemyParty[e] = battle.trainer?.genPartyMember(e)!; // TODO:: is the bang correct here? } else { let enemySpecies = this.scene.randomSpecies(battle.waveIndex, level, true); - // If player has golden bug net, rolls 10% chance to replace with species from the golden bug net bug pool - if (this.scene.findModifier(m => m instanceof BoostBugSpawnModifier) && randSeedInt(10) === 0) { - enemySpecies = getGoldenBugNetSpecies(); + // If player has golden bug net, rolls 10% chance to replace non-boss wave wild species from the golden bug net bug pool + if (this.scene.findModifier(m => m instanceof BoostBugSpawnModifier) + && !this.scene.gameMode.isBoss(battle.waveIndex) + && this.scene.arena.biomeType !== Biome.END + && randSeedInt(10) === 0) { + enemySpecies = getGoldenBugNetSpecies(level); } battle.enemyParty[e] = this.scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!this.scene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies)); if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) { @@ -157,7 +161,7 @@ export class EncounterPhase extends BattlePhase { if (battle.battleType === BattleType.TRAINER) { loadEnemyAssets.push(battle.trainer?.loadAssets().then(() => battle.trainer?.initSprite())!); // TODO: is this bang correct? - } else if (battle.battleType === BattleType.MYSTERY_ENCOUNTER) { + } else if (battle.isBattleMysteryEncounter()) { if (battle.mysteryEncounter?.introVisuals) { loadEnemyAssets.push(battle.mysteryEncounter.introVisuals.loadAssets().then(() => battle.mysteryEncounter!.introVisuals!.initSprite())); } @@ -189,7 +193,7 @@ export class EncounterPhase extends BattlePhase { Promise.all(loadEnemyAssets).then(() => { battle.enemyParty.every((enemyPokemon, e) => { - if (battle.battleType === BattleType.MYSTERY_ENCOUNTER) { + if (battle.isBattleMysteryEncounter()) { return false; } if (e < (battle.double ? 2 : 1)) { @@ -363,7 +367,7 @@ export class EncounterPhase extends BattlePhase { showDialogueAndSummon(); } } - } else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.scene.currentBattle.mysteryEncounter) { + } else if (this.scene.currentBattle.isBattleMysteryEncounter() && this.scene.currentBattle.mysteryEncounter) { const encounter = this.scene.currentBattle.mysteryEncounter; const introVisuals = encounter.introVisuals; introVisuals?.playAnim(); diff --git a/src/phases/post-summon-phase.ts b/src/phases/post-summon-phase.ts index e7f6c6ea3db..b99c0b90fd8 100644 --- a/src/phases/post-summon-phase.ts +++ b/src/phases/post-summon-phase.ts @@ -6,7 +6,6 @@ import { StatusEffect } from "#app/enums/status-effect"; import { PokemonPhase } from "./pokemon-phase"; import { MysteryEncounterPostSummonTag } from "#app/data/battler-tags"; import { BattlerTagType } from "#enums/battler-tag-type"; -import { BattleType } from "#app/battle"; export class PostSummonPhase extends PokemonPhase { constructor(scene: BattleScene, battlerIndex: BattlerIndex) { @@ -24,7 +23,7 @@ export class PostSummonPhase extends PokemonPhase { this.scene.arena.applyTags(ArenaTrapTag, pokemon); // If this is mystery encounter and has post summon phase tag, apply post summon effects - if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && pokemon.findTags(t => t instanceof MysteryEncounterPostSummonTag).length > 0) { + if (this.scene.currentBattle.isBattleMysteryEncounter() && pokemon.findTags(t => t instanceof MysteryEncounterPostSummonTag).length > 0) { pokemon.lapseTag(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON); } diff --git a/src/phases/summon-phase.ts b/src/phases/summon-phase.ts index d909c5c3501..dfa374307d5 100644 --- a/src/phases/summon-phase.ts +++ b/src/phases/summon-phase.ts @@ -87,7 +87,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { this.scene.pbTrayEnemy.hide(); this.scene.ui.showText(message, null, () => this.summon()); - } else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER) { + } else if (this.scene.currentBattle.isBattleMysteryEncounter()) { this.scene.pbTrayEnemy.hide(); this.summonWild(); } diff --git a/src/phases/victory-phase.ts b/src/phases/victory-phase.ts index c10adc5683d..e900ff97fc6 100644 --- a/src/phases/victory-phase.ts +++ b/src/phases/victory-phase.ts @@ -30,7 +30,7 @@ export class VictoryPhase extends PokemonPhase { const expValue = this.getPokemon().getExpValue(); this.scene.applyPartyExp(expValue, true); - if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER) { + if (this.scene.currentBattle.isBattleMysteryEncounter()) { handleMysteryEncounterVictory(this.scene, false, this.isExpOnly); return this.end(); } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 22a793e9aca..63c7cb1b13a 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1,5 +1,5 @@ import i18next from "i18next"; -import BattleScene, { PokeballCounts, bypassLogin } from "../battle-scene"; +import BattleScene, { bypassLogin, PokeballCounts } from "../battle-scene"; import Pokemon, { EnemyPokemon, PlayerPokemon } from "../field/pokemon"; import { pokemonPrevolutions } from "../data/pokemon-evolutions"; import PokemonSpecies, { allSpecies, getPokemonSpecies, noStarterFormKeys, speciesStarters } from "../data/pokemon-species"; @@ -13,11 +13,11 @@ import { GameModes, getGameMode } from "../game-mode"; import { BattleType } from "../battle"; import TrainerData from "./trainer-data"; import { trainerConfigs } from "../data/trainer-config"; -import { SettingKeys, resetSettings, setSetting } from "./settings/settings"; +import { resetSettings, setSetting, SettingKeys } from "./settings/settings"; import { achvs } from "./achv"; import EggData from "./egg-data"; import { Egg } from "../data/egg"; -import { VoucherType, vouchers } from "./voucher"; +import { vouchers, VoucherType } from "./voucher"; import { AES, enc } from "crypto-js"; import { Mode } from "../ui/ui"; import { clientSessionId, loggedInUser, updateUserInfo } from "../account"; @@ -28,8 +28,8 @@ import { speciesEggMoves } from "../data/egg-moves"; import { allMoves } from "../data/move"; import { TrainerVariant } from "../field/trainer"; import { Variant } from "#app/data/variant"; -import {setSettingGamepad, SettingGamepad, settingGamepadDefaults} from "./settings/settings-gamepad"; -import {setSettingKeyboard, SettingKeyboard} from "#app/system/settings/settings-keyboard"; +import { setSettingGamepad, SettingGamepad, settingGamepadDefaults } from "./settings/settings-gamepad"; +import { setSettingKeyboard, SettingKeyboard } from "#app/system/settings/settings-keyboard"; import { TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; import * as Modifier from "../modifier/modifier"; import { StatusEffect } from "#app/data/status-effect"; @@ -48,6 +48,7 @@ import { RUN_HISTORY_LIMIT } from "#app/ui/run-history-ui-handler"; import { applySessionDataPatches, applySettingsDataPatches, applySystemDataPatches } from "./version-converter"; import { MysteryEncounterSaveData } from "../data/mystery-encounters/mystery-encounter-save-data"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; +import { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api"; export const defaultStarterSpecies: Species[] = [ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, @@ -1186,37 +1187,43 @@ export class GameData { }); } - tryClearSession(scene: BattleScene, slotId: integer): Promise<[success: boolean, newClear: boolean]> { - return new Promise<[boolean, boolean]>(resolve => { - if (bypassLogin) { - localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); - return resolve([true, true]); + + /** + * Attempt to clear session data. After session data is removed, attempt to update user info so the menu updates + */ + async tryClearSession(scene: BattleScene, slotId: integer): Promise<[success: boolean, newClear: boolean]> { + let result: [boolean, boolean] = [false, false]; + + if (bypassLogin) { + localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); + result = [true, true]; + } else { + const sessionData = this.getSessionSaveData(scene); + const response = await Utils.apiPost(`savedata/session/clear?slot=${slotId}&trainerId=${this.trainerId}&secretId=${this.secretId}&clientSessionId=${clientSessionId}`, JSON.stringify(sessionData), undefined, true); + + if (response.ok) { + loggedInUser!.lastSessionSlot = -1; // TODO: is the bang correct? + localStorage.removeItem(`sessionData${this.scene.sessionSlotId ? this.scene.sessionSlotId : ""}_${loggedInUser?.username}`); } - updateUserInfo().then(success => { - if (success !== null && !success) { - return resolve([false, false]); + const jsonResponse: PokerogueApiClearSessionData = await response.json(); + + if (!jsonResponse.error) { + result = [true, jsonResponse.success ?? false]; + } else { + if (jsonResponse && jsonResponse.error?.startsWith("session out of date")) { + this.scene.clearPhaseQueue(); + this.scene.unshiftPhase(new ReloadSessionPhase(this.scene)); } - const sessionData = this.getSessionSaveData(scene); - Utils.apiPost(`savedata/session/clear?slot=${slotId}&trainerId=${this.trainerId}&secretId=${this.secretId}&clientSessionId=${clientSessionId}`, JSON.stringify(sessionData), undefined, true).then(response => { - if (response.ok) { - loggedInUser!.lastSessionSlot = -1; // TODO: is the bang correct? - localStorage.removeItem(`sessionData${this.scene.sessionSlotId ? this.scene.sessionSlotId : ""}_${loggedInUser?.username}`); - } - return response.json(); - }).then(jsonResponse => { - if (!jsonResponse.error) { - return resolve([true, jsonResponse.success as boolean]); - } - if (jsonResponse && jsonResponse.error.startsWith("session out of date")) { - this.scene.clearPhaseQueue(); - this.scene.unshiftPhase(new ReloadSessionPhase(this.scene)); - } - console.error(jsonResponse); - resolve([false, false]); - }); - }); - }); + + console.error(jsonResponse); + result = [false, false]; + } + } + + await updateUserInfo(); + + return result; } parseSessionData(dataStr: string): SessionSaveData { @@ -1576,12 +1583,20 @@ export class GameData { * @returns `true` if Pokemon catch unlocked a new starter, `false` if Pokemon catch did not unlock a starter */ setPokemonCaught(pokemon: Pokemon, incrementCount: boolean = true, fromEgg: boolean = false, showMessage: boolean = true): Promise { - return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg, showMessage); + // If incrementCount === false (not a catch scenario), only update the pokemon's dex data if the Pokemon has already been marked as caught in dex + // Prevents form changes, nature changes, etc. from unintentionally updating the dex data of a "rental" pokemon + const speciesRootForm = pokemon.species.getRootSpeciesId(); + if (!incrementCount && !this.scene.gameData.dexData[speciesRootForm].caughtAttr) { + return Promise.resolve(false); + } else { + return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg, showMessage); + } } /** * * @param pokemon + * @param species * @param incrementCount * @param fromEgg * @param showMessage @@ -1597,12 +1612,18 @@ export class GameData { } const dexAttr = pokemon.getDexAttr(); pokemon.formIndex = formIndex; + + // Mark as caught dexEntry.caughtAttr |= dexAttr; + + // Unlock ability if (speciesStarters.hasOwnProperty(species.speciesId)) { this.starterData[species.speciesId].abilityAttr |= pokemon.abilityIndex !== 1 || pokemon.species.ability2 ? 1 << pokemon.abilityIndex : AbilityAttr.ABILITY_HIDDEN; } + + // Unlock nature dexEntry.natureAttr |= 1 << (pokemon.nature + 1); const hasPrevolution = pokemonPrevolutions.hasOwnProperty(species.speciesId); @@ -1697,9 +1718,19 @@ export class GameData { return ++this.starterData[speciesIdToIncrement].classicWinCount; } + /** + * Adds a candy to the player's game data for a given {@linkcode PokemonSpecies}. + * Will do nothing if the player does not have the Pokemon owned in their system save data. + * @param species + * @param count + */ addStarterCandy(species: PokemonSpecies, count: integer): void { - this.scene.candyBar.showStarterSpeciesCandy(species.speciesId, count); - this.starterData[species.speciesId].candyCount += count; + // Only gain candies if the Pokemon has already been marked as caught in dex (ignore "rental" pokemon) + const speciesRootForm = species.getRootSpeciesId(); + if (this.scene.gameData.dexData[speciesRootForm].caughtAttr) { + this.scene.candyBar.showStarterSpeciesCandy(species.speciesId, count); + this.starterData[species.speciesId].candyCount += count; + } } /** diff --git a/src/test/system/game_data.test.ts b/src/test/system/game_data.test.ts new file mode 100644 index 00000000000..e3550e44fff --- /dev/null +++ b/src/test/system/game_data.test.ts @@ -0,0 +1,89 @@ +import * as BattleScene from "#app/battle-scene"; +import { SessionSaveData } from "#app/system/game-data"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import GameManager from "#test/utils/gameManager"; +import { http, HttpResponse } from "msw"; +import { setupServer } from "msw/node"; +import Phaser from "phaser"; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import * as account from "../../account"; + +const apiBase = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8001"; + +export const server = setupServer(); + +describe("System - Game Data", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + server.listen(); + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterAll(() => { + server.close(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([Moves.SPLASH]) + .battleType("single") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + afterEach(() => { + server.resetHandlers(); + game.phaseInterceptor.restoreOg(); + }); + + describe("tryClearSession", () => { + beforeEach(() => { + vi.spyOn(BattleScene, "bypassLogin", "get").mockReturnValue(false); + vi.spyOn(game.scene.gameData, "getSessionSaveData").mockReturnValue({} as SessionSaveData); + vi.spyOn(account, "updateUserInfo").mockImplementation(async () => [true, 1]); + }); + + it("should return [true, true] if bypassLogin is true", async () => { + vi.spyOn(BattleScene, "bypassLogin", "get").mockReturnValue(true); + + const result = await game.scene.gameData.tryClearSession(game.scene, 0); + + expect(result).toEqual([true, true]); + }); + + it("should return [true, true] if successful", async () => { + server.use(http.post(`${apiBase}/savedata/session/clear`, () => HttpResponse.json({ success: true }))); + + const result = await game.scene.gameData.tryClearSession(game.scene, 0); + + expect(result).toEqual([true, true]); + expect(account.updateUserInfo).toHaveBeenCalled(); + }); + + it("should return [true, false] if not successful", async () => { + server.use(http.post(`${apiBase}/savedata/session/clear`, () => HttpResponse.json({ success: false }))); + + const result = await game.scene.gameData.tryClearSession(game.scene, 0); + + expect(result).toEqual([true, false]); + expect(account.updateUserInfo).toHaveBeenCalled(); + }); + + it("should return [false, false] session is out of date", async () => { + server.use( + http.post(`${apiBase}/savedata/session/clear`, () => HttpResponse.json({ error: "session out of date" })) + ); + + const result = await game.scene.gameData.tryClearSession(game.scene, 0); + + expect(result).toEqual([false, false]); + expect(account.updateUserInfo).toHaveBeenCalled(); + }); + }); +});