diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a30cb642a46..032e1fee69c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,37 +1,76 @@ - - - + + + + ## What are the changes the user will see? ## Why am I making these changes? - - - + + ## What are the changes from a developer perspective? - - + -### Screenshots/Videos - - +## Screenshots/Videos + ## How to test the changes? - - - - + ## Checklist - [ ] **I'm using `beta` as my base branch** - [ ] There is no overlap with another PR? - [ ] The PR is self-contained and cannot be split into smaller PRs? - [ ] Have I provided a clear explanation of the changes? -- [ ] Have I considered writing automated tests for the issue? -- [ ] If I have text, did I make it translatable and add a key in the English locale file(s)? -- [ ] Have I tested the changes (manually)? - - [ ] Are all unit tests still passing? (`npm run test`) -- [ ] Are the changes visual? - - [ ] Have I provided screenshots/videos of the changes? +- [ ] Have I tested the changes manually? +- [ ] Are all unit tests still passing? (`npm run test`) + - [ ] Have I created new automated tests (`npm run create-test`) or updated existing tests related to the PR's changes? +- [ ] Have I provided screenshots/videos of the changes (if applicable)? + - [ ] Have I made sure that any UI change works for both UI themes (default and legacy)? + +Are there any localization additions or changes? If so: +- [ ] Has a locales PR been created on the [locales](https://github.com/pagefaultgames/pokerogue-locales) repo? + - [ ] If so, please leave a link to it here: +- [ ] Has the translation team been contacted for proofreading/translation? \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9e512884922..9d6e2440f44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.1.6", + "version": "1.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.1.6", + "version": "1.2.2", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index f106fb1a773..ef2d4938087 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.1.6", + "version": "1.2.2", "type": "module", "scripts": { "start": "vite", diff --git a/public/images/items.png b/public/images/items.png index cb4f8fa7d06..191766f520e 100644 Binary files a/public/images/items.png and b/public/images/items.png differ diff --git a/public/images/items/catching_charm.png b/public/images/items/catching_charm.png index 9d72fe465e3..c220ff70c03 100644 Binary files a/public/images/items/catching_charm.png and b/public/images/items/catching_charm.png differ diff --git a/public/images/pokemon/1003.png b/public/images/pokemon/1003.png index 3a88f39d65f..eb69527246d 100644 Binary files a/public/images/pokemon/1003.png and b/public/images/pokemon/1003.png differ diff --git a/public/images/pokemon/159.png b/public/images/pokemon/159.png index 62de85e4ad7..46073ff539c 100644 Binary files a/public/images/pokemon/159.png and b/public/images/pokemon/159.png differ diff --git a/public/images/pokemon/164.png b/public/images/pokemon/164.png index c172959d338..b5d83ad6818 100644 Binary files a/public/images/pokemon/164.png and b/public/images/pokemon/164.png differ diff --git a/public/images/pokemon/190.png b/public/images/pokemon/190.png index b049ba83296..40563cec158 100644 Binary files a/public/images/pokemon/190.png and b/public/images/pokemon/190.png differ diff --git a/public/images/pokemon/199.png b/public/images/pokemon/199.png index d3b072497bd..f2e8888fb2d 100644 Binary files a/public/images/pokemon/199.png and b/public/images/pokemon/199.png differ diff --git a/public/images/pokemon/218.png b/public/images/pokemon/218.png index aeb9a35f9fe..64faad88ba3 100644 Binary files a/public/images/pokemon/218.png and b/public/images/pokemon/218.png differ diff --git a/public/images/pokemon/226.png b/public/images/pokemon/226.png index dbc04cc885f..006bd465b05 100644 Binary files a/public/images/pokemon/226.png and b/public/images/pokemon/226.png differ diff --git a/public/images/pokemon/228.png b/public/images/pokemon/228.png index c601cc4058d..476aa4d619d 100644 Binary files a/public/images/pokemon/228.png and b/public/images/pokemon/228.png differ diff --git a/public/images/pokemon/229-mega.png b/public/images/pokemon/229-mega.png index ebcda7bf90a..fac79bad8c1 100644 Binary files a/public/images/pokemon/229-mega.png and b/public/images/pokemon/229-mega.png differ diff --git a/public/images/pokemon/229.png b/public/images/pokemon/229.png index 270f36e64eb..6439012bacf 100644 Binary files a/public/images/pokemon/229.png and b/public/images/pokemon/229.png differ diff --git a/public/images/pokemon/232.png b/public/images/pokemon/232.png index ac7ae0eb5ae..0bfb76be5ed 100644 Binary files a/public/images/pokemon/232.png and b/public/images/pokemon/232.png differ diff --git a/public/images/pokemon/25-cool-cosplay.png b/public/images/pokemon/25-cool-cosplay.png index 123ae257598..ba1e1145901 100644 Binary files a/public/images/pokemon/25-cool-cosplay.png and b/public/images/pokemon/25-cool-cosplay.png differ diff --git a/public/images/pokemon/256.png b/public/images/pokemon/256.png index beb509fa9de..2a071e76188 100644 Binary files a/public/images/pokemon/256.png and b/public/images/pokemon/256.png differ diff --git a/public/images/pokemon/257-mega.png b/public/images/pokemon/257-mega.png index 0350e97deee..51d700c3e9a 100644 Binary files a/public/images/pokemon/257-mega.png and b/public/images/pokemon/257-mega.png differ diff --git a/public/images/pokemon/257.png b/public/images/pokemon/257.png index 76cfb0490e8..77dbc705a60 100644 Binary files a/public/images/pokemon/257.png and b/public/images/pokemon/257.png differ diff --git a/public/images/pokemon/261.png b/public/images/pokemon/261.png index a519b9951a4..9e47128a545 100644 Binary files a/public/images/pokemon/261.png and b/public/images/pokemon/261.png differ diff --git a/public/images/pokemon/262.png b/public/images/pokemon/262.png index ee95836e908..71509b88626 100644 Binary files a/public/images/pokemon/262.png and b/public/images/pokemon/262.png differ diff --git a/public/images/pokemon/308.png b/public/images/pokemon/308.png index 20e41507efa..94dd021f209 100644 Binary files a/public/images/pokemon/308.png and b/public/images/pokemon/308.png differ diff --git a/public/images/pokemon/335.png b/public/images/pokemon/335.png index 87f8b341b55..e5d051dd850 100644 Binary files a/public/images/pokemon/335.png and b/public/images/pokemon/335.png differ diff --git a/public/images/pokemon/336.png b/public/images/pokemon/336.png index 5908f2b36a2..daf64440220 100644 Binary files a/public/images/pokemon/336.png and b/public/images/pokemon/336.png differ diff --git a/public/images/pokemon/357.png b/public/images/pokemon/357.png index ce003f24c41..6b1ed63c3fe 100644 Binary files a/public/images/pokemon/357.png and b/public/images/pokemon/357.png differ diff --git a/public/images/pokemon/370.png b/public/images/pokemon/370.png index c53d42f9cd3..e9f29872fb2 100644 Binary files a/public/images/pokemon/370.png and b/public/images/pokemon/370.png differ diff --git a/public/images/pokemon/373.png b/public/images/pokemon/373.png index e3f967583a5..5174907b69b 100644 Binary files a/public/images/pokemon/373.png and b/public/images/pokemon/373.png differ diff --git a/public/images/pokemon/401.png b/public/images/pokemon/401.png index fa3dd915202..f4fffa67e54 100644 Binary files a/public/images/pokemon/401.png and b/public/images/pokemon/401.png differ diff --git a/public/images/pokemon/402.png b/public/images/pokemon/402.png index a7808e446a6..15de8f02a0d 100644 Binary files a/public/images/pokemon/402.png and b/public/images/pokemon/402.png differ diff --git a/public/images/pokemon/4080.png b/public/images/pokemon/4080.png index 4af9ba7ea0d..2ad2193cdbc 100644 Binary files a/public/images/pokemon/4080.png and b/public/images/pokemon/4080.png differ diff --git a/public/images/pokemon/418.png b/public/images/pokemon/418.png index 005c917463f..fba2402c2b3 100644 Binary files a/public/images/pokemon/418.png and b/public/images/pokemon/418.png differ diff --git a/public/images/pokemon/419.png b/public/images/pokemon/419.png index 572f819749b..5fbe90ff3bd 100644 Binary files a/public/images/pokemon/419.png and b/public/images/pokemon/419.png differ diff --git a/public/images/pokemon/4199.png b/public/images/pokemon/4199.png index df9dee11cdb..9c9f86e1f5d 100644 Binary files a/public/images/pokemon/4199.png and b/public/images/pokemon/4199.png differ diff --git a/public/images/pokemon/424.png b/public/images/pokemon/424.png index d19a5a79e4a..c0bc59a0caa 100644 Binary files a/public/images/pokemon/424.png and b/public/images/pokemon/424.png differ diff --git a/public/images/pokemon/45.png b/public/images/pokemon/45.png index db9c8d9c3f2..1c6f5a5a9f2 100644 Binary files a/public/images/pokemon/45.png and b/public/images/pokemon/45.png differ diff --git a/public/images/pokemon/456.png b/public/images/pokemon/456.png index 4b6c8c4e52f..501eb5904fe 100644 Binary files a/public/images/pokemon/456.png and b/public/images/pokemon/456.png differ diff --git a/public/images/pokemon/4562.png b/public/images/pokemon/4562.png index 1165444cc50..b08f724ab8b 100644 Binary files a/public/images/pokemon/4562.png and b/public/images/pokemon/4562.png differ diff --git a/public/images/pokemon/457.png b/public/images/pokemon/457.png index 6ee49243598..07425b2a147 100644 Binary files a/public/images/pokemon/457.png and b/public/images/pokemon/457.png differ diff --git a/public/images/pokemon/467.png b/public/images/pokemon/467.png index a22d045f925..ec7039932d1 100644 Binary files a/public/images/pokemon/467.png and b/public/images/pokemon/467.png differ diff --git a/public/images/pokemon/531-mega.png b/public/images/pokemon/531-mega.png index 4e692979402..f08cc04b51c 100644 Binary files a/public/images/pokemon/531-mega.png and b/public/images/pokemon/531-mega.png differ diff --git a/public/images/pokemon/669-blue.png b/public/images/pokemon/669-blue.png index 5cdefbbae6b..85426c58d51 100644 Binary files a/public/images/pokemon/669-blue.png and b/public/images/pokemon/669-blue.png differ diff --git a/public/images/pokemon/669-orange.png b/public/images/pokemon/669-orange.png index 6d93c5b13b8..565301b795b 100644 Binary files a/public/images/pokemon/669-orange.png and b/public/images/pokemon/669-orange.png differ diff --git a/public/images/pokemon/669-red.png b/public/images/pokemon/669-red.png index 02d89f59c31..b6219100729 100644 Binary files a/public/images/pokemon/669-red.png and b/public/images/pokemon/669-red.png differ diff --git a/public/images/pokemon/669-white.png b/public/images/pokemon/669-white.png index b815b86c5f5..a2809abf193 100644 Binary files a/public/images/pokemon/669-white.png and b/public/images/pokemon/669-white.png differ diff --git a/public/images/pokemon/669-yellow.png b/public/images/pokemon/669-yellow.png index 517406798e7..c3ad0eff812 100644 Binary files a/public/images/pokemon/669-yellow.png and b/public/images/pokemon/669-yellow.png differ diff --git a/public/images/pokemon/670-blue.png b/public/images/pokemon/670-blue.png index b70ec5532f9..4359006fe78 100644 Binary files a/public/images/pokemon/670-blue.png and b/public/images/pokemon/670-blue.png differ diff --git a/public/images/pokemon/670-orange.png b/public/images/pokemon/670-orange.png index 9beb7d884d5..d5c10c4c40b 100644 Binary files a/public/images/pokemon/670-orange.png and b/public/images/pokemon/670-orange.png differ diff --git a/public/images/pokemon/670-red.png b/public/images/pokemon/670-red.png index 9452ba90968..0ac18083828 100644 Binary files a/public/images/pokemon/670-red.png and b/public/images/pokemon/670-red.png differ diff --git a/public/images/pokemon/670-white.png b/public/images/pokemon/670-white.png index dba946ff47a..e8894d4f668 100644 Binary files a/public/images/pokemon/670-white.png and b/public/images/pokemon/670-white.png differ diff --git a/public/images/pokemon/670-yellow.png b/public/images/pokemon/670-yellow.png index 2d028fe5b1a..4803acafcb5 100644 Binary files a/public/images/pokemon/670-yellow.png and b/public/images/pokemon/670-yellow.png differ diff --git a/public/images/pokemon/671-blue.png b/public/images/pokemon/671-blue.png index ccbd88bb0b8..b384058bee9 100644 Binary files a/public/images/pokemon/671-blue.png and b/public/images/pokemon/671-blue.png differ diff --git a/public/images/pokemon/671-orange.png b/public/images/pokemon/671-orange.png index a99b8302e76..ac60adbcf10 100644 Binary files a/public/images/pokemon/671-orange.png and b/public/images/pokemon/671-orange.png differ diff --git a/public/images/pokemon/671-red.png b/public/images/pokemon/671-red.png index 460dafd4cc1..1b83ecf38ca 100644 Binary files a/public/images/pokemon/671-red.png and b/public/images/pokemon/671-red.png differ diff --git a/public/images/pokemon/671-white.png b/public/images/pokemon/671-white.png index 3d6f0d841b8..393970614d6 100644 Binary files a/public/images/pokemon/671-white.png and b/public/images/pokemon/671-white.png differ diff --git a/public/images/pokemon/671-yellow.png b/public/images/pokemon/671-yellow.png index 650e8db7a35..2af1b4aa543 100644 Binary files a/public/images/pokemon/671-yellow.png and b/public/images/pokemon/671-yellow.png differ diff --git a/public/images/pokemon/677.png b/public/images/pokemon/677.png index d0ebc245b32..3a5d6833ced 100644 Binary files a/public/images/pokemon/677.png and b/public/images/pokemon/677.png differ diff --git a/public/images/pokemon/678-female.png b/public/images/pokemon/678-female.png index 73abb68900a..087c5301dd0 100644 Binary files a/public/images/pokemon/678-female.png and b/public/images/pokemon/678-female.png differ diff --git a/public/images/pokemon/678.png b/public/images/pokemon/678.png index 7846bebd294..e4a1f8854fb 100644 Binary files a/public/images/pokemon/678.png and b/public/images/pokemon/678.png differ diff --git a/public/images/pokemon/698.png b/public/images/pokemon/698.png index 81c7b03e375..2e00f5693a6 100644 Binary files a/public/images/pokemon/698.png and b/public/images/pokemon/698.png differ diff --git a/public/images/pokemon/699.png b/public/images/pokemon/699.png index c8b7dda83ba..2d5320b71a2 100644 Binary files a/public/images/pokemon/699.png and b/public/images/pokemon/699.png differ diff --git a/public/images/pokemon/702.png b/public/images/pokemon/702.png index 0e3daf90889..4e0eccee204 100644 Binary files a/public/images/pokemon/702.png and b/public/images/pokemon/702.png differ diff --git a/public/images/pokemon/715.png b/public/images/pokemon/715.png index a13b8f435e4..e173bfe25ff 100644 Binary files a/public/images/pokemon/715.png and b/public/images/pokemon/715.png differ diff --git a/public/images/pokemon/716-active.png b/public/images/pokemon/716-active.png index 50b69e5ba7d..55ad63f4d3d 100644 Binary files a/public/images/pokemon/716-active.png and b/public/images/pokemon/716-active.png differ diff --git a/public/images/pokemon/716-neutral.png b/public/images/pokemon/716-neutral.png index 62a90a55dd1..8390dddffdc 100644 Binary files a/public/images/pokemon/716-neutral.png and b/public/images/pokemon/716-neutral.png differ diff --git a/public/images/pokemon/772.png b/public/images/pokemon/772.png index a32fd5c1b72..129e12d1e4c 100644 Binary files a/public/images/pokemon/772.png and b/public/images/pokemon/772.png differ diff --git a/public/images/pokemon/777.png b/public/images/pokemon/777.png index 074df4db673..bf1779d0f10 100644 Binary files a/public/images/pokemon/777.png and b/public/images/pokemon/777.png differ diff --git a/public/images/pokemon/778-disguised.png b/public/images/pokemon/778-disguised.png index 97397e9414c..b048cf02233 100644 Binary files a/public/images/pokemon/778-disguised.png and b/public/images/pokemon/778-disguised.png differ diff --git a/public/images/pokemon/80-mega.png b/public/images/pokemon/80-mega.png index 42aed7b3c66..6f7e9f0d962 100644 Binary files a/public/images/pokemon/80-mega.png and b/public/images/pokemon/80-mega.png differ diff --git a/public/images/pokemon/80.png b/public/images/pokemon/80.png index c6120f8b0b1..bcea1acb9b7 100644 Binary files a/public/images/pokemon/80.png and b/public/images/pokemon/80.png differ diff --git a/public/images/pokemon/818-gigantamax.png b/public/images/pokemon/818-gigantamax.png index c103073e4cf..c19add87a4f 100644 Binary files a/public/images/pokemon/818-gigantamax.png and b/public/images/pokemon/818-gigantamax.png differ diff --git a/public/images/pokemon/862.png b/public/images/pokemon/862.png index 4d6daf0a7da..3d82d7ef07a 100644 Binary files a/public/images/pokemon/862.png and b/public/images/pokemon/862.png differ diff --git a/public/images/pokemon/876-female.png b/public/images/pokemon/876-female.png index db4d869c148..3294cfc5b21 100644 Binary files a/public/images/pokemon/876-female.png and b/public/images/pokemon/876-female.png differ diff --git a/public/images/pokemon/876.png b/public/images/pokemon/876.png index a204d67325b..ae5a23d3d94 100644 Binary files a/public/images/pokemon/876.png and b/public/images/pokemon/876.png differ diff --git a/public/images/pokemon/881.png b/public/images/pokemon/881.png index 01cc12c00dd..321e2962b8b 100644 Binary files a/public/images/pokemon/881.png and b/public/images/pokemon/881.png differ diff --git a/public/images/pokemon/896.png b/public/images/pokemon/896.png index 1b64f2641a3..8157c737363 100644 Binary files a/public/images/pokemon/896.png and b/public/images/pokemon/896.png differ diff --git a/public/images/pokemon/898-ice.png b/public/images/pokemon/898-ice.png index 3723a78f33a..ebbe798f696 100644 Binary files a/public/images/pokemon/898-ice.png and b/public/images/pokemon/898-ice.png differ diff --git a/public/images/pokemon/898-shadow.png b/public/images/pokemon/898-shadow.png index 30bdbe224ec..cf6e79c1794 100644 Binary files a/public/images/pokemon/898-shadow.png and b/public/images/pokemon/898-shadow.png differ diff --git a/public/images/pokemon/898.png b/public/images/pokemon/898.png index d20e1f937e1..6966777e821 100644 Binary files a/public/images/pokemon/898.png and b/public/images/pokemon/898.png differ diff --git a/public/images/pokemon/912.png b/public/images/pokemon/912.png index 60b288d350e..022a653212c 100644 Binary files a/public/images/pokemon/912.png and b/public/images/pokemon/912.png differ diff --git a/public/images/pokemon/913.png b/public/images/pokemon/913.png index 7baef852807..328b48ff47b 100644 Binary files a/public/images/pokemon/913.png and b/public/images/pokemon/913.png differ diff --git a/public/images/pokemon/914.png b/public/images/pokemon/914.png index a2a89748c90..4e044dfae23 100644 Binary files a/public/images/pokemon/914.png and b/public/images/pokemon/914.png differ diff --git a/public/images/pokemon/940.png b/public/images/pokemon/940.png index f35482bb36a..434afc4a180 100644 Binary files a/public/images/pokemon/940.png and b/public/images/pokemon/940.png differ diff --git a/public/images/pokemon/941.png b/public/images/pokemon/941.png index 417d7923296..bbe885fd7b1 100644 Binary files a/public/images/pokemon/941.png and b/public/images/pokemon/941.png differ diff --git a/public/images/pokemon/981.png b/public/images/pokemon/981.png index ff66259c58d..b0f4a16498e 100644 Binary files a/public/images/pokemon/981.png and b/public/images/pokemon/981.png differ diff --git a/public/images/pokemon/997.png b/public/images/pokemon/997.png index 6b9248d85a3..5fee59edad6 100644 Binary files a/public/images/pokemon/997.png and b/public/images/pokemon/997.png differ diff --git a/public/images/pokemon/back/1003.png b/public/images/pokemon/back/1003.png index 77ece80dcc9..36ee14788b3 100644 Binary files a/public/images/pokemon/back/1003.png and b/public/images/pokemon/back/1003.png differ diff --git a/public/images/pokemon/back/126.png b/public/images/pokemon/back/126.png index 4b65d1323c8..193c38f7e2c 100644 Binary files a/public/images/pokemon/back/126.png and b/public/images/pokemon/back/126.png differ diff --git a/public/images/pokemon/back/159.png b/public/images/pokemon/back/159.png index 710014bf180..699661bb510 100644 Binary files a/public/images/pokemon/back/159.png and b/public/images/pokemon/back/159.png differ diff --git a/public/images/pokemon/back/190.png b/public/images/pokemon/back/190.png index bc4a5eee405..687eb29a67f 100644 Binary files a/public/images/pokemon/back/190.png and b/public/images/pokemon/back/190.png differ diff --git a/public/images/pokemon/back/199.png b/public/images/pokemon/back/199.png index 099dffb2a61..a7cffbc7820 100644 Binary files a/public/images/pokemon/back/199.png and b/public/images/pokemon/back/199.png differ diff --git a/public/images/pokemon/back/228.png b/public/images/pokemon/back/228.png index e723a44c31e..3a1952f81e7 100644 Binary files a/public/images/pokemon/back/228.png and b/public/images/pokemon/back/228.png differ diff --git a/public/images/pokemon/back/229-mega.png b/public/images/pokemon/back/229-mega.png index 6e09a3ae218..2c13a17ccc1 100644 Binary files a/public/images/pokemon/back/229-mega.png and b/public/images/pokemon/back/229-mega.png differ diff --git a/public/images/pokemon/back/229.png b/public/images/pokemon/back/229.png index 6cdef1e4d79..08692a9babe 100644 Binary files a/public/images/pokemon/back/229.png and b/public/images/pokemon/back/229.png differ diff --git a/public/images/pokemon/back/25-gigantamax.png b/public/images/pokemon/back/25-gigantamax.png index c80b3d5d486..1bed545d749 100644 Binary files a/public/images/pokemon/back/25-gigantamax.png and b/public/images/pokemon/back/25-gigantamax.png differ diff --git a/public/images/pokemon/back/256.png b/public/images/pokemon/back/256.png index 86f771dee3f..9e58466f2ba 100644 Binary files a/public/images/pokemon/back/256.png and b/public/images/pokemon/back/256.png differ diff --git a/public/images/pokemon/back/257-mega.png b/public/images/pokemon/back/257-mega.png index 1222c1cf8e2..df1f65d5811 100644 Binary files a/public/images/pokemon/back/257-mega.png and b/public/images/pokemon/back/257-mega.png differ diff --git a/public/images/pokemon/back/257.png b/public/images/pokemon/back/257.png index cc319ea4841..0104c4799da 100644 Binary files a/public/images/pokemon/back/257.png and b/public/images/pokemon/back/257.png differ diff --git a/public/images/pokemon/back/261.png b/public/images/pokemon/back/261.png index ce8d9579465..b44a6dc019e 100644 Binary files a/public/images/pokemon/back/261.png and b/public/images/pokemon/back/261.png differ diff --git a/public/images/pokemon/back/262.png b/public/images/pokemon/back/262.png index e1c7a26e2e8..2bc9bf59816 100644 Binary files a/public/images/pokemon/back/262.png and b/public/images/pokemon/back/262.png differ diff --git a/public/images/pokemon/back/303-mega.png b/public/images/pokemon/back/303-mega.png index c1fe85b22ff..94960dc84b1 100644 Binary files a/public/images/pokemon/back/303-mega.png and b/public/images/pokemon/back/303-mega.png differ diff --git a/public/images/pokemon/back/357.png b/public/images/pokemon/back/357.png index 4c832d552a9..7a7e551c4a2 100644 Binary files a/public/images/pokemon/back/357.png and b/public/images/pokemon/back/357.png differ diff --git a/public/images/pokemon/back/401.png b/public/images/pokemon/back/401.png index 61baacef0b6..1227e0533e3 100644 Binary files a/public/images/pokemon/back/401.png and b/public/images/pokemon/back/401.png differ diff --git a/public/images/pokemon/back/402.png b/public/images/pokemon/back/402.png index 68d74ba524d..f74de4e8dc2 100644 Binary files a/public/images/pokemon/back/402.png and b/public/images/pokemon/back/402.png differ diff --git a/public/images/pokemon/back/4080.png b/public/images/pokemon/back/4080.png index ce3c9cbd3f5..182424bd1e0 100644 Binary files a/public/images/pokemon/back/4080.png and b/public/images/pokemon/back/4080.png differ diff --git a/public/images/pokemon/back/412-sandy.png b/public/images/pokemon/back/412-sandy.png index c76152b11bc..61219669129 100644 Binary files a/public/images/pokemon/back/412-sandy.png and b/public/images/pokemon/back/412-sandy.png differ diff --git a/public/images/pokemon/back/418.png b/public/images/pokemon/back/418.png index 5d2cf6c1368..724948d9809 100644 Binary files a/public/images/pokemon/back/418.png and b/public/images/pokemon/back/418.png differ diff --git a/public/images/pokemon/back/419.png b/public/images/pokemon/back/419.png index 6ece4983987..7a389c2cbe3 100644 Binary files a/public/images/pokemon/back/419.png and b/public/images/pokemon/back/419.png differ diff --git a/public/images/pokemon/back/4199.png b/public/images/pokemon/back/4199.png index 1b45a0c2016..eb02986212f 100644 Binary files a/public/images/pokemon/back/4199.png and b/public/images/pokemon/back/4199.png differ diff --git a/public/images/pokemon/back/424.png b/public/images/pokemon/back/424.png index 76bc69d20e8..c953801431e 100644 Binary files a/public/images/pokemon/back/424.png and b/public/images/pokemon/back/424.png differ diff --git a/public/images/pokemon/back/456.png b/public/images/pokemon/back/456.png index 74d21eee031..216cca54757 100644 Binary files a/public/images/pokemon/back/456.png and b/public/images/pokemon/back/456.png differ diff --git a/public/images/pokemon/back/4562.png b/public/images/pokemon/back/4562.png index 6bbbf07ebdc..1e23be42716 100644 Binary files a/public/images/pokemon/back/4562.png and b/public/images/pokemon/back/4562.png differ diff --git a/public/images/pokemon/back/457.png b/public/images/pokemon/back/457.png index 239b235e7bd..806cacfaed2 100644 Binary files a/public/images/pokemon/back/457.png and b/public/images/pokemon/back/457.png differ diff --git a/public/images/pokemon/back/467.png b/public/images/pokemon/back/467.png index 0073f964ade..5edba20e48e 100644 Binary files a/public/images/pokemon/back/467.png and b/public/images/pokemon/back/467.png differ diff --git a/public/images/pokemon/back/556.png b/public/images/pokemon/back/556.png index aeab696307a..43652a17d06 100644 Binary files a/public/images/pokemon/back/556.png and b/public/images/pokemon/back/556.png differ diff --git a/public/images/pokemon/back/569-gigantamax.png b/public/images/pokemon/back/569-gigantamax.png index ca4e897ecc2..334c513dd73 100644 Binary files a/public/images/pokemon/back/569-gigantamax.png and b/public/images/pokemon/back/569-gigantamax.png differ diff --git a/public/images/pokemon/back/699.png b/public/images/pokemon/back/699.png index d24d2ad0a73..25693e4a3f9 100644 Binary files a/public/images/pokemon/back/699.png and b/public/images/pokemon/back/699.png differ diff --git a/public/images/pokemon/back/702.png b/public/images/pokemon/back/702.png index 9b375837be3..2b1d490b71a 100644 Binary files a/public/images/pokemon/back/702.png and b/public/images/pokemon/back/702.png differ diff --git a/public/images/pokemon/back/716-active.png b/public/images/pokemon/back/716-active.png index 0b5d2ec3c66..c3276ec81b6 100644 Binary files a/public/images/pokemon/back/716-active.png and b/public/images/pokemon/back/716-active.png differ diff --git a/public/images/pokemon/back/716-neutral.png b/public/images/pokemon/back/716-neutral.png index 291fb1600dd..73ebb3231cc 100644 Binary files a/public/images/pokemon/back/716-neutral.png and b/public/images/pokemon/back/716-neutral.png differ diff --git a/public/images/pokemon/back/772.png b/public/images/pokemon/back/772.png index eb4e5e9b8b1..059671261d7 100644 Binary files a/public/images/pokemon/back/772.png and b/public/images/pokemon/back/772.png differ diff --git a/public/images/pokemon/back/798.png b/public/images/pokemon/back/798.png index 085db6e0876..262f0b4fd79 100644 Binary files a/public/images/pokemon/back/798.png and b/public/images/pokemon/back/798.png differ diff --git a/public/images/pokemon/back/80-mega.png b/public/images/pokemon/back/80-mega.png index 5bc773e3475..005e2a813f3 100644 Binary files a/public/images/pokemon/back/80-mega.png and b/public/images/pokemon/back/80-mega.png differ diff --git a/public/images/pokemon/back/80.png b/public/images/pokemon/back/80.png index 25b7f5fff9c..f993d4b695b 100644 Binary files a/public/images/pokemon/back/80.png and b/public/images/pokemon/back/80.png differ diff --git a/public/images/pokemon/back/818-gigantamax.png b/public/images/pokemon/back/818-gigantamax.png index 93dc06b038c..22b6e71281a 100644 Binary files a/public/images/pokemon/back/818-gigantamax.png and b/public/images/pokemon/back/818-gigantamax.png differ diff --git a/public/images/pokemon/back/876-female.png b/public/images/pokemon/back/876-female.png index 29e7d4a2afd..5c25cc2f977 100644 Binary files a/public/images/pokemon/back/876-female.png and b/public/images/pokemon/back/876-female.png differ diff --git a/public/images/pokemon/back/876.png b/public/images/pokemon/back/876.png index 1ba33ec5516..1fc71387c62 100644 Binary files a/public/images/pokemon/back/876.png and b/public/images/pokemon/back/876.png differ diff --git a/public/images/pokemon/back/880.png b/public/images/pokemon/back/880.png index a82239996bc..d175b340bb8 100644 Binary files a/public/images/pokemon/back/880.png and b/public/images/pokemon/back/880.png differ diff --git a/public/images/pokemon/back/881.png b/public/images/pokemon/back/881.png index 852453aaaa0..2f77327cfd0 100644 Binary files a/public/images/pokemon/back/881.png and b/public/images/pokemon/back/881.png differ diff --git a/public/images/pokemon/back/882.png b/public/images/pokemon/back/882.png index cb05d6c5a91..0675270f6e9 100644 Binary files a/public/images/pokemon/back/882.png and b/public/images/pokemon/back/882.png differ diff --git a/public/images/pokemon/back/896.png b/public/images/pokemon/back/896.png index 243e9a4cfde..f989d532c8b 100644 Binary files a/public/images/pokemon/back/896.png and b/public/images/pokemon/back/896.png differ diff --git a/public/images/pokemon/back/898-ice.png b/public/images/pokemon/back/898-ice.png index ca5b032669e..b279a7416ed 100644 Binary files a/public/images/pokemon/back/898-ice.png and b/public/images/pokemon/back/898-ice.png differ diff --git a/public/images/pokemon/back/898-shadow.png b/public/images/pokemon/back/898-shadow.png index 0bbf0d2083c..0491ba74c86 100644 Binary files a/public/images/pokemon/back/898-shadow.png and b/public/images/pokemon/back/898-shadow.png differ diff --git a/public/images/pokemon/back/898.png b/public/images/pokemon/back/898.png index f99aa938ea2..fafc2947908 100644 Binary files a/public/images/pokemon/back/898.png and b/public/images/pokemon/back/898.png differ diff --git a/public/images/pokemon/back/913.png b/public/images/pokemon/back/913.png index 0935def3821..4a08acae4ea 100644 Binary files a/public/images/pokemon/back/913.png and b/public/images/pokemon/back/913.png differ diff --git a/public/images/pokemon/back/914.png b/public/images/pokemon/back/914.png index 7e87e0cc60e..221a91d018a 100644 Binary files a/public/images/pokemon/back/914.png and b/public/images/pokemon/back/914.png differ diff --git a/public/images/pokemon/back/981.png b/public/images/pokemon/back/981.png index 38b1a715f69..6744ddcf6b9 100644 Binary files a/public/images/pokemon/back/981.png and b/public/images/pokemon/back/981.png differ diff --git a/public/images/pokemon/back/female/190.png b/public/images/pokemon/back/female/190.png index 68b0624d213..1028c6410a6 100644 Binary files a/public/images/pokemon/back/female/190.png and b/public/images/pokemon/back/female/190.png differ diff --git a/public/images/pokemon/back/female/229.png b/public/images/pokemon/back/female/229.png index 76be7104638..f3bb6b6f2f6 100644 Binary files a/public/images/pokemon/back/female/229.png and b/public/images/pokemon/back/female/229.png differ diff --git a/public/images/pokemon/back/female/256.png b/public/images/pokemon/back/female/256.png index 6b6f7b97b7c..92612d4ccdc 100644 Binary files a/public/images/pokemon/back/female/256.png and b/public/images/pokemon/back/female/256.png differ diff --git a/public/images/pokemon/back/female/257.png b/public/images/pokemon/back/female/257.png index 0b93d07d99e..7b8171f39c0 100644 Binary files a/public/images/pokemon/back/female/257.png and b/public/images/pokemon/back/female/257.png differ diff --git a/public/images/pokemon/back/female/401.png b/public/images/pokemon/back/female/401.png index 2b0206a6707..8ebce5ff353 100644 Binary files a/public/images/pokemon/back/female/401.png and b/public/images/pokemon/back/female/401.png differ diff --git a/public/images/pokemon/back/female/402.png b/public/images/pokemon/back/female/402.png index bc8ca92ea94..6e88b492759 100644 Binary files a/public/images/pokemon/back/female/402.png and b/public/images/pokemon/back/female/402.png differ diff --git a/public/images/pokemon/back/female/418.png b/public/images/pokemon/back/female/418.png index 14c1eee1a63..1fc721cd534 100644 Binary files a/public/images/pokemon/back/female/418.png and b/public/images/pokemon/back/female/418.png differ diff --git a/public/images/pokemon/back/female/419.png b/public/images/pokemon/back/female/419.png index 9c757d2faba..22ac91c7208 100644 Binary files a/public/images/pokemon/back/female/419.png and b/public/images/pokemon/back/female/419.png differ diff --git a/public/images/pokemon/back/female/424.png b/public/images/pokemon/back/female/424.png index b05fbcf8a19..b8128ba481b 100644 Binary files a/public/images/pokemon/back/female/424.png and b/public/images/pokemon/back/female/424.png differ diff --git a/public/images/pokemon/back/female/456.png b/public/images/pokemon/back/female/456.png index dd326cb32f1..4c666b8cc19 100644 Binary files a/public/images/pokemon/back/female/456.png and b/public/images/pokemon/back/female/456.png differ diff --git a/public/images/pokemon/back/female/457.png b/public/images/pokemon/back/female/457.png index 04e1ae12ff4..9f243381edc 100644 Binary files a/public/images/pokemon/back/female/457.png and b/public/images/pokemon/back/female/457.png differ diff --git a/public/images/pokemon/back/shiny/1003.png b/public/images/pokemon/back/shiny/1003.png index 6ebce339091..fa50a1c8ffe 100644 Binary files a/public/images/pokemon/back/shiny/1003.png and b/public/images/pokemon/back/shiny/1003.png differ diff --git a/public/images/pokemon/back/shiny/190.png b/public/images/pokemon/back/shiny/190.png index cdbf2611180..a0a65c18c7f 100644 Binary files a/public/images/pokemon/back/shiny/190.png and b/public/images/pokemon/back/shiny/190.png differ diff --git a/public/images/pokemon/back/shiny/257-mega.png b/public/images/pokemon/back/shiny/257-mega.png index 40eb7a61bb5..04603c4a5e0 100644 Binary files a/public/images/pokemon/back/shiny/257-mega.png and b/public/images/pokemon/back/shiny/257-mega.png differ diff --git a/public/images/pokemon/back/shiny/261.png b/public/images/pokemon/back/shiny/261.png index a43f3d73f76..3399736c315 100644 Binary files a/public/images/pokemon/back/shiny/261.png and b/public/images/pokemon/back/shiny/261.png differ diff --git a/public/images/pokemon/back/shiny/262.png b/public/images/pokemon/back/shiny/262.png index afcc2c8bfe6..9e76bfed3fc 100644 Binary files a/public/images/pokemon/back/shiny/262.png and b/public/images/pokemon/back/shiny/262.png differ diff --git a/public/images/pokemon/back/shiny/303-mega.png b/public/images/pokemon/back/shiny/303-mega.png index c7de009cf2a..7097e527ddf 100644 Binary files a/public/images/pokemon/back/shiny/303-mega.png and b/public/images/pokemon/back/shiny/303-mega.png differ diff --git a/public/images/pokemon/back/shiny/357.png b/public/images/pokemon/back/shiny/357.png index da2497041e4..783f4401b2d 100644 Binary files a/public/images/pokemon/back/shiny/357.png and b/public/images/pokemon/back/shiny/357.png differ diff --git a/public/images/pokemon/back/shiny/373-mega.png b/public/images/pokemon/back/shiny/373-mega.png index 95145fd40e3..ce2c48a77b4 100644 Binary files a/public/images/pokemon/back/shiny/373-mega.png and b/public/images/pokemon/back/shiny/373-mega.png differ diff --git a/public/images/pokemon/back/shiny/4080.png b/public/images/pokemon/back/shiny/4080.png index 2c8d85fa5d7..4f214c399b8 100644 Binary files a/public/images/pokemon/back/shiny/4080.png and b/public/images/pokemon/back/shiny/4080.png differ diff --git a/public/images/pokemon/back/shiny/424.png b/public/images/pokemon/back/shiny/424.png index 67675146686..7e27173b989 100644 Binary files a/public/images/pokemon/back/shiny/424.png and b/public/images/pokemon/back/shiny/424.png differ diff --git a/public/images/pokemon/back/shiny/433.png b/public/images/pokemon/back/shiny/433.png index a6bb0e59098..040b700225f 100644 Binary files a/public/images/pokemon/back/shiny/433.png and b/public/images/pokemon/back/shiny/433.png differ diff --git a/public/images/pokemon/back/shiny/469.png b/public/images/pokemon/back/shiny/469.png index 8ac1f32335d..bdd46a1ed16 100644 Binary files a/public/images/pokemon/back/shiny/469.png and b/public/images/pokemon/back/shiny/469.png differ diff --git a/public/images/pokemon/back/shiny/477.png b/public/images/pokemon/back/shiny/477.png index 25414ab5c18..45879a61d11 100644 Binary files a/public/images/pokemon/back/shiny/477.png and b/public/images/pokemon/back/shiny/477.png differ diff --git a/public/images/pokemon/back/shiny/556.png b/public/images/pokemon/back/shiny/556.png index 4f2e991b010..8a5a573e5d5 100644 Binary files a/public/images/pokemon/back/shiny/556.png and b/public/images/pokemon/back/shiny/556.png differ diff --git a/public/images/pokemon/back/shiny/698.png b/public/images/pokemon/back/shiny/698.png index 22f9b2b660d..3daad1fd4ab 100644 Binary files a/public/images/pokemon/back/shiny/698.png and b/public/images/pokemon/back/shiny/698.png differ diff --git a/public/images/pokemon/back/shiny/699.png b/public/images/pokemon/back/shiny/699.png index 58bd840f1e3..0eb93c80f38 100644 Binary files a/public/images/pokemon/back/shiny/699.png and b/public/images/pokemon/back/shiny/699.png differ diff --git a/public/images/pokemon/back/shiny/716-active.png b/public/images/pokemon/back/shiny/716-active.png index 7c4db546443..96c6814d109 100644 Binary files a/public/images/pokemon/back/shiny/716-active.png and b/public/images/pokemon/back/shiny/716-active.png differ diff --git a/public/images/pokemon/back/shiny/716-neutral.png b/public/images/pokemon/back/shiny/716-neutral.png index fe52ce43e0c..9c80656e93c 100644 Binary files a/public/images/pokemon/back/shiny/716-neutral.png and b/public/images/pokemon/back/shiny/716-neutral.png differ diff --git a/public/images/pokemon/back/shiny/772.png b/public/images/pokemon/back/shiny/772.png index f999ba8ec01..e275c06ee41 100644 Binary files a/public/images/pokemon/back/shiny/772.png and b/public/images/pokemon/back/shiny/772.png differ diff --git a/public/images/pokemon/back/shiny/773.png b/public/images/pokemon/back/shiny/773.png index 6dba183d9d2..26aafa2d2ea 100644 Binary files a/public/images/pokemon/back/shiny/773.png and b/public/images/pokemon/back/shiny/773.png differ diff --git a/public/images/pokemon/back/shiny/798.png b/public/images/pokemon/back/shiny/798.png index b1948a6a3cd..56a45c895a0 100644 Binary files a/public/images/pokemon/back/shiny/798.png and b/public/images/pokemon/back/shiny/798.png differ diff --git a/public/images/pokemon/back/shiny/80-mega.png b/public/images/pokemon/back/shiny/80-mega.png index 6c508034c3e..5baf6ccb873 100644 Binary files a/public/images/pokemon/back/shiny/80-mega.png and b/public/images/pokemon/back/shiny/80-mega.png differ diff --git a/public/images/pokemon/back/shiny/80.png b/public/images/pokemon/back/shiny/80.png index 68e3d526965..c6c3b23f364 100644 Binary files a/public/images/pokemon/back/shiny/80.png and b/public/images/pokemon/back/shiny/80.png differ diff --git a/public/images/pokemon/back/shiny/818-gigantamax.png b/public/images/pokemon/back/shiny/818-gigantamax.png index 224858fc0be..ca58c4eb34c 100644 Binary files a/public/images/pokemon/back/shiny/818-gigantamax.png and b/public/images/pokemon/back/shiny/818-gigantamax.png differ diff --git a/public/images/pokemon/back/shiny/898-ice.png b/public/images/pokemon/back/shiny/898-ice.png index 3bf247280b9..0e96f7ca9d3 100644 Binary files a/public/images/pokemon/back/shiny/898-ice.png and b/public/images/pokemon/back/shiny/898-ice.png differ diff --git a/public/images/pokemon/back/shiny/898-shadow.png b/public/images/pokemon/back/shiny/898-shadow.png index a1ea98d1f3f..6319b0c56d1 100644 Binary files a/public/images/pokemon/back/shiny/898-shadow.png and b/public/images/pokemon/back/shiny/898-shadow.png differ diff --git a/public/images/pokemon/back/shiny/913.png b/public/images/pokemon/back/shiny/913.png index d57246f3565..e3a4405fd1e 100644 Binary files a/public/images/pokemon/back/shiny/913.png and b/public/images/pokemon/back/shiny/913.png differ diff --git a/public/images/pokemon/back/shiny/914.png b/public/images/pokemon/back/shiny/914.png index f22947be030..5e88e004266 100644 Binary files a/public/images/pokemon/back/shiny/914.png and b/public/images/pokemon/back/shiny/914.png differ diff --git a/public/images/pokemon/back/shiny/981.png b/public/images/pokemon/back/shiny/981.png index b89fa6b1629..0a5d6e5fb90 100644 Binary files a/public/images/pokemon/back/shiny/981.png and b/public/images/pokemon/back/shiny/981.png differ diff --git a/public/images/pokemon/back/shiny/983.png b/public/images/pokemon/back/shiny/983.png index 4b69919c297..5cdf12cc859 100644 Binary files a/public/images/pokemon/back/shiny/983.png and b/public/images/pokemon/back/shiny/983.png differ diff --git a/public/images/pokemon/back/shiny/female/190.png b/public/images/pokemon/back/shiny/female/190.png index 11c7f6a84e5..cb2352cfb4d 100644 Binary files a/public/images/pokemon/back/shiny/female/190.png and b/public/images/pokemon/back/shiny/female/190.png differ diff --git a/public/images/pokemon/back/shiny/female/424.png b/public/images/pokemon/back/shiny/female/424.png index dd620a0cfa9..a00c99e375e 100644 Binary files a/public/images/pokemon/back/shiny/female/424.png and b/public/images/pokemon/back/shiny/female/424.png differ diff --git a/public/images/pokemon/exp/1003.png b/public/images/pokemon/exp/1003.png index e6c8cbc2b67..2d02c4050e9 100644 Binary files a/public/images/pokemon/exp/1003.png and b/public/images/pokemon/exp/1003.png differ diff --git a/public/images/pokemon/exp/229-mega.png b/public/images/pokemon/exp/229-mega.png index bc7656d9f1c..babc5310bb4 100644 Binary files a/public/images/pokemon/exp/229-mega.png and b/public/images/pokemon/exp/229-mega.png differ diff --git a/public/images/pokemon/exp/373-mega.png b/public/images/pokemon/exp/373-mega.png index 93c27d88db6..0b93c472c76 100644 Binary files a/public/images/pokemon/exp/373-mega.png and b/public/images/pokemon/exp/373-mega.png differ diff --git a/public/images/pokemon/exp/4080.png b/public/images/pokemon/exp/4080.png index 81890a8b9e5..77e47856b0a 100644 Binary files a/public/images/pokemon/exp/4080.png and b/public/images/pokemon/exp/4080.png differ diff --git a/public/images/pokemon/exp/4199.png b/public/images/pokemon/exp/4199.png index b1858760c0c..b7a7dd9bfbb 100644 Binary files a/public/images/pokemon/exp/4199.png and b/public/images/pokemon/exp/4199.png differ diff --git a/public/images/pokemon/exp/4222.png b/public/images/pokemon/exp/4222.png index b78d04c371c..5e04aafdc22 100644 Binary files a/public/images/pokemon/exp/4222.png and b/public/images/pokemon/exp/4222.png differ diff --git a/public/images/pokemon/exp/4264.png b/public/images/pokemon/exp/4264.png index 3436fe2fe13..4bc70f2fdce 100644 Binary files a/public/images/pokemon/exp/4264.png and b/public/images/pokemon/exp/4264.png differ diff --git a/public/images/pokemon/exp/4562.png b/public/images/pokemon/exp/4562.png index 69b90f182ca..307390e8e2c 100644 Binary files a/public/images/pokemon/exp/4562.png and b/public/images/pokemon/exp/4562.png differ diff --git a/public/images/pokemon/exp/531-mega.png b/public/images/pokemon/exp/531-mega.png index d9b93c2ecca..391cc22b6db 100644 Binary files a/public/images/pokemon/exp/531-mega.png and b/public/images/pokemon/exp/531-mega.png differ diff --git a/public/images/pokemon/exp/677.png b/public/images/pokemon/exp/677.png index 70d8a0f185d..d25f1675102 100644 Binary files a/public/images/pokemon/exp/677.png and b/public/images/pokemon/exp/677.png differ diff --git a/public/images/pokemon/exp/678-female.png b/public/images/pokemon/exp/678-female.png index 3af30f5d2a7..b2021bd5923 100644 Binary files a/public/images/pokemon/exp/678-female.png and b/public/images/pokemon/exp/678-female.png differ diff --git a/public/images/pokemon/exp/698.png b/public/images/pokemon/exp/698.png index 3fba3dad32a..6d8ca555881 100644 Binary files a/public/images/pokemon/exp/698.png and b/public/images/pokemon/exp/698.png differ diff --git a/public/images/pokemon/exp/699.png b/public/images/pokemon/exp/699.png index d2108e813aa..1b7a4f402e3 100644 Binary files a/public/images/pokemon/exp/699.png and b/public/images/pokemon/exp/699.png differ diff --git a/public/images/pokemon/exp/702.png b/public/images/pokemon/exp/702.png index a5d375e779a..9d042fd8293 100644 Binary files a/public/images/pokemon/exp/702.png and b/public/images/pokemon/exp/702.png differ diff --git a/public/images/pokemon/exp/716-active.png b/public/images/pokemon/exp/716-active.png index 2f6ec8f76da..223a73d9cb7 100644 Binary files a/public/images/pokemon/exp/716-active.png and b/public/images/pokemon/exp/716-active.png differ diff --git a/public/images/pokemon/exp/716-neutral.png b/public/images/pokemon/exp/716-neutral.png index dd2d1821986..91fefde1eb7 100644 Binary files a/public/images/pokemon/exp/716-neutral.png and b/public/images/pokemon/exp/716-neutral.png differ diff --git a/public/images/pokemon/exp/752.png b/public/images/pokemon/exp/752.png index 88bbba63252..e78e9803919 100644 Binary files a/public/images/pokemon/exp/752.png and b/public/images/pokemon/exp/752.png differ diff --git a/public/images/pokemon/exp/770.png b/public/images/pokemon/exp/770.png index 7cfd1179298..30f9073a58f 100644 Binary files a/public/images/pokemon/exp/770.png and b/public/images/pokemon/exp/770.png differ diff --git a/public/images/pokemon/exp/771.png b/public/images/pokemon/exp/771.png index d53f1e52286..3a2ef676382 100644 Binary files a/public/images/pokemon/exp/771.png and b/public/images/pokemon/exp/771.png differ diff --git a/public/images/pokemon/exp/772.png b/public/images/pokemon/exp/772.png index c3a986ff15e..0a28235f416 100644 Binary files a/public/images/pokemon/exp/772.png and b/public/images/pokemon/exp/772.png differ diff --git a/public/images/pokemon/exp/773_Test.png b/public/images/pokemon/exp/773_Test.png index a77cdf691e2..ab932e78c1a 100644 Binary files a/public/images/pokemon/exp/773_Test.png and b/public/images/pokemon/exp/773_Test.png differ diff --git a/public/images/pokemon/exp/776.png b/public/images/pokemon/exp/776.png index f002de4cf6a..07550683210 100644 Binary files a/public/images/pokemon/exp/776.png and b/public/images/pokemon/exp/776.png differ diff --git a/public/images/pokemon/exp/777.png b/public/images/pokemon/exp/777.png index 0683a9e0855..f60fcc50786 100644 Binary files a/public/images/pokemon/exp/777.png and b/public/images/pokemon/exp/777.png differ diff --git a/public/images/pokemon/exp/793.png b/public/images/pokemon/exp/793.png index 683dd1153f1..fb1e37da979 100644 Binary files a/public/images/pokemon/exp/793.png and b/public/images/pokemon/exp/793.png differ diff --git a/public/images/pokemon/exp/798.png b/public/images/pokemon/exp/798.png index 6c88f1130c9..8434a1721e8 100644 Binary files a/public/images/pokemon/exp/798.png and b/public/images/pokemon/exp/798.png differ diff --git a/public/images/pokemon/exp/818.png b/public/images/pokemon/exp/818.png index ff767c962a4..b71cccf2679 100644 Binary files a/public/images/pokemon/exp/818.png and b/public/images/pokemon/exp/818.png differ diff --git a/public/images/pokemon/exp/857.png b/public/images/pokemon/exp/857.png index 0a3195e2bda..85f17ece3d8 100644 Binary files a/public/images/pokemon/exp/857.png and b/public/images/pokemon/exp/857.png differ diff --git a/public/images/pokemon/exp/876-female.png b/public/images/pokemon/exp/876-female.png index eb61b85e351..0eb5b407970 100644 Binary files a/public/images/pokemon/exp/876-female.png and b/public/images/pokemon/exp/876-female.png differ diff --git a/public/images/pokemon/exp/876.png b/public/images/pokemon/exp/876.png index e1c47e16c0c..842a98830a7 100644 Binary files a/public/images/pokemon/exp/876.png and b/public/images/pokemon/exp/876.png differ diff --git a/public/images/pokemon/exp/880.png b/public/images/pokemon/exp/880.png index 7edffc97cc7..34a898fb5ac 100644 Binary files a/public/images/pokemon/exp/880.png and b/public/images/pokemon/exp/880.png differ diff --git a/public/images/pokemon/exp/881.png b/public/images/pokemon/exp/881.png index aeaa1728f1a..291f4c261fa 100644 Binary files a/public/images/pokemon/exp/881.png and b/public/images/pokemon/exp/881.png differ diff --git a/public/images/pokemon/exp/882.png b/public/images/pokemon/exp/882.png index 15269a499ca..37c4facc672 100644 Binary files a/public/images/pokemon/exp/882.png and b/public/images/pokemon/exp/882.png differ diff --git a/public/images/pokemon/exp/896.png b/public/images/pokemon/exp/896.png index f6f646aec65..7025ae49fb8 100644 Binary files a/public/images/pokemon/exp/896.png and b/public/images/pokemon/exp/896.png differ diff --git a/public/images/pokemon/exp/898-ice.png b/public/images/pokemon/exp/898-ice.png index c7c00f5551d..3cdf6adc202 100644 Binary files a/public/images/pokemon/exp/898-ice.png and b/public/images/pokemon/exp/898-ice.png differ diff --git a/public/images/pokemon/exp/898-shadow.png b/public/images/pokemon/exp/898-shadow.png index 5a41eb6cee0..b5f18487f32 100644 Binary files a/public/images/pokemon/exp/898-shadow.png and b/public/images/pokemon/exp/898-shadow.png differ diff --git a/public/images/pokemon/exp/912.png b/public/images/pokemon/exp/912.png index 23c03342039..b8c7465768c 100644 Binary files a/public/images/pokemon/exp/912.png and b/public/images/pokemon/exp/912.png differ diff --git a/public/images/pokemon/exp/913.png b/public/images/pokemon/exp/913.png index 1bfd1c8f022..538f852208a 100644 Binary files a/public/images/pokemon/exp/913.png and b/public/images/pokemon/exp/913.png differ diff --git a/public/images/pokemon/exp/914.png b/public/images/pokemon/exp/914.png index 33ca7719da2..013934d03f5 100644 Binary files a/public/images/pokemon/exp/914.png and b/public/images/pokemon/exp/914.png differ diff --git a/public/images/pokemon/exp/940.png b/public/images/pokemon/exp/940.png index 42aed88443c..5ecc20ea5d1 100644 Binary files a/public/images/pokemon/exp/940.png and b/public/images/pokemon/exp/940.png differ diff --git a/public/images/pokemon/exp/954.png b/public/images/pokemon/exp/954.png index 6097a0f0393..85a6017c417 100644 Binary files a/public/images/pokemon/exp/954.png and b/public/images/pokemon/exp/954.png differ diff --git a/public/images/pokemon/exp/974.png b/public/images/pokemon/exp/974.png index e016f114cce..354bcbed533 100644 Binary files a/public/images/pokemon/exp/974.png and b/public/images/pokemon/exp/974.png differ diff --git a/public/images/pokemon/exp/981.png b/public/images/pokemon/exp/981.png index 5c87495f6e9..c763e8ec358 100644 Binary files a/public/images/pokemon/exp/981.png and b/public/images/pokemon/exp/981.png differ diff --git a/public/images/pokemon/exp/983.png b/public/images/pokemon/exp/983.png index 226d971ae32..2fac1759c12 100644 Binary files a/public/images/pokemon/exp/983.png and b/public/images/pokemon/exp/983.png differ diff --git a/public/images/pokemon/exp/back/1003.png b/public/images/pokemon/exp/back/1003.png index d83789d1fb8..fc368e56f81 100644 Binary files a/public/images/pokemon/exp/back/1003.png and b/public/images/pokemon/exp/back/1003.png differ diff --git a/public/images/pokemon/exp/back/229-mega.png b/public/images/pokemon/exp/back/229-mega.png index aae59a3a1d0..b538f3523dd 100644 Binary files a/public/images/pokemon/exp/back/229-mega.png and b/public/images/pokemon/exp/back/229-mega.png differ diff --git a/public/images/pokemon/exp/back/257-mega.png b/public/images/pokemon/exp/back/257-mega.png index 48bd446329f..b27b98fa153 100644 Binary files a/public/images/pokemon/exp/back/257-mega.png and b/public/images/pokemon/exp/back/257-mega.png differ diff --git a/public/images/pokemon/exp/back/4080.png b/public/images/pokemon/exp/back/4080.png index f4cfb4cd3c5..d0ffefd6503 100644 Binary files a/public/images/pokemon/exp/back/4080.png and b/public/images/pokemon/exp/back/4080.png differ diff --git a/public/images/pokemon/exp/back/4199.png b/public/images/pokemon/exp/back/4199.png index 174a325b28a..aa841a9e4d1 100644 Binary files a/public/images/pokemon/exp/back/4199.png and b/public/images/pokemon/exp/back/4199.png differ diff --git a/public/images/pokemon/exp/back/4222.png b/public/images/pokemon/exp/back/4222.png index 202817b2163..163dcb1432e 100644 Binary files a/public/images/pokemon/exp/back/4222.png and b/public/images/pokemon/exp/back/4222.png differ diff --git a/public/images/pokemon/exp/back/4562.png b/public/images/pokemon/exp/back/4562.png index 691c60c8b0a..0f8fdde8b81 100644 Binary files a/public/images/pokemon/exp/back/4562.png and b/public/images/pokemon/exp/back/4562.png differ diff --git a/public/images/pokemon/exp/back/698.png b/public/images/pokemon/exp/back/698.png index 6250dc0110f..43738b78928 100644 Binary files a/public/images/pokemon/exp/back/698.png and b/public/images/pokemon/exp/back/698.png differ diff --git a/public/images/pokemon/exp/back/699.png b/public/images/pokemon/exp/back/699.png index 7558357e206..cd1b9a82de7 100644 Binary files a/public/images/pokemon/exp/back/699.png and b/public/images/pokemon/exp/back/699.png differ diff --git a/public/images/pokemon/exp/back/702.png b/public/images/pokemon/exp/back/702.png index be5cf42476b..e90d2e5200b 100644 Binary files a/public/images/pokemon/exp/back/702.png and b/public/images/pokemon/exp/back/702.png differ diff --git a/public/images/pokemon/exp/back/716-active.png b/public/images/pokemon/exp/back/716-active.png index 5bd4fcd74c6..9d10446def7 100644 Binary files a/public/images/pokemon/exp/back/716-active.png and b/public/images/pokemon/exp/back/716-active.png differ diff --git a/public/images/pokemon/exp/back/716-neutral.png b/public/images/pokemon/exp/back/716-neutral.png index 579173b757f..871a9471357 100644 Binary files a/public/images/pokemon/exp/back/716-neutral.png and b/public/images/pokemon/exp/back/716-neutral.png differ diff --git a/public/images/pokemon/exp/back/772.png b/public/images/pokemon/exp/back/772.png index b287c20b1cb..b1ccc79fb6c 100644 Binary files a/public/images/pokemon/exp/back/772.png and b/public/images/pokemon/exp/back/772.png differ diff --git a/public/images/pokemon/exp/back/776.png b/public/images/pokemon/exp/back/776.png index 6e0c7026d56..d23a85dc55d 100644 Binary files a/public/images/pokemon/exp/back/776.png and b/public/images/pokemon/exp/back/776.png differ diff --git a/public/images/pokemon/exp/back/777.png b/public/images/pokemon/exp/back/777.png index d8f25cc7362..f4b0e23c5e2 100644 Binary files a/public/images/pokemon/exp/back/777.png and b/public/images/pokemon/exp/back/777.png differ diff --git a/public/images/pokemon/exp/back/797.png b/public/images/pokemon/exp/back/797.png index 17cae929dbc..2c3258b6858 100644 Binary files a/public/images/pokemon/exp/back/797.png and b/public/images/pokemon/exp/back/797.png differ diff --git a/public/images/pokemon/exp/back/798.png b/public/images/pokemon/exp/back/798.png index 50b663a19dd..1cc3b7c4103 100644 Binary files a/public/images/pokemon/exp/back/798.png and b/public/images/pokemon/exp/back/798.png differ diff --git a/public/images/pokemon/exp/back/80-mega.png b/public/images/pokemon/exp/back/80-mega.png index f6c67586eaa..a8bcfbcff97 100644 Binary files a/public/images/pokemon/exp/back/80-mega.png and b/public/images/pokemon/exp/back/80-mega.png differ diff --git a/public/images/pokemon/exp/back/804.png b/public/images/pokemon/exp/back/804.png index 1dbf3c502d3..5de6c92f36d 100644 Binary files a/public/images/pokemon/exp/back/804.png and b/public/images/pokemon/exp/back/804.png differ diff --git a/public/images/pokemon/exp/back/876-female.png b/public/images/pokemon/exp/back/876-female.png index 78ca08e6d09..18a4a9834a9 100644 Binary files a/public/images/pokemon/exp/back/876-female.png and b/public/images/pokemon/exp/back/876-female.png differ diff --git a/public/images/pokemon/exp/back/876.png b/public/images/pokemon/exp/back/876.png index 0073e1642af..87ed3646b3e 100644 Binary files a/public/images/pokemon/exp/back/876.png and b/public/images/pokemon/exp/back/876.png differ diff --git a/public/images/pokemon/exp/back/880.png b/public/images/pokemon/exp/back/880.png index 4ee65833e55..c2891b4165a 100644 Binary files a/public/images/pokemon/exp/back/880.png and b/public/images/pokemon/exp/back/880.png differ diff --git a/public/images/pokemon/exp/back/881.png b/public/images/pokemon/exp/back/881.png index 377347f49bc..1c0322a43fd 100644 Binary files a/public/images/pokemon/exp/back/881.png and b/public/images/pokemon/exp/back/881.png differ diff --git a/public/images/pokemon/exp/back/882.png b/public/images/pokemon/exp/back/882.png index c2c9b1b302b..d5d5ad902f5 100644 Binary files a/public/images/pokemon/exp/back/882.png and b/public/images/pokemon/exp/back/882.png differ diff --git a/public/images/pokemon/exp/back/888-crowned.png b/public/images/pokemon/exp/back/888-crowned.png index 4cc454caaa1..827678bf53d 100644 Binary files a/public/images/pokemon/exp/back/888-crowned.png and b/public/images/pokemon/exp/back/888-crowned.png differ diff --git a/public/images/pokemon/exp/back/896.png b/public/images/pokemon/exp/back/896.png index dd7a984cae7..c0c26abd888 100644 Binary files a/public/images/pokemon/exp/back/896.png and b/public/images/pokemon/exp/back/896.png differ diff --git a/public/images/pokemon/exp/back/898-ice.png b/public/images/pokemon/exp/back/898-ice.png index 899a4dd0896..bbb27761875 100644 Binary files a/public/images/pokemon/exp/back/898-ice.png and b/public/images/pokemon/exp/back/898-ice.png differ diff --git a/public/images/pokemon/exp/back/898-shadow.png b/public/images/pokemon/exp/back/898-shadow.png index 9f40e0ede70..27191a9428b 100644 Binary files a/public/images/pokemon/exp/back/898-shadow.png and b/public/images/pokemon/exp/back/898-shadow.png differ diff --git a/public/images/pokemon/exp/back/898.png b/public/images/pokemon/exp/back/898.png index eb7bc938ee3..c2154aa45e9 100644 Binary files a/public/images/pokemon/exp/back/898.png and b/public/images/pokemon/exp/back/898.png differ diff --git a/public/images/pokemon/exp/back/913.png b/public/images/pokemon/exp/back/913.png index 9a33a6de3af..cd32c18afcc 100644 Binary files a/public/images/pokemon/exp/back/913.png and b/public/images/pokemon/exp/back/913.png differ diff --git a/public/images/pokemon/exp/back/914.png b/public/images/pokemon/exp/back/914.png index abf275e24f0..e476a2e58ec 100644 Binary files a/public/images/pokemon/exp/back/914.png and b/public/images/pokemon/exp/back/914.png differ diff --git a/public/images/pokemon/exp/back/954.png b/public/images/pokemon/exp/back/954.png index be75ebbb453..64a60ce7b89 100644 Binary files a/public/images/pokemon/exp/back/954.png and b/public/images/pokemon/exp/back/954.png differ diff --git a/public/images/pokemon/exp/back/981.png b/public/images/pokemon/exp/back/981.png index 360f4267be5..523135b7f3c 100644 Binary files a/public/images/pokemon/exp/back/981.png and b/public/images/pokemon/exp/back/981.png differ diff --git a/public/images/pokemon/exp/back/shiny/1003.png b/public/images/pokemon/exp/back/shiny/1003.png index 628a1098ab6..503211f914a 100644 Binary files a/public/images/pokemon/exp/back/shiny/1003.png and b/public/images/pokemon/exp/back/shiny/1003.png differ diff --git a/public/images/pokemon/exp/back/shiny/257-mega.png b/public/images/pokemon/exp/back/shiny/257-mega.png index 47725c71073..1aaad61acbf 100644 Binary files a/public/images/pokemon/exp/back/shiny/257-mega.png and b/public/images/pokemon/exp/back/shiny/257-mega.png differ diff --git a/public/images/pokemon/exp/back/shiny/373-mega.png b/public/images/pokemon/exp/back/shiny/373-mega.png index 6c5ce34d155..558a7ef2fbc 100644 Binary files a/public/images/pokemon/exp/back/shiny/373-mega.png and b/public/images/pokemon/exp/back/shiny/373-mega.png differ diff --git a/public/images/pokemon/exp/back/shiny/4080.png b/public/images/pokemon/exp/back/shiny/4080.png index e70503a7820..1f3ec6c122a 100644 Binary files a/public/images/pokemon/exp/back/shiny/4080.png and b/public/images/pokemon/exp/back/shiny/4080.png differ diff --git a/public/images/pokemon/exp/back/shiny/4222.png b/public/images/pokemon/exp/back/shiny/4222.png index 15970729f49..e5c30260c2b 100644 Binary files a/public/images/pokemon/exp/back/shiny/4222.png and b/public/images/pokemon/exp/back/shiny/4222.png differ diff --git a/public/images/pokemon/exp/back/shiny/698.png b/public/images/pokemon/exp/back/shiny/698.png index 781f363220a..dbd5cefcbf0 100644 Binary files a/public/images/pokemon/exp/back/shiny/698.png and b/public/images/pokemon/exp/back/shiny/698.png differ diff --git a/public/images/pokemon/exp/back/shiny/699.png b/public/images/pokemon/exp/back/shiny/699.png index 0a17af2f53f..75f5c8d8b78 100644 Binary files a/public/images/pokemon/exp/back/shiny/699.png and b/public/images/pokemon/exp/back/shiny/699.png differ diff --git a/public/images/pokemon/exp/back/shiny/708.png b/public/images/pokemon/exp/back/shiny/708.png index 8673e917e75..35e2594241a 100644 Binary files a/public/images/pokemon/exp/back/shiny/708.png and b/public/images/pokemon/exp/back/shiny/708.png differ diff --git a/public/images/pokemon/exp/back/shiny/709.png b/public/images/pokemon/exp/back/shiny/709.png index 5148cd1ed08..c0d67915d17 100644 Binary files a/public/images/pokemon/exp/back/shiny/709.png and b/public/images/pokemon/exp/back/shiny/709.png differ diff --git a/public/images/pokemon/exp/back/shiny/716-active.png b/public/images/pokemon/exp/back/shiny/716-active.png index b99aabd1496..effe84542dc 100644 Binary files a/public/images/pokemon/exp/back/shiny/716-active.png and b/public/images/pokemon/exp/back/shiny/716-active.png differ diff --git a/public/images/pokemon/exp/back/shiny/716-neutral.png b/public/images/pokemon/exp/back/shiny/716-neutral.png index c8bee30f32f..26ee61454fd 100644 Binary files a/public/images/pokemon/exp/back/shiny/716-neutral.png and b/public/images/pokemon/exp/back/shiny/716-neutral.png differ diff --git a/public/images/pokemon/exp/back/shiny/772.png b/public/images/pokemon/exp/back/shiny/772.png index 407e3be6691..49124763f6c 100644 Binary files a/public/images/pokemon/exp/back/shiny/772.png and b/public/images/pokemon/exp/back/shiny/772.png differ diff --git a/public/images/pokemon/exp/back/shiny/773.png b/public/images/pokemon/exp/back/shiny/773.png index f6a98c1b43a..2c4741a6b0b 100644 Binary files a/public/images/pokemon/exp/back/shiny/773.png and b/public/images/pokemon/exp/back/shiny/773.png differ diff --git a/public/images/pokemon/exp/back/shiny/776.png b/public/images/pokemon/exp/back/shiny/776.png index d669b9f3ce6..4c4115a8132 100644 Binary files a/public/images/pokemon/exp/back/shiny/776.png and b/public/images/pokemon/exp/back/shiny/776.png differ diff --git a/public/images/pokemon/exp/back/shiny/778-disguised.png b/public/images/pokemon/exp/back/shiny/778-disguised.png index 2b1c9ecf3c9..8d3183cee0c 100644 Binary files a/public/images/pokemon/exp/back/shiny/778-disguised.png and b/public/images/pokemon/exp/back/shiny/778-disguised.png differ diff --git a/public/images/pokemon/exp/back/shiny/798.png b/public/images/pokemon/exp/back/shiny/798.png index 68fd3382ddc..322600a1fdf 100644 Binary files a/public/images/pokemon/exp/back/shiny/798.png and b/public/images/pokemon/exp/back/shiny/798.png differ diff --git a/public/images/pokemon/exp/back/shiny/80-mega.png b/public/images/pokemon/exp/back/shiny/80-mega.png index 12e88cdb937..af2277cb9da 100644 Binary files a/public/images/pokemon/exp/back/shiny/80-mega.png and b/public/images/pokemon/exp/back/shiny/80-mega.png differ diff --git a/public/images/pokemon/exp/back/shiny/888-crowned.png b/public/images/pokemon/exp/back/shiny/888-crowned.png index b3eb012e3c8..a4ed4c67ed4 100644 Binary files a/public/images/pokemon/exp/back/shiny/888-crowned.png and b/public/images/pokemon/exp/back/shiny/888-crowned.png differ diff --git a/public/images/pokemon/exp/back/shiny/898-ice.png b/public/images/pokemon/exp/back/shiny/898-ice.png index 6b3e8277180..9f1a5bd03e3 100644 Binary files a/public/images/pokemon/exp/back/shiny/898-ice.png and b/public/images/pokemon/exp/back/shiny/898-ice.png differ diff --git a/public/images/pokemon/exp/back/shiny/898-shadow.png b/public/images/pokemon/exp/back/shiny/898-shadow.png index d40bd1ab48e..2a506193e7d 100644 Binary files a/public/images/pokemon/exp/back/shiny/898-shadow.png and b/public/images/pokemon/exp/back/shiny/898-shadow.png differ diff --git a/public/images/pokemon/exp/back/shiny/913.png b/public/images/pokemon/exp/back/shiny/913.png index 07838b5d996..9d65e55e94a 100644 Binary files a/public/images/pokemon/exp/back/shiny/913.png and b/public/images/pokemon/exp/back/shiny/913.png differ diff --git a/public/images/pokemon/exp/back/shiny/914.png b/public/images/pokemon/exp/back/shiny/914.png index 2f0510312bb..17f787add8f 100644 Binary files a/public/images/pokemon/exp/back/shiny/914.png and b/public/images/pokemon/exp/back/shiny/914.png differ diff --git a/public/images/pokemon/exp/back/shiny/954.png b/public/images/pokemon/exp/back/shiny/954.png index 3d2111bd99e..e12b479d462 100644 Binary files a/public/images/pokemon/exp/back/shiny/954.png and b/public/images/pokemon/exp/back/shiny/954.png differ diff --git a/public/images/pokemon/exp/back/shiny/981.png b/public/images/pokemon/exp/back/shiny/981.png index 90a25d7eca3..153f6594be4 100644 Binary files a/public/images/pokemon/exp/back/shiny/981.png and b/public/images/pokemon/exp/back/shiny/981.png differ diff --git a/public/images/pokemon/exp/shiny/1003.png b/public/images/pokemon/exp/shiny/1003.png index 6fab9bfe143..22c1d89a879 100644 Binary files a/public/images/pokemon/exp/shiny/1003.png and b/public/images/pokemon/exp/shiny/1003.png differ diff --git a/public/images/pokemon/exp/shiny/373-mega.png b/public/images/pokemon/exp/shiny/373-mega.png index dc42bd43632..15f7a2e9017 100644 Binary files a/public/images/pokemon/exp/shiny/373-mega.png and b/public/images/pokemon/exp/shiny/373-mega.png differ diff --git a/public/images/pokemon/exp/shiny/4080.png b/public/images/pokemon/exp/shiny/4080.png index 9c383118928..20cf5abe061 100644 Binary files a/public/images/pokemon/exp/shiny/4080.png and b/public/images/pokemon/exp/shiny/4080.png differ diff --git a/public/images/pokemon/exp/shiny/4222.png b/public/images/pokemon/exp/shiny/4222.png index 443aeb5fab3..62ab7974e7e 100644 Binary files a/public/images/pokemon/exp/shiny/4222.png and b/public/images/pokemon/exp/shiny/4222.png differ diff --git a/public/images/pokemon/exp/shiny/4264.png b/public/images/pokemon/exp/shiny/4264.png index 4848f512a60..3508177e683 100644 Binary files a/public/images/pokemon/exp/shiny/4264.png and b/public/images/pokemon/exp/shiny/4264.png differ diff --git a/public/images/pokemon/exp/shiny/677.png b/public/images/pokemon/exp/shiny/677.png index d2703b7f7c0..1a236f65716 100644 Binary files a/public/images/pokemon/exp/shiny/677.png and b/public/images/pokemon/exp/shiny/677.png differ diff --git a/public/images/pokemon/exp/shiny/678-female.png b/public/images/pokemon/exp/shiny/678-female.png index 7ae67d63a33..021055baf2c 100644 Binary files a/public/images/pokemon/exp/shiny/678-female.png and b/public/images/pokemon/exp/shiny/678-female.png differ diff --git a/public/images/pokemon/exp/shiny/679.png b/public/images/pokemon/exp/shiny/679.png index 6ac3c47f498..46373f60ead 100644 Binary files a/public/images/pokemon/exp/shiny/679.png and b/public/images/pokemon/exp/shiny/679.png differ diff --git a/public/images/pokemon/exp/shiny/698.png b/public/images/pokemon/exp/shiny/698.png index 322a44b92e8..84d8ba3dac5 100644 Binary files a/public/images/pokemon/exp/shiny/698.png and b/public/images/pokemon/exp/shiny/698.png differ diff --git a/public/images/pokemon/exp/shiny/699.png b/public/images/pokemon/exp/shiny/699.png index d68bd5c0e2a..7ec9dbd7252 100644 Binary files a/public/images/pokemon/exp/shiny/699.png and b/public/images/pokemon/exp/shiny/699.png differ diff --git a/public/images/pokemon/exp/shiny/716-active.png b/public/images/pokemon/exp/shiny/716-active.png index 898d23dd4a4..126c1a78e79 100644 Binary files a/public/images/pokemon/exp/shiny/716-active.png and b/public/images/pokemon/exp/shiny/716-active.png differ diff --git a/public/images/pokemon/exp/shiny/716-neutral.png b/public/images/pokemon/exp/shiny/716-neutral.png index 062deb9ba6a..4806e57123b 100644 Binary files a/public/images/pokemon/exp/shiny/716-neutral.png and b/public/images/pokemon/exp/shiny/716-neutral.png differ diff --git a/public/images/pokemon/exp/shiny/752.png b/public/images/pokemon/exp/shiny/752.png index 0902846f5f5..22a70b76218 100644 Binary files a/public/images/pokemon/exp/shiny/752.png and b/public/images/pokemon/exp/shiny/752.png differ diff --git a/public/images/pokemon/exp/shiny/771.png b/public/images/pokemon/exp/shiny/771.png index 76bf27514d4..b9e8e315b77 100644 Binary files a/public/images/pokemon/exp/shiny/771.png and b/public/images/pokemon/exp/shiny/771.png differ diff --git a/public/images/pokemon/exp/shiny/772.png b/public/images/pokemon/exp/shiny/772.png index 80be3267ea8..16bc67faf12 100644 Binary files a/public/images/pokemon/exp/shiny/772.png and b/public/images/pokemon/exp/shiny/772.png differ diff --git a/public/images/pokemon/exp/shiny/773.png b/public/images/pokemon/exp/shiny/773.png index 407cc9144ef..9b0c6b98b9d 100644 Binary files a/public/images/pokemon/exp/shiny/773.png and b/public/images/pokemon/exp/shiny/773.png differ diff --git a/public/images/pokemon/exp/shiny/776.png b/public/images/pokemon/exp/shiny/776.png index 882a4ed5a6d..a0a363aff3e 100644 Binary files a/public/images/pokemon/exp/shiny/776.png and b/public/images/pokemon/exp/shiny/776.png differ diff --git a/public/images/pokemon/exp/shiny/777.png b/public/images/pokemon/exp/shiny/777.png index 4862152e407..504a2d23abc 100644 Binary files a/public/images/pokemon/exp/shiny/777.png and b/public/images/pokemon/exp/shiny/777.png differ diff --git a/public/images/pokemon/exp/shiny/778-disguised.png b/public/images/pokemon/exp/shiny/778-disguised.png index 13fecc069c6..07f0b9183c9 100644 Binary files a/public/images/pokemon/exp/shiny/778-disguised.png and b/public/images/pokemon/exp/shiny/778-disguised.png differ diff --git a/public/images/pokemon/exp/shiny/793.png b/public/images/pokemon/exp/shiny/793.png index 7cc43d73f02..72a1e65037a 100644 Binary files a/public/images/pokemon/exp/shiny/793.png and b/public/images/pokemon/exp/shiny/793.png differ diff --git a/public/images/pokemon/exp/shiny/798.png b/public/images/pokemon/exp/shiny/798.png index b88b0c1efa5..d67c0a50fdc 100644 Binary files a/public/images/pokemon/exp/shiny/798.png and b/public/images/pokemon/exp/shiny/798.png differ diff --git a/public/images/pokemon/exp/shiny/818.png b/public/images/pokemon/exp/shiny/818.png index f4a8bfa2f6a..0105e7e38ab 100644 Binary files a/public/images/pokemon/exp/shiny/818.png and b/public/images/pokemon/exp/shiny/818.png differ diff --git a/public/images/pokemon/exp/shiny/857.png b/public/images/pokemon/exp/shiny/857.png index 65a7c0f8f39..331e54f93e6 100644 Binary files a/public/images/pokemon/exp/shiny/857.png and b/public/images/pokemon/exp/shiny/857.png differ diff --git a/public/images/pokemon/exp/shiny/898-ice.png b/public/images/pokemon/exp/shiny/898-ice.png index 33850906ca3..4fc9cb48083 100644 Binary files a/public/images/pokemon/exp/shiny/898-ice.png and b/public/images/pokemon/exp/shiny/898-ice.png differ diff --git a/public/images/pokemon/exp/shiny/898-shadow.png b/public/images/pokemon/exp/shiny/898-shadow.png index 8c4e18e6ba8..8587106d483 100644 Binary files a/public/images/pokemon/exp/shiny/898-shadow.png and b/public/images/pokemon/exp/shiny/898-shadow.png differ diff --git a/public/images/pokemon/exp/shiny/912.png b/public/images/pokemon/exp/shiny/912.png index 1f1692d6ceb..9306f0d8cef 100644 Binary files a/public/images/pokemon/exp/shiny/912.png and b/public/images/pokemon/exp/shiny/912.png differ diff --git a/public/images/pokemon/exp/shiny/913.png b/public/images/pokemon/exp/shiny/913.png index 7e458a0796c..9179cfe07f7 100644 Binary files a/public/images/pokemon/exp/shiny/913.png and b/public/images/pokemon/exp/shiny/913.png differ diff --git a/public/images/pokemon/exp/shiny/914.png b/public/images/pokemon/exp/shiny/914.png index bffa5a1489d..8697f0ea3fd 100644 Binary files a/public/images/pokemon/exp/shiny/914.png and b/public/images/pokemon/exp/shiny/914.png differ diff --git a/public/images/pokemon/exp/shiny/940.png b/public/images/pokemon/exp/shiny/940.png index 2e66b03cd9f..7eab3973ebf 100644 Binary files a/public/images/pokemon/exp/shiny/940.png and b/public/images/pokemon/exp/shiny/940.png differ diff --git a/public/images/pokemon/exp/shiny/954.png b/public/images/pokemon/exp/shiny/954.png index 8bb46149716..87f5093f221 100644 Binary files a/public/images/pokemon/exp/shiny/954.png and b/public/images/pokemon/exp/shiny/954.png differ diff --git a/public/images/pokemon/exp/shiny/970.png b/public/images/pokemon/exp/shiny/970.png index 52ad602b0a4..d455d836e51 100644 Binary files a/public/images/pokemon/exp/shiny/970.png and b/public/images/pokemon/exp/shiny/970.png differ diff --git a/public/images/pokemon/exp/shiny/981.png b/public/images/pokemon/exp/shiny/981.png index f8f977fed92..5cced7d6d3f 100644 Binary files a/public/images/pokemon/exp/shiny/981.png and b/public/images/pokemon/exp/shiny/981.png differ diff --git a/public/images/pokemon/exp/shiny/983.png b/public/images/pokemon/exp/shiny/983.png index 36e0df81562..f7505c9b1a6 100644 Binary files a/public/images/pokemon/exp/shiny/983.png and b/public/images/pokemon/exp/shiny/983.png differ diff --git a/public/images/pokemon/female/190.png b/public/images/pokemon/female/190.png index d0d5a1a2f76..a2d5c0b7b7d 100644 Binary files a/public/images/pokemon/female/190.png and b/public/images/pokemon/female/190.png differ diff --git a/public/images/pokemon/female/229.png b/public/images/pokemon/female/229.png index 3d0b516a797..836ceab6bb5 100644 Binary files a/public/images/pokemon/female/229.png and b/public/images/pokemon/female/229.png differ diff --git a/public/images/pokemon/female/232.png b/public/images/pokemon/female/232.png index 0359febee15..9477fd192f7 100644 Binary files a/public/images/pokemon/female/232.png and b/public/images/pokemon/female/232.png differ diff --git a/public/images/pokemon/female/25-cool-cosplay.png b/public/images/pokemon/female/25-cool-cosplay.png index ae1e7c76d44..9f76c7826f1 100644 Binary files a/public/images/pokemon/female/25-cool-cosplay.png and b/public/images/pokemon/female/25-cool-cosplay.png differ diff --git a/public/images/pokemon/female/256.png b/public/images/pokemon/female/256.png index f470f5daf4b..c8b0b2cbd4c 100644 Binary files a/public/images/pokemon/female/256.png and b/public/images/pokemon/female/256.png differ diff --git a/public/images/pokemon/female/257.png b/public/images/pokemon/female/257.png index 1c8a4c70757..ed3e8d2914e 100644 Binary files a/public/images/pokemon/female/257.png and b/public/images/pokemon/female/257.png differ diff --git a/public/images/pokemon/female/401.png b/public/images/pokemon/female/401.png index 8e145b0c1c2..4cd3fc77097 100644 Binary files a/public/images/pokemon/female/401.png and b/public/images/pokemon/female/401.png differ diff --git a/public/images/pokemon/female/402.png b/public/images/pokemon/female/402.png index bfa3b5b8670..1b92a7a9a95 100644 Binary files a/public/images/pokemon/female/402.png and b/public/images/pokemon/female/402.png differ diff --git a/public/images/pokemon/female/418.png b/public/images/pokemon/female/418.png index 005c917463f..fba2402c2b3 100644 Binary files a/public/images/pokemon/female/418.png and b/public/images/pokemon/female/418.png differ diff --git a/public/images/pokemon/female/419.png b/public/images/pokemon/female/419.png index 572f819749b..5fbe90ff3bd 100644 Binary files a/public/images/pokemon/female/419.png and b/public/images/pokemon/female/419.png differ diff --git a/public/images/pokemon/female/424.png b/public/images/pokemon/female/424.png index 8e4fbc235ca..4d86b5be16e 100644 Binary files a/public/images/pokemon/female/424.png and b/public/images/pokemon/female/424.png differ diff --git a/public/images/pokemon/female/45.png b/public/images/pokemon/female/45.png index fad183bbf8d..3c5d4d91aeb 100644 Binary files a/public/images/pokemon/female/45.png and b/public/images/pokemon/female/45.png differ diff --git a/public/images/pokemon/female/456.png b/public/images/pokemon/female/456.png index a50fd2aa034..ca0d454c98f 100644 Binary files a/public/images/pokemon/female/456.png and b/public/images/pokemon/female/456.png differ diff --git a/public/images/pokemon/female/457.png b/public/images/pokemon/female/457.png index 2aec3e26a07..605bb23a892 100644 Binary files a/public/images/pokemon/female/457.png and b/public/images/pokemon/female/457.png differ diff --git a/public/images/pokemon/icons/2/154-f.png b/public/images/pokemon/icons/2/154-f.png new file mode 100644 index 00000000000..6481cdd8a00 Binary files /dev/null and b/public/images/pokemon/icons/2/154-f.png differ diff --git a/public/images/pokemon/icons/2/154s-f.png b/public/images/pokemon/icons/2/154s-f.png new file mode 100644 index 00000000000..44ded711dcd Binary files /dev/null and b/public/images/pokemon/icons/2/154s-f.png differ diff --git a/public/images/pokemon/icons/3/255-f.png b/public/images/pokemon/icons/3/255-f.png new file mode 100644 index 00000000000..bb221be21e7 Binary files /dev/null and b/public/images/pokemon/icons/3/255-f.png differ diff --git a/public/images/pokemon/icons/3/255s-f.png b/public/images/pokemon/icons/3/255s-f.png new file mode 100644 index 00000000000..898b17c163c Binary files /dev/null and b/public/images/pokemon/icons/3/255s-f.png differ diff --git a/public/images/pokemon/icons/3/256-f.png b/public/images/pokemon/icons/3/256-f.png new file mode 100644 index 00000000000..72800cc5e25 Binary files /dev/null and b/public/images/pokemon/icons/3/256-f.png differ diff --git a/public/images/pokemon/icons/3/256s-f.png b/public/images/pokemon/icons/3/256s-f.png new file mode 100644 index 00000000000..ce6608f7bc5 Binary files /dev/null and b/public/images/pokemon/icons/3/256s-f.png differ diff --git a/public/images/pokemon/icons/3/257-f-mega.png b/public/images/pokemon/icons/3/257-f-mega.png new file mode 100644 index 00000000000..ed64fe8f41f Binary files /dev/null and b/public/images/pokemon/icons/3/257-f-mega.png differ diff --git a/public/images/pokemon/icons/3/257-f.png b/public/images/pokemon/icons/3/257-f.png new file mode 100644 index 00000000000..ee42a9f75c0 Binary files /dev/null and b/public/images/pokemon/icons/3/257-f.png differ diff --git a/public/images/pokemon/icons/3/257s-f-mega.png b/public/images/pokemon/icons/3/257s-f-mega.png new file mode 100644 index 00000000000..faf5e5aa30c Binary files /dev/null and b/public/images/pokemon/icons/3/257s-f-mega.png differ diff --git a/public/images/pokemon/icons/3/257s-f.png b/public/images/pokemon/icons/3/257s-f.png new file mode 100644 index 00000000000..bf59393972f Binary files /dev/null and b/public/images/pokemon/icons/3/257s-f.png differ diff --git a/public/images/pokemon/shiny/1003.png b/public/images/pokemon/shiny/1003.png index 3c5415cf94e..17462eaf89f 100644 Binary files a/public/images/pokemon/shiny/1003.png and b/public/images/pokemon/shiny/1003.png differ diff --git a/public/images/pokemon/shiny/1018.png b/public/images/pokemon/shiny/1018.png index 7c753bb05e5..42076fd0687 100644 Binary files a/public/images/pokemon/shiny/1018.png and b/public/images/pokemon/shiny/1018.png differ diff --git a/public/images/pokemon/shiny/164.png b/public/images/pokemon/shiny/164.png index de6405ff580..4e36ce61adb 100644 Binary files a/public/images/pokemon/shiny/164.png and b/public/images/pokemon/shiny/164.png differ diff --git a/public/images/pokemon/shiny/190.png b/public/images/pokemon/shiny/190.png index 3ad2e7b5582..60b7ad3163d 100644 Binary files a/public/images/pokemon/shiny/190.png and b/public/images/pokemon/shiny/190.png differ diff --git a/public/images/pokemon/shiny/218.png b/public/images/pokemon/shiny/218.png index cd70183de39..b3e42ae4adc 100644 Binary files a/public/images/pokemon/shiny/218.png and b/public/images/pokemon/shiny/218.png differ diff --git a/public/images/pokemon/shiny/226.png b/public/images/pokemon/shiny/226.png index 5b24827b5d5..f2934a577f1 100644 Binary files a/public/images/pokemon/shiny/226.png and b/public/images/pokemon/shiny/226.png differ diff --git a/public/images/pokemon/shiny/261.png b/public/images/pokemon/shiny/261.png index 1a976339b67..6ae6e5838ce 100644 Binary files a/public/images/pokemon/shiny/261.png and b/public/images/pokemon/shiny/261.png differ diff --git a/public/images/pokemon/shiny/262.png b/public/images/pokemon/shiny/262.png index ea42b525b6b..d2dbec0bb8d 100644 Binary files a/public/images/pokemon/shiny/262.png and b/public/images/pokemon/shiny/262.png differ diff --git a/public/images/pokemon/shiny/308.png b/public/images/pokemon/shiny/308.png index 14e97cf83a3..102bc0256e4 100644 Binary files a/public/images/pokemon/shiny/308.png and b/public/images/pokemon/shiny/308.png differ diff --git a/public/images/pokemon/shiny/335.png b/public/images/pokemon/shiny/335.png index e4f8d10fb1b..765344af6fd 100644 Binary files a/public/images/pokemon/shiny/335.png and b/public/images/pokemon/shiny/335.png differ diff --git a/public/images/pokemon/shiny/336.png b/public/images/pokemon/shiny/336.png index efa1262248a..45d57027704 100644 Binary files a/public/images/pokemon/shiny/336.png and b/public/images/pokemon/shiny/336.png differ diff --git a/public/images/pokemon/shiny/357.png b/public/images/pokemon/shiny/357.png index ca74e4b466c..0eb62e53719 100644 Binary files a/public/images/pokemon/shiny/357.png and b/public/images/pokemon/shiny/357.png differ diff --git a/public/images/pokemon/shiny/370.png b/public/images/pokemon/shiny/370.png index 8a7bf0b11a8..f49fe4fe27c 100644 Binary files a/public/images/pokemon/shiny/370.png and b/public/images/pokemon/shiny/370.png differ diff --git a/public/images/pokemon/shiny/373-mega.png b/public/images/pokemon/shiny/373-mega.png index 4e9fe93fa5c..fd2e8eed6e2 100644 Binary files a/public/images/pokemon/shiny/373-mega.png and b/public/images/pokemon/shiny/373-mega.png differ diff --git a/public/images/pokemon/shiny/373.png b/public/images/pokemon/shiny/373.png index cae369ce412..6e21c49c034 100644 Binary files a/public/images/pokemon/shiny/373.png and b/public/images/pokemon/shiny/373.png differ diff --git a/public/images/pokemon/shiny/4080.png b/public/images/pokemon/shiny/4080.png index 9ff6184d692..35f3c7c0ff6 100644 Binary files a/public/images/pokemon/shiny/4080.png and b/public/images/pokemon/shiny/4080.png differ diff --git a/public/images/pokemon/shiny/4199.png b/public/images/pokemon/shiny/4199.png index d428931eff8..fb4b8b70ddb 100644 Binary files a/public/images/pokemon/shiny/4199.png and b/public/images/pokemon/shiny/4199.png differ diff --git a/public/images/pokemon/shiny/424.png b/public/images/pokemon/shiny/424.png index 0c97de2883e..5685c21e276 100644 Binary files a/public/images/pokemon/shiny/424.png and b/public/images/pokemon/shiny/424.png differ diff --git a/public/images/pokemon/shiny/433.png b/public/images/pokemon/shiny/433.png index 55021a56458..f5f34928c21 100644 Binary files a/public/images/pokemon/shiny/433.png and b/public/images/pokemon/shiny/433.png differ diff --git a/public/images/pokemon/shiny/45.png b/public/images/pokemon/shiny/45.png index 92b28c054c9..4aab94dfb65 100644 Binary files a/public/images/pokemon/shiny/45.png and b/public/images/pokemon/shiny/45.png differ diff --git a/public/images/pokemon/shiny/469.png b/public/images/pokemon/shiny/469.png index c7f7ee3b68e..7e8d8b674d3 100644 Binary files a/public/images/pokemon/shiny/469.png and b/public/images/pokemon/shiny/469.png differ diff --git a/public/images/pokemon/shiny/472.png b/public/images/pokemon/shiny/472.png index f1e833b66cb..14fa9b0fe8b 100644 Binary files a/public/images/pokemon/shiny/472.png and b/public/images/pokemon/shiny/472.png differ diff --git a/public/images/pokemon/shiny/477.png b/public/images/pokemon/shiny/477.png index 0f14172f019..2011636c517 100644 Binary files a/public/images/pokemon/shiny/477.png and b/public/images/pokemon/shiny/477.png differ diff --git a/public/images/pokemon/shiny/556.png b/public/images/pokemon/shiny/556.png index b0052759531..d62d114bbcb 100644 Binary files a/public/images/pokemon/shiny/556.png and b/public/images/pokemon/shiny/556.png differ diff --git a/public/images/pokemon/shiny/677.png b/public/images/pokemon/shiny/677.png index b90d0286879..a885bec4ee0 100644 Binary files a/public/images/pokemon/shiny/677.png and b/public/images/pokemon/shiny/677.png differ diff --git a/public/images/pokemon/shiny/678-female.png b/public/images/pokemon/shiny/678-female.png index 9a288a4fcb4..e999a0fbd69 100644 Binary files a/public/images/pokemon/shiny/678-female.png and b/public/images/pokemon/shiny/678-female.png differ diff --git a/public/images/pokemon/shiny/678.png b/public/images/pokemon/shiny/678.png index da33c6b3645..683d92c3299 100644 Binary files a/public/images/pokemon/shiny/678.png and b/public/images/pokemon/shiny/678.png differ diff --git a/public/images/pokemon/shiny/698.png b/public/images/pokemon/shiny/698.png index 0874f9af37e..c04cc11875d 100644 Binary files a/public/images/pokemon/shiny/698.png and b/public/images/pokemon/shiny/698.png differ diff --git a/public/images/pokemon/shiny/699.png b/public/images/pokemon/shiny/699.png index 16876941901..1e22a84228f 100644 Binary files a/public/images/pokemon/shiny/699.png and b/public/images/pokemon/shiny/699.png differ diff --git a/public/images/pokemon/shiny/716-active.png b/public/images/pokemon/shiny/716-active.png index 077c657f814..357f0fb843b 100644 Binary files a/public/images/pokemon/shiny/716-active.png and b/public/images/pokemon/shiny/716-active.png differ diff --git a/public/images/pokemon/shiny/716-neutral.png b/public/images/pokemon/shiny/716-neutral.png index ffe04571aa7..bcccc513da4 100644 Binary files a/public/images/pokemon/shiny/716-neutral.png and b/public/images/pokemon/shiny/716-neutral.png differ diff --git a/public/images/pokemon/shiny/772.png b/public/images/pokemon/shiny/772.png index f2038ddd4fa..759691cc312 100644 Binary files a/public/images/pokemon/shiny/772.png and b/public/images/pokemon/shiny/772.png differ diff --git a/public/images/pokemon/shiny/773.png b/public/images/pokemon/shiny/773.png index 3b2b7f9b296..6f900ae9fdc 100644 Binary files a/public/images/pokemon/shiny/773.png and b/public/images/pokemon/shiny/773.png differ diff --git a/public/images/pokemon/shiny/777.png b/public/images/pokemon/shiny/777.png index c8ba24bf3ac..8ceb5506f9b 100644 Binary files a/public/images/pokemon/shiny/777.png and b/public/images/pokemon/shiny/777.png differ diff --git a/public/images/pokemon/shiny/80-mega.png b/public/images/pokemon/shiny/80-mega.png index 399402cf618..21eb3c37a05 100644 Binary files a/public/images/pokemon/shiny/80-mega.png and b/public/images/pokemon/shiny/80-mega.png differ diff --git a/public/images/pokemon/shiny/80.png b/public/images/pokemon/shiny/80.png index 750f0d7cc92..a40953ebc30 100644 Binary files a/public/images/pokemon/shiny/80.png and b/public/images/pokemon/shiny/80.png differ diff --git a/public/images/pokemon/shiny/818-gigantamax.png b/public/images/pokemon/shiny/818-gigantamax.png index 694692964fb..6ff10199f70 100644 Binary files a/public/images/pokemon/shiny/818-gigantamax.png and b/public/images/pokemon/shiny/818-gigantamax.png differ diff --git a/public/images/pokemon/shiny/862.png b/public/images/pokemon/shiny/862.png index bc949797ee9..e48ad78032b 100644 Binary files a/public/images/pokemon/shiny/862.png and b/public/images/pokemon/shiny/862.png differ diff --git a/public/images/pokemon/shiny/864.png b/public/images/pokemon/shiny/864.png index 780f52945f2..383dfecc748 100644 Binary files a/public/images/pokemon/shiny/864.png and b/public/images/pokemon/shiny/864.png differ diff --git a/public/images/pokemon/shiny/898-ice.png b/public/images/pokemon/shiny/898-ice.png index d262f8c3e9d..ae98d45e159 100644 Binary files a/public/images/pokemon/shiny/898-ice.png and b/public/images/pokemon/shiny/898-ice.png differ diff --git a/public/images/pokemon/shiny/898-shadow.png b/public/images/pokemon/shiny/898-shadow.png index 6744535f165..6d056c192b1 100644 Binary files a/public/images/pokemon/shiny/898-shadow.png and b/public/images/pokemon/shiny/898-shadow.png differ diff --git a/public/images/pokemon/shiny/912.png b/public/images/pokemon/shiny/912.png index 9fcdbbae78f..70067668d6a 100644 Binary files a/public/images/pokemon/shiny/912.png and b/public/images/pokemon/shiny/912.png differ diff --git a/public/images/pokemon/shiny/913.png b/public/images/pokemon/shiny/913.png index 5791f5be095..08eb57e1957 100644 Binary files a/public/images/pokemon/shiny/913.png and b/public/images/pokemon/shiny/913.png differ diff --git a/public/images/pokemon/shiny/914.png b/public/images/pokemon/shiny/914.png index f20466d543d..950f964aa09 100644 Binary files a/public/images/pokemon/shiny/914.png and b/public/images/pokemon/shiny/914.png differ diff --git a/public/images/pokemon/shiny/940.png b/public/images/pokemon/shiny/940.png index 77b45558e2c..a953bd6fc44 100644 Binary files a/public/images/pokemon/shiny/940.png and b/public/images/pokemon/shiny/940.png differ diff --git a/public/images/pokemon/shiny/941.png b/public/images/pokemon/shiny/941.png index 986a6a53a8e..5ccba807754 100644 Binary files a/public/images/pokemon/shiny/941.png and b/public/images/pokemon/shiny/941.png differ diff --git a/public/images/pokemon/shiny/981.png b/public/images/pokemon/shiny/981.png index 68570ed91f2..4b1ea705a5c 100644 Binary files a/public/images/pokemon/shiny/981.png and b/public/images/pokemon/shiny/981.png differ diff --git a/public/images/pokemon/shiny/997.png b/public/images/pokemon/shiny/997.png index a9efb86b999..e164116e56c 100644 Binary files a/public/images/pokemon/shiny/997.png and b/public/images/pokemon/shiny/997.png differ diff --git a/public/images/pokemon/shiny/female/190.png b/public/images/pokemon/shiny/female/190.png index 0fc6b5f08dd..c79a1f85fe2 100644 Binary files a/public/images/pokemon/shiny/female/190.png and b/public/images/pokemon/shiny/female/190.png differ diff --git a/public/images/pokemon/shiny/female/424.png b/public/images/pokemon/shiny/female/424.png index 84ed5063655..f84f91548c9 100644 Binary files a/public/images/pokemon/shiny/female/424.png and b/public/images/pokemon/shiny/female/424.png differ diff --git a/public/images/pokemon/shiny/female/45.png b/public/images/pokemon/shiny/female/45.png index a6bbe3039cb..2ea6e0d214b 100644 Binary files a/public/images/pokemon/shiny/female/45.png and b/public/images/pokemon/shiny/female/45.png differ diff --git a/public/images/pokemon/variant/113_1.png b/public/images/pokemon/variant/113_1.png index bf4ce11b3d7..b64aca2eb7e 100644 Binary files a/public/images/pokemon/variant/113_1.png and b/public/images/pokemon/variant/113_1.png differ diff --git a/public/images/pokemon/variant/113_2.png b/public/images/pokemon/variant/113_2.png index 455068d0c66..d89db9f3b73 100644 Binary files a/public/images/pokemon/variant/113_2.png and b/public/images/pokemon/variant/113_2.png differ diff --git a/public/images/pokemon/variant/113_3.png b/public/images/pokemon/variant/113_3.png index 3a82615fcca..2623a4c5527 100644 Binary files a/public/images/pokemon/variant/113_3.png and b/public/images/pokemon/variant/113_3.png differ diff --git a/public/images/pokemon/variant/125_3.png b/public/images/pokemon/variant/125_3.png index 89c02510442..dfab3fd2b7a 100644 Binary files a/public/images/pokemon/variant/125_3.png and b/public/images/pokemon/variant/125_3.png differ diff --git a/public/images/pokemon/variant/126_2.png b/public/images/pokemon/variant/126_2.png index 19aa928037d..12ddf148e51 100644 Binary files a/public/images/pokemon/variant/126_2.png and b/public/images/pokemon/variant/126_2.png differ diff --git a/public/images/pokemon/variant/139_3.png b/public/images/pokemon/variant/139_3.png index 0c6bd552707..90f8728ffc7 100644 Binary files a/public/images/pokemon/variant/139_3.png and b/public/images/pokemon/variant/139_3.png differ diff --git a/public/images/pokemon/variant/141_2.png b/public/images/pokemon/variant/141_2.png index 3cd10984009..c94613ee202 100644 Binary files a/public/images/pokemon/variant/141_2.png and b/public/images/pokemon/variant/141_2.png differ diff --git a/public/images/pokemon/variant/141_3.png b/public/images/pokemon/variant/141_3.png index 271e5310b84..74ff87613d6 100644 Binary files a/public/images/pokemon/variant/141_3.png and b/public/images/pokemon/variant/141_3.png differ diff --git a/public/images/pokemon/variant/144_2.png b/public/images/pokemon/variant/144_2.png index 9c5ff41d5c5..ca20163748d 100644 Binary files a/public/images/pokemon/variant/144_2.png and b/public/images/pokemon/variant/144_2.png differ diff --git a/public/images/pokemon/variant/144_3.png b/public/images/pokemon/variant/144_3.png index 52e8bb092f1..a14e9166803 100644 Binary files a/public/images/pokemon/variant/144_3.png and b/public/images/pokemon/variant/144_3.png differ diff --git a/public/images/pokemon/variant/161_3.png b/public/images/pokemon/variant/161_3.png index a26adbff423..f4badb44d7f 100644 Binary files a/public/images/pokemon/variant/161_3.png and b/public/images/pokemon/variant/161_3.png differ diff --git a/public/images/pokemon/variant/164_2.png b/public/images/pokemon/variant/164_2.png index 0bd9234ca76..a5809a334f9 100644 Binary files a/public/images/pokemon/variant/164_2.png and b/public/images/pokemon/variant/164_2.png differ diff --git a/public/images/pokemon/variant/164_3.png b/public/images/pokemon/variant/164_3.png index fb3c689aa05..38c88b30a49 100644 Binary files a/public/images/pokemon/variant/164_3.png and b/public/images/pokemon/variant/164_3.png differ diff --git a/public/images/pokemon/variant/173_3.png b/public/images/pokemon/variant/173_3.png index 5cb3abbaaec..2799a88a0df 100644 Binary files a/public/images/pokemon/variant/173_3.png and b/public/images/pokemon/variant/173_3.png differ diff --git a/public/images/pokemon/variant/180_2.png b/public/images/pokemon/variant/180_2.png index 522014a78ba..fbdd97e2d52 100644 Binary files a/public/images/pokemon/variant/180_2.png and b/public/images/pokemon/variant/180_2.png differ diff --git a/public/images/pokemon/variant/180_3.png b/public/images/pokemon/variant/180_3.png index 074a4d06b80..382b3ea0961 100644 Binary files a/public/images/pokemon/variant/180_3.png and b/public/images/pokemon/variant/180_3.png differ diff --git a/public/images/pokemon/variant/181-mega_3.png b/public/images/pokemon/variant/181-mega_3.png index 444947d3207..4adad450342 100644 Binary files a/public/images/pokemon/variant/181-mega_3.png and b/public/images/pokemon/variant/181-mega_3.png differ diff --git a/public/images/pokemon/variant/183_3.png b/public/images/pokemon/variant/183_3.png index ba04c8da2d7..479164bc4f8 100644 Binary files a/public/images/pokemon/variant/183_3.png and b/public/images/pokemon/variant/183_3.png differ diff --git a/public/images/pokemon/variant/184_2.png b/public/images/pokemon/variant/184_2.png index dc166ced0db..fd57af02f36 100644 Binary files a/public/images/pokemon/variant/184_2.png and b/public/images/pokemon/variant/184_2.png differ diff --git a/public/images/pokemon/variant/184_3.png b/public/images/pokemon/variant/184_3.png index edde99b92ff..09fa5274381 100644 Binary files a/public/images/pokemon/variant/184_3.png and b/public/images/pokemon/variant/184_3.png differ diff --git a/public/images/pokemon/variant/199_1.png b/public/images/pokemon/variant/199_1.png index 9899cae4e7f..3366b156560 100644 Binary files a/public/images/pokemon/variant/199_1.png and b/public/images/pokemon/variant/199_1.png differ diff --git a/public/images/pokemon/variant/212-mega_2.png b/public/images/pokemon/variant/212-mega_2.png index a4db96d6aac..e3d12893a29 100644 Binary files a/public/images/pokemon/variant/212-mega_2.png and b/public/images/pokemon/variant/212-mega_2.png differ diff --git a/public/images/pokemon/variant/212-mega_3.png b/public/images/pokemon/variant/212-mega_3.png index dac4b3bd552..9d7ba9e777e 100644 Binary files a/public/images/pokemon/variant/212-mega_3.png and b/public/images/pokemon/variant/212-mega_3.png differ diff --git a/public/images/pokemon/variant/212_2.png b/public/images/pokemon/variant/212_2.png index 913ab71026d..a22ed57eaf3 100644 Binary files a/public/images/pokemon/variant/212_2.png and b/public/images/pokemon/variant/212_2.png differ diff --git a/public/images/pokemon/variant/212_3.png b/public/images/pokemon/variant/212_3.png index 6a027cd53dc..1a71f292f28 100644 Binary files a/public/images/pokemon/variant/212_3.png and b/public/images/pokemon/variant/212_3.png differ diff --git a/public/images/pokemon/variant/226_2.png b/public/images/pokemon/variant/226_2.png index 770f77e7154..2d011894969 100644 Binary files a/public/images/pokemon/variant/226_2.png and b/public/images/pokemon/variant/226_2.png differ diff --git a/public/images/pokemon/variant/226_3.png b/public/images/pokemon/variant/226_3.png index eff63a19224..d0ad24bc78d 100644 Binary files a/public/images/pokemon/variant/226_3.png and b/public/images/pokemon/variant/226_3.png differ diff --git a/public/images/pokemon/variant/239_3.png b/public/images/pokemon/variant/239_3.png index 25f32c3f96c..158d8701098 100644 Binary files a/public/images/pokemon/variant/239_3.png and b/public/images/pokemon/variant/239_3.png differ diff --git a/public/images/pokemon/variant/242_1.png b/public/images/pokemon/variant/242_1.png index 987c4d5a9f9..8b5cff906e4 100644 Binary files a/public/images/pokemon/variant/242_1.png and b/public/images/pokemon/variant/242_1.png differ diff --git a/public/images/pokemon/variant/242_2.png b/public/images/pokemon/variant/242_2.png index 276d36f7091..aefddbd0cf8 100644 Binary files a/public/images/pokemon/variant/242_2.png and b/public/images/pokemon/variant/242_2.png differ diff --git a/public/images/pokemon/variant/242_3.png b/public/images/pokemon/variant/242_3.png index 6f83ed75c95..bc121988137 100644 Binary files a/public/images/pokemon/variant/242_3.png and b/public/images/pokemon/variant/242_3.png differ diff --git a/public/images/pokemon/variant/244_2.png b/public/images/pokemon/variant/244_2.png index 2b7b4e57b97..b6418e496f6 100644 Binary files a/public/images/pokemon/variant/244_2.png and b/public/images/pokemon/variant/244_2.png differ diff --git a/public/images/pokemon/variant/244_3.png b/public/images/pokemon/variant/244_3.png index 93b51f45f2f..c903b01d8ce 100644 Binary files a/public/images/pokemon/variant/244_3.png and b/public/images/pokemon/variant/244_3.png differ diff --git a/public/images/pokemon/variant/248-mega_2.png b/public/images/pokemon/variant/248-mega_2.png index a6000c370a7..1aade727abf 100644 Binary files a/public/images/pokemon/variant/248-mega_2.png and b/public/images/pokemon/variant/248-mega_2.png differ diff --git a/public/images/pokemon/variant/249_2.png b/public/images/pokemon/variant/249_2.png index 220258fb7f8..d896fa2999f 100644 Binary files a/public/images/pokemon/variant/249_2.png and b/public/images/pokemon/variant/249_2.png differ diff --git a/public/images/pokemon/variant/249_3.png b/public/images/pokemon/variant/249_3.png index 85a453e0ad5..7a932d917fb 100644 Binary files a/public/images/pokemon/variant/249_3.png and b/public/images/pokemon/variant/249_3.png differ diff --git a/public/images/pokemon/variant/250_2.png b/public/images/pokemon/variant/250_2.png index 5c1d4828ebe..d63c5310db8 100644 Binary files a/public/images/pokemon/variant/250_2.png and b/public/images/pokemon/variant/250_2.png differ diff --git a/public/images/pokemon/variant/250_3.png b/public/images/pokemon/variant/250_3.png index 90fb6bb0680..59fbb3bdfd5 100644 Binary files a/public/images/pokemon/variant/250_3.png and b/public/images/pokemon/variant/250_3.png differ diff --git a/public/images/pokemon/variant/257_3.png b/public/images/pokemon/variant/257_3.png index 8242580aaec..62c4b6589a3 100644 Binary files a/public/images/pokemon/variant/257_3.png and b/public/images/pokemon/variant/257_3.png differ diff --git a/public/images/pokemon/variant/291_1.png b/public/images/pokemon/variant/291_1.png index fea63c6c27c..30cae5bb507 100644 Binary files a/public/images/pokemon/variant/291_1.png and b/public/images/pokemon/variant/291_1.png differ diff --git a/public/images/pokemon/variant/291_2.png b/public/images/pokemon/variant/291_2.png index b7b771acb30..ccbe82a1201 100644 Binary files a/public/images/pokemon/variant/291_2.png and b/public/images/pokemon/variant/291_2.png differ diff --git a/public/images/pokemon/variant/291_3.png b/public/images/pokemon/variant/291_3.png index 72d28c371f2..26ea5d3cf4d 100644 Binary files a/public/images/pokemon/variant/291_3.png and b/public/images/pokemon/variant/291_3.png differ diff --git a/public/images/pokemon/variant/292_1.png b/public/images/pokemon/variant/292_1.png index 118bfe79542..3f4ec4df742 100644 Binary files a/public/images/pokemon/variant/292_1.png and b/public/images/pokemon/variant/292_1.png differ diff --git a/public/images/pokemon/variant/292_3.png b/public/images/pokemon/variant/292_3.png index 6b5f128fdd6..989d28d017a 100644 Binary files a/public/images/pokemon/variant/292_3.png and b/public/images/pokemon/variant/292_3.png differ diff --git a/public/images/pokemon/variant/298_2.png b/public/images/pokemon/variant/298_2.png index b48ebec70ad..f071c40c69a 100644 Binary files a/public/images/pokemon/variant/298_2.png and b/public/images/pokemon/variant/298_2.png differ diff --git a/public/images/pokemon/variant/298_3.png b/public/images/pokemon/variant/298_3.png index 137cee603a7..5dbf9b03b31 100644 Binary files a/public/images/pokemon/variant/298_3.png and b/public/images/pokemon/variant/298_3.png differ diff --git a/public/images/pokemon/variant/2_2.png b/public/images/pokemon/variant/2_2.png index 2477646fef4..b12bd60bd23 100644 Binary files a/public/images/pokemon/variant/2_2.png and b/public/images/pokemon/variant/2_2.png differ diff --git a/public/images/pokemon/variant/3-mega_2.png b/public/images/pokemon/variant/3-mega_2.png index 037e983a030..ddc2bd976ad 100644 Binary files a/public/images/pokemon/variant/3-mega_2.png and b/public/images/pokemon/variant/3-mega_2.png differ diff --git a/public/images/pokemon/variant/3-mega_3.png b/public/images/pokemon/variant/3-mega_3.png index 6a967466ac1..56945d383e6 100644 Binary files a/public/images/pokemon/variant/3-mega_3.png and b/public/images/pokemon/variant/3-mega_3.png differ diff --git a/public/images/pokemon/variant/308_2.png b/public/images/pokemon/variant/308_2.png index 42a11414659..0c13b01d575 100644 Binary files a/public/images/pokemon/variant/308_2.png and b/public/images/pokemon/variant/308_2.png differ diff --git a/public/images/pokemon/variant/31_1.png b/public/images/pokemon/variant/31_1.png index d471b062136..d968477a946 100644 Binary files a/public/images/pokemon/variant/31_1.png and b/public/images/pokemon/variant/31_1.png differ diff --git a/public/images/pokemon/variant/329_3.png b/public/images/pokemon/variant/329_3.png index 45fad04068e..0530cfa7be3 100644 Binary files a/public/images/pokemon/variant/329_3.png and b/public/images/pokemon/variant/329_3.png differ diff --git a/public/images/pokemon/variant/334-mega_2.png b/public/images/pokemon/variant/334-mega_2.png index df2c3950f2c..f0304935968 100644 Binary files a/public/images/pokemon/variant/334-mega_2.png and b/public/images/pokemon/variant/334-mega_2.png differ diff --git a/public/images/pokemon/variant/334_2.png b/public/images/pokemon/variant/334_2.png index 94457f721e3..cf30637cf79 100644 Binary files a/public/images/pokemon/variant/334_2.png and b/public/images/pokemon/variant/334_2.png differ diff --git a/public/images/pokemon/variant/334_3.png b/public/images/pokemon/variant/334_3.png index 67fd670b3cb..b54ed45c264 100644 Binary files a/public/images/pokemon/variant/334_3.png and b/public/images/pokemon/variant/334_3.png differ diff --git a/public/images/pokemon/variant/335_2.png b/public/images/pokemon/variant/335_2.png index 6f7924b4b33..4baa18218ae 100644 Binary files a/public/images/pokemon/variant/335_2.png and b/public/images/pokemon/variant/335_2.png differ diff --git a/public/images/pokemon/variant/335_3.png b/public/images/pokemon/variant/335_3.png index 25ab4a00c09..c42ce4ce429 100644 Binary files a/public/images/pokemon/variant/335_3.png and b/public/images/pokemon/variant/335_3.png differ diff --git a/public/images/pokemon/variant/340_3.png b/public/images/pokemon/variant/340_3.png index 7ddb0768e02..24aede4bafe 100644 Binary files a/public/images/pokemon/variant/340_3.png and b/public/images/pokemon/variant/340_3.png differ diff --git a/public/images/pokemon/variant/341_2.png b/public/images/pokemon/variant/341_2.png index 71793d13d87..ff943eab93c 100644 Binary files a/public/images/pokemon/variant/341_2.png and b/public/images/pokemon/variant/341_2.png differ diff --git a/public/images/pokemon/variant/341_3.png b/public/images/pokemon/variant/341_3.png index b0e07fea033..ed4697d48b8 100644 Binary files a/public/images/pokemon/variant/341_3.png and b/public/images/pokemon/variant/341_3.png differ diff --git a/public/images/pokemon/variant/342_2.png b/public/images/pokemon/variant/342_2.png index 647d838c357..e1f8acaf8a6 100644 Binary files a/public/images/pokemon/variant/342_2.png and b/public/images/pokemon/variant/342_2.png differ diff --git a/public/images/pokemon/variant/342_3.png b/public/images/pokemon/variant/342_3.png index b4d8e18d8a8..2a10036b3f3 100644 Binary files a/public/images/pokemon/variant/342_3.png and b/public/images/pokemon/variant/342_3.png differ diff --git a/public/images/pokemon/variant/351-rainy_2.png b/public/images/pokemon/variant/351-rainy_2.png index 0b3f403c1ff..61cacb77d2e 100644 Binary files a/public/images/pokemon/variant/351-rainy_2.png and b/public/images/pokemon/variant/351-rainy_2.png differ diff --git a/public/images/pokemon/variant/351-rainy_3.png b/public/images/pokemon/variant/351-rainy_3.png index fc163d23ddf..c61be0fdd7d 100644 Binary files a/public/images/pokemon/variant/351-rainy_3.png and b/public/images/pokemon/variant/351-rainy_3.png differ diff --git a/public/images/pokemon/variant/351-sunny_2.png b/public/images/pokemon/variant/351-sunny_2.png index 6fc85cb6094..3815dd5fd8a 100644 Binary files a/public/images/pokemon/variant/351-sunny_2.png and b/public/images/pokemon/variant/351-sunny_2.png differ diff --git a/public/images/pokemon/variant/351-sunny_3.png b/public/images/pokemon/variant/351-sunny_3.png index e21f7627d1f..3627d88615e 100644 Binary files a/public/images/pokemon/variant/351-sunny_3.png and b/public/images/pokemon/variant/351-sunny_3.png differ diff --git a/public/images/pokemon/variant/351_2.png b/public/images/pokemon/variant/351_2.png index c9369b2bef2..30b88866823 100644 Binary files a/public/images/pokemon/variant/351_2.png and b/public/images/pokemon/variant/351_2.png differ diff --git a/public/images/pokemon/variant/351_3.png b/public/images/pokemon/variant/351_3.png index ba77333aa28..4e319855999 100644 Binary files a/public/images/pokemon/variant/351_3.png and b/public/images/pokemon/variant/351_3.png differ diff --git a/public/images/pokemon/variant/358_1.png b/public/images/pokemon/variant/358_1.png index 369b9828261..ddbe5e00908 100644 Binary files a/public/images/pokemon/variant/358_1.png and b/public/images/pokemon/variant/358_1.png differ diff --git a/public/images/pokemon/variant/35_3.png b/public/images/pokemon/variant/35_3.png index 90883d9b2b8..68a8194fa0d 100644 Binary files a/public/images/pokemon/variant/35_3.png and b/public/images/pokemon/variant/35_3.png differ diff --git a/public/images/pokemon/variant/362_2.png b/public/images/pokemon/variant/362_2.png index 1775f62a68f..3c21d176209 100644 Binary files a/public/images/pokemon/variant/362_2.png and b/public/images/pokemon/variant/362_2.png differ diff --git a/public/images/pokemon/variant/362_3.png b/public/images/pokemon/variant/362_3.png index 7b0d15894db..72b598a2d7b 100644 Binary files a/public/images/pokemon/variant/362_3.png and b/public/images/pokemon/variant/362_3.png differ diff --git a/public/images/pokemon/variant/373-mega_2.png b/public/images/pokemon/variant/373-mega_2.png index 2ddf5e07af5..ebde7060535 100644 Binary files a/public/images/pokemon/variant/373-mega_2.png and b/public/images/pokemon/variant/373-mega_2.png differ diff --git a/public/images/pokemon/variant/373-mega_3.png b/public/images/pokemon/variant/373-mega_3.png index 50cc1517a17..8fd93cbc0d2 100644 Binary files a/public/images/pokemon/variant/373-mega_3.png and b/public/images/pokemon/variant/373-mega_3.png differ diff --git a/public/images/pokemon/variant/384-mega_2.png b/public/images/pokemon/variant/384-mega_2.png index a834d31418c..370cea05f93 100644 Binary files a/public/images/pokemon/variant/384-mega_2.png and b/public/images/pokemon/variant/384-mega_2.png differ diff --git a/public/images/pokemon/variant/4080_1.png b/public/images/pokemon/variant/4080_1.png index 2508ea4c736..73ccbebdfa4 100644 Binary files a/public/images/pokemon/variant/4080_1.png and b/public/images/pokemon/variant/4080_1.png differ diff --git a/public/images/pokemon/variant/412-sandy_1.png b/public/images/pokemon/variant/412-sandy_1.png index d41a9cde14b..ec173a73749 100644 Binary files a/public/images/pokemon/variant/412-sandy_1.png and b/public/images/pokemon/variant/412-sandy_1.png differ diff --git a/public/images/pokemon/variant/412-sandy_2.png b/public/images/pokemon/variant/412-sandy_2.png index cd0ac94b35a..fb8d7724760 100644 Binary files a/public/images/pokemon/variant/412-sandy_2.png and b/public/images/pokemon/variant/412-sandy_2.png differ diff --git a/public/images/pokemon/variant/412-sandy_3.png b/public/images/pokemon/variant/412-sandy_3.png index f416fa6e46d..75ae220614c 100644 Binary files a/public/images/pokemon/variant/412-sandy_3.png and b/public/images/pokemon/variant/412-sandy_3.png differ diff --git a/public/images/pokemon/variant/413-plant_1.png b/public/images/pokemon/variant/413-plant_1.png index 367ee3bffee..59de20445ab 100644 Binary files a/public/images/pokemon/variant/413-plant_1.png and b/public/images/pokemon/variant/413-plant_1.png differ diff --git a/public/images/pokemon/variant/413-plant_2.png b/public/images/pokemon/variant/413-plant_2.png index 5b89b029bee..8e29a3b0549 100644 Binary files a/public/images/pokemon/variant/413-plant_2.png and b/public/images/pokemon/variant/413-plant_2.png differ diff --git a/public/images/pokemon/variant/413-plant_3.png b/public/images/pokemon/variant/413-plant_3.png index 21b9d30a5d5..cd0dc42bae1 100644 Binary files a/public/images/pokemon/variant/413-plant_3.png and b/public/images/pokemon/variant/413-plant_3.png differ diff --git a/public/images/pokemon/variant/4144_2.png b/public/images/pokemon/variant/4144_2.png index 873b08c4247..24453364a60 100644 Binary files a/public/images/pokemon/variant/4144_2.png and b/public/images/pokemon/variant/4144_2.png differ diff --git a/public/images/pokemon/variant/4144_3.png b/public/images/pokemon/variant/4144_3.png index 164e7dc0d25..5a55039463b 100644 Binary files a/public/images/pokemon/variant/4144_3.png and b/public/images/pokemon/variant/4144_3.png differ diff --git a/public/images/pokemon/variant/4199_1.png b/public/images/pokemon/variant/4199_1.png index e2fe544a480..85f535c8256 100644 Binary files a/public/images/pokemon/variant/4199_1.png and b/public/images/pokemon/variant/4199_1.png differ diff --git a/public/images/pokemon/variant/440_3.png b/public/images/pokemon/variant/440_3.png index 6c0086945e1..b6b8f2266fa 100644 Binary files a/public/images/pokemon/variant/440_3.png and b/public/images/pokemon/variant/440_3.png differ diff --git a/public/images/pokemon/variant/466_3.png b/public/images/pokemon/variant/466_3.png index 5267e3bf87a..146c4707a4f 100644 Binary files a/public/images/pokemon/variant/466_3.png and b/public/images/pokemon/variant/466_3.png differ diff --git a/public/images/pokemon/variant/469_2.png b/public/images/pokemon/variant/469_2.png index f7ea79b0509..82874a3978c 100644 Binary files a/public/images/pokemon/variant/469_2.png and b/public/images/pokemon/variant/469_2.png differ diff --git a/public/images/pokemon/variant/469_3.png b/public/images/pokemon/variant/469_3.png index 9c724123f37..a76d0d84f5c 100644 Binary files a/public/images/pokemon/variant/469_3.png and b/public/images/pokemon/variant/469_3.png differ diff --git a/public/images/pokemon/variant/471_2.png b/public/images/pokemon/variant/471_2.png index 62be05287c6..d93266b56db 100644 Binary files a/public/images/pokemon/variant/471_2.png and b/public/images/pokemon/variant/471_2.png differ diff --git a/public/images/pokemon/variant/471_3.png b/public/images/pokemon/variant/471_3.png index 0d2f5e2cfee..12df5891dc2 100644 Binary files a/public/images/pokemon/variant/471_3.png and b/public/images/pokemon/variant/471_3.png differ diff --git a/public/images/pokemon/variant/478_2.png b/public/images/pokemon/variant/478_2.png index 152b51b0b38..65131a6ecfa 100644 Binary files a/public/images/pokemon/variant/478_2.png and b/public/images/pokemon/variant/478_2.png differ diff --git a/public/images/pokemon/variant/492-land_2.png b/public/images/pokemon/variant/492-land_2.png index 823678f5a05..cf51ec294ab 100644 Binary files a/public/images/pokemon/variant/492-land_2.png and b/public/images/pokemon/variant/492-land_2.png differ diff --git a/public/images/pokemon/variant/526_2.png b/public/images/pokemon/variant/526_2.png index cf095fcc45b..68df77dd22d 100644 Binary files a/public/images/pokemon/variant/526_2.png and b/public/images/pokemon/variant/526_2.png differ diff --git a/public/images/pokemon/variant/526_3.png b/public/images/pokemon/variant/526_3.png index c365c379910..f347af32030 100644 Binary files a/public/images/pokemon/variant/526_3.png and b/public/images/pokemon/variant/526_3.png differ diff --git a/public/images/pokemon/variant/529_2.png b/public/images/pokemon/variant/529_2.png index 049f45bd07b..59e8dc11094 100644 Binary files a/public/images/pokemon/variant/529_2.png and b/public/images/pokemon/variant/529_2.png differ diff --git a/public/images/pokemon/variant/529_3.png b/public/images/pokemon/variant/529_3.png index de34a2b8cd2..ad7c95bbcc2 100644 Binary files a/public/images/pokemon/variant/529_3.png and b/public/images/pokemon/variant/529_3.png differ diff --git a/public/images/pokemon/variant/530_2.png b/public/images/pokemon/variant/530_2.png index 00e9c7b2103..2fb768d6df4 100644 Binary files a/public/images/pokemon/variant/530_2.png and b/public/images/pokemon/variant/530_2.png differ diff --git a/public/images/pokemon/variant/530_3.png b/public/images/pokemon/variant/530_3.png index 6772ad1ea1c..f92b642163c 100644 Binary files a/public/images/pokemon/variant/530_3.png and b/public/images/pokemon/variant/530_3.png differ diff --git a/public/images/pokemon/variant/539_2.png b/public/images/pokemon/variant/539_2.png index 7db9919d8b5..7b738217ed4 100644 Binary files a/public/images/pokemon/variant/539_2.png and b/public/images/pokemon/variant/539_2.png differ diff --git a/public/images/pokemon/variant/539_3.png b/public/images/pokemon/variant/539_3.png index 9b025a27e9f..8f581d1348e 100644 Binary files a/public/images/pokemon/variant/539_3.png and b/public/images/pokemon/variant/539_3.png differ diff --git a/public/images/pokemon/variant/543_3.png b/public/images/pokemon/variant/543_3.png index f10317e806d..7877d5e39b4 100644 Binary files a/public/images/pokemon/variant/543_3.png and b/public/images/pokemon/variant/543_3.png differ diff --git a/public/images/pokemon/variant/544_3.png b/public/images/pokemon/variant/544_3.png index 921a667741d..a0d810c4a29 100644 Binary files a/public/images/pokemon/variant/544_3.png and b/public/images/pokemon/variant/544_3.png differ diff --git a/public/images/pokemon/variant/549_3.png b/public/images/pokemon/variant/549_3.png index b7f2244e373..fffb5b9848a 100644 Binary files a/public/images/pokemon/variant/549_3.png and b/public/images/pokemon/variant/549_3.png differ diff --git a/public/images/pokemon/variant/568_2.png b/public/images/pokemon/variant/568_2.png index ed4c0d50ead..5ec25e6e8a6 100644 Binary files a/public/images/pokemon/variant/568_2.png and b/public/images/pokemon/variant/568_2.png differ diff --git a/public/images/pokemon/variant/568_3.png b/public/images/pokemon/variant/568_3.png index d499797bc92..cc991834a42 100644 Binary files a/public/images/pokemon/variant/568_3.png and b/public/images/pokemon/variant/568_3.png differ diff --git a/public/images/pokemon/variant/56_2.png b/public/images/pokemon/variant/56_2.png index a4d69550157..8f9b8f258e1 100644 Binary files a/public/images/pokemon/variant/56_2.png and b/public/images/pokemon/variant/56_2.png differ diff --git a/public/images/pokemon/variant/56_3.png b/public/images/pokemon/variant/56_3.png index 0c056ccdac9..ee5508c861a 100644 Binary files a/public/images/pokemon/variant/56_3.png and b/public/images/pokemon/variant/56_3.png differ diff --git a/public/images/pokemon/variant/57_1.png b/public/images/pokemon/variant/57_1.png index 73db688c129..8ea65328703 100644 Binary files a/public/images/pokemon/variant/57_1.png and b/public/images/pokemon/variant/57_1.png differ diff --git a/public/images/pokemon/variant/57_2.png b/public/images/pokemon/variant/57_2.png index b2edfa6cea7..6786b956a3c 100644 Binary files a/public/images/pokemon/variant/57_2.png and b/public/images/pokemon/variant/57_2.png differ diff --git a/public/images/pokemon/variant/57_3.png b/public/images/pokemon/variant/57_3.png index 9ec02aa03a9..720ad1f3529 100644 Binary files a/public/images/pokemon/variant/57_3.png and b/public/images/pokemon/variant/57_3.png differ diff --git a/public/images/pokemon/variant/585-autumn_1.png b/public/images/pokemon/variant/585-autumn_1.png index bc5c1424226..8edc0f0f152 100644 Binary files a/public/images/pokemon/variant/585-autumn_1.png and b/public/images/pokemon/variant/585-autumn_1.png differ diff --git a/public/images/pokemon/variant/585-spring_1.png b/public/images/pokemon/variant/585-spring_1.png index 1f154916dcd..7ab83601cf6 100644 Binary files a/public/images/pokemon/variant/585-spring_1.png and b/public/images/pokemon/variant/585-spring_1.png differ diff --git a/public/images/pokemon/variant/585-summer_1.png b/public/images/pokemon/variant/585-summer_1.png index 59b40b7bfef..e4204ea7dd8 100644 Binary files a/public/images/pokemon/variant/585-summer_1.png and b/public/images/pokemon/variant/585-summer_1.png differ diff --git a/public/images/pokemon/variant/585-winter_1.png b/public/images/pokemon/variant/585-winter_1.png index b296e059d1c..e5a0993319c 100644 Binary files a/public/images/pokemon/variant/585-winter_1.png and b/public/images/pokemon/variant/585-winter_1.png differ diff --git a/public/images/pokemon/variant/592_3.png b/public/images/pokemon/variant/592_3.png index e7694c4c5cf..aaded0d9d7e 100644 Binary files a/public/images/pokemon/variant/592_3.png and b/public/images/pokemon/variant/592_3.png differ diff --git a/public/images/pokemon/variant/594_3.png b/public/images/pokemon/variant/594_3.png index 5db7ef43b86..91f730c416f 100644 Binary files a/public/images/pokemon/variant/594_3.png and b/public/images/pokemon/variant/594_3.png differ diff --git a/public/images/pokemon/variant/631_2.png b/public/images/pokemon/variant/631_2.png index 846ab3c59b5..e2f0d2b9252 100644 Binary files a/public/images/pokemon/variant/631_2.png and b/public/images/pokemon/variant/631_2.png differ diff --git a/public/images/pokemon/variant/631_3.png b/public/images/pokemon/variant/631_3.png index bd271ebda23..4bcb055fbe5 100644 Binary files a/public/images/pokemon/variant/631_3.png and b/public/images/pokemon/variant/631_3.png differ diff --git a/public/images/pokemon/variant/666-continental_3.png b/public/images/pokemon/variant/666-continental_3.png index 8052f0360f5..24e4c9ab37c 100644 Binary files a/public/images/pokemon/variant/666-continental_3.png and b/public/images/pokemon/variant/666-continental_3.png differ diff --git a/public/images/pokemon/variant/666-fancy_2.png b/public/images/pokemon/variant/666-fancy_2.png index 68e535cf3a1..100ba90d7e4 100644 Binary files a/public/images/pokemon/variant/666-fancy_2.png and b/public/images/pokemon/variant/666-fancy_2.png differ diff --git a/public/images/pokemon/variant/666-fancy_3.png b/public/images/pokemon/variant/666-fancy_3.png index 2accdb4f486..a8453d6cbce 100644 Binary files a/public/images/pokemon/variant/666-fancy_3.png and b/public/images/pokemon/variant/666-fancy_3.png differ diff --git a/public/images/pokemon/variant/666-poke-ball_3.png b/public/images/pokemon/variant/666-poke-ball_3.png index 64a072a7cbe..e6056246fce 100644 Binary files a/public/images/pokemon/variant/666-poke-ball_3.png and b/public/images/pokemon/variant/666-poke-ball_3.png differ diff --git a/public/images/pokemon/variant/666-river_2.png b/public/images/pokemon/variant/666-river_2.png index 9b02df92a91..a5a65f4933b 100644 Binary files a/public/images/pokemon/variant/666-river_2.png and b/public/images/pokemon/variant/666-river_2.png differ diff --git a/public/images/pokemon/variant/669-blue_2.png b/public/images/pokemon/variant/669-blue_2.png index b2f9ac59598..32ecda80b8d 100644 Binary files a/public/images/pokemon/variant/669-blue_2.png and b/public/images/pokemon/variant/669-blue_2.png differ diff --git a/public/images/pokemon/variant/669-blue_3.png b/public/images/pokemon/variant/669-blue_3.png index 8cc36b72d06..8ce437a4442 100644 Binary files a/public/images/pokemon/variant/669-blue_3.png and b/public/images/pokemon/variant/669-blue_3.png differ diff --git a/public/images/pokemon/variant/669-orange_2.png b/public/images/pokemon/variant/669-orange_2.png index 3131bba78ea..fe6a2ccbf7d 100644 Binary files a/public/images/pokemon/variant/669-orange_2.png and b/public/images/pokemon/variant/669-orange_2.png differ diff --git a/public/images/pokemon/variant/669-red_2.png b/public/images/pokemon/variant/669-red_2.png index b898c298fbf..5d30b38b1d4 100644 Binary files a/public/images/pokemon/variant/669-red_2.png and b/public/images/pokemon/variant/669-red_2.png differ diff --git a/public/images/pokemon/variant/669-yellow_2.png b/public/images/pokemon/variant/669-yellow_2.png index 37e8d8726a9..5811dfd493b 100644 Binary files a/public/images/pokemon/variant/669-yellow_2.png and b/public/images/pokemon/variant/669-yellow_2.png differ diff --git a/public/images/pokemon/variant/670-blue_2.png b/public/images/pokemon/variant/670-blue_2.png index 1362ccbd2e5..73e797d7c28 100644 Binary files a/public/images/pokemon/variant/670-blue_2.png and b/public/images/pokemon/variant/670-blue_2.png differ diff --git a/public/images/pokemon/variant/670-blue_3.png b/public/images/pokemon/variant/670-blue_3.png index 881ca7f208f..e9f9322eaf1 100644 Binary files a/public/images/pokemon/variant/670-blue_3.png and b/public/images/pokemon/variant/670-blue_3.png differ diff --git a/public/images/pokemon/variant/670-orange_2.png b/public/images/pokemon/variant/670-orange_2.png index 80ccbdf030a..1144b3deb5e 100644 Binary files a/public/images/pokemon/variant/670-orange_2.png and b/public/images/pokemon/variant/670-orange_2.png differ diff --git a/public/images/pokemon/variant/670-orange_3.png b/public/images/pokemon/variant/670-orange_3.png index 0c579de4ed8..585031e7c26 100644 Binary files a/public/images/pokemon/variant/670-orange_3.png and b/public/images/pokemon/variant/670-orange_3.png differ diff --git a/public/images/pokemon/variant/670-red_2.png b/public/images/pokemon/variant/670-red_2.png index 7c7618848b9..5a53a3fc8a1 100644 Binary files a/public/images/pokemon/variant/670-red_2.png and b/public/images/pokemon/variant/670-red_2.png differ diff --git a/public/images/pokemon/variant/670-red_3.png b/public/images/pokemon/variant/670-red_3.png index 95bea559c8d..4774c9e8012 100644 Binary files a/public/images/pokemon/variant/670-red_3.png and b/public/images/pokemon/variant/670-red_3.png differ diff --git a/public/images/pokemon/variant/670-white_2.png b/public/images/pokemon/variant/670-white_2.png index 303905201d8..f5cdefbeef6 100644 Binary files a/public/images/pokemon/variant/670-white_2.png and b/public/images/pokemon/variant/670-white_2.png differ diff --git a/public/images/pokemon/variant/670-white_3.png b/public/images/pokemon/variant/670-white_3.png index ce9479353f4..051eea69c8f 100644 Binary files a/public/images/pokemon/variant/670-white_3.png and b/public/images/pokemon/variant/670-white_3.png differ diff --git a/public/images/pokemon/variant/670-yellow_2.png b/public/images/pokemon/variant/670-yellow_2.png index e1866464222..9a02754ed75 100644 Binary files a/public/images/pokemon/variant/670-yellow_2.png and b/public/images/pokemon/variant/670-yellow_2.png differ diff --git a/public/images/pokemon/variant/670-yellow_3.png b/public/images/pokemon/variant/670-yellow_3.png index af6e6d83f43..86464b7c97e 100644 Binary files a/public/images/pokemon/variant/670-yellow_3.png and b/public/images/pokemon/variant/670-yellow_3.png differ diff --git a/public/images/pokemon/variant/671-blue_3.png b/public/images/pokemon/variant/671-blue_3.png index 8d755b76a7c..fb57dab589e 100644 Binary files a/public/images/pokemon/variant/671-blue_3.png and b/public/images/pokemon/variant/671-blue_3.png differ diff --git a/public/images/pokemon/variant/671-red_3.png b/public/images/pokemon/variant/671-red_3.png index ad3656d2b62..9daddb10dc1 100644 Binary files a/public/images/pokemon/variant/671-red_3.png and b/public/images/pokemon/variant/671-red_3.png differ diff --git a/public/images/pokemon/variant/671-white_3.png b/public/images/pokemon/variant/671-white_3.png index bab8091ae50..3c024e09b8d 100644 Binary files a/public/images/pokemon/variant/671-white_3.png and b/public/images/pokemon/variant/671-white_3.png differ diff --git a/public/images/pokemon/variant/671-yellow_3.png b/public/images/pokemon/variant/671-yellow_3.png index f518af40869..dab7a758d81 100644 Binary files a/public/images/pokemon/variant/671-yellow_3.png and b/public/images/pokemon/variant/671-yellow_3.png differ diff --git a/public/images/pokemon/variant/672_3.png b/public/images/pokemon/variant/672_3.png index 47e1401b99f..02d2fe283b9 100644 Binary files a/public/images/pokemon/variant/672_3.png and b/public/images/pokemon/variant/672_3.png differ diff --git a/public/images/pokemon/variant/696_3.png b/public/images/pokemon/variant/696_3.png index d053158281d..6eab4cd29b3 100644 Binary files a/public/images/pokemon/variant/696_3.png and b/public/images/pokemon/variant/696_3.png differ diff --git a/public/images/pokemon/variant/697_3.png b/public/images/pokemon/variant/697_3.png index c6dbd843eb0..055f35c71e0 100644 Binary files a/public/images/pokemon/variant/697_3.png and b/public/images/pokemon/variant/697_3.png differ diff --git a/public/images/pokemon/variant/69_2.png b/public/images/pokemon/variant/69_2.png index 2f2a713de27..8ed462e7c9b 100644 Binary files a/public/images/pokemon/variant/69_2.png and b/public/images/pokemon/variant/69_2.png differ diff --git a/public/images/pokemon/variant/69_3.png b/public/images/pokemon/variant/69_3.png index 537d1379e1b..6e37bdf8c33 100644 Binary files a/public/images/pokemon/variant/69_3.png and b/public/images/pokemon/variant/69_3.png differ diff --git a/public/images/pokemon/variant/715_2.png b/public/images/pokemon/variant/715_2.png index 33534d0e77e..fe80cacfd31 100644 Binary files a/public/images/pokemon/variant/715_2.png and b/public/images/pokemon/variant/715_2.png differ diff --git a/public/images/pokemon/variant/715_3.png b/public/images/pokemon/variant/715_3.png index 77b4b1d5006..e48057a11ff 100644 Binary files a/public/images/pokemon/variant/715_3.png and b/public/images/pokemon/variant/715_3.png differ diff --git a/public/images/pokemon/variant/742_2.png b/public/images/pokemon/variant/742_2.png index 43103181126..32dc5593c55 100644 Binary files a/public/images/pokemon/variant/742_2.png and b/public/images/pokemon/variant/742_2.png differ diff --git a/public/images/pokemon/variant/742_3.png b/public/images/pokemon/variant/742_3.png index 88002632e61..599b1598002 100644 Binary files a/public/images/pokemon/variant/742_3.png and b/public/images/pokemon/variant/742_3.png differ diff --git a/public/images/pokemon/variant/743_2.png b/public/images/pokemon/variant/743_2.png index fe5fbfae5d3..fb83af131eb 100644 Binary files a/public/images/pokemon/variant/743_2.png and b/public/images/pokemon/variant/743_2.png differ diff --git a/public/images/pokemon/variant/743_3.png b/public/images/pokemon/variant/743_3.png index 36a3ae6513b..7a36dc4f89c 100644 Binary files a/public/images/pokemon/variant/743_3.png and b/public/images/pokemon/variant/743_3.png differ diff --git a/public/images/pokemon/variant/756_3.png b/public/images/pokemon/variant/756_3.png index c9277b4e307..f4a072a1b2b 100644 Binary files a/public/images/pokemon/variant/756_3.png and b/public/images/pokemon/variant/756_3.png differ diff --git a/public/images/pokemon/variant/791_1.png b/public/images/pokemon/variant/791_1.png index d5ccdb14e90..719e1b34c59 100644 Binary files a/public/images/pokemon/variant/791_1.png and b/public/images/pokemon/variant/791_1.png differ diff --git a/public/images/pokemon/variant/7_2.png b/public/images/pokemon/variant/7_2.png index 13d2f17b641..63321bf71c2 100644 Binary files a/public/images/pokemon/variant/7_2.png and b/public/images/pokemon/variant/7_2.png differ diff --git a/public/images/pokemon/variant/7_3.png b/public/images/pokemon/variant/7_3.png index f15d95d100f..b4adaff2f54 100644 Binary files a/public/images/pokemon/variant/7_3.png and b/public/images/pokemon/variant/7_3.png differ diff --git a/public/images/pokemon/variant/823-gigantamax_2.png b/public/images/pokemon/variant/823-gigantamax_2.png index 9bd4dd183a3..eecb3695378 100644 Binary files a/public/images/pokemon/variant/823-gigantamax_2.png and b/public/images/pokemon/variant/823-gigantamax_2.png differ diff --git a/public/images/pokemon/variant/823-gigantamax_3.png b/public/images/pokemon/variant/823-gigantamax_3.png index 6e51618a272..0af4712fdf7 100644 Binary files a/public/images/pokemon/variant/823-gigantamax_3.png and b/public/images/pokemon/variant/823-gigantamax_3.png differ diff --git a/public/images/pokemon/variant/836_2.png b/public/images/pokemon/variant/836_2.png index 7f584eeb5ad..303975e7e58 100644 Binary files a/public/images/pokemon/variant/836_2.png and b/public/images/pokemon/variant/836_2.png differ diff --git a/public/images/pokemon/variant/836_3.png b/public/images/pokemon/variant/836_3.png index 22418aaee07..95ae2990ed2 100644 Binary files a/public/images/pokemon/variant/836_3.png and b/public/images/pokemon/variant/836_3.png differ diff --git a/public/images/pokemon/variant/83_3.png b/public/images/pokemon/variant/83_3.png index 8a2f0d763b1..eb6604c6299 100644 Binary files a/public/images/pokemon/variant/83_3.png and b/public/images/pokemon/variant/83_3.png differ diff --git a/public/images/pokemon/variant/857_2.png b/public/images/pokemon/variant/857_2.png index 6395590c758..9273ef2a097 100644 Binary files a/public/images/pokemon/variant/857_2.png and b/public/images/pokemon/variant/857_2.png differ diff --git a/public/images/pokemon/variant/857_3.png b/public/images/pokemon/variant/857_3.png index c2a1b95c337..dc3277bcc2c 100644 Binary files a/public/images/pokemon/variant/857_3.png and b/public/images/pokemon/variant/857_3.png differ diff --git a/public/images/pokemon/variant/859_2.png b/public/images/pokemon/variant/859_2.png index 111e51b0892..82e8be45c39 100644 Binary files a/public/images/pokemon/variant/859_2.png and b/public/images/pokemon/variant/859_2.png differ diff --git a/public/images/pokemon/variant/859_3.png b/public/images/pokemon/variant/859_3.png index 1c6888a0f95..800063f08aa 100644 Binary files a/public/images/pokemon/variant/859_3.png and b/public/images/pokemon/variant/859_3.png differ diff --git a/public/images/pokemon/variant/862_2.png b/public/images/pokemon/variant/862_2.png index d006a389c11..4c52d8a260f 100644 Binary files a/public/images/pokemon/variant/862_2.png and b/public/images/pokemon/variant/862_2.png differ diff --git a/public/images/pokemon/variant/862_3.png b/public/images/pokemon/variant/862_3.png index 1d9240d85e6..170ae08d72d 100644 Binary files a/public/images/pokemon/variant/862_3.png and b/public/images/pokemon/variant/862_3.png differ diff --git a/public/images/pokemon/variant/887_1.png b/public/images/pokemon/variant/887_1.png index 8348e95c664..505ac265740 100644 Binary files a/public/images/pokemon/variant/887_1.png and b/public/images/pokemon/variant/887_1.png differ diff --git a/public/images/pokemon/variant/890-eternamax_2.png b/public/images/pokemon/variant/890-eternamax_2.png index b5aab00c241..2327900b971 100644 Binary files a/public/images/pokemon/variant/890-eternamax_2.png and b/public/images/pokemon/variant/890-eternamax_2.png differ diff --git a/public/images/pokemon/variant/890-eternamax_3.png b/public/images/pokemon/variant/890-eternamax_3.png index 29a3d84c0d6..140837cfbd0 100644 Binary files a/public/images/pokemon/variant/890-eternamax_3.png and b/public/images/pokemon/variant/890-eternamax_3.png differ diff --git a/public/images/pokemon/variant/890_2.png b/public/images/pokemon/variant/890_2.png index 46d2a4590a4..936f13cb6b2 100644 Binary files a/public/images/pokemon/variant/890_2.png and b/public/images/pokemon/variant/890_2.png differ diff --git a/public/images/pokemon/variant/890_3.png b/public/images/pokemon/variant/890_3.png index 635272e7e17..683658d9b86 100644 Binary files a/public/images/pokemon/variant/890_3.png and b/public/images/pokemon/variant/890_3.png differ diff --git a/public/images/pokemon/variant/897_1.png b/public/images/pokemon/variant/897_1.png index 74e793e31fa..9519aadd702 100644 Binary files a/public/images/pokemon/variant/897_1.png and b/public/images/pokemon/variant/897_1.png differ diff --git a/public/images/pokemon/variant/8_2.png b/public/images/pokemon/variant/8_2.png index c65b2bf1aae..06067c8e4f2 100644 Binary files a/public/images/pokemon/variant/8_2.png and b/public/images/pokemon/variant/8_2.png differ diff --git a/public/images/pokemon/variant/8_3.png b/public/images/pokemon/variant/8_3.png index 55e8869cbc7..5c32863d7df 100644 Binary files a/public/images/pokemon/variant/8_3.png and b/public/images/pokemon/variant/8_3.png differ diff --git a/public/images/pokemon/variant/9-gigantamax_3.png b/public/images/pokemon/variant/9-gigantamax_3.png index 1a12ccc6f00..54819b05e7e 100644 Binary files a/public/images/pokemon/variant/9-gigantamax_3.png and b/public/images/pokemon/variant/9-gigantamax_3.png differ diff --git a/public/images/pokemon/variant/9-mega_2.png b/public/images/pokemon/variant/9-mega_2.png index c3c06c1eca7..0a56f1a3a68 100644 Binary files a/public/images/pokemon/variant/9-mega_2.png and b/public/images/pokemon/variant/9-mega_2.png differ diff --git a/public/images/pokemon/variant/9-mega_3.png b/public/images/pokemon/variant/9-mega_3.png index d7a4b6f9140..606f18d6337 100644 Binary files a/public/images/pokemon/variant/9-mega_3.png and b/public/images/pokemon/variant/9-mega_3.png differ diff --git a/public/images/pokemon/variant/909_2.png b/public/images/pokemon/variant/909_2.png index 87d636295f9..142d46abb95 100644 Binary files a/public/images/pokemon/variant/909_2.png and b/public/images/pokemon/variant/909_2.png differ diff --git a/public/images/pokemon/variant/909_3.png b/public/images/pokemon/variant/909_3.png index 9681aebe268..ec49f615edf 100644 Binary files a/public/images/pokemon/variant/909_3.png and b/public/images/pokemon/variant/909_3.png differ diff --git a/public/images/pokemon/variant/910_2.png b/public/images/pokemon/variant/910_2.png index 616d1380f64..14fcf13f9a9 100644 Binary files a/public/images/pokemon/variant/910_2.png and b/public/images/pokemon/variant/910_2.png differ diff --git a/public/images/pokemon/variant/910_3.png b/public/images/pokemon/variant/910_3.png index 5c5c051ecd5..8a9dfa4f8b0 100644 Binary files a/public/images/pokemon/variant/910_3.png and b/public/images/pokemon/variant/910_3.png differ diff --git a/public/images/pokemon/variant/913_2.png b/public/images/pokemon/variant/913_2.png index 0af21bab11c..ab5e42c3b73 100644 Binary files a/public/images/pokemon/variant/913_2.png and b/public/images/pokemon/variant/913_2.png differ diff --git a/public/images/pokemon/variant/913_3.png b/public/images/pokemon/variant/913_3.png index 42398fe12d6..3c29e2b8f91 100644 Binary files a/public/images/pokemon/variant/913_3.png and b/public/images/pokemon/variant/913_3.png differ diff --git a/public/images/pokemon/variant/914_2.png b/public/images/pokemon/variant/914_2.png index 672e45f026a..d1db92c1e8a 100644 Binary files a/public/images/pokemon/variant/914_2.png and b/public/images/pokemon/variant/914_2.png differ diff --git a/public/images/pokemon/variant/920_1.png b/public/images/pokemon/variant/920_1.png index 40d07ac6111..a0fcd5b4a7f 100644 Binary files a/public/images/pokemon/variant/920_1.png and b/public/images/pokemon/variant/920_1.png differ diff --git a/public/images/pokemon/variant/920_2.png b/public/images/pokemon/variant/920_2.png index ac8dc6ba169..71b9a3b7651 100644 Binary files a/public/images/pokemon/variant/920_2.png and b/public/images/pokemon/variant/920_2.png differ diff --git a/public/images/pokemon/variant/920_3.png b/public/images/pokemon/variant/920_3.png index b46cfe90aa6..0db8dad3cd9 100644 Binary files a/public/images/pokemon/variant/920_3.png and b/public/images/pokemon/variant/920_3.png differ diff --git a/public/images/pokemon/variant/92_1.png b/public/images/pokemon/variant/92_1.png index a47bf334486..23f4da8ef6a 100644 Binary files a/public/images/pokemon/variant/92_1.png and b/public/images/pokemon/variant/92_1.png differ diff --git a/public/images/pokemon/variant/92_2.png b/public/images/pokemon/variant/92_2.png index a6bff69023f..383151d9a72 100644 Binary files a/public/images/pokemon/variant/92_2.png and b/public/images/pokemon/variant/92_2.png differ diff --git a/public/images/pokemon/variant/92_3.png b/public/images/pokemon/variant/92_3.png index 4839b2d4ce6..38684540b9f 100644 Binary files a/public/images/pokemon/variant/92_3.png and b/public/images/pokemon/variant/92_3.png differ diff --git a/public/images/pokemon/variant/94-gigantamax_2.png b/public/images/pokemon/variant/94-gigantamax_2.png index 008536206d1..f47846e421d 100644 Binary files a/public/images/pokemon/variant/94-gigantamax_2.png and b/public/images/pokemon/variant/94-gigantamax_2.png differ diff --git a/public/images/pokemon/variant/94-gigantamax_3.png b/public/images/pokemon/variant/94-gigantamax_3.png index 91247d2373b..bd571698edc 100644 Binary files a/public/images/pokemon/variant/94-gigantamax_3.png and b/public/images/pokemon/variant/94-gigantamax_3.png differ diff --git a/public/images/pokemon/variant/94-mega_1.png b/public/images/pokemon/variant/94-mega_1.png index 5484a0b7f61..c1b560477ac 100644 Binary files a/public/images/pokemon/variant/94-mega_1.png and b/public/images/pokemon/variant/94-mega_1.png differ diff --git a/public/images/pokemon/variant/94-mega_2.png b/public/images/pokemon/variant/94-mega_2.png index 12890419db2..79329baa6e9 100644 Binary files a/public/images/pokemon/variant/94-mega_2.png and b/public/images/pokemon/variant/94-mega_2.png differ diff --git a/public/images/pokemon/variant/94-mega_3.png b/public/images/pokemon/variant/94-mega_3.png index 7abb2c15a6f..0df495494b4 100644 Binary files a/public/images/pokemon/variant/94-mega_3.png and b/public/images/pokemon/variant/94-mega_3.png differ diff --git a/public/images/pokemon/variant/968_2.png b/public/images/pokemon/variant/968_2.png index 73a91ca6913..45c8f6b260a 100644 Binary files a/public/images/pokemon/variant/968_2.png and b/public/images/pokemon/variant/968_2.png differ diff --git a/public/images/pokemon/variant/968_3.png b/public/images/pokemon/variant/968_3.png index 10e4f06fc3f..73c87fbe249 100644 Binary files a/public/images/pokemon/variant/968_3.png and b/public/images/pokemon/variant/968_3.png differ diff --git a/public/images/pokemon/variant/973_1.png b/public/images/pokemon/variant/973_1.png index 38cdfed1b5a..bbf65d9d7fa 100644 Binary files a/public/images/pokemon/variant/973_1.png and b/public/images/pokemon/variant/973_1.png differ diff --git a/public/images/pokemon/variant/973_2.png b/public/images/pokemon/variant/973_2.png index 0e0ed775104..bbebe06afb0 100644 Binary files a/public/images/pokemon/variant/973_2.png and b/public/images/pokemon/variant/973_2.png differ diff --git a/public/images/pokemon/variant/973_3.png b/public/images/pokemon/variant/973_3.png index 07c09415b98..2f90e0cdbee 100644 Binary files a/public/images/pokemon/variant/973_3.png and b/public/images/pokemon/variant/973_3.png differ diff --git a/public/images/pokemon/variant/975_2.png b/public/images/pokemon/variant/975_2.png index a122990f639..bc174f1c824 100644 Binary files a/public/images/pokemon/variant/975_2.png and b/public/images/pokemon/variant/975_2.png differ diff --git a/public/images/pokemon/variant/975_3.png b/public/images/pokemon/variant/975_3.png index e1cb9773902..218ad884dde 100644 Binary files a/public/images/pokemon/variant/975_3.png and b/public/images/pokemon/variant/975_3.png differ diff --git a/public/images/pokemon/variant/978-curly_2.png b/public/images/pokemon/variant/978-curly_2.png index d579278625f..d29314bd6ea 100644 Binary files a/public/images/pokemon/variant/978-curly_2.png and b/public/images/pokemon/variant/978-curly_2.png differ diff --git a/public/images/pokemon/variant/978-curly_3.png b/public/images/pokemon/variant/978-curly_3.png index 7bc73280dc3..5e811b4ae7d 100644 Binary files a/public/images/pokemon/variant/978-curly_3.png and b/public/images/pokemon/variant/978-curly_3.png differ diff --git a/public/images/pokemon/variant/978-droopy_2.png b/public/images/pokemon/variant/978-droopy_2.png index 4241c9009cc..cd7759606a4 100644 Binary files a/public/images/pokemon/variant/978-droopy_2.png and b/public/images/pokemon/variant/978-droopy_2.png differ diff --git a/public/images/pokemon/variant/978-droopy_3.png b/public/images/pokemon/variant/978-droopy_3.png index b7f2429b04f..d9cf0f0800d 100644 Binary files a/public/images/pokemon/variant/978-droopy_3.png and b/public/images/pokemon/variant/978-droopy_3.png differ diff --git a/public/images/pokemon/variant/978-stretchy_2.png b/public/images/pokemon/variant/978-stretchy_2.png index 786dc3ec254..07f9b62e2e7 100644 Binary files a/public/images/pokemon/variant/978-stretchy_2.png and b/public/images/pokemon/variant/978-stretchy_2.png differ diff --git a/public/images/pokemon/variant/978-stretchy_3.png b/public/images/pokemon/variant/978-stretchy_3.png index 428aa8c9c91..d1686831e1d 100644 Binary files a/public/images/pokemon/variant/978-stretchy_3.png and b/public/images/pokemon/variant/978-stretchy_3.png differ diff --git a/public/images/pokemon/variant/979_1.png b/public/images/pokemon/variant/979_1.png index 01216516c57..352783875e4 100644 Binary files a/public/images/pokemon/variant/979_1.png and b/public/images/pokemon/variant/979_1.png differ diff --git a/public/images/pokemon/variant/979_2.png b/public/images/pokemon/variant/979_2.png index 52828c62f1e..b7111102ed9 100644 Binary files a/public/images/pokemon/variant/979_2.png and b/public/images/pokemon/variant/979_2.png differ diff --git a/public/images/pokemon/variant/979_3.png b/public/images/pokemon/variant/979_3.png index ed4407c2a38..2b187754cea 100644 Binary files a/public/images/pokemon/variant/979_3.png and b/public/images/pokemon/variant/979_3.png differ diff --git a/public/images/pokemon/variant/9_2.png b/public/images/pokemon/variant/9_2.png index 216d1423374..a31ea1e073e 100644 Binary files a/public/images/pokemon/variant/9_2.png and b/public/images/pokemon/variant/9_2.png differ diff --git a/public/images/pokemon/variant/9_3.png b/public/images/pokemon/variant/9_3.png index 0f1bce73356..5ef7a8d739e 100644 Binary files a/public/images/pokemon/variant/9_3.png and b/public/images/pokemon/variant/9_3.png differ diff --git a/public/images/pokemon/variant/back/1022_2.png b/public/images/pokemon/variant/back/1022_2.png index 4a59f687da2..cdd94da0af6 100644 Binary files a/public/images/pokemon/variant/back/1022_2.png and b/public/images/pokemon/variant/back/1022_2.png differ diff --git a/public/images/pokemon/variant/back/1022_3.png b/public/images/pokemon/variant/back/1022_3.png index 846ecdd4f73..2d5df98da9d 100644 Binary files a/public/images/pokemon/variant/back/1022_3.png and b/public/images/pokemon/variant/back/1022_3.png differ diff --git a/public/images/pokemon/variant/back/125_3.png b/public/images/pokemon/variant/back/125_3.png index eef852c92e7..68e9503d1cb 100644 Binary files a/public/images/pokemon/variant/back/125_3.png and b/public/images/pokemon/variant/back/125_3.png differ diff --git a/public/images/pokemon/variant/back/126_2.png b/public/images/pokemon/variant/back/126_2.png index 9f22780f1d8..016cb367db3 100644 Binary files a/public/images/pokemon/variant/back/126_2.png and b/public/images/pokemon/variant/back/126_2.png differ diff --git a/public/images/pokemon/variant/back/180_3.png b/public/images/pokemon/variant/back/180_3.png index 82d8d9c0c68..0cf0357f3c0 100644 Binary files a/public/images/pokemon/variant/back/180_3.png and b/public/images/pokemon/variant/back/180_3.png differ diff --git a/public/images/pokemon/variant/back/181-mega_3.png b/public/images/pokemon/variant/back/181-mega_3.png index 5d30a156cbc..17832724081 100644 Binary files a/public/images/pokemon/variant/back/181-mega_3.png and b/public/images/pokemon/variant/back/181-mega_3.png differ diff --git a/public/images/pokemon/variant/back/199_1.png b/public/images/pokemon/variant/back/199_1.png index 004346df151..66d6fa0a4d7 100644 Binary files a/public/images/pokemon/variant/back/199_1.png and b/public/images/pokemon/variant/back/199_1.png differ diff --git a/public/images/pokemon/variant/back/200_2.png b/public/images/pokemon/variant/back/200_2.png index 0702c2596e1..ef296028bb0 100644 Binary files a/public/images/pokemon/variant/back/200_2.png and b/public/images/pokemon/variant/back/200_2.png differ diff --git a/public/images/pokemon/variant/back/200_3.png b/public/images/pokemon/variant/back/200_3.png index 0f7b4a5fd05..f707e04ea86 100644 Binary files a/public/images/pokemon/variant/back/200_3.png and b/public/images/pokemon/variant/back/200_3.png differ diff --git a/public/images/pokemon/variant/back/212-mega_2.png b/public/images/pokemon/variant/back/212-mega_2.png index adf745f6851..d066510353d 100644 Binary files a/public/images/pokemon/variant/back/212-mega_2.png and b/public/images/pokemon/variant/back/212-mega_2.png differ diff --git a/public/images/pokemon/variant/back/212-mega_3.png b/public/images/pokemon/variant/back/212-mega_3.png index 0cfead081c4..f3c4e5bd110 100644 Binary files a/public/images/pokemon/variant/back/212-mega_3.png and b/public/images/pokemon/variant/back/212-mega_3.png differ diff --git a/public/images/pokemon/variant/back/212_2.png b/public/images/pokemon/variant/back/212_2.png index 9f325d62aa9..7a24be11f16 100644 Binary files a/public/images/pokemon/variant/back/212_2.png and b/public/images/pokemon/variant/back/212_2.png differ diff --git a/public/images/pokemon/variant/back/212_3.png b/public/images/pokemon/variant/back/212_3.png index d06a89140c7..a22f1a9d38e 100644 Binary files a/public/images/pokemon/variant/back/212_3.png and b/public/images/pokemon/variant/back/212_3.png differ diff --git a/public/images/pokemon/variant/back/239_3.png b/public/images/pokemon/variant/back/239_3.png index 02a680ff5a7..b5ce88685a7 100644 Binary files a/public/images/pokemon/variant/back/239_3.png and b/public/images/pokemon/variant/back/239_3.png differ diff --git a/public/images/pokemon/variant/back/244_2.png b/public/images/pokemon/variant/back/244_2.png index 6244b6eb74c..968b5c325bd 100644 Binary files a/public/images/pokemon/variant/back/244_2.png and b/public/images/pokemon/variant/back/244_2.png differ diff --git a/public/images/pokemon/variant/back/244_3.png b/public/images/pokemon/variant/back/244_3.png index 7e04e3d6086..323b9a6b337 100644 Binary files a/public/images/pokemon/variant/back/244_3.png and b/public/images/pokemon/variant/back/244_3.png differ diff --git a/public/images/pokemon/variant/back/291_1.png b/public/images/pokemon/variant/back/291_1.png index dad69ed24af..a465af75920 100644 Binary files a/public/images/pokemon/variant/back/291_1.png and b/public/images/pokemon/variant/back/291_1.png differ diff --git a/public/images/pokemon/variant/back/291_2.png b/public/images/pokemon/variant/back/291_2.png index d3005597f60..6eafa03d9d5 100644 Binary files a/public/images/pokemon/variant/back/291_2.png and b/public/images/pokemon/variant/back/291_2.png differ diff --git a/public/images/pokemon/variant/back/291_3.png b/public/images/pokemon/variant/back/291_3.png index 9c62398a5fc..98c0d6c6b63 100644 Binary files a/public/images/pokemon/variant/back/291_3.png and b/public/images/pokemon/variant/back/291_3.png differ diff --git a/public/images/pokemon/variant/back/292_1.png b/public/images/pokemon/variant/back/292_1.png index ae99178d90a..4625db861b3 100644 Binary files a/public/images/pokemon/variant/back/292_1.png and b/public/images/pokemon/variant/back/292_1.png differ diff --git a/public/images/pokemon/variant/back/292_2.png b/public/images/pokemon/variant/back/292_2.png index fc3d4090a1d..c773f10b69d 100644 Binary files a/public/images/pokemon/variant/back/292_2.png and b/public/images/pokemon/variant/back/292_2.png differ diff --git a/public/images/pokemon/variant/back/292_3.png b/public/images/pokemon/variant/back/292_3.png index 1ebe95bb1b5..164d583eb43 100644 Binary files a/public/images/pokemon/variant/back/292_3.png and b/public/images/pokemon/variant/back/292_3.png differ diff --git a/public/images/pokemon/variant/back/3-mega_2.png b/public/images/pokemon/variant/back/3-mega_2.png index 52f8ed7b580..7bb201ef984 100644 Binary files a/public/images/pokemon/variant/back/3-mega_2.png and b/public/images/pokemon/variant/back/3-mega_2.png differ diff --git a/public/images/pokemon/variant/back/3-mega_3.png b/public/images/pokemon/variant/back/3-mega_3.png index 9d964688f14..5d7fb8ad798 100644 Binary files a/public/images/pokemon/variant/back/3-mega_3.png and b/public/images/pokemon/variant/back/3-mega_3.png differ diff --git a/public/images/pokemon/variant/back/335_2.png b/public/images/pokemon/variant/back/335_2.png index e21955c3033..5e23f357767 100644 Binary files a/public/images/pokemon/variant/back/335_2.png and b/public/images/pokemon/variant/back/335_2.png differ diff --git a/public/images/pokemon/variant/back/335_3.png b/public/images/pokemon/variant/back/335_3.png index 3ccd19f715f..407413dca23 100644 Binary files a/public/images/pokemon/variant/back/335_3.png and b/public/images/pokemon/variant/back/335_3.png differ diff --git a/public/images/pokemon/variant/back/339_2.png b/public/images/pokemon/variant/back/339_2.png index 77dc5e5e936..ceed75f36f6 100644 Binary files a/public/images/pokemon/variant/back/339_2.png and b/public/images/pokemon/variant/back/339_2.png differ diff --git a/public/images/pokemon/variant/back/340_3.png b/public/images/pokemon/variant/back/340_3.png index 6d0b7ab033a..771b424564b 100644 Binary files a/public/images/pokemon/variant/back/340_3.png and b/public/images/pokemon/variant/back/340_3.png differ diff --git a/public/images/pokemon/variant/back/342_2.png b/public/images/pokemon/variant/back/342_2.png index 6238027c434..d5138c51fcf 100644 Binary files a/public/images/pokemon/variant/back/342_2.png and b/public/images/pokemon/variant/back/342_2.png differ diff --git a/public/images/pokemon/variant/back/342_3.png b/public/images/pokemon/variant/back/342_3.png index d68f7fd40e8..af788f45bfa 100644 Binary files a/public/images/pokemon/variant/back/342_3.png and b/public/images/pokemon/variant/back/342_3.png differ diff --git a/public/images/pokemon/variant/back/351-sunny_3.png b/public/images/pokemon/variant/back/351-sunny_3.png index 66f1536eb84..059b85417e1 100644 Binary files a/public/images/pokemon/variant/back/351-sunny_3.png and b/public/images/pokemon/variant/back/351-sunny_3.png differ diff --git a/public/images/pokemon/variant/back/369_2.png b/public/images/pokemon/variant/back/369_2.png index 8510afc4eb4..62b37b70738 100644 Binary files a/public/images/pokemon/variant/back/369_2.png and b/public/images/pokemon/variant/back/369_2.png differ diff --git a/public/images/pokemon/variant/back/369_3.png b/public/images/pokemon/variant/back/369_3.png index 165b5ad0199..69cedd6571c 100644 Binary files a/public/images/pokemon/variant/back/369_3.png and b/public/images/pokemon/variant/back/369_3.png differ diff --git a/public/images/pokemon/variant/back/36_2.png b/public/images/pokemon/variant/back/36_2.png index 8b7bb25cc59..f30397b482f 100644 Binary files a/public/images/pokemon/variant/back/36_2.png and b/public/images/pokemon/variant/back/36_2.png differ diff --git a/public/images/pokemon/variant/back/370_2.png b/public/images/pokemon/variant/back/370_2.png index 48e7d90585f..32d49cd89a3 100644 Binary files a/public/images/pokemon/variant/back/370_2.png and b/public/images/pokemon/variant/back/370_2.png differ diff --git a/public/images/pokemon/variant/back/370_3.png b/public/images/pokemon/variant/back/370_3.png index f5a0768f26b..f20b119f333 100644 Binary files a/public/images/pokemon/variant/back/370_3.png and b/public/images/pokemon/variant/back/370_3.png differ diff --git a/public/images/pokemon/variant/back/383_2.png b/public/images/pokemon/variant/back/383_2.png index 98ac154832f..9c280b56dd7 100644 Binary files a/public/images/pokemon/variant/back/383_2.png and b/public/images/pokemon/variant/back/383_2.png differ diff --git a/public/images/pokemon/variant/back/383_3.png b/public/images/pokemon/variant/back/383_3.png index f8856a6aa2d..b754d969e4a 100644 Binary files a/public/images/pokemon/variant/back/383_3.png and b/public/images/pokemon/variant/back/383_3.png differ diff --git a/public/images/pokemon/variant/back/387_2.png b/public/images/pokemon/variant/back/387_2.png index d55cb1c5384..00c947db821 100644 Binary files a/public/images/pokemon/variant/back/387_2.png and b/public/images/pokemon/variant/back/387_2.png differ diff --git a/public/images/pokemon/variant/back/399_2.png b/public/images/pokemon/variant/back/399_2.png index 55ab33679cb..b71497f9ccf 100644 Binary files a/public/images/pokemon/variant/back/399_2.png and b/public/images/pokemon/variant/back/399_2.png differ diff --git a/public/images/pokemon/variant/back/4080_1.png b/public/images/pokemon/variant/back/4080_1.png index 7f6ba3be1c4..885cd8b2c54 100644 Binary files a/public/images/pokemon/variant/back/4080_1.png and b/public/images/pokemon/variant/back/4080_1.png differ diff --git a/public/images/pokemon/variant/back/412-sandy_1.png b/public/images/pokemon/variant/back/412-sandy_1.png index 9dcd4798761..a8988e8ab22 100644 Binary files a/public/images/pokemon/variant/back/412-sandy_1.png and b/public/images/pokemon/variant/back/412-sandy_1.png differ diff --git a/public/images/pokemon/variant/back/412-sandy_2.png b/public/images/pokemon/variant/back/412-sandy_2.png index de7c581bb73..730e0896c92 100644 Binary files a/public/images/pokemon/variant/back/412-sandy_2.png and b/public/images/pokemon/variant/back/412-sandy_2.png differ diff --git a/public/images/pokemon/variant/back/412-sandy_3.png b/public/images/pokemon/variant/back/412-sandy_3.png index 46022a40775..bf2f2f0b94a 100644 Binary files a/public/images/pokemon/variant/back/412-sandy_3.png and b/public/images/pokemon/variant/back/412-sandy_3.png differ diff --git a/public/images/pokemon/variant/back/4199_1.png b/public/images/pokemon/variant/back/4199_1.png index daaac5a6448..45b81fb3413 100644 Binary files a/public/images/pokemon/variant/back/4199_1.png and b/public/images/pokemon/variant/back/4199_1.png differ diff --git a/public/images/pokemon/variant/back/441_3.png b/public/images/pokemon/variant/back/441_3.png index 271e40e3423..3cfa821a8f9 100644 Binary files a/public/images/pokemon/variant/back/441_3.png and b/public/images/pokemon/variant/back/441_3.png differ diff --git a/public/images/pokemon/variant/back/457_2.png b/public/images/pokemon/variant/back/457_2.png index 9168013d2e6..f41fb311b01 100644 Binary files a/public/images/pokemon/variant/back/457_2.png and b/public/images/pokemon/variant/back/457_2.png differ diff --git a/public/images/pokemon/variant/back/458_2.png b/public/images/pokemon/variant/back/458_2.png index 5c1db97b56d..d593fd73842 100644 Binary files a/public/images/pokemon/variant/back/458_2.png and b/public/images/pokemon/variant/back/458_2.png differ diff --git a/public/images/pokemon/variant/back/458_3.png b/public/images/pokemon/variant/back/458_3.png index 7cf9d011c04..605d0dac846 100644 Binary files a/public/images/pokemon/variant/back/458_3.png and b/public/images/pokemon/variant/back/458_3.png differ diff --git a/public/images/pokemon/variant/back/466_1.png b/public/images/pokemon/variant/back/466_1.png index 32f481f6885..eab00428a23 100644 Binary files a/public/images/pokemon/variant/back/466_1.png and b/public/images/pokemon/variant/back/466_1.png differ diff --git a/public/images/pokemon/variant/back/469_2.png b/public/images/pokemon/variant/back/469_2.png index 6e064707bba..b83cf418a57 100644 Binary files a/public/images/pokemon/variant/back/469_2.png and b/public/images/pokemon/variant/back/469_2.png differ diff --git a/public/images/pokemon/variant/back/470_1.png b/public/images/pokemon/variant/back/470_1.png index a156101f2cf..7e64d672b38 100644 Binary files a/public/images/pokemon/variant/back/470_1.png and b/public/images/pokemon/variant/back/470_1.png differ diff --git a/public/images/pokemon/variant/back/470_2.png b/public/images/pokemon/variant/back/470_2.png index 69e75827b0a..f062750b14f 100644 Binary files a/public/images/pokemon/variant/back/470_2.png and b/public/images/pokemon/variant/back/470_2.png differ diff --git a/public/images/pokemon/variant/back/472_3.png b/public/images/pokemon/variant/back/472_3.png index 79b07833534..a6e22d85113 100644 Binary files a/public/images/pokemon/variant/back/472_3.png and b/public/images/pokemon/variant/back/472_3.png differ diff --git a/public/images/pokemon/variant/back/478_2.png b/public/images/pokemon/variant/back/478_2.png index 9d165174556..979bfc9fd11 100644 Binary files a/public/images/pokemon/variant/back/478_2.png and b/public/images/pokemon/variant/back/478_2.png differ diff --git a/public/images/pokemon/variant/back/529_2.png b/public/images/pokemon/variant/back/529_2.png index 06e853c19c2..22d3d5958ba 100644 Binary files a/public/images/pokemon/variant/back/529_2.png and b/public/images/pokemon/variant/back/529_2.png differ diff --git a/public/images/pokemon/variant/back/529_3.png b/public/images/pokemon/variant/back/529_3.png index 935c5788841..8458afd7642 100644 Binary files a/public/images/pokemon/variant/back/529_3.png and b/public/images/pokemon/variant/back/529_3.png differ diff --git a/public/images/pokemon/variant/back/530_3.png b/public/images/pokemon/variant/back/530_3.png index d5b7b9b651b..ec2a1e7cd77 100644 Binary files a/public/images/pokemon/variant/back/530_3.png and b/public/images/pokemon/variant/back/530_3.png differ diff --git a/public/images/pokemon/variant/back/539_2.png b/public/images/pokemon/variant/back/539_2.png index e4bca835949..01956ca440c 100644 Binary files a/public/images/pokemon/variant/back/539_2.png and b/public/images/pokemon/variant/back/539_2.png differ diff --git a/public/images/pokemon/variant/back/539_3.png b/public/images/pokemon/variant/back/539_3.png index fb28b78459c..b4126047a5c 100644 Binary files a/public/images/pokemon/variant/back/539_3.png and b/public/images/pokemon/variant/back/539_3.png differ diff --git a/public/images/pokemon/variant/back/585-autumn_1.png b/public/images/pokemon/variant/back/585-autumn_1.png index 48c5968bff7..147e14fc5fa 100644 Binary files a/public/images/pokemon/variant/back/585-autumn_1.png and b/public/images/pokemon/variant/back/585-autumn_1.png differ diff --git a/public/images/pokemon/variant/back/585-spring_1.png b/public/images/pokemon/variant/back/585-spring_1.png index e3d6d7f75bd..e715844e976 100644 Binary files a/public/images/pokemon/variant/back/585-spring_1.png and b/public/images/pokemon/variant/back/585-spring_1.png differ diff --git a/public/images/pokemon/variant/back/585-winter_1.png b/public/images/pokemon/variant/back/585-winter_1.png index fe85cebd87d..24d991327f7 100644 Binary files a/public/images/pokemon/variant/back/585-winter_1.png and b/public/images/pokemon/variant/back/585-winter_1.png differ diff --git a/public/images/pokemon/variant/back/592_3.png b/public/images/pokemon/variant/back/592_3.png index 88ac9e57362..f7469e36ec6 100644 Binary files a/public/images/pokemon/variant/back/592_3.png and b/public/images/pokemon/variant/back/592_3.png differ diff --git a/public/images/pokemon/variant/back/594_3.png b/public/images/pokemon/variant/back/594_3.png index 9e4215d42b7..4f1c28d8335 100644 Binary files a/public/images/pokemon/variant/back/594_3.png and b/public/images/pokemon/variant/back/594_3.png differ diff --git a/public/images/pokemon/variant/back/618_2.png b/public/images/pokemon/variant/back/618_2.png index e74c6db3f04..a0077a1f023 100644 Binary files a/public/images/pokemon/variant/back/618_2.png and b/public/images/pokemon/variant/back/618_2.png differ diff --git a/public/images/pokemon/variant/back/631_2.png b/public/images/pokemon/variant/back/631_2.png index d5d6af70546..b3cee0d8baa 100644 Binary files a/public/images/pokemon/variant/back/631_2.png and b/public/images/pokemon/variant/back/631_2.png differ diff --git a/public/images/pokemon/variant/back/631_3.png b/public/images/pokemon/variant/back/631_3.png index bb029fd7f3c..a052b6ea4b1 100644 Binary files a/public/images/pokemon/variant/back/631_3.png and b/public/images/pokemon/variant/back/631_3.png differ diff --git a/public/images/pokemon/variant/back/666-fancy_2.png b/public/images/pokemon/variant/back/666-fancy_2.png index d51a6403f3b..a1e23edd659 100644 Binary files a/public/images/pokemon/variant/back/666-fancy_2.png and b/public/images/pokemon/variant/back/666-fancy_2.png differ diff --git a/public/images/pokemon/variant/back/666-fancy_3.png b/public/images/pokemon/variant/back/666-fancy_3.png index aeca21cbeb5..6d15bc3f680 100644 Binary files a/public/images/pokemon/variant/back/666-fancy_3.png and b/public/images/pokemon/variant/back/666-fancy_3.png differ diff --git a/public/images/pokemon/variant/back/666-river_2.png b/public/images/pokemon/variant/back/666-river_2.png index 06c1b09d749..8d829e974f4 100644 Binary files a/public/images/pokemon/variant/back/666-river_2.png and b/public/images/pokemon/variant/back/666-river_2.png differ diff --git a/public/images/pokemon/variant/back/696_3.png b/public/images/pokemon/variant/back/696_3.png index 87dc6ff576c..76bced189af 100644 Binary files a/public/images/pokemon/variant/back/696_3.png and b/public/images/pokemon/variant/back/696_3.png differ diff --git a/public/images/pokemon/variant/back/697_3.png b/public/images/pokemon/variant/back/697_3.png index 430bde3ae6d..cea5cfb6830 100644 Binary files a/public/images/pokemon/variant/back/697_3.png and b/public/images/pokemon/variant/back/697_3.png differ diff --git a/public/images/pokemon/variant/back/715_2.png b/public/images/pokemon/variant/back/715_2.png index 91bebbc7e58..d9e04847334 100644 Binary files a/public/images/pokemon/variant/back/715_2.png and b/public/images/pokemon/variant/back/715_2.png differ diff --git a/public/images/pokemon/variant/back/715_3.png b/public/images/pokemon/variant/back/715_3.png index 123e9a7fa1d..11069652972 100644 Binary files a/public/images/pokemon/variant/back/715_3.png and b/public/images/pokemon/variant/back/715_3.png differ diff --git a/public/images/pokemon/variant/back/742_2.png b/public/images/pokemon/variant/back/742_2.png index 955cd3514ae..cfcc6c31f20 100644 Binary files a/public/images/pokemon/variant/back/742_2.png and b/public/images/pokemon/variant/back/742_2.png differ diff --git a/public/images/pokemon/variant/back/742_3.png b/public/images/pokemon/variant/back/742_3.png index a42604a6b56..a8157351738 100644 Binary files a/public/images/pokemon/variant/back/742_3.png and b/public/images/pokemon/variant/back/742_3.png differ diff --git a/public/images/pokemon/variant/back/743_2.png b/public/images/pokemon/variant/back/743_2.png index 983addac875..3e90381dcc1 100644 Binary files a/public/images/pokemon/variant/back/743_2.png and b/public/images/pokemon/variant/back/743_2.png differ diff --git a/public/images/pokemon/variant/back/743_3.png b/public/images/pokemon/variant/back/743_3.png index b892f735a5b..03d5b2719ff 100644 Binary files a/public/images/pokemon/variant/back/743_3.png and b/public/images/pokemon/variant/back/743_3.png differ diff --git a/public/images/pokemon/variant/back/754_2.png b/public/images/pokemon/variant/back/754_2.png index 234f96b9f45..af52b9c5f44 100644 Binary files a/public/images/pokemon/variant/back/754_2.png and b/public/images/pokemon/variant/back/754_2.png differ diff --git a/public/images/pokemon/variant/back/754_3.png b/public/images/pokemon/variant/back/754_3.png index 7a99986e40e..e00a2353a60 100644 Binary files a/public/images/pokemon/variant/back/754_3.png and b/public/images/pokemon/variant/back/754_3.png differ diff --git a/public/images/pokemon/variant/back/791_1.png b/public/images/pokemon/variant/back/791_1.png index 9d5da99ce5c..647884de128 100644 Binary files a/public/images/pokemon/variant/back/791_1.png and b/public/images/pokemon/variant/back/791_1.png differ diff --git a/public/images/pokemon/variant/back/7_2.png b/public/images/pokemon/variant/back/7_2.png index 7f0970f95bc..1deb4d30f61 100644 Binary files a/public/images/pokemon/variant/back/7_2.png and b/public/images/pokemon/variant/back/7_2.png differ diff --git a/public/images/pokemon/variant/back/7_3.png b/public/images/pokemon/variant/back/7_3.png index 2758617eea9..8111d99023e 100644 Binary files a/public/images/pokemon/variant/back/7_3.png and b/public/images/pokemon/variant/back/7_3.png differ diff --git a/public/images/pokemon/variant/back/823-gigantamax_2.png b/public/images/pokemon/variant/back/823-gigantamax_2.png index 7ccc99014a6..d37529893d9 100644 Binary files a/public/images/pokemon/variant/back/823-gigantamax_2.png and b/public/images/pokemon/variant/back/823-gigantamax_2.png differ diff --git a/public/images/pokemon/variant/back/823-gigantamax_3.png b/public/images/pokemon/variant/back/823-gigantamax_3.png index a85e9813268..9b329a4d6f6 100644 Binary files a/public/images/pokemon/variant/back/823-gigantamax_3.png and b/public/images/pokemon/variant/back/823-gigantamax_3.png differ diff --git a/public/images/pokemon/variant/back/83_2.png b/public/images/pokemon/variant/back/83_2.png index 3dda813cf92..103155eb387 100644 Binary files a/public/images/pokemon/variant/back/83_2.png and b/public/images/pokemon/variant/back/83_2.png differ diff --git a/public/images/pokemon/variant/back/83_3.png b/public/images/pokemon/variant/back/83_3.png index b8de9d82cc7..e06e48e577f 100644 Binary files a/public/images/pokemon/variant/back/83_3.png and b/public/images/pokemon/variant/back/83_3.png differ diff --git a/public/images/pokemon/variant/back/857_2.png b/public/images/pokemon/variant/back/857_2.png index bbc09762342..2481e0b825f 100644 Binary files a/public/images/pokemon/variant/back/857_2.png and b/public/images/pokemon/variant/back/857_2.png differ diff --git a/public/images/pokemon/variant/back/857_3.png b/public/images/pokemon/variant/back/857_3.png index 9f77ff938c6..0b14194a26f 100644 Binary files a/public/images/pokemon/variant/back/857_3.png and b/public/images/pokemon/variant/back/857_3.png differ diff --git a/public/images/pokemon/variant/back/862_2.png b/public/images/pokemon/variant/back/862_2.png index 705898eb9a7..1a79d39d63f 100644 Binary files a/public/images/pokemon/variant/back/862_2.png and b/public/images/pokemon/variant/back/862_2.png differ diff --git a/public/images/pokemon/variant/back/862_3.png b/public/images/pokemon/variant/back/862_3.png index 92f81bfe220..d8e6d2b5639 100644 Binary files a/public/images/pokemon/variant/back/862_3.png and b/public/images/pokemon/variant/back/862_3.png differ diff --git a/public/images/pokemon/variant/back/881_2.png b/public/images/pokemon/variant/back/881_2.png index 76176d7d5fe..2060481d855 100644 Binary files a/public/images/pokemon/variant/back/881_2.png and b/public/images/pokemon/variant/back/881_2.png differ diff --git a/public/images/pokemon/variant/back/881_3.png b/public/images/pokemon/variant/back/881_3.png index c255e83cc16..6ed3c2495ba 100644 Binary files a/public/images/pokemon/variant/back/881_3.png and b/public/images/pokemon/variant/back/881_3.png differ diff --git a/public/images/pokemon/variant/back/8_2.png b/public/images/pokemon/variant/back/8_2.png index d0171dd1bdc..8c3605eb75b 100644 Binary files a/public/images/pokemon/variant/back/8_2.png and b/public/images/pokemon/variant/back/8_2.png differ diff --git a/public/images/pokemon/variant/back/8_3.png b/public/images/pokemon/variant/back/8_3.png index ea7724838db..c74f82777ce 100644 Binary files a/public/images/pokemon/variant/back/8_3.png and b/public/images/pokemon/variant/back/8_3.png differ diff --git a/public/images/pokemon/variant/back/9-gigantamax_3.png b/public/images/pokemon/variant/back/9-gigantamax_3.png index c98249e14d5..444264fa4fd 100644 Binary files a/public/images/pokemon/variant/back/9-gigantamax_3.png and b/public/images/pokemon/variant/back/9-gigantamax_3.png differ diff --git a/public/images/pokemon/variant/back/9-mega_2.png b/public/images/pokemon/variant/back/9-mega_2.png index e961ace2e5c..02987564bea 100644 Binary files a/public/images/pokemon/variant/back/9-mega_2.png and b/public/images/pokemon/variant/back/9-mega_2.png differ diff --git a/public/images/pokemon/variant/back/9-mega_3.png b/public/images/pokemon/variant/back/9-mega_3.png index 95a7babe58b..00150d4dd46 100644 Binary files a/public/images/pokemon/variant/back/9-mega_3.png and b/public/images/pokemon/variant/back/9-mega_3.png differ diff --git a/public/images/pokemon/variant/back/910_2.png b/public/images/pokemon/variant/back/910_2.png index 4efa5be2565..8c4dd643574 100644 Binary files a/public/images/pokemon/variant/back/910_2.png and b/public/images/pokemon/variant/back/910_2.png differ diff --git a/public/images/pokemon/variant/back/910_3.png b/public/images/pokemon/variant/back/910_3.png index c5f4b605dcb..ad622de11a4 100644 Binary files a/public/images/pokemon/variant/back/910_3.png and b/public/images/pokemon/variant/back/910_3.png differ diff --git a/public/images/pokemon/variant/back/92_1.png b/public/images/pokemon/variant/back/92_1.png index 20faf4213ca..96a70ecbf7b 100644 Binary files a/public/images/pokemon/variant/back/92_1.png and b/public/images/pokemon/variant/back/92_1.png differ diff --git a/public/images/pokemon/variant/back/92_2.png b/public/images/pokemon/variant/back/92_2.png index 6a7e13cc25e..711ece9d98b 100644 Binary files a/public/images/pokemon/variant/back/92_2.png and b/public/images/pokemon/variant/back/92_2.png differ diff --git a/public/images/pokemon/variant/back/92_3.png b/public/images/pokemon/variant/back/92_3.png index df995a87d55..918e0ee35f8 100644 Binary files a/public/images/pokemon/variant/back/92_3.png and b/public/images/pokemon/variant/back/92_3.png differ diff --git a/public/images/pokemon/variant/back/970_2.png b/public/images/pokemon/variant/back/970_2.png index 2e07eb2fb07..4f3a7eb76ef 100644 Binary files a/public/images/pokemon/variant/back/970_2.png and b/public/images/pokemon/variant/back/970_2.png differ diff --git a/public/images/pokemon/variant/back/978-curly_2.png b/public/images/pokemon/variant/back/978-curly_2.png index 4a5ede3e81a..70bde1acb2f 100644 Binary files a/public/images/pokemon/variant/back/978-curly_2.png and b/public/images/pokemon/variant/back/978-curly_2.png differ diff --git a/public/images/pokemon/variant/back/978-curly_3.png b/public/images/pokemon/variant/back/978-curly_3.png index af6d8a8aa33..877dbbaee6f 100644 Binary files a/public/images/pokemon/variant/back/978-curly_3.png and b/public/images/pokemon/variant/back/978-curly_3.png differ diff --git a/public/images/pokemon/variant/back/978-droopy_2.png b/public/images/pokemon/variant/back/978-droopy_2.png index 23e1b955d4d..7259f4e5635 100644 Binary files a/public/images/pokemon/variant/back/978-droopy_2.png and b/public/images/pokemon/variant/back/978-droopy_2.png differ diff --git a/public/images/pokemon/variant/back/978-droopy_3.png b/public/images/pokemon/variant/back/978-droopy_3.png index 6255349f590..9ba70e6d395 100644 Binary files a/public/images/pokemon/variant/back/978-droopy_3.png and b/public/images/pokemon/variant/back/978-droopy_3.png differ diff --git a/public/images/pokemon/variant/back/982-three-segment_3.png b/public/images/pokemon/variant/back/982-three-segment_3.png index 3286d3331a5..ed5d835ab16 100644 Binary files a/public/images/pokemon/variant/back/982-three-segment_3.png and b/public/images/pokemon/variant/back/982-three-segment_3.png differ diff --git a/public/images/pokemon/variant/back/982_3.png b/public/images/pokemon/variant/back/982_3.png index b6b0ef0c2f4..0c8766b59cb 100644 Binary files a/public/images/pokemon/variant/back/982_3.png and b/public/images/pokemon/variant/back/982_3.png differ diff --git a/public/images/pokemon/variant/back/9_2.png b/public/images/pokemon/variant/back/9_2.png index a55c0c139fb..409472b2e52 100644 Binary files a/public/images/pokemon/variant/back/9_2.png and b/public/images/pokemon/variant/back/9_2.png differ diff --git a/public/images/pokemon/variant/back/9_3.png b/public/images/pokemon/variant/back/9_3.png index edae3f66b71..2cb0b1a3917 100644 Binary files a/public/images/pokemon/variant/back/9_3.png and b/public/images/pokemon/variant/back/9_3.png differ diff --git a/public/images/pokemon/variant/back/female/399_2.png b/public/images/pokemon/variant/back/female/399_2.png index fcd948a0ef9..b71497f9ccf 100644 Binary files a/public/images/pokemon/variant/back/female/399_2.png and b/public/images/pokemon/variant/back/female/399_2.png differ diff --git a/public/images/pokemon/variant/back/female/418_2.png b/public/images/pokemon/variant/back/female/418_2.png index fc6ad0362df..03a1b2b7dd4 100644 Binary files a/public/images/pokemon/variant/back/female/418_2.png and b/public/images/pokemon/variant/back/female/418_2.png differ diff --git a/public/images/pokemon/variant/back/female/418_3.png b/public/images/pokemon/variant/back/female/418_3.png index a9051456db9..faf166b7184 100644 Binary files a/public/images/pokemon/variant/back/female/418_3.png and b/public/images/pokemon/variant/back/female/418_3.png differ diff --git a/public/images/pokemon/variant/back/female/41_2.png b/public/images/pokemon/variant/back/female/41_2.png index bd1e22238cc..4fdb671c61a 100644 Binary files a/public/images/pokemon/variant/back/female/41_2.png and b/public/images/pokemon/variant/back/female/41_2.png differ diff --git a/public/images/pokemon/variant/back/female/41_3.png b/public/images/pokemon/variant/back/female/41_3.png index fec4f49c599..f494bd5b07e 100644 Binary files a/public/images/pokemon/variant/back/female/41_3.png and b/public/images/pokemon/variant/back/female/41_3.png differ diff --git a/public/images/pokemon/variant/back/female/42_2.png b/public/images/pokemon/variant/back/female/42_2.png index 61360275ca1..2fa196d973a 100644 Binary files a/public/images/pokemon/variant/back/female/42_2.png and b/public/images/pokemon/variant/back/female/42_2.png differ diff --git a/public/images/pokemon/variant/back/female/42_3.png b/public/images/pokemon/variant/back/female/42_3.png index bd86c83f3c0..4e88627d6b6 100644 Binary files a/public/images/pokemon/variant/back/female/42_3.png and b/public/images/pokemon/variant/back/female/42_3.png differ diff --git a/public/images/pokemon/variant/exp/181-mega_3.png b/public/images/pokemon/variant/exp/181-mega_3.png index 2e88beea872..7172bc45244 100644 Binary files a/public/images/pokemon/variant/exp/181-mega_3.png and b/public/images/pokemon/variant/exp/181-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/212-mega_2.png b/public/images/pokemon/variant/exp/212-mega_2.png index d08116555cd..2665dfbc253 100644 Binary files a/public/images/pokemon/variant/exp/212-mega_2.png and b/public/images/pokemon/variant/exp/212-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/212-mega_3.png b/public/images/pokemon/variant/exp/212-mega_3.png index c93db623fda..75226e68010 100644 Binary files a/public/images/pokemon/variant/exp/212-mega_3.png and b/public/images/pokemon/variant/exp/212-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/3-mega_2.png b/public/images/pokemon/variant/exp/3-mega_2.png index 97dce2ae673..b9cb20aba0a 100644 Binary files a/public/images/pokemon/variant/exp/3-mega_2.png and b/public/images/pokemon/variant/exp/3-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/3-mega_3.png b/public/images/pokemon/variant/exp/3-mega_3.png index 277b3c82082..ddd1e998130 100644 Binary files a/public/images/pokemon/variant/exp/3-mega_3.png and b/public/images/pokemon/variant/exp/3-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/334-mega_2.png b/public/images/pokemon/variant/exp/334-mega_2.png index 7a6fdb20cf2..9588df214d0 100644 Binary files a/public/images/pokemon/variant/exp/334-mega_2.png and b/public/images/pokemon/variant/exp/334-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/384-mega_2.png b/public/images/pokemon/variant/exp/384-mega_2.png index dc03a7ba8e2..57ed787e8da 100644 Binary files a/public/images/pokemon/variant/exp/384-mega_2.png and b/public/images/pokemon/variant/exp/384-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/4080_1.png b/public/images/pokemon/variant/exp/4080_1.png index a7e6de6cff7..aad11f1dd4a 100644 Binary files a/public/images/pokemon/variant/exp/4080_1.png and b/public/images/pokemon/variant/exp/4080_1.png differ diff --git a/public/images/pokemon/variant/exp/4199_1.png b/public/images/pokemon/variant/exp/4199_1.png index 4ad5b00b4c7..0a22d90da05 100644 Binary files a/public/images/pokemon/variant/exp/4199_1.png and b/public/images/pokemon/variant/exp/4199_1.png differ diff --git a/public/images/pokemon/variant/exp/666-fancy_2.png b/public/images/pokemon/variant/exp/666-fancy_2.png index df1343095d0..68af4d0a07a 100644 Binary files a/public/images/pokemon/variant/exp/666-fancy_2.png and b/public/images/pokemon/variant/exp/666-fancy_2.png differ diff --git a/public/images/pokemon/variant/exp/666-fancy_3.png b/public/images/pokemon/variant/exp/666-fancy_3.png index 4a48c5cc236..a8e39976f2a 100644 Binary files a/public/images/pokemon/variant/exp/666-fancy_3.png and b/public/images/pokemon/variant/exp/666-fancy_3.png differ diff --git a/public/images/pokemon/variant/exp/666-meadow_2.png b/public/images/pokemon/variant/exp/666-meadow_2.png index 5ada6bb51be..8aada72636f 100644 Binary files a/public/images/pokemon/variant/exp/666-meadow_2.png and b/public/images/pokemon/variant/exp/666-meadow_2.png differ diff --git a/public/images/pokemon/variant/exp/666-meadow_3.png b/public/images/pokemon/variant/exp/666-meadow_3.png index 2acb4732409..146ea5e2ba9 100644 Binary files a/public/images/pokemon/variant/exp/666-meadow_3.png and b/public/images/pokemon/variant/exp/666-meadow_3.png differ diff --git a/public/images/pokemon/variant/exp/666-poke-ball_3.png b/public/images/pokemon/variant/exp/666-poke-ball_3.png index 9e821efd1eb..767a55ab849 100644 Binary files a/public/images/pokemon/variant/exp/666-poke-ball_3.png and b/public/images/pokemon/variant/exp/666-poke-ball_3.png differ diff --git a/public/images/pokemon/variant/exp/666-river_2.png b/public/images/pokemon/variant/exp/666-river_2.png index 7dc96690328..863acbbdc76 100644 Binary files a/public/images/pokemon/variant/exp/666-river_2.png and b/public/images/pokemon/variant/exp/666-river_2.png differ diff --git a/public/images/pokemon/variant/exp/696_2.png b/public/images/pokemon/variant/exp/696_2.png index 031589b4c30..cfc40b59d39 100644 Binary files a/public/images/pokemon/variant/exp/696_2.png and b/public/images/pokemon/variant/exp/696_2.png differ diff --git a/public/images/pokemon/variant/exp/696_3.png b/public/images/pokemon/variant/exp/696_3.png index 8ec6baa4724..647aba679f6 100644 Binary files a/public/images/pokemon/variant/exp/696_3.png and b/public/images/pokemon/variant/exp/696_3.png differ diff --git a/public/images/pokemon/variant/exp/697_3.png b/public/images/pokemon/variant/exp/697_3.png index f58c494a094..b18579c9494 100644 Binary files a/public/images/pokemon/variant/exp/697_3.png and b/public/images/pokemon/variant/exp/697_3.png differ diff --git a/public/images/pokemon/variant/exp/715_2.png b/public/images/pokemon/variant/exp/715_2.png index 4383b8917ae..22fb386440a 100644 Binary files a/public/images/pokemon/variant/exp/715_2.png and b/public/images/pokemon/variant/exp/715_2.png differ diff --git a/public/images/pokemon/variant/exp/717_2.png b/public/images/pokemon/variant/exp/717_2.png index 30b5a9863de..3e11dfa8837 100644 Binary files a/public/images/pokemon/variant/exp/717_2.png and b/public/images/pokemon/variant/exp/717_2.png differ diff --git a/public/images/pokemon/variant/exp/717_3.png b/public/images/pokemon/variant/exp/717_3.png index ad17cdd305f..e39ddfc55d0 100644 Binary files a/public/images/pokemon/variant/exp/717_3.png and b/public/images/pokemon/variant/exp/717_3.png differ diff --git a/public/images/pokemon/variant/exp/729_2.png b/public/images/pokemon/variant/exp/729_2.png index c5c309dbaee..8349e63c91a 100644 Binary files a/public/images/pokemon/variant/exp/729_2.png and b/public/images/pokemon/variant/exp/729_2.png differ diff --git a/public/images/pokemon/variant/exp/729_3.png b/public/images/pokemon/variant/exp/729_3.png index 75a11c74cdc..a4b4197f18a 100644 Binary files a/public/images/pokemon/variant/exp/729_3.png and b/public/images/pokemon/variant/exp/729_3.png differ diff --git a/public/images/pokemon/variant/exp/730_2.png b/public/images/pokemon/variant/exp/730_2.png index f2ef5220ea9..f7a1b20a9be 100644 Binary files a/public/images/pokemon/variant/exp/730_2.png and b/public/images/pokemon/variant/exp/730_2.png differ diff --git a/public/images/pokemon/variant/exp/742_2.png b/public/images/pokemon/variant/exp/742_2.png index a2a238353ea..d4495c7b805 100644 Binary files a/public/images/pokemon/variant/exp/742_2.png and b/public/images/pokemon/variant/exp/742_2.png differ diff --git a/public/images/pokemon/variant/exp/742_3.png b/public/images/pokemon/variant/exp/742_3.png index a4c4f372972..8d55c3263b0 100644 Binary files a/public/images/pokemon/variant/exp/742_3.png and b/public/images/pokemon/variant/exp/742_3.png differ diff --git a/public/images/pokemon/variant/exp/743_2.png b/public/images/pokemon/variant/exp/743_2.png index dae1418901d..6236408f2ca 100644 Binary files a/public/images/pokemon/variant/exp/743_2.png and b/public/images/pokemon/variant/exp/743_2.png differ diff --git a/public/images/pokemon/variant/exp/743_3.png b/public/images/pokemon/variant/exp/743_3.png index 99d6ae3763e..2759946a0fd 100644 Binary files a/public/images/pokemon/variant/exp/743_3.png and b/public/images/pokemon/variant/exp/743_3.png differ diff --git a/public/images/pokemon/variant/exp/747_2.png b/public/images/pokemon/variant/exp/747_2.png index cf3832c9236..5afb5dbe45e 100644 Binary files a/public/images/pokemon/variant/exp/747_2.png and b/public/images/pokemon/variant/exp/747_2.png differ diff --git a/public/images/pokemon/variant/exp/747_3.png b/public/images/pokemon/variant/exp/747_3.png index 9fd3b92aa3e..ceb750efe0c 100644 Binary files a/public/images/pokemon/variant/exp/747_3.png and b/public/images/pokemon/variant/exp/747_3.png differ diff --git a/public/images/pokemon/variant/exp/754_2.png b/public/images/pokemon/variant/exp/754_2.png index fc7e9eadac6..c1c55966656 100644 Binary files a/public/images/pokemon/variant/exp/754_2.png and b/public/images/pokemon/variant/exp/754_2.png differ diff --git a/public/images/pokemon/variant/exp/754_3.png b/public/images/pokemon/variant/exp/754_3.png index c9ad7c5d4ca..dca99a4eb83 100644 Binary files a/public/images/pokemon/variant/exp/754_3.png and b/public/images/pokemon/variant/exp/754_3.png differ diff --git a/public/images/pokemon/variant/exp/771_2.png b/public/images/pokemon/variant/exp/771_2.png index ec47015842d..f2059e6a8eb 100644 Binary files a/public/images/pokemon/variant/exp/771_2.png and b/public/images/pokemon/variant/exp/771_2.png differ diff --git a/public/images/pokemon/variant/exp/771_3.png b/public/images/pokemon/variant/exp/771_3.png index 4a0ac89ac2e..9016079d1cb 100644 Binary files a/public/images/pokemon/variant/exp/771_3.png and b/public/images/pokemon/variant/exp/771_3.png differ diff --git a/public/images/pokemon/variant/exp/791_1.png b/public/images/pokemon/variant/exp/791_1.png index 6c337194ec3..4d5f210ec9f 100644 Binary files a/public/images/pokemon/variant/exp/791_1.png and b/public/images/pokemon/variant/exp/791_1.png differ diff --git a/public/images/pokemon/variant/exp/793_2.png b/public/images/pokemon/variant/exp/793_2.png index 9c70c5a94ee..13f22cffdda 100644 Binary files a/public/images/pokemon/variant/exp/793_2.png and b/public/images/pokemon/variant/exp/793_2.png differ diff --git a/public/images/pokemon/variant/exp/793_3.png b/public/images/pokemon/variant/exp/793_3.png index a758fcb28a4..137cdd97d6d 100644 Binary files a/public/images/pokemon/variant/exp/793_3.png and b/public/images/pokemon/variant/exp/793_3.png differ diff --git a/public/images/pokemon/variant/exp/821_2.png b/public/images/pokemon/variant/exp/821_2.png index 5de24ec92a2..84bb53c19ff 100644 Binary files a/public/images/pokemon/variant/exp/821_2.png and b/public/images/pokemon/variant/exp/821_2.png differ diff --git a/public/images/pokemon/variant/exp/821_3.png b/public/images/pokemon/variant/exp/821_3.png index 7c2bd32a288..eab0bca889f 100644 Binary files a/public/images/pokemon/variant/exp/821_3.png and b/public/images/pokemon/variant/exp/821_3.png differ diff --git a/public/images/pokemon/variant/exp/836_2.png b/public/images/pokemon/variant/exp/836_2.png index 9729f1dd4cf..2961e1015a9 100644 Binary files a/public/images/pokemon/variant/exp/836_2.png and b/public/images/pokemon/variant/exp/836_2.png differ diff --git a/public/images/pokemon/variant/exp/836_3.png b/public/images/pokemon/variant/exp/836_3.png index 76caf187b4d..a48d218ed98 100644 Binary files a/public/images/pokemon/variant/exp/836_3.png and b/public/images/pokemon/variant/exp/836_3.png differ diff --git a/public/images/pokemon/variant/exp/857_2.png b/public/images/pokemon/variant/exp/857_2.png index 2a60b21cef0..c98f602a8e5 100644 Binary files a/public/images/pokemon/variant/exp/857_2.png and b/public/images/pokemon/variant/exp/857_2.png differ diff --git a/public/images/pokemon/variant/exp/857_3.png b/public/images/pokemon/variant/exp/857_3.png index f9e25f22cc4..1b5f73c35de 100644 Binary files a/public/images/pokemon/variant/exp/857_3.png and b/public/images/pokemon/variant/exp/857_3.png differ diff --git a/public/images/pokemon/variant/exp/862_2.png b/public/images/pokemon/variant/exp/862_2.png index 1ed022bfdf7..d97613e5e89 100644 Binary files a/public/images/pokemon/variant/exp/862_2.png and b/public/images/pokemon/variant/exp/862_2.png differ diff --git a/public/images/pokemon/variant/exp/862_3.png b/public/images/pokemon/variant/exp/862_3.png index 79fb464d72f..9f6857d961a 100644 Binary files a/public/images/pokemon/variant/exp/862_3.png and b/public/images/pokemon/variant/exp/862_3.png differ diff --git a/public/images/pokemon/variant/exp/882_2.png b/public/images/pokemon/variant/exp/882_2.png index a702a507f22..fa0c3825cc1 100644 Binary files a/public/images/pokemon/variant/exp/882_2.png and b/public/images/pokemon/variant/exp/882_2.png differ diff --git a/public/images/pokemon/variant/exp/890-eternamax_2.png b/public/images/pokemon/variant/exp/890-eternamax_2.png index b234ec88e16..2327900b971 100644 Binary files a/public/images/pokemon/variant/exp/890-eternamax_2.png and b/public/images/pokemon/variant/exp/890-eternamax_2.png differ diff --git a/public/images/pokemon/variant/exp/890-eternamax_3.png b/public/images/pokemon/variant/exp/890-eternamax_3.png index f24e74283c5..140837cfbd0 100644 Binary files a/public/images/pokemon/variant/exp/890-eternamax_3.png and b/public/images/pokemon/variant/exp/890-eternamax_3.png differ diff --git a/public/images/pokemon/variant/exp/890_2.png b/public/images/pokemon/variant/exp/890_2.png index 036ee01f676..2412e5f95d9 100644 Binary files a/public/images/pokemon/variant/exp/890_2.png and b/public/images/pokemon/variant/exp/890_2.png differ diff --git a/public/images/pokemon/variant/exp/890_3.png b/public/images/pokemon/variant/exp/890_3.png index fb757ecc5cd..855b646e514 100644 Binary files a/public/images/pokemon/variant/exp/890_3.png and b/public/images/pokemon/variant/exp/890_3.png differ diff --git a/public/images/pokemon/variant/exp/9-mega_2.png b/public/images/pokemon/variant/exp/9-mega_2.png index c3c06c1eca7..0a56f1a3a68 100644 Binary files a/public/images/pokemon/variant/exp/9-mega_2.png and b/public/images/pokemon/variant/exp/9-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/9-mega_3.png b/public/images/pokemon/variant/exp/9-mega_3.png index d7a4b6f9140..606f18d6337 100644 Binary files a/public/images/pokemon/variant/exp/9-mega_3.png and b/public/images/pokemon/variant/exp/9-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/910_2.png b/public/images/pokemon/variant/exp/910_2.png index 47dfe4ac7b0..751585f5b0b 100644 Binary files a/public/images/pokemon/variant/exp/910_2.png and b/public/images/pokemon/variant/exp/910_2.png differ diff --git a/public/images/pokemon/variant/exp/910_3.png b/public/images/pokemon/variant/exp/910_3.png index 3206742c7d8..39b728c4350 100644 Binary files a/public/images/pokemon/variant/exp/910_3.png and b/public/images/pokemon/variant/exp/910_3.png differ diff --git a/public/images/pokemon/variant/exp/911_2.png b/public/images/pokemon/variant/exp/911_2.png index 78cf3658061..af9f0237ccf 100644 Binary files a/public/images/pokemon/variant/exp/911_2.png and b/public/images/pokemon/variant/exp/911_2.png differ diff --git a/public/images/pokemon/variant/exp/911_3.png b/public/images/pokemon/variant/exp/911_3.png index d4c2e86b7d7..4280cbdc4a3 100644 Binary files a/public/images/pokemon/variant/exp/911_3.png and b/public/images/pokemon/variant/exp/911_3.png differ diff --git a/public/images/pokemon/variant/exp/912_3.png b/public/images/pokemon/variant/exp/912_3.png index 846915f851e..211af0da412 100644 Binary files a/public/images/pokemon/variant/exp/912_3.png and b/public/images/pokemon/variant/exp/912_3.png differ diff --git a/public/images/pokemon/variant/exp/913_3.png b/public/images/pokemon/variant/exp/913_3.png index acb749c995d..f18a8e917eb 100644 Binary files a/public/images/pokemon/variant/exp/913_3.png and b/public/images/pokemon/variant/exp/913_3.png differ diff --git a/public/images/pokemon/variant/exp/914_2.png b/public/images/pokemon/variant/exp/914_2.png index 08093e2b50b..66aa120f002 100644 Binary files a/public/images/pokemon/variant/exp/914_2.png and b/public/images/pokemon/variant/exp/914_2.png differ diff --git a/public/images/pokemon/variant/exp/925-four_2.png b/public/images/pokemon/variant/exp/925-four_2.png index 1a6403a6673..3a2f00f0606 100644 Binary files a/public/images/pokemon/variant/exp/925-four_2.png and b/public/images/pokemon/variant/exp/925-four_2.png differ diff --git a/public/images/pokemon/variant/exp/925-four_3.png b/public/images/pokemon/variant/exp/925-four_3.png index 41972571610..51496f55c18 100644 Binary files a/public/images/pokemon/variant/exp/925-four_3.png and b/public/images/pokemon/variant/exp/925-four_3.png differ diff --git a/public/images/pokemon/variant/exp/925-three_2.png b/public/images/pokemon/variant/exp/925-three_2.png index 2bfb7863223..f571d24f033 100644 Binary files a/public/images/pokemon/variant/exp/925-three_2.png and b/public/images/pokemon/variant/exp/925-three_2.png differ diff --git a/public/images/pokemon/variant/exp/925-three_3.png b/public/images/pokemon/variant/exp/925-three_3.png index 0b9a4ae7fc5..e6c54ceb519 100644 Binary files a/public/images/pokemon/variant/exp/925-three_3.png and b/public/images/pokemon/variant/exp/925-three_3.png differ diff --git a/public/images/pokemon/variant/exp/936_1.png b/public/images/pokemon/variant/exp/936_1.png index 980f82162ec..cdc333ab841 100644 Binary files a/public/images/pokemon/variant/exp/936_1.png and b/public/images/pokemon/variant/exp/936_1.png differ diff --git a/public/images/pokemon/variant/exp/936_3.png b/public/images/pokemon/variant/exp/936_3.png index 9a9b984a6ab..27874a25886 100644 Binary files a/public/images/pokemon/variant/exp/936_3.png and b/public/images/pokemon/variant/exp/936_3.png differ diff --git a/public/images/pokemon/variant/exp/937_1.png b/public/images/pokemon/variant/exp/937_1.png index 53fff3c074b..82fa70b0c5b 100644 Binary files a/public/images/pokemon/variant/exp/937_1.png and b/public/images/pokemon/variant/exp/937_1.png differ diff --git a/public/images/pokemon/variant/exp/937_2.png b/public/images/pokemon/variant/exp/937_2.png index af4a9c79eee..43e2b060319 100644 Binary files a/public/images/pokemon/variant/exp/937_2.png and b/public/images/pokemon/variant/exp/937_2.png differ diff --git a/public/images/pokemon/variant/exp/937_3.png b/public/images/pokemon/variant/exp/937_3.png index 5917cc01076..9a208ba1457 100644 Binary files a/public/images/pokemon/variant/exp/937_3.png and b/public/images/pokemon/variant/exp/937_3.png differ diff --git a/public/images/pokemon/variant/exp/94-mega_1.png b/public/images/pokemon/variant/exp/94-mega_1.png index f37635c0c8b..78787902b23 100644 Binary files a/public/images/pokemon/variant/exp/94-mega_1.png and b/public/images/pokemon/variant/exp/94-mega_1.png differ diff --git a/public/images/pokemon/variant/exp/94-mega_2.png b/public/images/pokemon/variant/exp/94-mega_2.png index 264672eb70b..c4ac996ff52 100644 Binary files a/public/images/pokemon/variant/exp/94-mega_2.png and b/public/images/pokemon/variant/exp/94-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/94-mega_3.png b/public/images/pokemon/variant/exp/94-mega_3.png index 89965a8a68f..f63c504e903 100644 Binary files a/public/images/pokemon/variant/exp/94-mega_3.png and b/public/images/pokemon/variant/exp/94-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/970_2.png b/public/images/pokemon/variant/exp/970_2.png index 23b7304a188..e7a046c2d7f 100644 Binary files a/public/images/pokemon/variant/exp/970_2.png and b/public/images/pokemon/variant/exp/970_2.png differ diff --git a/public/images/pokemon/variant/exp/970_3.png b/public/images/pokemon/variant/exp/970_3.png index 4513e32e924..213268b4d44 100644 Binary files a/public/images/pokemon/variant/exp/970_3.png and b/public/images/pokemon/variant/exp/970_3.png differ diff --git a/public/images/pokemon/variant/exp/978-curly_2.png b/public/images/pokemon/variant/exp/978-curly_2.png index 7fde5dc7ff4..800d4b3ee48 100644 Binary files a/public/images/pokemon/variant/exp/978-curly_2.png and b/public/images/pokemon/variant/exp/978-curly_2.png differ diff --git a/public/images/pokemon/variant/exp/978-curly_3.png b/public/images/pokemon/variant/exp/978-curly_3.png index 61f28cd014c..0625741b052 100644 Binary files a/public/images/pokemon/variant/exp/978-curly_3.png and b/public/images/pokemon/variant/exp/978-curly_3.png differ diff --git a/public/images/pokemon/variant/exp/978-droopy_2.png b/public/images/pokemon/variant/exp/978-droopy_2.png index c1570d64cc4..3ece2e41e47 100644 Binary files a/public/images/pokemon/variant/exp/978-droopy_2.png and b/public/images/pokemon/variant/exp/978-droopy_2.png differ diff --git a/public/images/pokemon/variant/exp/978-droopy_3.png b/public/images/pokemon/variant/exp/978-droopy_3.png index d64226dfb45..f1134506f3b 100644 Binary files a/public/images/pokemon/variant/exp/978-droopy_3.png and b/public/images/pokemon/variant/exp/978-droopy_3.png differ diff --git a/public/images/pokemon/variant/exp/978-stretchy_2.png b/public/images/pokemon/variant/exp/978-stretchy_2.png index 38fb36d785f..62d37a3e66a 100644 Binary files a/public/images/pokemon/variant/exp/978-stretchy_2.png and b/public/images/pokemon/variant/exp/978-stretchy_2.png differ diff --git a/public/images/pokemon/variant/exp/978-stretchy_3.png b/public/images/pokemon/variant/exp/978-stretchy_3.png index 1a2ded1841e..608ec2697cc 100644 Binary files a/public/images/pokemon/variant/exp/978-stretchy_3.png and b/public/images/pokemon/variant/exp/978-stretchy_3.png differ diff --git a/public/images/pokemon/variant/exp/979_1.png b/public/images/pokemon/variant/exp/979_1.png index 9d07620bf16..89c3a37d4aa 100644 Binary files a/public/images/pokemon/variant/exp/979_1.png and b/public/images/pokemon/variant/exp/979_1.png differ diff --git a/public/images/pokemon/variant/exp/979_2.png b/public/images/pokemon/variant/exp/979_2.png index 07c6ece9b07..788de4b089d 100644 Binary files a/public/images/pokemon/variant/exp/979_2.png and b/public/images/pokemon/variant/exp/979_2.png differ diff --git a/public/images/pokemon/variant/exp/979_3.png b/public/images/pokemon/variant/exp/979_3.png index da84b866c39..b0e6826c6c1 100644 Binary files a/public/images/pokemon/variant/exp/979_3.png and b/public/images/pokemon/variant/exp/979_3.png differ diff --git a/public/images/pokemon/variant/exp/994_3.png b/public/images/pokemon/variant/exp/994_3.png index a9f3f7fddc2..abd17460bc7 100644 Binary files a/public/images/pokemon/variant/exp/994_3.png and b/public/images/pokemon/variant/exp/994_3.png differ diff --git a/public/images/pokemon/variant/exp/997_2.png b/public/images/pokemon/variant/exp/997_2.png index 42065f31cad..6c61c142d9a 100644 Binary files a/public/images/pokemon/variant/exp/997_2.png and b/public/images/pokemon/variant/exp/997_2.png differ diff --git a/public/images/pokemon/variant/exp/997_3.png b/public/images/pokemon/variant/exp/997_3.png index 27ccadb26f8..c25719e15c7 100644 Binary files a/public/images/pokemon/variant/exp/997_3.png and b/public/images/pokemon/variant/exp/997_3.png differ diff --git a/public/images/pokemon/variant/exp/998_2.png b/public/images/pokemon/variant/exp/998_2.png index e79ad7c367b..ec371e4d986 100644 Binary files a/public/images/pokemon/variant/exp/998_2.png and b/public/images/pokemon/variant/exp/998_2.png differ diff --git a/public/images/pokemon/variant/exp/998_3.png b/public/images/pokemon/variant/exp/998_3.png index 19d7cc76f86..92db876caad 100644 Binary files a/public/images/pokemon/variant/exp/998_3.png and b/public/images/pokemon/variant/exp/998_3.png differ diff --git a/public/images/pokemon/variant/exp/999_1.png b/public/images/pokemon/variant/exp/999_1.png index c5092e856ce..df33c59f607 100644 Binary files a/public/images/pokemon/variant/exp/999_1.png and b/public/images/pokemon/variant/exp/999_1.png differ diff --git a/public/images/pokemon/variant/exp/back/181-mega_3.png b/public/images/pokemon/variant/exp/back/181-mega_3.png index 81856e501e1..771ce25a0da 100644 Binary files a/public/images/pokemon/variant/exp/back/181-mega_3.png and b/public/images/pokemon/variant/exp/back/181-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/back/212-mega_2.png b/public/images/pokemon/variant/exp/back/212-mega_2.png index d4337df3477..877ede02ad4 100644 Binary files a/public/images/pokemon/variant/exp/back/212-mega_2.png and b/public/images/pokemon/variant/exp/back/212-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/back/212-mega_3.png b/public/images/pokemon/variant/exp/back/212-mega_3.png index 173fb44c257..68db47ab830 100644 Binary files a/public/images/pokemon/variant/exp/back/212-mega_3.png and b/public/images/pokemon/variant/exp/back/212-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/back/248-mega_2.png b/public/images/pokemon/variant/exp/back/248-mega_2.png index 6dd5a1a7111..7971c22d8fe 100644 Binary files a/public/images/pokemon/variant/exp/back/248-mega_2.png and b/public/images/pokemon/variant/exp/back/248-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/back/3-mega_2.png b/public/images/pokemon/variant/exp/back/3-mega_2.png index 12a633ba7fa..777f4d0bca5 100644 Binary files a/public/images/pokemon/variant/exp/back/3-mega_2.png and b/public/images/pokemon/variant/exp/back/3-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/back/3-mega_3.png b/public/images/pokemon/variant/exp/back/3-mega_3.png index dbca39c55e6..4684c989e3d 100644 Binary files a/public/images/pokemon/variant/exp/back/3-mega_3.png and b/public/images/pokemon/variant/exp/back/3-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/back/4080_1.png b/public/images/pokemon/variant/exp/back/4080_1.png index 580548f6d3a..2bed3a5b4c1 100644 Binary files a/public/images/pokemon/variant/exp/back/4080_1.png and b/public/images/pokemon/variant/exp/back/4080_1.png differ diff --git a/public/images/pokemon/variant/exp/back/4080_2.png b/public/images/pokemon/variant/exp/back/4080_2.png index 988ac3f7834..e0fa30094cf 100644 Binary files a/public/images/pokemon/variant/exp/back/4080_2.png and b/public/images/pokemon/variant/exp/back/4080_2.png differ diff --git a/public/images/pokemon/variant/exp/back/4080_3.png b/public/images/pokemon/variant/exp/back/4080_3.png index 0fb239266ec..ed11f7ab90c 100644 Binary files a/public/images/pokemon/variant/exp/back/4080_3.png and b/public/images/pokemon/variant/exp/back/4080_3.png differ diff --git a/public/images/pokemon/variant/exp/back/4199_1.png b/public/images/pokemon/variant/exp/back/4199_1.png index 17e691cb35b..eb658cc2171 100644 Binary files a/public/images/pokemon/variant/exp/back/4199_1.png and b/public/images/pokemon/variant/exp/back/4199_1.png differ diff --git a/public/images/pokemon/variant/exp/back/665_2.png b/public/images/pokemon/variant/exp/back/665_2.png index bfddd085cc2..83762b9392c 100644 Binary files a/public/images/pokemon/variant/exp/back/665_2.png and b/public/images/pokemon/variant/exp/back/665_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-archipelago_2.png b/public/images/pokemon/variant/exp/back/666-archipelago_2.png index 032fd73f5c3..86e17e33f11 100644 Binary files a/public/images/pokemon/variant/exp/back/666-archipelago_2.png and b/public/images/pokemon/variant/exp/back/666-archipelago_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-archipelago_3.png b/public/images/pokemon/variant/exp/back/666-archipelago_3.png index b14fc9699cb..7028f550d45 100644 Binary files a/public/images/pokemon/variant/exp/back/666-archipelago_3.png and b/public/images/pokemon/variant/exp/back/666-archipelago_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-continental_2.png b/public/images/pokemon/variant/exp/back/666-continental_2.png index df588f7c4f5..3b9a31469af 100644 Binary files a/public/images/pokemon/variant/exp/back/666-continental_2.png and b/public/images/pokemon/variant/exp/back/666-continental_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-continental_3.png b/public/images/pokemon/variant/exp/back/666-continental_3.png index 76bb3953e51..b61b16538eb 100644 Binary files a/public/images/pokemon/variant/exp/back/666-continental_3.png and b/public/images/pokemon/variant/exp/back/666-continental_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-elegant_2.png b/public/images/pokemon/variant/exp/back/666-elegant_2.png index 68129e87db0..315b2fe859d 100644 Binary files a/public/images/pokemon/variant/exp/back/666-elegant_2.png and b/public/images/pokemon/variant/exp/back/666-elegant_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-elegant_3.png b/public/images/pokemon/variant/exp/back/666-elegant_3.png index d68e8977850..490bbb5951c 100644 Binary files a/public/images/pokemon/variant/exp/back/666-elegant_3.png and b/public/images/pokemon/variant/exp/back/666-elegant_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-fancy_2.png b/public/images/pokemon/variant/exp/back/666-fancy_2.png index 1fce2d851f4..a92f1e7eecf 100644 Binary files a/public/images/pokemon/variant/exp/back/666-fancy_2.png and b/public/images/pokemon/variant/exp/back/666-fancy_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-fancy_3.png b/public/images/pokemon/variant/exp/back/666-fancy_3.png index 8bb80556451..7a54e9bb6cd 100644 Binary files a/public/images/pokemon/variant/exp/back/666-fancy_3.png and b/public/images/pokemon/variant/exp/back/666-fancy_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-garden_2.png b/public/images/pokemon/variant/exp/back/666-garden_2.png index 547bcb72245..c56ff652c7d 100644 Binary files a/public/images/pokemon/variant/exp/back/666-garden_2.png and b/public/images/pokemon/variant/exp/back/666-garden_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-garden_3.png b/public/images/pokemon/variant/exp/back/666-garden_3.png index 8b0261631c3..60c7f5b7d01 100644 Binary files a/public/images/pokemon/variant/exp/back/666-garden_3.png and b/public/images/pokemon/variant/exp/back/666-garden_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-high-plains_2.png b/public/images/pokemon/variant/exp/back/666-high-plains_2.png index d656a17d3cd..d53634ed092 100644 Binary files a/public/images/pokemon/variant/exp/back/666-high-plains_2.png and b/public/images/pokemon/variant/exp/back/666-high-plains_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-high-plains_3.png b/public/images/pokemon/variant/exp/back/666-high-plains_3.png index cc4d6aa7536..d6c577be131 100644 Binary files a/public/images/pokemon/variant/exp/back/666-high-plains_3.png and b/public/images/pokemon/variant/exp/back/666-high-plains_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-icy-snow_2.png b/public/images/pokemon/variant/exp/back/666-icy-snow_2.png index f5b9bff1f1a..02e7e2e61af 100644 Binary files a/public/images/pokemon/variant/exp/back/666-icy-snow_2.png and b/public/images/pokemon/variant/exp/back/666-icy-snow_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-icy-snow_3.png b/public/images/pokemon/variant/exp/back/666-icy-snow_3.png index 3b9a184ff14..3c247e0d43a 100644 Binary files a/public/images/pokemon/variant/exp/back/666-icy-snow_3.png and b/public/images/pokemon/variant/exp/back/666-icy-snow_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-jungle_2.png b/public/images/pokemon/variant/exp/back/666-jungle_2.png index 64465ae4644..d6023a6500f 100644 Binary files a/public/images/pokemon/variant/exp/back/666-jungle_2.png and b/public/images/pokemon/variant/exp/back/666-jungle_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-jungle_3.png b/public/images/pokemon/variant/exp/back/666-jungle_3.png index e0132ad8b7a..0f4ca358601 100644 Binary files a/public/images/pokemon/variant/exp/back/666-jungle_3.png and b/public/images/pokemon/variant/exp/back/666-jungle_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-marine_2.png b/public/images/pokemon/variant/exp/back/666-marine_2.png index 11f4045e000..ffa21823012 100644 Binary files a/public/images/pokemon/variant/exp/back/666-marine_2.png and b/public/images/pokemon/variant/exp/back/666-marine_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-marine_3.png b/public/images/pokemon/variant/exp/back/666-marine_3.png index f8dbcebb2d2..ee4c51543ee 100644 Binary files a/public/images/pokemon/variant/exp/back/666-marine_3.png and b/public/images/pokemon/variant/exp/back/666-marine_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-meadow_2.png b/public/images/pokemon/variant/exp/back/666-meadow_2.png index 3a66918a8d2..bb54cac34cd 100644 Binary files a/public/images/pokemon/variant/exp/back/666-meadow_2.png and b/public/images/pokemon/variant/exp/back/666-meadow_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-meadow_3.png b/public/images/pokemon/variant/exp/back/666-meadow_3.png index 04c790e6b2b..865e404c1cd 100644 Binary files a/public/images/pokemon/variant/exp/back/666-meadow_3.png and b/public/images/pokemon/variant/exp/back/666-meadow_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-modern_2.png b/public/images/pokemon/variant/exp/back/666-modern_2.png index 1e226e6b79c..4cd5d770881 100644 Binary files a/public/images/pokemon/variant/exp/back/666-modern_2.png and b/public/images/pokemon/variant/exp/back/666-modern_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-modern_3.png b/public/images/pokemon/variant/exp/back/666-modern_3.png index 6d7516c4620..5795174404f 100644 Binary files a/public/images/pokemon/variant/exp/back/666-modern_3.png and b/public/images/pokemon/variant/exp/back/666-modern_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-monsoon_2.png b/public/images/pokemon/variant/exp/back/666-monsoon_2.png index 7570e6a7bfe..8f091f4d1de 100644 Binary files a/public/images/pokemon/variant/exp/back/666-monsoon_2.png and b/public/images/pokemon/variant/exp/back/666-monsoon_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-monsoon_3.png b/public/images/pokemon/variant/exp/back/666-monsoon_3.png index 6e9314cde1f..f216010ca99 100644 Binary files a/public/images/pokemon/variant/exp/back/666-monsoon_3.png and b/public/images/pokemon/variant/exp/back/666-monsoon_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-ocean_2.png b/public/images/pokemon/variant/exp/back/666-ocean_2.png index f8757bc7547..6f4fefc99f8 100644 Binary files a/public/images/pokemon/variant/exp/back/666-ocean_2.png and b/public/images/pokemon/variant/exp/back/666-ocean_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-ocean_3.png b/public/images/pokemon/variant/exp/back/666-ocean_3.png index 77b839e4326..554fcb7b510 100644 Binary files a/public/images/pokemon/variant/exp/back/666-ocean_3.png and b/public/images/pokemon/variant/exp/back/666-ocean_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-poke-ball_2.png b/public/images/pokemon/variant/exp/back/666-poke-ball_2.png index caaf61118bc..a1bd953a1b3 100644 Binary files a/public/images/pokemon/variant/exp/back/666-poke-ball_2.png and b/public/images/pokemon/variant/exp/back/666-poke-ball_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-poke-ball_3.png b/public/images/pokemon/variant/exp/back/666-poke-ball_3.png index 944f53eb4aa..9e7ff12912d 100644 Binary files a/public/images/pokemon/variant/exp/back/666-poke-ball_3.png and b/public/images/pokemon/variant/exp/back/666-poke-ball_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-polar_2.png b/public/images/pokemon/variant/exp/back/666-polar_2.png index e8d5a056bb3..b66daac7d2c 100644 Binary files a/public/images/pokemon/variant/exp/back/666-polar_2.png and b/public/images/pokemon/variant/exp/back/666-polar_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-polar_3.png b/public/images/pokemon/variant/exp/back/666-polar_3.png index 131d702ddb1..cab4822a306 100644 Binary files a/public/images/pokemon/variant/exp/back/666-polar_3.png and b/public/images/pokemon/variant/exp/back/666-polar_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-river_2.png b/public/images/pokemon/variant/exp/back/666-river_2.png index 97ce9b85139..c689a6c7150 100644 Binary files a/public/images/pokemon/variant/exp/back/666-river_2.png and b/public/images/pokemon/variant/exp/back/666-river_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-river_3.png b/public/images/pokemon/variant/exp/back/666-river_3.png index c84413aaaaf..a163e179d0e 100644 Binary files a/public/images/pokemon/variant/exp/back/666-river_3.png and b/public/images/pokemon/variant/exp/back/666-river_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-sandstorm_2.png b/public/images/pokemon/variant/exp/back/666-sandstorm_2.png index 541d183dc62..534e96bee13 100644 Binary files a/public/images/pokemon/variant/exp/back/666-sandstorm_2.png and b/public/images/pokemon/variant/exp/back/666-sandstorm_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-sandstorm_3.png b/public/images/pokemon/variant/exp/back/666-sandstorm_3.png index 393e47eb747..649fa83e025 100644 Binary files a/public/images/pokemon/variant/exp/back/666-sandstorm_3.png and b/public/images/pokemon/variant/exp/back/666-sandstorm_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-savanna_2.png b/public/images/pokemon/variant/exp/back/666-savanna_2.png index dea05ede882..b4b8ecedb9e 100644 Binary files a/public/images/pokemon/variant/exp/back/666-savanna_2.png and b/public/images/pokemon/variant/exp/back/666-savanna_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-savanna_3.png b/public/images/pokemon/variant/exp/back/666-savanna_3.png index bc2366e3483..6bc0a0b8363 100644 Binary files a/public/images/pokemon/variant/exp/back/666-savanna_3.png and b/public/images/pokemon/variant/exp/back/666-savanna_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-sun_2.png b/public/images/pokemon/variant/exp/back/666-sun_2.png index 32737f852e6..c9168d5a1c5 100644 Binary files a/public/images/pokemon/variant/exp/back/666-sun_2.png and b/public/images/pokemon/variant/exp/back/666-sun_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-sun_3.png b/public/images/pokemon/variant/exp/back/666-sun_3.png index d1679b936e1..1a36299851e 100644 Binary files a/public/images/pokemon/variant/exp/back/666-sun_3.png and b/public/images/pokemon/variant/exp/back/666-sun_3.png differ diff --git a/public/images/pokemon/variant/exp/back/666-tundra_2.png b/public/images/pokemon/variant/exp/back/666-tundra_2.png index 7311852570a..49325397d8a 100644 Binary files a/public/images/pokemon/variant/exp/back/666-tundra_2.png and b/public/images/pokemon/variant/exp/back/666-tundra_2.png differ diff --git a/public/images/pokemon/variant/exp/back/666-tundra_3.png b/public/images/pokemon/variant/exp/back/666-tundra_3.png index 3d1d40ca2a2..3284e1e637b 100644 Binary files a/public/images/pokemon/variant/exp/back/666-tundra_3.png and b/public/images/pokemon/variant/exp/back/666-tundra_3.png differ diff --git a/public/images/pokemon/variant/exp/back/696_1.png b/public/images/pokemon/variant/exp/back/696_1.png index daae82216a5..5e68ab9c167 100644 Binary files a/public/images/pokemon/variant/exp/back/696_1.png and b/public/images/pokemon/variant/exp/back/696_1.png differ diff --git a/public/images/pokemon/variant/exp/back/696_2.png b/public/images/pokemon/variant/exp/back/696_2.png index a8183d3c396..17e53dcd881 100644 Binary files a/public/images/pokemon/variant/exp/back/696_2.png and b/public/images/pokemon/variant/exp/back/696_2.png differ diff --git a/public/images/pokemon/variant/exp/back/696_3.png b/public/images/pokemon/variant/exp/back/696_3.png index 1eef16f0612..b6cecfa1c8d 100644 Binary files a/public/images/pokemon/variant/exp/back/696_3.png and b/public/images/pokemon/variant/exp/back/696_3.png differ diff --git a/public/images/pokemon/variant/exp/back/697_3.png b/public/images/pokemon/variant/exp/back/697_3.png index d9f80e85a02..4c916ab0d82 100644 Binary files a/public/images/pokemon/variant/exp/back/697_3.png and b/public/images/pokemon/variant/exp/back/697_3.png differ diff --git a/public/images/pokemon/variant/exp/back/699_2.png b/public/images/pokemon/variant/exp/back/699_2.png index 249930be50f..ea3da153124 100644 Binary files a/public/images/pokemon/variant/exp/back/699_2.png and b/public/images/pokemon/variant/exp/back/699_2.png differ diff --git a/public/images/pokemon/variant/exp/back/699_3.png b/public/images/pokemon/variant/exp/back/699_3.png index f5082d58284..4fd35302b43 100644 Binary files a/public/images/pokemon/variant/exp/back/699_3.png and b/public/images/pokemon/variant/exp/back/699_3.png differ diff --git a/public/images/pokemon/variant/exp/back/729_2.png b/public/images/pokemon/variant/exp/back/729_2.png index 1f2e8f31e2a..d5600f3bee4 100644 Binary files a/public/images/pokemon/variant/exp/back/729_2.png and b/public/images/pokemon/variant/exp/back/729_2.png differ diff --git a/public/images/pokemon/variant/exp/back/729_3.png b/public/images/pokemon/variant/exp/back/729_3.png index 08eb10257e1..182d81a0754 100644 Binary files a/public/images/pokemon/variant/exp/back/729_3.png and b/public/images/pokemon/variant/exp/back/729_3.png differ diff --git a/public/images/pokemon/variant/exp/back/730_2.png b/public/images/pokemon/variant/exp/back/730_2.png index b8340e4fca3..e9090ce19dd 100644 Binary files a/public/images/pokemon/variant/exp/back/730_2.png and b/public/images/pokemon/variant/exp/back/730_2.png differ diff --git a/public/images/pokemon/variant/exp/back/742_2.png b/public/images/pokemon/variant/exp/back/742_2.png index a442d157a0a..805fe7a4431 100644 Binary files a/public/images/pokemon/variant/exp/back/742_2.png and b/public/images/pokemon/variant/exp/back/742_2.png differ diff --git a/public/images/pokemon/variant/exp/back/742_3.png b/public/images/pokemon/variant/exp/back/742_3.png index 4fb526feb83..ddb72c1836a 100644 Binary files a/public/images/pokemon/variant/exp/back/742_3.png and b/public/images/pokemon/variant/exp/back/742_3.png differ diff --git a/public/images/pokemon/variant/exp/back/743_2.png b/public/images/pokemon/variant/exp/back/743_2.png index 33ab2c28ab8..e8b6ac6c82b 100644 Binary files a/public/images/pokemon/variant/exp/back/743_2.png and b/public/images/pokemon/variant/exp/back/743_2.png differ diff --git a/public/images/pokemon/variant/exp/back/743_3.png b/public/images/pokemon/variant/exp/back/743_3.png index 50328efe675..4a55750114d 100644 Binary files a/public/images/pokemon/variant/exp/back/743_3.png and b/public/images/pokemon/variant/exp/back/743_3.png differ diff --git a/public/images/pokemon/variant/exp/back/747_2.png b/public/images/pokemon/variant/exp/back/747_2.png index 50f44c0def7..f0df54539eb 100644 Binary files a/public/images/pokemon/variant/exp/back/747_2.png and b/public/images/pokemon/variant/exp/back/747_2.png differ diff --git a/public/images/pokemon/variant/exp/back/747_3.png b/public/images/pokemon/variant/exp/back/747_3.png index 2fb8e6036b9..7d887899e74 100644 Binary files a/public/images/pokemon/variant/exp/back/747_3.png and b/public/images/pokemon/variant/exp/back/747_3.png differ diff --git a/public/images/pokemon/variant/exp/back/754_2.png b/public/images/pokemon/variant/exp/back/754_2.png index 63f7486da1c..057d90eb009 100644 Binary files a/public/images/pokemon/variant/exp/back/754_2.png and b/public/images/pokemon/variant/exp/back/754_2.png differ diff --git a/public/images/pokemon/variant/exp/back/754_3.png b/public/images/pokemon/variant/exp/back/754_3.png index 205c3648755..3a3c01f7095 100644 Binary files a/public/images/pokemon/variant/exp/back/754_3.png and b/public/images/pokemon/variant/exp/back/754_3.png differ diff --git a/public/images/pokemon/variant/exp/back/776_2.png b/public/images/pokemon/variant/exp/back/776_2.png index 61e3662b56b..84393b04c56 100644 Binary files a/public/images/pokemon/variant/exp/back/776_2.png and b/public/images/pokemon/variant/exp/back/776_2.png differ diff --git a/public/images/pokemon/variant/exp/back/776_3.png b/public/images/pokemon/variant/exp/back/776_3.png index 5094ab508d1..600b00f8636 100644 Binary files a/public/images/pokemon/variant/exp/back/776_3.png and b/public/images/pokemon/variant/exp/back/776_3.png differ diff --git a/public/images/pokemon/variant/exp/back/857_2.png b/public/images/pokemon/variant/exp/back/857_2.png index d6472911e31..b51428bbec2 100644 Binary files a/public/images/pokemon/variant/exp/back/857_2.png and b/public/images/pokemon/variant/exp/back/857_2.png differ diff --git a/public/images/pokemon/variant/exp/back/857_3.png b/public/images/pokemon/variant/exp/back/857_3.png index 27f39ebfaf9..4dc21c5492d 100644 Binary files a/public/images/pokemon/variant/exp/back/857_3.png and b/public/images/pokemon/variant/exp/back/857_3.png differ diff --git a/public/images/pokemon/variant/exp/back/862_2.png b/public/images/pokemon/variant/exp/back/862_2.png index fae2900c566..55fee69723b 100644 Binary files a/public/images/pokemon/variant/exp/back/862_2.png and b/public/images/pokemon/variant/exp/back/862_2.png differ diff --git a/public/images/pokemon/variant/exp/back/862_3.png b/public/images/pokemon/variant/exp/back/862_3.png index 3f4537474f5..b3c9cc656b5 100644 Binary files a/public/images/pokemon/variant/exp/back/862_3.png and b/public/images/pokemon/variant/exp/back/862_3.png differ diff --git a/public/images/pokemon/variant/exp/back/9-mega_2.png b/public/images/pokemon/variant/exp/back/9-mega_2.png index e961ace2e5c..02987564bea 100644 Binary files a/public/images/pokemon/variant/exp/back/9-mega_2.png and b/public/images/pokemon/variant/exp/back/9-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/back/9-mega_3.png b/public/images/pokemon/variant/exp/back/9-mega_3.png index 95a7babe58b..00150d4dd46 100644 Binary files a/public/images/pokemon/variant/exp/back/9-mega_3.png and b/public/images/pokemon/variant/exp/back/9-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/back/910_2.png b/public/images/pokemon/variant/exp/back/910_2.png index 851bfd64563..2fa214c4e35 100644 Binary files a/public/images/pokemon/variant/exp/back/910_2.png and b/public/images/pokemon/variant/exp/back/910_2.png differ diff --git a/public/images/pokemon/variant/exp/back/910_3.png b/public/images/pokemon/variant/exp/back/910_3.png index 168db41336e..1027adef03f 100644 Binary files a/public/images/pokemon/variant/exp/back/910_3.png and b/public/images/pokemon/variant/exp/back/910_3.png differ diff --git a/public/images/pokemon/variant/exp/back/914_2.png b/public/images/pokemon/variant/exp/back/914_2.png index 5dee5c12f76..12bdc769c53 100644 Binary files a/public/images/pokemon/variant/exp/back/914_2.png and b/public/images/pokemon/variant/exp/back/914_2.png differ diff --git a/public/images/pokemon/variant/exp/back/914_3.png b/public/images/pokemon/variant/exp/back/914_3.png index 0185c529f70..5304b52d91a 100644 Binary files a/public/images/pokemon/variant/exp/back/914_3.png and b/public/images/pokemon/variant/exp/back/914_3.png differ diff --git a/public/images/pokemon/variant/exp/back/925-four_2.png b/public/images/pokemon/variant/exp/back/925-four_2.png index 6016d30d27c..9dd508f1cdb 100644 Binary files a/public/images/pokemon/variant/exp/back/925-four_2.png and b/public/images/pokemon/variant/exp/back/925-four_2.png differ diff --git a/public/images/pokemon/variant/exp/back/925-four_3.png b/public/images/pokemon/variant/exp/back/925-four_3.png index 3bc6a158fd5..74bb7d3385c 100644 Binary files a/public/images/pokemon/variant/exp/back/925-four_3.png and b/public/images/pokemon/variant/exp/back/925-four_3.png differ diff --git a/public/images/pokemon/variant/exp/back/925-three_2.png b/public/images/pokemon/variant/exp/back/925-three_2.png index 789e5afb20a..e2303d720b9 100644 Binary files a/public/images/pokemon/variant/exp/back/925-three_2.png and b/public/images/pokemon/variant/exp/back/925-three_2.png differ diff --git a/public/images/pokemon/variant/exp/back/925-three_3.png b/public/images/pokemon/variant/exp/back/925-three_3.png index cc1a1d3be11..8d568cce517 100644 Binary files a/public/images/pokemon/variant/exp/back/925-three_3.png and b/public/images/pokemon/variant/exp/back/925-three_3.png differ diff --git a/public/images/pokemon/variant/exp/back/936_1.png b/public/images/pokemon/variant/exp/back/936_1.png index 2b9e2d533f8..154c4e86364 100644 Binary files a/public/images/pokemon/variant/exp/back/936_1.png and b/public/images/pokemon/variant/exp/back/936_1.png differ diff --git a/public/images/pokemon/variant/exp/back/936_2.png b/public/images/pokemon/variant/exp/back/936_2.png index 45fb506fd01..442abc72971 100644 Binary files a/public/images/pokemon/variant/exp/back/936_2.png and b/public/images/pokemon/variant/exp/back/936_2.png differ diff --git a/public/images/pokemon/variant/exp/back/936_3.png b/public/images/pokemon/variant/exp/back/936_3.png index 82d3c0ecb0b..db67191d73e 100644 Binary files a/public/images/pokemon/variant/exp/back/936_3.png and b/public/images/pokemon/variant/exp/back/936_3.png differ diff --git a/public/images/pokemon/variant/exp/back/937_1.png b/public/images/pokemon/variant/exp/back/937_1.png index c0668be0103..2d0d58b0912 100644 Binary files a/public/images/pokemon/variant/exp/back/937_1.png and b/public/images/pokemon/variant/exp/back/937_1.png differ diff --git a/public/images/pokemon/variant/exp/back/937_2.png b/public/images/pokemon/variant/exp/back/937_2.png index f5bfd790b75..7ba1aa09b97 100644 Binary files a/public/images/pokemon/variant/exp/back/937_2.png and b/public/images/pokemon/variant/exp/back/937_2.png differ diff --git a/public/images/pokemon/variant/exp/back/937_3.png b/public/images/pokemon/variant/exp/back/937_3.png index c0a2be1ae0e..ee875356334 100644 Binary files a/public/images/pokemon/variant/exp/back/937_3.png and b/public/images/pokemon/variant/exp/back/937_3.png differ diff --git a/public/images/pokemon/variant/exp/back/952_2.png b/public/images/pokemon/variant/exp/back/952_2.png index 2518adc55ed..403030f2e3d 100644 Binary files a/public/images/pokemon/variant/exp/back/952_2.png and b/public/images/pokemon/variant/exp/back/952_2.png differ diff --git a/public/images/pokemon/variant/exp/back/968_2.png b/public/images/pokemon/variant/exp/back/968_2.png index 30b92268fbe..726c305140e 100644 Binary files a/public/images/pokemon/variant/exp/back/968_2.png and b/public/images/pokemon/variant/exp/back/968_2.png differ diff --git a/public/images/pokemon/variant/exp/back/968_3.png b/public/images/pokemon/variant/exp/back/968_3.png index e066f0eceef..541c3cf2d84 100644 Binary files a/public/images/pokemon/variant/exp/back/968_3.png and b/public/images/pokemon/variant/exp/back/968_3.png differ diff --git a/public/images/pokemon/variant/exp/back/970_2.png b/public/images/pokemon/variant/exp/back/970_2.png index dd61d57f2ac..5c7d2650363 100644 Binary files a/public/images/pokemon/variant/exp/back/970_2.png and b/public/images/pokemon/variant/exp/back/970_2.png differ diff --git a/public/images/pokemon/variant/exp/back/970_3.png b/public/images/pokemon/variant/exp/back/970_3.png index 025f88e1cbe..592c1f21961 100644 Binary files a/public/images/pokemon/variant/exp/back/970_3.png and b/public/images/pokemon/variant/exp/back/970_3.png differ diff --git a/public/images/pokemon/variant/exp/back/978-curly_2.png b/public/images/pokemon/variant/exp/back/978-curly_2.png index 205f55bf3dc..1ed3505ceee 100644 Binary files a/public/images/pokemon/variant/exp/back/978-curly_2.png and b/public/images/pokemon/variant/exp/back/978-curly_2.png differ diff --git a/public/images/pokemon/variant/exp/back/978-curly_3.png b/public/images/pokemon/variant/exp/back/978-curly_3.png index bee54677b74..dcc2129f72b 100644 Binary files a/public/images/pokemon/variant/exp/back/978-curly_3.png and b/public/images/pokemon/variant/exp/back/978-curly_3.png differ diff --git a/public/images/pokemon/variant/exp/back/978-droopy_2.png b/public/images/pokemon/variant/exp/back/978-droopy_2.png index ddd0430bca6..ed0999c43ca 100644 Binary files a/public/images/pokemon/variant/exp/back/978-droopy_2.png and b/public/images/pokemon/variant/exp/back/978-droopy_2.png differ diff --git a/public/images/pokemon/variant/exp/back/978-droopy_3.png b/public/images/pokemon/variant/exp/back/978-droopy_3.png index 6fa78fb9fef..22416861830 100644 Binary files a/public/images/pokemon/variant/exp/back/978-droopy_3.png and b/public/images/pokemon/variant/exp/back/978-droopy_3.png differ diff --git a/public/images/pokemon/variant/female/3_2.png b/public/images/pokemon/variant/female/3_2.png index df83d7b05e2..8e955e2c82f 100644 Binary files a/public/images/pokemon/variant/female/3_2.png and b/public/images/pokemon/variant/female/3_2.png differ diff --git a/public/images/pokemon/variant/female/402_2.png b/public/images/pokemon/variant/female/402_2.png index 3ce28cc787a..b9fd36890a3 100644 Binary files a/public/images/pokemon/variant/female/402_2.png and b/public/images/pokemon/variant/female/402_2.png differ diff --git a/public/images/pokemon/variant/female/402_3.png b/public/images/pokemon/variant/female/402_3.png index a34ef79b0ff..5e43029bfdb 100644 Binary files a/public/images/pokemon/variant/female/402_3.png and b/public/images/pokemon/variant/female/402_3.png differ diff --git a/public/images/pokemon/variant/female/419_2.png b/public/images/pokemon/variant/female/419_2.png index 897efbd57ba..ca9ea1d6f72 100644 Binary files a/public/images/pokemon/variant/female/419_2.png and b/public/images/pokemon/variant/female/419_2.png differ diff --git a/public/images/pokemon_icons_1.json b/public/images/pokemon_icons_1.json index 49e471514cd..12e26b380a5 100644 --- a/public/images/pokemon_icons_1.json +++ b/public/images/pokemon_icons_1.json @@ -1647,6 +1647,27 @@ "h": 25 } }, + { + "filename": "85-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 3, + "w": 29, + "h": 25 + }, + "frame": { + "x": 55, + "y": 270, + "w": 29, + "h": 25 + } + }, { "filename": "22s", "rotated": false, @@ -1731,6 +1752,27 @@ "h": 25 } }, + { + "filename": "85s-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 3, + "w": 29, + "h": 25 + }, + "frame": { + "x": 56, + "y": 317, + "w": 29, + "h": 25 + } + }, { "filename": "9s", "rotated": false, @@ -6456,6 +6498,27 @@ "h": 18 } }, + { + "filename": "84-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 10, + "w": 21, + "h": 18 + }, + "frame": { + "x": 98, + "y": 712, + "w": 21, + "h": 18 + } + }, { "filename": "107", "rotated": false, @@ -6519,6 +6582,27 @@ "h": 18 } }, + { + "filename": "84s-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 10, + "w": 21, + "h": 18 + }, + "frame": { + "x": 96, + "y": 770, + "w": 21, + "h": 18 + } + }, { "filename": "88", "rotated": false, diff --git a/public/images/pokemon_icons_2.json b/public/images/pokemon_icons_2.json index 5a389362bc0..c5ebfe61487 100644 --- a/public/images/pokemon_icons_2.json +++ b/public/images/pokemon_icons_2.json @@ -786,6 +786,27 @@ "h": 27 } }, + { + "filename": "154-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 1, + "w": 23, + "h": 27 + }, + "frame": { + "x": 29, + "y": 147, + "w": 23, + "h": 27 + } + }, { "filename": "154s", "rotated": false, @@ -807,6 +828,27 @@ "h": 27 } }, + { + "filename": "154s-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 1, + "w": 23, + "h": 27 + }, + "frame": { + "x": 29, + "y": 174, + "w": 23, + "h": 27 + } + }, { "filename": "229-mega", "rotated": false, diff --git a/public/images/pokemon_icons_3.json b/public/images/pokemon_icons_3.json index 220d91f5222..a1aefa0ff0b 100644 --- a/public/images/pokemon_icons_3.json +++ b/public/images/pokemon_icons_3.json @@ -198,6 +198,27 @@ "h": 27 } }, + { + "filename": "257-f-mega", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 32, + "h": 27 + }, + "frame": { + "x": 0, + "y": 79, + "w": 32, + "h": 27 + } + }, { "filename": "257s-mega", "rotated": false, @@ -219,6 +240,27 @@ "h": 27 } }, + { + "filename": "257s-f-mega", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 32, + "h": 27 + }, + "frame": { + "x": 0, + "y": 106, + "w": 32, + "h": 27 + } + }, { "filename": "323-mega", "rotated": false, @@ -1248,6 +1290,27 @@ "h": 26 } }, + { + "filename": "257-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 2, + "w": 25, + "h": 26 + }, + "frame": { + "x": 28, + "y": 556, + "w": 25, + "h": 26 + } + }, { "filename": "257s", "rotated": false, @@ -1269,6 +1332,27 @@ "h": 26 } }, + { + "filename": "257s-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 2, + "w": 25, + "h": 26 + }, + "frame": { + "x": 28, + "y": 582, + "w": 25, + "h": 26 + } + }, { "filename": "359-mega", "rotated": false, @@ -1605,6 +1689,27 @@ "h": 25 } }, + { + "filename": "256-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 3, + "w": 23, + "h": 25 + }, + "frame": { + "x": 98, + "y": 72, + "w": 23, + "h": 25 + } + }, { "filename": "282s-mega", "rotated": false, @@ -5553,6 +5658,27 @@ "h": 19 } }, + { + "filename": "255-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 9, + "w": 13, + "h": 19 + }, + "frame": { + "x": 204, + "y": 342, + "w": 13, + "h": 19 + } + }, { "filename": "307s", "rotated": false, diff --git a/public/locales b/public/locales index fc4a1effd51..ed1b1df4776 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit fc4a1effd5170def3c8314208a52cd0d8e6913ef +Subproject commit ed1b1df4776ccd4330e8ac1d2f44de611d04c2bc diff --git a/src/@types/PokerogueSessionSavedataApi.ts b/src/@types/PokerogueSessionSavedataApi.ts index 5fcd8575b15..c4650611c4f 100644 --- a/src/@types/PokerogueSessionSavedataApi.ts +++ b/src/@types/PokerogueSessionSavedataApi.ts @@ -8,6 +8,7 @@ export class UpdateSessionSavedataRequest { /** This is **NOT** similar to {@linkcode ClearSessionSavedataRequest} */ export interface NewClearSessionSavedataRequest { slot: number; + isVictory: boolean; clientSessionId: string; } diff --git a/src/battle-scene.ts b/src/battle-scene.ts index cde10b4dd53..3e072383c8f 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -774,7 +774,7 @@ export default class BattleScene extends SceneBase { /** * @returns An array of {@linkcode PlayerPokemon} filtered from the player's party - * that are {@linkcode PlayerPokemon.isAllowedInBattle | allowed in battle}. + * that are {@linkcode Pokemon.isAllowedInBattle | allowed in battle}. */ public getPokemonAllowedInBattle(): PlayerPokemon[] { return this.getPlayerParty().filter(p => p.isAllowedInBattle()); @@ -1233,33 +1233,64 @@ export default class BattleScene extends SceneBase { newDouble = !!double; } - if (Overrides.BATTLE_TYPE_OVERRIDE === "double") { - newDouble = true; - } - /* Override battles into single only if not fighting with trainers */ - if (newBattleType !== BattleType.TRAINER && Overrides.BATTLE_TYPE_OVERRIDE === "single") { + // Disable double battles on Endless/Endless Spliced Wave 50x boss battles (Introduced 1.2.0) + if (this.gameMode.isEndlessBoss(newWaveIndex)) { newDouble = false; } - const lastBattle = this.currentBattle; + if (!isNullOrUndefined(Overrides.BATTLE_TYPE_OVERRIDE)) { + let doubleOverrideForWave: "single" | "double" | null = null; - if (lastBattle?.double && !newDouble) { - this.tryRemovePhase(p => p instanceof SwitchPhase); + switch (Overrides.BATTLE_TYPE_OVERRIDE) { + case "double": + doubleOverrideForWave = "double"; + break; + case "single": + doubleOverrideForWave = "single"; + break; + case "even-doubles": + doubleOverrideForWave = (newWaveIndex % 2) ? "single" : "double"; + break; + case "odd-doubles": + doubleOverrideForWave = (newWaveIndex % 2) ? "double" : "single"; + break; + } + + if (doubleOverrideForWave === "double") { + newDouble = true; + } + /** + * Override battles into single only if not fighting with trainers. + * @see {@link https://github.com/pagefaultgames/pokerogue/issues/1948 | GitHub Issue #1948} + */ + if (newBattleType !== BattleType.TRAINER && doubleOverrideForWave === "single") { + newDouble = false; + } } + const lastBattle = this.currentBattle; + const maxExpLevel = this.getMaxExpLevel(); this.lastEnemyTrainer = lastBattle?.trainer ?? null; this.lastMysteryEncounter = lastBattle?.mysteryEncounter; + if (newBattleType === BattleType.MYSTERY_ENCOUNTER) { + // Disable double battle on mystery encounters (it may be re-enabled as part of encounter) + newDouble = false; + } + + if (lastBattle?.double && !newDouble) { + this.tryRemovePhase(p => p instanceof SwitchPhase); + this.getPlayerField().forEach(p => p.lapseTag(BattlerTagType.COMMANDED)); + } + this.executeWithSeedOffset(() => { this.currentBattle = new Battle(this.gameMode, newWaveIndex, newBattleType, newTrainer, newDouble); }, newWaveIndex << 3, this.waveSeed); this.currentBattle.incrementTurn(this); if (newBattleType === BattleType.MYSTERY_ENCOUNTER) { - // Disable double battle on mystery encounters (it may be re-enabled as part of encounter) - this.currentBattle.double = false; // Will generate the actual Mystery Encounter during NextEncounterPhase, to ensure it uses proper biome this.currentBattle.mysteryEncounterType = mysteryEncounterType; } @@ -1391,10 +1422,19 @@ export default class BattleScene extends SceneBase { case Species.PALDEA_TAUROS: return Utils.randSeedInt(species.forms.length); case Species.PIKACHU: + if (this.currentBattle?.battleType === BattleType.TRAINER && this.currentBattle?.waveIndex < 30) { + return 0; // Ban Cosplay and Partner Pika from Trainers before wave 30 + } return Utils.randSeedInt(8); case Species.EEVEE: + if (this.currentBattle?.battleType === BattleType.TRAINER && this.currentBattle?.waveIndex < 30) { + return 0; // No Partner Eevee for Wave 12 Preschoolers + } return Utils.randSeedInt(2); case Species.GRENINJA: + if (this.currentBattle?.battleType === BattleType.TRAINER) { + return 0; // Don't give trainers Battle Bond Greninja + } return Utils.randSeedInt(2); case Species.ZYGARDE: return Utils.randSeedInt(4); @@ -2566,14 +2606,15 @@ export default class BattleScene extends SceneBase { * The quantity to transfer is automatically capped at how much the recepient can take before reaching the maximum stack size for the item. * A transfer that moves a quantity smaller than what is specified in the transferQuantity parameter is still considered successful. * @param itemModifier {@linkcode PokemonHeldItemModifier} item to transfer (represents the whole stack) - * @param target {@linkcode Pokemon} pokemon recepient in this transfer - * @param playSound {boolean} - * @param transferQuantity {@linkcode integer} how many items of the stack to transfer. Optional, defaults to 1 - * @param instant {boolean} - * @param ignoreUpdate {boolean} - * @returns true if the transfer was successful + * @param target {@linkcode Pokemon} recepient in this transfer + * @param playSound `true` to play a sound when transferring the item + * @param transferQuantity How many items of the stack to transfer. Optional, defaults to `1` + * @param instant ??? (Optional) + * @param ignoreUpdate ??? (Optional) + * @param itemLost If `true`, treat the item's current holder as losing the item (for now, this simply enables Unburden). Default is `true`. + * @returns `true` if the transfer was successful */ - tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, playSound: boolean, transferQuantity: integer = 1, instant?: boolean, ignoreUpdate?: boolean): Promise { + tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, playSound: boolean, transferQuantity: number = 1, instant?: boolean, ignoreUpdate?: boolean, itemLost: boolean = true): Promise { return new Promise(resolve => { const source = itemModifier.pokemonId ? itemModifier.getPokemon(target.scene) : null; const cancelled = new Utils.BooleanHolder(false); @@ -2606,14 +2647,14 @@ export default class BattleScene extends SceneBase { if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) { if (target.isPlayer()) { this.addModifier(newItemModifier, ignoreUpdate, playSound, false, instant).then(() => { - if (source) { + if (source && itemLost) { applyPostItemLostAbAttrs(PostItemLostAbAttr, source, false); } resolve(true); }); } else { this.addEnemyModifier(newItemModifier, ignoreUpdate, instant).then(() => { - if (source) { + if (source && itemLost) { applyPostItemLostAbAttrs(PostItemLostAbAttr, source, false); } resolve(true); @@ -2785,7 +2826,15 @@ export default class BattleScene extends SceneBase { }); } - removeModifier(modifier: PersistentModifier, enemy?: boolean): boolean { + /** + * Removes a currently owned item. If the item is stacked, the entire item stack + * gets removed. This function does NOT apply in-battle effects, such as Unburden. + * If in-battle effects are needed, use {@linkcode Pokemon.loseHeldItem} instead. + * @param modifier The item to be removed. + * @param enemy If `true`, remove an item owned by the enemy. If `false`, remove an item owned by the player. Default is `false`. + * @returns `true` if the item exists and was successfully removed, `false` otherwise. + */ + removeModifier(modifier: PersistentModifier, enemy: boolean = false): boolean { const modifiers = !enemy ? this.modifiers : this.enemyModifiers; const modifierIndex = modifiers.indexOf(modifier); if (modifierIndex > -1) { diff --git a/src/data/ability.ts b/src/data/ability.ts index 08dc1ed27a4..3103c08cee6 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -7,7 +7,7 @@ import { Weather } from "#app/data/weather"; import { BattlerTag, BattlerTagLapseType, GroundedTag } from "./battler-tags"; import { getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "#app/data/status-effect"; import { Gender } from "./gender"; -import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move"; +import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { BerryModifier, HitHealModifier, PokemonHeldItemModifier } from "../modifier/modifier"; import { TerrainType } from "./terrain"; @@ -516,7 +516,7 @@ export class NonSuperEffectiveImmunityAbAttr extends TypeImmunityAbAttr { applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { const modifierValue = args.length > 0 ? (args[0] as Utils.NumberHolder).value - : pokemon.getAttackTypeEffectiveness(attacker.getMoveType(move), attacker); + : pokemon.getAttackTypeEffectiveness(attacker.getMoveType(move), attacker, undefined, undefined, move); if (move instanceof AttackMove && modifierValue < 2) { cancelled.value = true; // Suppresses "No Effect" message @@ -1351,65 +1351,30 @@ export class AddSecondStrikeAbAttr extends PreAttackAbAttr { this.damageMultiplier = damageMultiplier; } - /** - * Determines whether this attribute can apply to a given move. - * @param {Move} move the move to which this attribute may apply - * @param numTargets the number of {@linkcode Pokemon} targeted by this move - * @returns true if the attribute can apply to the move, false otherwise - */ - canApplyPreAttack(move: Move, numTargets: integer): boolean { - /** - * Parental Bond cannot apply to multi-hit moves, charging moves, or - * moves that cause the user to faint. - */ - const exceptAttrs: Constructor[] = [ - MultiHitAttr, - SacrificialAttr, - SacrificialAttrOnHit - ]; - - /** Parental Bond cannot apply to these specific moves */ - const exceptMoves: Moves[] = [ - Moves.FLING, - Moves.UPROAR, - Moves.ROLLOUT, - Moves.ICE_BALL, - Moves.ENDEAVOR - ]; - - /** Also check if this move is an Attack move and if it's only targeting one Pokemon */ - return numTargets === 1 - && !move.isChargingMove() - && !exceptAttrs.some(attr => move.hasAttr(attr)) - && !exceptMoves.some(id => move.id === id) - && move.category !== MoveCategory.STATUS; - } - /** * If conditions are met, this doubles the move's hit count (via args[1]) * or multiplies the damage of secondary strikes (via args[2]) - * @param {Pokemon} pokemon the Pokemon using the move + * @param pokemon the {@linkcode Pokemon} using the move * @param passive n/a * @param defender n/a - * @param {Move} move the move used by the ability source - * @param args\[0\] the number of Pokemon this move is targeting - * @param {Utils.IntegerHolder} args\[1\] the number of strikes with this move - * @param {Utils.NumberHolder} args\[2\] the damage multiplier for the current strike + * @param move the {@linkcode Move} used by the ability source + * @param args Additional arguments: + * - `[0]` the number of strikes this move currently has ({@linkcode Utils.NumberHolder}) + * - `[1]` the damage multiplier for the current strike ({@linkcode Utils.NumberHolder}) * @returns */ applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { - const numTargets = args[0] as integer; - const hitCount = args[1] as Utils.IntegerHolder; - const multiplier = args[2] as Utils.NumberHolder; + const hitCount = args[0] as Utils.NumberHolder; + const multiplier = args[1] as Utils.NumberHolder; - if (this.canApplyPreAttack(move, numTargets)) { + if (move.canBeMultiStrikeEnhanced(pokemon, true)) { this.showAbility = !!hitCount?.value; - if (!!hitCount?.value) { - hitCount.value *= 2; + if (hitCount?.value) { + hitCount.value += 1; } - if (!!multiplier?.value && pokemon.turnData.hitsLeft % 2 === 1 && pokemon.turnData.hitsLeft !== pokemon.turnData.hitCount) { - multiplier.value *= this.damageMultiplier; + if (multiplier?.value && pokemon.turnData.hitsLeft === 1) { + multiplier.value = this.damageMultiplier; } return true; } @@ -2463,12 +2428,15 @@ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr { } } +/** + * Used by Imposter + */ export class PostSummonTransformAbAttr extends PostSummonAbAttr { constructor() { super(true); } - async applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): Promise { + async applyPostSummon(pokemon: Pokemon, _passive: boolean, simulated: boolean, _args: any[]): Promise { const targets = pokemon.getOpponents(); if (simulated || !targets.length) { return simulated; @@ -2477,17 +2445,31 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { let target: Pokemon; if (targets.length > 1) { - pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); + pokemon.scene.executeWithSeedOffset(() => { + // in a double battle, if one of the opposing pokemon is fused the other one will be chosen + // if both are fused, then Imposter will fail below + if (targets[0].fusionSpecies) { + target = targets[1]; + return; + } else if (targets[1].fusionSpecies) { + target = targets[0]; + return; + } + target = Utils.randSeedItem(targets); + }, pokemon.scene.currentBattle.waveIndex); } else { target = targets[0]; } - target = target!; + + // transforming from or into fusion pokemon causes various problems (including crashes and save corruption) + if (target.fusionSpecies || pokemon.fusionSpecies) { + return false; + } + pokemon.summonData.speciesForm = target.getSpeciesForm(); - pokemon.summonData.fusionSpeciesForm = target.getFusionSpeciesForm(); pokemon.summonData.ability = target.getAbility().id; pokemon.summonData.gender = target.getGender(); - pokemon.summonData.fusionGender = target.getFusionGender(); // Copy all stats (except HP) for (const s of EFFECTIVE_STATS) { @@ -3198,7 +3180,7 @@ function getAnticipationCondition(): AbAttrCondition { continue; } // the move's base type (not accounting for variable type changes) is super effective - if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent, true) >= 2) { + if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent, true, undefined, move.getMove()) >= 2) { return true; } // move is a OHKO @@ -4135,7 +4117,7 @@ export class PostBattleLootAbAttr extends PostBattleAbAttr { if (!simulated && postBattleLoot.length) { const randItem = Utils.randSeedItem(postBattleLoot); //@ts-ignore - TODO see below - if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, true, 1, true)) { // TODO: fix. This is a promise!? + if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, true, 1, true, undefined, false)) { // TODO: fix. This is a promise!? postBattleLoot.splice(postBattleLoot.indexOf(randItem), 1); pokemon.scene.queueMessage(i18next.t("abilityTriggers:postBattleLoot", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), itemName: randItem.type.name })); return true; @@ -4969,9 +4951,10 @@ class ForceSwitchOutHelper { } /** * For wild Pokémon battles, the Pokémon will flee if the conditions are met (waveIndex and double battles). + * It will not flee if it is a Mystery Encounter with fleeing disabled (checked in `getSwitchOutCondition()`) or if it is a wave 10x wild boss */ } else { - if (!pokemon.scene.currentBattle.waveIndex && pokemon.scene.currentBattle.waveIndex % 10 === 0) { + if (!pokemon.scene.currentBattle.waveIndex || pokemon.scene.currentBattle.waveIndex % 10 === 0) { return false; } @@ -5599,7 +5582,9 @@ export function initAbilities() { new Ability(Abilities.ANGER_POINT, 4) .attr(PostDefendCritStatStageChangeAbAttr, Stat.ATK, 6), new Ability(Abilities.UNBURDEN, 4) - .attr(PostItemLostApplyBattlerTagAbAttr, BattlerTagType.UNBURDEN), + .attr(PostItemLostApplyBattlerTagAbAttr, BattlerTagType.UNBURDEN) + .bypassFaint() // Allows reviver seed to activate Unburden + .edgeCase(), // Should not restore Unburden boost if Pokemon loses then regains Unburden ability new Ability(Abilities.HEATPROOF, 4) .attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5) .attr(ReduceBurnDamageAbAttr, 0.5) @@ -6106,11 +6091,9 @@ export function initAbilities() { new Ability(Abilities.NEUROFORCE, 7) .attr(MovePowerBoostAbAttr, (user, target, move) => (target?.getMoveEffectiveness(user!, move) ?? 1) >= 2, 1.25), new Ability(Abilities.INTREPID_SWORD, 8) - .attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true) - .condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)), + .attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true), new Ability(Abilities.DAUNTLESS_SHIELD, 8) - .attr(PostSummonStatStageChangeAbAttr, [ Stat.DEF ], 1, true) - .condition(getOncePerBattleCondition(Abilities.DAUNTLESS_SHIELD)), + .attr(PostSummonStatStageChangeAbAttr, [ Stat.DEF ], 1, true), new Ability(Abilities.LIBERO, 8) .attr(PokemonTypeChangeAbAttr), //.condition((p) => !p.summonData?.abilitiesApplied.includes(Abilities.LIBERO)), //Gen 9 Implementation @@ -6137,8 +6120,7 @@ export function initAbilities() { .attr(NoFusionAbilityAbAttr) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) - .bypassFaint() - .edgeCase(), // Soft-locks the game if a form-changed Cramorant and its attacker both faint at the same time (ex. using Self-Destruct) + .bypassFaint(), new Ability(Abilities.STALWART, 8) .attr(BlockRedirectAbAttr), new Ability(Abilities.STEAM_ENGINE, 8) diff --git a/src/data/balance/tms.ts b/src/data/balance/tms.ts index 7b65ae65ec4..4882cf4f652 100644 --- a/src/data/balance/tms.ts +++ b/src/data/balance/tms.ts @@ -3302,11 +3302,23 @@ export const tmSpecies: TmSpecies = { Species.FERALIGATR, Species.SENTRET, Species.FURRET, + Species.HOOTHOOT, Species.NOCTOWL, + Species.LEDYBA, + Species.LEDIAN, + Species.SPINARAK, + Species.ARIADOS, Species.CROBAT, Species.CHINCHOU, Species.LANTURN, + Species.PICHU, + Species.CLEFFA, Species.IGGLYBUFF, + Species.TYROGUE, + Species.TOGEPI, + Species.TOGETIC, + Species.NATU, + Species.XATU, Species.MAREEP, Species.FLAAFFY, Species.AMPHAROS, @@ -3328,6 +3340,7 @@ export const tmSpecies: TmSpecies = { Species.UMBREON, Species.MURKROW, Species.SLOWKING, + Species.MISDREAVUS, Species.GIRAFARIG, Species.PINECO, Species.FORRETRESS, @@ -3338,11 +3351,21 @@ export const tmSpecies: TmSpecies = { Species.GRANBULL, Species.QWILFISH, Species.SCIZOR, + Species.SHUCKLE, Species.HERACROSS, + Species.SNEASEL, Species.TEDDIURSA, Species.URSARING, + Species.SLUGMA, + Species.MAGCARGO, Species.SWINUB, Species.PILOSWINE, + Species.CORSOLA, + Species.REMORAID, + Species.OCTILLERY, + Species.DELIBIRD, + Species.MANTINE, + Species.SKARMORY, Species.HOUNDOUR, Species.HOUNDOOM, Species.KINGDRA, @@ -3350,9 +3373,12 @@ export const tmSpecies: TmSpecies = { Species.DONPHAN, Species.PORYGON2, Species.STANTLER, + Species.TYROGUE, Species.HITMONTOP, + Species.SMOOCHUM, Species.ELEKID, Species.MAGBY, + Species.MILTANK, Species.BLISSEY, Species.RAIKOU, Species.ENTEI, @@ -3362,6 +3388,9 @@ export const tmSpecies: TmSpecies = { Species.TYRANITAR, Species.LUGIA, Species.HO_OH, + Species.CELEBI, + Species.TREECKO, + Species.GROVYLE, Species.SCEPTILE, Species.TORCHIC, Species.COMBUSKEN, @@ -3371,41 +3400,116 @@ export const tmSpecies: TmSpecies = { Species.SWAMPERT, Species.POOCHYENA, Species.MIGHTYENA, + Species.ZIGZAGOON, + Species.LINOONE, + Species.BEAUTIFLY, + Species.DUSTOX, Species.LOTAD, Species.LOMBRE, Species.LUDICOLO, Species.SEEDOT, Species.NUZLEAF, Species.SHIFTRY, + Species.TAILLOW, + Species.SWELLOW, + Species.WINGULL, + Species.PELIPPER, + Species.RALTS, + Species.KIRLIA, + Species.GARDEVOIR, + Species.SURSKIT, + Species.MASQUERAIN, + Species.SHROOMISH, + Species.BRELOOM, Species.VIGOROTH, Species.SLAKING, + Species.NINCADA, + Species.NINJASK, + Species.SHEDINJA, + Species.WHISMUR, + Species.LOUDRED, + Species.EXPLOUD, Species.MAKUHITA, Species.HARIYAMA, + Species.AZURILL, Species.NOSEPASS, + Species.SKITTY, + Species.DELCATTY, + Species.SABLEYE, + Species.MAWILE, + Species.ARON, + Species.LAIRON, + Species.AGGRON, + Species.MEDITITE, + Species.MEDICHAM, + Species.ELECTRIKE, + Species.MANECTRIC, + Species.PLUSLE, + Species.MINUN, Species.VOLBEAT, Species.ILLUMISE, + Species.ROSELIA, + Species.GULPIN, Species.SWALOT, + Species.CARVANHA, + Species.SHARPEDO, + Species.WAILMER, + Species.WAILORD, Species.NUMEL, Species.CAMERUPT, Species.TORKOAL, + Species.SPOINK, + Species.GRUMPIG, + Species.SPINDA, + Species.TRAPINCH, + Species.VIBRAVA, Species.FLYGON, + Species.CACNEA, + Species.CACTURNE, + Species.SWABLU, Species.ALTARIA, Species.ZANGOOSE, Species.SEVIPER, + Species.LUNATONE, + Species.SOLROCK, Species.BARBOACH, Species.WHISCASH, Species.CORPHISH, Species.CRAWDAUNT, + Species.BALTOY, + Species.CLAYDOL, + Species.LILEEP, + Species.CRADILY, + Species.ANORITH, + Species.ARMALDO, Species.FEEBAS, Species.MILOTIC, + Species.CASTFORM, + Species.KECLEON, + Species.SHUPPET, + Species.BANETTE, + Species.DUSKULL, + Species.DUSCLOPS, Species.TROPIUS, Species.CHIMECHO, + Species.ABSOL, + Species.SNORUNT, + Species.GLALIE, + Species.SPHEAL, + Species.SEALEO, + Species.WALREIN, + Species.CLAMPERL, + Species.HUNTAIL, + Species.GOREBYSS, + Species.RELICANTH, + Species.LUVDISC, Species.BAGON, Species.SHELGON, Species.SALAMENCE, Species.METANG, Species.METAGROSS, Species.REGIROCK, + Species.REGICE, Species.REGISTEEL, Species.LATIAS, Species.LATIOS, @@ -3413,6 +3517,7 @@ export const tmSpecies: TmSpecies = { Species.GROUDON, Species.RAYQUAZA, Species.JIRACHI, + Species.DEOXYS, Species.TURTWIG, Species.GROTLE, Species.TORTERRA, @@ -64246,12 +64351,16 @@ export const tmSpecies: TmSpecies = { Species.BLOODMOON_URSALUNA, ], [Moves.LIQUIDATION]: [ + Species.SQUIRTLE, + Species.WARTORTLE, Species.BLASTOISE, Species.PSYDUCK, Species.GOLDUCK, Species.POLIWAG, Species.POLIWHIRL, Species.POLIWRATH, + Species.TENTACOOL, + Species.TENTACRUEL, Species.SLOWPOKE, Species.SLOWBRO, Species.DEWGONG, @@ -64267,7 +64376,11 @@ export const tmSpecies: TmSpecies = { Species.KABUTO, Species.KABUTOPS, Species.MEW, + Species.TOTODILE, + Species.CROCONAW, Species.FERALIGATR, + Species.CHINCHOU, + Species.LANTURN, Species.MARILL, Species.AZUMARILL, Species.POLITOED, @@ -64280,6 +64393,9 @@ export const tmSpecies: TmSpecies = { Species.MANTINE, Species.KINGDRA, Species.SUICUNE, + Species.LUGIA, + Species.MUDKIP, + Species.MARSHTOMP, Species.SWAMPERT, Species.WINGULL, Species.PELIPPER, @@ -64296,6 +64412,8 @@ export const tmSpecies: TmSpecies = { Species.WALREIN, Species.RELICANTH, Species.LUVDISC, + Species.LATIAS, + Species.LATIOS, Species.KYOGRE, Species.PIPLUP, Species.PRINPLUP, @@ -64407,11 +64525,13 @@ export const tmSpecies: TmSpecies = { Species.ONIX, Species.HYPNO, Species.LICKITUNG, + Species.RHYHORN, Species.RHYDON, Species.LAPRAS, Species.SNORLAX, Species.DRAGONITE, Species.MEW, + Species.MEGANIUM, Species.SUDOWOODO, Species.QUAGSIRE, Species.FORRETRESS, @@ -64445,6 +64565,8 @@ export const tmSpecies: TmSpecies = { Species.REGISTEEL, Species.GROUDON, Species.TORTERRA, + Species.RAMPARDOS, + Species.BASTIODON, Species.BRONZONG, Species.HIPPOPOTAS, Species.HIPPOWDON, @@ -64459,6 +64581,7 @@ export const tmSpecies: TmSpecies = { Species.HEATRAN, Species.REGIGIGAS, Species.ARCEUS, + Species.EMBOAR, Species.ROGGENROLA, Species.BOLDORE, Species.GIGALITH, @@ -64471,6 +64594,7 @@ export const tmSpecies: TmSpecies = { Species.CUBCHOO, Species.BEARTIC, Species.GOLURK, + Species.COBALION, Species.RESHIRAM, Species.ZEKROM, Species.KYUREM, diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 25d65fbc372..ce25b56157c 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1502,9 +1502,14 @@ export class ContactBurnProtectedTag extends DamageProtectedTag { } } +/** + * `BattlerTag` class for effects that cause the affected Pokemon to survive lethal attacks at 1 HP. + * Used for {@link https://bulbapedia.bulbagarden.net/wiki/Endure_(move) | Endure} and + * Endure Tokens. + */ export class EnduringTag extends BattlerTag { - constructor(sourceMove: Moves) { - super(BattlerTagType.ENDURING, BattlerTagLapseType.TURN_END, 0, sourceMove); + constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: Moves) { + super(tagType, lapseType, 0, sourceMove); } onAdd(pokemon: Pokemon): void { @@ -1809,8 +1814,8 @@ export class TypeImmuneTag extends BattlerTag { * @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | Moves.TELEKINESIS} */ export class FloatingTag extends TypeImmuneTag { - constructor(tagType: BattlerTagType, sourceMove: Moves) { - super(tagType, sourceMove, Type.GROUND, 5); + constructor(tagType: BattlerTagType, sourceMove: Moves, turnCount: number) { + super(tagType, sourceMove, Type.GROUND, turnCount); } onAdd(pokemon: Pokemon): void { @@ -2158,6 +2163,11 @@ export class CommandedTag extends BattlerTag { pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.COMMANDER_REMOVE); } } + + override loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this._tatsugiriFormKey = source._tatsugiriFormKey; + } } /** @@ -3004,7 +3014,9 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source case BattlerTagType.BURNING_BULWARK: return new ContactBurnProtectedTag(sourceMove); case BattlerTagType.ENDURING: - return new EnduringTag(sourceMove); + return new EnduringTag(tagType, BattlerTagLapseType.TURN_END, sourceMove); + case BattlerTagType.ENDURE_TOKEN: + return new EnduringTag(tagType, BattlerTagLapseType.AFTER_HIT, sourceMove); case BattlerTagType.STURDY: return new SturdyTag(sourceMove); case BattlerTagType.PERISH_SONG: @@ -3053,7 +3065,7 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source case BattlerTagType.CHARGED: return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); case BattlerTagType.FLOATING: - return new FloatingTag(tagType, sourceMove); + return new FloatingTag(tagType, sourceMove, turnCount); case BattlerTagType.MINIMIZED: return new MinimizeTag(); case BattlerTagType.DESTINY_BOND: diff --git a/src/data/berry.ts b/src/data/berry.ts index d2bbd0fdd1c..dfd6a7ddcf0 100644 --- a/src/data/berry.ts +++ b/src/data/berry.ts @@ -61,13 +61,13 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate { } } -export type BerryEffectFunc = (pokemon: Pokemon) => void; +export type BerryEffectFunc = (pokemon: Pokemon, berryOwner?: Pokemon) => void; export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { switch (berryType) { case BerryType.SITRUS: case BerryType.ENIGMA: - return (pokemon: Pokemon) => { + return (pokemon: Pokemon, berryOwner?: Pokemon) => { if (pokemon.battleData) { pokemon.battleData.berriesEaten.push(berryType); } @@ -75,10 +75,10 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, hpHealed); pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), hpHealed.value, i18next.t("battle:hpHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: getBerryName(berryType) }), true)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); + applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); }; case BerryType.LUM: - return (pokemon: Pokemon) => { + return (pokemon: Pokemon, berryOwner?: Pokemon) => { if (pokemon.battleData) { pokemon.battleData.berriesEaten.push(berryType); } @@ -87,14 +87,14 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { } pokemon.resetStatus(true, true); pokemon.updateInfo(); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); + applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); }; case BerryType.LIECHI: case BerryType.GANLON: case BerryType.PETAYA: case BerryType.APICOT: case BerryType.SALAC: - return (pokemon: Pokemon) => { + return (pokemon: Pokemon, berryOwner?: Pokemon) => { if (pokemon.battleData) { pokemon.battleData.berriesEaten.push(berryType); } @@ -103,18 +103,18 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { const statStages = new Utils.NumberHolder(1); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], statStages.value)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); + applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); }; case BerryType.LANSAT: - return (pokemon: Pokemon) => { + return (pokemon: Pokemon, berryOwner?: Pokemon) => { if (pokemon.battleData) { pokemon.battleData.berriesEaten.push(berryType); } pokemon.addTag(BattlerTagType.CRIT_BOOST); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); + applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); }; case BerryType.STARF: - return (pokemon: Pokemon) => { + return (pokemon: Pokemon, berryOwner?: Pokemon) => { if (pokemon.battleData) { pokemon.battleData.berriesEaten.push(berryType); } @@ -122,10 +122,10 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { const stages = new Utils.NumberHolder(2); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randStat ], stages.value)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); + applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); }; case BerryType.LEPPA: - return (pokemon: Pokemon) => { + return (pokemon: Pokemon, berryOwner?: Pokemon) => { if (pokemon.battleData) { pokemon.battleData.berriesEaten.push(berryType); } @@ -133,7 +133,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { if (ppRestoreMove !== undefined) { ppRestoreMove!.ppUsed = Math.max(ppRestoreMove!.ppUsed - 10, 0); pokemon.scene.queueMessage(i18next.t("battle:ppHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: ppRestoreMove!.getName(), berryName: getBerryName(berryType) })); - applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); + applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); } }; } diff --git a/src/data/challenge.ts b/src/data/challenge.ts index af6bbf5b00f..4301ea7b375 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -653,7 +653,7 @@ export class FreshStartChallenge extends Challenge { pokemon.shiny = false; // Not shiny pokemon.variant = 0; // Not shiny pokemon.formIndex = 0; // Froakie should be base form - pokemon.ivs = [ 10, 10, 10, 10, 10, 10 ]; // Default IVs of 10 for all stats + pokemon.ivs = [ 15, 15, 15, 15, 15, 15 ]; // Default IVs of 15 for all stats (Updated to 15 from 10 in 1.2.0) return true; } diff --git a/src/data/egg.ts b/src/data/egg.ts index f7d109dfa62..7f1deecc63f 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -17,39 +17,44 @@ export const EGG_SEED = 1073741824; /** Egg options to override egg properties */ export interface IEggOptions { - /** Id. Used to check if egg type will be manaphy (id % 204 === 0) */ + /** ID. Used to check if egg type will be manaphy (`id % 204 === 0`) */ id?: number; /** Timestamp when this egg got created */ timestamp?: number; - /** Defines if the egg got pulled from a gacha or not. If true, egg pity and pull statistics will be applyed. + /** + * Defines if the egg got pulled from a gacha or not. If true, egg pity and pull statistics will be applyed. * Egg will be automaticly added to the game data. - * NEEDS scene eggOption to work. + * NEEDS `scene` `eggOption` to work. */ pulled?: boolean; - /** Defines where the egg comes from. Applies specific modifiers. + /** + * Defines where the egg comes from. Applies specific modifiers. * Will also define the text displayed in the egg list. */ sourceType?: EggSourceType; - /** Needs to be defined if eggOption pulled is defined or if no species or isShiny is degined since this will be needed to generate them. */ + /** Needs to be defined if `eggOption` pulled is defined or if no species or `isShiny` is defined since this will be needed to generate them. */ scene?: BattleScene; - /** Sets the tier of the egg. Only species of this tier can be hatched from this egg. - * Tier will be overriden if species eggOption is set. + /** + * Sets the tier of the egg. Only species of this tier can be hatched from this egg. + * Tier will be overriden if species `eggOption` is set. */ tier?: EggTier; /** Sets how many waves it will take till this egg hatches. */ hatchWaves?: number; - /** Sets the exact species that will hatch from this egg. - * Needs scene eggOption if not provided. + /** + * Sets the exact species that will hatch from this egg. + * Needs `scene` `eggOption` if not provided. */ species?: Species; /** Defines if the hatched pokemon will be a shiny. */ isShiny?: boolean; - /** Defines the variant of the pokemon that will hatch from this egg. If no variantTier is given the normal variant rates will apply. */ + /** Defines the variant of the pokemon that will hatch from this egg. If no `variantTier` is given the normal variant rates will apply. */ variantTier?: VariantTier; - /** Defines which egg move will be unlocked. 3 = rare egg move. */ + /** Defines which egg move will be unlocked. `3` = rare egg move. */ eggMoveIndex?: number; - /** Defines if the egg will hatch with the hidden ability of this species. - * If no hidden ability exist, a random one will get choosen. + /** + * Defines if the egg will hatch with the hidden ability of this species. + * If no hidden ability exist, a random one will get choosen. */ overrideHiddenAbility?: boolean, @@ -418,7 +423,7 @@ export class Egg { } /** - * Pokemon that are cheaper in their tier get a weight boost. Regionals get a weight penalty + * Pokemon that are cheaper in their tier get a weight boost. * 1 cost mons get 2x * 2 cost mons get 1.5x * 4, 6, 8 cost mons get 1.75x @@ -433,11 +438,7 @@ export class Egg { for (const speciesId of speciesPool) { // Accounts for species that have starter costs outside of the normal range for their EggTier const speciesCostClamped = Phaser.Math.Clamp(speciesStarterCosts[speciesId], minStarterValue, maxStarterValue); - let weight = Math.floor((((maxStarterValue - speciesCostClamped) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100); - const species = getPokemonSpecies(speciesId); - if (species.isRegional()) { - weight = Math.floor(weight / 2); - } + const weight = Math.floor((((maxStarterValue - speciesCostClamped) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100); speciesWeights.push(totalWeight + weight); totalWeight += weight; } diff --git a/src/data/move.ts b/src/data/move.ts index 071d7fa1e65..2ac4d74b712 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -668,12 +668,12 @@ export default class Move implements Localizable { } /** - * Sees if, given the target pokemon, a move fails on it (by looking at each {@linkcode MoveAttr} of this move + * Sees if a move has a custom failure text (by looking at each {@linkcode MoveAttr} of this move) * @param user {@linkcode Pokemon} using the move * @param target {@linkcode Pokemon} receiving the move * @param move {@linkcode Move} using the move * @param cancelled {@linkcode Utils.BooleanHolder} to hold boolean value - * @returns string of the failed text, or null + * @returns string of the custom failure text, or `null` if it uses the default text ("But it failed!") */ getFailedText(user: Pokemon, target: Pokemon, move: Move, cancelled: Utils.BooleanHolder): string | null { for (const attr of this.attrs) { @@ -818,8 +818,6 @@ export default class Move implements Localizable { applyMoveAttrs(VariablePowerAttr, source, target, this, power); - source.scene.applyModifiers(PokemonMultiHitModifier, source.isPlayer(), source, new Utils.IntegerHolder(0), power); - if (!this.hasAttr(TypelessAttr)) { source.scene.arena.applyTags(WeakenMoveTypeTag, simulated, this.type, power); source.scene.applyModifiers(AttackTypeBoosterModifier, source.isPlayer(), source, this.type, power); @@ -840,6 +838,45 @@ export default class Move implements Localizable { return priority.value; } + + /** + * Returns `true` if this move can be given additional strikes + * by enhancing effects. + * Currently used for {@link https://bulbapedia.bulbagarden.net/wiki/Parental_Bond_(Ability) | Parental Bond} + * and {@linkcode PokemonMultiHitModifier | Multi-Lens}. + * @param user The {@linkcode Pokemon} using the move + * @param restrictSpread `true` if the enhancing effect + * should not affect multi-target moves (default `false`) + */ + canBeMultiStrikeEnhanced(user: Pokemon, restrictSpread: boolean = false): boolean { + // Multi-strike enhancers... + + // ...cannot enhance moves that hit multiple targets + const { targets, multiple } = getMoveTargets(user, this.id); + const isMultiTarget = multiple && targets.length > 1; + + // ...cannot enhance multi-hit or sacrificial moves + const exceptAttrs: Constructor[] = [ + MultiHitAttr, + SacrificialAttr, + SacrificialAttrOnHit + ]; + + // ...and cannot enhance these specific moves. + const exceptMoves: Moves[] = [ + Moves.FLING, + Moves.UPROAR, + Moves.ROLLOUT, + Moves.ICE_BALL, + Moves.ENDEAVOR + ]; + + return (!restrictSpread || !isMultiTarget) + && !this.isChargingMove() + && !exceptAttrs.some(attr => this.hasAttr(attr)) + && !exceptMoves.some(id => this.id === id) + && this.category !== MoveCategory.STATUS; + } } export class AttackMove extends Move { @@ -860,7 +897,7 @@ export class AttackMove extends Move { let attackScore = 0; - const effectiveness = target.getAttackTypeEffectiveness(this.type, user); + const effectiveness = target.getAttackTypeEffectiveness(this.type, user, undefined, undefined, this); attackScore = Math.pow(effectiveness - 1, 2) * effectiveness < 1 ? -2 : 2; if (attackScore) { if (this.category === MoveCategory.PHYSICAL) { @@ -2417,9 +2454,8 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { const removedItem = heldItems[user.randSeedInt(heldItems.length)]; // Decrease item amount and update icon - !--removedItem.stackCount; + target.loseHeldItem(removedItem); target.scene.updateModifiers(target.isPlayer()); - applyPostItemLostAbAttrs(PostItemLostAbAttr, target, false); if (this.berriesOnly) { @@ -2489,18 +2525,15 @@ export class EatBerryAttr extends MoveEffectAttr { } reduceBerryModifier(target: Pokemon) { - if (this.chosenBerry?.stackCount === 1) { - target.scene.removeModifier(this.chosenBerry, !target.isPlayer()); - } else if (this.chosenBerry !== undefined && this.chosenBerry.stackCount > 1) { - this.chosenBerry.stackCount--; + if (this.chosenBerry) { + target.loseHeldItem(this.chosenBerry); } target.scene.updateModifiers(target.isPlayer()); } - eatBerry(consumer: Pokemon) { - getBerryEffectFunc(this.chosenBerry!.berryType)(consumer); // consumer eats the berry + eatBerry(consumer: Pokemon, berryOwner?: Pokemon) { + getBerryEffectFunc(this.chosenBerry!.berryType)(consumer, berryOwner); // consumer eats the berry applyAbAttrs(HealFromBerryUseAbAttr, consumer, new Utils.BooleanHolder(false)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, consumer, false); } } @@ -2540,7 +2573,7 @@ export class StealEatBerryAttr extends EatBerryAttr { const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: this.chosenBerry.type.name }); user.scene.queueMessage(message); this.reduceBerryModifier(target); - this.eatBerry(user); + this.eatBerry(user, target); return true; } } @@ -2556,12 +2589,11 @@ export class HealStatusEffectAttr extends MoveEffectAttr { /** * @param selfTarget - Whether this move targets the user - * @param ...effects - List of status effects to cure + * @param effects - status effect or list of status effects to cure */ - constructor(selfTarget: boolean, ...effects: StatusEffect[]) { + constructor(selfTarget: boolean, effects: StatusEffect | StatusEffect[]) { super(selfTarget, { lastHitOnly: true }); - - this.effects = effects; + this.effects = [ effects ].flat(1); } /** @@ -4938,22 +4970,6 @@ export class NeutralDamageAgainstFlyingTypeMultiplierAttr extends VariableMoveTy } } -export class WaterSuperEffectTypeMultiplierAttr extends VariableMoveTypeMultiplierAttr { - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const multiplier = args[0] as Utils.NumberHolder; - if (target.isOfType(Type.WATER)) { - const effectivenessAgainstWater = new Utils.NumberHolder(getTypeDamageMultiplier(move.type, Type.WATER)); - applyChallenges(user.scene.gameMode, ChallengeType.TYPE_EFFECTIVENESS, effectivenessAgainstWater); - if (effectivenessAgainstWater.value !== 0) { - multiplier.value *= 2 / effectivenessAgainstWater.value; - return true; - } - } - - return false; - } -} - export class IceNoEffectTypeAttr extends VariableMoveTypeMultiplierAttr { /** * Checks to see if the Target is Ice-Type or not. If so, the move will have no effect. @@ -4981,6 +4997,41 @@ export class FlyingTypeMultiplierAttr extends VariableMoveTypeMultiplierAttr { } } +/** + * Attribute for moves which have a custom type chart interaction. + */ +export class VariableMoveTypeChartAttr extends MoveAttr { + /** + * @param user {@linkcode Pokemon} using the move + * @param target {@linkcode Pokemon} target of the move + * @param move {@linkcode Move} with this attribute + * @param args [0] {@linkcode NumberHolder} holding the type effectiveness + * @param args [1] A single defensive type of the target + * + * @returns true if application of the attribute succeeds + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + return false; + } +} + +/** + * This class forces Freeze-Dry to be super effective against Water Type. + */ +export class FreezeDryAttr extends VariableMoveTypeChartAttr { + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + const multiplier = args[0] as Utils.NumberHolder; + const defType = args[1] as Type; + + if (defType === Type.WATER) { + multiplier.value = 2; + return true; + } else { + return false; + } + } +} + export class OneHitKOAccuracyAttr extends VariableAccuracyAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const accuracy = args[0] as Utils.NumberHolder; @@ -6373,10 +6424,17 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr { } export class RandomMoveAttr extends OverrideMoveEffectAttr { + /** + * This function exists solely to allow tests to override the randomly selected move by mocking this function. + */ + public getMoveOverride(): Moves | null { + return null; + } + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { return new Promise(resolve => { const moveIds = Utils.getEnumValues(Moves).filter(m => !allMoves[m].hasFlag(MoveFlags.IGNORE_VIRTUAL) && !allMoves[m].name.endsWith(" (N)")); - const moveId = moveIds[user.randSeedInt(moveIds.length)]; + const moveId = this.getMoveOverride() ?? moveIds[user.randSeedInt(moveIds.length)]; const moveTargets = getMoveTargets(user, moveId); if (!moveTargets.targets.length) { @@ -6759,7 +6817,7 @@ export class SketchAttr extends MoveEffectAttr { return false; } - const targetMove = target.getLastXMoves(target.battleSummonData.turnCount) + const targetMove = target.getLastXMoves(-1) .find(m => m.move !== Moves.NONE && m.move !== Moves.STRUGGLE && !m.virtual); if (!targetMove) { return false; @@ -6988,6 +7046,9 @@ export class SuppressAbilitiesIfActedAttr extends MoveEffectAttr { } } +/** + * Used by Transform + */ export class TransformAttr extends MoveEffectAttr { async apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { if (!super.apply(user, target, move, args)) { @@ -6996,10 +7057,8 @@ export class TransformAttr extends MoveEffectAttr { const promises: Promise[] = []; user.summonData.speciesForm = target.getSpeciesForm(); - user.summonData.fusionSpeciesForm = target.getFusionSpeciesForm(); user.summonData.ability = target.getAbility().id; user.summonData.gender = target.getGender(); - user.summonData.fusionGender = target.getFusionGender(); // Power Trick's effect will not preserved after using Transform user.removeTag(BattlerTagType.POWER_TRICK); @@ -8070,7 +8129,8 @@ export function initMoves() { .ignoresVirtual(), new StatusMove(Moves.TRANSFORM, Type.NORMAL, -1, 10, -1, 0, 1) .attr(TransformAttr) - .condition((user, target, move) => !target.getTag(BattlerTagType.SUBSTITUTE)) + // transforming from or into fusion pokemon causes various problems (such as crashes) + .condition((user, target, move) => !target.getTag(BattlerTagType.SUBSTITUTE) && !user.fusionSpecies && !target.fusionSpecies) .ignoresProtect(), new AttackMove(Moves.BUBBLE, Type.WATER, MoveCategory.SPECIAL, 40, 100, 30, 10, 0, 1) .attr(StatStageChangeAttr, [ Stat.SPD ], -1) @@ -8475,7 +8535,8 @@ export function initMoves() { new StatusMove(Moves.HELPING_HAND, Type.NORMAL, -1, 20, -1, 5, 3) .attr(AddBattlerTagAttr, BattlerTagType.HELPING_HAND) .ignoresSubstitute() - .target(MoveTarget.NEAR_ALLY), + .target(MoveTarget.NEAR_ALLY) + .condition(failIfSingleBattle), new StatusMove(Moves.TRICK, Type.PSYCHIC, 100, 10, -1, 0, 3) .unimplemented(), new StatusMove(Moves.ROLE_PLAY, Type.PSYCHIC, -1, 10, -1, 0, 3) @@ -8521,7 +8582,7 @@ export function initMoves() { .attr(AddArenaTagAttr, ArenaTagType.IMPRISON, 1, true, false) .target(MoveTarget.ENEMY_SIDE), new SelfStatusMove(Moves.REFRESH, Type.NORMAL, -1, 20, -1, 0, 3) - .attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN) + .attr(HealStatusEffectAttr, true, [ StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN ]) .condition((user, target, move) => !!user.status && (user.status.effect === StatusEffect.PARALYSIS || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.BURN)), new SelfStatusMove(Moves.GRUDGE, Type.GHOST, -1, 5, -1, 0, 3) .attr(AddBattlerTagAttr, BattlerTagType.GRUDGE, true, undefined, 1), @@ -8828,7 +8889,7 @@ export function initMoves() { new SelfStatusMove(Moves.AQUA_RING, Type.WATER, -1, 20, -1, 0, 4) .attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true), new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4) - .attr(AddBattlerTagAttr, BattlerTagType.FLOATING, true, true) + .attr(AddBattlerTagAttr, BattlerTagType.FLOATING, true, true, 5) .condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) && [ BattlerTagType.FLOATING, BattlerTagType.IGNORE_FLYING, BattlerTagType.INGRAIN ].every((tag) => !user.getTag(tag))), new AttackMove(Moves.FLARE_BLITZ, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 4) .attr(RecoilAttr, false, 0.33) @@ -9167,6 +9228,7 @@ export function initMoves() { .target(MoveTarget.ALL_NEAR_ENEMIES) .attr(RemoveHeldItemAttr, true), new StatusMove(Moves.QUASH, Type.DARK, 100, 15, -1, 0, 5) + .condition(failIfSingleBattle) .unimplemented(), new AttackMove(Moves.ACROBATICS, Type.FLYING, MoveCategory.PHYSICAL, 55, 100, 15, -1, 0, 5) .attr(MovePowerMultiplierAttr, (user, target, move) => Math.max(1, 2 - 0.2 * user.getHeldItems().filter(i => i.isTransferable).reduce((v, m) => v + m.stackCount, 0))), @@ -9378,8 +9440,7 @@ export function initMoves() { .target(MoveTarget.ALL_NEAR_OTHERS), new AttackMove(Moves.FREEZE_DRY, Type.ICE, MoveCategory.SPECIAL, 70, 100, 20, 10, 0, 6) .attr(StatusEffectAttr, StatusEffect.FREEZE) - .attr(WaterSuperEffectTypeMultiplierAttr) - .edgeCase(), // This currently just multiplies the move's power instead of changing its effectiveness. It also doesn't account for abilities that modify type effectiveness such as tera shell. + .attr(FreezeDryAttr), new AttackMove(Moves.DISARMING_VOICE, Type.FAIRY, MoveCategory.SPECIAL, 40, -1, 15, -1, 0, 6) .soundBased() .target(MoveTarget.ALL_NEAR_ENEMIES), @@ -9454,6 +9515,7 @@ export function initMoves() { new StatusMove(Moves.AROMATIC_MIST, Type.FAIRY, -1, 20, -1, 0, 6) .attr(StatStageChangeAttr, [ Stat.SPDEF ], 1) .ignoresSubstitute() + .condition(failIfSingleBattle) .target(MoveTarget.NEAR_ALLY), new StatusMove(Moves.EERIE_IMPULSE, Type.ELECTRIC, 100, 15, -1, 0, 6) .attr(StatStageChangeAttr, [ Stat.SPATK ], -2), @@ -9682,7 +9744,8 @@ export function initMoves() { new AttackMove(Moves.LEAFAGE, Type.GRASS, MoveCategory.PHYSICAL, 40, 100, 40, -1, 0, 7) .makesContact(false), new StatusMove(Moves.SPOTLIGHT, Type.NORMAL, -1, 15, -1, 3, 7) - .attr(AddBattlerTagAttr, BattlerTagType.CENTER_OF_ATTENTION, false), + .attr(AddBattlerTagAttr, BattlerTagType.CENTER_OF_ATTENTION, false) + .condition(failIfSingleBattle), new StatusMove(Moves.TOXIC_THREAD, Type.POISON, 100, 20, -1, 0, 7) .attr(StatusEffectAttr, StatusEffect.POISON) .attr(StatStageChangeAttr, [ Stat.SPD ], -1), @@ -9728,7 +9791,7 @@ export function initMoves() { .condition( (user: Pokemon, target: Pokemon, move: Move) => isNonVolatileStatusEffect(target.status?.effect!)) // TODO: is this bang correct? .attr(HealAttr, 0.5) - .attr(HealStatusEffectAttr, false, ...getNonVolatileStatusEffects()) + .attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects()) .triageMove(), new AttackMove(Moves.REVELATION_DANCE, Type.NORMAL, MoveCategory.SPECIAL, 90, 100, 15, -1, 0, 7) .danceMove() @@ -9812,11 +9875,9 @@ export function initMoves() { .ignoresSubstitute() .partial(), // Does not steal stats new AttackMove(Moves.SUNSTEEL_STRIKE, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 7) - .ignoresAbilities() - .edgeCase(), // Should not ignore abilities when called virtually (metronome) + .ignoresAbilities(), new AttackMove(Moves.MOONGEIST_BEAM, Type.GHOST, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7) - .ignoresAbilities() - .edgeCase(), // Should not ignore abilities when called virtually (metronome) + .ignoresAbilities(), new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, -1, 0, 7) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1), new AttackMove(Moves.ZING_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 30, 0, 7) @@ -9839,8 +9900,7 @@ export function initMoves() { .punchingMove(), new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7) .attr(PhotonGeyserCategoryAttr) - .ignoresAbilities() - .edgeCase(), // Should not ignore abilities when called virtually (metronome) + .ignoresAbilities(), /* Unused */ new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7) .attr(PhotonGeyserCategoryAttr) @@ -10139,7 +10199,8 @@ export function initMoves() { .unimplemented(), new StatusMove(Moves.COACHING, Type.FIGHTING, -1, 10, -1, 0, 8) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF ], 1) - .target(MoveTarget.NEAR_ALLY), + .target(MoveTarget.NEAR_ALLY) + .condition(failIfSingleBattle), new AttackMove(Moves.FLIP_TURN, Type.WATER, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 8) .attr(ForceSwitchOutAttr, true), new AttackMove(Moves.TRIPLE_AXEL, Type.ICE, MoveCategory.PHYSICAL, 20, 90, 10, -1, 0, 8) @@ -10154,7 +10215,7 @@ export function initMoves() { .attr(StatusEffectAttr, StatusEffect.BURN), new StatusMove(Moves.JUNGLE_HEALING, Type.GRASS, -1, 10, -1, 0, 8) .attr(HealAttr, 0.25, true, false) - .attr(HealStatusEffectAttr, false, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP) + .attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects()) .target(MoveTarget.USER_AND_ALLIES), new AttackMove(Moves.WICKED_BLOW, Type.DARK, MoveCategory.PHYSICAL, 75, 100, 5, -1, 0, 8) .attr(CritOnlyAttr) @@ -10258,12 +10319,12 @@ export function initMoves() { .target(MoveTarget.ALL_NEAR_ENEMIES), new StatusMove(Moves.LUNAR_BLESSING, Type.PSYCHIC, -1, 5, -1, 0, 8) .attr(HealAttr, 0.25, true, false) - .attr(HealStatusEffectAttr, false, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP) + .attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects()) .target(MoveTarget.USER_AND_ALLIES) .triageMove(), new SelfStatusMove(Moves.TAKE_HEART, Type.PSYCHIC, -1, 10, -1, 0, 8) .attr(StatStageChangeAttr, [ Stat.SPATK, Stat.SPDEF ], 1, true) - .attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP), + .attr(HealStatusEffectAttr, true, [ StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP ]), /* Unused new AttackMove(Moves.G_MAX_WILDFIRE, Type.FIRE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.ALL_NEAR_ENEMIES) 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 7a03e6efdd2..ecd6972902b 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -477,12 +477,9 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = .withOptionPhase(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter!; const modifier = encounter.misc.chosenModifier; + const chosenPokemon: PlayerPokemon = encounter.misc.chosenPokemon; - // Remove the modifier if its stacks go to 0 - modifier.stackCount -= 1; - if (modifier.stackCount === 0) { - scene.removeModifier(modifier); - } + chosenPokemon.loseHeldItem(modifier, false); scene.updateModifiers(true, true); const bugNet = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!; diff --git a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts index d5a938b9cef..a3a97a01238 100644 --- a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts +++ b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts @@ -8,7 +8,7 @@ import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/u import { getPokemonSpecies } from "#app/data/pokemon-species"; import Pokemon, { PlayerPokemon } from "#app/field/pokemon"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; -import { BerryModifier, HealingBoosterModifier, LevelIncrementBoosterModifier, MoneyMultiplierModifier, PokemonHeldItemModifier, PreserveBerryModifier } from "#app/modifier/modifier"; +import { BerryModifier, HealingBoosterModifier, LevelIncrementBoosterModifier, MoneyMultiplierModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, PreserveBerryModifier } from "#app/modifier/modifier"; import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase"; import i18next from "#app/plugins/i18n"; @@ -197,7 +197,8 @@ export const DelibirdyEncounter: MysteryEncounter = }) .withOptionPhase(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter!; - const modifier: BerryModifier | HealingBoosterModifier = encounter.misc.chosenModifier; + const modifier: BerryModifier | PokemonInstantReviveModifier = encounter.misc.chosenModifier; + const chosenPokemon: PlayerPokemon = encounter.misc.chosenPokemon; // Give the player a Candy Jar if they gave a Berry, and a Berry Pouch for Reviver Seed if (modifier instanceof BerryModifier) { @@ -228,11 +229,7 @@ export const DelibirdyEncounter: MysteryEncounter = } } - // Remove the modifier if its stacks go to 0 - modifier.stackCount -= 1; - if (modifier.stackCount === 0) { - scene.removeModifier(modifier); - } + chosenPokemon.loseHeldItem(modifier, false); leaveEncounterWithoutBattle(scene, true); }) @@ -292,6 +289,7 @@ export const DelibirdyEncounter: MysteryEncounter = .withOptionPhase(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter!; const modifier = encounter.misc.chosenModifier; + const chosenPokemon: PlayerPokemon = encounter.misc.chosenPokemon; // Check if the player has max stacks of Healing Charm already const existing = scene.findModifier(m => m instanceof HealingBoosterModifier) as HealingBoosterModifier; @@ -306,11 +304,7 @@ export const DelibirdyEncounter: MysteryEncounter = scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.HEALING_CHARM)); } - // Remove the modifier if its stacks go to 0 - modifier.stackCount -= 1; - if (modifier.stackCount === 0) { - scene.removeModifier(modifier); - } + chosenPokemon.loseHeldItem(modifier, false); leaveEncounterWithoutBattle(scene, true); }) 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 7bf48aa5926..c286fffe0de 100644 --- a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts +++ b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts @@ -305,7 +305,7 @@ async function showWobbuffetHealthBar(scene: BattleScene) { scene.field.add(wobbuffet); const playerPokemon = scene.getPlayerPokemon() as Pokemon; - if (playerPokemon?.visible) { + if (playerPokemon?.isOnField()) { scene.field.moveBelow(wobbuffet, playerPokemon); } // Show health bar and trigger cry diff --git a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts index b0d547e36cf..2d569621449 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -345,6 +345,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = // Pokemon and item selected encounter.setDialogueToken("chosenItem", modifier.type.name); encounter.misc.chosenModifier = modifier; + encounter.misc.chosenPokemon = pokemon; return true; }, }; @@ -370,6 +371,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; const modifier = encounter.misc.chosenModifier as PokemonHeldItemModifier; const party = scene.getPlayerParty(); + const chosenPokemon: PlayerPokemon = encounter.misc.chosenPokemon; // Check tier of the traded item, the received item will be one tier up const type = modifier.type.withTierFromPool(ModifierPoolType.PLAYER, party); @@ -397,11 +399,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = encounter.setDialogueToken("itemName", item.type.name); setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false }); - // Remove the chosen modifier if its stacks go to 0 - modifier.stackCount -= 1; - if (modifier.stackCount === 0) { - scene.removeModifier(modifier); - } + chosenPokemon.loseHeldItem(modifier, false); await scene.updateModifiers(true, true); // Generate a trainer name diff --git a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts index 798e85868f6..3f1ace47b0f 100644 --- a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts +++ b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts @@ -138,7 +138,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = newNature = randSeedInt(25) as Nature; } - chosenPokemon.customPokemonData.nature = newNature; + chosenPokemon.setCustomNature(newNature); encounter.setDialogueToken("newNature", getNatureName(newNature)); queueEncounterMessage(scene, `${namespace}:cheap_side_effects`); setEncounterExp(scene, [ chosenPokemon.id ], 100); diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index 4a0a91bf751..725c4ba79eb 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -226,8 +226,8 @@ export const TrainingSessionEncounter: MysteryEncounter = const onBeforeRewardsPhase = () => { queueEncounterMessage(scene, `${namespace}:option.2.finished`); // Add the pokemon back to party with Nature change - playerPokemon.setNature(encounter.misc.chosenNature); - scene.gameData.setPokemonCaught(playerPokemon, false); + playerPokemon.setCustomNature(encounter.misc.chosenNature); + scene.gameData.unlockSpeciesNature(playerPokemon.species, encounter.misc.chosenNature); // Add pokemon and modifiers back scene.getPlayerParty().push(playerPokemon); diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 3c541e20bf4..3d2e8493d44 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -312,6 +312,7 @@ export const WeirdDreamEncounter: MysteryEncounter = pokemon.levelExp = 0; pokemon.calculateStats(); + pokemon.getBattleInfo().setLevel(pokemon.level); await pokemon.updateInfo(); } diff --git a/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts b/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts index c4d5e47cb05..acaa7c6244f 100644 --- a/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts @@ -7,22 +7,22 @@ import i18next from "i18next"; /** * Will inject all relevant dialogue tokens that exist in the {@linkcode BattleScene.currentBattle.mysteryEncounter.dialogueTokens}, into i18n text. * Also adds BBCodeText fragments for colored text, if applicable - * @param scene * @param keyOrString * @param primaryStyle Can define a text style to be applied to the entire string. Must be defined for BBCodeText styles to be applied correctly - * @param uiTheme */ -export function getEncounterText(scene: BattleScene, keyOrString?: string, primaryStyle?: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string | null { +export function getEncounterText(scene: BattleScene, keyOrString?: string, primaryStyle?: TextStyle): string | null { if (isNullOrUndefined(keyOrString)) { return null; } + const uiTheme = scene.uiTheme ?? UiTheme.DEFAULT; + let textString: string | null = getTextWithDialogueTokens(scene, keyOrString); // Can only color the text if a Primary Style is defined // primaryStyle is applied to all text that does not have its own specified style if (primaryStyle && textString) { - textString = getTextWithColors(textString, primaryStyle, uiTheme); + textString = getTextWithColors(textString, primaryStyle, uiTheme, true); } return textString; diff --git a/src/data/pokeball.ts b/src/data/pokeball.ts index 49cb0d1bf72..4c9fc719a4d 100644 --- a/src/data/pokeball.ts +++ b/src/data/pokeball.ts @@ -1,3 +1,4 @@ +import { CriticalCatchChanceBoosterModifier } from "#app/modifier/modifier"; import { NumberHolder } from "#app/utils"; import { PokeballType } from "#enums/pokeball"; import BattleScene from "../battle-scene"; @@ -94,7 +95,7 @@ export function getCriticalCaptureChance(scene: BattleScene, modifiedCatchRate: } const dexCount = scene.gameData.getSpeciesCount(d => !!d.caughtAttr); const catchingCharmMultiplier = new NumberHolder(1); - //scene.findModifier(m => m instanceof CriticalCatchChanceBoosterModifier)?.apply(catchingCharmMultiplier); + scene.findModifier(m => m instanceof CriticalCatchChanceBoosterModifier)?.apply(catchingCharmMultiplier); const dexMultiplier = scene.gameMode.isDaily || dexCount > 800 ? 2.5 : dexCount > 600 ? 2 : dexCount > 400 ? 1.5 diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index e7fe902956c..ec104d4d4aa 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -363,6 +363,12 @@ export abstract class PokemonSpeciesForm { } switch (this.speciesId) { + case Species.DODUO: + case Species.DODRIO: + case Species.MEGANIUM: + case Species.TORCHIC: + case Species.COMBUSKEN: + case Species.BLAZIKEN: case Species.HIPPOPOTAS: case Species.HIPPOWDON: case Species.UNFEZANT: @@ -499,11 +505,11 @@ export abstract class PokemonSpeciesForm { scene.anims.create({ key: this.getSpriteKey(female, formIndex, shiny, variant), frames: frameNames, - frameRate: 12, + frameRate: 10, repeat: -1 }); } else { - scene.anims.get(spriteKey).frameRate = 12; + scene.anims.get(spriteKey).frameRate = 10; } let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, ""); const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey); @@ -888,17 +894,24 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali getCompatibleFusionSpeciesFilter(): PokemonSpeciesFilter { const hasEvolution = pokemonEvolutions.hasOwnProperty(this.speciesId); const hasPrevolution = pokemonPrevolutions.hasOwnProperty(this.speciesId); - const pseudoLegendary = this.subLegendary; + const subLegendary = this.subLegendary; const legendary = this.legendary; const mythical = this.mythical; return species => { - return (pseudoLegendary || legendary || mythical || - (pokemonEvolutions.hasOwnProperty(species.speciesId) === hasEvolution - && pokemonPrevolutions.hasOwnProperty(species.speciesId) === hasPrevolution)) - && species.subLegendary === pseudoLegendary + return ( + subLegendary + || legendary + || mythical + || ( + pokemonEvolutions.hasOwnProperty(species.speciesId) === hasEvolution + && pokemonPrevolutions.hasOwnProperty(species.speciesId) === hasPrevolution + ) + ) + && species.subLegendary === subLegendary && species.legendary === legendary && species.mythical === mythical - && (this.isTrainerForbidden() || !species.isTrainerForbidden()); + && (this.isTrainerForbidden() || !species.isTrainerForbidden()) + && species.speciesId !== Species.DITTO; }; } diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index d82d568ecc6..5e5f38bd00d 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -1841,21 +1841,25 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL) .setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE) .setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM, () => modifierTypes.ABILITY_CHARM) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true, + (p => p.abilityIndex = 0))) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL ], TrainerSlot.TRAINER, true)), [TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2) .setModifierRewardFuncs(() => modifierTypes.EXP_SHARE) .setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true, + (p => p.abilityIndex = 0))) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)), [TrainerType.RIVAL_3]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_3) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, + (p => p.abilityIndex = 0))) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setSpeciesFilter(species => species.baseTotal >= 540), [TrainerType.RIVAL_4]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_2").setMixedBattleBgm("battle_rival_2").setPartyTemplates(trainerPartyTemplates.RIVAL_4) - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, + (p => p.abilityIndex = 0))) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setSpeciesFilter(species => species.baseTotal >= 540) @@ -1865,7 +1869,10 @@ export const trainerConfigs: TrainerConfigs = { }), [TrainerType.RIVAL_5]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_5) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, - p => p.setBoss(true, 2))) + p => { + p.setBoss(true, 2); + p.abilityIndex = 0; + })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setSpeciesFilter(species => species.baseTotal >= 540) @@ -1883,6 +1890,7 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 3); + p.abilityIndex = 0; p.generateAndPopulateMoveset(); })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true, diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index b2bbc1e6189..bb969386630 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -92,4 +92,5 @@ export enum BattlerTagType { COMMANDED = "COMMANDED", GRUDGE = "GRUDGE", PSYCHO_SHIFT = "PSYCHO_SHIFT", + ENDURE_TOKEN = "ENDURE_TOKEN", } diff --git a/src/field/mystery-encounter-intro.ts b/src/field/mystery-encounter-intro.ts index 12bcace500c..1577d1157d7 100644 --- a/src/field/mystery-encounter-intro.ts +++ b/src/field/mystery-encounter-intro.ts @@ -212,7 +212,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con this.scene.anims.create({ key: config.spriteKey, frames: frameNames, - frameRate: 12, + frameRate: 10, repeat: -1 }); } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index e0b7bf1094f..217d5fa699b 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3,7 +3,7 @@ import BattleScene, { AnySound } from "#app/battle-scene"; import { Variant, VariantSet, variantColorCache } from "#app/data/variant"; import { variantData } from "#app/data/variant"; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "#app/ui/battle-info"; -import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget, CombinedPledgeStabBoostAttr } from "#app/data/move"; +import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget, CombinedPledgeStabBoostAttr, VariableMoveTypeChartAttr } from "#app/data/move"; import { default as PokemonSpecies, PokemonSpeciesForm, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species"; import { CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER, getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters"; import { starterPassiveAbilities } from "#app/data/balance/passives"; @@ -23,7 +23,7 @@ import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "#app/data/balance/ import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag, PowerTrickTag } from "../data/battler-tags"; import { WeatherType } from "#enums/weather-type"; import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag"; -import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs, InfiltratorAbAttr, AlliedFieldDamageReductionAbAttr, PostDamageAbAttr, applyPostDamageAbAttrs, PostDamageForceSwitchAbAttr } from "#app/data/ability"; +import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs, InfiltratorAbAttr, AlliedFieldDamageReductionAbAttr, PostDamageAbAttr, applyPostDamageAbAttrs, PostDamageForceSwitchAbAttr, CommanderAbAttr, applyPostItemLostAbAttrs, PostItemLostAbAttr } from "#app/data/ability"; import PokemonData from "#app/system/pokemon-data"; import { BattlerIndex } from "#app/battle"; import { Mode } from "#app/ui/ui"; @@ -427,7 +427,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.anims.create({ key: this.getBattleSpriteKey(), frames: battleFrameNames, - frameRate: 12, + frameRate: 10, repeat: -1 }); } @@ -442,7 +442,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { }; if (this.shiny) { const populateVariantColors = (isBackSprite: boolean = false): Promise => { - return new Promise(resolve => { + return new Promise(async resolve => { const battleSpritePath = this.getBattleSpriteAtlasPath(isBackSprite, ignoreOverride).replace("variant/", "").replace(/_[1-3]$/, ""); let config = variantData; const useExpSprite = this.scene.experimentalSprites && this.scene.hasExpSprite(this.getBattleSpriteKey(isBackSprite, ignoreOverride)); @@ -451,7 +451,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (variantSet && variantSet[this.variant] === 1) { const cacheKey = this.getBattleSpriteKey(isBackSprite); if (!variantColorCache.hasOwnProperty(cacheKey)) { - this.populateVariantColorCache(cacheKey, useExpSprite, battleSpritePath); + await this.populateVariantColorCache(cacheKey, useExpSprite, battleSpritePath); } } resolve(); @@ -483,10 +483,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param battleSpritePath the filename of the sprite * @param optionalParams any additional params to log */ - fallbackVariantColor(cacheKey: string, attemptedSpritePath: string, useExpSprite: boolean, battleSpritePath: string, ...optionalParams: any[]) { + async fallbackVariantColor(cacheKey: string, attemptedSpritePath: string, useExpSprite: boolean, battleSpritePath: string, ...optionalParams: any[]) { console.warn(`Could not load ${attemptedSpritePath}!`, ...optionalParams); if (useExpSprite) { - this.populateVariantColorCache(cacheKey, false, battleSpritePath); + await this.populateVariantColorCache(cacheKey, false, battleSpritePath); } } @@ -497,18 +497,20 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param useExpSprite should the experimental sprite be used * @param battleSpritePath the filename of the sprite */ - populateVariantColorCache(cacheKey: string, useExpSprite: boolean, battleSpritePath: string) { + async populateVariantColorCache(cacheKey: string, useExpSprite: boolean, battleSpritePath: string) { const spritePath = `./images/pokemon/variant/${useExpSprite ? "exp/" : ""}${battleSpritePath}.json`; - this.scene.cachedFetch(spritePath).then(res => { + return this.scene.cachedFetch(spritePath).then(res => { // Prevent the JSON from processing if it failed to load if (!res.ok) { return this.fallbackVariantColor(cacheKey, res.url, useExpSprite, battleSpritePath, res.status, res.statusText); } return res.json(); }).catch(error => { - this.fallbackVariantColor(cacheKey, spritePath, useExpSprite, battleSpritePath, error); + return this.fallbackVariantColor(cacheKey, spritePath, useExpSprite, battleSpritePath, error); }).then(c => { - variantColorCache[cacheKey] = c; + if (!isNullOrUndefined(c)) { + variantColorCache[cacheKey] = c; + } }); } @@ -985,7 +987,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (this.status && this.status.effect === StatusEffect.PARALYSIS) { ret >>= 1; } - if (this.getTag(BattlerTagType.UNBURDEN) && !this.scene.getField(true).some(pokemon => pokemon !== this && pokemon.hasAbilityWithAttr(SuppressFieldAbilitiesAbAttr))) { + if (this.getTag(BattlerTagType.UNBURDEN) && this.hasAbility(Abilities.UNBURDEN)) { ret *= 2; } break; @@ -1070,6 +1072,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.calculateStats(); } + setCustomNature(nature: Nature): void { + this.customPokemonData.nature = nature; + this.calculateStats(); + } + generateNature(naturePool?: Nature[]): void { if (naturePool === undefined) { naturePool = Utils.getEnumValues(Nature); @@ -1630,7 +1637,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const moveType = source.getMoveType(move); const typeMultiplier = new Utils.NumberHolder((move.category !== MoveCategory.STATUS || move.hasAttr(RespectAttackTypeImmunityAttr)) - ? this.getAttackTypeEffectiveness(moveType, source, false, simulated) + ? this.getAttackTypeEffectiveness(moveType, source, false, simulated, move) : 1); applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier); @@ -1682,9 +1689,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param source {@linkcode Pokemon} the Pokemon using the move * @param ignoreStrongWinds whether or not this ignores strong winds (anticipation, forewarn, stealth rocks) * @param simulated tag to only apply the strong winds effect message when the move is used + * @param move (optional) the move whose type effectiveness is to be checked. Used for applying {@linkcode VariableMoveTypeChartAttr} * @returns a multiplier for the type effectiveness */ - getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true): TypeDamageMultiplier { + getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true, move?: Move): TypeDamageMultiplier { if (moveType === Type.STELLAR) { return this.isTerastallized() ? 2 : 1; } @@ -1703,6 +1711,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { let multiplier = types.map(defType => { const multiplier = new Utils.NumberHolder(getTypeDamageMultiplier(moveType, defType)); applyChallenges(this.scene.gameMode, ChallengeType.TYPE_EFFECTIVENESS, multiplier); + if (move) { + applyMoveAttrs(VariableMoveTypeChartAttr, null, this, move, multiplier, defType); + } if (source) { const ignoreImmunity = new Utils.BooleanHolder(false); if (source.isActive(true) && source.hasAbilityWithAttr(IgnoreTypeImmunityAbAttr)) { @@ -2030,15 +2041,17 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const hasHiddenAbility = !Utils.randSeedInt(hiddenAbilityChance.value); const randAbilityIndex = Utils.randSeedInt(2); - const filter = !forStarter ? this.species.getCompatibleFusionSpeciesFilter() - : species => { + const filter = !forStarter ? + this.species.getCompatibleFusionSpeciesFilter() + : (species: PokemonSpecies) => { return pokemonEvolutions.hasOwnProperty(species.speciesId) - && !pokemonPrevolutions.hasOwnProperty(species.speciesId) - && !species.pseudoLegendary - && !species.legendary - && !species.mythical - && !species.isTrainerForbidden() - && species.speciesId !== this.species.speciesId; + && !pokemonPrevolutions.hasOwnProperty(species.speciesId) + && !species.subLegendary + && !species.legendary + && !species.mythical + && !species.isTrainerForbidden() + && species.speciesId !== this.species.speciesId + && species.speciesId !== Species.DITTO; }; let fusionOverride: PokemonSpecies | undefined = undefined; @@ -2609,6 +2622,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const fixedDamage = new Utils.IntegerHolder(0); applyMoveAttrs(FixedDamageAttr, source, this, move, fixedDamage); if (fixedDamage.value) { + const multiLensMultiplier = new Utils.NumberHolder(1); + source.scene.applyModifiers(PokemonMultiHitModifier, source.isPlayer(), source, move.id, null, multiLensMultiplier); + fixedDamage.value = Utils.toDmgValue(fixedDamage.value * multiLensMultiplier.value); + return { cancelled: false, result: HitResult.EFFECTIVE, @@ -2638,10 +2655,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const numTargets = multiple ? targets.length : 1; const targetMultiplier = (numTargets > 1) ? 0.75 : 1; - /** 0.25x multiplier if this is an added strike from the attacker's Parental Bond */ - const parentalBondMultiplier = new Utils.NumberHolder(1); + /** Multiplier for moves enhanced by Multi-Lens and/or Parental Bond */ + const multiStrikeEnhancementMultiplier = new Utils.NumberHolder(1); + source.scene.applyModifiers(PokemonMultiHitModifier, source.isPlayer(), source, move.id, null, multiStrikeEnhancementMultiplier); if (!ignoreSourceAbility) { - applyPreAttackAbAttrs(AddSecondStrikeAbAttr, source, this, move, simulated, numTargets, new Utils.IntegerHolder(0), parentalBondMultiplier); + applyPreAttackAbAttrs(AddSecondStrikeAbAttr, source, this, move, simulated, null, multiStrikeEnhancementMultiplier); } /** Doubles damage if this Pokemon's last move was Glaive Rush */ @@ -2718,7 +2736,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { damage.value = Utils.toDmgValue( baseDamage * targetMultiplier - * parentalBondMultiplier.value + * multiStrikeEnhancementMultiplier.value * arenaAttackTypeMultiplier.value * glaiveRushMultiplier.value * criticalMultiplier.value @@ -2946,6 +2964,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { surviveDamage.value = this.lapseTag(BattlerTagType.ENDURING); } else if (this.hp > 1 && this.getTag(BattlerTagType.STURDY)) { surviveDamage.value = this.lapseTag(BattlerTagType.STURDY); + } else if (this.hp >= 1 && this.getTag(BattlerTagType.ENDURE_TOKEN)) { + surviveDamage.value = this.lapseTag(BattlerTagType.ENDURE_TOKEN); } if (!surviveDamage.value) { this.scene.applyModifiers(SurviveDamageModifier, this.isPlayer(), this, surviveDamage); @@ -3081,6 +3101,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } lapseTag(tagType: BattlerTagType): boolean { + if (!this.summonData) { + return false; + } const tags = this.summonData.tags; const tag = tags.find(t => t.tagType === tagType); if (tag && !(tag.lapse(this, BattlerTagLapseType.CUSTOM))) { @@ -3091,6 +3114,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } lapseTags(lapseType: BattlerTagLapseType): void { + if (!this.summonData) { + return; + } const tags = this.summonData.tags; tags.filter(t => lapseType === BattlerTagLapseType.FAINT || ((t.lapseTypes.some(lType => lType === lapseType)) && !(t.lapse(this, lapseType)))).forEach(t => { t.onRemove(this); @@ -3099,6 +3125,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } removeTag(tagType: BattlerTagType): boolean { + if (!this.summonData) { + return false; + } const tags = this.summonData.tags; const tag = tags.find(t => t.tagType === tagType); if (tag) { @@ -3214,18 +3243,33 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return null; } - getMoveHistory(): TurnMove[] { + public getMoveHistory(): TurnMove[] { return this.battleSummonData.moveHistory; } - pushMoveHistory(turnMove: TurnMove) { + public pushMoveHistory(turnMove: TurnMove): void { + if (!this.isOnField()) { + return; + } turnMove.turn = this.scene.currentBattle?.turn; this.getMoveHistory().push(turnMove); } - getLastXMoves(turnCount: integer = 0): TurnMove[] { + /** + * Returns a list of the most recent move entries in this Pokemon's move history. + * The retrieved move entries are sorted in order from NEWEST to OLDEST. + * @param moveCount The number of move entries to retrieve. + * If negative, retrieve the Pokemon's entire move history (equivalent to reversing the output of {@linkcode getMoveHistory()}). + * Default is `1`. + * @returns A list of {@linkcode TurnMove}, as specified above. + */ + getLastXMoves(moveCount: number = 1): TurnMove[] { const moveHistory = this.getMoveHistory(); - return moveHistory.slice(turnCount >= 0 ? Math.max(moveHistory.length - (turnCount || 1), 0) : 0, moveHistory.length).reverse(); + if (moveCount >= 0) { + return moveHistory.slice(Math.max(moveHistory.length - moveCount, 0)).reverse(); + } else { + return moveHistory.slice(0).reverse(); + } } getMoveQueue(): QueuedMove[] { @@ -3588,7 +3632,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } this.status = null; if (lastStatus === StatusEffect.SLEEP) { - this.setFrameRate(12); + this.setFrameRate(10); if (this.getTag(BattlerTagType.NIGHTMARE)) { this.lapseTag(BattlerTagType.NIGHTMARE); } @@ -3646,6 +3690,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.triggerPokemonBattleAnim(this, PokemonAnimType.SUBSTITUTE_ADD); this.getTag(SubstituteTag)!.sourceInFocus = false; } + + // If this Pokemon has Commander and Dondozo as an active ally, hide this Pokemon's sprite. + if (this.hasAbilityWithAttr(CommanderAbAttr) + && this.scene.currentBattle.double + && this.getAlly()?.species.speciesId === Species.DONDOZO) { + this.setVisible(false); + } this.summonDataPrimer = null; } this.updateInfo(); @@ -4029,8 +4080,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.resetTurnData(); if (clearEffects) { this.destroySubstitute(); - this.resetSummonData(); - this.resetBattleData(); + this.resetSummonData(); // this also calls `resetBattleSummonData` } if (hideInfo) { this.hideInfo(); @@ -4079,6 +4129,28 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } return false; } + + /** + * Reduces one of this Pokemon's held item stacks by 1, and removes the item if applicable. + * Does nothing if this Pokemon is somehow not the owner of the held item. + * @param heldItem The item stack to be reduced by 1. + * @param forBattle If `false`, do not trigger in-battle effects (such as Unburden) from losing the item. For example, set this to `false` if the Pokemon is giving away the held item for a Mystery Encounter. Default is `true`. + * @returns `true` if the item was removed successfully, `false` otherwise. + */ + public loseHeldItem(heldItem: PokemonHeldItemModifier, forBattle: boolean = true): boolean { + if (heldItem.pokemonId === -1 || heldItem.pokemonId === this.id) { + heldItem.stackCount--; + if (heldItem.stackCount <= 0) { + this.scene.removeModifier(heldItem, !this.isPlayer()); + } + if (forBattle) { + applyPostItemLostAbAttrs(PostItemLostAbAttr, this, false); + } + return true; + } else { + return false; + } + } } export default interface Pokemon { @@ -4521,7 +4593,7 @@ export class PlayerPokemon extends Pokemon { && m.pokemonId === pokemon.id, true) as PokemonHeldItemModifier[]; const transferModifiers: Promise[] = []; for (const modifier of fusedPartyMemberHeldModifiers) { - transferModifiers.push(this.scene.tryTransferHeldItemModifier(modifier, this, false, modifier.getStackCount(), true, true)); + transferModifiers.push(this.scene.tryTransferHeldItemModifier(modifier, this, false, modifier.getStackCount(), true, true, false)); } Promise.allSettled(transferModifiers).then(() => { this.scene.updateModifiers(true, true).then(() => { @@ -5092,7 +5164,7 @@ export class EnemyPokemon extends Pokemon { /** * Add a new pokemon to the player's party (at `slotIndex` if set). - * If the first slot is replaced, the new pokemon's visibility will be set to `false`. + * The new pokemon's visibility will be set to `false`. * @param pokeballType the type of pokeball the pokemon was caught with * @param slotIndex an optional index to place the pokemon in the party * @returns the pokemon that was added or null if the pokemon could not be added @@ -5110,14 +5182,14 @@ export class EnemyPokemon extends Pokemon { const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, this.gender, this.shiny, this.variant, this.ivs, this.nature, this); if (Utils.isBetween(slotIndex, 0, PLAYER_PARTY_MAX_SIZE - 1)) { - if (slotIndex === 0) { - newPokemon.setVisible(false); // Hide if replaced with first pokemon - } party.splice(slotIndex, 0, newPokemon); } else { party.push(newPokemon); } + // Hide the Pokemon since it is not on the field + newPokemon.setVisible(false); + ret = newPokemon; this.scene.triggerPokemonFormChange(newPokemon, SpeciesFormChangeActiveTrigger, true); } diff --git a/src/game-mode.ts b/src/game-mode.ts index 8f1bb9356e6..3f12c5b056e 100644 --- a/src/game-mode.ts +++ b/src/game-mode.ts @@ -230,13 +230,20 @@ export class GameMode implements GameModeConfig { return waveIndex % 10 === 0; } + /** + * @returns `true` if the current battle is against classic mode's final boss + */ + isBattleClassicFinalBoss(waveIndex: number): boolean { + return (this.modeId === GameModes.CLASSIC || this.modeId === GameModes.CHALLENGE) && this.isWaveFinal(waveIndex); + } + /** * Every 50 waves of an Endless mode is a boss * At this time it is paradox pokemon * @returns true if waveIndex is a multiple of 50 in Endless */ isEndlessBoss(waveIndex: integer): boolean { - return !!(waveIndex % 50) && + return waveIndex % 50 === 0 && (this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS); } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 571c54d76e9..4986c1feab1 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -10,7 +10,7 @@ import { getStatusEffectDescriptor } from "#app/data/status-effect"; import { Type } from "#enums/type"; import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; -import { AddPokeballModifier, AddVoucherModifier, AttackTypeBoosterModifier, BaseStatModifier, BerryModifier, BoostBugSpawnModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, CritBoosterModifier, DamageMoneyRewardModifier, DoubleBattleChanceBoosterModifier, EnemyAttackStatusEffectChanceModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, EvolutionItemModifier, EvolutionStatBoosterModifier, EvoTrackerModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, GigantamaxAccessModifier, HealingBoosterModifier, HealShopCostModifier, HiddenAbilityRateBoosterModifier, HitHealModifier, IvScannerModifier, LevelIncrementBoosterModifier, LockModifierTiersModifier, MapModifier, MegaEvolutionAccessModifier, MoneyInterestModifier, MoneyMultiplierModifier, MoneyRewardModifier, MultipleParticipantExpBonusModifier, PokemonAllMovePpRestoreModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, PokemonInstantReviveModifier, PokemonLevelIncrementModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PokemonNatureChangeModifier, PokemonNatureWeightModifier, PokemonPpRestoreModifier, PokemonPpUpModifier, PokemonStatusHealModifier, PreserveBerryModifier, RememberMoveModifier, ResetNegativeStatStageModifier, ShinyRateBoosterModifier, SpeciesCritBoosterModifier, SpeciesStatBoosterModifier, SurviveDamageModifier, SwitchEffectTransferModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeAccessModifier, TerastallizeModifier, TmModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier, type EnemyPersistentModifier, type Modifier, type PersistentModifier, TempExtraModifierModifier } from "#app/modifier/modifier"; +import { AddPokeballModifier, AddVoucherModifier, AttackTypeBoosterModifier, BaseStatModifier, BerryModifier, BoostBugSpawnModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, CritBoosterModifier, DamageMoneyRewardModifier, DoubleBattleChanceBoosterModifier, EnemyAttackStatusEffectChanceModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, EvolutionItemModifier, EvolutionStatBoosterModifier, EvoTrackerModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, GigantamaxAccessModifier, HealingBoosterModifier, HealShopCostModifier, HiddenAbilityRateBoosterModifier, HitHealModifier, IvScannerModifier, LevelIncrementBoosterModifier, LockModifierTiersModifier, MapModifier, MegaEvolutionAccessModifier, MoneyInterestModifier, MoneyMultiplierModifier, MoneyRewardModifier, MultipleParticipantExpBonusModifier, PokemonAllMovePpRestoreModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, PokemonInstantReviveModifier, PokemonLevelIncrementModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PokemonNatureChangeModifier, PokemonNatureWeightModifier, PokemonPpRestoreModifier, PokemonPpUpModifier, PokemonStatusHealModifier, PreserveBerryModifier, RememberMoveModifier, ResetNegativeStatStageModifier, ShinyRateBoosterModifier, SpeciesCritBoosterModifier, SpeciesStatBoosterModifier, SurviveDamageModifier, SwitchEffectTransferModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeAccessModifier, TerastallizeModifier, TmModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier, type EnemyPersistentModifier, type Modifier, type PersistentModifier, TempExtraModifierModifier, CriticalCatchChanceBoosterModifier } from "#app/modifier/modifier"; import { ModifierTier } from "#app/modifier/modifier-tier"; import Overrides from "#app/overrides"; import { Unlockables } from "#app/system/unlockables"; @@ -1554,6 +1554,7 @@ export const modifierTypes = { SHINY_CHARM: () => new ModifierType("modifierType:ModifierType.SHINY_CHARM", "shiny_charm", (type, _args) => new ShinyRateBoosterModifier(type)), ABILITY_CHARM: () => new ModifierType("modifierType:ModifierType.ABILITY_CHARM", "ability_charm", (type, _args) => new HiddenAbilityRateBoosterModifier(type)), + CATCHING_CHARM: () => new ModifierType("modifierType:ModifierType.CATCHING_CHARM", "catching_charm", (type, _args) => new CriticalCatchChanceBoosterModifier(type)), IV_SCANNER: () => new ModifierType("modifierType:ModifierType.IV_SCANNER", "scanner", (type, _args) => new IvScannerModifier(type)), @@ -1620,19 +1621,21 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.POKEBALL, (party: Pokemon[]) => (hasMaximumBalls(party, PokeballType.POKEBALL)) ? 0 : 6, 6), new WeightedModifierType(modifierTypes.RARE_CANDY, 2), new WeightedModifierType(modifierTypes.POTION, (party: Pokemon[]) => { - const thresholdPartyMemberCount = Math.min(party.filter(p => (p.getInverseHp() >= 10 || p.getHpRatio() <= 0.875) && !p.isFainted()).length, 3); + const thresholdPartyMemberCount = Math.min(party.filter(p => (p.getInverseHp() >= 10 && p.getHpRatio() <= 0.875) && !p.isFainted()).length, 3); return thresholdPartyMemberCount * 3; }, 9), new WeightedModifierType(modifierTypes.SUPER_POTION, (party: Pokemon[]) => { - const thresholdPartyMemberCount = Math.min(party.filter(p => (p.getInverseHp() >= 25 || p.getHpRatio() <= 0.75) && !p.isFainted()).length, 3); + const thresholdPartyMemberCount = Math.min(party.filter(p => (p.getInverseHp() >= 25 && p.getHpRatio() <= 0.75) && !p.isFainted()).length, 3); return thresholdPartyMemberCount; }, 3), new WeightedModifierType(modifierTypes.ETHER, (party: Pokemon[]) => { - const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed >= Math.floor(m.getMovePp() / 2)).length).length, 3); + const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA) + && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3); return thresholdPartyMemberCount * 3; }, 9), new WeightedModifierType(modifierTypes.MAX_ETHER, (party: Pokemon[]) => { - const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed >= Math.floor(m.getMovePp() / 2)).length).length, 3); + const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA) + && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3); return thresholdPartyMemberCount; }, 3), new WeightedModifierType(modifierTypes.LURE, lureWeightFunc(10, 2)), @@ -1666,11 +1669,11 @@ const modifierPool: ModifierPool = { return party.filter(p => p.isFainted()).length >= Math.ceil(party.length / 2) ? 1 : 0; }, 1), new WeightedModifierType(modifierTypes.HYPER_POTION, (party: Pokemon[]) => { - const thresholdPartyMemberCount = Math.min(party.filter(p => (p.getInverseHp() >= 100 || p.getHpRatio() <= 0.625) && !p.isFainted()).length, 3); + const thresholdPartyMemberCount = Math.min(party.filter(p => (p.getInverseHp() >= 100 && p.getHpRatio() <= 0.625) && !p.isFainted()).length, 3); return thresholdPartyMemberCount * 3; }, 9), new WeightedModifierType(modifierTypes.MAX_POTION, (party: Pokemon[]) => { - const thresholdPartyMemberCount = Math.min(party.filter(p => (p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5) && !p.isFainted()).length, 3); + const thresholdPartyMemberCount = Math.min(party.filter(p => (p.getInverseHp() >= 100 && p.getHpRatio() <= 0.5) && !p.isFainted()).length, 3); return thresholdPartyMemberCount; }, 3), new WeightedModifierType(modifierTypes.FULL_RESTORE, (party: Pokemon[]) => { @@ -1680,15 +1683,17 @@ const modifierPool: ModifierPool = { } return false; })).length, 3); - const thresholdPartyMemberCount = Math.floor((Math.min(party.filter(p => (p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5) && !p.isFainted()).length, 3) + statusEffectPartyMemberCount) / 2); + const thresholdPartyMemberCount = Math.floor((Math.min(party.filter(p => (p.getInverseHp() >= 100 && p.getHpRatio() <= 0.5) && !p.isFainted()).length, 3) + statusEffectPartyMemberCount) / 2); return thresholdPartyMemberCount; }, 3), new WeightedModifierType(modifierTypes.ELIXIR, (party: Pokemon[]) => { - const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed >= Math.floor(m.getMovePp() / 2)).length).length, 3); + const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA) + && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3); return thresholdPartyMemberCount * 3; }, 9), new WeightedModifierType(modifierTypes.MAX_ELIXIR, (party: Pokemon[]) => { - const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed >= Math.floor(m.getMovePp() / 2)).length).length, 3); + const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA) + && p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3); return thresholdPartyMemberCount; }, 3), new WeightedModifierType(modifierTypes.DIRE_HIT, 4), @@ -1697,10 +1702,7 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, (party: Pokemon[]) => { return Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15), 8); }, 8), - new WeightedModifierType(modifierTypes.MAP, - (party: Pokemon[]) => party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex < 180 ? party[0].scene.eventManager.isEventActive() ? 2 : 1 : 0, - (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 2 : 1), - new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 3 : 0), + new WeightedModifierType(modifierTypes.MAP, (party: Pokemon[]) => party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex < 180 ? 1 : 0, 1), new WeightedModifierType(modifierTypes.TM_GREAT, 3), new WeightedModifierType(modifierTypes.MEMORY_MUSHROOM, (party: Pokemon[]) => { if (!party.find(p => p.getLearnableLevelMoves().length)) { @@ -1768,7 +1770,7 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)), new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9), new WeightedModifierType(modifierTypes.TM_ULTRA, 11), - new WeightedModifierType(modifierTypes.RARER_CANDY, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 6 : 4), + new WeightedModifierType(modifierTypes.RARER_CANDY, 4), new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)), new WeightedModifierType(modifierTypes.IV_SCANNER, skipInLastClassicWaveOrDefault(4)), new WeightedModifierType(modifierTypes.EXP_CHARM, skipInLastClassicWaveOrDefault(8)), @@ -1791,7 +1793,8 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.BATON, 2), new WeightedModifierType(modifierTypes.SOUL_DEW, 7), //new WeightedModifierType(modifierTypes.OVAL_CHARM, 6), - new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => party[0].scene.eventManager.isEventActive() ? 0 : 4), + new WeightedModifierType(modifierTypes.CATCHING_CHARM, (party: Pokemon[]) => !party[0].scene.gameMode.isFreshStartChallenge() && party[0].scene.gameData.getSpeciesCount(d => !!d.caughtAttr) > 100 ? 4 : 0, 4), + new WeightedModifierType(modifierTypes.SOOTHE_BELL, 4), new WeightedModifierType(modifierTypes.ABILITY_CHARM, skipInClassicAfterWave(189, 6)), new WeightedModifierType(modifierTypes.FOCUS_BAND, 5), new WeightedModifierType(modifierTypes.KINGS_ROCK, 3), diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index d2965247826..5e5246269a3 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1,12 +1,11 @@ import type BattleScene from "#app/battle-scene"; -import { FusionSpeciesFormEvolution, pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; +import { FusionSpeciesFormEvolution, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { getBerryEffectFunc, getBerryPredicate } from "#app/data/berry"; import { getLevelTotalExp } from "#app/data/exp"; import { allMoves } from "#app/data/move"; import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball"; import { type FormChangeItem, SpeciesFormChangeItemTrigger, SpeciesFormChangeLapseTeraTrigger, SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms"; import { getStatusEffectHealText } from "#app/data/status-effect"; -import { Type } from "#enums/type"; import Pokemon, { type PlayerPokemon } from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; import Overrides from "#app/overrides"; @@ -22,11 +21,13 @@ import { BooleanHolder, hslToHex, isNullOrUndefined, NumberHolder, toDmgValue } import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; import { BerryType } from "#enums/berry-type"; +import { Moves } from "#enums/moves"; import type { Nature } from "#enums/nature"; import type { PokeballType } from "#enums/pokeball"; import { Species } from "#enums/species"; import { type PermanentStat, type TempBattleStat, BATTLE_STATS, Stat, TEMP_BATTLE_STATS } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; +import { Type } from "#enums/type"; import i18next from "i18next"; import { type DoubleBattleChanceBoosterModifierType, type EvolutionItemModifierType, type FormChangeItemModifierType, type ModifierOverride, type ModifierType, type PokemonBaseStatTotalModifierType, type PokemonExpBoosterModifierType, type PokemonFriendshipBoosterModifierType, type PokemonMoveAccuracyBoosterModifierType, type PokemonMultiHitModifierType, type TerastallizeModifierType, type TmModifierType, getModifierType, ModifierPoolType, ModifierTypeGenerator, modifierTypes, PokemonHeldItemModifierType } from "./modifier-type"; import { Color, ShadowColor } from "#enums/color"; @@ -728,10 +729,10 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { //Applies to items with chance of activating secondary effects ie Kings Rock getSecondaryChanceMultiplier(pokemon: Pokemon): number { // Temporary quickfix to stop game from freezing when the opponet uses u-turn while holding on to king's rock - if (!pokemon.getLastXMoves(0)[0]) { + if (!pokemon.getLastXMoves()[0]) { return 1; } - const sheerForceAffected = allMoves[pokemon.getLastXMoves(0)[0].move].chance >= 0 && pokemon.hasAbility(Abilities.SHEER_FORCE); + const sheerForceAffected = allMoves[pokemon.getLastXMoves()[0].move].chance >= 0 && pokemon.hasAbility(Abilities.SHEER_FORCE); if (sheerForceAffected) { return 0; @@ -2196,14 +2197,8 @@ export class PokemonNatureChangeModifier extends ConsumablePokemonModifier { * @returns */ override apply(playerPokemon: PlayerPokemon): boolean { - playerPokemon.customPokemonData.nature = this.nature; - let speciesId = playerPokemon.species.speciesId; - playerPokemon.scene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1); - - while (pokemonPrevolutions.hasOwnProperty(speciesId)) { - speciesId = pokemonPrevolutions[speciesId]; - playerPokemon.scene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1); - } + playerPokemon.setCustomNature(this.nature); + playerPokemon.scene.gameData.unlockSpeciesNature(playerPokemon.species, this.nature); return true; } @@ -2689,32 +2684,65 @@ export class PokemonMultiHitModifier extends PokemonHeldItemModifier { } /** - * Applies {@linkcode PokemonMultiHitModifier} - * @param _pokemon The {@linkcode Pokemon} using the move - * @param count {@linkcode NumberHolder} holding the number of items - * @param power {@linkcode NumberHolder} holding the power of the move + * For each stack, converts 25 percent of attack damage into an additional strike. + * @param pokemon The {@linkcode Pokemon} using the move + * @param moveId The {@linkcode Moves | identifier} for the move being used + * @param count {@linkcode NumberHolder} holding the move's hit count for this turn + * @param damageMultiplier {@linkcode NumberHolder} holding a damage multiplier applied to a strike of this move * @returns always `true` */ - override apply(_pokemon: Pokemon, count: NumberHolder, power: NumberHolder): boolean { - count.value *= (this.getStackCount() + 1); - - switch (this.getStackCount()) { - case 1: - power.value *= 0.4; - break; - case 2: - power.value *= 0.25; - break; - case 3: - power.value *= 0.175; - break; + override apply(pokemon: Pokemon, moveId: Moves, count: NumberHolder | null = null, damageMultiplier: NumberHolder | null = null): boolean { + const move = allMoves[moveId]; + /** + * The move must meet Parental Bond's restrictions for this item + * to apply. This means + * - Only attacks are boosted + * - Multi-strike moves, charge moves, and self-sacrificial moves are not boosted + * (though Multi-Lens can still affect moves boosted by Parental Bond) + * - Multi-target moves are not boosted *unless* they can only hit a single Pokemon + * - Fling, Uproar, Rollout, Ice Ball, and Endeavor are not boosted + */ + if (!move.canBeMultiStrikeEnhanced(pokemon)) { + return false; } + if (!isNullOrUndefined(count)) { + return this.applyHitCountBoost(count); + } else if (!isNullOrUndefined(damageMultiplier)) { + return this.applyDamageModifier(pokemon, damageMultiplier); + } + + return false; + } + + /** Adds strikes to a move equal to the number of stacked Multi-Lenses */ + private applyHitCountBoost(count: NumberHolder): boolean { + count.value += this.getStackCount(); return true; } + /** + * If applied to the first hit of a move, sets the damage multiplier + * equal to (1 - the number of stacked Multi-Lenses). + * Additional strikes beyond that are given a 0.25x damage multiplier + */ + private applyDamageModifier(pokemon: Pokemon, damageMultiplier: NumberHolder): boolean { + if (pokemon.turnData.hitsLeft === pokemon.turnData.hitCount) { + // Reduce first hit by 25% for each stack count + damageMultiplier.value *= 1 - 0.25 * this.getStackCount(); + return true; + } else if (pokemon.turnData.hitCount - pokemon.turnData.hitsLeft !== this.getStackCount() + 1) { + // Deal 25% damage for each remaining Multi Lens hit + damageMultiplier.value *= 0.25; + return true; + } else { + // An extra hit not caused by Multi Lens -- assume it is Parental Bond + return false; + } + } + getMaxHeldItemCount(pokemon: Pokemon): number { - return 3; + return 2; } } @@ -2792,7 +2820,7 @@ export class MoneyRewardModifier extends ConsumableModifier { battleScene.getPlayerParty().map(p => { if (p.species?.speciesId === Species.GIMMIGHOUL || p.fusionSpecies?.speciesId === Species.GIMMIGHOUL) { - p.evoCounter ? p.evoCounter++ : p.evoCounter = 1; + p.evoCounter ? p.evoCounter += Math.min(Math.floor(this.moneyMultiplier), 3) : p.evoCounter = Math.min(Math.floor(this.moneyMultiplier), 3); const modifier = getModifierType(modifierTypes.EVOLUTION_TRACKER_GIMMIGHOUL).newModifier(p) as EvoTrackerModifier; battleScene.addModifier(modifier); } @@ -2957,6 +2985,38 @@ export class ShinyRateBoosterModifier extends PersistentModifier { } } +export class CriticalCatchChanceBoosterModifier extends PersistentModifier { + constructor(type: ModifierType, stackCount?: number) { + super(type, stackCount); + } + + match(modifier: Modifier): boolean { + return modifier instanceof CriticalCatchChanceBoosterModifier; + } + + clone(): CriticalCatchChanceBoosterModifier { + return new CriticalCatchChanceBoosterModifier(this.type, this.stackCount); + } + + /** + * Applies {@linkcode CriticalCatchChanceBoosterModifier} + * @param boost {@linkcode NumberHolder} holding the boost value + * @returns always `true` + */ + override apply(boost: NumberHolder): boolean { + // 1 stack: 2x + // 2 stack: 2.5x + // 3 stack: 3x + boost.value *= 1.5 + this.getStackCount() / 2; + + return true; + } + + getMaxStackCount(scene: BattleScene): number { + return 3; + } +} + export class LockModifierTiersModifier extends PersistentModifier { constructor(type: ModifierType, stackCount?: number) { super(type, stackCount); @@ -3573,7 +3633,7 @@ export class EnemyEndureChanceModifier extends EnemyPersistentModifier { super(type, stackCount || 10); //Hardcode temporarily - this.chance = .02; + this.chance = 2; } match(modifier: Modifier) { @@ -3581,24 +3641,24 @@ export class EnemyEndureChanceModifier extends EnemyPersistentModifier { } clone() { - return new EnemyEndureChanceModifier(this.type, this.chance * 100, this.stackCount); + return new EnemyEndureChanceModifier(this.type, this.chance, this.stackCount); } getArgs(): any[] { - return [ this.chance * 100 ]; + return [ this.chance ]; } /** - * Applies {@linkcode EnemyEndureChanceModifier} - * @param target {@linkcode Pokemon} to apply the {@linkcode BattlerTagType.ENDURING} chance to + * Applies a chance of enduring a lethal hit of an attack + * @param target the {@linkcode Pokemon} to apply the {@linkcode BattlerTagType.ENDURING} chance to * @returns `true` if {@linkcode Pokemon} endured */ override apply(target: Pokemon): boolean { - if (target.battleData.endured || Phaser.Math.RND.realInRange(0, 1) >= (this.chance * this.getStackCount())) { + if (target.battleData.endured || target.randSeedInt(100) >= (this.chance * this.getStackCount())) { return false; } - target.addTag(BattlerTagType.ENDURING, 1); + target.addTag(BattlerTagType.ENDURE_TOKEN, 1); target.battleData.endured = true; diff --git a/src/overrides.ts b/src/overrides.ts index d7a8ee18f15..7b73cd47b03 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -47,7 +47,18 @@ class DefaultOverrides { /** a specific seed (default: a random string of 24 characters) */ readonly SEED_OVERRIDE: string = ""; readonly WEATHER_OVERRIDE: WeatherType = WeatherType.NONE; - readonly BATTLE_TYPE_OVERRIDE: "double" | "single" | null = null; + /** + * If `null`, ignore this override. + * + * If `"single"`, set every non-trainer battle to be a single battle. + * + * If `"double"`, set every battle (including trainer battles) to be a double battle. + * + * If `"even-doubles"`, follow the `"double"` rule on even wave numbers, and follow the `"single"` rule on odd wave numbers. + * + * If `"odd-doubles"`, follow the `"double"` rule on odd wave numbers, and follow the `"single"` rule on even wave numbers. + */ + readonly BATTLE_TYPE_OVERRIDE: BattleStyle | null = null; readonly STARTING_WAVE_OVERRIDE: number = 0; readonly STARTING_BIOME_OVERRIDE: Biome = Biome.TOWN; readonly ARENA_TINT_OVERRIDE: TimeOfDay | null = null; @@ -229,3 +240,5 @@ export default { ...defaultOverrides, ...overrides } satisfies InstanceType; + +export type BattleStyle = "double" | "single" | "even-doubles" | "odd-doubles"; diff --git a/src/phases/berry-phase.ts b/src/phases/berry-phase.ts index 7404766ebd5..c0d0eb03026 100644 --- a/src/phases/berry-phase.ts +++ b/src/phases/berry-phase.ts @@ -31,11 +31,8 @@ export class BerryPhase extends FieldPhase { for (const berryModifier of this.scene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) { if (berryModifier.consumed) { - if (!--berryModifier.stackCount) { - this.scene.removeModifier(berryModifier); - } else { - berryModifier.consumed = false; - } + berryModifier.consumed = false; + pokemon.loseHeldItem(berryModifier); } this.scene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier)); // Announce a berry was used } diff --git a/src/phases/check-switch-phase.ts b/src/phases/check-switch-phase.ts index 9ae720fbe8e..a5859748cea 100644 --- a/src/phases/check-switch-phase.ts +++ b/src/phases/check-switch-phase.ts @@ -26,25 +26,29 @@ export class CheckSwitchPhase extends BattlePhase { const pokemon = this.scene.getPlayerField()[this.fieldIndex]; + // End this phase early... + + // ...if the user is playing in Set Mode if (this.scene.battleStyle === BattleStyle.SET) { - super.end(); - return; + return super.end(); } + // ...if the checked Pokemon is somehow not on the field if (this.scene.field.getAll().indexOf(pokemon) === -1) { this.scene.unshiftPhase(new SummonMissingPhase(this.scene, this.fieldIndex)); - super.end(); - return; + return super.end(); } + // ...if there are no other allowed Pokemon in the player's party to switch with if (!this.scene.getPlayerParty().slice(1).filter(p => p.isActive()).length) { - super.end(); - return; + return super.end(); } - if (pokemon.getTag(BattlerTagType.FRENZY)) { - super.end(); - return; + // ...or if any player Pokemon has an effect that prevents the checked Pokemon from switching + if (pokemon.getTag(BattlerTagType.FRENZY) + || pokemon.isTrapped() + || this.scene.getPlayerField().some(p => p.getTag(BattlerTagType.COMMANDED))) { + return super.end(); } this.scene.ui.showText(i18next.t("battle:switchQuestion", { pokemonName: this.useName ? getPokemonNameWithAffix(pokemon) : i18next.t("battle:pokemon") }), null, () => { diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index c131f28fd71..001a65e2508 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -36,7 +36,6 @@ import { PlayerGender } from "#enums/player-gender"; import { Species } from "#enums/species"; import i18next from "i18next"; import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters"; -import { BattlerTagType } from "#enums/battler-tag-type"; export class EncounterPhase extends BattlePhase { private loaded: boolean; @@ -142,10 +141,6 @@ export class EncounterPhase extends BattlePhase { } else if (!(battle.waveIndex % 1000)) { enemyPokemon.formIndex = 1; enemyPokemon.updateScale(); - const bossMBH = this.scene.findModifier(m => m instanceof TurnHeldItemTransferModifier && m.pokemonId === enemyPokemon.id, false) as TurnHeldItemTransferModifier; - this.scene.removeModifier(bossMBH!); - bossMBH?.setTransferrableFalse(); - this.scene.addEnemyModifier(bossMBH!); } } @@ -203,7 +198,7 @@ export class EncounterPhase extends BattlePhase { this.scene.field.add(enemyPokemon); battle.seenEnemyPartyMemberIds.add(enemyPokemon.id); const playerPokemon = this.scene.getPlayerPokemon(); - if (playerPokemon?.visible) { + if (playerPokemon?.isOnField()) { this.scene.field.moveBelow(enemyPokemon as Pokemon, playerPokemon); } enemyPokemon.tint(0, 0.5); @@ -226,7 +221,8 @@ export class EncounterPhase extends BattlePhase { this.scene.ui.setMode(Mode.MESSAGE).then(() => { if (!this.loaded) { this.trySetWeatherIfNewBiome(); // Set weather before session gets saved - this.scene.gameData.saveAll(this.scene, true, battle.waveIndex % 10 === 1 || (this.scene.lastSavePlayTime ?? 0) >= 300).then(success => { + // Game syncs to server on waves X1 and X6 (As of 1.2.0) + this.scene.gameData.saveAll(this.scene, true, battle.waveIndex % 5 === 1 || (this.scene.lastSavePlayTime ?? 0) >= 300).then(success => { this.scene.disableMenu = false; if (!success) { return this.scene.reset(true); @@ -443,6 +439,15 @@ export class EncounterPhase extends BattlePhase { if (enemyPokemon.isShiny()) { this.scene.unshiftPhase(new ShinySparklePhase(this.scene, BattlerIndex.ENEMY + e)); } + /** This sets Eternatus' held item to be untransferrable, preventing it from being stolen */ + if (enemyPokemon.species.speciesId === Species.ETERNATUS && (this.scene.gameMode.isBattleClassicFinalBoss(this.scene.currentBattle.waveIndex) || this.scene.gameMode.isEndlessMajorBoss(this.scene.currentBattle.waveIndex))) { + const enemyMBH = this.scene.findModifier(m => m instanceof TurnHeldItemTransferModifier, false) as TurnHeldItemTransferModifier; + if (enemyMBH) { + this.scene.removeModifier(enemyMBH, true); + enemyMBH.setTransferrableFalse(); + this.scene.addEnemyModifier(enemyMBH); + } + } }); if (![ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.scene.currentBattle.battleType)) { @@ -483,7 +488,6 @@ export class EncounterPhase extends BattlePhase { } } else { if (availablePartyMembers.length > 1 && availablePartyMembers[1].isOnField()) { - this.scene.getPlayerField().forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDED)); this.scene.pushPhase(new ReturnPhase(this.scene, 1)); } this.scene.pushPhase(new ToggleDoublePositionPhase(this.scene, false)); diff --git a/src/phases/faint-phase.ts b/src/phases/faint-phase.ts index d66c5b66144..1c48bdfb37a 100644 --- a/src/phases/faint-phase.ts +++ b/src/phases/faint-phase.ts @@ -55,21 +55,21 @@ export class FaintPhase extends PokemonPhase { start() { super.start(); + const faintPokemon = this.getPokemon(); + if (!isNullOrUndefined(this.destinyTag) && !isNullOrUndefined(this.source)) { this.destinyTag.lapse(this.source, BattlerTagLapseType.CUSTOM); } if (!isNullOrUndefined(this.grudgeTag) && !isNullOrUndefined(this.source)) { - this.grudgeTag.lapse(this.getPokemon(), BattlerTagLapseType.CUSTOM, this.source); + this.grudgeTag.lapse(faintPokemon, BattlerTagLapseType.CUSTOM, this.source); } if (!this.preventEndure) { - const instantReviveModifier = this.scene.applyModifier(PokemonInstantReviveModifier, this.player, this.getPokemon()) as PokemonInstantReviveModifier; + const instantReviveModifier = this.scene.applyModifier(PokemonInstantReviveModifier, this.player, faintPokemon) as PokemonInstantReviveModifier; if (instantReviveModifier) { - if (!--instantReviveModifier.stackCount) { - this.scene.removeModifier(instantReviveModifier); - } + faintPokemon.loseHeldItem(instantReviveModifier); this.scene.updateModifiers(this.player); return this.end(); } diff --git a/src/phases/game-over-phase.ts b/src/phases/game-over-phase.ts index 331ab27bf30..8adfd93f1d6 100644 --- a/src/phases/game-over-phase.ts +++ b/src/phases/game-over-phase.ts @@ -26,13 +26,13 @@ import i18next from "i18next"; import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; export class GameOverPhase extends BattlePhase { - private victory: boolean; + private isVictory: boolean; private firstRibbons: PokemonSpecies[] = []; - constructor(scene: BattleScene, victory: boolean = false) { + constructor(scene: BattleScene, isVictory: boolean = false) { super(scene); - this.victory = victory; + this.isVictory = isVictory; } start() { @@ -40,22 +40,22 @@ export class GameOverPhase extends BattlePhase { // Failsafe if players somehow skip floor 200 in classic mode if (this.scene.gameMode.isClassic && this.scene.currentBattle.waveIndex > 200) { - this.victory = true; + this.isVictory = true; } // Handle Mystery Encounter special Game Over cases // Situations such as when player lost a battle, but it isn't treated as full Game Over - if (!this.victory && this.scene.currentBattle.mysteryEncounter?.onGameOver && !this.scene.currentBattle.mysteryEncounter.onGameOver(this.scene)) { + if (!this.isVictory && this.scene.currentBattle.mysteryEncounter?.onGameOver && !this.scene.currentBattle.mysteryEncounter.onGameOver(this.scene)) { // Do not end the game return this.end(); } // Otherwise, continue standard Game Over logic - if (this.victory && this.scene.gameMode.isEndless) { + if (this.isVictory && this.scene.gameMode.isEndless) { const genderIndex = this.scene.gameData.gender ?? PlayerGender.UNSET; const genderStr = PlayerGender[genderIndex].toLowerCase(); this.scene.ui.showDialogue(i18next.t("miscDialogue:ending_endless", { context: genderStr }), i18next.t("miscDialogue:ending_name"), 0, () => this.handleGameOver()); - } else if (this.victory || !this.scene.enableRetries) { + } else if (this.isVictory || !this.scene.enableRetries) { this.handleGameOver(); } else { this.scene.ui.showText(i18next.t("battle:retryBattle"), null, () => { @@ -93,7 +93,7 @@ export class GameOverPhase extends BattlePhase { this.scene.disableMenu = true; this.scene.time.delayedCall(1000, () => { let firstClear = false; - if (this.victory && newClear) { + if (this.isVictory && newClear) { if (this.scene.gameMode.isClassic) { firstClear = this.scene.validateAchv(achvs.CLASSIC_VICTORY); this.scene.validateAchv(achvs.UNEVOLVED_CLASSIC_VICTORY); @@ -109,8 +109,8 @@ export class GameOverPhase extends BattlePhase { this.scene.gameData.gameStats.dailyRunSessionsWon++; } } - this.scene.gameData.saveRunHistory(this.scene, this.scene.gameData.getSessionSaveData(this.scene), this.victory); - const fadeDuration = this.victory ? 10000 : 5000; + this.scene.gameData.saveRunHistory(this.scene, this.scene.gameData.getSessionSaveData(this.scene), this.isVictory); + const fadeDuration = this.isVictory ? 10000 : 5000; this.scene.fadeOutBgm(fadeDuration, true); const activeBattlers = this.scene.getField().filter(p => p?.isActive(true)); activeBattlers.map(p => p.hideInfo()); @@ -120,15 +120,14 @@ export class GameOverPhase extends BattlePhase { this.scene.clearPhaseQueue(); this.scene.ui.clearText(); - if (this.victory && this.scene.gameMode.isChallenge) { + if (this.isVictory && this.scene.gameMode.isChallenge) { this.scene.gameMode.challenges.forEach(c => this.scene.validateAchvs(ChallengeAchv, c)); } const clear = (endCardPhase?: EndCardPhase) => { - if (newClear) { + if (this.isVictory && newClear) { this.handleUnlocks(); - } - if (this.victory && newClear) { + for (const species of this.firstRibbons) { this.scene.unshiftPhase(new RibbonModifierRewardPhase(this.scene, modifierTypes.VOUCHER_PLUS, species)); } @@ -140,7 +139,7 @@ export class GameOverPhase extends BattlePhase { this.end(); }; - if (this.victory && this.scene.gameMode.isClassic) { + if (this.isVictory && this.scene.gameMode.isClassic) { const dialogueKey = "miscDialogue:ending"; if (!this.scene.ui.shouldSkipDialogue(dialogueKey)) { @@ -173,25 +172,23 @@ export class GameOverPhase extends BattlePhase { }); }; - /* Added a local check to see if the game is running offline on victory + /* Added a local check to see if the game is running offline If Online, execute apiFetch as intended - If Offline, execute offlineNewClear(), a localStorage implementation of newClear daily run checks */ - if (this.victory) { - if (!isLocal || isLocalServerConnected) { - pokerogueApi.savedata.session.newclear({ slot: this.scene.sessionSlotId, clientSessionId }) - .then((success) => doGameOver(!!success)); - } else { - this.scene.gameData.offlineNewClear(this.scene).then(result => { - doGameOver(result); - }); - } + If Offline, execute offlineNewClear() only for victory, a localStorage implementation of newClear daily run checks */ + if (!isLocal || isLocalServerConnected) { + pokerogueApi.savedata.session.newclear({ slot: this.scene.sessionSlotId, isVictory: this.isVictory, clientSessionId: clientSessionId }) + .then((success) => doGameOver(!!success)); + } else if (this.isVictory) { + this.scene.gameData.offlineNewClear(this.scene).then(result => { + doGameOver(result); + }); } else { doGameOver(false); } } handleUnlocks(): void { - if (this.victory && this.scene.gameMode.isClassic) { + if (this.isVictory && this.scene.gameMode.isClassic) { if (!this.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]) { this.scene.unshiftPhase(new UnlockPhase(this.scene, Unlockables.ENDLESS_MODE)); } diff --git a/src/phases/level-up-phase.ts b/src/phases/level-up-phase.ts index 29abb6d0c38..4f26abc5af3 100644 --- a/src/phases/level-up-phase.ts +++ b/src/phases/level-up-phase.ts @@ -1,27 +1,27 @@ -import BattleScene from "#app/battle-scene"; +import type BattleScene from "#app/battle-scene"; import { ExpNotification } from "#app/enums/exp-notification"; -import { EvolutionPhase } from "#app/phases/evolution-phase"; -import { PlayerPokemon } from "#app/field/pokemon"; +import type { PlayerPokemon } from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; +import { EvolutionPhase } from "#app/phases/evolution-phase"; +import { LearnMovePhase } from "#app/phases/learn-move-phase"; +import { PlayerPartyMemberPokemonPhase } from "#app/phases/player-party-member-pokemon-phase"; import { LevelAchv } from "#app/system/achv"; -import i18next from "i18next"; import { NumberHolder } from "#app/utils"; -import { PlayerPartyMemberPokemonPhase } from "./player-party-member-pokemon-phase"; -import { LearnMovePhase } from "./learn-move-phase"; +import i18next from "i18next"; export class LevelUpPhase extends PlayerPartyMemberPokemonPhase { - private lastLevel: number; - private level: number; + protected lastLevel: number; + protected level: number; + protected pokemon: PlayerPokemon = this.getPlayerPokemon(); constructor(scene: BattleScene, partyMemberIndex: number, lastLevel: number, level: number) { super(scene, partyMemberIndex); this.lastLevel = lastLevel; this.level = level; - this.scene = scene; } - start() { + public override start() { super.start(); if (this.level > this.scene.gameData.gameStats.highestLevel) { @@ -30,30 +30,37 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase { this.scene.validateAchvs(LevelAchv, new NumberHolder(this.level)); - const pokemon = this.getPokemon(); - const prevStats = pokemon.stats.slice(0); - pokemon.calculateStats(); - pokemon.updateInfo(); + const prevStats = this.pokemon.stats.slice(0); + this.pokemon.calculateStats(); + this.pokemon.updateInfo(); if (this.scene.expParty === ExpNotification.DEFAULT) { this.scene.playSound("level_up_fanfare"); - this.scene.ui.showText(i18next.t("battle:levelUp", { pokemonName: getPokemonNameWithAffix(this.getPokemon()), level: this.level }), null, () => this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()), null, true); + this.scene.ui.showText( + i18next.t("battle:levelUp", { pokemonName: getPokemonNameWithAffix(this.pokemon), level: this.level }), + null, + () => this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false) + .then(() => this.end()), null, true); } else if (this.scene.expParty === ExpNotification.SKIP) { this.end(); } else { // we still want to display the stats if activated this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()); } + } + + public override end() { if (this.lastLevel < 100) { // this feels like an unnecessary optimization const levelMoves = this.getPokemon().getLevelMoves(this.lastLevel + 1); for (const lm of levelMoves) { this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.partyMemberIndex, lm[1])); } } - if (!pokemon.pauseEvolutions) { - const evolution = pokemon.getEvolution(); + if (!this.pokemon.pauseEvolutions) { + const evolution = this.pokemon.getEvolution(); if (evolution) { - this.scene.unshiftPhase(new EvolutionPhase(this.scene, pokemon as PlayerPokemon, evolution, this.lastLevel)); + this.scene.unshiftPhase(new EvolutionPhase(this.scene, this.pokemon, evolution, this.lastLevel)); } } + return super.end(); } } diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index ef863d64c50..f7a9b22c396 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -26,7 +26,7 @@ import { applyMoveAttrs, AttackMove, DelayedAttackAttr, - FixedDamageAttr, + FlinchAttr, HitsTagAttr, MissEffectAttr, MoveAttr, @@ -92,8 +92,20 @@ export class MoveEffectPhase extends PokemonPhase { const isDelayedAttack = this.move.getMove().hasAttr(DelayedAttackAttr); /** If the user was somehow removed from the field and it's not a delayed attack, end this phase */ - if (!user.isOnField() && !isDelayedAttack) { - return super.end(); + if (!user.isOnField()) { + if (!isDelayedAttack) { + return super.end(); + } else { + if (!user.scene) { + /** + * This happens if the Pokemon that used the delayed attack gets caught and released + * on the turn the attack would have triggered. Having access to the global scene + * in the future may solve this entirely, so for now we just cancel the hit + */ + return super.end(); + } + user.resetTurnData(); + } } /** @@ -122,12 +134,10 @@ export class MoveEffectPhase extends PokemonPhase { const hitCount = new NumberHolder(1); // Assume single target for multi hit applyMoveAttrs(MultiHitAttr, user, this.getFirstTarget() ?? null, move, hitCount); - // If Parental Bond is applicable, double the hit count - applyPreAttackAbAttrs(AddSecondStrikeAbAttr, user, null, move, false, targets.length, hitCount, new NumberHolder(0)); - // If Multi-Lens is applicable, multiply the hit count by 1 + the number of Multi-Lenses held by the user - if (move instanceof AttackMove && !move.hasAttr(FixedDamageAttr)) { - this.scene.applyModifiers(PokemonMultiHitModifier, user.isPlayer(), user, hitCount, new NumberHolder(0)); - } + // If Parental Bond is applicable, add another hit + applyPreAttackAbAttrs(AddSecondStrikeAbAttr, user, null, move, false, hitCount, null); + // If Multi-Lens is applicable, add hits equal to the number of held Multi-Lenses + this.scene.applyModifiers(PokemonMultiHitModifier, user.isPlayer(), user, move.id, hitCount); // Set the user's relevant turnData fields to reflect the final hit count user.turnData.hitCount = hitCount.value; user.turnData.hitsLeft = hitCount.value; @@ -176,7 +186,7 @@ export class MoveEffectPhase extends PokemonPhase { const playOnEmptyField = this.scene.currentBattle?.mysteryEncounter?.hasBattleAnimationsWithoutTargets ?? false; // Move animation only needs one target - new MoveAnim(move.id as Moves, user, this.getFirstTarget()!.getBattlerIndex()!, playOnEmptyField).play(this.scene, move.hitsSubstitute(user, this.getFirstTarget()!), () => { + new MoveAnim(move.id as Moves, user, this.getFirstTarget()!.getBattlerIndex(), playOnEmptyField).play(this.scene, move.hitsSubstitute(user, this.getFirstTarget()!), () => { /** Has the move successfully hit a target (for damage) yet? */ let hasHit: boolean = false; for (const target of targets) { @@ -505,6 +515,10 @@ export class MoveEffectPhase extends PokemonPhase { */ protected applyHeldItemFlinchCheck(user: Pokemon, target: Pokemon, dealsDamage: boolean) : () => void { return () => { + if (this.move.getMove().hasAttr(FlinchAttr)) { + return; + } + if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && !this.move.getMove().hitsSubstitute(user, target)) { const flinched = new BooleanHolder(false); user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched); diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 6bdef281d70..005cdbe1716 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -121,12 +121,11 @@ export class MovePhase extends BattlePhase { // Check if move is unusable (e.g. because it's out of PP due to a mid-turn Spite). if (!this.canMove(true)) { - if (this.pokemon.isActive(true) && this.move.ppUsed >= this.move.getMovePp()) { + if (this.pokemon.isActive(true)) { this.fail(); this.showMoveText(); this.showFailedText(); } - return this.end(); } @@ -378,15 +377,9 @@ export class MovePhase extends BattlePhase { } else { this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual }); - let failedText: string | undefined; const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new BooleanHolder(false)); - - if (failureMessage) { - failedText = failureMessage; - } - this.showMoveText(); - this.showFailedText(failedText); + this.showFailedText(failureMessage ?? undefined); // Remove the user from its semi-invulnerable state (if applicable) this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); diff --git a/src/phases/pokemon-anim-phase.ts b/src/phases/pokemon-anim-phase.ts index 46d8127e27b..212429964e5 100644 --- a/src/phases/pokemon-anim-phase.ts +++ b/src/phases/pokemon-anim-phase.ts @@ -312,6 +312,10 @@ export class PokemonAnimPhase extends BattlePhase { // Note: unlike the other Commander animation, this is played through the // Dondozo instead of the Tatsugiri. const tatsugiri = this.pokemon.getAlly(); + if (isNullOrUndefined(tatsugiri)) { + console.warn("Aborting COMMANDER_REMOVE anim: Tatsugiri is undefined"); + return this.end(); + } const tatsuSprite = this.scene.addPokemonSprite( tatsugiri, diff --git a/src/phases/quiet-form-change-phase.ts b/src/phases/quiet-form-change-phase.ts index c28cc28b592..6c84c0d1a8a 100644 --- a/src/phases/quiet-form-change-phase.ts +++ b/src/phases/quiet-form-change-phase.ts @@ -29,10 +29,14 @@ export class QuietFormChangePhase extends BattlePhase { const preName = getPokemonNameWithAffix(this.pokemon); - if (!this.pokemon.isOnField() || this.pokemon.getTag(SemiInvulnerableTag)) { - this.pokemon.changeForm(this.formChange).then(() => { - this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), 1500); - }); + if (!this.pokemon.isOnField() || this.pokemon.getTag(SemiInvulnerableTag) || this.pokemon.isFainted()) { + if (this.pokemon.isPlayer() || this.pokemon.isActive()) { + this.pokemon.changeForm(this.formChange).then(() => { + this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), 1500); + }); + } else { + this.end(); + } return; } diff --git a/src/phases/select-modifier-phase.ts b/src/phases/select-modifier-phase.ts index dbc4b3402c9..ec1134376ba 100644 --- a/src/phases/select-modifier-phase.ts +++ b/src/phases/select-modifier-phase.ts @@ -102,7 +102,7 @@ export class SelectModifierPhase extends BattlePhase { const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.isTransferable && m.pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[]; const itemModifier = itemModifiers[itemIndex]; - this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, itemQuantity); + this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, itemQuantity, undefined, undefined, false); } else { this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), this.typeOptions, modifierSelectCallback, this.getRerollCost(this.scene.lockModifierTiers)); } diff --git a/src/phases/stat-stage-change-phase.ts b/src/phases/stat-stage-change-phase.ts index 892cb94e486..b000d40cc11 100644 --- a/src/phases/stat-stage-change-phase.ts +++ b/src/phases/stat-stage-change-phase.ts @@ -125,10 +125,7 @@ export class StatStageChangePhase extends PokemonPhase { const whiteHerb = this.scene.applyModifier(ResetNegativeStatStageModifier, this.player, pokemon) as ResetNegativeStatStageModifier; // If the White Herb was applied, consume it if (whiteHerb) { - whiteHerb.stackCount--; - if (whiteHerb.stackCount <= 0) { - this.scene.removeModifier(whiteHerb); - } + pokemon.loseHeldItem(whiteHerb); this.scene.updateModifiers(this.player); } } diff --git a/src/phases/summon-phase.ts b/src/phases/summon-phase.ts index eaac4fe2eea..7de9b4e9c13 100644 --- a/src/phases/summon-phase.ts +++ b/src/phases/summon-phase.ts @@ -140,7 +140,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { this.scene.field.add(pokemon); if (!this.player) { const playerPokemon = this.scene.getPlayerPokemon() as Pokemon; - if (playerPokemon?.visible) { + if (playerPokemon?.isOnField()) { this.scene.field.moveBelow(pokemon, playerPokemon); } this.scene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id); @@ -193,7 +193,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { this.scene.field.add(pokemon); if (!this.player) { const playerPokemon = this.scene.getPlayerPokemon() as Pokemon; - if (playerPokemon?.visible) { + if (playerPokemon?.isOnField()) { this.scene.field.moveBelow(pokemon, playerPokemon); } this.scene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id); diff --git a/src/phases/switch-summon-phase.ts b/src/phases/switch-summon-phase.ts index 0838eac77da..88fd3a5187e 100644 --- a/src/phases/switch-summon-phase.ts +++ b/src/phases/switch-summon-phase.ts @@ -111,7 +111,7 @@ export class SwitchSummonPhase extends SummonPhase { const batonPassModifier = this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id) as SwitchEffectTransferModifier; if (batonPassModifier && !this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedInPokemon.id)) { - this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedInPokemon, false); + this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedInPokemon, false, undefined, undefined, undefined, false); } } } @@ -138,7 +138,6 @@ export class SwitchSummonPhase extends SummonPhase { switchedInPokemon.setAlpha(0.5); } } else { - switchedInPokemon.resetBattleData(); switchedInPokemon.resetSummonData(); } this.summon(); diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 8f179ddb677..3e3a6ce8f8b 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -506,9 +506,9 @@ export class GameData { const starterIds = Object.keys(this.starterData).map(s => parseInt(s) as Species); for (const s of starterIds) { - this.starterData[s].candyCount += this.dexData[s].caughtCount; - this.starterData[s].candyCount += this.dexData[s].hatchedCount * 2; - if (this.dexData[s].caughtAttr & DexAttr.SHINY) { + this.starterData[s].candyCount += systemData.dexData[s].caughtCount; + this.starterData[s].candyCount += systemData.dexData[s].hatchedCount * 2; + if (systemData.dexData[s].caughtAttr & DexAttr.SHINY) { this.starterData[s].candyCount += 4; } } @@ -679,7 +679,7 @@ export class GameData { return ret; } - return k.endsWith("Attr") && ![ "natureAttr", "abilityAttr", "passiveAttr" ].includes(k) ? BigInt(v) : v; + return k.endsWith("Attr") && ![ "natureAttr", "abilityAttr", "passiveAttr" ].includes(k) ? BigInt(v ?? 0) : v; }) as SystemSaveData; } @@ -1540,7 +1540,7 @@ export class GameData { entry.caughtAttr = defaultStarterAttr; entry.natureAttr = 1 << (defaultStarterNatures[ds] + 1); for (const i in entry.ivs) { - entry.ivs[i] = 10; + entry.ivs[i] = 15; } } @@ -1791,6 +1791,32 @@ export class GameData { }); } + /** + * Checks whether the root species of a given {@PokemonSpecies} has been unlocked in the dex + */ + isRootSpeciesUnlocked(species: PokemonSpecies): boolean { + return !!this.dexData[species.getRootSpeciesId()]?.caughtAttr; + } + + /** + * Unlocks the given {@linkcode Nature} for a {@linkcode PokemonSpecies} and its prevolutions. + * Will fail silently if root species has not been unlocked + */ + unlockSpeciesNature(species: PokemonSpecies, nature: Nature): void { + if (!this.isRootSpeciesUnlocked(species)) { + return; + } + + //recursively unlock nature for species and prevolutions + const _unlockSpeciesNature = (speciesId: Species) => { + this.dexData[speciesId].natureAttr |= 1 << (nature + 1); + if (pokemonPrevolutions.hasOwnProperty(speciesId)) { + _unlockSpeciesNature(pokemonPrevolutions[speciesId]); + } + }; + _unlockSpeciesNature(species.speciesId); + } + updateSpeciesDexIvs(speciesId: Species, ivs: integer[]): void { let dexEntry: DexEntry; do { diff --git a/src/system/version_migration/version_converter.ts b/src/system/version_migration/version_converter.ts index e96afb5cbd4..d0c69dc3213 100644 --- a/src/system/version_migration/version_converter.ts +++ b/src/system/version_migration/version_converter.ts @@ -129,7 +129,7 @@ class SessionVersionConverter extends VersionConverter { if (curMajor === 1) { if (curMinor === 0) { - if (curPatch <= 4) { + if (curPatch <= 5) { console.log("Applying v1.0.4 session data migration!"); this.callMigrators(data, v1_0_4.sessionMigrators); } diff --git a/src/system/version_migration/versions/v1_0_4.ts b/src/system/version_migration/versions/v1_0_4.ts index f16b6bcb6bb..95f0337ecdd 100644 --- a/src/system/version_migration/versions/v1_0_4.ts +++ b/src/system/version_migration/versions/v1_0_4.ts @@ -1,6 +1,8 @@ -import { SettingKeys } from "../../settings/settings"; -import { AbilityAttr, defaultStarterSpecies, DexAttr, SystemSaveData, SessionSaveData } from "../../game-data"; -import { allSpecies } from "../../../data/pokemon-species"; +import { SettingKeys } from "#app/system/settings/settings"; +import { AbilityAttr, defaultStarterSpecies, DexAttr, SystemSaveData, SessionSaveData } from "#app/system/game-data"; +import { allSpecies } from "#app/data/pokemon-species"; +import { CustomPokemonData } from "#app/data/custom-pokemon-data"; +import { isNullOrUndefined } from "#app/utils"; export const systemMigrators = [ /** @@ -46,12 +48,14 @@ export const systemMigrators = [ * @param data {@linkcode SystemSaveData} */ function fixStarterData(data: SystemSaveData) { - for (const starterId of defaultStarterSpecies) { - if (data.starterData[starterId]?.abilityAttr) { - data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1; - } - if (data.dexData[starterId]?.caughtAttr) { - data.dexData[starterId].caughtAttr |= DexAttr.FEMALE; + if (!isNullOrUndefined(data.starterData)) { + for (const starterId of defaultStarterSpecies) { + if (data.starterData[starterId]?.abilityAttr) { + data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1; + } + if (data.dexData[starterId]?.caughtAttr) { + data.dexData[starterId].caughtAttr |= DexAttr.FEMALE; + } } } } @@ -131,5 +135,28 @@ export const sessionMigrators = [ m.className = "ResetNegativeStatStageModifier"; } }); + }, + /** + * Converts old Pokemon natureOverride and mysteryEncounterData + * to use the new conjoined {@linkcode Pokemon.customPokemonData} structure instead. + * @param data {@linkcode SessionSaveData} + */ + function migrateCustomPokemonDataAndNatureOverrides(data: SessionSaveData) { + // Fix Pokemon nature overrides and custom data migration + data.party.forEach(pokemon => { + if (pokemon["mysteryEncounterPokemonData"]) { + pokemon.customPokemonData = new CustomPokemonData(pokemon["mysteryEncounterPokemonData"]); + pokemon["mysteryEncounterPokemonData"] = null; + } + if (pokemon["fusionMysteryEncounterPokemonData"]) { + pokemon.fusionCustomPokemonData = new CustomPokemonData(pokemon["fusionMysteryEncounterPokemonData"]); + pokemon["fusionMysteryEncounterPokemonData"] = null; + } + pokemon.customPokemonData = pokemon.customPokemonData ?? new CustomPokemonData(); + if (!isNullOrUndefined(pokemon["natureOverride"]) && pokemon["natureOverride"] >= 0) { + pokemon.customPokemonData.nature = pokemon["natureOverride"]; + pokemon["natureOverride"] = -1; + } + }); } ] as const; diff --git a/src/system/version_migration/versions/v1_1_0.ts b/src/system/version_migration/versions/v1_1_0.ts index aac554c4531..5d6247aeaa2 100644 --- a/src/system/version_migration/versions/v1_1_0.ts +++ b/src/system/version_migration/versions/v1_1_0.ts @@ -1,32 +1,5 @@ -import { SessionSaveData } from "../../game-data"; -import { CustomPokemonData } from "#app/data/custom-pokemon-data"; - export const systemMigrators = [] as const; export const settingsMigrators = [] as const; -export const sessionMigrators = [ - /** - * Converts old Pokemon natureOverride and mysteryEncounterData - * to use the new conjoined {@linkcode Pokemon.customPokemonData} structure instead. - * @param data {@linkcode SessionSaveData} - */ - function migrateCustomPokemonDataAndNatureOverrides(data: SessionSaveData) { - // Fix Pokemon nature overrides and custom data migration - data.party.forEach(pokemon => { - if (pokemon["mysteryEncounterPokemonData"]) { - pokemon.customPokemonData = new CustomPokemonData(pokemon["mysteryEncounterPokemonData"]); - pokemon["mysteryEncounterPokemonData"] = null; - } - if (pokemon["fusionMysteryEncounterPokemonData"]) { - pokemon.fusionCustomPokemonData = new CustomPokemonData(pokemon["fusionMysteryEncounterPokemonData"]); - pokemon["fusionMysteryEncounterPokemonData"] = null; - } - pokemon.customPokemonData = pokemon.customPokemonData ?? new CustomPokemonData(); - if (pokemon["natureOverride"] && pokemon["natureOverride"] >= 0) { - pokemon.customPokemonData.nature = pokemon["natureOverride"]; - pokemon["natureOverride"] = -1; - } - }); - } -] as const; +export const sessionMigrators = [] as const; diff --git a/src/test/abilities/parental_bond.test.ts b/src/test/abilities/parental_bond.test.ts index d8f952ae6ad..10048a774cd 100644 --- a/src/test/abilities/parental_bond.test.ts +++ b/src/test/abilities/parental_bond.test.ts @@ -274,7 +274,7 @@ describe("Abilities - Parental Bond", () => { ); it( - "Moves boosted by this ability and Multi-Lens should strike 4 times", + "Moves boosted by this ability and Multi-Lens should strike 3 times", async () => { game.override.moveset([ Moves.TACKLE ]); game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); @@ -287,36 +287,12 @@ describe("Abilities - Parental Bond", () => { await game.phaseInterceptor.to("DamagePhase"); - expect(leadPokemon.turnData.hitCount).toBe(4); + expect(leadPokemon.turnData.hitCount).toBe(3); } ); it( - "Super Fang boosted by this ability and Multi-Lens should strike twice", - async () => { - game.override.moveset([ Moves.SUPER_FANG ]); - game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - - await game.classicMode.startBattle([ Species.MAGIKARP ]); - - const leadPokemon = game.scene.getPlayerPokemon()!; - const enemyPokemon = game.scene.getEnemyPokemon()!; - - game.move.select(Moves.SUPER_FANG); - await game.move.forceHit(); - - await game.phaseInterceptor.to("DamagePhase"); - - expect(leadPokemon.turnData.hitCount).toBe(2); - - await game.phaseInterceptor.to("MoveEndPhase", false); - - expect(enemyPokemon.hp).toBe(Math.ceil(enemyPokemon.getMaxHp() * 0.25)); - } - ); - - it( - "Seismic Toss boosted by this ability and Multi-Lens should strike twice", + "Seismic Toss boosted by this ability and Multi-Lens should strike 3 times", async () => { game.override.moveset([ Moves.SEISMIC_TOSS ]); game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); @@ -333,7 +309,7 @@ describe("Abilities - Parental Bond", () => { await game.phaseInterceptor.to("DamagePhase"); - expect(leadPokemon.turnData.hitCount).toBe(2); + expect(leadPokemon.turnData.hitCount).toBe(3); await game.phaseInterceptor.to("MoveEndPhase", false); @@ -494,30 +470,4 @@ describe("Abilities - Parental Bond", () => { expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(1); } ); - - it( - "should not apply to multi-target moves with Multi-Lens", - async () => { - game.override.battleType("double"); - game.override.moveset([ Moves.EARTHQUAKE, Moves.SPLASH ]); - game.override.passiveAbility(Abilities.LEVITATE); - game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - - await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); - - const enemyPokemon = game.scene.getEnemyField(); - - const enemyStartingHp = enemyPokemon.map(p => p.hp); - - game.move.select(Moves.EARTHQUAKE); - game.move.select(Moves.SPLASH, 1); - - await game.phaseInterceptor.to("DamagePhase"); - const enemyFirstHitDamage = enemyStartingHp.map((hp, i) => hp - enemyPokemon[i].hp); - - await game.phaseInterceptor.to("BerryPhase", false); - - enemyPokemon.forEach((p, i) => expect(enemyStartingHp[i] - p.hp).toBe(2 * enemyFirstHitDamage[i])); - } - ); }); diff --git a/src/test/abilities/sap_sipper.test.ts b/src/test/abilities/sap_sipper.test.ts index a4ce0c1b8f6..dc254a54b54 100644 --- a/src/test/abilities/sap_sipper.test.ts +++ b/src/test/abilities/sap_sipper.test.ts @@ -8,7 +8,8 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { allMoves, RandomMoveAttr } from "#app/data/move"; // See also: TypeImmunityAbAttr describe("Abilities - Sap Sipper", () => { @@ -27,20 +28,20 @@ describe("Abilities - Sap Sipper", () => { beforeEach(() => { game = new GameManager(phaserGame); - game.override.battleType("single"); - game.override.disableCrits(); + game.override.battleType("single") + .disableCrits() + .ability(Abilities.SAP_SIPPER) + .enemySpecies(Species.RATTATA) + .enemyAbility(Abilities.SAP_SIPPER) + .enemyMoveset(Moves.SPLASH); }); it("raises ATK stat stage by 1 and block effects when activated against a grass attack", async() => { const moveToUse = Moves.LEAFAGE; - const enemyAbility = Abilities.SAP_SIPPER; - game.override.moveset([ moveToUse ]); - game.override.enemyMoveset(Moves.SPLASH); - game.override.enemySpecies(Species.DUSKULL); - game.override.enemyAbility(enemyAbility); + game.override.moveset(moveToUse); - await game.startBattle(); + await game.classicMode.startBattle([ Species.BULBASAUR ]); const enemyPokemon = game.scene.getEnemyPokemon()!; const initialEnemyHp = enemyPokemon.hp; @@ -55,14 +56,10 @@ describe("Abilities - Sap Sipper", () => { it("raises ATK stat stage by 1 and block effects when activated against a grass status move", async() => { const moveToUse = Moves.SPORE; - const enemyAbility = Abilities.SAP_SIPPER; - game.override.moveset([ moveToUse ]); - game.override.enemyMoveset(Moves.SPLASH); - game.override.enemySpecies(Species.RATTATA); - game.override.enemyAbility(enemyAbility); + game.override.moveset(moveToUse); - await game.startBattle(); + await game.classicMode.startBattle([ Species.BULBASAUR ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -76,14 +73,10 @@ describe("Abilities - Sap Sipper", () => { it("do not activate against status moves that target the field", async () => { const moveToUse = Moves.GRASSY_TERRAIN; - const enemyAbility = Abilities.SAP_SIPPER; - game.override.moveset([ moveToUse ]); - game.override.enemyMoveset(Moves.SPLASH); - game.override.enemySpecies(Species.RATTATA); - game.override.enemyAbility(enemyAbility); + game.override.moveset(moveToUse); - await game.startBattle(); + await game.classicMode.startBattle([ Species.BULBASAUR ]); game.move.select(moveToUse); @@ -96,14 +89,10 @@ describe("Abilities - Sap Sipper", () => { it("activate once against multi-hit grass attacks", async () => { const moveToUse = Moves.BULLET_SEED; - const enemyAbility = Abilities.SAP_SIPPER; - game.override.moveset([ moveToUse ]); - game.override.enemyMoveset(Moves.SPLASH); - game.override.enemySpecies(Species.RATTATA); - game.override.enemyAbility(enemyAbility); + game.override.moveset(moveToUse); - await game.startBattle(); + await game.classicMode.startBattle([ Species.BULBASAUR ]); const enemyPokemon = game.scene.getEnemyPokemon()!; const initialEnemyHp = enemyPokemon.hp; @@ -118,15 +107,10 @@ describe("Abilities - Sap Sipper", () => { it("do not activate against status moves that target the user", async () => { const moveToUse = Moves.SPIKY_SHIELD; - const ability = Abilities.SAP_SIPPER; - game.override.moveset([ moveToUse ]); - game.override.ability(ability); - game.override.enemyMoveset(Moves.SPLASH); - game.override.enemySpecies(Species.RATTATA); - game.override.enemyAbility(Abilities.NONE); + game.override.moveset(moveToUse); - await game.startBattle(); + await game.classicMode.startBattle([ Species.BULBASAUR ]); const playerPokemon = game.scene.getPlayerPokemon()!; @@ -142,18 +126,15 @@ describe("Abilities - Sap Sipper", () => { expect(game.phaseInterceptor.log).not.toContain("ShowAbilityPhase"); }); - // TODO Add METRONOME outcome override - // To run this testcase, manually modify the METRONOME move to always give SAP_SIPPER, then uncomment - it.todo("activate once against multi-hit grass attacks (metronome)", async () => { + it("activate once against multi-hit grass attacks (metronome)", async () => { const moveToUse = Moves.METRONOME; - const enemyAbility = Abilities.SAP_SIPPER; - game.override.moveset([ moveToUse ]); - game.override.enemyMoveset([ Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE ]); - game.override.enemySpecies(Species.RATTATA); - game.override.enemyAbility(enemyAbility); + const randomMoveAttr = allMoves[Moves.METRONOME].findAttr(attr => attr instanceof RandomMoveAttr) as RandomMoveAttr; + vi.spyOn(randomMoveAttr, "getMoveOverride").mockReturnValue(Moves.BULLET_SEED); - await game.startBattle(); + game.override.moveset(moveToUse); + + await game.classicMode.startBattle([ Species.BULBASAUR ]); const enemyPokemon = game.scene.getEnemyPokemon()!; const initialEnemyHp = enemyPokemon.hp; @@ -168,11 +149,8 @@ describe("Abilities - Sap Sipper", () => { it("still activates regardless of accuracy check", async () => { game.override.moveset(Moves.LEAF_BLADE); - game.override.enemyMoveset(Moves.SPLASH); - game.override.enemySpecies(Species.MAGIKARP); - game.override.enemyAbility(Abilities.SAP_SIPPER); - await game.classicMode.startBattle(); + await game.classicMode.startBattle([ Species.BULBASAUR ]); const enemyPokemon = game.scene.getEnemyPokemon()!; diff --git a/src/test/abilities/unburden.test.ts b/src/test/abilities/unburden.test.ts index 7cd69f4a075..ba14c7fdcd0 100644 --- a/src/test/abilities/unburden.test.ts +++ b/src/test/abilities/unburden.test.ts @@ -1,18 +1,35 @@ +import { BattlerIndex } from "#app/battle"; +import { PostItemLostAbAttr } from "#app/data/ability"; +import { allMoves, StealHeldItemChanceAttr } from "#app/data/move"; +import Pokemon from "#app/field/pokemon"; +import type { ContactHeldItemTransferChanceModifier } from "#app/modifier/modifier"; import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { BerryType } from "#enums/berry-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { Stat } from "#enums/stat"; -import { BerryType } from "#app/enums/berry-type"; -import { allMoves, StealHeldItemChanceAttr } from "#app/data/move"; describe("Abilities - Unburden", () => { let phaserGame: Phaser.Game; let game: GameManager; + /** + * Count the number of held items a Pokemon has, accounting for stacks of multiple items. + */ + function getHeldItemCount(pokemon: Pokemon): number { + const stackCounts = pokemon.getHeldItems().map(m => m.getStackCount()); + if (stackCounts.length) { + return stackCounts.reduce((a, b) => a + b); + } else { + return 0; + } + } + beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, @@ -27,9 +44,9 @@ describe("Abilities - Unburden", () => { game = new GameManager(phaserGame); game.override .battleType("single") - .starterSpecies(Species.TREECKO) .startingLevel(1) - .moveset([ Moves.POPULATION_BOMB, Moves.KNOCK_OFF, Moves.PLUCK, Moves.THIEF ]) + .ability(Abilities.UNBURDEN) + .moveset([ Moves.SPLASH, Moves.KNOCK_OFF, Moves.PLUCK, Moves.FALSE_SWIPE ]) .startingHeldItems([ { name: "BERRY", count: 1, type: BerryType.SITRUS }, { name: "BERRY", count: 2, type: BerryType.APICOT }, @@ -37,209 +54,348 @@ describe("Abilities - Unburden", () => { ]) .enemySpecies(Species.NINJASK) .enemyLevel(100) - .enemyMoveset([ Moves.FALSE_SWIPE ]) + .enemyMoveset(Moves.SPLASH) .enemyAbility(Abilities.UNBURDEN) .enemyPassiveAbility(Abilities.NO_GUARD) .enemyHeldItems([ { name: "BERRY", type: BerryType.SITRUS, count: 1 }, { name: "BERRY", type: BerryType.LUM, count: 1 }, ]); + // For the various tests that use Thief, give it a 100% steal rate + vi.spyOn(allMoves[Moves.THIEF], "attrs", "get").mockReturnValue([ new StealHeldItemChanceAttr(1.0) ]); }); it("should activate when a berry is eaten", async () => { - await game.classicMode.startBattle(); + game.override.enemyMoveset(Moves.FALSE_SWIPE); + await game.classicMode.startBattle([ Species.TREECKO ]); const playerPokemon = game.scene.getPlayerPokemon()!; - playerPokemon.abilityIndex = 2; - const playerHeldItems = playerPokemon.getHeldItems().length; + const playerHeldItems = getHeldItemCount(playerPokemon); const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); - game.move.select(Moves.FALSE_SWIPE); + // Player gets hit by False Swipe and eats its own Sitrus Berry + game.move.select(Moves.SPLASH); await game.toNextTurn(); - expect(playerPokemon.getHeldItems().length).toBeLessThan(playerHeldItems); - expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialPlayerSpeed * 2); + expect(getHeldItemCount(playerPokemon)).toBeLessThan(playerHeldItems); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed * 2); }); - it("should activate when a berry is stolen", async () => { - await game.classicMode.startBattle(); + it("should activate when a berry is eaten, even if Berry Pouch preserves the berry", async () => { + game.override.enemyMoveset(Moves.FALSE_SWIPE) + .startingModifier([{ name: "BERRY_POUCH", count: 5850 }]); + await game.classicMode.startBattle([ Species.TREECKO ]); + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerHeldItems = getHeldItemCount(playerPokemon); + const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + + // Player gets hit by False Swipe and eats its own Sitrus Berry + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(getHeldItemCount(playerPokemon)).toBe(playerHeldItems); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed * 2); + }); + + it("should activate for the target, and not the stealer, when a berry is stolen", async () => { + await game.classicMode.startBattle([ Species.TREECKO ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); const enemyPokemon = game.scene.getEnemyPokemon()!; - const enemyHeldItemCt = enemyPokemon.getHeldItems().length; + const enemyHeldItemCt = getHeldItemCount(enemyPokemon); const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + // Player uses Pluck and eats the opponent's berry game.move.select(Moves.PLUCK); await game.toNextTurn(); - expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); - expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); + expect(getHeldItemCount(enemyPokemon)).toBeLessThan(enemyHeldItemCt); + expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBe(initialEnemySpeed * 2); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed); }); it("should activate when an item is knocked off", async () => { - await game.classicMode.startBattle(); + await game.classicMode.startBattle([ Species.TREECKO ]); const enemyPokemon = game.scene.getEnemyPokemon()!; - const enemyHeldItemCt = enemyPokemon.getHeldItems().length; + const enemyHeldItemCt = getHeldItemCount(enemyPokemon); const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + // Player uses Knock Off and removes the opponent's item game.move.select(Moves.KNOCK_OFF); await game.toNextTurn(); - expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); - expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); + expect(getHeldItemCount(enemyPokemon)).toBeLessThan(enemyHeldItemCt); + expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBe(initialEnemySpeed * 2); }); it("should activate when an item is stolen via attacking ability", async () => { game.override .ability(Abilities.MAGICIAN) - .startingHeldItems([ - { name: "MULTI_LENS", count: 3 }, - ]); - await game.classicMode.startBattle(); + .startingHeldItems([]); // Remove player's full stacks of held items so it can steal opponent's held items + await game.classicMode.startBattle([ Species.TREECKO ]); const enemyPokemon = game.scene.getEnemyPokemon()!; - const enemyHeldItemCt = enemyPokemon.getHeldItems().length; + const enemyHeldItemCt = getHeldItemCount(enemyPokemon); const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); - game.move.select(Moves.POPULATION_BOMB); + // Player steals the opponent's item via ability Magician + game.move.select(Moves.FALSE_SWIPE); await game.toNextTurn(); - expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); - expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); + expect(getHeldItemCount(enemyPokemon)).toBeLessThan(enemyHeldItemCt); + expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBe(initialEnemySpeed * 2); }); it("should activate when an item is stolen via defending ability", async () => { game.override - .startingLevel(45) .enemyAbility(Abilities.PICKPOCKET) - .startingHeldItems([ - { name: "MULTI_LENS", count: 3 }, - { name: "SOUL_DEW", count: 1 }, - { name: "LUCKY_EGG", count: 1 }, - ]); - await game.classicMode.startBattle(); + .enemyHeldItems([]); // Remove opponent's full stacks of held items so it can steal player's held items + await game.classicMode.startBattle([ Species.TREECKO ]); const playerPokemon = game.scene.getPlayerPokemon()!; - playerPokemon.abilityIndex = 2; - const playerHeldItems = playerPokemon.getHeldItems().length; + const playerHeldItems = getHeldItemCount(playerPokemon); const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); - game.move.select(Moves.POPULATION_BOMB); + // Player's item gets stolen via ability Pickpocket + game.move.select(Moves.FALSE_SWIPE); await game.toNextTurn(); - expect(playerPokemon.getHeldItems().length).toBeLessThan(playerHeldItems); - expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialPlayerSpeed * 2); + expect(getHeldItemCount(playerPokemon)).toBeLessThan(playerHeldItems); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed * 2); }); it("should activate when an item is stolen via move", async () => { - vi.spyOn(allMoves[Moves.THIEF], "attrs", "get").mockReturnValue([ new StealHeldItemChanceAttr(1.0) ]); // give Thief 100% steal rate - game.override.startingHeldItems([ - { name: "MULTI_LENS", count: 3 }, - ]); - await game.classicMode.startBattle(); + game.override.moveset(Moves.THIEF) + .startingHeldItems([]); // Remove player's full stacks of held items so it can steal opponent's held items + await game.classicMode.startBattle([ Species.TREECKO ]); const enemyPokemon = game.scene.getEnemyPokemon()!; - const enemyHeldItemCt = enemyPokemon.getHeldItems().length; + const enemyHeldItemCt = getHeldItemCount(enemyPokemon); const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + // Player uses Thief and steals the opponent's item game.move.select(Moves.THIEF); await game.toNextTurn(); - expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); - expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); + expect(getHeldItemCount(enemyPokemon)).toBeLessThan(enemyHeldItemCt); + expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBe(initialEnemySpeed * 2); }); it("should activate when an item is stolen via grip claw", async () => { game.override - .startingLevel(5) .startingHeldItems([ - { name: "GRIP_CLAW", count: 5 }, - { name: "MULTI_LENS", count: 3 }, - ]) - .enemyHeldItems([ - { name: "SOUL_DEW", count: 1 }, - { name: "LUCKY_EGG", count: 1 }, - { name: "LEFTOVERS", count: 1 }, { name: "GRIP_CLAW", count: 1 }, - { name: "MULTI_LENS", count: 1 }, - { name: "BERRY", type: BerryType.SITRUS, count: 1 }, - { name: "BERRY", type: BerryType.LUM, count: 1 }, ]); - await game.classicMode.startBattle(); - - const enemyPokemon = game.scene.getEnemyPokemon()!; - const enemyHeldItemCt = enemyPokemon.getHeldItems().length; - const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); - - while (enemyPokemon.getHeldItems().length === enemyHeldItemCt) { - game.move.select(Moves.POPULATION_BOMB); - await game.toNextTurn(); - } - - expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); - expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); - }); - - it("should not activate when a neutralizing ability is present", async () => { - game.override.enemyAbility(Abilities.NEUTRALIZING_GAS); - await game.classicMode.startBattle(); + await game.classicMode.startBattle([ Species.TREECKO ]); const playerPokemon = game.scene.getPlayerPokemon()!; - const playerHeldItems = playerPokemon.getHeldItems().length; - const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier; + vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100); + const enemyPokemon = game.scene.getEnemyPokemon()!; + const enemyHeldItemCt = getHeldItemCount(enemyPokemon); + const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + + // Player steals the opponent's item using Grip Claw game.move.select(Moves.FALSE_SWIPE); await game.toNextTurn(); - expect(playerPokemon.getHeldItems().length).toBeLessThan(playerHeldItems); - expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialPlayerSpeed); + expect(getHeldItemCount(enemyPokemon)).toBeLessThan(enemyHeldItemCt); + expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBe(initialEnemySpeed * 2); + }); + + it("should not activate when a neutralizing ability is present", async () => { + game.override.enemyAbility(Abilities.NEUTRALIZING_GAS) + .enemyMoveset(Moves.FALSE_SWIPE); + await game.classicMode.startBattle([ Species.TREECKO ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerHeldItems = getHeldItemCount(playerPokemon); + const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + + // Player gets hit by False Swipe and eats Sitrus Berry, which should not trigger Unburden + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(getHeldItemCount(playerPokemon)).toBeLessThan(playerHeldItems); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed); + expect(playerPokemon.getTag(BattlerTagType.UNBURDEN)).toBeUndefined(); }); it("should activate when a move that consumes a berry is used", async () => { - game.override.enemyMoveset([ Moves.STUFF_CHEEKS ]); - await game.classicMode.startBattle(); + game.override.moveset(Moves.STUFF_CHEEKS); + await game.classicMode.startBattle([ Species.TREECKO ]); - const enemyPokemon = game.scene.getEnemyPokemon()!; - const enemyHeldItemCt = enemyPokemon.getHeldItems().length; - const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD); + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerHeldItemCt = getHeldItemCount(playerPokemon); + const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + // Player uses Stuff Cheeks and eats its own berry + // Caution: Do not test this using opponent, there is a known issue where opponent can randomly generate with Salac Berry game.move.select(Moves.STUFF_CHEEKS); await game.toNextTurn(); - expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt); - expect(enemyPokemon.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialEnemySpeed * 2); + expect(getHeldItemCount(playerPokemon)).toBeLessThan(playerHeldItemCt); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed * 2); }); - it("should deactivate when a neutralizing gas user enters the field", async () => { + it("should deactivate temporarily when a neutralizing gas user is on the field", async () => { game.override .battleType("double") - .moveset([ Moves.SPLASH ]); + .ability(Abilities.NONE); // Disable ability override so that we can properly set abilities below await game.classicMode.startBattle([ Species.TREECKO, Species.MEOWTH, Species.WEEZING ]); - const playerPokemon = game.scene.getPlayerParty(); - const treecko = playerPokemon[0]; - const weezing = playerPokemon[2]; - treecko.abilityIndex = 2; - weezing.abilityIndex = 1; - const playerHeldItems = treecko.getHeldItems().length; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [ treecko, _meowth, weezing ] = game.scene.getPlayerParty(); + treecko.abilityIndex = 2; // Treecko has Unburden + weezing.abilityIndex = 1; // Weezing has Neutralizing Gas + const playerHeldItems = getHeldItemCount(treecko); const initialPlayerSpeed = treecko.getStat(Stat.SPD); + // Turn 1: Treecko gets hit by False Swipe and eats Sitrus Berry, activating Unburden game.move.select(Moves.SPLASH); - game.move.select(Moves.SPLASH); + game.move.select(Moves.SPLASH, 1); await game.forceEnemyMove(Moves.FALSE_SWIPE, 0); await game.forceEnemyMove(Moves.FALSE_SWIPE, 0); await game.phaseInterceptor.to("TurnEndPhase"); - expect(treecko.getHeldItems().length).toBeLessThan(playerHeldItems); - expect(treecko.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialPlayerSpeed * 2); + expect(getHeldItemCount(treecko)).toBeLessThan(playerHeldItems); + expect(treecko.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed * 2); + // Turn 2: Switch Meowth to Weezing, activating Neutralizing Gas await game.toNextTurn(); game.move.select(Moves.SPLASH); game.doSwitchPokemon(2); await game.phaseInterceptor.to("TurnEndPhase"); - expect(treecko.getHeldItems().length).toBeLessThan(playerHeldItems); - expect(treecko.getEffectiveStat(Stat.SPD)).toBeCloseTo(initialPlayerSpeed); + expect(getHeldItemCount(treecko)).toBeLessThan(playerHeldItems); + expect(treecko.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed); + + // Turn 3: Switch Weezing to Meowth, deactivating Neutralizing Gas + await game.toNextTurn(); + game.move.select(Moves.SPLASH); + game.doSwitchPokemon(2); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(getHeldItemCount(treecko)).toBeLessThan(playerHeldItems); + expect(treecko.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed * 2); }); + it("should not activate when passing a baton to a teammate switching in", async () => { + game.override.startingHeldItems([{ name: "BATON" }]) + .moveset(Moves.BATON_PASS); + await game.classicMode.startBattle([ Species.TREECKO, Species.PURRLOIN ]); + + const [ treecko, purrloin ] = game.scene.getPlayerParty(); + const initialTreeckoSpeed = treecko.getStat(Stat.SPD); + const initialPurrloinSpeed = purrloin.getStat(Stat.SPD); + const unburdenAttr = treecko.getAbilityAttrs(PostItemLostAbAttr)[0]; + vi.spyOn(unburdenAttr, "applyPostItemLost"); + + // Player uses Baton Pass, which also passes the Baton item + game.move.select(Moves.BATON_PASS); + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + + expect(getHeldItemCount(treecko)).toBe(0); + expect(getHeldItemCount(purrloin)).toBe(1); + expect(treecko.getEffectiveStat(Stat.SPD)).toBe(initialTreeckoSpeed); + expect(purrloin.getEffectiveStat(Stat.SPD)).toBe(initialPurrloinSpeed); + expect(unburdenAttr.applyPostItemLost).not.toHaveBeenCalled(); + }); + + it("should not speed up a Pokemon after it loses the ability Unburden", async () => { + game.override.enemyMoveset([ Moves.FALSE_SWIPE, Moves.WORRY_SEED ]); + await game.classicMode.startBattle([ Species.PURRLOIN ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerHeldItems = getHeldItemCount(playerPokemon); + const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + + // Turn 1: Get hit by False Swipe and eat Sitrus Berry, activating Unburden + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.FALSE_SWIPE); + await game.toNextTurn(); + + expect(getHeldItemCount(playerPokemon)).toBeLessThan(playerHeldItems); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed * 2); + + // Turn 2: Get hit by Worry Seed, deactivating Unburden + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.WORRY_SEED); + await game.toNextTurn(); + + expect(getHeldItemCount(playerPokemon)).toBeLessThan(playerHeldItems); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed); + }); + + it("should activate when a reviver seed is used", async () => { + game.override.startingHeldItems([{ name: "REVIVER_SEED" }]) + .enemyMoveset([ Moves.WING_ATTACK ]); + await game.classicMode.startBattle([ Species.TREECKO ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerHeldItems = getHeldItemCount(playerPokemon); + const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD); + + // Turn 1: Get hit by Wing Attack and faint, activating Reviver Seed + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + expect(getHeldItemCount(playerPokemon)).toBeLessThan(playerHeldItems); + expect(playerPokemon.getEffectiveStat(Stat.SPD)).toBe(initialPlayerSpeed * 2); + }); + + // test for `.bypassFaint()` - singles + it("shouldn't persist when revived normally if activated while fainting", async () => { + game.override.enemyMoveset([ Moves.SPLASH, Moves.THIEF ]); + await game.classicMode.startBattle([ Species.TREECKO, Species.FEEBAS ]); + + const treecko = game.scene.getPlayerPokemon()!; + const treeckoInitialHeldItems = getHeldItemCount(treecko); + const initialSpeed = treecko.getStat(Stat.SPD); + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.THIEF); + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + + game.doRevivePokemon(1); + game.doSwitchPokemon(1); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + expect(game.scene.getPlayerPokemon()!).toBe(treecko); + expect(getHeldItemCount(treecko)).toBeLessThan(treeckoInitialHeldItems); + expect(treecko.getEffectiveStat(Stat.SPD)).toBe(initialSpeed); + }); + + // test for `.bypassFaint()` - doubles + it("shouldn't persist when revived by revival blessing if activated while fainting", async () => { + game.override + .battleType("double") + .enemyMoveset([ Moves.SPLASH, Moves.THIEF ]) + .moveset([ Moves.SPLASH, Moves.REVIVAL_BLESSING ]) + .startingHeldItems([{ name: "WIDE_LENS" }]); + await game.classicMode.startBattle([ Species.TREECKO, Species.FEEBAS, Species.MILOTIC ]); + + const treecko = game.scene.getPlayerField()[0]; + const treeckoInitialHeldItems = getHeldItemCount(treecko); + const initialSpeed = treecko.getStat(Stat.SPD); + + game.move.select(Moves.SPLASH); + game.move.select(Moves.REVIVAL_BLESSING, 1); + await game.forceEnemyMove(Moves.THIEF, BattlerIndex.PLAYER); + await game.forceEnemyMove(Moves.SPLASH); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2 ]); + game.doSelectPartyPokemon(0, "MoveEffectPhase"); + await game.toNextTurn(); + + expect(game.scene.getPlayerField()[0]).toBe(treecko); + expect(getHeldItemCount(treecko)).toBeLessThan(treeckoInitialHeldItems); + expect(treecko.getEffectiveStat(Stat.SPD)).toBe(initialSpeed); + }); }); diff --git a/src/test/abilities/wimp_out.test.ts b/src/test/abilities/wimp_out.test.ts index 6f56a2f4e7e..4283386b248 100644 --- a/src/test/abilities/wimp_out.test.ts +++ b/src/test/abilities/wimp_out.test.ts @@ -296,7 +296,9 @@ describe("Abilities - Wimp Out", () => { Species.TYRUNT ]); - game.move.select(Moves.SPLASH); + game.scene.getPlayerPokemon()!.hp *= 0.51; + + game.move.select(Moves.ENDURE); await game.phaseInterceptor.to("TurnEndPhase"); confirmNoSwitch(); @@ -611,4 +613,23 @@ describe("Abilities - Wimp Out", () => { confirmNoSwitch(); }); + + it("should not activate on wave X0 bosses", async () => { + game.override.enemyAbility(Abilities.WIMP_OUT) + .startingLevel(5850) + .startingWave(10); + await game.classicMode.startBattle([ Species.GOLISOPOD ]); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + + // Use 2 turns of False Swipe due to opponent's health bar shield + game.move.select(Moves.FALSE_SWIPE); + await game.toNextTurn(); + game.move.select(Moves.FALSE_SWIPE); + await game.toNextTurn(); + + const isVisible = enemyPokemon.visible; + const hasFled = enemyPokemon.switchOutStatus; + expect(isVisible && !hasFled).toBe(true); + }); }); diff --git a/src/test/abilities/zen_mode.test.ts b/src/test/abilities/zen_mode.test.ts index 4ba5e3d5929..e0cc457c4d5 100644 --- a/src/test/abilities/zen_mode.test.ts +++ b/src/test/abilities/zen_mode.test.ts @@ -1,14 +1,8 @@ -import { BattlerIndex } from "#app/battle"; import { Status } from "#app/data/status-effect"; -import { DamagePhase } from "#app/phases/damage-phase"; -import { SwitchSummonPhase } from "#app/phases/switch-summon-phase"; -import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { Stat } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; -import { SwitchType } from "#enums/switch-type"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -34,78 +28,60 @@ describe("Abilities - ZEN MODE", () => { game = new GameManager(phaserGame); game.override .battleType("single") - .enemySpecies(Species.RATTATA) - .enemyAbility(Abilities.HYDRATION) + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyLevel(5) .ability(Abilities.ZEN_MODE) - .startingLevel(100) .moveset(Moves.SPLASH) - .enemyMoveset(Moves.TACKLE); + .enemyMoveset(Moves.SEISMIC_TOSS); }); it("shouldn't change form when taking damage if not dropping below 50% HP", async () => { await game.classicMode.startBattle([ Species.DARMANITAN ]); - const player = game.scene.getPlayerPokemon()!; - player.stats[Stat.HP] = 100; - player.hp = 100; - expect(player.formIndex).toBe(baseForm); + const darmanitan = game.scene.getPlayerPokemon()!; + expect(darmanitan.formIndex).toBe(baseForm); game.move.select(Moves.SPLASH); - await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); - await game.phaseInterceptor.to("BerryPhase"); + await game.toNextTurn(); - expect(player.hp).toBeLessThan(100); - expect(player.formIndex).toBe(baseForm); + expect(darmanitan.getHpRatio()).toBeLessThan(1); + expect(darmanitan.getHpRatio()).toBeGreaterThan(0.5); + expect(darmanitan.formIndex).toBe(baseForm); }); it("should change form when falling below 50% HP", async () => { await game.classicMode.startBattle([ Species.DARMANITAN ]); - const player = game.scene.getPlayerPokemon()!; - player.stats[Stat.HP] = 1000; - player.hp = 100; - expect(player.formIndex).toBe(baseForm); + const darmanitan = game.scene.getPlayerPokemon()!; + darmanitan.hp = (darmanitan.getMaxHp() / 2) + 1; + expect(darmanitan.formIndex).toBe(baseForm); game.move.select(Moves.SPLASH); + await game.toNextTurn(); - await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); - await game.phaseInterceptor.to("QuietFormChangePhase"); - await game.phaseInterceptor.to("TurnInitPhase", false); - - expect(player.hp).not.toBe(100); - expect(player.formIndex).toBe(zenForm); + expect(darmanitan.getHpRatio()).toBeLessThan(0.5); + expect(darmanitan.formIndex).toBe(zenForm); }); it("should stay zen mode when fainted", async () => { await game.classicMode.startBattle([ Species.DARMANITAN, Species.CHARIZARD ]); - const player = game.scene.getPlayerPokemon()!; - player.stats[Stat.HP] = 1000; - player.hp = 100; - expect(player.formIndex).toBe(baseForm); + const darmanitan = game.scene.getPlayerPokemon()!; + darmanitan.hp = (darmanitan.getMaxHp() / 2) + 1; + expect(darmanitan.formIndex).toBe(baseForm); game.move.select(Moves.SPLASH); + await game.toNextTurn(); - await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); - await game.phaseInterceptor.to(DamagePhase, false); - const damagePhase = game.scene.getCurrentPhase() as DamagePhase; - damagePhase.updateAmount(80); - await game.phaseInterceptor.to("QuietFormChangePhase"); + expect(darmanitan.getHpRatio()).toBeLessThan(0.5); + expect(darmanitan.formIndex).toBe(zenForm); - expect(player.hp).not.toBe(100); - expect(player.formIndex).toBe(zenForm); - - await game.killPokemon(player); - expect(player.isFainted()).toBe(true); - - await game.phaseInterceptor.to("TurnStartPhase"); - game.onNextPrompt("SwitchPhase", Mode.PARTY, () => { - game.scene.unshiftPhase(new SwitchSummonPhase(game.scene, SwitchType.SWITCH, 0, 1, false)); - game.scene.ui.setMode(Mode.MESSAGE); - }); - game.onNextPrompt("SwitchPhase", Mode.MESSAGE, () => { - game.endPhase(); - }); - await game.phaseInterceptor.to("PostSummonPhase"); + game.move.select(Moves.SPLASH); + await game.killPokemon(darmanitan); + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + expect(darmanitan.isFainted()).toBe(true); expect(game.scene.getPlayerParty()[1].formIndex).toBe(zenForm); }); @@ -117,7 +93,8 @@ describe("Abilities - ZEN MODE", () => { await game.classicMode.startBattle([ Species.MAGIKARP, Species.DARMANITAN ]); - const darmanitan = game.scene.getPlayerParty().find((p) => p.species.speciesId === Species.DARMANITAN)!; + const darmanitan = game.scene.getPlayerParty()[1]; + darmanitan.hp = 1; expect(darmanitan.formIndex).toBe(zenForm); darmanitan.hp = 0; @@ -126,9 +103,7 @@ describe("Abilities - ZEN MODE", () => { game.move.select(Moves.SPLASH); await game.doKillOpponents(); - await game.phaseInterceptor.to("TurnEndPhase"); - game.doSelectModifier(); - await game.phaseInterceptor.to("QuietFormChangePhase"); + await game.toNextWave(); expect(darmanitan.formIndex).toBe(baseForm); }); diff --git a/src/test/battle/double_battle.test.ts b/src/test/battle/double_battle.test.ts index 1fc24bfc027..b48f2a96a5b 100644 --- a/src/test/battle/double_battle.test.ts +++ b/src/test/battle/double_battle.test.ts @@ -1,4 +1,6 @@ import { Status } from "#app/data/status-effect"; +import { Abilities } from "#enums/abilities"; +import { GameModes, getGameMode } from "#app/game-mode"; import { BattleEndPhase } from "#app/phases/battle-end-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase"; import { Moves } from "#enums/moves"; @@ -6,9 +8,11 @@ import { Species } from "#enums/species"; import { StatusEffect } from "#enums/status-effect"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Double Battles", () => { + const DOUBLE_CHANCE = 8; // Normal chance of double battle is 1/8 + let phaserGame: Phaser.Game; let game: GameManager; @@ -56,4 +60,40 @@ describe("Double Battles", () => { await game.phaseInterceptor.to(TurnInitPhase); expect(game.scene.getPlayerField().filter(p => !p.isFainted())).toHaveLength(2); }, 20000); + + it("randomly chooses between single and double battles if there is no battle type override", async () => { + let rngSweepProgress = 0; // Will simulate RNG rolls by slowly increasing from 0 to 1 + let doubleCount = 0; + let singleCount = 0; + + vi.spyOn(Phaser.Math.RND, "realInRange").mockImplementation((min: number, max: number) => { + return rngSweepProgress * (max - min) + min; + }); + + game.override.enemyMoveset(Moves.SPLASH) + .moveset(Moves.SPLASH) + .enemyAbility(Abilities.BALL_FETCH) + .ability(Abilities.BALL_FETCH); + + // Play through endless, waves 1 to 9, counting number of double battles from waves 2 to 9 + await game.classicMode.startBattle([ Species.BULBASAUR ]); + game.scene.gameMode = getGameMode(GameModes.ENDLESS); + + for (let i = 0; i < DOUBLE_CHANCE; i++) { + rngSweepProgress = (i + 0.5) / DOUBLE_CHANCE; + + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.toNextWave(); + + if (game.scene.getEnemyParty().length === 1) { + singleCount++; + } else if (game.scene.getEnemyParty().length === 2) { + doubleCount++; + } + } + + expect(doubleCount).toBe(1); + expect(singleCount).toBe(DOUBLE_CHANCE - 1); + }); }); diff --git a/src/test/items/multi_lens.test.ts b/src/test/items/multi_lens.test.ts new file mode 100644 index 00000000000..c5e60c9f9e5 --- /dev/null +++ b/src/test/items/multi_lens.test.ts @@ -0,0 +1,138 @@ +import { BattlerIndex } from "#app/battle"; +import { Stat } from "#enums/stat"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Items - Multi Lens", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.TACKLE, Moves.TRAILBLAZE, Moves.TACHYON_CUTTER ]) + .ability(Abilities.BALL_FETCH) + .startingHeldItems([{ name: "MULTI_LENS" }]) + .battleType("single") + .disableCrits() + .enemySpecies(Species.SNORLAX) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .startingLevel(99) // Check for proper rounding on Seismic Toss damage reduction + .enemyLevel(99); + }); + + it.each([ + { stackCount: 1, firstHitDamage: 0.75 }, + { stackCount: 2, firstHitDamage: 0.50 } + ])("$stackCount count: should deal {$firstHitDamage}x damage on the first hit, then hit $stackCount times for 0.25x", + async ({ stackCount, firstHitDamage }) => { + game.override.startingHeldItems([{ name: "MULTI_LENS", count: stackCount }]); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + const spy = vi.spyOn(enemyPokemon, "getAttackDamage"); + vi.spyOn(enemyPokemon, "getBaseDamage").mockReturnValue(100); + + game.move.select(Moves.TACKLE); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to("MoveEndPhase"); + const damageResults = spy.mock.results.map(result => result.value?.damage); + + expect(damageResults).toHaveLength(1 + stackCount); + expect(damageResults[0]).toBe(firstHitDamage * 100); + damageResults.slice(1).forEach(dmg => expect(dmg).toBe(25)); + }); + + it("should stack additively with Parental Bond", async () => { + game.override.ability(Abilities.PARENTAL_BOND); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.TACKLE); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to("MoveEndPhase"); + expect(playerPokemon.turnData.hitCount).toBe(3); + }); + + it("should apply secondary effects on each hit", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.TRAILBLAZE); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(playerPokemon.getStatStage(Stat.SPD)).toBe(2); + }); + + it("should not enhance multi-hit moves", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.TACHYON_CUTTER); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(playerPokemon.turnData.hitCount).toBe(2); + }); + + it("should enhance multi-target moves", async () => { + game.override + .battleType("double") + .moveset([ Moves.SWIFT, Moves.SPLASH ]); + + await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]); + + const [ magikarp, ] = game.scene.getPlayerField(); + + game.move.select(Moves.SWIFT, 0); + game.move.select(Moves.SPLASH, 1); + + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to("MoveEndPhase"); + + expect(magikarp.turnData.hitCount).toBe(2); + }); + + it("should enhance fixed-damage moves while also applying damage reduction", async () => { + game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]) + .moveset(Moves.SEISMIC_TOSS); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + const spy = vi.spyOn(enemyPokemon, "getAttackDamage"); + + game.move.select(Moves.SEISMIC_TOSS); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to("MoveEndPhase"); + const damageResults = spy.mock.results.map(result => result.value?.damage); + + expect(damageResults).toHaveLength(2); + expect(damageResults[0]).toBe(Math.floor(playerPokemon.level * 0.75)); + expect(damageResults[1]).toBe(Math.floor(playerPokemon.level * 0.25)); + }); +}); diff --git a/src/test/moves/beat_up.test.ts b/src/test/moves/beat_up.test.ts index a0129621f0e..41e5b63471f 100644 --- a/src/test/moves/beat_up.test.ts +++ b/src/test/moves/beat_up.test.ts @@ -74,29 +74,4 @@ describe("Moves - Beat Up", () => { expect(playerPokemon.turnData.hitCount).toBe(5); } ); - - it( - "should hit twice for each player Pokemon if the user has Multi-Lens", - async () => { - game.override.startingHeldItems([{ name: "MULTI_LENS", count: 1 }]); - await game.startBattle([ Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE ]); - - const playerPokemon = game.scene.getPlayerPokemon()!; - const enemyPokemon = game.scene.getEnemyPokemon()!; - let enemyStartingHp = enemyPokemon.hp; - - game.move.select(Moves.BEAT_UP); - - await game.phaseInterceptor.to(MoveEffectPhase); - - expect(playerPokemon.turnData.hitCount).toBe(12); - expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); - - while (playerPokemon.turnData.hitsLeft > 0) { - enemyStartingHp = enemyPokemon.hp; - await game.phaseInterceptor.to(MoveEffectPhase); - expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); - } - } - ); }); diff --git a/src/test/moves/ceaseless_edge.test.ts b/src/test/moves/ceaseless_edge.test.ts index 88c8c8cf011..3fbbb7b0aaf 100644 --- a/src/test/moves/ceaseless_edge.test.ts +++ b/src/test/moves/ceaseless_edge.test.ts @@ -34,7 +34,7 @@ describe("Moves - Ceaseless Edge", () => { game.override.startingLevel(100); game.override.enemyLevel(100); game.override.moveset([ Moves.CEASELESS_EDGE, Moves.SPLASH, Moves.ROAR ]); - game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); + game.override.enemyMoveset(Moves.SPLASH); vi.spyOn(allMoves[Moves.CEASELESS_EDGE], "accuracy", "get").mockReturnValue(100); }); @@ -42,7 +42,7 @@ describe("Moves - Ceaseless Edge", () => { test( "move should hit and apply spikes", async () => { - await game.startBattle([ Species.ILLUMISE ]); + await game.classicMode.startBattle([ Species.ILLUMISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -67,7 +67,7 @@ describe("Moves - Ceaseless Edge", () => { "move should hit twice with multi lens and apply two layers of spikes", async () => { game.override.startingHeldItems([{ name: "MULTI_LENS" }]); - await game.startBattle([ Species.ILLUMISE ]); + await game.classicMode.startBattle([ Species.ILLUMISE ]); const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -92,9 +92,9 @@ describe("Moves - Ceaseless Edge", () => { "trainer - move should hit twice, apply two layers of spikes, force switch opponent - opponent takes damage", async () => { game.override.startingHeldItems([{ name: "MULTI_LENS" }]); - game.override.startingWave(5); + game.override.startingWave(25); - await game.startBattle([ Species.ILLUMISE ]); + await game.classicMode.startBattle([ Species.ILLUMISE ]); game.move.select(Moves.CEASELESS_EDGE); await game.phaseInterceptor.to(MoveEffectPhase, false); @@ -102,7 +102,7 @@ describe("Moves - Ceaseless Edge", () => { const tagBefore = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; expect(tagBefore instanceof ArenaTrapTag).toBeFalsy(); - await game.phaseInterceptor.to(TurnEndPhase, false); + await game.toNextTurn(); const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; expect(tagAfter instanceof ArenaTrapTag).toBeTruthy(); expect(tagAfter.layers).toBe(2); diff --git a/src/test/moves/dragon_rage.test.ts b/src/test/moves/dragon_rage.test.ts index e8185f013e5..d5536ff9d2f 100644 --- a/src/test/moves/dragon_rage.test.ts +++ b/src/test/moves/dragon_rage.test.ts @@ -2,7 +2,6 @@ import { Stat } from "#enums/stat"; import { Type } from "#enums/type"; import { Species } from "#app/enums/species"; import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; -import { modifierTypes } from "#app/modifier/modifier-type"; import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; @@ -114,14 +113,4 @@ describe("Moves - Dragon Rage", () => { expect(enemyPokemon.getInverseHp()).toBe(dragonRageDamage); }); - - it("ignores multi hit", async () => { - game.override.disableCrits(); - game.scene.addModifier(modifierTypes.MULTI_LENS().newModifier(partyPokemon), false); - - game.move.select(Moves.DRAGON_RAGE); - await game.phaseInterceptor.to(TurnEndPhase); - - expect(enemyPokemon.getInverseHp()).toBe(dragonRageDamage); - }); }); diff --git a/src/test/moves/electro_shot.test.ts b/src/test/moves/electro_shot.test.ts index 1373b4941eb..283154b3408 100644 --- a/src/test/moves/electro_shot.test.ts +++ b/src/test/moves/electro_shot.test.ts @@ -98,7 +98,7 @@ describe("Moves - Electro Shot", () => { game.move.select(Moves.ELECTRO_SHOT); await game.phaseInterceptor.to("MoveEndPhase"); - expect(playerPokemon.turnData.hitCount).toBe(2); + expect(playerPokemon.turnData.hitCount).toBe(1); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(1); }); }); diff --git a/src/test/moves/endure.test.ts b/src/test/moves/endure.test.ts new file mode 100644 index 00000000000..bde5a26f68e --- /dev/null +++ b/src/test/moves/endure.test.ts @@ -0,0 +1,65 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Endure", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.THUNDER, Moves.BULLET_SEED, Moves.TOXIC ]) + .ability(Abilities.SKILL_LINK) + .startingLevel(100) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.NO_GUARD) + .enemyMoveset(Moves.ENDURE); + }); + + it("should let the pokemon survive with 1 HP", async () => { + await game.classicMode.startBattle([ Species.ARCEUS ]); + + game.move.select(Moves.THUNDER); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.getEnemyPokemon()!.hp).toBe(1); + }); + + it("should let the pokemon survive with 1 HP when hit with a multihit move", async () => { + await game.classicMode.startBattle([ Species.ARCEUS ]); + + game.move.select(Moves.BULLET_SEED); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.getEnemyPokemon()!.hp).toBe(1); + }); + + it("shouldn't prevent fainting from indirect damage", async () => { + game.override.enemyLevel(100); + await game.classicMode.startBattle([ Species.ARCEUS ]); + + const enemy = game.scene.getEnemyPokemon()!; + enemy.hp = 2; + + game.move.select(Moves.TOXIC); + await game.phaseInterceptor.to("VictoryPhase"); + + expect(enemy.isFainted()).toBe(true); + }); +}); diff --git a/src/test/moves/freeze_dry.test.ts b/src/test/moves/freeze_dry.test.ts index f766ed41a82..9206a103a35 100644 --- a/src/test/moves/freeze_dry.test.ts +++ b/src/test/moves/freeze_dry.test.ts @@ -2,6 +2,8 @@ import { BattlerIndex } from "#app/battle"; import { Abilities } from "#app/enums/abilities"; import { Moves } from "#app/enums/moves"; import { Species } from "#app/enums/species"; +import { Type } from "#enums/type"; +import { Challenges } from "#enums/challenges"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -28,7 +30,7 @@ describe("Moves - Freeze-Dry", () => { .enemyMoveset(Moves.SPLASH) .starterSpecies(Species.FEEBAS) .ability(Abilities.BALL_FETCH) - .moveset([ Moves.FREEZE_DRY ]); + .moveset([ Moves.FREEZE_DRY, Moves.FORESTS_CURSE, Moves.SOAK ]); }); it("should deal 2x damage to pure water types", async () => { @@ -97,8 +99,72 @@ describe("Moves - Freeze-Dry", () => { expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); }); - // enable if this is ever fixed (lol) - it.todo("should deal 2x damage to water types under Normalize", async () => { + it("should deal 8x damage to water/ground/grass type under Forest's Curse", async () => { + game.override.enemySpecies(Species.QUAGSIRE); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FORESTS_CURSE); + await game.toNextTurn(); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(8); + }); + + it("should deal 2x damage to steel type terastallized into water", async () => { + game.override.enemySpecies(Species.SKARMORY) + .enemyHeldItems([{ name: "TERA_SHARD", type: Type.WATER }]); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); + }); + + it("should deal 0.5x damage to water type terastallized into fire", async () => { + game.override.enemySpecies(Species.PELIPPER) + .enemyHeldItems([{ name: "TERA_SHARD", type: Type.FIRE }]); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(0.5); + }); + + it("should deal 0.5x damage to water type Terapagos with Tera Shell", async () => { + game.override.enemySpecies(Species.TERAPAGOS) + .enemyAbility(Abilities.TERA_SHELL); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.SOAK); + await game.toNextTurn(); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(0.5); + }); + + it("should deal 2x damage to water type under Normalize", async () => { game.override.ability(Abilities.NORMALIZE); await game.classicMode.startBattle(); @@ -112,8 +178,39 @@ describe("Moves - Freeze-Dry", () => { expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); }); - // enable once Electrify is implemented (and the interaction is fixed, as above) - it.todo("should deal 2x damage to water types under Electrify", async () => { + it("should deal 0.25x damage to rock/steel type under Normalize", async () => { + game.override + .ability(Abilities.NORMALIZE) + .enemySpecies(Species.SHIELDON); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(0.25); + }); + + it("should deal 0x damage to water/ghost type under Normalize", async () => { + game.override + .ability(Abilities.NORMALIZE) + .enemySpecies(Species.JELLICENT); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(0); + }); + + it("should deal 2x damage to water type under Electrify", async () => { game.override.enemyMoveset([ Moves.ELECTRIFY ]); await game.classicMode.startBattle(); @@ -126,4 +223,128 @@ describe("Moves - Freeze-Dry", () => { expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); }); + + it("should deal 4x damage to water/flying type under Electrify", async () => { + game.override + .enemyMoveset([ Moves.ELECTRIFY ]) + .enemySpecies(Species.GYARADOS); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); + }); + + it("should deal 0x damage to water/ground type under Electrify", async () => { + game.override + .enemyMoveset([ Moves.ELECTRIFY ]) + .enemySpecies(Species.BARBOACH); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(0); + }); + + it("should deal 0.25x damage to Grass/Dragon type under Electrify", async () => { + game.override + .enemyMoveset([ Moves.ELECTRIFY ]) + .enemySpecies(Species.FLAPPLE); + await game.classicMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(0.25); + }); + + it("should deal 2x damage to Water type during inverse battle", async () => { + game.override + .moveset([ Moves.FREEZE_DRY ]) + .enemySpecies(Species.MAGIKARP); + game.challengeMode.addChallenge(Challenges.INVERSE_BATTLE, 1, 1); + + + await game.challengeMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); + }); + + it("should deal 2x damage to Water type during inverse battle under Normalize", async () => { + game.override + .moveset([ Moves.FREEZE_DRY ]) + .ability(Abilities.NORMALIZE) + .enemySpecies(Species.MAGIKARP); + game.challengeMode.addChallenge(Challenges.INVERSE_BATTLE, 1, 1); + + await game.challengeMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); + }); + + it("should deal 2x damage to Water type during inverse battle under Electrify", async () => { + game.override + .moveset([ Moves.FREEZE_DRY ]) + .enemySpecies(Species.MAGIKARP) + .enemyMoveset([ Moves.ELECTRIFY ]); + game.challengeMode.addChallenge(Challenges.INVERSE_BATTLE, 1, 1); + + await game.challengeMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); + }); + + it("should deal 1x damage to water/flying type during inverse battle under Electrify", async () => { + game.override + .enemyMoveset([ Moves.ELECTRIFY ]) + .enemySpecies(Species.GYARADOS); + + game.challengeMode.addChallenge(Challenges.INVERSE_BATTLE, 1, 1); + + await game.challengeMode.startBattle(); + + const enemy = game.scene.getEnemyPokemon()!; + vi.spyOn(enemy, "getMoveEffectiveness"); + + game.move.select(Moves.FREEZE_DRY); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy.getMoveEffectiveness).toHaveReturnedWith(1); + }); }); diff --git a/src/test/moves/gastro_acid.test.ts b/src/test/moves/gastro_acid.test.ts index fdd75b90b13..ec9246c855c 100644 --- a/src/test/moves/gastro_acid.test.ts +++ b/src/test/moves/gastro_acid.test.ts @@ -62,7 +62,7 @@ describe("Moves - Gastro Acid", () => { }); it("fails if used on an enemy with an already-suppressed ability", async () => { - game.override.battleType(null); + game.override.battleType("single"); await game.startBattle(); diff --git a/src/test/moves/moongeist_beam.test.ts b/src/test/moves/moongeist_beam.test.ts new file mode 100644 index 00000000000..216eee482fb --- /dev/null +++ b/src/test/moves/moongeist_beam.test.ts @@ -0,0 +1,59 @@ +import { allMoves, RandomMoveAttr } from "#app/data/move"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Moves - Moongeist Beam", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.MOONGEIST_BEAM, Moves.METRONOME ]) + .ability(Abilities.BALL_FETCH) + .startingLevel(200) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.STURDY) + .enemyMoveset(Moves.SPLASH); + }); + + // Also covers Photon Geyser and Sunsteel Strike + it("should ignore enemy abilities", async () => { + await game.classicMode.startBattle([ Species.MILOTIC ]); + + const enemy = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.MOONGEIST_BEAM); + await game.phaseInterceptor.to("BerryPhase"); + + expect(enemy.isFainted()).toBe(true); + }); + + // Also covers Photon Geyser and Sunsteel Strike + it("should not ignore enemy abilities when called by another move, such as metronome", async () => { + await game.classicMode.startBattle([ Species.MILOTIC ]); + vi.spyOn(allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0], "getMoveOverride").mockReturnValue(Moves.MOONGEIST_BEAM); + + game.move.select(Moves.METRONOME); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.getEnemyPokemon()!.isFainted()).toBe(false); + expect(game.scene.getPlayerPokemon()!.getLastXMoves()[0].move).toBe(Moves.MOONGEIST_BEAM); + }); +}); diff --git a/src/test/moves/sketch.test.ts b/src/test/moves/sketch.test.ts index 4386ce5868e..f531f44ef0c 100644 --- a/src/test/moves/sketch.test.ts +++ b/src/test/moves/sketch.test.ts @@ -4,9 +4,10 @@ import { Species } from "#enums/species"; import { MoveResult, PokemonMove } from "#app/field/pokemon"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { StatusEffect } from "#app/enums/status-effect"; import { BattlerIndex } from "#app/battle"; +import { allMoves, RandomMoveAttr } from "#app/data/move"; describe("Moves - Sketch", () => { let phaserGame: Phaser.Game; @@ -76,4 +77,22 @@ describe("Moves - Sketch", () => { expect(playerPokemon.moveset[0]?.moveId).toBe(Moves.SPLASH); expect(playerPokemon.moveset[1]?.moveId).toBe(Moves.GROWL); }); + + it("should sketch moves that call other moves", async () => { + const randomMoveAttr = allMoves[Moves.METRONOME].findAttr(attr => attr instanceof RandomMoveAttr) as RandomMoveAttr; + vi.spyOn(randomMoveAttr, "getMoveOverride").mockReturnValue(Moves.FALSE_SWIPE); + + game.override.enemyMoveset([ Moves.METRONOME ]); + await game.classicMode.startBattle([ Species.REGIELEKI ]); + const playerPokemon = game.scene.getPlayerPokemon()!; + playerPokemon.moveset = [ new PokemonMove(Moves.SKETCH) ]; + + // Opponent uses Metronome -> False Swipe, then player uses Sketch, which should sketch Metronome + game.move.select(Moves.SKETCH); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS); + expect(playerPokemon.moveset[0]?.moveId).toBe(Moves.METRONOME); + expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); // Make sure opponent actually used False Swipe + }); }); diff --git a/src/test/phases/game-over-phase.test.ts b/src/test/phases/game-over-phase.test.ts new file mode 100644 index 00000000000..2e19d5fe954 --- /dev/null +++ b/src/test/phases/game-over-phase.test.ts @@ -0,0 +1,77 @@ +import { Biome } from "#enums/biome"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { achvs } from "#app/system/achv"; +import { Unlockables } from "#app/system/unlockables"; + +describe("Game Over Phase", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.MEMENTO, Moves.ICE_BEAM, Moves.SPLASH ]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .startingWave(200) + .startingBiome(Biome.END) + .startingLevel(10000); + }); + + it("winning a run should give rewards", async () => { + await game.classicMode.startBattle([ Species.BULBASAUR ]); + vi.spyOn(game.scene, "validateAchv"); + + // Note: `game.doKillOpponents()` does not properly handle final boss + // Final boss phase 1 + game.move.select(Moves.ICE_BEAM); + await game.toNextTurn(); + + // Final boss phase 2 + game.move.select(Moves.ICE_BEAM); + await game.phaseInterceptor.to("PostGameOverPhase", false); + + // The game refused to actually give the vouchers during tests, + // so the best we can do is to check that their reward phases occurred. + expect(game.phaseInterceptor.log.includes("GameOverPhase")).toBe(true); + expect(game.phaseInterceptor.log.includes("UnlockPhase")).toBe(true); + expect(game.phaseInterceptor.log.includes("RibbonModifierRewardPhase")).toBe(true); + expect(game.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]).toBe(true); + expect(game.scene.validateAchv).toHaveBeenCalledWith(achvs.CLASSIC_VICTORY); + expect(game.scene.gameData.achvUnlocks[achvs.CLASSIC_VICTORY.id]).toBeTruthy(); + }); + + it("losing a run should not give rewards", async () => { + await game.classicMode.startBattle([ Species.BULBASAUR ]); + vi.spyOn(game.scene, "validateAchv"); + + game.move.select(Moves.MEMENTO); + await game.phaseInterceptor.to("PostGameOverPhase", false); + + expect(game.phaseInterceptor.log.includes("GameOverPhase")).toBe(true); + expect(game.phaseInterceptor.log.includes("UnlockPhase")).toBe(false); + expect(game.phaseInterceptor.log.includes("RibbonModifierRewardPhase")).toBe(false); + expect(game.phaseInterceptor.log.includes("GameOverModifierRewardPhase")).toBe(false); + expect(game.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]).toBe(false); + expect(game.scene.validateAchv).not.toHaveBeenCalledWith(achvs.CLASSIC_VICTORY); + expect(game.scene.gameData.achvUnlocks[achvs.CLASSIC_VICTORY.id]).toBeFalsy(); + }); +}); diff --git a/src/test/plugins/api/pokerogue-session-savedata-api.test.ts b/src/test/plugins/api/pokerogue-session-savedata-api.test.ts index d9f6216c4cf..f453c5edd88 100644 --- a/src/test/plugins/api/pokerogue-session-savedata-api.test.ts +++ b/src/test/plugins/api/pokerogue-session-savedata-api.test.ts @@ -28,7 +28,8 @@ describe("Pokerogue Session Savedata API", () => { describe("Newclear", () => { const params: NewClearSessionSavedataRequest = { clientSessionId: "test-session-id", - slot: 3, + isVictory: true, + slot: 3 }; it("should return true on SUCCESS", async () => { diff --git a/src/test/utils/helpers/overridesHelper.ts b/src/test/utils/helpers/overridesHelper.ts index 02950d497ee..1c05f92a334 100644 --- a/src/test/utils/helpers/overridesHelper.ts +++ b/src/test/utils/helpers/overridesHelper.ts @@ -4,7 +4,7 @@ import { Abilities } from "#app/enums/abilities"; import * as GameMode from "#app/game-mode"; import { GameModes, getGameMode } from "#app/game-mode"; import { ModifierOverride } from "#app/modifier/modifier-type"; -import Overrides from "#app/overrides"; +import Overrides, { BattleStyle } from "#app/overrides"; import { Unlockables } from "#app/system/unlockables"; import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; @@ -238,13 +238,14 @@ export class OverridesHelper extends GameManagerHelper { } /** - * Override the battle type (single or double) + * Override the battle type (e.g., single or double). + * @see {@linkcode Overrides.BATTLE_TYPE_OVERRIDE} * @param battleType battle type to set * @returns `this` */ - public battleType(battleType: "single" | "double" | null): this { + public battleType(battleType: BattleStyle | null): this { vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue(battleType); - this.log(`Battle type set to ${battleType} only!`); + this.log(battleType === null ? "Battle type override disabled!" : `Battle type set to ${battleType}!`); return this; } diff --git a/src/test/utils/phaseInterceptor.ts b/src/test/utils/phaseInterceptor.ts index 17b6c7a6c81..4029e5e168c 100644 --- a/src/test/utils/phaseInterceptor.ts +++ b/src/test/utils/phaseInterceptor.ts @@ -55,6 +55,11 @@ import { import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase"; import { PartyExpPhase } from "#app/phases/party-exp-phase"; import { ExpPhase } from "#app/phases/exp-phase"; +import { GameOverPhase } from "#app/phases/game-over-phase"; +import { RibbonModifierRewardPhase } from "#app/phases/ribbon-modifier-reward-phase"; +import { GameOverModifierRewardPhase } from "#app/phases/game-over-modifier-reward-phase"; +import { UnlockPhase } from "#app/phases/unlock-phase"; +import { PostGameOverPhase } from "#app/phases/post-game-over-phase"; export interface PromptHandler { phaseTarget?: string; @@ -113,10 +118,15 @@ type PhaseClass = | typeof MysteryEncounterBattlePhase | typeof MysteryEncounterRewardsPhase | typeof PostMysteryEncounterPhase + | typeof RibbonModifierRewardPhase + | typeof GameOverModifierRewardPhase | typeof ModifierRewardPhase | typeof PartyExpPhase | typeof ExpPhase - | typeof EncounterPhase; + | typeof EncounterPhase + | typeof GameOverPhase + | typeof UnlockPhase + | typeof PostGameOverPhase; type PhaseString = | "LoginPhase" @@ -167,10 +177,15 @@ type PhaseString = | "MysteryEncounterBattlePhase" | "MysteryEncounterRewardsPhase" | "PostMysteryEncounterPhase" + | "RibbonModifierRewardPhase" + | "GameOverModifierRewardPhase" | "ModifierRewardPhase" | "PartyExpPhase" | "ExpPhase" - | "EncounterPhase"; + | "EncounterPhase" + | "GameOverPhase" + | "UnlockPhase" + | "PostGameOverPhase"; type PhaseInterceptorPhase = PhaseClass | PhaseString; @@ -245,10 +260,15 @@ export default class PhaseInterceptor { [ MysteryEncounterBattlePhase, this.startPhase ], [ MysteryEncounterRewardsPhase, this.startPhase ], [ PostMysteryEncounterPhase, this.startPhase ], + [ RibbonModifierRewardPhase, this.startPhase ], + [ GameOverModifierRewardPhase, this.startPhase ], [ ModifierRewardPhase, this.startPhase ], [ PartyExpPhase, this.startPhase ], [ ExpPhase, this.startPhase ], [ EncounterPhase, this.startPhase ], + [ GameOverPhase, this.startPhase ], + [ UnlockPhase, this.startPhase ], + [ PostGameOverPhase, this.startPhase ], ]; private endBySetMode = [ diff --git a/src/ui/mystery-encounter-ui-handler.ts b/src/ui/mystery-encounter-ui-handler.ts index b568f8b71de..cdb1c9024c5 100644 --- a/src/ui/mystery-encounter-ui-handler.ts +++ b/src/ui/mystery-encounter-ui-handler.ts @@ -369,9 +369,9 @@ export default class MysteryEncounterUiHandler extends UiHandler { let text: string | null; if (option.hasRequirements() && this.optionsMeetsReqs[i] && (option.optionMode === MysteryEncounterOptionMode.DEFAULT_OR_SPECIAL || option.optionMode === MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)) { // Options with special requirements that are met are automatically colored green - text = getEncounterText(this.scene, label, TextStyle.SUMMARY_GREEN); + text = getEncounterText(this.scene, label, TextStyle.ME_OPTION_SPECIAL); } else { - text = getEncounterText(this.scene, label, optionDialogue.style ? optionDialogue.style : TextStyle.WINDOW); + text = getEncounterText(this.scene, label, optionDialogue.style ? optionDialogue.style : TextStyle.ME_OPTION_DEFAULT); } if (text) { diff --git a/src/ui/run-info-ui-handler.ts b/src/ui/run-info-ui-handler.ts index 82d390016f7..ace9d956dd9 100644 --- a/src/ui/run-info-ui-handler.ts +++ b/src/ui/run-info-ui-handler.ts @@ -518,7 +518,8 @@ export default class RunInfoUiHandler extends UiHandler { const runTime = Utils.getPlayTimeString(this.runInfo.playTime); runInfoText.appendText(`${i18next.t("runHistory:runLength")}: ${runTime}`, false); const runMoney = Utils.formatMoney(this.scene.moneyFormat, this.runInfo.money); - runInfoText.appendText(`[color=${getTextColor(TextStyle.MONEY)}]${i18next.t("battleScene:moneyOwned", { formattedMoney : runMoney })}[/color]`); + const moneyTextColor = getTextColor(TextStyle.MONEY_WINDOW, false, this.scene.uiTheme); + runInfoText.appendText(`[color=${moneyTextColor}]${i18next.t("battleScene:moneyOwned", { formattedMoney : runMoney })}[/color]`); runInfoText.setPosition(7, 70); runInfoTextContainer.add(runInfoText); // Luck diff --git a/src/ui/target-select-ui-handler.ts b/src/ui/target-select-ui-handler.ts index ecc15e5985e..249ae7b8b01 100644 --- a/src/ui/target-select-ui-handler.ts +++ b/src/ui/target-select-ui-handler.ts @@ -13,9 +13,11 @@ import { SubstituteTag } from "#app/data/battler-tags"; export type TargetSelectCallback = (targets: BattlerIndex[]) => void; export default class TargetSelectUiHandler extends UiHandler { - private fieldIndex: integer; + private fieldIndex: number; private move: Moves; private targetSelectCallback: TargetSelectCallback; + private cursor0: number; // associated with BattlerIndex.PLAYER + private cursor1: number; // associated with BattlerIndex.PLAYER_2 private isMultipleTargets: boolean = false; private targets: BattlerIndex[]; @@ -42,8 +44,9 @@ export default class TargetSelectUiHandler extends UiHandler { this.fieldIndex = args[0] as integer; this.move = args[1] as Moves; this.targetSelectCallback = args[2] as TargetSelectCallback; + const user = this.scene.getPlayerField()[this.fieldIndex]; - const moveTargets = getMoveTargets(this.scene.getPlayerField()[this.fieldIndex], this.move); + const moveTargets = getMoveTargets(user, this.move); this.targets = moveTargets.targets; this.isMultipleTargets = moveTargets.multiple ?? false; @@ -53,11 +56,29 @@ export default class TargetSelectUiHandler extends UiHandler { this.enemyModifiers = this.scene.getModifierBar(true); - this.setCursor(this.targets.includes(this.cursor) ? this.cursor : this.targets[0]); - + if (this.fieldIndex === BattlerIndex.PLAYER) { + this.resetCursor(this.cursor0, user); + } else if (this.fieldIndex === BattlerIndex.PLAYER_2) { + this.resetCursor(this.cursor1, user); + } return true; } + /** + * Determines what value to assign the main cursor based on the previous turn's target or the user's status + * @param cursorN the cursor associated with the user's field index + * @param user the Pokemon using the move + */ + resetCursor(cursorN: number, user: Pokemon): void { + if (!Utils.isNullOrUndefined(cursorN)) { + if ([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2 ].includes(cursorN) || user.battleSummonData.waveTurnCount === 1) { + // Reset cursor on the first turn of a fight or if an ally was targeted last turn + cursorN = -1; + } + } + this.setCursor(this.targets.includes(cursorN) ? cursorN : this.targets[0]); + } + processInput(button: Button): boolean { const ui = this.getUi(); @@ -67,6 +88,15 @@ export default class TargetSelectUiHandler extends UiHandler { const targetIndexes: BattlerIndex[] = this.isMultipleTargets ? this.targets : [ this.cursor ]; this.targetSelectCallback(button === Button.ACTION ? targetIndexes : []); success = true; + if (this.fieldIndex === BattlerIndex.PLAYER) { + if (Utils.isNullOrUndefined(this.cursor0) || this.cursor0 !== this.cursor) { + this.cursor0 = this.cursor; + } + } else if (this.fieldIndex === BattlerIndex.PLAYER_2) { + if (Utils.isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor) { + this.cursor1 = this.cursor; + } + } } else if (this.isMultipleTargets) { success = false; } else { @@ -152,7 +182,6 @@ export default class TargetSelectUiHandler extends UiHandler { yoyo: true })); }); - return ret; } @@ -184,7 +213,6 @@ export default class TargetSelectUiHandler extends UiHandler { } clear() { - this.cursor = -1; super.clear(); this.eraseCursor(); } diff --git a/src/ui/text.ts b/src/ui/text.ts index 069aa8680fc..17ae02be9ef 100644 --- a/src/ui/text.ts +++ b/src/ui/text.ts @@ -22,7 +22,8 @@ export enum TextStyle { SUMMARY_GOLD, SUMMARY_GRAY, SUMMARY_GREEN, - MONEY, + MONEY, // Money default styling (pale yellow) + MONEY_WINDOW, // Money displayed in Windows (needs different colors based on theme) STATS_LABEL, STATS_VALUE, SETTINGS_VALUE, @@ -38,7 +39,9 @@ export enum TextStyle { MOVE_PP_EMPTY, SMALLER_WINDOW_ALT, BGM_BAR, - PERFECT_IV + PERFECT_IV, + ME_OPTION_DEFAULT, // Default style for choices in ME + ME_OPTION_SPECIAL, // Style for choices with special requirements in ME } export interface TextStyleOptions { @@ -139,6 +142,8 @@ export function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraSty case TextStyle.SUMMARY_GREEN: case TextStyle.WINDOW: case TextStyle.WINDOW_ALT: + case TextStyle.ME_OPTION_DEFAULT: + case TextStyle.ME_OPTION_SPECIAL: shadowXpos = 3; shadowYpos = 3; break; @@ -177,6 +182,7 @@ export function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraSty break; case TextStyle.BATTLE_INFO: case TextStyle.MONEY: + case TextStyle.MONEY_WINDOW: case TextStyle.TOOLTIP_TITLE: styleOptions.fontSize = defaultFontSize - 24; shadowXpos = 3.5; @@ -238,13 +244,22 @@ export function getBBCodeFrag(content: string, textStyle: TextStyle, uiTheme: Ui * - "red text" with TextStyle.SUMMARY_RED applied * @param content string with styling that need to be applied for BBCodeTextObject * @param primaryStyle Primary style is required in order to escape BBCode styling properly. - * @param uiTheme + * @param uiTheme the {@linkcode UiTheme} to get TextStyle for + * @param forWindow set to `true` if the text is to be displayed in a window ({@linkcode BattleScene.addWindow}) + * it will replace all instances of the default MONEY TextStyle by {@linkcode TextStyle.MONEY_WINDOW} */ -export function getTextWithColors(content: string, primaryStyle: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string { +export function getTextWithColors(content: string, primaryStyle: TextStyle, uiTheme: UiTheme, forWindow?: boolean): string { // Apply primary styling before anything else let text = getBBCodeFrag(content, primaryStyle, uiTheme) + "[/color][/shadow]"; const primaryStyleString = [ ...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))! ][0]; + /* For money text displayed in game windows, we can't use the default {@linkcode TextStyle.MONEY} + * or it will look wrong in legacy mode because of the different window background color + * So, for text to be displayed in windows replace all "@[MONEY]" with "@[MONEY_WINDOW]" */ + if (forWindow) { + text = text.replace(/@\[MONEY\]/g, (_substring: string) => "@[MONEY_WINDOW]"); + } + // Set custom colors text = text.replace(/@\[([^{]*)\]{([^}]*)}/gi, (substring, textStyle: string, textToColor: string) => { return "[/color][/shadow]" + getBBCodeFrag(textToColor, TextStyle[textStyle], uiTheme) + "[/color][/shadow]" + primaryStyleString; @@ -310,7 +325,12 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui return !shadow ? "#f89890" : "#984038"; case TextStyle.SUMMARY_GOLD: case TextStyle.MONEY: - return !shadow ? "#e8e8a8" : "#a0a060"; + return !shadow ? "#e8e8a8" : "#a0a060"; // Pale Yellow/Gold + case TextStyle.MONEY_WINDOW: + if (isLegacyTheme) { + return !shadow ? "#f8b050" : "#c07800"; // Gold + } + return !shadow ? "#e8e8a8" : "#a0a060"; // Pale Yellow/Gold case TextStyle.SETTINGS_LOCKED: case TextStyle.SUMMARY_GRAY: return !shadow ? "#a0a0a0" : "#636363"; @@ -332,6 +352,13 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui return !shadow ? "#484848" : "#d0d0c8"; case TextStyle.BGM_BAR: return !shadow ? "#f8f8f8" : "#6b5a73"; + case TextStyle.ME_OPTION_DEFAULT: + return !shadow ? "#f8f8f8" : "#6b5a73"; // White + case TextStyle.ME_OPTION_SPECIAL: + if (isLegacyTheme) { + return !shadow ? "#f8b050" : "#c07800"; // Gold + } + return !shadow ? "#78c850" : "#306850"; // Green } }