From 5ad8f189501a0afea2cc458eeacecaadae5c192c Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Fri, 14 Feb 2025 02:13:28 +0100 Subject: [PATCH 01/15] getFullUnlockedData now properly accounts for forms --- src/data/pokemon-species.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 5883bac3fc8..8473f7788e3 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -1051,7 +1051,11 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali caughtAttr += DexAttr.VARIANT_2; caughtAttr += DexAttr.VARIANT_3; } - caughtAttr += DexAttr.DEFAULT_FORM; + + // Summing successive bigints for each obtainable form + caughtAttr += this.forms + .map((f, index) => f.isUnobtainable ? 0n : 128n * 2n ** BigInt(index)) + .reduce((acc, val) => acc + val, 0n); return caughtAttr; } From 7611061378f61e21381719a33f21266f3e02774d Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Fri, 14 Feb 2025 02:15:24 +0100 Subject: [PATCH 02/15] Updating version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 270b72afda8..1bf7649704b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "pokemon-rogue-battle", - "version": "1.6.0", + "version": "1.6.1", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 3861d5fb4ca..4e43b835189 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.6.0", + "version": "1.6.1", "type": "module", "scripts": { "start": "vite", From 8f498f1197df29673b25e2f9116589feae59065b Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Fri, 14 Feb 2025 03:03:14 +0100 Subject: [PATCH 03/15] Counting default form in caughtAttr for mons that don't have alternative forms --- src/data/pokemon-species.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 8473f7788e3..4349cee2cbf 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -1053,9 +1053,9 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali } // Summing successive bigints for each obtainable form - caughtAttr += this.forms - .map((f, index) => f.isUnobtainable ? 0n : 128n * 2n ** BigInt(index)) - .reduce((acc, val) => acc + val, 0n); + caughtAttr += this?.forms?.length > 1 ? + this.forms.map((f, index) => f.isUnobtainable ? 0n : 128n * 2n ** BigInt(index)).reduce((acc, val) => acc + val, 0n) : + DexAttr.DEFAULT_FORM; return caughtAttr; } From d159901ea1464911af612cd950c0eb4c5b671b84 Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Fri, 14 Feb 2025 03:03:58 +0100 Subject: [PATCH 04/15] Updated version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1bf7649704b..b3ce2c3b415 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "pokemon-rogue-battle", - "version": "1.6.1", + "version": "1.6.2", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 4e43b835189..bbbb0f56f6b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.6.1", + "version": "1.6.2", "type": "module", "scripts": { "start": "vite", From 77fbcc70ef7c0c56c6b75f8e252ecd46c442e8f1 Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Fri, 14 Feb 2025 18:40:13 +1100 Subject: [PATCH 05/15] [Bug][Hotfix] Fix fusion with dual type + monotype with shared primary type. (#5322) * Fix fusion with dual type + monotype with shared primary type. * Update version number * Add test case --- package-lock.json | 4 ++-- package.json | 2 +- src/field/pokemon.ts | 6 ++++++ src/test/field/pokemon.test.ts | 11 +++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3ce2c3b415..2ae45b1e2c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.6.2", + "version": "1.6.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.5.4", + "version": "1.6.3", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index bbbb0f56f6b..495815be15d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.6.2", + "version": "1.6.3", "type": "module", "scripts": { "start": "vite", diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 82674fb8b46..b1e48df5c61 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1322,6 +1322,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } else if (fusionType1 !== types[0]) { secondType = fusionType1; } + + + if (secondType === Type.UNKNOWN && Utils.isNullOrUndefined(fusionType2)) { // If second pokemon was monotype and shared its primary type + secondType = (customTypes && this.customPokemonData.types.length > 1 && this.customPokemonData.types[1] !== Type.UNKNOWN) + ? this.customPokemonData.types[1] : (speciesForm.type2 ?? Type.UNKNOWN); + } } else { // If not a fusion, just get the second type from the species, checking for permanent changes from ME secondType = (customTypes && this.customPokemonData.types.length > 1 && this.customPokemonData.types[1] !== Type.UNKNOWN) diff --git a/src/test/field/pokemon.test.ts b/src/test/field/pokemon.test.ts index 0a1ddac9e90..0c282b44f49 100644 --- a/src/test/field/pokemon.test.ts +++ b/src/test/field/pokemon.test.ts @@ -150,6 +150,17 @@ describe("Spec - Pokemon", () => { expect(types[1]).toBe(Type.DARK); }); + it("Fusing mons with two and one types", async () => { + game.override.starterSpecies(Species.NUMEL); + game.override.starterFusionSpecies(Species.CHARMANDER); + await game.classicMode.startBattle(); + const pokemon = scene.getPlayerParty()[0]; + + const types = pokemon.getTypes(); + expect(types[0]).toBe(Type.FIRE); + expect(types[1]).toBe(Type.GROUND); + }); + it("Fusing two mons with two types", async () => { game.override.starterSpecies(Species.NATU); game.override.starterFusionSpecies(Species.HOUNDOUR); From 7b9d1d6570a9560909acad59a8b47c263eb1d7ad Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Fri, 14 Feb 2025 21:51:41 -0500 Subject: [PATCH 06/15] [Hotfix] Fix crash involving female Pyroar fusions with exp sprites (#5331) * Fix crash involving female Pyroar fusions with exp sprites * Update locales submodule --- package-lock.json | 4 +-- package.json | 2 +- public/images/pokemon/668-female.json | 41 -------------------------- public/images/pokemon/668-female.png | Bin 898 -> 0 bytes public/locales | 2 +- src/field/pokemon.ts | 9 ++++-- 6 files changed, 11 insertions(+), 47 deletions(-) delete mode 100644 public/images/pokemon/668-female.json delete mode 100644 public/images/pokemon/668-female.png diff --git a/package-lock.json b/package-lock.json index 2ae45b1e2c2..ce1feb7db41 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.6.3", + "version": "1.6.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.6.3", + "version": "1.6.4", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index 495815be15d..c9b5798af76 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.6.3", + "version": "1.6.4", "type": "module", "scripts": { "start": "vite", diff --git a/public/images/pokemon/668-female.json b/public/images/pokemon/668-female.json deleted file mode 100644 index 13d67c90194..00000000000 --- a/public/images/pokemon/668-female.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "textures": [ - { - "image": "668-female.png", - "format": "RGBA8888", - "size": { - "w": 72, - "h": 72 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 63, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 63, - "h": 72 - }, - "frame": { - "x": 0, - "y": 0, - "w": 63, - "h": 72 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:3f88e039152d4a967a218cb721938610:e6991ce9c3bad348cbc05ebf9b440302:d99ed0e84a0695b54e479aa98271aba1$" - } -} diff --git a/public/images/pokemon/668-female.png b/public/images/pokemon/668-female.png deleted file mode 100644 index c8f4e205491a3c9298afb167fad34989f8374085..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 898 zcmV-|1AY97P)9ipC~f?H~&!QiD!hish$88UPV zX(u5MN3Tnl78^R0QcSc72YT@Sk_7y}^xnye&XO&Ec#yfDzW0!f$u4>Rk(|gR-)KI>MZL8`JY?jNP&BPpk z6|3KFQ6lfn-Xc{mT6Lf2H;>h)Axik%pjItc)tU~_I*I3uq1tV~#v*s8`={!Q&I&?M zEt~!CDA|j+TdhG$g9vL!E*a^euWJRRMZ~jg`J-=0@=t+I%akdP8K*>eQUBYPZAT?F7FrJ>ozcaRU5 zxHTzg-8A_bJ&aN_4fI8G8h0oG=;o!VGS})bQdotb6mO_W5BVh`EjEaFjJ^68!pF@y zKNr|r^idL66vPgq{YMaac5iN$<`D}J=>Z}Z6{ct!1w6o=b}OCL4pIuFMFEdl+^sYR z+98=pSuV1y;Cw~{1+qn`+l0J9bs9_RNhuf9PQ$q!iV|7s*{n8=1qqF6k#^>JMOf;& zYLMrk8KPFnA^@cd9}x*V^st8{KK6IMJ@!Ts9iW;x2@fGMA0TB>K^!zYh?0GDriQ5Y z8x%IkUQq`n7I8dvkr(!m{cmaZMzm80P=bitw=s+_cc?Jepa4b?W7MDxsDmhxQna^w zC5S`gxPlIm0H+S(D*z79$it~aR6+?BIT<1;G`{iCFewBmM58JZ8*DnI@Qs{Qj2#F6 Y0boY}eU9#KL;wH)07*qoM6N<$f?NrLjQ{`u diff --git a/public/locales b/public/locales index f917baa1bb2..58dda14ee83 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit f917baa1bb2fc5071587b7894ce7b4898cc64f36 +Subproject commit 58dda14ee834204c4bd5ece47694a3c068df4b0e diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index b1e48df5c61..5c6fbb34aea 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4042,6 +4042,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + if (fusionPixelColors.length === 0) { // ERROR HANDLING IS NOT OPTIONAL BUDDY + console.log("Failed to create fusion palette"); + return; + } + let paletteColors: Map; let fusionPaletteColors: Map; @@ -4055,8 +4060,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { Math.random = originalRandom; - paletteColors = paletteColors!; // tell TS compiler that paletteColors is defined! - fusionPaletteColors = fusionPaletteColors!; // TS compiler that fusionPaletteColors is defined! + paletteColors = paletteColors!; // erroneously tell TS compiler that paletteColors is defined! + fusionPaletteColors = fusionPaletteColors!; // mischievously misinform TS compiler that fusionPaletteColors is defined! const [ palette, fusionPalette ] = [ paletteColors, fusionPaletteColors ] .map(paletteColors => { let keys = Array.from(paletteColors.keys()).sort((a: number, b: number) => paletteColors.get(a)! < paletteColors.get(b)! ? 1 : -1); From 4d5f9cecf102d429513d78f0f5208fc981e5982b Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Sat, 15 Feb 2025 20:32:07 -0600 Subject: [PATCH 07/15] Fix Zenith Marshadow missing a party icon (#5301) --- public/images/pokemon/icons/7/802-zenith.png | Bin 0 -> 396 bytes public/images/pokemon/icons/7/802s-zenith.png | Bin 0 -> 396 bytes public/images/pokemon_icons_7.json | 5950 +++++++++-------- public/images/pokemon_icons_7.png | Bin 51140 -> 51451 bytes 4 files changed, 2996 insertions(+), 2954 deletions(-) create mode 100644 public/images/pokemon/icons/7/802-zenith.png create mode 100644 public/images/pokemon/icons/7/802s-zenith.png diff --git a/public/images/pokemon/icons/7/802-zenith.png b/public/images/pokemon/icons/7/802-zenith.png new file mode 100644 index 0000000000000000000000000000000000000000..7e0fee2d6096fd8d6e0c6135bfd47d71a6eff0c2 GIT binary patch literal 396 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`r2~9ITpb)7zJFKQx7;Cn{oI6vhz}n$E+jZKG!y{k^Jd4`11ZjuAiv=M zP{0uEUm*k%EbxddW?P6+uW^joTG!tv6?>RECv37kFe-<*}cAQ)W! fU~OE}+FFK`J#t5WE3bV6^e}^`tDnm{r-UW|T_T?L literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/7/802s-zenith.png b/public/images/pokemon/icons/7/802s-zenith.png new file mode 100644 index 0000000000000000000000000000000000000000..7e0fee2d6096fd8d6e0c6135bfd47d71a6eff0c2 GIT binary patch literal 396 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`r2~9ITpb)7zJFKQx7;Cn{oI6vhz}n$E+jZKG!y{k^Jd4`11ZjuAiv=M zP{0uEUm*k%EbxddW?P6+uW^joTG!tv6?>RECv37kFe-<*}cAQ)W! fU~OE}+FFK`J#t5WE3bV6^e}^`tDnm{r-UW|T_T?L literal 0 HcmV?d00001 diff --git a/public/images/pokemon_icons_7.json b/public/images/pokemon_icons_7.json index 0523a232d79..03eeba88a70 100644 --- a/public/images/pokemon_icons_7.json +++ b/public/images/pokemon_icons_7.json @@ -5,7 +5,7 @@ "format": "RGBA8888", "size": { "w": 502, - "h": 323 + "h": 325 }, "scale": 1, "frames": [ @@ -324,48 +324,6 @@ "h": 29 } }, - { - "filename": "795", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 28, - "h": 30 - }, - "frame": { - "x": 0, - "y": 293, - "w": 28, - "h": 30 - } - }, - { - "filename": "795s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 28, - "h": 30 - }, - "frame": { - "x": 28, - "y": 293, - "w": 28, - "h": 30 - } - }, { "filename": "798s", "rotated": false, @@ -381,8 +339,8 @@ "h": 29 }, "frame": { - "x": 112, - "y": 0, + "x": 0, + "y": 293, "w": 31, "h": 29 } @@ -402,7 +360,7 @@ "h": 28 }, "frame": { - "x": 143, + "x": 112, "y": 0, "w": 30, "h": 28 @@ -423,8 +381,8 @@ "h": 28 }, "frame": { - "x": 173, - "y": 0, + "x": 108, + "y": 28, "w": 30, "h": 28 } @@ -444,7 +402,7 @@ "h": 28 }, "frame": { - "x": 203, + "x": 142, "y": 0, "w": 29, "h": 28 @@ -465,8 +423,8 @@ "h": 28 }, "frame": { - "x": 232, - "y": 0, + "x": 138, + "y": 28, "w": 29, "h": 28 } @@ -486,7 +444,7 @@ "h": 27 }, "frame": { - "x": 261, + "x": 171, "y": 0, "w": 29, "h": 27 @@ -507,7 +465,7 @@ "h": 27 }, "frame": { - "x": 290, + "x": 200, "y": 0, "w": 29, "h": 27 @@ -528,7 +486,7 @@ "h": 27 }, "frame": { - "x": 319, + "x": 229, "y": 0, "w": 28, "h": 27 @@ -549,7 +507,7 @@ "h": 27 }, "frame": { - "x": 347, + "x": 257, "y": 0, "w": 28, "h": 27 @@ -570,7 +528,7 @@ "h": 23 }, "frame": { - "x": 375, + "x": 285, "y": 0, "w": 32, "h": 23 @@ -591,14 +549,14 @@ "h": 23 }, "frame": { - "x": 407, + "x": 317, "y": 0, "w": 32, "h": 23 } }, { - "filename": "800", + "filename": "795", "rotated": false, "trimmed": true, "sourceSize": { @@ -619,7 +577,7 @@ } }, { - "filename": "800s", + "filename": "795s", "rotated": false, "trimmed": true, "sourceSize": { @@ -639,6 +597,48 @@ "h": 30 } }, + { + "filename": "800", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 0, + "w": 28, + "h": 30 + }, + "frame": { + "x": 32, + "y": 145, + "w": 28, + "h": 30 + } + }, + { + "filename": "800s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 0, + "w": 28, + "h": 30 + }, + "frame": { + "x": 32, + "y": 175, + "w": 28, + "h": 30 + } + }, { "filename": "805", "rotated": false, @@ -654,8 +654,8 @@ "h": 30 }, "frame": { - "x": 32, - "y": 145, + "x": 31, + "y": 205, "w": 28, "h": 30 } @@ -674,31 +674,10 @@ "w": 28, "h": 30 }, - "frame": { - "x": 32, - "y": 175, - "w": 28, - "h": 30 - } - }, - { - "filename": "773", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 26, - "h": 30 - }, "frame": { "x": 31, - "y": 205, - "w": 26, + "y": 235, + "w": 28, "h": 30 } }, @@ -718,32 +697,11 @@ }, "frame": { "x": 31, - "y": 235, + "y": 265, "w": 26, "h": 30 } }, - { - "filename": "792", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 1, - "w": 28, - "h": 28 - }, - "frame": { - "x": 31, - "y": 265, - "w": 28, - "h": 28 - } - }, { "filename": "773-dark", "rotated": false, @@ -759,8 +717,8 @@ "h": 30 }, "frame": { - "x": 56, - "y": 293, + "x": 31, + "y": 295, "w": 26, "h": 30 } @@ -780,7 +738,7 @@ "h": 25 }, "frame": { - "x": 439, + "x": 349, "y": 0, "w": 30, "h": 25 @@ -801,12 +759,75 @@ "h": 25 }, "frame": { - "x": 469, + "x": 379, "y": 0, "w": 30, "h": 25 } }, + { + "filename": "785", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 3, + "w": 28, + "h": 26 + }, + "frame": { + "x": 409, + "y": 0, + "w": 28, + "h": 26 + } + }, + { + "filename": "785s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 3, + "w": 28, + "h": 26 + }, + "frame": { + "x": 437, + "y": 0, + "w": 28, + "h": 26 + } + }, + { + "filename": "792", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 1, + "w": 28, + "h": 28 + }, + "frame": { + "x": 465, + "y": 0, + "w": 28, + "h": 28 + } + }, { "filename": "792s", "rotated": false, @@ -822,8 +843,8 @@ "h": 28 }, "frame": { - "x": 108, - "y": 29, + "x": 70, + "y": 57, "w": 28, "h": 28 } @@ -843,8 +864,8 @@ "h": 30 }, "frame": { - "x": 70, - "y": 57, + "x": 62, + "y": 85, "w": 26, "h": 30 } @@ -864,8 +885,8 @@ "h": 30 }, "frame": { - "x": 96, - "y": 57, + "x": 62, + "y": 115, "w": 26, "h": 30 } @@ -885,8 +906,8 @@ "h": 30 }, "frame": { - "x": 62, - "y": 87, + "x": 60, + "y": 145, "w": 26, "h": 30 } @@ -906,8 +927,8 @@ "h": 30 }, "frame": { - "x": 88, - "y": 87, + "x": 60, + "y": 175, "w": 26, "h": 30 } @@ -927,8 +948,8 @@ "h": 30 }, "frame": { - "x": 62, - "y": 117, + "x": 59, + "y": 205, "w": 26, "h": 30 } @@ -948,8 +969,8 @@ "h": 30 }, "frame": { - "x": 88, - "y": 117, + "x": 59, + "y": 235, "w": 26, "h": 30 } @@ -969,8 +990,8 @@ "h": 30 }, "frame": { - "x": 60, - "y": 147, + "x": 57, + "y": 265, "w": 26, "h": 30 } @@ -990,12 +1011,54 @@ "h": 30 }, "frame": { - "x": 86, - "y": 147, + "x": 57, + "y": 295, "w": 26, "h": 30 } }, + { + "filename": "764", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 0, + "w": 25, + "h": 30 + }, + "frame": { + "x": 88, + "y": 85, + "w": 25, + "h": 30 + } + }, + { + "filename": "764s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 0, + "w": 25, + "h": 30 + }, + "frame": { + "x": 88, + "y": 115, + "w": 25, + "h": 30 + } + }, { "filename": "773-ground", "rotated": false, @@ -1011,8 +1074,8 @@ "h": 30 }, "frame": { - "x": 60, - "y": 177, + "x": 86, + "y": 145, "w": 26, "h": 30 } @@ -1033,7 +1096,7 @@ }, "frame": { "x": 86, - "y": 177, + "y": 175, "w": 26, "h": 30 } @@ -1053,8 +1116,8 @@ "h": 30 }, "frame": { - "x": 57, - "y": 207, + "x": 85, + "y": 205, "w": 26, "h": 30 } @@ -1074,54 +1137,12 @@ "h": 30 }, "frame": { - "x": 83, - "y": 207, + "x": 85, + "y": 235, "w": 26, "h": 30 } }, - { - "filename": "2026", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 26, - "h": 28 - }, - "frame": { - "x": 57, - "y": 237, - "w": 26, - "h": 28 - } - }, - { - "filename": "772", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 2, - "w": 25, - "h": 28 - }, - "frame": { - "x": 59, - "y": 265, - "w": 25, - "h": 28 - } - }, { "filename": "773-rock", "rotated": false, @@ -1136,53 +1157,11 @@ "w": 26, "h": 30 }, - "frame": { - "x": 82, - "y": 293, - "w": 26, - "h": 30 - } - }, - { - "filename": "2026s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 26, - "h": 28 - }, "frame": { "x": 83, - "y": 237, - "w": 26, - "h": 28 - } - }, - { - "filename": "772s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 2, - "w": 25, - "h": 28 - }, - "frame": { - "x": 84, "y": 265, - "w": 25, - "h": 28 + "w": 26, + "h": 30 } }, { @@ -1200,14 +1179,14 @@ "h": 30 }, "frame": { - "x": 108, - "y": 293, + "x": 83, + "y": 295, "w": 26, "h": 30 } }, { - "filename": "764", + "filename": "772", "rotated": false, "trimmed": true, "sourceSize": { @@ -1215,16 +1194,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 0, + "x": 8, + "y": 2, "w": 25, - "h": 30 + "h": 28 }, "frame": { - "x": 122, + "x": 98, "y": 57, "w": 25, - "h": 30 + "h": 28 } }, { @@ -1242,14 +1221,14 @@ "h": 30 }, "frame": { - "x": 114, - "y": 87, + "x": 123, + "y": 56, "w": 26, "h": 30 } }, { - "filename": "773s", + "filename": "773", "rotated": false, "trimmed": true, "sourceSize": { @@ -1263,8 +1242,8 @@ "h": 30 }, "frame": { - "x": 114, - "y": 117, + "x": 149, + "y": 56, "w": 26, "h": 30 } @@ -1284,8 +1263,8 @@ "h": 30 }, "frame": { - "x": 112, - "y": 147, + "x": 113, + "y": 86, "w": 26, "h": 30 } @@ -1305,8 +1284,8 @@ "h": 30 }, "frame": { - "x": 112, - "y": 177, + "x": 139, + "y": 86, "w": 26, "h": 30 } @@ -1326,8 +1305,8 @@ "h": 30 }, "frame": { - "x": 109, - "y": 207, + "x": 113, + "y": 116, "w": 26, "h": 30 } @@ -1347,33 +1326,12 @@ "h": 30 }, "frame": { - "x": 109, - "y": 237, + "x": 139, + "y": 116, "w": 26, "h": 30 } }, - { - "filename": "785", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 3, - "w": 28, - "h": 26 - }, - "frame": { - "x": 109, - "y": 267, - "w": 28, - "h": 26 - } - }, { "filename": "773s-fairy", "rotated": false, @@ -1389,33 +1347,12 @@ "h": 30 }, "frame": { - "x": 134, - "y": 293, + "x": 112, + "y": 146, "w": 26, "h": 30 } }, - { - "filename": "801", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 20, - "h": 28 - }, - "frame": { - "x": 136, - "y": 29, - "w": 20, - "h": 28 - } - }, { "filename": "773s-fighting", "rotated": false, @@ -1431,8 +1368,8 @@ "h": 30 }, "frame": { - "x": 156, - "y": 28, + "x": 138, + "y": 146, "w": 26, "h": 30 } @@ -1452,8 +1389,8 @@ "h": 30 }, "frame": { - "x": 182, - "y": 28, + "x": 112, + "y": 176, "w": 26, "h": 30 } @@ -1473,8 +1410,8 @@ "h": 30 }, "frame": { - "x": 208, - "y": 28, + "x": 138, + "y": 176, "w": 26, "h": 30 } @@ -1494,8 +1431,8 @@ "h": 30 }, "frame": { - "x": 234, - "y": 28, + "x": 111, + "y": 206, "w": 26, "h": 30 } @@ -1515,8 +1452,8 @@ "h": 30 }, "frame": { - "x": 147, - "y": 58, + "x": 137, + "y": 206, "w": 26, "h": 30 } @@ -1536,8 +1473,8 @@ "h": 30 }, "frame": { - "x": 173, - "y": 58, + "x": 111, + "y": 236, "w": 26, "h": 30 } @@ -1557,8 +1494,8 @@ "h": 30 }, "frame": { - "x": 199, - "y": 58, + "x": 137, + "y": 236, "w": 26, "h": 30 } @@ -1578,12 +1515,33 @@ "h": 30 }, "frame": { - "x": 225, - "y": 58, + "x": 109, + "y": 266, "w": 26, "h": 30 } }, + { + "filename": "794", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 1, + "w": 25, + "h": 29 + }, + "frame": { + "x": 109, + "y": 296, + "w": 25, + "h": 29 + } + }, { "filename": "773s-psychic", "rotated": false, @@ -1599,12 +1557,54 @@ "h": 30 }, "frame": { - "x": 140, - "y": 88, + "x": 135, + "y": 266, "w": 26, "h": 30 } }, + { + "filename": "794s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 1, + "w": 25, + "h": 29 + }, + "frame": { + "x": 134, + "y": 296, + "w": 25, + "h": 29 + } + }, + { + "filename": "796", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 1, + "w": 18, + "h": 29 + }, + "frame": { + "x": 159, + "y": 296, + "w": 18, + "h": 29 + } + }, { "filename": "773s-rock", "rotated": false, @@ -1620,12 +1620,54 @@ "h": 30 }, "frame": { - "x": 166, - "y": 88, + "x": 161, + "y": 266, "w": 26, "h": 30 } }, + { + "filename": "796s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 1, + "w": 18, + "h": 29 + }, + "frame": { + "x": 177, + "y": 296, + "w": 18, + "h": 29 + } + }, + { + "filename": "772s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 2, + "w": 25, + "h": 28 + }, + "frame": { + "x": 167, + "y": 28, + "w": 25, + "h": 28 + } + }, { "filename": "773s-steel", "rotated": false, @@ -1642,7 +1684,7 @@ }, "frame": { "x": 192, - "y": 88, + "y": 27, "w": 26, "h": 30 } @@ -1663,13 +1705,13 @@ }, "frame": { "x": 218, - "y": 88, + "y": 27, "w": 26, "h": 30 } }, { - "filename": "764s", + "filename": "773s", "rotated": false, "trimmed": true, "sourceSize": { @@ -1677,123 +1719,18 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, + "x": 7, "y": 0, - "w": 25, + "w": 26, "h": 30 }, "frame": { - "x": 140, - "y": 118, - "w": 25, + "x": 244, + "y": 27, + "w": 26, "h": 30 } }, - { - "filename": "785s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 3, - "w": 28, - "h": 26 - }, - "frame": { - "x": 165, - "y": 118, - "w": 28, - "h": 26 - } - }, - { - "filename": "2075", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 29, - "h": 24 - }, - "frame": { - "x": 193, - "y": 118, - "w": 29, - "h": 24 - } - }, - { - "filename": "794", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 1, - "w": 25, - "h": 29 - }, - "frame": { - "x": 138, - "y": 148, - "w": 25, - "h": 29 - } - }, - { - "filename": "794s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 1, - "w": 25, - "h": 29 - }, - "frame": { - "x": 138, - "y": 177, - "w": 25, - "h": 29 - } - }, - { - "filename": "726", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 222, - "y": 118, - "w": 23, - "h": 24 - } - }, { "filename": "2103", "rotated": false, @@ -1809,12 +1746,75 @@ "h": 30 }, "frame": { - "x": 251, - "y": 58, + "x": 270, + "y": 27, "w": 21, "h": 30 } }, + { + "filename": "2026", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 1, + "w": 26, + "h": 28 + }, + "frame": { + "x": 291, + "y": 23, + "w": 26, + "h": 28 + } + }, + { + "filename": "2026s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 1, + "w": 26, + "h": 28 + }, + "frame": { + "x": 317, + "y": 23, + "w": 26, + "h": 28 + } + }, + { + "filename": "2075", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 29, + "h": 24 + }, + "frame": { + "x": 343, + "y": 25, + "w": 29, + "h": 24 + } + }, { "filename": "2075s", "rotated": false, @@ -1830,180 +1830,12 @@ "h": 24 }, "frame": { - "x": 244, - "y": 88, + "x": 372, + "y": 25, "w": 29, "h": 24 } }, - { - "filename": "748", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 26, - "h": 25 - }, - "frame": { - "x": 245, - "y": 112, - "w": 26, - "h": 25 - } - }, - { - "filename": "2103s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 0, - "w": 21, - "h": 30 - }, - "frame": { - "x": 260, - "y": 28, - "w": 21, - "h": 30 - } - }, - { - "filename": "748s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 26, - "h": 25 - }, - "frame": { - "x": 281, - "y": 27, - "w": 26, - "h": 25 - } - }, - { - "filename": "2089", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 3, - "w": 26, - "h": 25 - }, - "frame": { - "x": 307, - "y": 27, - "w": 26, - "h": 25 - } - }, - { - "filename": "2089s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 3, - "w": 26, - "h": 25 - }, - "frame": { - "x": 333, - "y": 27, - "w": 26, - "h": 25 - } - }, - { - "filename": "724", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 19, - "h": 25 - }, - "frame": { - "x": 359, - "y": 27, - "w": 19, - "h": 25 - } - }, - { - "filename": "745-dusk", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 25, - "h": 25 - }, - "frame": { - "x": 378, - "y": 23, - "w": 25, - "h": 25 - } - }, - { - "filename": "745s-dusk", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 25, - "h": 25 - }, - "frame": { - "x": 403, - "y": 23, - "w": 25, - "h": 25 - } - }, { "filename": "746-school", "rotated": false, @@ -2019,8 +1851,8 @@ "h": 22 }, "frame": { - "x": 428, - "y": 25, + "x": 401, + "y": 26, "w": 28, "h": 22 } @@ -2040,14 +1872,14 @@ "h": 22 }, "frame": { - "x": 456, - "y": 25, + "x": 429, + "y": 26, "w": 28, "h": 22 } }, { - "filename": "796", + "filename": "760", "rotated": false, "trimmed": true, "sourceSize": { @@ -2055,20 +1887,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 1, - "w": 18, - "h": 29 + "x": 13, + "y": 4, + "w": 17, + "h": 24 }, "frame": { - "x": 484, - "y": 25, - "w": 18, - "h": 29 + "x": 175, + "y": 56, + "w": 17, + "h": 24 } }, { - "filename": "796s", + "filename": "748", "rotated": false, "trimmed": true, "sourceSize": { @@ -2076,16 +1908,121 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 1, - "w": 18, - "h": 29 + "x": 7, + "y": 5, + "w": 26, + "h": 25 }, "frame": { - "x": 272, - "y": 58, - "w": 18, - "h": 29 + "x": 192, + "y": 57, + "w": 26, + "h": 25 + } + }, + { + "filename": "748s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 26, + "h": 25 + }, + "frame": { + "x": 218, + "y": 57, + "w": 26, + "h": 25 + } + }, + { + "filename": "2089", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 3, + "w": 26, + "h": 25 + }, + "frame": { + "x": 244, + "y": 57, + "w": 26, + "h": 25 + } + }, + { + "filename": "745-dusk", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 25, + "h": 25 + }, + "frame": { + "x": 270, + "y": 57, + "w": 25, + "h": 25 + } + }, + { + "filename": "2089s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 3, + "w": 26, + "h": 25 + }, + "frame": { + "x": 295, + "y": 51, + "w": 26, + "h": 25 + } + }, + { + "filename": "745s-dusk", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 25, + "h": 25 + }, + "frame": { + "x": 321, + "y": 51, + "w": 25, + "h": 25 } }, { @@ -2103,8 +2040,8 @@ "h": 26 }, "frame": { - "x": 290, - "y": 52, + "x": 346, + "y": 49, "w": 24, "h": 26 } @@ -2124,159 +2061,12 @@ "h": 26 }, "frame": { - "x": 314, - "y": 52, + "x": 370, + "y": 49, "w": 24, "h": 26 } }, - { - "filename": "750", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 25, - "h": 24 - }, - "frame": { - "x": 338, - "y": 52, - "w": 25, - "h": 24 - } - }, - { - "filename": "724s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 19, - "h": 25 - }, - "frame": { - "x": 273, - "y": 87, - "w": 19, - "h": 25 - } - }, - { - "filename": "776", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 23, - "h": 26 - }, - "frame": { - "x": 271, - "y": 112, - "w": 23, - "h": 26 - } - }, - { - "filename": "750s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 25, - "h": 24 - }, - "frame": { - "x": 292, - "y": 78, - "w": 25, - "h": 24 - } - }, - { - "filename": "726s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 317, - "y": 78, - "w": 23, - "h": 24 - } - }, - { - "filename": "776s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 23, - "h": 26 - }, - "frame": { - "x": 340, - "y": 76, - "w": 23, - "h": 26 - } - }, - { - "filename": "801-original", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 20, - "h": 28 - }, - "frame": { - "x": 363, - "y": 52, - "w": 20, - "h": 28 - } - }, { "filename": "765", "rotated": false, @@ -2292,14 +2082,56 @@ "h": 21 }, "frame": { - "x": 383, - "y": 48, + "x": 457, + "y": 28, "w": 28, "h": 21 } }, { - "filename": "727", + "filename": "760s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 4, + "w": 17, + "h": 24 + }, + "frame": { + "x": 485, + "y": 28, + "w": 17, + "h": 24 + } + }, + { + "filename": "2103s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 0, + "w": 21, + "h": 30 + }, + "frame": { + "x": 165, + "y": 86, + "w": 21, + "h": 30 + } + }, + { + "filename": "783", "rotated": false, "trimmed": true, "sourceSize": { @@ -2308,14 +2140,56 @@ }, "spriteSourceSize": { "x": 9, + "y": 3, + "w": 21, + "h": 27 + }, + "frame": { + "x": 165, + "y": 116, + "w": 21, + "h": 27 + } + }, + { + "filename": "750", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, "y": 4, - "w": 23, + "w": 25, "h": 24 }, "frame": { - "x": 363, - "y": 80, - "w": 23, + "x": 186, + "y": 82, + "w": 25, + "h": 24 + } + }, + { + "filename": "750s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 25, + "h": 24 + }, + "frame": { + "x": 211, + "y": 82, + "w": 25, "h": 24 } }, @@ -2334,159 +2208,12 @@ "h": 21 }, "frame": { - "x": 294, - "y": 102, + "x": 186, + "y": 106, "w": 28, "h": 21 } }, - { - "filename": "725", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 25, - "h": 21 - }, - "frame": { - "x": 322, - "y": 102, - "w": 25, - "h": 21 - } - }, - { - "filename": "780", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 27, - "h": 19 - }, - "frame": { - "x": 294, - "y": 123, - "w": 27, - "h": 19 - } - }, - { - "filename": "780s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 27, - "h": 19 - }, - "frame": { - "x": 321, - "y": 123, - "w": 27, - "h": 19 - } - }, - { - "filename": "723", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 17, - "h": 22 - }, - "frame": { - "x": 411, - "y": 48, - "w": 17, - "h": 22 - } - }, - { - "filename": "745", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 23 - }, - "frame": { - "x": 428, - "y": 47, - "w": 25, - "h": 23 - } - }, - { - "filename": "745s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 23 - }, - "frame": { - "x": 453, - "y": 47, - "w": 25, - "h": 23 - } - }, - { - "filename": "768", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 478, - "y": 54, - "w": 24, - "h": 23 - } - }, { "filename": "2028", "rotated": false, @@ -2502,8 +2229,8 @@ "h": 24 }, "frame": { - "x": 386, - "y": 69, + "x": 236, + "y": 82, "w": 25, "h": 24 } @@ -2523,56 +2250,14 @@ "h": 24 }, "frame": { - "x": 411, - "y": 70, + "x": 261, + "y": 82, "w": 25, "h": 24 } }, { - "filename": "727s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 436, - "y": 70, - "w": 23, - "h": 24 - } - }, - { - "filename": "781", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 3, - "w": 19, - "h": 25 - }, - "frame": { - "x": 459, - "y": 70, - "w": 19, - "h": 25 - } - }, - { - "filename": "768s", + "filename": "725", "rotated": false, "trimmed": true, "sourceSize": { @@ -2581,15 +2266,15 @@ }, "spriteSourceSize": { "x": 8, - "y": 5, - "w": 24, - "h": 23 + "y": 7, + "w": 25, + "h": 21 }, "frame": { - "x": 478, - "y": 77, - "w": 24, - "h": 23 + "x": 214, + "y": 106, + "w": 25, + "h": 21 } }, { @@ -2607,14 +2292,14 @@ "h": 21 }, "frame": { - "x": 386, - "y": 93, + "x": 239, + "y": 106, "w": 25, "h": 21 } }, { - "filename": "2020", + "filename": "726", "rotated": false, "trimmed": true, "sourceSize": { @@ -2623,40 +2308,19 @@ }, "spriteSourceSize": { "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 411, - "y": 94, - "w": 25, - "h": 22 - } - }, - { - "filename": "729", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, + "y": 4, "w": 23, "h": 24 }, "frame": { - "x": 436, - "y": 94, + "x": 264, + "y": 106, "w": 23, "h": 24 } }, { - "filename": "781s", + "filename": "780", "rotated": false, "trimmed": true, "sourceSize": { @@ -2664,62 +2328,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 3, - "w": 19, - "h": 25 - }, - "frame": { - "x": 459, - "y": 95, - "w": 19, - "h": 25 - } - }, - { - "filename": "2105", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 478, - "y": 100, - "w": 24, - "h": 23 - } - }, - { - "filename": "761", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 16, + "x": 7, + "y": 7, + "w": 27, "h": 19 }, "frame": { - "x": 347, - "y": 102, - "w": 16, + "x": 186, + "y": 127, + "w": 27, "h": 19 } }, { - "filename": "729s", + "filename": "780s", "rotated": false, "trimmed": true, "sourceSize": { @@ -2727,184 +2349,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 23, - "h": 24 - }, - "frame": { - "x": 363, - "y": 104, - "w": 23, - "h": 24 - } - }, - { - "filename": "734", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 25, - "h": 16 - }, - "frame": { - "x": 386, - "y": 114, - "w": 25, - "h": 16 - } - }, - { - "filename": "734s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 25, - "h": 16 - }, - "frame": { - "x": 411, - "y": 116, - "w": 25, - "h": 16 - } - }, - { - "filename": "733", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, + "x": 7, "y": 7, - "w": 23, - "h": 21 + "w": 27, + "h": 19 }, "frame": { - "x": 436, - "y": 118, - "w": 23, - "h": 21 - } - }, - { - "filename": "732", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 19, - "h": 22 - }, - "frame": { - "x": 459, - "y": 120, - "w": 19, - "h": 22 - } - }, - { - "filename": "2105s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 478, - "y": 123, - "w": 24, - "h": 23 - } - }, - { - "filename": "2050", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 10, - "w": 15, - "h": 18 - }, - "frame": { - "x": 348, - "y": 121, - "w": 15, - "h": 18 - } - }, - { - "filename": "733s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 23, - "h": 21 - }, - "frame": { - "x": 363, - "y": 128, - "w": 23, - "h": 21 - } - }, - { - "filename": "2020s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 386, - "y": 130, - "w": 25, - "h": 22 + "x": 213, + "y": 127, + "w": 27, + "h": 19 } }, { @@ -2922,14 +2376,14 @@ "h": 22 }, "frame": { - "x": 411, - "y": 132, + "x": 240, + "y": 127, "w": 24, "h": 22 } }, { - "filename": "758s", + "filename": "726s", "rotated": false, "trimmed": true, "sourceSize": { @@ -2937,104 +2391,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 24, - "h": 22 + "x": 8, + "y": 4, + "w": 23, + "h": 24 }, "frame": { - "x": 435, - "y": 139, - "w": 24, - "h": 22 + "x": 264, + "y": 130, + "w": 23, + "h": 24 } }, { - "filename": "732s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 19, - "h": 22 - }, - "frame": { - "x": 459, - "y": 142, - "w": 19, - "h": 22 - } - }, - { - "filename": "2053", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 24, - "h": 22 - }, - "frame": { - "x": 478, - "y": 146, - "w": 24, - "h": 22 - } - }, - { - "filename": "801s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 20, - "h": 28 - }, - "frame": { - "x": 135, - "y": 207, - "w": 20, - "h": 28 - } - }, - { - "filename": "801s-original", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 20, - "h": 28 - }, - "frame": { - "x": 135, - "y": 235, - "w": 20, - "h": 28 - } - }, - { - "filename": "783", + "filename": "727", "rotated": false, "trimmed": true, "sourceSize": { @@ -3043,15 +2413,78 @@ }, "spriteSourceSize": { "x": 9, - "y": 3, - "w": 21, - "h": 27 + "y": 4, + "w": 23, + "h": 24 }, "frame": { - "x": 137, - "y": 263, - "w": 21, - "h": 27 + "x": 286, + "y": 82, + "w": 23, + "h": 24 + } + }, + { + "filename": "776", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 23, + "h": 26 + }, + "frame": { + "x": 287, + "y": 106, + "w": 23, + "h": 26 + } + }, + { + "filename": "727s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 287, + "y": 132, + "w": 23, + "h": 24 + } + }, + { + "filename": "776s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 23, + "h": 26 + }, + "frame": { + "x": 309, + "y": 76, + "w": 23, + "h": 26 } }, { @@ -3069,8 +2502,8 @@ "h": 27 }, "frame": { - "x": 155, - "y": 206, + "x": 310, + "y": 102, "w": 21, "h": 27 } @@ -3090,8 +2523,8 @@ "h": 26 }, "frame": { - "x": 155, - "y": 233, + "x": 310, + "y": 129, "w": 22, "h": 26 } @@ -3111,8 +2544,8 @@ "h": 26 }, "frame": { - "x": 158, - "y": 259, + "x": 332, + "y": 76, "w": 22, "h": 26 } @@ -3132,12 +2565,306 @@ "h": 26 }, "frame": { - "x": 160, - "y": 285, + "x": 331, + "y": 102, "w": 22, "h": 26 } }, + { + "filename": "745", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 23 + }, + "frame": { + "x": 354, + "y": 75, + "w": 25, + "h": 23 + } + }, + { + "filename": "788s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 2, + "w": 22, + "h": 26 + }, + "frame": { + "x": 332, + "y": 128, + "w": 22, + "h": 26 + } + }, + { + "filename": "724", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 4, + "w": 19, + "h": 25 + }, + "frame": { + "x": 379, + "y": 75, + "w": 19, + "h": 25 + } + }, + { + "filename": "724s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 4, + "w": 19, + "h": 25 + }, + "frame": { + "x": 394, + "y": 49, + "w": 19, + "h": 25 + } + }, + { + "filename": "745s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 23 + }, + "frame": { + "x": 413, + "y": 48, + "w": 25, + "h": 23 + } + }, + { + "filename": "781", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 3, + "w": 19, + "h": 25 + }, + "frame": { + "x": 438, + "y": 48, + "w": 19, + "h": 25 + } + }, + { + "filename": "729", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 23, + "h": 24 + }, + "frame": { + "x": 457, + "y": 49, + "w": 23, + "h": 24 + } + }, + { + "filename": "806", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 3, + "w": 22, + "h": 25 + }, + "frame": { + "x": 480, + "y": 52, + "w": 22, + "h": 25 + } + }, + { + "filename": "801-original", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 20, + "h": 28 + }, + "frame": { + "x": 398, + "y": 74, + "w": 20, + "h": 28 + } + }, + { + "filename": "801", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 20, + "h": 28 + }, + "frame": { + "x": 418, + "y": 71, + "w": 20, + "h": 28 + } + }, + { + "filename": "803", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 3, + "w": 23, + "h": 25 + }, + "frame": { + "x": 438, + "y": 73, + "w": 23, + "h": 25 + } + }, + { + "filename": "781s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 3, + "w": 19, + "h": 25 + }, + "frame": { + "x": 461, + "y": 73, + "w": 19, + "h": 25 + } + }, + { + "filename": "806s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 3, + "w": 22, + "h": 25 + }, + "frame": { + "x": 480, + "y": 77, + "w": 22, + "h": 25 + } + }, + { + "filename": "734", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 10, + "w": 25, + "h": 16 + }, + "frame": { + "x": 354, + "y": 98, + "w": 25, + "h": 16 + } + }, { "filename": "767", "rotated": false, @@ -3153,14 +2880,35 @@ "h": 14 }, "frame": { - "x": 245, - "y": 137, + "x": 353, + "y": 114, "w": 24, "h": 14 } }, { - "filename": "767s", + "filename": "803s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 3, + "w": 23, + "h": 25 + }, + "frame": { + "x": 354, + "y": 128, + "w": 23, + "h": 25 + } + }, + { + "filename": "732", "rotated": false, "trimmed": true, "sourceSize": { @@ -3169,15 +2917,603 @@ }, "spriteSourceSize": { "x": 10, - "y": 11, - "w": 24, - "h": 14 + "y": 6, + "w": 19, + "h": 22 }, "frame": { - "x": 269, - "y": 138, + "x": 379, + "y": 100, + "w": 19, + "h": 22 + } + }, + { + "filename": "801s-original", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 20, + "h": 28 + }, + "frame": { + "x": 377, + "y": 122, + "w": 20, + "h": 28 + } + }, + { + "filename": "729s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 23, + "h": 24 + }, + "frame": { + "x": 398, + "y": 102, + "w": 23, + "h": 24 + } + }, + { + "filename": "768", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, "w": 24, - "h": 14 + "h": 23 + }, + "frame": { + "x": 397, + "y": 126, + "w": 24, + "h": 23 + } + }, + { + "filename": "801s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 20, + "h": 28 + }, + "frame": { + "x": 421, + "y": 99, + "w": 20, + "h": 28 + } + }, + { + "filename": "768s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 441, + "y": 98, + "w": 24, + "h": 23 + } + }, + { + "filename": "735", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 4, + "w": 20, + "h": 24 + }, + "frame": { + "x": 421, + "y": 127, + "w": 20, + "h": 24 + } + }, + { + "filename": "770", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 441, + "y": 121, + "w": 23, + "h": 24 + } + }, + { + "filename": "2050", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 10, + "w": 15, + "h": 18 + }, + "frame": { + "x": 465, + "y": 98, + "w": 15, + "h": 18 + } + }, + { + "filename": "756", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 22, + "h": 24 + }, + "frame": { + "x": 480, + "y": 102, + "w": 22, + "h": 24 + } + }, + { + "filename": "2050s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 10, + "w": 15, + "h": 18 + }, + "frame": { + "x": 465, + "y": 116, + "w": 15, + "h": 18 + } + }, + { + "filename": "756s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 22, + "h": 24 + }, + "frame": { + "x": 480, + "y": 126, + "w": 22, + "h": 24 + } + }, + { + "filename": "761", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 16, + "h": 19 + }, + "frame": { + "x": 464, + "y": 134, + "w": 16, + "h": 19 + } + }, + { + "filename": "802-zenith", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 4, + "w": 22, + "h": 24 + }, + "frame": { + "x": 480, + "y": 150, + "w": 22, + "h": 24 + } + }, + { + "filename": "733", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 23, + "h": 21 + }, + "frame": { + "x": 441, + "y": 145, + "w": 23, + "h": 21 + } + }, + { + "filename": "761s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 16, + "h": 19 + }, + "frame": { + "x": 464, + "y": 153, + "w": 16, + "h": 19 + } + }, + { + "filename": "745-midnight", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 165, + "y": 143, + "w": 21, + "h": 24 + } + }, + { + "filename": "2020", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 186, + "y": 146, + "w": 25, + "h": 22 + } + }, + { + "filename": "2020s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 211, + "y": 146, + "w": 25, + "h": 22 + } + }, + { + "filename": "802", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 4, + "w": 22, + "h": 24 + }, + "frame": { + "x": 164, + "y": 167, + "w": 22, + "h": 24 + } + }, + { + "filename": "2105", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 186, + "y": 168, + "w": 24, + "h": 23 + } + }, + { + "filename": "2105s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 210, + "y": 168, + "w": 24, + "h": 23 + } + }, + { + "filename": "734s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 10, + "w": 25, + "h": 16 + }, + "frame": { + "x": 164, + "y": 191, + "w": 25, + "h": 16 + } + }, + { + "filename": "770s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 163, + "y": 207, + "w": 23, + "h": 24 + } + }, + { + "filename": "2051", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 163, + "y": 231, + "w": 23, + "h": 24 + } + }, + { + "filename": "758s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 24, + "h": 22 + }, + "frame": { + "x": 189, + "y": 191, + "w": 24, + "h": 22 + } + }, + { + "filename": "2051s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 186, + "y": 213, + "w": 23, + "h": 24 + } + }, + { + "filename": "745s-midnight", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 213, + "y": 191, + "w": 21, + "h": 24 + } + }, + { + "filename": "2053", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 24, + "h": 22 + }, + "frame": { + "x": 209, + "y": 215, + "w": 24, + "h": 22 } }, { @@ -3195,8 +3531,8 @@ "h": 22 }, "frame": { - "x": 293, - "y": 142, + "x": 186, + "y": 237, "w": 24, "h": 22 } @@ -3216,14 +3552,14 @@ "h": 22 }, "frame": { - "x": 317, - "y": 142, + "x": 210, + "y": 237, "w": 23, "h": 22 } }, { - "filename": "769s", + "filename": "802s-zenith", "rotated": false, "trimmed": true, "sourceSize": { @@ -3231,125 +3567,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 340, - "y": 142, - "w": 23, - "h": 22 - } - }, - { - "filename": "752", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 23, - "h": 18 - }, - "frame": { - "x": 363, - "y": 149, - "w": 23, - "h": 18 - } - }, - { - "filename": "2074", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 13, - "w": 24, - "h": 15 - }, - "frame": { - "x": 386, - "y": 152, - "w": 24, - "h": 15 - } - }, - { - "filename": "2074s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 13, - "w": 24, - "h": 15 - }, - "frame": { - "x": 410, - "y": 154, - "w": 24, - "h": 15 - } - }, - { - "filename": "752s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 23, - "h": 18 - }, - "frame": { - "x": 434, - "y": 161, - "w": 23, - "h": 18 - } - }, - { - "filename": "745-midnight", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, + "x": 13, "y": 4, - "w": 21, + "w": 22, "h": 24 }, "frame": { - "x": 457, - "y": 164, - "w": 21, + "x": 187, + "y": 259, + "w": 22, "h": 24 } }, { - "filename": "770", + "filename": "802s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3357,20 +3588,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, + "x": 13, "y": 4, - "w": 23, + "w": 22, "h": 24 }, "frame": { - "x": 478, - "y": 168, - "w": 23, + "x": 209, + "y": 259, + "w": 22, "h": 24 } }, { - "filename": "722", + "filename": "746", "rotated": false, "trimmed": true, "sourceSize": { @@ -3379,19 +3610,40 @@ }, "spriteSourceSize": { "x": 12, - "y": 8, - "w": 17, - "h": 18 + "y": 11, + "w": 18, + "h": 13 }, "frame": { - "x": 163, - "y": 188, - "w": 17, - "h": 18 + "x": 187, + "y": 283, + "w": 18, + "h": 13 } }, { - "filename": "735", + "filename": "733s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 23, + "h": 21 + }, + "frame": { + "x": 236, + "y": 149, + "w": 23, + "h": 21 + } + }, + { + "filename": "807", "rotated": false, "trimmed": true, "sourceSize": { @@ -3401,308 +3653,14 @@ "spriteSourceSize": { "x": 11, "y": 4, - "w": 20, - "h": 24 - }, - "frame": { - "x": 163, - "y": 164, - "w": 20, - "h": 24 - } - }, - { - "filename": "789", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 23, - "h": 20 - }, - "frame": { - "x": 165, - "y": 144, - "w": 23, - "h": 20 - } - }, - { - "filename": "788s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 2, "w": 22, - "h": 26 + "h": 24 }, "frame": { - "x": 176, - "y": 206, + "x": 234, + "y": 170, "w": 22, - "h": 26 - } - }, - { - "filename": "803", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 3, - "w": 23, - "h": 25 - }, - "frame": { - "x": 177, - "y": 232, - "w": 23, - "h": 25 - } - }, - { - "filename": "786", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 3, - "w": 20, - "h": 25 - }, - "frame": { - "x": 180, - "y": 257, - "w": 20, - "h": 25 - } - }, - { - "filename": "786s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 3, - "w": 20, - "h": 25 - }, - "frame": { - "x": 182, - "y": 282, - "w": 20, - "h": 25 - } - }, - { - "filename": "778-busted", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 21, - "h": 16 - }, - "frame": { - "x": 182, - "y": 307, - "w": 21, - "h": 16 - } - }, - { - "filename": "757", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 19, - "h": 18 - }, - "frame": { - "x": 180, - "y": 188, - "w": 19, - "h": 18 - } - }, - { - "filename": "735s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 20, "h": 24 - }, - "frame": { - "x": 183, - "y": 164, - "w": 20, - "h": 24 - } - }, - { - "filename": "728", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 17, - "h": 20 - }, - "frame": { - "x": 188, - "y": 144, - "w": 17, - "h": 20 - } - }, - { - "filename": "770s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 205, - "y": 142, - "w": 23, - "h": 24 - } - }, - { - "filename": "760", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 4, - "w": 17, - "h": 24 - }, - "frame": { - "x": 228, - "y": 142, - "w": 17, - "h": 24 - } - }, - { - "filename": "803s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 3, - "w": 23, - "h": 25 - }, - "frame": { - "x": 203, - "y": 166, - "w": 23, - "h": 25 - } - }, - { - "filename": "806", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 3, - "w": 22, - "h": 25 - }, - "frame": { - "x": 226, - "y": 166, - "w": 22, - "h": 25 - } - }, - { - "filename": "789s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 23, - "h": 20 - }, - "frame": { - "x": 199, - "y": 191, - "w": 23, - "h": 20 } }, { @@ -3720,14 +3678,14 @@ "h": 21 }, "frame": { - "x": 198, - "y": 211, + "x": 234, + "y": 194, "w": 22, "h": 21 } }, { - "filename": "806s", + "filename": "807s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3735,125 +3693,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, - "y": 3, - "w": 22, - "h": 25 - }, - "frame": { - "x": 200, - "y": 232, - "w": 22, - "h": 25 - } - }, - { - "filename": "756", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 22, - "h": 24 - }, - "frame": { - "x": 200, - "y": 257, - "w": 22, - "h": 24 - } - }, - { - "filename": "745s-midnight", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, + "x": 11, "y": 4, - "w": 21, + "w": 22, "h": 24 }, "frame": { - "x": 202, - "y": 281, - "w": 21, - "h": 24 - } - }, - { - "filename": "2027", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 21, - "h": 18 - }, - "frame": { - "x": 203, - "y": 305, - "w": 21, - "h": 18 - } - }, - { - "filename": "2051", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 222, - "y": 191, - "w": 23, - "h": 24 - } - }, - { - "filename": "778s-busted", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 21, - "h": 16 - }, - "frame": { - "x": 220, + "x": 233, "y": 215, - "w": 21, - "h": 16 + "w": 22, + "h": 24 } }, { - "filename": "756s", + "filename": "738s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3862,19 +3715,19 @@ }, "spriteSourceSize": { "x": 9, - "y": 5, + "y": 6, "w": 22, - "h": 24 + "h": 21 }, "frame": { - "x": 222, - "y": 231, + "x": 233, + "y": 239, "w": 22, - "h": 24 + "h": 21 } }, { - "filename": "802", + "filename": "769s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3882,16 +3735,37 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, - "y": 4, - "w": 22, - "h": 24 + "x": 8, + "y": 6, + "w": 23, + "h": 22 }, "frame": { - "x": 222, - "y": 255, - "w": 22, - "h": 24 + "x": 231, + "y": 260, + "w": 23, + "h": 22 + } + }, + { + "filename": "767s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 11, + "w": 24, + "h": 14 + }, + "frame": { + "x": 205, + "y": 283, + "w": 24, + "h": 14 } }, { @@ -3909,8 +3783,71 @@ "h": 24 }, "frame": { - "x": 223, - "y": 279, + "x": 195, + "y": 297, + "w": 21, + "h": 24 + } + }, + { + "filename": "735s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 4, + "w": 20, + "h": 24 + }, + "frame": { + "x": 216, + "y": 297, + "w": 20, + "h": 24 + } + }, + { + "filename": "752", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 23, + "h": 18 + }, + "frame": { + "x": 259, + "y": 154, + "w": 23, + "h": 18 + } + }, + { + "filename": "763s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 256, + "y": 172, "w": 21, "h": 24 } @@ -3930,134 +3867,8 @@ "h": 20 }, "frame": { - "x": 224, - "y": 303, - "w": 22, - "h": 20 - } - }, - { - "filename": "746", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 11, - "w": 18, - "h": 13 - }, - "frame": { - "x": 245, - "y": 151, - "w": 18, - "h": 13 - } - }, - { - "filename": "760s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 4, - "w": 17, - "h": 24 - }, - "frame": { - "x": 248, - "y": 164, - "w": 17, - "h": 24 - } - }, - { - "filename": "2051s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 265, - "y": 152, - "w": 23, - "h": 24 - } - }, - { - "filename": "738s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 265, - "y": 176, - "w": 22, - "h": 21 - } - }, - { - "filename": "743", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 5, - "w": 20, - "h": 22 - }, - "frame": { - "x": 245, - "y": 191, - "w": 20, - "h": 22 - } - }, - { - "filename": "747s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 22, - "h": 20 - }, - "frame": { - "x": 265, - "y": 197, + "x": 256, + "y": 196, "w": 22, "h": 20 } @@ -4077,8 +3888,8 @@ "h": 23 }, "frame": { - "x": 288, - "y": 164, + "x": 255, + "y": 216, "w": 22, "h": 23 } @@ -4098,77 +3909,14 @@ "h": 23 }, "frame": { - "x": 310, - "y": 164, + "x": 255, + "y": 239, "w": 22, "h": 23 } }, { - "filename": "802s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 4, - "w": 22, - "h": 24 - }, - "frame": { - "x": 287, - "y": 187, - "w": 22, - "h": 24 - } - }, - { - "filename": "807", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 22, - "h": 24 - }, - "frame": { - "x": 309, - "y": 187, - "w": 22, - "h": 24 - } - }, - { - "filename": "807s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 4, - "w": 22, - "h": 24 - }, - "frame": { - "x": 332, - "y": 164, - "w": 22, - "h": 24 - } - }, - { - "filename": "749", + "filename": "789", "rotated": false, "trimmed": true, "sourceSize": { @@ -4177,19 +3925,61 @@ }, "spriteSourceSize": { "x": 10, + "y": 6, + "w": 23, + "h": 20 + }, + "frame": { + "x": 254, + "y": 262, + "w": 23, + "h": 20 + } + }, + { + "filename": "752s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 23, + "h": 18 + }, + "frame": { + "x": 282, + "y": 156, + "w": 23, + "h": 18 + } + }, + { + "filename": "743", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, "y": 5, - "w": 21, - "h": 23 + "w": 20, + "h": 22 }, "frame": { - "x": 331, - "y": 188, - "w": 21, - "h": 23 + "x": 277, + "y": 174, + "w": 20, + "h": 22 } }, { - "filename": "2037", + "filename": "732s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4198,61 +3988,19 @@ }, "spriteSourceSize": { "x": 10, - "y": 7, - "w": 22, - "h": 21 + "y": 6, + "w": 19, + "h": 22 }, "frame": { - "x": 354, - "y": 167, - "w": 22, - "h": 21 + "x": 278, + "y": 196, + "w": 19, + "h": 22 } }, { - "filename": "749s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 352, - "y": 188, - "w": 21, - "h": 23 - } - }, - { - "filename": "2037s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 22, - "h": 21 - }, - "frame": { - "x": 376, - "y": 167, - "w": 22, - "h": 21 - } - }, - { - "filename": "763s", + "filename": "786", "rotated": false, "trimmed": true, "sourceSize": { @@ -4261,15 +4009,57 @@ }, "spriteSourceSize": { "x": 11, - "y": 4, - "w": 21, - "h": 24 + "y": 3, + "w": 20, + "h": 25 }, "frame": { - "x": 373, - "y": 188, - "w": 21, - "h": 24 + "x": 277, + "y": 218, + "w": 20, + "h": 25 + } + }, + { + "filename": "786s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 3, + "w": 20, + "h": 25 + }, + "frame": { + "x": 277, + "y": 243, + "w": 20, + "h": 25 + } + }, + { + "filename": "739", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 20, + "h": 21 + }, + "frame": { + "x": 277, + "y": 268, + "w": 20, + "h": 21 } }, { @@ -4287,54 +4077,12 @@ "h": 24 }, "frame": { - "x": 394, - "y": 188, + "x": 297, + "y": 174, "w": 13, "h": 24 } }, - { - "filename": "790", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 21, - "h": 19 - }, - "frame": { - "x": 398, - "y": 169, - "w": 21, - "h": 19 - } - }, - { - "filename": "2050s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 10, - "w": 15, - "h": 18 - }, - "frame": { - "x": 419, - "y": 169, - "w": 15, - "h": 18 - } - }, { "filename": "755s", "rotated": false, @@ -4350,8 +4098,8 @@ "h": 24 }, "frame": { - "x": 407, - "y": 188, + "x": 297, + "y": 198, "w": 13, "h": 24 } @@ -4371,180 +4119,12 @@ "h": 24 }, "frame": { - "x": 420, - "y": 187, + "x": 297, + "y": 222, "w": 21, "h": 24 } }, - { - "filename": "761s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 16, - "h": 19 - }, - "frame": { - "x": 441, - "y": 179, - "w": 16, - "h": 19 - } - }, - { - "filename": "775", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 21, - "h": 20 - }, - "frame": { - "x": 457, - "y": 188, - "w": 21, - "h": 20 - } - }, - { - "filename": "775s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 21, - "h": 20 - }, - "frame": { - "x": 478, - "y": 192, - "w": 21, - "h": 20 - } - }, - { - "filename": "751", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 14, - "h": 20 - }, - "frame": { - "x": 441, - "y": 198, - "w": 14, - "h": 20 - } - }, - { - "filename": "779", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 21, - "h": 20 - }, - "frame": { - "x": 420, - "y": 211, - "w": 21, - "h": 20 - } - }, - { - "filename": "779s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 21, - "h": 20 - }, - "frame": { - "x": 455, - "y": 208, - "w": 21, - "h": 20 - } - }, - { - "filename": "751s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 14, - "h": 20 - }, - "frame": { - "x": 441, - "y": 218, - "w": 14, - "h": 20 - } - }, - { - "filename": "790s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 21, - "h": 19 - }, - "frame": { - "x": 476, - "y": 212, - "w": 21, - "h": 19 - } - }, { "filename": "793s", "rotated": false, @@ -4560,14 +4140,161 @@ "h": 24 }, "frame": { - "x": 455, - "y": 228, + "x": 297, + "y": 246, "w": 21, "h": 24 } }, { - "filename": "2019", + "filename": "747s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 22, + "h": 20 + }, + "frame": { + "x": 297, + "y": 270, + "w": 22, + "h": 20 + } + }, + { + "filename": "2074", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 13, + "w": 24, + "h": 15 + }, + "frame": { + "x": 231, + "y": 282, + "w": 24, + "h": 15 + } + }, + { + "filename": "2037", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 22, + "h": 21 + }, + "frame": { + "x": 255, + "y": 282, + "w": 22, + "h": 21 + } + }, + { + "filename": "744", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 19, + "h": 22 + }, + "frame": { + "x": 236, + "y": 297, + "w": 19, + "h": 22 + } + }, + { + "filename": "743s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 5, + "w": 20, + "h": 22 + }, + "frame": { + "x": 255, + "y": 303, + "w": 20, + "h": 22 + } + }, + { + "filename": "754", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 20, + "h": 22 + }, + "frame": { + "x": 275, + "y": 303, + "w": 20, + "h": 22 + } + }, + { + "filename": "746s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 11, + "w": 18, + "h": 13 + }, + "frame": { + "x": 277, + "y": 290, + "w": 18, + "h": 13 + } + }, + { + "filename": "749", "rotated": false, "trimmed": true, "sourceSize": { @@ -4578,17 +4305,101 @@ "x": 10, "y": 5, "w": 21, - "h": 21 + "h": 23 }, "frame": { - "x": 476, - "y": 231, + "x": 295, + "y": 290, "w": 21, - "h": 21 + "h": 23 } }, { - "filename": "2019s", + "filename": "722", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 17, + "h": 18 + }, + "frame": { + "x": 305, + "y": 156, + "w": 17, + "h": 18 + } + }, + { + "filename": "741-sensu", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 310, + "y": 174, + "w": 17, + "h": 23 + } + }, + { + "filename": "741s-sensu", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 310, + "y": 197, + "w": 17, + "h": 23 + } + }, + { + "filename": "737", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 18, + "h": 19 + }, + "frame": { + "x": 322, + "y": 155, + "w": 18, + "h": 19 + } + }, + { + "filename": "749s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4599,55 +4410,13 @@ "x": 10, "y": 5, "w": 21, - "h": 21 + "h": 23 }, "frame": { - "x": 287, - "y": 211, + "x": 327, + "y": 174, "w": 21, - "h": 21 - } - }, - { - "filename": "2052", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 21, - "h": 21 - }, - "frame": { - "x": 308, - "y": 211, - "w": 21, - "h": 21 - } - }, - { - "filename": "2052s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 21, - "h": 21 - }, - "frame": { - "x": 329, - "y": 211, - "w": 21, - "h": 21 + "h": 23 } }, { @@ -4665,8 +4434,8 @@ "h": 23 }, "frame": { - "x": 350, - "y": 211, + "x": 327, + "y": 197, "w": 21, "h": 23 } @@ -4686,75 +4455,12 @@ "h": 23 }, "frame": { - "x": 371, - "y": 212, + "x": 318, + "y": 220, "w": 21, "h": 23 } }, - { - "filename": "743s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 5, - "w": 20, - "h": 22 - }, - "frame": { - "x": 392, - "y": 212, - "w": 20, - "h": 22 - } - }, - { - "filename": "739", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 20, - "h": 21 - }, - "frame": { - "x": 245, - "y": 213, - "w": 20, - "h": 21 - } - }, - { - "filename": "754", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 20, - "h": 22 - }, - "frame": { - "x": 244, - "y": 234, - "w": 20, - "h": 22 - } - }, { "filename": "754s", "rotated": false, @@ -4770,12 +4476,33 @@ "h": 22 }, "frame": { - "x": 244, - "y": 256, + "x": 318, + "y": 243, "w": 20, "h": 22 } }, + { + "filename": "728", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 17, + "h": 20 + }, + "frame": { + "x": 340, + "y": 154, + "w": 17, + "h": 20 + } + }, { "filename": "739s", "rotated": false, @@ -4791,14 +4518,14 @@ "h": 21 }, "frame": { - "x": 244, - "y": 278, + "x": 357, + "y": 153, "w": 20, "h": 21 } }, { - "filename": "2027s", + "filename": "789s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4807,19 +4534,19 @@ }, "spriteSourceSize": { "x": 10, - "y": 10, - "w": 21, - "h": 18 + "y": 6, + "w": 23, + "h": 20 }, "frame": { - "x": 265, - "y": 217, - "w": 21, - "h": 18 + "x": 348, + "y": 174, + "w": 23, + "h": 20 } }, { - "filename": "744", + "filename": "2037s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4827,16 +4554,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 19, - "h": 22 + "x": 10, + "y": 7, + "w": 22, + "h": 21 }, "frame": { - "x": 264, - "y": 235, - "w": 19, - "h": 22 + "x": 348, + "y": 194, + "w": 22, + "h": 21 } }, { @@ -4854,33 +4581,12 @@ "h": 22 }, "frame": { - "x": 264, - "y": 257, + "x": 377, + "y": 150, "w": 19, "h": 22 } }, - { - "filename": "741-pompom", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 20, - "h": 20 - }, - "frame": { - "x": 264, - "y": 279, - "w": 20, - "h": 20 - } - }, { "filename": "762", "rotated": false, @@ -4896,8 +4602,8 @@ "h": 23 }, "frame": { - "x": 246, - "y": 299, + "x": 319, + "y": 265, "w": 18, "h": 23 } @@ -4917,54 +4623,12 @@ "h": 23 }, "frame": { - "x": 264, - "y": 299, + "x": 339, + "y": 220, "w": 18, "h": 23 } }, - { - "filename": "741-sensu", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 283, - "y": 235, - "w": 17, - "h": 23 - } - }, - { - "filename": "728s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 17, - "h": 20 - }, - "frame": { - "x": 283, - "y": 258, - "w": 17, - "h": 20 - } - }, { "filename": "741-pau", "rotated": false, @@ -4980,8 +4644,8 @@ "h": 22 }, "frame": { - "x": 300, - "y": 232, + "x": 338, + "y": 243, "w": 18, "h": 22 } @@ -5001,35 +4665,14 @@ "h": 22 }, "frame": { - "x": 318, - "y": 232, + "x": 337, + "y": 265, "w": 18, "h": 22 } }, { - "filename": "741s-pompom", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 20, - "h": 20 - }, - "frame": { - "x": 300, - "y": 254, - "w": 20, - "h": 20 - } - }, - { - "filename": "723s", + "filename": "723", "rotated": false, "trimmed": true, "sourceSize": { @@ -5043,14 +4686,14 @@ "h": 22 }, "frame": { - "x": 284, - "y": 278, + "x": 357, + "y": 215, "w": 17, "h": 22 } }, { - "filename": "741s-sensu", + "filename": "2074s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5058,20 +4701,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, - "y": 5, - "w": 17, - "h": 23 + "x": 8, + "y": 13, + "w": 24, + "h": 15 }, "frame": { - "x": 282, - "y": 300, - "w": 17, - "h": 23 + "x": 397, + "y": 149, + "w": 24, + "h": 15 } }, { - "filename": "731", + "filename": "741-pompom", "rotated": false, "trimmed": true, "sourceSize": { @@ -5079,16 +4722,37 @@ "h": 30 }, "spriteSourceSize": { - "x": 12, + "x": 10, + "y": 7, + "w": 20, + "h": 20 + }, + "frame": { + "x": 421, + "y": 151, + "w": 20, + "h": 20 + } + }, + { + "filename": "775", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, "y": 6, - "w": 17, - "h": 22 + "w": 21, + "h": 20 }, "frame": { - "x": 320, - "y": 254, - "w": 17, - "h": 22 + "x": 396, + "y": 164, + "w": 21, + "h": 20 } }, { @@ -5106,14 +4770,119 @@ "h": 20 }, "frame": { - "x": 301, - "y": 274, + "x": 377, + "y": 172, "w": 19, "h": 20 } }, { - "filename": "722s", + "filename": "775s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 21, + "h": 20 + }, + "frame": { + "x": 417, + "y": 171, + "w": 21, + "h": 20 + } + }, + { + "filename": "778-busted", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 21, + "h": 16 + }, + "frame": { + "x": 396, + "y": 184, + "w": 21, + "h": 16 + } + }, + { + "filename": "778s-busted", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 21, + "h": 16 + }, + "frame": { + "x": 417, + "y": 191, + "w": 21, + "h": 16 + } + }, + { + "filename": "779", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 21, + "h": 20 + }, + "frame": { + "x": 441, + "y": 166, + "w": 21, + "h": 20 + } + }, + { + "filename": "2019", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 5, + "w": 21, + "h": 21 + }, + "frame": { + "x": 438, + "y": 186, + "w": 21, + "h": 21 + } + }, + { + "filename": "737s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5123,18 +4892,18 @@ "spriteSourceSize": { "x": 12, "y": 8, - "w": 17, - "h": 18 + "w": 18, + "h": 19 }, "frame": { - "x": 320, - "y": 276, - "w": 17, - "h": 18 + "x": 462, + "y": 172, + "w": 18, + "h": 19 } }, { - "filename": "753", + "filename": "779s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5142,20 +4911,125 @@ "h": 30 }, "spriteSourceSize": { - "x": 14, - "y": 8, - "w": 14, + "x": 10, + "y": 7, + "w": 21, + "h": 20 + }, + "frame": { + "x": 480, + "y": 174, + "w": 21, + "h": 20 + } + }, + { + "filename": "790", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 21, "h": 19 }, "frame": { - "x": 336, - "y": 232, - "w": 14, + "x": 459, + "y": 191, + "w": 21, "h": 19 } }, { - "filename": "2088", + "filename": "790s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 21, + "h": 19 + }, + "frame": { + "x": 480, + "y": 194, + "w": 21, + "h": 19 + } + }, + { + "filename": "2019s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 5, + "w": 21, + "h": 21 + }, + "frame": { + "x": 370, + "y": 194, + "w": 21, + "h": 21 + } + }, + { + "filename": "723s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 374, + "y": 215, + "w": 17, + "h": 22 + } + }, + { + "filename": "2052", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 21, + "h": 21 + }, + "frame": { + "x": 391, + "y": 200, + "w": 21, + "h": 21 + } + }, + { + "filename": "2027", "rotated": false, "trimmed": true, "sourceSize": { @@ -5169,14 +5043,56 @@ "h": 18 }, "frame": { - "x": 350, - "y": 234, + "x": 391, + "y": 221, "w": 21, "h": 18 } }, { - "filename": "2088s", + "filename": "2052s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 21, + "h": 21 + }, + "frame": { + "x": 412, + "y": 207, + "w": 21, + "h": 21 + } + }, + { + "filename": "741s-pompom", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 20, + "h": 20 + }, + "frame": { + "x": 433, + "y": 207, + "w": 20, + "h": 20 + } + }, + { + "filename": "2027s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5190,8 +5106,8 @@ "h": 18 }, "frame": { - "x": 371, - "y": 235, + "x": 412, + "y": 228, "w": 21, "h": 18 } @@ -5211,12 +5127,75 @@ "h": 20 }, "frame": { - "x": 392, - "y": 234, + "x": 433, + "y": 227, "w": 19, "h": 20 } }, + { + "filename": "2088", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 10, + "w": 21, + "h": 18 + }, + "frame": { + "x": 453, + "y": 210, + "w": 21, + "h": 18 + } + }, + { + "filename": "2088s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 10, + "w": 21, + "h": 18 + }, + "frame": { + "x": 452, + "y": 228, + "w": 21, + "h": 18 + } + }, + { + "filename": "757", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 9, + "w": 19, + "h": 18 + }, + "frame": { + "x": 474, + "y": 213, + "w": 19, + "h": 18 + } + }, { "filename": "757s", "rotated": false, @@ -5232,12 +5211,54 @@ "h": 18 }, "frame": { - "x": 301, - "y": 294, + "x": 473, + "y": 231, "w": 19, "h": 18 } }, + { + "filename": "731", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 17, + "h": 22 + }, + "frame": { + "x": 316, + "y": 290, + "w": 17, + "h": 22 + } + }, + { + "filename": "771", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 11, + "w": 18, + "h": 13 + }, + "frame": { + "x": 316, + "y": 312, + "w": 18, + "h": 13 + } + }, { "filename": "731s", "rotated": false, @@ -5253,12 +5274,33 @@ "h": 22 }, "frame": { - "x": 320, - "y": 294, + "x": 333, + "y": 288, "w": 17, "h": 22 } }, + { + "filename": "736", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 12, + "w": 17, + "h": 13 + }, + "frame": { + "x": 334, + "y": 310, + "w": 17, + "h": 13 + } + }, { "filename": "778-disguised", "rotated": false, @@ -5274,8 +5316,8 @@ "h": 22 }, "frame": { - "x": 337, - "y": 252, + "x": 350, + "y": 287, "w": 17, "h": 22 } @@ -5295,54 +5337,12 @@ "h": 22 }, "frame": { - "x": 354, - "y": 252, + "x": 355, + "y": 265, "w": 17, "h": 22 } }, - { - "filename": "737", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 18, - "h": 19 - }, - "frame": { - "x": 337, - "y": 274, - "w": 18, - "h": 19 - } - }, - { - "filename": "737s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 18, - "h": 19 - }, - "frame": { - "x": 371, - "y": 253, - "w": 18, - "h": 19 - } - }, { "filename": "741", "rotated": false, @@ -5358,12 +5358,96 @@ "h": 19 }, "frame": { - "x": 337, - "y": 293, + "x": 356, + "y": 246, "w": 17, "h": 19 } }, + { + "filename": "728s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 17, + "h": 20 + }, + "frame": { + "x": 373, + "y": 237, + "w": 17, + "h": 20 + } + }, + { + "filename": "722s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 17, + "h": 18 + }, + "frame": { + "x": 390, + "y": 239, + "w": 17, + "h": 18 + } + }, + { + "filename": "736s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 12, + "w": 17, + "h": 13 + }, + "frame": { + "x": 351, + "y": 309, + "w": 17, + "h": 13 + } + }, + { + "filename": "771s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 11, + "w": 18, + "h": 13 + }, + "frame": { + "x": 373, + "y": 257, + "w": 18, + "h": 13 + } + }, { "filename": "741s", "rotated": false, @@ -5379,8 +5463,8 @@ "h": 19 }, "frame": { - "x": 355, - "y": 274, + "x": 372, + "y": 270, "w": 17, "h": 19 } @@ -5400,12 +5484,33 @@ "h": 19 }, "frame": { - "x": 354, - "y": 293, + "x": 367, + "y": 289, "w": 17, "h": 19 } }, + { + "filename": "808", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 11, + "w": 17, + "h": 17 + }, + "frame": { + "x": 368, + "y": 308, + "w": 17, + "h": 17 + } + }, { "filename": "759s", "rotated": false, @@ -5421,96 +5526,12 @@ "h": 19 }, "frame": { - "x": 372, - "y": 272, + "x": 391, + "y": 257, "w": 17, "h": 19 } }, - { - "filename": "777", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 17, - "h": 19 - }, - "frame": { - "x": 389, - "y": 254, - "w": 17, - "h": 19 - } - }, - { - "filename": "774", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 17, - "h": 18 - }, - "frame": { - "x": 389, - "y": 273, - "w": 17, - "h": 18 - } - }, - { - "filename": "774s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 17, - "h": 18 - }, - "frame": { - "x": 389, - "y": 273, - "w": 17, - "h": 18 - } - }, - { - "filename": "753s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 8, - "w": 14, - "h": 19 - }, - "frame": { - "x": 406, - "y": 254, - "w": 14, - "h": 19 - } - }, { "filename": "774-blue", "rotated": false, @@ -5526,35 +5547,14 @@ "h": 18 }, "frame": { - "x": 406, - "y": 273, + "x": 389, + "y": 276, "w": 17, "h": 18 } }, { - "filename": "746s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 11, - "w": 18, - "h": 13 - }, - "frame": { - "x": 423, - "y": 231, - "w": 18, - "h": 13 - } - }, - { - "filename": "777s", + "filename": "777", "rotated": false, "trimmed": true, "sourceSize": { @@ -5568,54 +5568,12 @@ "h": 19 }, "frame": { - "x": 420, - "y": 244, + "x": 408, + "y": 246, "w": 17, "h": 19 } }, - { - "filename": "771", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 11, - "w": 18, - "h": 13 - }, - "frame": { - "x": 437, - "y": 244, - "w": 18, - "h": 13 - } - }, - { - "filename": "771s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 11, - "w": 18, - "h": 13 - }, - "frame": { - "x": 437, - "y": 257, - "w": 18, - "h": 13 - } - }, { "filename": "774-green", "rotated": false, @@ -5631,12 +5589,33 @@ "h": 18 }, "frame": { - "x": 455, - "y": 252, + "x": 408, + "y": 265, "w": 17, "h": 18 } }, + { + "filename": "777s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 17, + "h": 19 + }, + "frame": { + "x": 425, + "y": 247, + "w": 17, + "h": 19 + } + }, { "filename": "774-indigo", "rotated": false, @@ -5652,14 +5631,14 @@ "h": 18 }, "frame": { - "x": 472, - "y": 252, + "x": 425, + "y": 266, "w": 17, "h": 18 } }, { - "filename": "736", + "filename": "751", "rotated": false, "trimmed": true, "sourceSize": { @@ -5667,37 +5646,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 12, - "y": 12, - "w": 17, - "h": 13 + "x": 13, + "y": 8, + "w": 14, + "h": 20 }, "frame": { - "x": 372, - "y": 291, - "w": 17, - "h": 13 - } - }, - { - "filename": "736s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 12, - "w": 17, - "h": 13 - }, - "frame": { - "x": 389, - "y": 291, - "w": 17, - "h": 13 + "x": 442, + "y": 247, + "w": 14, + "h": 20 } }, { @@ -5715,8 +5673,8 @@ "h": 18 }, "frame": { - "x": 406, - "y": 291, + "x": 456, + "y": 246, "w": 17, "h": 18 } @@ -5736,12 +5694,33 @@ "h": 18 }, "frame": { - "x": 371, - "y": 304, + "x": 473, + "y": 249, "w": 17, "h": 18 } }, + { + "filename": "751s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 14, + "h": 20 + }, + "frame": { + "x": 442, + "y": 267, + "w": 14, + "h": 20 + } + }, { "filename": "774-violet", "rotated": false, @@ -5757,8 +5736,8 @@ "h": 18 }, "frame": { - "x": 388, - "y": 304, + "x": 456, + "y": 264, "w": 17, "h": 18 } @@ -5778,8 +5757,29 @@ "h": 18 }, "frame": { - "x": 423, - "y": 270, + "x": 473, + "y": 267, + "w": 17, + "h": 18 + } + }, + { + "filename": "774", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 8, + "w": 17, + "h": 18 + }, + "frame": { + "x": 406, + "y": 283, "w": 17, "h": 18 } @@ -5800,32 +5800,11 @@ }, "frame": { "x": 423, - "y": 288, + "y": 284, "w": 17, "h": 18 } }, - { - "filename": "808", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 11, - "w": 17, - "h": 17 - }, - "frame": { - "x": 423, - "y": 306, - "w": 17, - "h": 17 - } - }, { "filename": "774s-green", "rotated": false, @@ -5842,11 +5821,32 @@ }, "frame": { "x": 440, - "y": 270, + "y": 287, "w": 17, "h": 18 } }, + { + "filename": "753", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 8, + "w": 14, + "h": 19 + }, + "frame": { + "x": 457, + "y": 282, + "w": 14, + "h": 19 + } + }, { "filename": "774s-indigo", "rotated": false, @@ -5862,14 +5862,14 @@ "h": 18 }, "frame": { - "x": 440, - "y": 288, + "x": 471, + "y": 285, "w": 17, "h": 18 } }, { - "filename": "808s", + "filename": "753s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5877,16 +5877,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 12, - "y": 11, - "w": 17, - "h": 17 + "x": 14, + "y": 8, + "w": 14, + "h": 19 }, "frame": { - "x": 440, - "y": 306, - "w": 17, - "h": 17 + "x": 488, + "y": 285, + "w": 14, + "h": 19 } }, { @@ -5904,8 +5904,8 @@ "h": 18 }, "frame": { - "x": 457, - "y": 270, + "x": 385, + "y": 294, "w": 17, "h": 18 } @@ -5925,8 +5925,8 @@ "h": 18 }, "frame": { - "x": 457, - "y": 288, + "x": 402, + "y": 301, "w": 17, "h": 18 } @@ -5946,8 +5946,8 @@ "h": 18 }, "frame": { - "x": 474, - "y": 270, + "x": 419, + "y": 302, "w": 17, "h": 18 } @@ -5967,11 +5967,53 @@ "h": 18 }, "frame": { - "x": 474, - "y": 288, + "x": 436, + "y": 305, "w": 17, "h": 18 } + }, + { + "filename": "774s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 8, + "w": 17, + "h": 18 + }, + "frame": { + "x": 453, + "y": 305, + "w": 17, + "h": 18 + } + }, + { + "filename": "808s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 11, + "w": 17, + "h": 17 + }, + "frame": { + "x": 470, + "y": 303, + "w": 17, + "h": 17 + } } ] } @@ -5979,6 +6021,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:a4de8d1c4f7d4f58c929b8b5479e03f1:3c8ac308e19a7f9420a4df8a78188490:2e7c5873ead8fd8fce82a0b3fcc86b42$" + "smartupdate": "$TexturePacker:SmartUpdate:5861cb99c3db0943f1ccef3b0e1b4683:26656a692718930d92be5b6aba391ced:2e7c5873ead8fd8fce82a0b3fcc86b42$" } } diff --git a/public/images/pokemon_icons_7.png b/public/images/pokemon_icons_7.png index c9a396ed5c60981ba160c14a52f169a6257bb2a5..5e6421360fdbbcfce36acf687bd3395ea46656c1 100644 GIT binary patch literal 51451 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 Date: Sun, 16 Feb 2025 05:34:10 +0100 Subject: [PATCH 08/15] [Bug][UI/UX] Setting proper labels in cost reduction dropdown filter #5316 --- src/ui/pokedex-ui-handler.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ui/pokedex-ui-handler.ts b/src/ui/pokedex-ui-handler.ts index 9b54266b3ca..5180d7bd956 100644 --- a/src/ui/pokedex-ui-handler.ts +++ b/src/ui/pokedex-ui-handler.ts @@ -336,6 +336,8 @@ export default class PokedexUiHandler extends MessageUiHandler { const costReductionLabels = [ new DropDownLabel(i18next.t("filterBar:costReduction"), undefined, DropDownState.OFF), new DropDownLabel(i18next.t("filterBar:costReductionUnlocked"), undefined, DropDownState.ON), + new DropDownLabel(i18next.t("filterBar:costReductionUnlockedOne"), undefined, DropDownState.ONE), + new DropDownLabel(i18next.t("filterBar:costReductionUnlockedTwo"), undefined, DropDownState.TWO), new DropDownLabel(i18next.t("filterBar:costReductionUnlockable"), undefined, DropDownState.UNLOCKABLE), new DropDownLabel(i18next.t("filterBar:costReductionLocked"), undefined, DropDownState.EXCLUDE), ]; From ef11527b9acc12a49f679873d1cf40e5020f463b Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Sun, 16 Feb 2025 16:07:07 -0500 Subject: [PATCH 09/15] Remove outdated Victini check for monogen challenge (#5309) --- src/data/challenge.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 10fb9c55d3d..b6d123ce933 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -456,8 +456,8 @@ export class SingleGenerationChallenge extends Challenge { } applyPokemonInBattle(pokemon: Pokemon, valid: Utils.BooleanHolder): boolean { - const baseGeneration = pokemon.species.speciesId === Species.VICTINI ? 5 : getPokemonSpecies(pokemon.species.speciesId).generation; - const fusionGeneration = pokemon.isFusion() ? pokemon.fusionSpecies?.speciesId === Species.VICTINI ? 5 : getPokemonSpecies(pokemon.fusionSpecies!.speciesId).generation : 0; // TODO: is the bang on fusionSpecies correct? + const baseGeneration = getPokemonSpecies(pokemon.species.speciesId).generation; + const fusionGeneration = pokemon.isFusion() ? getPokemonSpecies(pokemon.fusionSpecies!.speciesId).generation : 0; // TODO: is the bang on fusionSpecies correct? if (pokemon.isPlayer() && (baseGeneration !== this.value || (pokemon.isFusion() && fusionGeneration !== this.value))) { valid.value = false; return true; From 4bc617bd5fbb5a3ba57336ffb2d996963b4e8771 Mon Sep 17 00:00:00 2001 From: Kenneth West <45572572+KennethWest@users.noreply.github.com> Date: Sun, 16 Feb 2025 16:18:19 -0500 Subject: [PATCH 10/15] Fix [BUG] #5081 Wrong visual text when using priority moves on Psychic Terrain (#5091) * Fix [BUG] #5081 Wrong visual text when using priority moves on Psychic Terrain * Apply suggestions from code review for global scene change --- src/phases/move-phase.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 9d32189edb5..73468dc1690 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -354,7 +354,7 @@ export class MovePhase extends BattlePhase { if (failureMessage) { failedText = failureMessage; } else if (failedDueToTerrain) { - failedText = getTerrainBlockMessage(this.pokemon, globalScene.arena.getTerrainType()); + failedText = getTerrainBlockMessage(targets[0], globalScene.arena.getTerrainType()); } this.showFailedText(failedText); From 90d32b886c772107b79945c513a0b603bcd824a5 Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Mon, 17 Feb 2025 08:20:50 +1100 Subject: [PATCH 11/15] [Feature] Tera Rework (#5233) * Commit old stashed changes * Complete basic implementation of Tera * Fix effectiveness test * Make tera retain until forced recall or faint, regain on biome change * Experimental sparkle fix * Fix champion teras * Attempted fix for double battles tera UI bug * Fix the fix * Fix linting and test issues * Fix more tests * Change int type * Implement tera for ME trainers * Cleanup species inclusivity check * Make tera instant recharge if terapagos in party * Make useless tera shards not generate * Implement stellar tera damage boost * Improve tera selection UI * Tidy up animation and localisation * Improve tera button sprite * Fix Lance tera * Make tera instant recharge during E4 in classic modes. * Fix formatting in the tera common animation The animation was also not playing due to `frameTimedEvents` being missing as well. * Make tera effect start after animation * Implement save migration * Update version number for migration code --------- Co-authored-by: Madmadness65 Co-authored-by: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> --- public/battle-anims/common-terastallize.json | 774 ++++++++++++++++++ public/images/battle_anims/terastallize.png | Bin 0 -> 2092 bytes public/images/ui/button_tera.json | 158 ++++ public/images/ui/button_tera.png | Bin 0 -> 6700 bytes public/images/ui/legacy/button_tera.json | 158 ++++ public/images/ui/legacy/button_tera.png | Bin 0 -> 6700 bytes src/battle-scene.ts | 25 +- src/battle.ts | 2 + src/data/ability.ts | 48 +- src/data/battle-anims.ts | 1 + src/data/battler-tags.ts | 2 +- src/data/move.ts | 66 +- .../global-trade-system-encounter.ts | 4 +- .../the-expert-pokemon-breeder-encounter.ts | 9 +- .../utils/encounter-phase-utils.ts | 10 + .../encounter-transformation-sequence.ts | 2 +- src/data/pokemon-forms.ts | 45 +- src/data/trainer-config.ts | 252 +++--- src/field/arena.ts | 2 + src/field/pokemon-sprite-sparkle-handler.ts | 3 + src/field/pokemon.ts | 109 ++- src/field/trainer.ts | 20 +- src/loading-scene.ts | 1 + src/modifier/modifier-type.ts | 79 +- src/modifier/modifier.ts | 104 +-- src/phases/command-phase.ts | 3 + src/phases/enemy-command-phase.ts | 4 + src/phases/evolution-phase.ts | 2 +- src/phases/faint-phase.ts | 2 + src/phases/move-effect-phase.ts | 6 + src/phases/party-heal-phase.ts | 1 + src/phases/quiet-form-change-phase.ts | 8 +- src/phases/tera-phase.ts | 51 ++ src/phases/turn-start-phase.ts | 15 + src/pipelines/sprite.ts | 2 +- src/system/arena-data.ts | 2 + src/system/game-data.ts | 2 + src/system/pokemon-data.ts | 9 + .../version_migration/version_converter.ts | 15 + .../version_migration/versions/v1_7_0.ts | 49 ++ src/test/abilities/libero.test.ts | 4 +- src/test/abilities/protean.test.ts | 4 +- src/test/moves/effectiveness.test.ts | 9 +- src/test/moves/freeze_dry.test.ts | 10 +- src/test/moves/tar_shot.test.ts | 7 +- src/test/moves/tera_blast.test.ts | 27 +- src/test/moves/tera_starstorm.test.ts | 11 +- src/ui/battle-info.ts | 6 +- src/ui/command-ui-handler.ts | 64 +- src/ui/fight-ui-handler.ts | 4 +- src/ui/run-info-ui-handler.ts | 23 - src/ui/summary-ui-handler.ts | 3 +- 52 files changed, 1784 insertions(+), 433 deletions(-) create mode 100644 public/battle-anims/common-terastallize.json create mode 100644 public/images/battle_anims/terastallize.png create mode 100644 public/images/ui/button_tera.json create mode 100644 public/images/ui/button_tera.png create mode 100644 public/images/ui/legacy/button_tera.json create mode 100644 public/images/ui/legacy/button_tera.png create mode 100644 src/phases/tera-phase.ts create mode 100644 src/system/version_migration/versions/v1_7_0.ts diff --git a/public/battle-anims/common-terastallize.json b/public/battle-anims/common-terastallize.json new file mode 100644 index 00000000000..3843464dbde --- /dev/null +++ b/public/battle-anims/common-terastallize.json @@ -0,0 +1,774 @@ +{ + "graphic": "terastallize", + "frames": [ + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 0, + "opacity": 150, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 0, + "opacity": 225, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 70, + "zoomY": 70, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 255, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 70, + "zoomY": 70, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 255, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 90, + "zoomY": 90, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 255, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 90, + "zoomY": 90, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 255, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 255, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 255, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 255, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 200, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 100, + 100, + 100, + 0 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 100, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 100, + 100, + 100, + 0 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 100, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 100, + 100, + 100, + 0 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 60, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 100, + 100, + 100, + 0 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 60, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 100, + 100, + 100, + 0 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + }, + { + "x": 0, + "y": -20, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 2, + "graphicFrame": 1, + "opacity": 60, + "priority": 1, + "focus": 2 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 100, + 100, + 100, + 0 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 255, + 255, + 255, + 255 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 255, + 255, + 255, + 0 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + } + ], + [ + { + "x": 0, + "y": 0, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 0, + "graphicFrame": 0, + "opacity": 255, + "tone": [ + 255, + 255, + 255, + 255 + ], + "locked": true, + "priority": 1, + "focus": 2 + }, + { + "x": 128, + "y": -64, + "zoomX": 100, + "zoomY": 100, + "visible": true, + "target": 1, + "graphicFrame": 0, + "opacity": 255, + "locked": true, + "priority": 1, + "focus": 1 + } + ] + ], + "frameTimedEvents": {}, + "position": 4, + "hue": 0 +} \ No newline at end of file diff --git a/public/images/battle_anims/terastallize.png b/public/images/battle_anims/terastallize.png new file mode 100644 index 0000000000000000000000000000000000000000..78fbb7ec33506e0318de050424d429e8bc428314 GIT binary patch literal 2092 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 literal 0 HcmV?d00001 diff --git a/public/images/ui/legacy/button_tera.json b/public/images/ui/legacy/button_tera.json new file mode 100644 index 00000000000..7b64db66ae6 --- /dev/null +++ b/public/images/ui/legacy/button_tera.json @@ -0,0 +1,158 @@ +{ "frames": { + "unknown": { + "frame": { "x": 0, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "bug": { + "frame": { "x": 18, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "dark": { + "frame": { "x": 36, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "dragon": { + "frame": { "x": 54, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "electric": { + "frame": { "x": 72, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fairy": { + "frame": { "x": 0, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fighting": { + "frame": { "x": 18, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fire": { + "frame": { "x": 36, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "flying": { + "frame": { "x": 54, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ghost": { + "frame": { "x": 72, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "grass": { + "frame": { "x": 0, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ground": { + "frame": { "x": 18, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ice": { + "frame": { "x": 36, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "normal": { + "frame": { "x": 54, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "poison": { + "frame": { "x": 72, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "psychic": { + "frame": { "x": 0, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "rock": { + "frame": { "x": 18, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "steel": { + "frame": { "x": 36, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "water": { + "frame": { "x": 54, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "stellar": { + "frame": { "x": 72, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + } + }, + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "button_tera.png", + "format": "RGBA8888", + "size": { "w": 90, "h": 84 }, + "scale": "1", + "frameTags": [ + ], + "layers": [ + { "name": "Sprite Sheet", "opacity": 255, "blendMode": "normal" } + ], + "slices": [ + ] + } +} diff --git a/public/images/ui/legacy/button_tera.png b/public/images/ui/legacy/button_tera.png new file mode 100644 index 0000000000000000000000000000000000000000..c9672bafa39be1077386d05e922bdc2683dc53d1 GIT binary patch literal 6700 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 literal 0 HcmV?d00001 diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 3f285c274af..4033f44eacb 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -9,7 +9,7 @@ import type { Constructor } from "#app/utils"; import { isNullOrUndefined, randSeedInt } from "#app/utils"; import * as Utils from "#app/utils"; import type { Modifier, ModifierPredicate, TurnHeldItemTransferModifier } from "./modifier/modifier"; -import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, ModifierBar, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, RememberMoveModifier, TerastallizeModifier } from "./modifier/modifier"; +import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, ModifierBar, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, RememberMoveModifier } from "./modifier/modifier"; import { PokeballType } from "#enums/pokeball"; import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "#app/data/battle-anims"; import type { Phase } from "#app/phase"; @@ -1373,7 +1373,11 @@ export default class BattleScene extends SceneBase { for (const pokemon of this.getPlayerParty()) { pokemon.resetBattleData(); + pokemon.resetTera(); applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon); + if (pokemon.hasSpecies(Species.TERAPAGOS) || (this.gameMode.isClassic && this.currentBattle.waveIndex > 180 && this.currentBattle.waveIndex <= 190)) { + this.arena.playerTerasUsed = 0; + } } if (!this.trainer.visible) { @@ -1658,7 +1662,7 @@ export default class BattleScene extends SceneBase { } initPokemonSprite(sprite: Phaser.GameObjects.Sprite, pokemon?: Pokemon, hasShadow: boolean = false, ignoreOverride: boolean = false): Phaser.GameObjects.Sprite { - sprite.setPipeline(this.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined }); + sprite.setPipeline(this.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined, isTerastallized: pokemon ? pokemon.isTerastallized : false }); this.spriteSparkleHandler.add(sprite); return sprite; } @@ -2589,11 +2593,8 @@ export default class BattleScene extends SceneBase { const modifiersToRemove: PersistentModifier[] = []; const modifierPromises: Promise[] = []; if (modifier instanceof PersistentModifier) { - if (modifier instanceof TerastallizeModifier) { - modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId))); - } if ((modifier as PersistentModifier).add(this.modifiers, !!virtual)) { - if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) { + if (modifier instanceof PokemonFormChangeItemModifier) { const pokemon = this.getPokemonById(modifier.pokemonId); if (pokemon) { success = modifier.apply(pokemon, true); @@ -2670,11 +2671,8 @@ export default class BattleScene extends SceneBase { addEnemyModifier(modifier: PersistentModifier, ignoreUpdate?: boolean, instant?: boolean): Promise { return new Promise(resolve => { const modifiersToRemove: PersistentModifier[] = []; - if (modifier instanceof TerastallizeModifier) { - modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId, false))); - } if ((modifier as PersistentModifier).add(this.enemyModifiers, false)) { - if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) { + if (modifier instanceof PokemonFormChangeItemModifier) { const pokemon = this.getPokemonById(modifier.pokemonId); if (pokemon) { modifier.apply(pokemon, true); @@ -2798,6 +2796,8 @@ export default class BattleScene extends SceneBase { for (const modifier of modifiers) { this.addEnemyModifier(modifier, true, true); } + + this.currentBattle.trainer.genAI(party); } party.forEach((enemyPokemon: EnemyPokemon, i: number) => { @@ -2929,7 +2929,7 @@ export default class BattleScene extends SceneBase { const modifierIndex = modifiers.indexOf(modifier); if (modifierIndex > -1) { modifiers.splice(modifierIndex, 1); - if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) { + if (modifier instanceof PokemonFormChangeItemModifier) { const pokemon = this.getPokemonById(modifier.pokemonId); if (pokemon) { modifier.apply(pokemon, false); @@ -3130,7 +3130,8 @@ export default class BattleScene extends SceneBase { name: p.name, form: p.getFormKey(), types: p.getTypes().map((type) => Type[type]), - teraType: p.getTeraType() !== Type.UNKNOWN ? Type[p.getTeraType()] : "", + teraType: Type[p.getTeraType()], + isTerastallized: p.isTerastallized, level: p.level, currentHP: p.hp, maxHP: p.getMaxHp(), diff --git a/src/battle.ts b/src/battle.ts index 7ede7b2982e..807ac215ea8 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -92,6 +92,7 @@ export default class Battle { public started: boolean = false; public enemySwitchCounter: number = 0; public turn: number = 0; + public preTurnCommands: TurnCommands; public turnCommands: TurnCommands; public playerParticipantIds: Set = new Set(); public battleScore: number = 0; @@ -180,6 +181,7 @@ export default class Battle { incrementTurn(): void { this.turn++; this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ])); + this.preTurnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ])); this.battleSeedState = null; } diff --git a/src/data/ability.ts b/src/data/ability.ts index e5b674d4fb4..6ba5f685acd 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -239,37 +239,25 @@ export class PostBattleInitFormChangeAbAttr extends PostBattleInitAbAttr { } } -export class PostBattleInitStatStageChangeAbAttr extends PostBattleInitAbAttr { +export class PostTeraFormChangeStatChangeAbAttr extends AbAttr { private stats: BattleStat[]; private stages: number; - private selfTarget: boolean; - constructor(stats: BattleStat[], stages: number, selfTarget?: boolean) { + constructor(stats: BattleStat[], stages: number) { super(); this.stats = stats; this.stages = stages; - this.selfTarget = !!selfTarget; } - applyPostBattleInit(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { + apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder | null, args: any[]): boolean | Promise { const statStageChangePhases: StatStageChangePhase[] = []; if (!simulated) { - if (this.selfTarget) { - statStageChangePhases.push(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages)); - } else { - for (const opponent of pokemon.getOpponents()) { - statStageChangePhases.push(new StatStageChangePhase(opponent.getBattlerIndex(), false, this.stats, this.stages)); - } - } + statStageChangePhases.push(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages)); for (const statStageChangePhase of statStageChangePhases) { - if (!this.selfTarget && !statStageChangePhase.getPokemon()?.summonData) { - globalScene.pushPhase(statStageChangePhase); - } else { // TODO: This causes the ability bar to be shown at the wrong time - globalScene.unshiftPhase(statStageChangePhase); - } + globalScene.unshiftPhase(statStageChangePhase); } } @@ -1307,7 +1295,7 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { if ( - !pokemon.isTerastallized() && + !pokemon.isTerastallized && move.id !== Moves.STRUGGLE && /** * Skip moves that call other moves because these moves generate a following move that will trigger this ability attribute @@ -4788,7 +4776,7 @@ export class TerrainEventTypeChangeAbAttr extends PostSummonAbAttr { } override apply(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _cancelled: Utils.BooleanHolder, _args: any[]): boolean { - if (pokemon.isTerastallized()) { + if (pokemon.isTerastallized) { return false; } const currentTerrain = globalScene.arena.getTerrainType(); @@ -6201,7 +6189,7 @@ export function initAbilities() { .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) .attr(NoFusionAbilityAbAttr) - .condition((pokemon) => !pokemon.isTerastallized()), + .condition((pokemon) => !pokemon.isTerastallized), new Ability(Abilities.QUICK_DRAW, 8) .attr(BypassSpeedChanceAbAttr, 30), new Ability(Abilities.UNSEEN_FIST, 8) @@ -6353,29 +6341,25 @@ export function initAbilities() { new Ability(Abilities.TOXIC_CHAIN, 9) .attr(PostAttackApplyStatusEffectAbAttr, false, 30, StatusEffect.TOXIC), new Ability(Abilities.EMBODY_ASPECT_TEAL, 9) - .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.SPD ], 1, true) + .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPD ], 1) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) - .attr(NoTransformAbilityAbAttr) - .partial(), // Ogerpon tera interactions + .attr(NoTransformAbilityAbAttr), new Ability(Abilities.EMBODY_ASPECT_WELLSPRING, 9) - .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.SPDEF ], 1, true) + .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPDEF ], 1) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) - .attr(NoTransformAbilityAbAttr) - .partial(), // Ogerpon tera interactions + .attr(NoTransformAbilityAbAttr), new Ability(Abilities.EMBODY_ASPECT_HEARTHFLAME, 9) - .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.ATK ], 1, true) + .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.ATK ], 1) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) - .attr(NoTransformAbilityAbAttr) - .partial(), // Ogerpon tera interactions + .attr(NoTransformAbilityAbAttr), new Ability(Abilities.EMBODY_ASPECT_CORNERSTONE, 9) - .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.DEF ], 1, true) + .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.DEF ], 1) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) - .attr(NoTransformAbilityAbAttr) - .partial(), // Ogerpon tera interactions + .attr(NoTransformAbilityAbAttr), new Ability(Abilities.TERA_SHIFT, 9) .attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1) .attr(UncopiableAbilityAbAttr) diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index 99e9e82d4a6..a179f3a3e9b 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -56,6 +56,7 @@ export enum ChargeAnim { export enum CommonAnim { USE_ITEM = 2000, HEALTH_UP, + TERASTALLIZE, POISON = 2010, TOXIC, PARALYSIS, diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 91ab10aecfa..b97be756048 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2485,7 +2485,7 @@ export class TarShotTag extends BattlerTag { * @returns whether the tag is applied */ override canAdd(pokemon: Pokemon): boolean { - return !pokemon.isTerastallized(); + return !pokemon.isTerastallized; } override onAdd(pokemon: Pokemon): void { diff --git a/src/data/move.ts b/src/data/move.ts index cc22f582790..7e504e87667 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -791,7 +791,7 @@ export default class Move implements Localizable { applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, null, typeChangeMovePowerMultiplier); const sourceTeraType = source.getTeraType(); - if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !globalScene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) { + if (source.isTerastallized && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !globalScene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) { power.value = 60; } @@ -4634,7 +4634,7 @@ export class TeraMoveCategoryAttr extends VariableMoveCategoryAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const category = (args[0] as Utils.NumberHolder); - if (user.isTerastallized() && user.getEffectiveStat(Stat.ATK, target, move, true, true, false, false, true) > + if (user.isTerastallized && user.getEffectiveStat(Stat.ATK, target, move, true, true, false, false, true) > user.getEffectiveStat(Stat.SPATK, target, move, true, true, false, false, true)) { category.value = MoveCategory.PHYSICAL; return true; @@ -4662,7 +4662,7 @@ export class TeraBlastPowerAttr extends VariablePowerAttr { */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const power = args[0] as Utils.NumberHolder; - if (user.isTerastallized() && user.getTeraType() === Type.STELLAR) { + if (user.isTerastallized && user.getTeraType() === Type.STELLAR) { power.value = 100; return true; } @@ -4720,30 +4720,6 @@ export class VariableMoveTypeAttr extends MoveAttr { } } -/** - * Attribute used for Tera Starstorm that changes the move type to Stellar - * @extends VariableMoveTypeAttr - */ -export class TeraStarstormTypeAttr extends VariableMoveTypeAttr { - /** - * - * @param user the {@linkcode Pokemon} using the move - * @param target n/a - * @param move n/a - * @param args[0] {@linkcode Utils.NumberHolder} the move type - * @returns `true` if the move type is changed to {@linkcode Type.STELLAR}, `false` otherwise - */ - override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - if (user.isTerastallized() && (user.hasFusionSpecies(Species.TERAPAGOS) || user.species.speciesId === Species.TERAPAGOS)) { - const moveType = args[0] as Utils.NumberHolder; - - moveType.value = Type.STELLAR; - return true; - } - return false; - } -} - export class FormChangeItemTypeAttr extends VariableMoveTypeAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const moveType = args[0]; @@ -5009,7 +4985,7 @@ export class TeraBlastTypeAttr extends VariableMoveTypeAttr { return false; } - if (user.isTerastallized()) { + if (user.isTerastallized) { moveType.value = user.getTeraType(); // changes move type to tera type return true; } @@ -5018,6 +4994,30 @@ export class TeraBlastTypeAttr extends VariableMoveTypeAttr { } } +/** + * Attribute used for Tera Starstorm that changes the move type to Stellar + * @extends VariableMoveTypeAttr + */ +export class TeraStarstormTypeAttr extends VariableMoveTypeAttr { + /** + * + * @param user the {@linkcode Pokemon} using the move + * @param target n/a + * @param move n/a + * @param args[0] {@linkcode Utils.NumberHolder} the move type + * @returns `true` if the move type is changed to {@linkcode Type.STELLAR}, `false` otherwise + */ + override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (user.isTerastallized && user.hasSpecies(Species.TERAPAGOS)) { + const moveType = args[0] as Utils.NumberHolder; + + moveType.value = Type.STELLAR; + return true; + } + return false; + } +} + export class MatchUserTypeAttr extends VariableMoveTypeAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const moveType = args[0]; @@ -6345,7 +6345,7 @@ export class RemoveTypeAttr extends MoveEffectAttr { return false; } - if (user.isTerastallized() && user.getTeraType() === this.removedType) { // active tera types cannot be removed + if (user.isTerastallized && user.getTeraType() === this.removedType) { // active tera types cannot be removed return false; } @@ -6525,7 +6525,7 @@ export class ChangeTypeAttr extends MoveEffectAttr { } getCondition(): MoveConditionFunc { - return (user, target, move) => !target.isTerastallized() && !target.hasAbility(Abilities.MULTITYPE) && !target.hasAbility(Abilities.RKS_SYSTEM) && !(target.getTypes().length === 1 && target.getTypes()[0] === this.type); + return (user, target, move) => !target.isTerastallized && !target.hasAbility(Abilities.MULTITYPE) && !target.hasAbility(Abilities.RKS_SYSTEM) && !(target.getTypes().length === 1 && target.getTypes()[0] === this.type); } } @@ -6548,7 +6548,7 @@ export class AddTypeAttr extends MoveEffectAttr { } getCondition(): MoveConditionFunc { - return (user, target, move) => !target.isTerastallized() && !target.getTypes().includes(this.type); + return (user, target, move) => !target.isTerastallized && !target.getTypes().includes(this.type); } } @@ -11076,7 +11076,7 @@ export function initMoves() { .attr(TeraMoveCategoryAttr) .attr(TeraBlastTypeAttr) .attr(TeraBlastPowerAttr) - .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, { condition: (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR) }), + .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, { condition: (user, target, move) => user.isTerastallized && user.isOfType(Type.STELLAR) }), new SelfStatusMove(Moves.SILK_TRAP, Type.BUG, -1, 10, -1, 4, 9) .attr(ProtectAttr, BattlerTagType.SILK_TRAP) .condition(failIfLastCondition), @@ -11271,7 +11271,7 @@ export function initMoves() { new AttackMove(Moves.TERA_STARSTORM, Type.NORMAL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) .attr(TeraMoveCategoryAttr) .attr(TeraStarstormTypeAttr) - .attr(VariableTargetAttr, (user, target, move) => (user.hasFusionSpecies(Species.TERAPAGOS) || user.species.speciesId === Species.TERAPAGOS) && user.isTerastallized() ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER) + .attr(VariableTargetAttr, (user, target, move) => user.hasSpecies(Species.TERAPAGOS) && user.isTerastallized ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER) .partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */ new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9) .attr(PreMoveMessageAttr, doublePowerChanceMessageFunc) 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 65bbab16603..f494aaf2c28 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -594,7 +594,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P console.error(`Failed to play animation for ${spriteKey}`, err); } - sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()) }); + sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()), isTerastallized: tradedPokemon.isTerastallized }); sprite.setPipelineData("ignoreTimeTint", true); sprite.setPipelineData("spriteKey", tradedPokemon.getSpriteKey()); sprite.setPipelineData("shiny", tradedPokemon.shiny); @@ -615,7 +615,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P console.error(`Failed to play animation for ${spriteKey}`, err); } - sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()) }); + sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()), isTerastallized: tradedPokemon.isTerastallized }); sprite.setPipelineData("ignoreTimeTint", true); sprite.setPipelineData("spriteKey", receivedPokemon.getSpriteKey()); sprite.setPipelineData("shiny", receivedPokemon.shiny); diff --git a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts index 2f5843e39d2..a4e80c158bb 100644 --- a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts @@ -1,5 +1,5 @@ import type { EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { generateModifierType, handleMysteryEncounterBattleFailed, initBattleWithEnemyConfig, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { handleMysteryEncounterBattleFailed, initBattleWithEnemyConfig, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { trainerConfigs } from "#app/data/trainer-config"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; @@ -23,7 +23,6 @@ import { EggSourceType } from "#enums/egg-source-types"; import { EggTier } from "#enums/egg-type"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; -import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { modifierTypes } from "#app/modifier/modifier-type"; import { Type } from "#enums/type"; import { getPokeballTintColor } from "#app/data/pokeball"; @@ -387,11 +386,7 @@ function getPartyConfig(): EnemyPartyConfig { nature: Nature.ADAMANT, moveSet: [ Moves.METEOR_MASH, Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH ], ivs: [ 31, 31, 31, 31, 31, 31 ], - modifierConfigs: [ - { - modifier: generateModifierType(modifierTypes.TERA_SHARD, [ Type.STEEL ]) as PokemonHeldItemModifierType, - } - ] + tera: Type.STEEL, } ] }; diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index 351b969b1a8..d745da5ecb3 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -46,6 +46,7 @@ import type { Variant } from "#app/data/variant"; import { StatusEffect } from "#enums/status-effect"; import { globalScene } from "#app/global-scene"; import { getPokemonSpecies } from "#app/data/pokemon-species"; +import { Type } from "#app/enums/type"; /** * Animates exclamation sprite over trainer's head at start of encounter @@ -98,6 +99,7 @@ export interface EnemyPokemonConfig { modifierConfigs?: HeldModifierConfig[]; tags?: BattlerTagType[]; dataSource?: PokemonData; + tera?: Type; aiType?: AiType; } @@ -329,6 +331,14 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): tags.forEach(tag => enemyPokemon.addTag(tag)); } + // Set tera + if (config.tera && config.tera !== Type.UNKNOWN) { + enemyPokemon.teraType = config.tera; + if (battle.trainer) { + battle.trainer.config.setInstantTera(e); + } + } + // mysteryEncounterBattleEffects will only be used IFF MYSTERY_ENCOUNTER_POST_SUMMON tag is applied if (config.mysteryEncounterBattleEffects) { enemyPokemon.mysteryEncounterBattleEffects = config.mysteryEncounterBattleEffects; diff --git a/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts b/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts index d4ae3496b0c..0cb2a695de8 100644 --- a/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts +++ b/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts @@ -61,7 +61,7 @@ export function doPokemonTransformationSequence(previousPokemon: PlayerPokemon, console.error(`Failed to play animation for ${spriteKey}`, err); } - sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(previousPokemon.getTeraType()) }); + sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(previousPokemon.getTeraType()), isTerastallized: previousPokemon.isTerastallized }); sprite.setPipelineData("ignoreTimeTint", true); sprite.setPipelineData("spriteKey", previousPokemon.getSpriteKey()); sprite.setPipelineData("shiny", previousPokemon.shiny); diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index 0226aef79d1..46dfbfecae2 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -1,8 +1,7 @@ -import { PokemonFormChangeItemModifier, TerastallizeModifier } from "../modifier/modifier"; +import { PokemonFormChangeItemModifier } from "../modifier/modifier"; import type Pokemon from "../field/pokemon"; import { StatusEffect } from "#enums/status-effect"; import { MoveCategory, allMoves } from "./move"; -import { Type } from "#enums/type"; import type { Constructor, nil } from "#app/utils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; @@ -399,23 +398,7 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger { * @extends SpeciesFormChangeTrigger */ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger { - /** The Tera type that triggers the form change */ - private teraType: Type; - - constructor(teraType: Type) { - super(); - this.teraType = teraType; - this.description = i18next.t("pokemonEvolutions:Forms.tera", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) }); - } - - /** - * Checks if the associated Pokémon has the required Tera Shard that matches with the associated Tera type. - * @param {Pokemon} pokemon the Pokémon that is trying to do the form change - * @returns `true` if the Pokémon can change forms, `false` otherwise - */ - canChange(pokemon: Pokemon): boolean { - return !!globalScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id && m.teraType === this.teraType); - } + description = i18next.t("pokemonEvolutions:Forms.tera" ); } /** @@ -425,10 +408,6 @@ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger { */ export class SpeciesFormChangeLapseTeraTrigger extends SpeciesFormChangeTrigger { description = i18next.t("pokemonEvolutions:Forms.teraLapse"); - - canChange(pokemon: Pokemon): boolean { - return !!globalScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id); - } } /** @@ -992,19 +971,19 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.OGERPON, "teal-mask", "wellspring-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.WELLSPRING_MASK)), new SpeciesFormChange(Species.OGERPON, "teal-mask", "hearthflame-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.HEARTHFLAME_MASK)), new SpeciesFormChange(Species.OGERPON, "teal-mask", "cornerstone-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.CORNERSTONE_MASK)), - new SpeciesFormChange(Species.OGERPON, "teal-mask", "teal-mask-tera", new SpeciesFormChangeTeraTrigger(Type.GRASS)), - new SpeciesFormChange(Species.OGERPON, "teal-mask-tera", "teal-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.GRASS)), - new SpeciesFormChange(Species.OGERPON, "wellspring-mask", "wellspring-mask-tera", new SpeciesFormChangeTeraTrigger(Type.WATER)), - new SpeciesFormChange(Species.OGERPON, "wellspring-mask-tera", "wellspring-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.WATER)), - new SpeciesFormChange(Species.OGERPON, "hearthflame-mask", "hearthflame-mask-tera", new SpeciesFormChangeTeraTrigger(Type.FIRE)), - new SpeciesFormChange(Species.OGERPON, "hearthflame-mask-tera", "hearthflame-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.FIRE)), - new SpeciesFormChange(Species.OGERPON, "cornerstone-mask", "cornerstone-mask-tera", new SpeciesFormChangeTeraTrigger(Type.ROCK)), - new SpeciesFormChange(Species.OGERPON, "cornerstone-mask-tera", "cornerstone-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.ROCK)) + new SpeciesFormChange(Species.OGERPON, "teal-mask", "teal-mask-tera", new SpeciesFormChangeTeraTrigger(), true), + new SpeciesFormChange(Species.OGERPON, "teal-mask-tera", "teal-mask", new SpeciesFormChangeLapseTeraTrigger(), true), + new SpeciesFormChange(Species.OGERPON, "wellspring-mask", "wellspring-mask-tera", new SpeciesFormChangeTeraTrigger(), true), + new SpeciesFormChange(Species.OGERPON, "wellspring-mask-tera", "wellspring-mask", new SpeciesFormChangeLapseTeraTrigger(), true), + new SpeciesFormChange(Species.OGERPON, "hearthflame-mask", "hearthflame-mask-tera", new SpeciesFormChangeTeraTrigger(), true), + new SpeciesFormChange(Species.OGERPON, "hearthflame-mask-tera", "hearthflame-mask", new SpeciesFormChangeLapseTeraTrigger(), true), + new SpeciesFormChange(Species.OGERPON, "cornerstone-mask", "cornerstone-mask-tera", new SpeciesFormChangeTeraTrigger(), true), + new SpeciesFormChange(Species.OGERPON, "cornerstone-mask-tera", "cornerstone-mask", new SpeciesFormChangeLapseTeraTrigger(), true) ], [Species.TERAPAGOS]: [ new SpeciesFormChange(Species.TERAPAGOS, "", "terastal", new SpeciesFormChangeAbilityTrigger(), true), - new SpeciesFormChange(Species.TERAPAGOS, "terastal", "stellar", new SpeciesFormChangeTeraTrigger(Type.STELLAR)), - new SpeciesFormChange(Species.TERAPAGOS, "stellar", "terastal", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.STELLAR)) + new SpeciesFormChange(Species.TERAPAGOS, "terastal", "stellar", new SpeciesFormChangeTeraTrigger(), true), + new SpeciesFormChange(Species.TERAPAGOS, "stellar", "terastal", new SpeciesFormChangeLapseTeraTrigger(), true) ], [Species.GALAR_DARMANITAN]: [ new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeAbilityTrigger(), true), diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 564518845dc..9cbec400a87 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -175,11 +175,51 @@ export const trainerPartyTemplates = { type PartyTemplateFunc = () => TrainerPartyTemplate; type PartyMemberFunc = (level: number, strength: PartyMemberStrength) => EnemyPokemon; type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[]; +type GenAIFunc = (party: EnemyPokemon[]) => void; export interface PartyMemberFuncs { [key: number]: PartyMemberFunc } +export enum TeraAIMode { + NO_TERA, + INSTANT_TERA, + SMART_TERA +} + +/** + * Stores data and helper functions about a trainers AI options. + */ +export class TrainerAI { + public teraMode: TeraAIMode = TeraAIMode.NO_TERA; + public instantTeras: number[]; + + /** + * @param canTerastallize Whether this trainer is allowed to tera + */ + constructor(teraMode: TeraAIMode = TeraAIMode.NO_TERA) { + this.teraMode = teraMode; + this.instantTeras = []; + } + + /** + * Checks if a trainer can tera + * @returns Whether this trainer can currently tera + */ + public canTerastallize() { + return this.teraMode !== TeraAIMode.NO_TERA; + } + + /** + * Sets a pokemon on this AI to just instantly tera on first move used + * @param index The index of the pokemon to instantly tera + */ + public setInstantTera(index: number) { + this.teraMode = TeraAIMode.INSTANT_TERA; + this.instantTeras.push(index); + } +} + export class TrainerConfig { public trainerType: TrainerType; public trainerTypeDouble: TrainerType; @@ -203,6 +243,7 @@ export class TrainerConfig { public doubleEncounterBgm: string; public victoryBgm: string; public genModifiersFunc: GenModifiersFunc; + public genAIFuncs: GenAIFunc[] = []; public modifierRewardFuncs: ModifierTypeFunc[] = []; public partyTemplates: TrainerPartyTemplate[]; public partyTemplateFunc: PartyTemplateFunc; @@ -212,6 +253,7 @@ export class TrainerConfig { public speciesFilter: PokemonSpeciesFilter; public specialtyTypes: Type[] = []; public hasVoucher: boolean = false; + public trainerAI: TrainerAI; public encounterMessages: string[] = []; public victoryMessages: string[] = []; @@ -227,6 +269,7 @@ export class TrainerConfig { constructor(trainerType: TrainerType, allowLegendaries?: boolean) { this.trainerType = trainerType; + this.trainerAI = new TrainerAI(); this.name = Utils.toReadableString(TrainerType[this.getDerivedType()]); this.battleBgm = "battle_trainer"; this.mixedBattleBgm = "battle_trainer"; @@ -550,6 +593,47 @@ export class TrainerConfig { return this; } + /** + * Sets random pokemon from the trainers team to instant tera. Uses their specialty types is they have one. + * @param count The amount of pokemon to have instant tera + * @returns this + */ + setRandomTeraModifiers(count: () => integer): TrainerConfig { + this.genAIFuncs.push((party: EnemyPokemon[]) => { + const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i); + for (let t = 0; t < Math.min(count(), party.length); t++) { + const randomIndex = Utils.randSeedItem(partyMemberIndexes); + partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1); + if (this.specialtyTypes?.length) { + party[randomIndex].teraType = Utils.randSeedItem(this.specialtyTypes); + } + this.trainerAI.setInstantTera(randomIndex); + } + }); + return this; + } + + /** + * Sets a specific pokemon to instant tera + * @param index The index within the team to have instant tera + * @returns this + */ + setInstantTera(index: number): TrainerConfig { + this.trainerAI.setInstantTera(index); + return this; + } + + // function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: Type[]): PersistentModifier[] { + // const ret: PersistentModifier[] = []; + // const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i); + // for (let t = 0; t < Math.min(count, party.length); t++) { + // const randomIndex = Utils.randSeedItem(partyMemberIndexes); + // partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1); + // ret.push(modifierTypes.TERA_SHARD().generateType([], [ Utils.randSeedItem(types ? types : party[randomIndex].getTypes()) ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct? + // } + // return ret; + // } + setEventModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig { this.eventRewardFuncs = modifierTypeFuncs.map(func => () => { const modifierTypeFunc = func(); @@ -851,10 +935,7 @@ export class TrainerConfig { this.setHasVoucher(true); this.setBattleBgm("battle_unova_gym"); this.setVictoryBgm("victory_gym"); - this.setGenModifiersFunc(party => { - const waveIndex = globalScene.currentBattle.waveIndex; - return getRandomTeraModifiers(party, waveIndex >= 100 ? 1 : 0, specialtyTypes.length ? specialtyTypes : undefined); - }); + this.setRandomTeraModifiers(() => globalScene.currentBattle.waveIndex >= 100 ? 1 : 0); return this; } @@ -910,7 +991,7 @@ export class TrainerConfig { this.setHasVoucher(true); this.setBattleBgm("battle_unova_elite"); this.setVictoryBgm("victory_gym"); - this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 1, specialtyTypes.length ? specialtyTypes : undefined)); + this.setRandomTeraModifiers(() => 1); return this; } @@ -1197,16 +1278,6 @@ function getSpeciesFilterRandomPartyMemberFunc( }; } -function getRandomTeraModifiers(party: EnemyPokemon[], count: number, types?: Type[]): PersistentModifier[] { - const ret: PersistentModifier[] = []; - const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i); - for (let t = 0; t < Math.min(count, party.length); t++) { - const randomIndex = Utils.randSeedItem(partyMemberIndexes); - partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1); - ret.push(modifierTypes.TERA_SHARD().generateType([], [ Utils.randSeedItem(types ? types : party[randomIndex].getTypes()) ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct? - } - return ret; -} type SignatureSpecies = { [key in string]: (Species | Species[])[]; @@ -1747,10 +1818,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateName(); p.gender = Gender.MALE; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[3]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(3), [TrainerType.RED]: new TrainerConfig(++t).initForChampion(true).setBattleBgm("battle_johto_champion").setMixedBattleBgm("battle_johto_champion").setHasDouble("red_blue_double").setDoubleTrainerType(TrainerType.BLUE).setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PIKACHU ], TrainerSlot.TRAINER, true, p => { p.formIndex = 8; // G-Max Pikachu @@ -1774,10 +1842,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateName(); p.gender = Gender.MALE; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[3]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(3), [TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t).setName("Lance").initForChampion(true).setBattleBgm("battle_johto_champion").setMixedBattleBgm("battle_johto_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.GYARADOS, Species.KINGDRA ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.AERODACTYL ])) @@ -1787,16 +1852,15 @@ export const trainerConfigs: TrainerConfigs = { p.generateName(); })) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.CHARIZARD ])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.TYRANITAR, Species.GARCHOMP, Species.KOMMO_O ])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.TYRANITAR, Species.GARCHOMP, Species.KOMMO_O ], TrainerSlot.TRAINER, true, p => { + p.teraType = p.species.type1; + })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.DRAGONITE ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.setBoss(true, 2); })) - .setGenModifiersFunc(party => { - const teraPokemon = party[4]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(4), [TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion(true).setBattleBgm("battle_hoenn_champion_g5").setMixedBattleBgm("battle_hoenn_champion_g6").setHasDouble("steven_wallace_double").setDoubleTrainerType(TrainerType.WALLACE).setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SKARMORY ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.CRADILY, Species.ARMALDO ])) @@ -1814,10 +1878,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.generateName(); })) - .setGenModifiersFunc(party => { - const teraPokemon = party[4]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(4), [TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion(true).setBattleBgm("battle_hoenn_champion_g5").setMixedBattleBgm("battle_hoenn_champion_g6").setHasDouble("wallace_steven_double").setDoubleTrainerType(TrainerType.STEVEN).setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PELIPPER ], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Drizzle @@ -1840,10 +1901,7 @@ export const trainerConfigs: TrainerConfigs = { p.gender = Gender.FEMALE; p.setBoss(true, 2); })) - .setGenModifiersFunc(party => { - const teraPokemon = party[4]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(4), [TrainerType.CYNTHIA]: new TrainerConfig(++t).initForChampion(false).setBattleBgm("battle_sinnoh_champion").setMixedBattleBgm("battle_sinnoh_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SPIRITOMB ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -1853,7 +1911,9 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; })) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.MILOTIC, Species.ROSERADE, Species.HISUI_ARCANINE ])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.MILOTIC, Species.ROSERADE, Species.HISUI_ARCANINE ], TrainerSlot.TRAINER, true, p => { + p.teraType = p.species.type1; + })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.TOGEKISS ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); @@ -1864,10 +1924,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateName(); p.gender = Gender.FEMALE; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[3]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(3), [TrainerType.ALDER]: new TrainerConfig(++t).initForChampion(true).setHasDouble("alder_iris_double").setDoubleTrainerType(TrainerType.IRIS).setDoubleTitle("champion_double").setBattleBgm("battle_champion_alder").setMixedBattleBgm("battle_champion_alder") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BOUFFALANT, Species.BRAVIARY ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.HISUI_LILLIGANT, Species.HISUI_ZOROARK, Species.BASCULEGION ], TrainerSlot.TRAINER, true, p => { @@ -1882,16 +1939,15 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; })) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.CHANDELURE, Species.KROOKODILE, Species.REUNICLUS, Species.CONKELDURR ])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.CHANDELURE, Species.KROOKODILE, Species.REUNICLUS, Species.CONKELDURR ], TrainerSlot.TRAINER, true, p => { + p.teraType = p.species.speciesId === Species.KROOKODILE ? Type.DARK : p.species.type1; + })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.VOLCARONA ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.setBoss(true, 2); })) - .setGenModifiersFunc(party => { - const pokemon = party[4]; - return [ modifierTypes.TERA_SHARD().generateType([], [ pokemon.species.speciesId === Species.KROOKODILE ? pokemon.species.type2 : pokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(pokemon) as PersistentModifier ]; - }), + .setInstantTera(4), [TrainerType.IRIS]: new TrainerConfig(++t).initForChampion(false).setBattleBgm("battle_champion_iris").setMixedBattleBgm("battle_champion_iris").setHasDouble("iris_alder_double").setDoubleTrainerType(TrainerType.ALDER).setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.DRUDDIGON ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.ARCHEOPS ])) @@ -1899,7 +1955,9 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; })) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.SALAMENCE, Species.HYDREIGON, Species.ARCHALUDON ])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.SALAMENCE, Species.HYDREIGON, Species.ARCHALUDON ], TrainerSlot.TRAINER, true, p => { + p.teraType = Type.DRAGON; + })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.LAPRAS ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // G-Max Lapras p.generateAndPopulateMoveset(); @@ -1911,10 +1969,7 @@ export const trainerConfigs: TrainerConfigs = { p.gender = Gender.FEMALE; p.setBoss(true, 2); })) - .setGenModifiersFunc(party => { - const teraPokemon = party[3]; - return [ modifierTypes.TERA_SHARD().generateType([], [ Type.DRAGON ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(3), [TrainerType.DIANTHA]: new TrainerConfig(++t).initForChampion(false).setMixedBattleBgm("battle_kalos_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.HAWLUCHA ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -1927,6 +1982,7 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.TYRANTRUM, Species.AURORUS ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.abilityIndex = 2; // Rock Head Tyrantrum, Snow Warning Aurorus + p.teraType = p.species.speciesId === Species.TYRANTRUM ? Type.DRAGON : Type.ICE; })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.GOODRA ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -1938,10 +1994,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateName(); p.gender = Gender.FEMALE; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[3]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type2 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(3), [TrainerType.KUKUI]: new TrainerConfig(++t).initForChampion(true).setMixedBattleBgm("battle_champion_kukui") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.LYCANROC ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -1965,11 +2018,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.INCINEROAR, Species.HISUI_DECIDUEYE ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; + p.teraType = p.species.speciesId === Species.INCINEROAR ? Type.DARK : Type.FIGHTING; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[5]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type2 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(5), [TrainerType.HAU]: new TrainerConfig(++t).initForChampion(true).setMixedBattleBgm("battle_alola_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ALOLA_RAICHU ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -1982,6 +2033,7 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.TAPU_LELE, Species.TAPU_BULU ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + p.teraType = p.species.type1; })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.ZYGARDE ], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Zygarde 10% forme, Aura Break @@ -1993,10 +2045,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.gender = p.species.speciesId === Species.PRIMARINA ? Gender.FEMALE : Gender.MALE; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[3]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(3), [TrainerType.LEON]: new TrainerConfig(++t).initForChampion(true).setMixedBattleBgm("battle_galar_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.AEGISLASH ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -2017,10 +2066,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateName(); p.gender = Gender.MALE; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[3]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(3), [TrainerType.MUSTARD]: new TrainerConfig(++t).initForChampion(true).setMixedBattleBgm("battle_mustard") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CORVIKNIGHT ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -2033,6 +2079,7 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.GALAR_SLOWBRO, Species.GALAR_SLOWKING ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + p.teraType = Type.PSYCHIC; })) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GALAR_DARMANITAN ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -2050,10 +2097,7 @@ export const trainerConfigs: TrainerConfigs = { p.gender = Gender.MALE; p.pokeball = PokeballType.ULTRA_BALL; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[2]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type2 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(2), [TrainerType.GEETA]: new TrainerConfig(++t).initForChampion(false).setMixedBattleBgm("battle_champion_geeta") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.GLIMMORA ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -2070,11 +2114,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.KINGAMBIT ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.abilityIndex = 1; // Supreme Overlord + p.teraType = Type.FLYING; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[5]; - return [ modifierTypes.TERA_SHARD().generateType([], [ Type.FLYING ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(5), [TrainerType.NEMONA]: new TrainerConfig(++t).initForChampion(false).setMixedBattleBgm("battle_champion_nemona") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.LYCANROC ], TrainerSlot.TRAINER, true, p => { p.formIndex = 0; // Midday form @@ -2086,16 +2128,15 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.MASTER_BALL; })) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GHOLDENGO ])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.ARMAROUGE, Species.CERULEDGE ])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.ARMAROUGE, Species.CERULEDGE ], TrainerSlot.TRAINER, true, p => { + p.teraType = p.species.speciesId === Species.ARMAROUGE ? Type.PSYCHIC : Type.GHOST; + })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.setBoss(true, 2); })) - .setGenModifiersFunc(party => { - const teraPokemon = party[4]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type2 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; - }), + .setInstantTera(4), [TrainerType.KIERAN]: new TrainerConfig(++t).initForChampion(true).setMixedBattleBgm("battle_champion_kieran") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.POLIWRATH, Species.POLITOED ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); @@ -2117,7 +2158,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.OGERPON ], TrainerSlot.TRAINER, true, p => { - p.formIndex = Utils.randSeedInt(4, 4); // Random Ogerpon Tera Mask + p.formIndex = Utils.randSeedInt(4); // Random Ogerpon Tera Mask p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; if (!p.moveset.some(move => !Utils.isNullOrUndefined(move) && move.moveId === Moves.IVY_CUDGEL)) { // Check if Ivy Cudgel is in the moveset, if not, replace the first move with Ivy Cudgel. @@ -2129,17 +2170,7 @@ export const trainerConfigs: TrainerConfigs = { p.gender = Gender.MALE; p.setBoss(true, 2); })) - .setGenModifiersFunc(party => { - const starter = party[4]; - let teraShardType: Type; - const pokemonType2 = starter.species.forms[starter.formIndex].type2; - if (starter.formIndex === 4 || Utils.isNullOrUndefined(pokemonType2)) { - teraShardType = starter.species.type1; - } else { - teraShardType = pokemonType2; - } - return [ modifierTypes.TERA_SHARD().generateType([], [ teraShardType ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; - }), + .setInstantTera(4), [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) @@ -2162,19 +2193,20 @@ export const trainerConfigs: TrainerConfigs = { .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, - (p => p.abilityIndex = 0))) + (p => { + p.abilityIndex = 0; + p.teraType = p.species.type1; + }))) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setSpeciesFilter(species => species.baseTotal >= 540) - .setGenModifiersFunc(party => { - const starter = party[0]; - return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; // TODO: is the bang correct? - }), + .setInstantTera(0), [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.abilityIndex = 0; + p.teraType = p.species.type1; })) .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)) @@ -2185,15 +2217,13 @@ export const trainerConfigs: TrainerConfigs = { p.shiny = true; p.variant = 1; })) - .setGenModifiersFunc(party => { - const starter = party[0]; - return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; //TODO: is the bang correct? - }), + .setInstantTera(0), [TrainerType.RIVAL_6]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm("final").setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_6) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 3); p.abilityIndex = 0; + p.teraType = p.species.type1; 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, @@ -2212,10 +2242,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; // Mega Rayquaza p.generateName(); })) - .setGenModifiersFunc(party => { - const starter = party[0]; - return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; // TODO: is the bang correct? - }), + .setInstantTera(0), [TrainerType.ROCKET_BOSS_GIOVANNI_1]: new TrainerConfig(t = TrainerType.ROCKET_BOSS_GIOVANNI_1).setName("Giovanni").initForEvilTeamLeader("Rocket Boss", []).setMixedBattleBgm("battle_rocket_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PERSIAN ], TrainerSlot.TRAINER, true, p => { @@ -2713,10 +2740,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.generateName(); })) - .setGenModifiersFunc(party => { - const teraPokemon = party[4]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; //TODO: is the bang correct? - }), + .setInstantTera(4), [TrainerType.PENNY_2]: new TrainerConfig(++t).setName("Cassiopeia").initForEvilTeamLeader("Star Boss", [], true).setMixedBattleBgm("battle_star_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2749,10 +2773,12 @@ export const trainerConfigs: TrainerConfigs = { p.generateName(); p.pokeball = PokeballType.ULTRA_BALL; })) - .setGenModifiersFunc(party => { - const teraPokemon = party[0]; - return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; //TODO: is the bang correct? - }), + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.ZAMAZENTA ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 2); + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.MASTER_BALL; + })) + .setInstantTera(0), [TrainerType.BUCK]: new TrainerConfig(++t).setName("Buck").initForStatTrainer([], true) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLAYDOL ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 3); diff --git a/src/field/arena.ts b/src/field/arena.ts index 5ee065d71dc..60ee4b5b03c 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -44,6 +44,7 @@ export class Arena { public bgm: string; public ignoreAbilities: boolean; public ignoringEffectSource: BattlerIndex | null; + public playerTerasUsed: number; /** * Saves the number of times a party pokemon faints during a arena encounter. * {@linkcode globalScene.currentBattle.enemyFaints} is the corresponding faint counter for the enemy (this resets every wave). @@ -63,6 +64,7 @@ export class Arena { this.bgm = bgm; this.trainerPool = biomeTrainerPools[biome]; this.updatePoolsForTimeOfDay(); + this.playerTerasUsed = 0; this.playerFaints = playerFaints; } diff --git a/src/field/pokemon-sprite-sparkle-handler.ts b/src/field/pokemon-sprite-sparkle-handler.ts index 074933f0f00..d1803cc036e 100644 --- a/src/field/pokemon-sprite-sparkle-handler.ts +++ b/src/field/pokemon-sprite-sparkle-handler.ts @@ -27,6 +27,9 @@ export default class PokemonSpriteSparkleHandler { if (!s.visible || (s.parentContainer instanceof Pokemon && !s.parentContainer.parentContainer)) { continue; } + if (!(s.parentContainer instanceof Pokemon) || !(s.parentContainer as Pokemon).isTerastallized) { + continue; + } const pokemon = s.parentContainer instanceof Pokemon ? s.parentContainer as Pokemon : null; const parent = (pokemon || s).parentContainer; const texture = s.texture; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 5c6fbb34aea..dfce632ab06 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -52,7 +52,7 @@ import { getTypeDamageMultiplier, getTypeRgb } from "#app/data/type"; import { Type } from "#enums/type"; import { getLevelTotalExp } from "#app/data/exp"; import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat"; -import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier, PokemonMultiHitModifier } from "#app/modifier/modifier"; +import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier, PokemonMultiHitModifier } from "#app/modifier/modifier"; import { PokeballType } from "#enums/pokeball"; import { Gender } from "#app/data/gender"; import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; @@ -79,7 +79,7 @@ import { DexAttr } from "#app/system/game-data"; import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities"; import { getNatureStatMultiplier } from "#app/data/nature"; import type { SpeciesFormChange } from "#app/data/pokemon-forms"; -import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "#app/data/pokemon-forms"; +import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeLapseTeraTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "#app/data/pokemon-forms"; import { TerrainType } from "#app/data/terrain"; import type { TrainerSlot } from "#app/data/trainer-config"; import Overrides from "#app/overrides"; @@ -163,6 +163,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public pokerus: boolean; public switchOutStatus: boolean; public evoCounter: number; + public teraType: Type; + public isTerastallized: boolean; + public stellarTypesBoosted: Type[]; public fusionSpecies: PokemonSpecies | null; public fusionFormIndex: number; @@ -172,6 +175,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public fusionGender: Gender; public fusionLuck: number; public fusionCustomPokemonData: CustomPokemonData | null; + public fusionTeraType: Type; private summonDataPrimer: PokemonSummonData | null; @@ -269,8 +273,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.fusionGender = dataSource.fusionGender; this.fusionLuck = dataSource.fusionLuck; this.fusionCustomPokemonData = dataSource.fusionCustomPokemonData; + this.fusionTeraType = dataSource.fusionTeraType; this.usedTMs = dataSource.usedTMs ?? []; this.customPokemonData = new CustomPokemonData(dataSource.customPokemonData); + this.teraType = dataSource.teraType; + this.isTerastallized = dataSource.isTerastallized; + this.stellarTypesBoosted = dataSource.stellarTypesBoosted ?? []; } else { this.id = Utils.randSeedInt(4294967296); this.ivs = ivs || Utils.getIvsFromId(this.id); @@ -319,6 +327,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } this.luck = (this.shiny ? this.variant + 1 : 0) + (this.fusionShiny ? this.fusionVariant + 1 : 0); this.fusionLuck = this.luck; + + this.teraType = Utils.randSeedItem(this.getTypes(false, false, true)); + this.isTerastallized = false; + this.stellarTypesBoosted = []; } this.generateName(); @@ -355,7 +367,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const getSprite = (hasShadow?: boolean) => { const ret = globalScene.addPokemonSprite(this, 0, 0, `pkmn__${this.isPlayer() ? "back__" : ""}sub`, undefined, true); ret.setOrigin(0.5, 1); - ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, teraColor: getTypeRgb(this.getTeraType()) }); + ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, teraColor: getTypeRgb(this.getTeraType()), isTerastallized: this.isTerastallized }); return ret; }; @@ -723,7 +735,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } updateSpritePipelineData(): void { - [ this.getSprite(), this.getTintSprite() ].filter(s => !!s).map(s => s.pipelineData["teraColor"] = getTypeRgb(this.getTeraType())); + [ this.getSprite(), this.getTintSprite() ].filter(s => !!s).map(s => { + s.pipelineData["teraColor"] = getTypeRgb(this.getTeraType()); + s.pipelineData["isTerastallized"] = this.isTerastallized; + }); this.updateInfo(true); } @@ -1208,6 +1223,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.fusionSpecies?.speciesId === species; } + /** + * Checks if the {@linkcode Pokemon} has is the specified {@linkcode Species} or is fused with it. + * @param species the pokemon {@linkcode Species} to check + * @returns `true` if the pokemon is the species or is fused with it, `false` otherwise + */ + hasSpecies(species: Species): boolean { + return this.species.speciesId === species || this.fusionSpecies?.speciesId === species; + } + abstract isBoss(): boolean; getMoveset(ignoreOverride?: boolean): (PokemonMove | null)[] { @@ -1284,9 +1308,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public getTypes(includeTeraType = false, forDefend: boolean = false, ignoreOverride: boolean = false): Type[] { const types: Type[] = []; - if (includeTeraType) { + if (includeTeraType && this.isTerastallized) { const teraType = this.getTeraType(); - if (teraType !== Type.UNKNOWN) { + if (this.isTerastallized && !(forDefend && teraType === Type.STELLAR)) { // Stellar tera uses its original types defensively types.push(teraType); if (forDefend) { return types; @@ -1590,23 +1614,31 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } /** - * @returns the pokemon's current tera {@linkcode Type}, or `Type.UNKNOWN` if the pokemon is not terastallized + * @returns the pokemon's current tera {@linkcode Type} */ - public getTeraType(): Type { - // I don't think this should be possible anymore, please report if you encounter this. --NightKev - if (globalScene === undefined) { - console.warn("Pokemon.getTeraType(): Global scene is not defined!"); - return Type.UNKNOWN; + getTeraType(): Type { + if (this.hasSpecies(Species.TERAPAGOS)) { + return Type.STELLAR; + } else if (this.hasSpecies(Species.OGERPON)) { + const ogerponForm = this.species.speciesId === Species.OGERPON ? this.formIndex : this.fusionFormIndex; + switch (ogerponForm) { + case 0: + case 4: + return Type.GRASS; + case 1: + case 5: + return Type.WATER; + case 2: + case 6: + return Type.FIRE; + case 3: + case 7: + return Type.ROCK; + } + } else if (this.hasSpecies(Species.SHEDINJA)) { + return Type.BUG; } - const teraModifier = globalScene.findModifier(m => - m instanceof TerastallizeModifier - && m.pokemonId === this.id - && m.getBattlesLeft() > 0, this.isPlayer()) as TerastallizeModifier; - return teraModifier?.teraType ?? Type.UNKNOWN; - } - - public isTerastallized(): boolean { - return this.getTeraType() !== Type.UNKNOWN; + return this.teraType; } public isGrounded(): boolean { @@ -1748,7 +1780,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true, move?: Move): TypeDamageMultiplier { if (moveType === Type.STELLAR) { - return this.isTerastallized() ? 2 : 1; + return this.isTerastallized ? 2 : 1; } const types = this.getTypes(true, true); const arena = globalScene.arena; @@ -2785,11 +2817,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const matchesSourceType = sourceTypes.includes(moveType); /** A damage multiplier for when the attack is of the attacker's type and/or Tera type. */ const stabMultiplier = new Utils.NumberHolder(1); - if (matchesSourceType) { - stabMultiplier.value += 0.5; - } - applyMoveAttrs(CombinedPledgeStabBoostAttr, source, this, move, stabMultiplier); - if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === moveType) { + if (matchesSourceType && moveType !== Type.STELLAR) { stabMultiplier.value += 0.5; } @@ -2797,6 +2825,20 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { applyAbAttrs(StabBoostAbAttr, source, null, simulated, stabMultiplier); } + applyMoveAttrs(CombinedPledgeStabBoostAttr, source, this, move, stabMultiplier); + + if (source.isTerastallized && sourceTeraType === moveType && moveType !== Type.STELLAR) { + stabMultiplier.value += 0.5; + } + + if (source.isTerastallized && source.teraType === Type.STELLAR && (!source.stellarTypesBoosted.includes(moveType) || source.hasSpecies(Species.TERAPAGOS))) { + if (matchesSourceType) { + stabMultiplier.value += 0.5; + } else { + stabMultiplier.value += 0.2; + } + } + stabMultiplier.value = Math.min(stabMultiplier.value, 2.25); /** Halves damage if the attacker is using a physical attack while burned */ @@ -3837,6 +3879,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + resetTera(): void { + const wasTerastallized = this.isTerastallized; + this.isTerastallized = false; + this.stellarTypesBoosted = []; + if (wasTerastallized) { + this.updateSpritePipelineData(); + globalScene.triggerPokemonFormChange(this, SpeciesFormChangeLapseTeraTrigger); + } + } + resetTurnData(): void { this.turnData = new PokemonTurnData(); } @@ -4600,6 +4652,7 @@ export class PlayerPokemon extends Pokemon { newPokemon.fusionVariant = this.fusionVariant; newPokemon.fusionGender = this.fusionGender; newPokemon.fusionLuck = this.fusionLuck; + newPokemon.fusionTeraType = this.teraType; newPokemon.usedTMs = this.usedTMs; globalScene.getPlayerParty().push(newPokemon); @@ -4751,6 +4804,7 @@ export class EnemyPokemon extends Pokemon { public aiType: AiType; public bossSegments: number; public bossSegmentIndex: number; + public initialTeamIndex: number; /** To indicate if the instance was populated with a dataSource -> e.g. loaded & populated from session data */ public readonly isPopulatedFromDataSource: boolean; @@ -4760,6 +4814,7 @@ export class EnemyPokemon extends Pokemon { undefined, dataSource ? dataSource.nature : undefined, dataSource); this.trainerSlot = trainerSlot; + this.initialTeamIndex = globalScene.currentBattle?.enemyParty.length ?? 0; this.isPopulatedFromDataSource = !!dataSource; // if a dataSource is provided, then it was populated from dataSource if (boss) { this.setBoss(boss, dataSource?.bossSegments); diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 65bca641163..5bce08afae6 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -11,7 +11,8 @@ import { TrainerSlot, trainerConfigs, trainerPartyTemplates, - signatureSpecies + signatureSpecies, + TeraAIMode } from "#app/data/trainer-config"; import type { EnemyPokemon } from "#app/field/pokemon"; import * as Utils from "#app/utils"; @@ -36,6 +37,7 @@ export default class Trainer extends Phaser.GameObjects.Container { public partyTemplateIndex: number; public name: string; public partnerName: string; + public originalIndexes: { [key: number]: number } = {}; constructor(trainerType: TrainerType, variant: TrainerVariant, partyTemplateIndex?: number, name?: string, partnerName?: string, trainerConfigOverride?: TrainerConfig) { super(globalScene, -72, 80); @@ -546,6 +548,13 @@ export default class Trainer extends Phaser.GameObjects.Container { return []; } + genAI(party: EnemyPokemon[]) { + if (this.config.genAIFuncs) { + this.config.genAIFuncs.forEach(f => f(party)); + } + console.log("Generated AI funcs"); + } + loadAssets(): Promise { return this.config.loadAssets(this.variant); } @@ -667,4 +676,13 @@ export default class Trainer extends Phaser.GameObjects.Container { } }); } + + shouldTera(pokemon: EnemyPokemon): boolean { + if (this.config.trainerAI.teraMode === TeraAIMode.INSTANT_TERA) { + if (!pokemon.isTerastallized && this.config.trainerAI.instantTeras.includes(pokemon.initialTeamIndex)) { + return true; + } + } + return false; + } } diff --git a/src/loading-scene.ts b/src/loading-scene.ts index e8f817c1c39..fc685fc2332 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -103,6 +103,7 @@ export class LoadingScene extends SceneBase { this.loadImage("icon_tera", "ui"); this.loadImage("type_tera", "ui"); this.loadAtlas("type_bgs", "ui"); + this.loadAtlas("button_tera", "ui"); this.loadImage("mystery_egg", "ui"); this.loadImage("normal_memory", "ui"); diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index da2ab49e9fc..35ed75d8c6e 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -11,7 +11,7 @@ import { Type } from "#enums/type"; import type { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon"; import type Pokemon 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, CriticalCatchChanceBoosterModifier } 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, TerrastalizeModifier, 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"; @@ -19,7 +19,7 @@ import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler"; import PartyUiHandler from "#app/ui/party-ui-handler"; import { getModifierTierTextTint } from "#app/ui/text"; -import { formatMoney, getEnumKeys, getEnumValues, isNullOrUndefined, NumberHolder, padInt, randSeedInt, randSeedItem } from "#app/utils"; +import { formatMoney, getEnumKeys, getEnumValues, isNullOrUndefined, NumberHolder, padInt, randSeedInt } from "#app/utils"; import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; import { BerryType } from "#enums/berry-type"; @@ -275,6 +275,36 @@ export class PokemonHeldItemModifierType extends PokemonModifierType { } } + +export class TerastallizeModifierType extends PokemonModifierType { + private teraType: Type; + + constructor(teraType: Type) { + super("", `${Type[teraType].toLowerCase()}_tera_shard`, (type, args) => new TerrastalizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), + (pokemon: PlayerPokemon) => { + if ([ pokemon.species.speciesId, pokemon.fusionSpecies?.speciesId ].filter(s => s === Species.TERAPAGOS || s === Species.OGERPON || s === Species.SHEDINJA).length > 0) { + return PartyUiHandler.NoEffectMessage; + } + return null; + }, + "tera_shard"); + + this.teraType = teraType; + } + + get name(): string { + return i18next.t("modifierType:ModifierType.TerastallizeModifierType.name", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) }); + } + + getDescription(): string { + return i18next.t("modifierType:ModifierType.TerastallizeModifierType.description", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) }); + } + + getPregenArgs(): any[] { + return [ this.teraType ]; + } +} + export class PokemonHpRestoreModifierType extends PokemonModifierType { protected restorePoints: number; protected restorePercent: number; @@ -1192,28 +1222,6 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { } } -export class TerastallizeModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType { - private teraType: Type; - - constructor(teraType: Type) { - super("", `${Type[teraType].toLowerCase()}_tera_shard`, (type, args) => new TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), "tera_shard"); - - this.teraType = teraType; - } - - get name(): string { - return i18next.t("modifierType:ModifierType.TerastallizeModifierType.name", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) }); - } - - getDescription(): string { - return i18next.t("modifierType:ModifierType.TerastallizeModifierType.description", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) }); - } - - getPregenArgs(): any[] { - return [ this.teraType ]; - } -} - export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemModifierType { private chancePercent: number; @@ -1469,14 +1477,21 @@ export const modifierTypes = { if (!globalScene.getModifiers(TerastallizeAccessModifier).length) { return null; } - let type: Type; - if (!randSeedInt(3)) { - const partyMemberTypes = party.map(p => p.getTypes(false, false, true)).flat(); - type = randSeedItem(partyMemberTypes); - } else { - type = randSeedInt(64) ? randSeedInt(18) as Type : Type.STELLAR; + const teraTypes: Type[] = []; + party.forEach(p => { + if (!(p.hasSpecies(Species.TERAPAGOS) || p.hasSpecies(Species.OGERPON) || p.hasSpecies(Species.SHEDINJA))) { + teraTypes.push(p.teraType); + } + }); + let excludedType = Type.UNKNOWN; + if (teraTypes.length > 0 && teraTypes.filter(t => t === teraTypes[0]).length === teraTypes.length) { + excludedType = teraTypes[0]; } - return new TerastallizeModifierType(type); + let shardType = randSeedInt(64) ? randSeedInt(18) as Type : Type.STELLAR; + while (shardType === excludedType) { + shardType = randSeedInt(64) ? randSeedInt(18) as Type : Type.STELLAR; + } + return new TerastallizeModifierType(shardType); }), BERRY: () => new ModifierTypeGenerator((_party: Pokemon[], pregenArgs?: any[]) => { @@ -1719,7 +1734,7 @@ const modifierPool: ModifierPool = { return Math.min(Math.ceil(highestPartyLevel / 20), 4); }, 4), new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3), - new WeightedModifierType(modifierTypes.TERA_SHARD, 1), + new WeightedModifierType(modifierTypes.TERA_SHARD, (party: Pokemon[]) => party.filter(p => !(p.hasSpecies(Species.TERAPAGOS) || p.hasSpecies(Species.OGERPON) || p.hasSpecies(Species.SHEDINJA))).length > 0 ? 1 : 0), new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => { if (party.filter(p => !p.fusionSpecies).length > 1) { if (globalScene.gameMode.isSplicedOnly) { diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index d955385ecee..fe61eadaccd 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -3,16 +3,16 @@ 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 { type FormChangeItem, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms"; import { getStatusEffectHealText } from "#app/data/status-effect"; -import Pokemon, { type PlayerPokemon } from "#app/field/pokemon"; +import type { PlayerPokemon } from "#app/field/pokemon"; +import Pokemon from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; import Overrides from "#app/overrides"; import { EvolutionPhase } from "#app/phases/evolution-phase"; import { LearnMovePhase, LearnMoveType } from "#app/phases/learn-move-phase"; import { LevelUpPhase } from "#app/phases/level-up-phase"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase"; -import { achvs } from "#app/system/achv"; import type { VoucherType } from "#app/system/voucher"; import { Command } from "#app/ui/command-ui-handler"; import { addTextObject, TextStyle } from "#app/ui/text"; @@ -25,7 +25,7 @@ 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 type { 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"; @@ -786,72 +786,6 @@ export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModi } } -export class TerastallizeModifier extends LapsingPokemonHeldItemModifier { - public override type: TerastallizeModifierType; - public teraType: Type; - public isTransferable: boolean = false; - - constructor(type: TerastallizeModifierType, pokemonId: number, teraType: Type, battlesLeft?: number, stackCount?: number) { - super(type, pokemonId, battlesLeft || 10, stackCount); - - this.teraType = teraType; - } - - matchType(modifier: Modifier): boolean { - if (modifier instanceof TerastallizeModifier && modifier.teraType === this.teraType) { - return true; - } - return false; - } - - clone(): TerastallizeModifier { - return new TerastallizeModifier(this.type, this.pokemonId, this.teraType, this.battlesLeft, this.stackCount); - } - - getArgs(): any[] { - return [ this.pokemonId, this.teraType, this.battlesLeft ]; - } - - /** - * Applies the {@linkcode TerastallizeModifier} to the specified {@linkcode Pokemon}. - * @param pokemon the {@linkcode Pokemon} to be terastallized - * @returns always `true` - */ - override apply(pokemon: Pokemon): boolean { - if (pokemon.isPlayer()) { - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeTeraTrigger); - globalScene.validateAchv(achvs.TERASTALLIZE); - if (this.teraType === Type.STELLAR) { - globalScene.validateAchv(achvs.STELLAR_TERASTALLIZE); - } - } - pokemon.updateSpritePipelineData(); - return true; - } - - /** - * Triggers {@linkcode LapsingPokemonHeldItemModifier.lapse} and if it returns `0` a form change is triggered. - * @param pokemon THe {@linkcode Pokemon} to be terastallized - * @returns the result of {@linkcode LapsingPokemonHeldItemModifier.lapse} - */ - public override lapse(pokemon: Pokemon): boolean { - const ret = super.lapse(pokemon); - if (!ret) { - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeLapseTeraTrigger); - pokemon.updateSpritePipelineData(); - } - return ret; - } - - getScoreMultiplier(): number { - return 1.25; - } - - getMaxHeldItemCount(pokemon: Pokemon): number { - return 1; - } -} - /** * Modifier used for held items, specifically vitamins like Carbos, Hp Up, etc., that * increase the value of a given {@linkcode PermanentStat}. @@ -2022,6 +1956,36 @@ export abstract class ConsumablePokemonModifier extends ConsumableModifier { } } +export class TerrastalizeModifier extends ConsumablePokemonModifier { + public override type: TerastallizeModifierType; + public teraType: Type; + + constructor(type: TerastallizeModifierType, pokemonId: number, teraType: Type) { + super(type, pokemonId); + + this.teraType = teraType; + } + + /** + * Checks if {@linkcode TerrastalizeModifier} should be applied + * @param playerPokemon The {@linkcode PlayerPokemon} that consumes the item + * @returns `true` if the {@linkcode TerrastalizeModifier} should be applied + */ + override shouldApply(playerPokemon?: PlayerPokemon): boolean { + return super.shouldApply(playerPokemon) && [ playerPokemon?.species.speciesId, playerPokemon?.fusionSpecies?.speciesId ].filter(s => s === Species.TERAPAGOS || s === Species.OGERPON || s === Species.SHEDINJA).length === 0; + } + + /** + * Applies {@linkcode TerrastalizeModifier} + * @param pokemon The {@linkcode PlayerPokemon} that consumes the item + * @returns `true` if hp was restored + */ + override apply(pokemon: Pokemon): boolean { + pokemon.teraType = this.teraType; + return true; + } +} + export class PokemonHpRestoreModifier extends ConsumablePokemonModifier { private restorePoints: number; private restorePercent: number; diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index 632344be335..411022a84b4 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -118,6 +118,7 @@ export class CommandPhase extends FieldPhase { let success: boolean = false; switch (command) { + case Command.TERA: case Command.FIGHT: let useStruggle = false; const turnMove: TurnMove | undefined = (args.length === 2 ? (args[1] as TurnMove) : undefined); @@ -137,6 +138,7 @@ export class CommandPhase extends FieldPhase { } const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args }; + const preTurnCommand: TurnCommand = { command: command, targets: [ this.fieldIndex ], skip: command === Command.FIGHT }; const moveTargets: MoveTargetSet = turnMove === undefined ? getMoveTargets(playerPokemon, moveId) : { targets: turnMove.targets, multiple: turnMove.targets.length > 1 }; if (!moveId) { turnCommand.targets = [ this.fieldIndex ]; @@ -152,6 +154,7 @@ export class CommandPhase extends FieldPhase { } else { globalScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex)); } + globalScene.currentBattle.preTurnCommands[this.fieldIndex] = preTurnCommand; globalScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand; success = true; } else if (cursor < playerPokemon.getMoveset().length) { diff --git a/src/phases/enemy-command-phase.ts b/src/phases/enemy-command-phase.ts index e76518bb71e..429674e7786 100644 --- a/src/phases/enemy-command-phase.ts +++ b/src/phases/enemy-command-phase.ts @@ -81,6 +81,10 @@ export class EnemyCommandPhase extends FieldPhase { /** Select a move to use (and a target to use it against, if applicable) */ const nextMove = enemyPokemon.getNextMove(); + if (trainer && trainer.shouldTera(enemyPokemon)) { + globalScene.currentBattle.preTurnCommands[this.fieldIndex + BattlerIndex.ENEMY] = { command: Command.TERA }; + } + globalScene.currentBattle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] = { command: Command.FIGHT, move: nextMove, skip: this.skipTurn }; diff --git a/src/phases/evolution-phase.ts b/src/phases/evolution-phase.ts index 12d2923ec36..ea857cac8ba 100644 --- a/src/phases/evolution-phase.ts +++ b/src/phases/evolution-phase.ts @@ -116,7 +116,7 @@ export class EvolutionPhase extends Phase { console.error(`Failed to play animation for ${spriteKey}`, err); } - sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) }); + sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()), isTerastallized: this.pokemon.isTerastallized }); sprite.setPipelineData("ignoreTimeTint", true); sprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey()); sprite.setPipelineData("shiny", this.pokemon.shiny); diff --git a/src/phases/faint-phase.ts b/src/phases/faint-phase.ts index 340c5362087..f354bc8031e 100644 --- a/src/phases/faint-phase.ts +++ b/src/phases/faint-phase.ts @@ -108,6 +108,8 @@ export class FaintPhase extends PokemonPhase { globalScene.queueMessage(i18next.t("battle:fainted", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, true); globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true); + pokemon.resetTera(); + if (pokemon.turnData?.attacksReceived?.length) { const lastAttack = pokemon.turnData.attacksReceived[0]; applyPostFaintAbAttrs(PostFaintAbAttr, pokemon, globalScene.getPokemonById(lastAttack.sourceId)!, new PokemonMove(lastAttack.move).getMove(), lastAttack.result); // TODO: is this bang correct? diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 35fe446fc43..65d8d95cde6 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -450,6 +450,12 @@ export class MoveEffectPhase extends PokemonPhase { target.lapseTag(BattlerTagType.SUBSTITUTE); } }); + + const moveType = user.getMoveType(move, true); + if (move.category !== MoveCategory.STATUS && !user.stellarTypesBoosted.includes(moveType)) { + user.stellarTypesBoosted.push(moveType); + } + this.end(); }); }); diff --git a/src/phases/party-heal-phase.ts b/src/phases/party-heal-phase.ts index 2c1a6c33163..c87c5d00be5 100644 --- a/src/phases/party-heal-phase.ts +++ b/src/phases/party-heal-phase.ts @@ -36,5 +36,6 @@ export class PartyHealPhase extends BattlePhase { globalScene.ui.fadeIn(500).then(() => this.end()); }); }); + globalScene.arena.playerTerasUsed = 0; } } diff --git a/src/phases/quiet-form-change-phase.ts b/src/phases/quiet-form-change-phase.ts index 185156a20c7..6cd1129d318 100644 --- a/src/phases/quiet-form-change-phase.ts +++ b/src/phases/quiet-form-change-phase.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import { SemiInvulnerableTag } from "#app/data/battler-tags"; import type { SpeciesFormChange } from "#app/data/pokemon-forms"; -import { getSpeciesFormChangeMessage } from "#app/data/pokemon-forms"; +import { getSpeciesFormChangeMessage, SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms"; import { getTypeRgb } from "#app/data/type"; import { BattleSpec } from "#app/enums/battle-spec"; import { BattlerTagType } from "#app/enums/battler-tag-type"; @@ -11,6 +11,7 @@ import { getPokemonNameWithAffix } from "#app/messages"; import { BattlePhase } from "./battle-phase"; import { MovePhase } from "./move-phase"; import { PokemonHealPhase } from "./pokemon-heal-phase"; +import { applyAbAttrs, PostTeraFormChangeStatChangeAbAttr } from "#app/data/ability"; export class QuietFormChangePhase extends BattlePhase { protected pokemon: Pokemon; @@ -51,7 +52,7 @@ export class QuietFormChangePhase extends BattlePhase { } catch (err: unknown) { console.error(`Failed to play animation for ${spriteKey}`, err); } - sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) }); + sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()), isTerastallized: this.pokemon.isTerastallized }); [ "spriteColors", "fusionSpriteColors" ].map(k => { if (this.pokemon.summonData?.speciesForm) { k += "Base"; @@ -145,6 +146,9 @@ export class QuietFormChangePhase extends BattlePhase { movePhase.cancel(); } } + if (this.formChange.trigger instanceof SpeciesFormChangeTeraTrigger) { + applyAbAttrs(PostTeraFormChangeStatChangeAbAttr, this.pokemon, null); + } super.end(); } diff --git a/src/phases/tera-phase.ts b/src/phases/tera-phase.ts new file mode 100644 index 00000000000..f4b72d39192 --- /dev/null +++ b/src/phases/tera-phase.ts @@ -0,0 +1,51 @@ +import type Pokemon from "#app/field/pokemon"; +import { getPokemonNameWithAffix } from "#app/messages"; +import { BattlePhase } from "./battle-phase"; +import i18next from "i18next"; +import { globalScene } from "#app/global-scene"; +import { Type } from "#app/enums/type"; +import { achvs } from "#app/system/achv"; +import { SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms"; +import { CommonAnim, CommonBattleAnim } from "#app/data/battle-anims"; + +export class TeraPhase extends BattlePhase { + public pokemon: Pokemon; + + constructor(pokemon: Pokemon) { + super(); + + this.pokemon = pokemon; + } + + start() { + super.start(); + + console.log(this.pokemon.name, "terastallized to", Type[this.pokemon.teraType].toString()); + + globalScene.queueMessage(i18next.t("battle:pokemonTerastallized", { pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon), type: i18next.t(`pokemonInfo:Type.${Type[this.pokemon.teraType]}`) })); + new CommonBattleAnim(CommonAnim.TERASTALLIZE, this.pokemon).play(false, () => { + this.end(); + }); + } + + + end() { + this.pokemon.isTerastallized = true; + this.pokemon.updateSpritePipelineData(); + + if (this.pokemon.isPlayer()) { + globalScene.arena.playerTerasUsed += 1; + } + + globalScene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangeTeraTrigger); + + if (this.pokemon.isPlayer()) { + globalScene.validateAchv(achvs.TERASTALLIZE); + if (this.pokemon.teraType === Type.STELLAR) { + globalScene.validateAchv(achvs.STELLAR_TERASTALLIZE); + } + } + + super.end(); + } +} diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index c64d7ddf526..c6d145e1a4c 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -21,6 +21,7 @@ import { BattlerIndex } from "#app/battle"; import { TrickRoomTag } from "#app/data/arena-tag"; import { SwitchType } from "#enums/switch-type"; import { globalScene } from "#app/global-scene"; +import { TeraPhase } from "./tera-phase"; export class TurnStartPhase extends FieldPhase { constructor() { @@ -139,6 +140,20 @@ export class TurnStartPhase extends FieldPhase { let orderIndex = 0; + for (const o of this.getSpeedOrder()) { + const pokemon = field[o]; + const preTurnCommand = globalScene.currentBattle.preTurnCommands[o]; + + if (preTurnCommand?.skip) { + continue; + } + + switch (preTurnCommand?.command) { + case Command.TERA: + globalScene.pushPhase(new TeraPhase(pokemon)); + } + } + for (const o of moveOrder) { const pokemon = field[o]; diff --git a/src/pipelines/sprite.ts b/src/pipelines/sprite.ts index 67639d6450a..90c0e65d25c 100644 --- a/src/pipelines/sprite.ts +++ b/src/pipelines/sprite.ts @@ -351,7 +351,7 @@ export default class SpritePipeline extends FieldSpritePipeline { const data = sprite.pipelineData; const tone = data["tone"] as number[]; - const teraColor = data["teraColor"] as number[] ?? [ 0, 0, 0 ]; + const teraColor = (data["isTerastallized"] as boolean) ? (data["teraColor"] as number[] ?? [ 0, 0, 0 ]) : [ 0, 0, 0 ]; const hasShadow = data["hasShadow"] as boolean; const yShadowOffset = data["yShadowOffset"] as number; const ignoreFieldPos = data["ignoreFieldPos"] as boolean; diff --git a/src/system/arena-data.ts b/src/system/arena-data.ts index 98ab611ff3c..518acb55c89 100644 --- a/src/system/arena-data.ts +++ b/src/system/arena-data.ts @@ -10,12 +10,14 @@ export default class ArenaData { public weather: Weather | null; public terrain: Terrain | null; public tags: ArenaTag[]; + public playerTerasUsed: number; constructor(source: Arena | any) { const sourceArena = source instanceof Arena ? source as Arena : null; this.biome = sourceArena ? sourceArena.biomeType : source.biome; this.weather = sourceArena ? sourceArena.weather : source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : null; this.terrain = sourceArena ? sourceArena.terrain : source.terrain ? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft) : null; + this.playerTerasUsed = (sourceArena ? sourceArena.playerTerasUsed : source.playerTerasUsed) ?? 0; this.tags = []; if (source.tags) { diff --git a/src/system/game-data.ts b/src/system/game-data.ts index c16fab9db04..63d79d47fba 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1087,6 +1087,8 @@ export class GameData { globalScene.arena.terrain = sessionData.arena.terrain; globalScene.arena.eventTarget.dispatchEvent(new TerrainChangedEvent(TerrainType.NONE, globalScene.arena.terrain?.terrainType!, globalScene.arena.terrain?.turnsLeft!)); // TODO: is this bang correct? + globalScene.arena.playerTerasUsed = sessionData.arena.playerTerasUsed; + globalScene.arena.tags = sessionData.arena.tags; if (globalScene.arena.tags) { for (const tag of globalScene.arena.tags) { diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 6459bb5033d..20507860e4e 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -13,6 +13,7 @@ import type { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; import type { Species } from "#enums/species"; import { CustomPokemonData } from "#app/data/custom-pokemon-data"; +import type { Type } from "#app/enums/type"; export default class PokemonData { public id: number; @@ -45,6 +46,9 @@ export default class PokemonData { public pokerus: boolean; public usedTMs: Moves[]; public evoCounter: number; + public teraType: Type; + public isTerastallized: boolean; + public stellarTypesBoosted: Type[]; public fusionSpecies: Species; public fusionFormIndex: number; @@ -53,6 +57,7 @@ export default class PokemonData { public fusionVariant: Variant; public fusionGender: Gender; public fusionLuck: number; + public fusionTeraType: Type; public boss: boolean; public bossSegments?: number; @@ -103,6 +108,9 @@ export default class PokemonData { this.evoCounter = source.evoCounter ?? 0; } this.pokerus = !!source.pokerus; + this.teraType = source.teraType as Type; + this.isTerastallized = source.isTerastallized || false; + this.stellarTypesBoosted = source.stellarTypesBoosted || []; this.fusionSpecies = sourcePokemon ? sourcePokemon.fusionSpecies?.speciesId : source.fusionSpecies; this.fusionFormIndex = source.fusionFormIndex; @@ -112,6 +120,7 @@ export default class PokemonData { this.fusionGender = source.fusionGender; this.fusionLuck = source.fusionLuck !== undefined ? source.fusionLuck : (source.fusionShiny ? source.fusionVariant + 1 : 0); this.fusionCustomPokemonData = new CustomPokemonData(source.fusionCustomPokemonData); + this.fusionTeraType = (source.fusionTeraType ?? 0) as Type; this.usedTMs = source.usedTMs ?? []; this.customPokemonData = new CustomPokemonData(source.customPokemonData); diff --git a/src/system/version_migration/version_converter.ts b/src/system/version_migration/version_converter.ts index aee84805143..95537461768 100644 --- a/src/system/version_migration/version_converter.ts +++ b/src/system/version_migration/version_converter.ts @@ -7,6 +7,9 @@ import * as v1_0_4 from "./versions/v1_0_4"; // --- v1.1.0 PATCHES --- // import * as v1_1_0 from "./versions/v1_1_0"; +// --- v1.7.0 PATCHES --- // +import * as v1_7_0 from "./versions/v1_7_0"; + const LATEST_VERSION = version.split(".").map(value => parseInt(value)); /** @@ -138,6 +141,10 @@ class SessionVersionConverter extends VersionConverter { console.log("Applying v1.1.0 session data migration!"); this.callMigrators(data, v1_1_0.sessionMigrators); } + if (curMinor < 7) { + console.log("Applying v1.7.0 session data migration!"); + this.callMigrators(data, v1_7_0.sessionMigrators); + } } console.log(`Session data successfully migrated to v${version}!`); @@ -164,6 +171,10 @@ class SystemVersionConverter extends VersionConverter { console.log("Applying v1.1.0 system data migraton!"); this.callMigrators(data, v1_1_0.systemMigrators); } + if (curMinor < 7) { + console.log("Applying v1.7.0 session data migration!"); + this.callMigrators(data, v1_7_0.systemMigrators); + } } console.log(`System data successfully migrated to v${version}!`); @@ -190,6 +201,10 @@ class SettingsVersionConverter extends VersionConverter { console.log("Applying v1.1.0 settings data migraton!"); this.callMigrators(data, v1_1_0.settingsMigrators); } + if (curMinor < 7) { + console.log("Applying v1.7.0 session data migration!"); + this.callMigrators(data, v1_7_0.settingsMigrators); + } } console.log(`System data successfully migrated to v${version}!`); diff --git a/src/system/version_migration/versions/v1_7_0.ts b/src/system/version_migration/versions/v1_7_0.ts new file mode 100644 index 00000000000..2acb9d8151a --- /dev/null +++ b/src/system/version_migration/versions/v1_7_0.ts @@ -0,0 +1,49 @@ +import { getPokemonSpeciesForm } from "#app/data/pokemon-species"; +import type { SessionSaveData } from "#app/system/game-data"; +import * as Utils from "#app/utils"; + +export const systemMigrators = [] as const; + +export const settingsMigrators = [] as const; + +export const sessionMigrators = [ + function migrateTera(data: SessionSaveData) { + for (let i = 0; i < data.modifiers.length;) { + if (data.modifiers[i].className === "TerastallizeModifier") { + data.party.forEach((p) => { + if (p.id === data.modifiers[i].args[0]) { + p.teraType = data.modifiers[i].args[1]; + } + }); + data.modifiers.splice(i, 1); + } else { + i++; + } + } + + for (let i = 0; i < data.enemyModifiers.length;) { + if (data.enemyModifiers[i].className === "TerastallizeModifier") { + data.enemyParty.forEach((p) => { + if (p.id === data.enemyModifiers[i].args[0]) { + p.teraType = data.enemyModifiers[i].args[1]; + } + }); + data.enemyModifiers.splice(i, 1); + } else { + i++; + } + } + + data.party.forEach(p => { + if (Utils.isNullOrUndefined(p.teraType)) { + p.teraType = getPokemonSpeciesForm(p.species, p.formIndex).type1; + } + }); + + data.enemyParty.forEach(p => { + if (Utils.isNullOrUndefined(p.teraType)) { + p.teraType = getPokemonSpeciesForm(p.species, p.formIndex).type1; + } + }); + } +] as const; diff --git a/src/test/abilities/libero.test.ts b/src/test/abilities/libero.test.ts index 42627da51a3..f6e85979c69 100644 --- a/src/test/abilities/libero.test.ts +++ b/src/test/abilities/libero.test.ts @@ -11,7 +11,7 @@ import { Species } from "#enums/species"; import { WeatherType } from "#enums/weather-type"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; describe("Abilities - Libero", () => { @@ -258,7 +258,7 @@ describe("Abilities - Libero", () => { const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); - vi.spyOn(leadPokemon, "isTerastallized").mockReturnValue(true); + leadPokemon.isTerastallized = true; game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/abilities/protean.test.ts b/src/test/abilities/protean.test.ts index 787834f8a9d..c7d04b9e1c8 100644 --- a/src/test/abilities/protean.test.ts +++ b/src/test/abilities/protean.test.ts @@ -11,7 +11,7 @@ import { Species } from "#enums/species"; import { WeatherType } from "#enums/weather-type"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; describe("Abilities - Protean", () => { @@ -258,7 +258,7 @@ describe("Abilities - Protean", () => { const leadPokemon = game.scene.getPlayerPokemon()!; expect(leadPokemon).not.toBe(undefined); - vi.spyOn(leadPokemon, "isTerastallized").mockReturnValue(true); + leadPokemon.isTerastallized = true; game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/moves/effectiveness.test.ts b/src/test/moves/effectiveness.test.ts index c78416b1237..09c94c740cc 100644 --- a/src/test/moves/effectiveness.test.ts +++ b/src/test/moves/effectiveness.test.ts @@ -6,7 +6,6 @@ import { Abilities } from "#app/enums/abilities"; import { Moves } from "#app/enums/moves"; import { Species } from "#app/enums/species"; import * as Messages from "#app/messages"; -import { TerastallizeModifier, overrideHeldItems } from "#app/modifier/modifier"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, describe, expect, it, vi } from "vitest"; @@ -15,15 +14,14 @@ function testMoveEffectiveness(game: GameManager, move: Moves, targetSpecies: Sp expected: number, targetAbility: Abilities = Abilities.BALL_FETCH, teraType?: Type): void { // Suppress getPokemonNameWithAffix because it calls on a null battle spec vi.spyOn(Messages, "getPokemonNameWithAffix").mockReturnValue(""); - game.override - .enemyAbility(targetAbility) - .enemyHeldItems([{ name:"TERA_SHARD", type: teraType }]); + game.override.enemyAbility(targetAbility); const user = game.scene.addPlayerPokemon(getPokemonSpecies(Species.SNORLAX), 5); const target = game.scene.addEnemyPokemon(getPokemonSpecies(targetSpecies), 5, TrainerSlot.NONE); if (teraType !== undefined) { - overrideHeldItems(target, false); + target.teraType = teraType; + target.isTerastallized = true; } expect(target.getMoveEffectiveness(user, allMoves[move])).toBe(expected); @@ -40,7 +38,6 @@ describe("Moves - Type Effectiveness", () => { type: Phaser.HEADLESS, }); game = new GameManager(phaserGame); - TerastallizeModifier.prototype.apply = (args) => true; game.override.ability(Abilities.BALL_FETCH); }); diff --git a/src/test/moves/freeze_dry.test.ts b/src/test/moves/freeze_dry.test.ts index 9206a103a35..f207e297191 100644 --- a/src/test/moves/freeze_dry.test.ts +++ b/src/test/moves/freeze_dry.test.ts @@ -117,11 +117,12 @@ describe("Moves - Freeze-Dry", () => { }); it("should deal 2x damage to steel type terastallized into water", async () => { - game.override.enemySpecies(Species.SKARMORY) - .enemyHeldItems([{ name: "TERA_SHARD", type: Type.WATER }]); + game.override.enemySpecies(Species.SKARMORY); await game.classicMode.startBattle(); const enemy = game.scene.getEnemyPokemon()!; + enemy.teraType = Type.WATER; + enemy.isTerastallized = true; vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FREEZE_DRY); @@ -132,11 +133,12 @@ describe("Moves - Freeze-Dry", () => { }); 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 }]); + game.override.enemySpecies(Species.PELIPPER); await game.classicMode.startBattle(); const enemy = game.scene.getEnemyPokemon()!; + enemy.teraType = Type.FIRE; + enemy.isTerastallized = true; vi.spyOn(enemy, "getMoveEffectiveness"); game.move.select(Moves.FREEZE_DRY); diff --git a/src/test/moves/tar_shot.test.ts b/src/test/moves/tar_shot.test.ts index 5fb70abc19c..66f540e4f9f 100644 --- a/src/test/moves/tar_shot.test.ts +++ b/src/test/moves/tar_shot.test.ts @@ -83,10 +83,12 @@ describe("Moves - Tar Shot", () => { }); it("does not double the effectiveness of Fire-type moves against a Pokémon that is Terastallized", async () => { - game.override.enemyHeldItems([{ name: "TERA_SHARD", type: Type.GRASS }]).enemySpecies(Species.SPRIGATITO); + game.override.enemySpecies(Species.SPRIGATITO); await game.classicMode.startBattle([ Species.PIKACHU ]); const enemy = game.scene.getEnemyPokemon()!; + enemy.teraType = Type.GRASS; + enemy.isTerastallized = true; vi.spyOn(enemy, "getMoveEffectiveness"); @@ -119,7 +121,8 @@ describe("Moves - Tar Shot", () => { await game.toNextTurn(); - game.override.enemyHeldItems([{ name: "TERA_SHARD", type: Type.GRASS }]); + enemy.teraType = Type.GRASS; + enemy.isTerastallized = true; game.move.select(Moves.FIRE_PUNCH); await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); diff --git a/src/test/moves/tera_blast.test.ts b/src/test/moves/tera_blast.test.ts index 34d171b47bb..08e401ef9d1 100644 --- a/src/test/moves/tera_blast.test.ts +++ b/src/test/moves/tera_blast.test.ts @@ -35,7 +35,6 @@ describe("Moves - Tera Blast", () => { .starterSpecies(Species.FEEBAS) .moveset([ Moves.TERA_BLAST ]) .ability(Abilities.BALL_FETCH) - .startingHeldItems([{ name: "TERA_SHARD", type: Type.FIRE }]) .enemySpecies(Species.MAGIKARP) .enemyMoveset(Moves.SPLASH) .enemyAbility(Abilities.STURDY) @@ -45,13 +44,15 @@ describe("Moves - Tera Blast", () => { }); it("changes type to match user's tera type", async () => { - game.override - .enemySpecies(Species.FURRET) - .startingHeldItems([{ name: "TERA_SHARD", type: Type.FIGHTING }]); + game.override.enemySpecies(Species.FURRET); await game.startBattle(); const enemyPokemon = game.scene.getEnemyPokemon()!; vi.spyOn(enemyPokemon, "apply"); + const playerPokemon = game.scene.getPlayerPokemon()!; + playerPokemon.teraType = Type.FIGHTING; + playerPokemon.isTerastallized = true; + game.move.select(Moves.TERA_BLAST); await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); @@ -60,10 +61,12 @@ describe("Moves - Tera Blast", () => { }, 20000); it("increases power if user is Stellar tera type", async () => { - game.override.startingHeldItems([{ name: "TERA_SHARD", type: Type.STELLAR }]); - await game.startBattle(); + const playerPokemon = game.scene.getPlayerPokemon()!; + playerPokemon.teraType = Type.STELLAR; + playerPokemon.isTerastallized = true; + game.move.select(Moves.TERA_BLAST); await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); @@ -72,13 +75,15 @@ describe("Moves - Tera Blast", () => { }, 20000); it("is super effective against terastallized targets if user is Stellar tera type", async () => { - game.override.startingHeldItems([{ name: "TERA_SHARD", type: Type.STELLAR }]); - await game.startBattle(); + const playerPokemon = game.scene.getPlayerPokemon()!; + playerPokemon.teraType = Type.STELLAR; + playerPokemon.isTerastallized = true; + const enemyPokemon = game.scene.getEnemyPokemon()!; vi.spyOn(enemyPokemon, "apply"); - vi.spyOn(enemyPokemon, "isTerastallized").mockReturnValue(true); + enemyPokemon.isTerastallized = true; game.move.select(Moves.TERA_BLAST); await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); @@ -93,6 +98,7 @@ describe("Moves - Tera Blast", () => { const playerPokemon = game.scene.getPlayerPokemon()!; playerPokemon.stats[Stat.ATK] = 100; playerPokemon.stats[Stat.SPATK] = 1; + playerPokemon.isTerastallized = true; vi.spyOn(teraBlastAttr, "apply"); @@ -169,10 +175,11 @@ describe("Moves - Tera Blast", () => { it("causes stat drops if user is Stellar tera type", async () => { - game.override.startingHeldItems([{ name: "TERA_SHARD", type: Type.STELLAR }]); await game.startBattle(); const playerPokemon = game.scene.getPlayerPokemon()!; + playerPokemon.teraType = Type.STELLAR; + playerPokemon.isTerastallized = true; game.move.select(Moves.TERA_BLAST); await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); diff --git a/src/test/moves/tera_starstorm.test.ts b/src/test/moves/tera_starstorm.test.ts index 22dd5b3c4d1..1e934b88c86 100644 --- a/src/test/moves/tera_starstorm.test.ts +++ b/src/test/moves/tera_starstorm.test.ts @@ -29,8 +29,7 @@ describe("Moves - Tera Starstorm", () => { .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) .enemyLevel(30) - .enemySpecies(Species.MAGIKARP) - .startingHeldItems([{ name: "TERA_SHARD", type: Type.FIRE }]); + .enemySpecies(Species.MAGIKARP); }); it("changes type to Stellar when used by Terapagos in its Stellar Form", async () => { @@ -38,19 +37,22 @@ describe("Moves - Tera Starstorm", () => { await game.classicMode.startBattle([ Species.TERAPAGOS ]); const terapagos = game.scene.getPlayerPokemon()!; + terapagos.isTerastallized = true; vi.spyOn(terapagos, "getMoveType"); game.move.select(Moves.TERA_STARSTORM); await game.phaseInterceptor.to("TurnEndPhase"); - expect(terapagos.isTerastallized()).toBe(true); expect(terapagos.getMoveType).toHaveReturnedWith(Type.STELLAR); }); it("targets both opponents in a double battle when used by Terapagos in its Stellar Form", async () => { await game.classicMode.startBattle([ Species.MAGIKARP, Species.TERAPAGOS ]); + const terapagos = game.scene.getPlayerParty()[1]; + terapagos.isTerastallized = true; + game.move.select(Moves.TERA_STARSTORM, 0, BattlerIndex.ENEMY); game.move.select(Moves.TERA_STARSTORM, 1); @@ -82,6 +84,8 @@ describe("Moves - Tera Starstorm", () => { fusionedMon.fusionGender = magikarp.gender; fusionedMon.fusionLuck = magikarp.luck; + fusionedMon.isTerastallized = true; + vi.spyOn(fusionedMon, "getMoveType"); game.move.select(Moves.TERA_STARSTORM, 0); @@ -90,7 +94,6 @@ describe("Moves - Tera Starstorm", () => { // Fusion and terastallized expect(fusionedMon.isFusion()).toBe(true); - expect(fusionedMon.isTerastallized()).toBe(true); // Move effects should be applied expect(fusionedMon.getMoveType).toHaveReturnedWith(Type.STELLAR); expect(game.scene.getEnemyField().every(pokemon => pokemon.isFullHp())).toBe(false); diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index fa8767f5eb0..ab7f76daf0b 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -324,9 +324,9 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.lastTeraType = pokemon.getTeraType(); this.teraIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1, 2); - this.teraIcon.setVisible(this.lastTeraType !== Type.UNKNOWN); + this.teraIcon.setVisible(pokemon.isTerastallized); this.teraIcon.on("pointerover", () => { - if (this.lastTeraType !== Type.UNKNOWN) { + if (pokemon.isTerastallized) { globalScene.ui.showTooltip("", i18next.t("fightUiHandler:teraHover", { type: i18next.t(`pokemonInfo:Type.${Type[this.lastTeraType]}`) })); } }); @@ -542,7 +542,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.genderText.setPositionRelative(this.nameText, this.nameText.displayWidth, 0); } - const teraType = pokemon.getTeraType(); + const teraType = pokemon.isTerastallized ? pokemon.getTeraType() : Type.UNKNOWN; const teraTypeUpdated = this.lastTeraType !== teraType; if (teraTypeUpdated) { diff --git a/src/ui/command-ui-handler.ts b/src/ui/command-ui-handler.ts index de75f29ff6f..f23cc78c9f7 100644 --- a/src/ui/command-ui-handler.ts +++ b/src/ui/command-ui-handler.ts @@ -7,18 +7,24 @@ import { Button } from "#enums/buttons"; import { getPokemonNameWithAffix } from "#app/messages"; import { CommandPhase } from "#app/phases/command-phase"; import { globalScene } from "#app/global-scene"; +import { TerastallizeAccessModifier } from "#app/modifier/modifier"; +import { Type } from "#app/enums/type"; +import { getTypeRgb } from "#app/data/type"; export enum Command { FIGHT = 0, BALL, POKEMON, - RUN + RUN, + TERA } export default class CommandUiHandler extends UiHandler { private commandsContainer: Phaser.GameObjects.Container; private cursorObj: Phaser.GameObjects.Image | null; + private teraButton: Phaser.GameObjects.Sprite; + protected fieldIndex: number = 0; protected cursor2: number = 0; @@ -40,6 +46,13 @@ export default class CommandUiHandler extends UiHandler { this.commandsContainer.setVisible(false); ui.add(this.commandsContainer); + this.teraButton = globalScene.add.sprite(-32, 15, "button_tera"); + this.teraButton.setName("terrastallize-button"); + this.teraButton.setScale(1.3); + this.teraButton.setFrame("fire"); + this.teraButton.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true, teraColor: getTypeRgb(Type.FIRE), isTerastallized: false }); + this.commandsContainer.add(this.teraButton); + for (let c = 0; c < commands.length; c++) { const commandText = addTextObject(c % 2 === 0 ? 0 : 55.8, c < 2 ? 0 : 16, commands[c], TextStyle.WINDOW); commandText.setName(commands[c]); @@ -62,11 +75,22 @@ export default class CommandUiHandler extends UiHandler { commandPhase = globalScene.getStandbyPhase() as CommandPhase; } + if (this.canTera()) { + this.teraButton.setVisible(true); + this.teraButton.setFrame(Type[globalScene.getField()[this.fieldIndex].getTeraType()].toLowerCase()); + } else { + this.teraButton.setVisible(false); + if (this.cursor === Command.TERA) { + this.setCursor(Command.FIGHT); + } + } + this.toggleTeraButton(); + const messageHandler = this.getUi().getMessageHandler(); messageHandler.bg.setVisible(true); messageHandler.commandWindow.setVisible(true); messageHandler.movesWindowContainer.setVisible(false); - messageHandler.message.setWordWrapWidth(1110); + messageHandler.message.setWordWrapWidth(this.canTera() ? 910 : 1110); messageHandler.showText(i18next.t("commandUiHandler:actionMessage", { pokemonName: getPokemonNameWithAffix(commandPhase.getPokemon()) }), 0); if (this.getCursor() === Command.POKEMON) { this.setCursor(Command.FIGHT); @@ -108,6 +132,10 @@ export default class CommandUiHandler extends UiHandler { (globalScene.getCurrentPhase() as CommandPhase).handleCommand(Command.RUN, 0); success = true; break; + case Command.TERA: + ui.setMode(Mode.FIGHT, (globalScene.getCurrentPhase() as CommandPhase).getFieldIndex(), Command.TERA); + success = true; + break; } } else { (globalScene.getCurrentPhase() as CommandPhase).cancel(); @@ -115,23 +143,29 @@ export default class CommandUiHandler extends UiHandler { } else { switch (button) { case Button.UP: - if (cursor >= 2) { + if (cursor === Command.POKEMON || cursor === Command.RUN) { success = this.setCursor(cursor - 2); } break; case Button.DOWN: - if (cursor < 2) { + if (cursor === Command.FIGHT || cursor === Command.BALL) { success = this.setCursor(cursor + 2); } break; case Button.LEFT: - if (cursor % 2 === 1) { + if (cursor === Command.BALL || cursor === Command.RUN) { success = this.setCursor(cursor - 1); + } else if ((cursor === Command.FIGHT || cursor === Command.POKEMON) && this.canTera()) { + success = this.setCursor(Command.TERA); + this.toggleTeraButton(); } break; case Button.RIGHT: - if (cursor % 2 === 0) { + if (cursor === Command.FIGHT || cursor === Command.POKEMON) { success = this.setCursor(cursor + 1); + } else if (cursor === Command.TERA) { + success = this.setCursor(Command.FIGHT); + this.toggleTeraButton(); } break; } @@ -144,6 +178,17 @@ export default class CommandUiHandler extends UiHandler { return success; } + canTera(): boolean { + const hasTeraMod = !!globalScene.getModifiers(TerastallizeAccessModifier).length; + const currentTeras = globalScene.arena.playerTerasUsed; + const plannedTera = globalScene.currentBattle.preTurnCommands[0]?.command === Command.TERA && this.fieldIndex > 0 ? 1 : 0; + return hasTeraMod && (currentTeras + plannedTera) < 1; + } + + toggleTeraButton() { + this.teraButton.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true, teraColor: getTypeRgb(globalScene.getField()[this.fieldIndex].getTeraType()), isTerastallized: this.getCursor() === Command.TERA }); + } + getCursor(): number { return !this.fieldIndex ? this.cursor : this.cursor2; } @@ -163,7 +208,12 @@ export default class CommandUiHandler extends UiHandler { this.commandsContainer.add(this.cursorObj); } - this.cursorObj.setPosition(-5 + (cursor % 2 === 1 ? 56 : 0), 8 + (cursor >= 2 ? 16 : 0)); + if (cursor === Command.TERA) { + this.cursorObj.setVisible(false); + } else { + this.cursorObj.setPosition(-5 + (cursor % 2 === 1 ? 56 : 0), 8 + (cursor >= 2 ? 16 : 0)); + this.cursorObj.setVisible(true); + } return changed; } diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 72fb90066e7..1c1dceb24a5 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -33,6 +33,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { private moveInfoOverlay : MoveInfoOverlay; protected fieldIndex: number = 0; + protected fromCommand: Command = Command.FIGHT; protected cursor2: number = 0; constructor() { @@ -114,6 +115,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { super.show(args); this.fieldIndex = args.length ? args[0] as number : 0; + this.fromCommand = args.length > 1 ? args[1] as Command : Command.FIGHT; const messageHandler = this.getUi().getMessageHandler(); messageHandler.bg.setVisible(false); @@ -140,7 +142,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { if (button === Button.CANCEL || button === Button.ACTION) { if (button === Button.ACTION) { - if ((globalScene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, cursor, false)) { + if ((globalScene.getCurrentPhase() as CommandPhase).handleCommand(this.fromCommand, cursor, false)) { success = true; } else { ui.playError(); diff --git a/src/ui/run-info-ui-handler.ts b/src/ui/run-info-ui-handler.ts index 02bcba17a73..bf07374e21a 100644 --- a/src/ui/run-info-ui-handler.ts +++ b/src/ui/run-info-ui-handler.ts @@ -420,17 +420,6 @@ export default class RunInfoUiHandler extends UiHandler { private parseTrainerDefeat(enemyContainer: Phaser.GameObjects.Container) { // Loads and adds trainer sprites to the UI this.showTrainerSprites(enemyContainer); - // Determining which Terastallize Modifier belongs to which Pokemon - // Creates a dictionary {PokemonId: TeraShardType} - const teraPokemon = {}; - this.runInfo.enemyModifiers.forEach((m) => { - const modifier = m.toModifier(this.modifiersModule[m.className]); - if (modifier instanceof Modifier.TerastallizeModifier) { - const teraDetails = modifier?.getArgs(); - const pkmnId = teraDetails[0]; - teraPokemon[pkmnId] = teraDetails[1]; - } - }); // Creates the Pokemon icons + level information and adds it to enemyContainer // 2 Rows x 3 Columns @@ -444,18 +433,6 @@ export default class RunInfoUiHandler extends UiHandler { enemyData["player"] = true; const enemy = enemyData.toPokemon(); const enemyIcon = globalScene.addPokemonIcon(enemy, 0, 0, 0, 0); - // Applying Terastallizing Type tint to Pokemon icon - // If the Pokemon is a fusion, it has two sprites and so, the tint has to be applied to each icon separately - const enemySprite1 = enemyIcon.list[0] as Phaser.GameObjects.Sprite; - const enemySprite2 = (enemyIcon.list.length > 1) ? enemyIcon.list[1] as Phaser.GameObjects.Sprite : undefined; - if (teraPokemon[enemyData.id]) { - const teraTint = getTypeRgb(teraPokemon[enemyData.id]); - const teraColor = new Phaser.Display.Color(teraTint[0], teraTint[1], teraTint[2]); - enemySprite1.setTint(teraColor.color); - if (enemySprite2) { - enemySprite2.setTint(teraColor.color); - } - } enemyIcon.setPosition(39 * (e % 3) + 5, (35 * pokemonRowHeight)); const enemyLevel = addTextObject(43 * (e % 3), (27 * (pokemonRowHeight + 1)), `${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`, isBoss ? TextStyle.PARTY_RED : TextStyle.PARTY, { fontSize: "54px" }); enemyLevel.setShadow(0, 0, undefined); diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index cf5d40bc006..1526ae982e5 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -334,6 +334,7 @@ export default class SummaryUiHandler extends UiHandler { console.error(`Failed to play animation for ${spriteKey}`, err); } this.pokemonSprite.setPipelineData("teraColor", getTypeRgb(this.pokemon.getTeraType())); + this.pokemonSprite.setPipelineData("isTerastallized", this.pokemon.isTerastallized); this.pokemonSprite.setPipelineData("ignoreTimeTint", true); this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey()); this.pokemonSprite.setPipelineData("shiny", this.pokemon.shiny); @@ -782,7 +783,7 @@ export default class SummaryUiHandler extends UiHandler { if (types.length > 1) { profileContainer.add(getTypeIcon(1, types[1])); } - if (this.pokemon?.isTerastallized()) { + if (this.pokemon?.isTerastallized) { profileContainer.add(getTypeIcon(types.length, this.pokemon.getTeraType(), true)); } From 4361aa089ba5af9f2ac0e3400e50937475b09c84 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sun, 16 Feb 2025 17:31:46 -0600 Subject: [PATCH 12/15] [Refactor] Replace integer holder with number holder (#5350) * Replace integer holder with number holder * Remove duplicate NumberHolder --------- Co-authored-by: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> --- src/battle-scene.ts | 4 +- src/battle.ts | 2 +- src/data/ability.ts | 10 ++--- src/data/challenge.ts | 32 ++++++++-------- src/data/move.ts | 38 +++++++++---------- .../encounters/safari-zone-encounter.ts | 4 +- .../encounters/weird-dream-encounter.ts | 4 +- src/field/pokemon.ts | 14 +++---- src/modifier/modifier-type.ts | 4 +- src/phases/money-reward-phase.ts | 2 +- src/phases/pokemon-heal-phase.ts | 2 +- src/phases/select-modifier-phase.ts | 2 +- src/test/achievements/achievement.test.ts | 4 +- src/ui/modifier-select-ui-handler.ts | 4 +- src/utils.ts | 7 ---- 15 files changed, 64 insertions(+), 69 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 4033f44eacb..c7e3d4bc928 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1212,7 +1212,7 @@ export default class BattleScene extends SceneBase { } getDoubleBattleChance(newWaveIndex: number, playerField: PlayerPokemon[]) { - const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); + const doubleChance = new Utils.NumberHolder(newWaveIndex % 10 === 0 ? 32 : 8); this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, false, doubleChance)); return Math.max(doubleChance.value, 1); @@ -2628,7 +2628,7 @@ export default class BattleScene extends SceneBase { const args: unknown[] = []; if (modifier instanceof PokemonHpRestoreModifier) { if (!(modifier as PokemonHpRestoreModifier).fainted) { - const hpRestoreMultiplier = new Utils.IntegerHolder(1); + const hpRestoreMultiplier = new Utils.NumberHolder(1); this.applyModifiers(HealingBoosterModifier, true, hpRestoreMultiplier); args.push(hpRestoreMultiplier.value); } else { diff --git a/src/battle.ts b/src/battle.ts index 807ac215ea8..242954a3729 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -203,7 +203,7 @@ export default class Battle { } pickUpScatteredMoney(): void { - const moneyAmount = new Utils.IntegerHolder(globalScene.currentBattle.moneyScattered); + const moneyAmount = new Utils.NumberHolder(globalScene.currentBattle.moneyScattered); globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); if (globalScene.arena.getTag(ArenaTagType.HAPPY_HOUR)) { diff --git a/src/data/ability.ts b/src/data/ability.ts index 6ba5f685acd..bf3b04e1f63 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -3115,7 +3115,7 @@ export class ChangeMovePriorityAbAttr extends AbAttr { return false; } - (args[1] as Utils.IntegerHolder).value += this.changeAmount; + (args[1] as Utils.NumberHolder).value += this.changeAmount; return true; } } @@ -3957,7 +3957,7 @@ export class StatStageChangeMultiplierAbAttr extends AbAttr { } override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value *= this.multiplier; + (args[0] as Utils.NumberHolder).value *= this.multiplier; return true; } @@ -4058,7 +4058,7 @@ export class HealFromBerryUseAbAttr extends AbAttr { export class RunSuccessAbAttr extends AbAttr { apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value = 256; + (args[0] as Utils.NumberHolder).value = 256; return true; } @@ -4128,7 +4128,7 @@ export class ArenaTrapAbAttr extends CheckTrappedAbAttr { export class MaxMultiHitAbAttr extends AbAttr { apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value = 0; + (args[0] as Utils.NumberHolder).value = 0; return true; } @@ -4259,7 +4259,7 @@ export class PostFaintHPDamageAbAttr extends PostFaintAbAttr { export class RedirectMoveAbAttr extends AbAttr { apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { if (this.canRedirect(args[0] as Moves)) { - const target = args[1] as Utils.IntegerHolder; + const target = args[1] as Utils.NumberHolder; const newTarget = pokemon.getBattlerIndex(); if (target.value !== newTarget) { target.value = newTarget; diff --git a/src/data/challenge.ts b/src/data/challenge.ts index b6d123ce933..c6e85be2389 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -349,23 +349,23 @@ export abstract class Challenge { /** * An apply function for AI_LEVEL challenges. Derived classes should alter this. - * @param level {@link Utils.IntegerHolder} The generated level. + * @param level {@link Utils.NumberHolder} The generated level. * @param levelCap {@link Number} The current level cap. * @param isTrainer {@link Boolean} Whether this is a trainer pokemon. * @param isBoss {@link Boolean} Whether this is a non-trainer boss pokemon. * @returns {@link boolean} Whether this function did anything. */ - applyLevelChange(level: Utils.IntegerHolder, levelCap: number, isTrainer: boolean, isBoss: boolean): boolean { + applyLevelChange(level: Utils.NumberHolder, levelCap: number, isTrainer: boolean, isBoss: boolean): boolean { return false; } /** * An apply function for AI_MOVE_SLOTS challenges. Derived classes should alter this. * @param pokemon {@link Pokemon} The pokemon that is being considered. - * @param moveSlots {@link Utils.IntegerHolder} The amount of move slots. + * @param moveSlots {@link Utils.NumberHolder} The amount of move slots. * @returns {@link boolean} Whether this function did anything. */ - applyMoveSlot(pokemon: Pokemon, moveSlots: Utils.IntegerHolder): boolean { + applyMoveSlot(pokemon: Pokemon, moveSlots: Utils.NumberHolder): boolean { return false; } @@ -393,10 +393,10 @@ export abstract class Challenge { * @param pokemon {@link Pokemon} What pokemon would learn the move. * @param moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param move {@link Moves} The move in question. - * @param level {@link Utils.IntegerHolder} The level threshold for access. + * @param level {@link Utils.NumberHolder} The level threshold for access. * @returns {@link boolean} Whether this function did anything. */ - applyMoveAccessLevel(pokemon: Pokemon, moveSource: MoveSourceType, move: Moves, level: Utils.IntegerHolder): boolean { + applyMoveAccessLevel(pokemon: Pokemon, moveSource: MoveSourceType, move: Moves, level: Utils.NumberHolder): boolean { return false; } @@ -405,10 +405,10 @@ export abstract class Challenge { * @param pokemon {@link Pokemon} What pokemon would learn the move. * @param moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param move {@link Moves} The move in question. - * @param weight {@link Utils.IntegerHolder} The base weight of the move + * @param weight {@link Utils.NumberHolder} The base weight of the move * @returns {@link boolean} Whether this function did anything. */ - applyMoveWeight(pokemon: Pokemon, moveSource: MoveSourceType, move: Moves, level: Utils.IntegerHolder): boolean { + applyMoveWeight(pokemon: Pokemon, moveSource: MoveSourceType, move: Moves, level: Utils.NumberHolder): boolean { return false; } @@ -913,22 +913,22 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType * Apply all challenges that modify what level AI are. * @param gameMode {@link GameMode} The current gameMode * @param challengeType {@link ChallengeType} ChallengeType.AI_LEVEL - * @param level {@link Utils.IntegerHolder} The generated level of the pokemon. + * @param level {@link Utils.NumberHolder} The generated level of the pokemon. * @param levelCap {@link Number} The maximum level cap for the current wave. * @param isTrainer {@link Boolean} Whether this is a trainer pokemon. * @param isBoss {@link Boolean} Whether this is a non-trainer boss pokemon. * @returns True if any challenge was successfully applied. */ -export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.AI_LEVEL, level: Utils.IntegerHolder, levelCap: number, isTrainer: boolean, isBoss: boolean): boolean; +export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.AI_LEVEL, level: Utils.NumberHolder, levelCap: number, isTrainer: boolean, isBoss: boolean): boolean; /** * Apply all challenges that modify how many move slots the AI has. * @param gameMode {@link GameMode} The current gameMode * @param challengeType {@link ChallengeType} ChallengeType.AI_MOVE_SLOTS * @param pokemon {@link Pokemon} The pokemon being considered. - * @param moveSlots {@link Utils.IntegerHolder} The amount of move slots. + * @param moveSlots {@link Utils.NumberHolder} The amount of move slots. * @returns True if any challenge was successfully applied. */ -export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.AI_MOVE_SLOTS, pokemon: Pokemon, moveSlots: Utils.IntegerHolder): boolean; +export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.AI_MOVE_SLOTS, pokemon: Pokemon, moveSlots: Utils.NumberHolder): boolean; /** * Apply all challenges that modify whether a pokemon has its passive. * @param gameMode {@link GameMode} The current gameMode @@ -952,10 +952,10 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType * @param pokemon {@link Pokemon} What pokemon would learn the move. * @param moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param move {@link Moves} The move in question. - * @param level {@link Utils.IntegerHolder} The level threshold for access. + * @param level {@link Utils.NumberHolder} The level threshold for access. * @returns True if any challenge was successfully applied. */ -export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.MOVE_ACCESS, pokemon: Pokemon, moveSource: MoveSourceType, move: Moves, level: Utils.IntegerHolder): boolean; +export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.MOVE_ACCESS, pokemon: Pokemon, moveSource: MoveSourceType, move: Moves, level: Utils.NumberHolder): boolean; /** * Apply all challenges that modify what weight a pokemon gives to move generation * @param gameMode {@link GameMode} The current gameMode @@ -963,10 +963,10 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType * @param pokemon {@link Pokemon} What pokemon would learn the move. * @param moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param move {@link Moves} The move in question. - * @param weight {@link Utils.IntegerHolder} The weight of the move. + * @param weight {@link Utils.NumberHolder} The weight of the move. * @returns True if any challenge was successfully applied. */ -export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.MOVE_WEIGHT, pokemon: Pokemon, moveSource: MoveSourceType, move: Moves, weight: Utils.IntegerHolder): boolean; +export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.MOVE_WEIGHT, pokemon: Pokemon, moveSource: MoveSourceType, move: Moves, weight: Utils.NumberHolder): boolean; export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.FLIP_STAT, pokemon: Pokemon, baseStats: number[]): boolean; diff --git a/src/data/move.ts b/src/data/move.ts index 7e504e87667..60c5690ae44 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -908,7 +908,7 @@ export class AttackMove extends Move { attackScore = Math.pow(effectiveness - 1, 2) * effectiveness < 1 ? -2 : 2; if (attackScore) { if (this.category === MoveCategory.PHYSICAL) { - const atk = new Utils.IntegerHolder(user.getEffectiveStat(Stat.ATK, target)); + const atk = new Utils.NumberHolder(user.getEffectiveStat(Stat.ATK, target)); applyMoveAttrs(VariableAtkAttr, user, target, move, atk); if (atk.value > user.getEffectiveStat(Stat.SPATK, target)) { const statRatio = user.getEffectiveStat(Stat.SPATK, target) / atk.value; @@ -919,7 +919,7 @@ export class AttackMove extends Move { } } } else { - const spAtk = new Utils.IntegerHolder(user.getEffectiveStat(Stat.SPATK, target)); + const spAtk = new Utils.NumberHolder(user.getEffectiveStat(Stat.SPATK, target)); applyMoveAttrs(VariableAtkAttr, user, target, move, spAtk); if (spAtk.value > user.getEffectiveStat(Stat.ATK, target)) { const statRatio = user.getEffectiveStat(Stat.ATK, target) / spAtk.value; @@ -1337,7 +1337,7 @@ export class IgnoreOpponentStatStagesAttr extends MoveAttr { export class HighCritAttr extends MoveAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value++; + (args[0] as Utils.NumberHolder).value++; return true; } @@ -1369,7 +1369,7 @@ export class FixedDamageAttr extends MoveAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value = this.getDamage(user, target, move); + (args[0] as Utils.NumberHolder).value = this.getDamage(user, target, move); return true; } @@ -1385,7 +1385,7 @@ export class UserHpDamageAttr extends FixedDamageAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value = user.hp; + (args[0] as Utils.NumberHolder).value = user.hp; return true; } @@ -1437,7 +1437,7 @@ export class MatchHpAttr extends FixedDamageAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value = target.hp - user.hp; + (args[0] as Utils.NumberHolder).value = target.hp - user.hp; return true; } @@ -1467,7 +1467,7 @@ export class CounterDamageAttr extends FixedDamageAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const damage = user.turnData.attacksReceived.filter(ar => this.moveFilter(allMoves[ar.move])).reduce((total: number, ar: AttackMoveResult) => total + ar.damage, 0); - (args[0] as Utils.IntegerHolder).value = Utils.toDmgValue(damage * this.multiplier); + (args[0] as Utils.NumberHolder).value = Utils.toDmgValue(damage * this.multiplier); return true; } @@ -1499,7 +1499,7 @@ export class RandomLevelDamageAttr extends FixedDamageAttr { export class ModifiedDamageAttr extends MoveAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const initialDamage = args[0] as Utils.IntegerHolder; + const initialDamage = args[0] as Utils.NumberHolder; initialDamage.value = this.getModifiedDamage(user, target, move, initialDamage.value); return true; @@ -2164,7 +2164,7 @@ export class IncrementMovePriorityAttr extends MoveAttr { * @param user {@linkcode Pokemon} using this move * @param target {@linkcode Pokemon} target of this move * @param move {@linkcode Move} being used - * @param args [0] {@linkcode Utils.IntegerHolder} for move priority. + * @param args [0] {@linkcode Utils.NumberHolder} for move priority. * @returns true if function succeeds */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { @@ -2172,7 +2172,7 @@ export class IncrementMovePriorityAttr extends MoveAttr { return false; } - (args[0] as Utils.IntegerHolder).value += this.increaseAmount; + (args[0] as Utils.NumberHolder).value += this.increaseAmount; return true; } } @@ -2210,7 +2210,7 @@ export class MultiHitAttr extends MoveAttr { * @param user {@linkcode Pokemon} that used the attack * @param target {@linkcode Pokemon} targeted by the attack * @param move {@linkcode Move} being used - * @param args [0] {@linkcode Utils.IntegerHolder} storing the hit count of the attack + * @param args [0] {@linkcode Utils.NumberHolder} storing the hit count of the attack * @returns True */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { @@ -2277,7 +2277,7 @@ export class ChangeMultiHitTypeAttr extends MoveAttr { export class WaterShurikenMultiHitTypeAttr extends ChangeMultiHitTypeAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { if (user.species.speciesId === Species.GRENINJA && user.hasAbility(Abilities.BATTLE_BOND) && user.formIndex === 2) { - (args[0] as Utils.IntegerHolder).value = MultiHitType._3; + (args[0] as Utils.NumberHolder).value = MultiHitType._3; return true; } return false; @@ -4118,7 +4118,7 @@ export class PresentPowerAttr extends VariablePowerAttr { export class WaterShurikenPowerAttr extends VariablePowerAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { if (user.species.speciesId === Species.GRENINJA && user.hasAbility(Abilities.BATTLE_BOND) && user.formIndex === 2) { - (args[0] as Utils.IntegerHolder).value = 20; + (args[0] as Utils.NumberHolder).value = 20; return true; } return false; @@ -4140,7 +4140,7 @@ export class SpitUpPowerAttr extends VariablePowerAttr { const stockpilingTag = user.getTag(StockpilingTag); if (stockpilingTag && stockpilingTag.stockpiledCount > 0) { - const power = args[0] as Utils.IntegerHolder; + const power = args[0] as Utils.NumberHolder; power.value = this.multiplier * stockpilingTag.stockpiledCount; return true; } @@ -4449,7 +4449,7 @@ export class VariableAtkAttr extends MoveAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - //const atk = args[0] as Utils.IntegerHolder; + //const atk = args[0] as Utils.NumberHolder; return false; } } @@ -4459,7 +4459,7 @@ export class TargetAtkUserAtkAttr extends VariableAtkAttr { super(); } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value = target.getEffectiveStat(Stat.ATK, target); + (args[0] as Utils.NumberHolder).value = target.getEffectiveStat(Stat.ATK, target); return true; } } @@ -4470,7 +4470,7 @@ export class DefAtkAttr extends VariableAtkAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value = user.getEffectiveStat(Stat.DEF, target); + (args[0] as Utils.NumberHolder).value = user.getEffectiveStat(Stat.DEF, target); return true; } } @@ -4481,7 +4481,7 @@ export class VariableDefAttr extends MoveAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - //const def = args[0] as Utils.IntegerHolder; + //const def = args[0] as Utils.NumberHolder; return false; } } @@ -4492,7 +4492,7 @@ export class DefDefAttr extends VariableDefAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.IntegerHolder).value = target.getEffectiveStat(Stat.DEF, user); + (args[0] as Utils.NumberHolder).value = target.getEffectiveStat(Stat.DEF, user); return true; } } diff --git a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts index aa497e3c8fc..130c55c361e 100644 --- a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts +++ b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts @@ -10,7 +10,7 @@ import { HiddenAbilityRateBoosterModifier, IvScannerModifier } from "#app/modifi import type { EnemyPokemon } from "#app/field/pokemon"; import { PokeballType } from "#enums/pokeball"; import { PlayerGender } from "#enums/player-gender"; -import { IntegerHolder, randSeedInt } from "#app/utils"; +import { NumberHolder, randSeedInt } from "#app/utils"; import type PokemonSpecies from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import { MoneyRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements"; @@ -279,7 +279,7 @@ async function summonSafariPokemon() { if (pokemon.species.abilityHidden) { const hiddenIndex = pokemon.species.ability2 ? 2 : 1; if (pokemon.abilityIndex < hiddenIndex) { - const hiddenAbilityChance = new IntegerHolder(256); + const hiddenAbilityChance = new NumberHolder(256); globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value); diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index e047a7a4f01..f7c70cb7052 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -12,7 +12,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode import type { PlayerPokemon } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon"; -import { IntegerHolder, isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils"; +import { NumberHolder, isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils"; import type PokemonSpecies from "#app/data/pokemon-species"; import { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species"; import type { PokemonHeldItemModifier } from "#app/modifier/modifier"; @@ -452,7 +452,7 @@ async function postProcessTransformedPokemon(previousPokemon: PlayerPokemon, new if (newPokemon.species.abilityHidden) { const hiddenIndex = newPokemon.species.ability2 ? 2 : 1; if (newPokemon.abilityIndex < hiddenIndex) { - const hiddenAbilityChance = new IntegerHolder(256); + const hiddenAbilityChance = new NumberHolder(256); globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index dfce632ab06..1377f11187b 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -204,7 +204,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { throw `Cannot create a player Pokemon for species '${species.getName(formIndex)}'`; } - const hiddenAbilityChance = new Utils.IntegerHolder(BASE_HIDDEN_ABILITY_CHANCE); + const hiddenAbilityChance = new Utils.NumberHolder(BASE_HIDDEN_ABILITY_CHANCE); if (!this.hasTrainer()) { globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); } @@ -960,7 +960,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns the final critical-hit stage value */ getCritStage(source: Pokemon, move: Move): number { - const critStage = new Utils.IntegerHolder(0); + const critStage = new Utils.NumberHolder(0); applyMoveAttrs(HighCritAttr, source, this, move, critStage); globalScene.applyModifiers(CritBoosterModifier, source.isPlayer(), source, critStage); globalScene.applyModifiers(TempCritBoosterModifier, source.isPlayer(), critStage); @@ -1074,7 +1074,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const baseStats = this.calculateBaseStats(); // Using base stats, calculate and store stats one by one for (const s of PERMANENT_STATS) { - const statHolder = new Utils.IntegerHolder(Math.floor(((2 * baseStats[s] + this.ivs[s]) * this.level) * 0.01)); + const statHolder = new Utils.NumberHolder(Math.floor(((2 * baseStats[s] + this.ivs[s]) * this.level) * 0.01)); if (s === Stat.HP) { statHolder.value = statHolder.value + this.level + 10; globalScene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder); @@ -2567,7 +2567,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @return the stat stage multiplier to be used for effective stat calculation */ getStatStageMultiplier(stat: EffectiveStat, opponent?: Pokemon, move?: Move, ignoreOppAbility: boolean = false, isCritical: boolean = false, simulated: boolean = true, ignoreHeldItems: boolean = false): number { - const statStage = new Utils.IntegerHolder(this.getStatStage(stat)); + const statStage = new Utils.NumberHolder(this.getStatStage(stat)); const ignoreStatStage = new Utils.BooleanHolder(false); if (opponent) { @@ -2617,8 +2617,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return 1; } - const userAccStage = new Utils.IntegerHolder(this.getStatStage(Stat.ACC)); - const targetEvaStage = new Utils.IntegerHolder(target.getStatStage(Stat.EVA)); + const userAccStage = new Utils.NumberHolder(this.getStatStage(Stat.ACC)); + const targetEvaStage = new Utils.NumberHolder(target.getStatStage(Stat.EVA)); const ignoreAccStatStage = new Utils.BooleanHolder(false); const ignoreEvaStatStage = new Utils.BooleanHolder(false); @@ -2797,7 +2797,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } /** Doubles damage if this Pokemon's last move was Glaive Rush */ - const glaiveRushMultiplier = new Utils.IntegerHolder(1); + const glaiveRushMultiplier = new Utils.NumberHolder(1); if (this.getTag(BattlerTagType.RECEIVE_DOUBLE_DAMAGE)) { glaiveRushMultiplier.value = 2; } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 35ed75d8c6e..30ad287fd98 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1186,11 +1186,11 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { if (p.species.speciesId === Species.NECROZMA) { // technically we could use a simplified version and check for formChanges.length > 3, but in case any code changes later, this might break... - let foundULTRA_Z = false, foundN_LUNA = false, foundN_SOLAR = false; formChangeItemTriggers.forEach((fc, _i) => { + console.log("Checking ", fc.item); switch (fc.item) { case FormChangeItem.ULTRANECROZIUM_Z: foundULTRA_Z = true; @@ -1206,6 +1206,8 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { if (foundULTRA_Z && foundN_LUNA && foundN_SOLAR) { // all three items are present -> user hasn't acquired any of the N_*ARIZERs -> block ULTRANECROZIUM_Z acquisition. formChangeItemTriggers = formChangeItemTriggers.filter(fc => fc.item !== FormChangeItem.ULTRANECROZIUM_Z); + } else { + console.log("DID NOT FIND "); } } return formChangeItemTriggers; diff --git a/src/phases/money-reward-phase.ts b/src/phases/money-reward-phase.ts index 70f0019227c..f460f89a72a 100644 --- a/src/phases/money-reward-phase.ts +++ b/src/phases/money-reward-phase.ts @@ -15,7 +15,7 @@ export class MoneyRewardPhase extends BattlePhase { } start() { - const moneyAmount = new Utils.IntegerHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier)); + const moneyAmount = new Utils.NumberHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier)); globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); diff --git a/src/phases/pokemon-heal-phase.ts b/src/phases/pokemon-heal-phase.ts index a544d47df70..6d0621b8f48 100644 --- a/src/phases/pokemon-heal-phase.ts +++ b/src/phases/pokemon-heal-phase.ts @@ -62,7 +62,7 @@ export class PokemonHealPhase extends CommonAnimPhase { this.message = null; return super.end(); } else if (healOrDamage) { - const hpRestoreMultiplier = new Utils.IntegerHolder(1); + const hpRestoreMultiplier = new Utils.NumberHolder(1); if (!this.revive) { globalScene.applyModifiers(HealingBoosterModifier, this.player, hpRestoreMultiplier); } diff --git a/src/phases/select-modifier-phase.ts b/src/phases/select-modifier-phase.ts index 3b9a0a0405c..a3a2fa1aa24 100644 --- a/src/phases/select-modifier-phase.ts +++ b/src/phases/select-modifier-phase.ts @@ -45,7 +45,7 @@ export class SelectModifierPhase extends BattlePhase { if (!this.isCopy) { regenerateModifierPoolThresholds(party, this.getPoolType(), this.rerollCount); } - const modifierCount = new Utils.IntegerHolder(3); + const modifierCount = new Utils.NumberHolder(3); if (this.isPlayer()) { globalScene.applyModifiers(ExtraModifierModifier, true, modifierCount); globalScene.applyModifiers(TempExtraModifierModifier, true, modifierCount); diff --git a/src/test/achievements/achievement.test.ts b/src/test/achievements/achievement.test.ts index b515c6bafa8..2d1cc50603e 100644 --- a/src/test/achievements/achievement.test.ts +++ b/src/test/achievements/achievement.test.ts @@ -1,6 +1,6 @@ import { TurnHeldItemTransferModifier } from "#app/modifier/modifier"; import { Achv, AchvTier, DamageAchv, HealAchv, LevelAchv, ModifierAchv, MoneyAchv, RibbonAchv, achvs } from "#app/system/achv"; -import { IntegerHolder, NumberHolder } from "#app/utils"; +import { NumberHolder } from "#app/utils"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -174,7 +174,7 @@ describe("LevelAchv", () => { it("should validate the achievement based on the level", () => { const levelAchv = new LevelAchv("", "Test Level Achievement", 100, "level_icon", 10); - const integerHolder = new IntegerHolder(50); + const integerHolder = new NumberHolder(50); expect(levelAchv.validate([ integerHolder ])).toBe(false); diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index a3508532631..76d02c191bb 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -14,7 +14,7 @@ import * as Utils from "./../utils"; import Overrides from "#app/overrides"; import i18next from "i18next"; import { ShopCursorTarget } from "#app/enums/shop-cursor-target"; -import { IntegerHolder } from "./../utils"; +import { NumberHolder } from "./../utils"; import Phaser from "phaser"; import type { PokeballType } from "#enums/pokeball"; @@ -191,7 +191,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { const typeOptions = args[1] as ModifierTypeOption[]; const removeHealShop = globalScene.gameMode.hasNoShop; - const baseShopCost = new IntegerHolder(globalScene.getWaveMoneyAmount(1)); + const baseShopCost = new NumberHolder(globalScene.getWaveMoneyAmount(1)); globalScene.applyModifier(HealShopCostModifier, true, baseShopCost); const shopTypeOptions = !removeHealShop ? getPlayerShopModifierTypeOptionsForWave(globalScene.currentBattle.waveIndex, baseShopCost.value) diff --git a/src/utils.ts b/src/utils.ts index a906ee76391..56df3f3f48e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -342,13 +342,6 @@ export class NumberHolder { } } -/** @deprecated Use {@linkcode NumberHolder} */ -export class IntegerHolder extends NumberHolder { - constructor(value: number) { - super(value); - } -} - export class FixedInt { public readonly value: number; From 0913c77140de9eb2df2dc3323f99719e809da427 Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Mon, 17 Feb 2025 11:07:09 +1100 Subject: [PATCH 13/15] Update version number for migration code (#5354) --- package-lock.json | 4 ++-- package.json | 2 +- src/system/version_migration/version_converter.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index ce1feb7db41..739ce18496d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.6.4", + "version": "1.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.6.4", + "version": "1.7.0", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index c9b5798af76..5a191b3ec99 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.6.4", + "version": "1.7.0", "type": "module", "scripts": { "start": "vite", diff --git a/src/system/version_migration/version_converter.ts b/src/system/version_migration/version_converter.ts index 95537461768..98d340d03aa 100644 --- a/src/system/version_migration/version_converter.ts +++ b/src/system/version_migration/version_converter.ts @@ -172,7 +172,7 @@ class SystemVersionConverter extends VersionConverter { this.callMigrators(data, v1_1_0.systemMigrators); } if (curMinor < 7) { - console.log("Applying v1.7.0 session data migration!"); + console.log("Applying v1.7.0 system data migration!"); this.callMigrators(data, v1_7_0.systemMigrators); } } @@ -202,11 +202,11 @@ class SettingsVersionConverter extends VersionConverter { this.callMigrators(data, v1_1_0.settingsMigrators); } if (curMinor < 7) { - console.log("Applying v1.7.0 session data migration!"); + console.log("Applying v1.7.0 settings data migration!"); this.callMigrators(data, v1_7_0.settingsMigrators); } } - console.log(`System data successfully migrated to v${version}!`); + console.log(`Settings data successfully migrated to v${version}!`); } } From e1327c1d2d87d85f4baa494220ee63cdf31b4b9c Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Sun, 16 Feb 2025 19:40:11 -0600 Subject: [PATCH 14/15] [Balance] Guarantee Tera Orb as a reward from Rival 4, Remove it from Classic Item Pool (#5353) * Add Tera Orb to Rival * Remove Tera Orb from Classic Rewards --- src/data/trainer-config.ts | 1 + src/modifier/modifier-type.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 9cbec400a87..d9aab528e72 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -2192,6 +2192,7 @@ export const trainerConfigs: TrainerConfigs = { .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) + .setModifierRewardFuncs(() => modifierTypes.TERA_ORB) .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; diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 30ad287fd98..336cbe67ccc 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1859,7 +1859,7 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.IV_SCANNER, skipInLastClassicWaveOrDefault(4)), new WeightedModifierType(modifierTypes.EXP_CHARM, skipInLastClassicWaveOrDefault(8)), new WeightedModifierType(modifierTypes.EXP_SHARE, skipInLastClassicWaveOrDefault(10)), - new WeightedModifierType(modifierTypes.TERA_ORB, () => Math.min(Math.max(Math.floor(globalScene.currentBattle.waveIndex / 50) * 2, 1), 4), 4), + new WeightedModifierType(modifierTypes.TERA_ORB, () => !globalScene.gameMode.isClassic ? Math.min(Math.max(Math.floor(globalScene.currentBattle.waveIndex / 50) * 2, 1), 4) : 0, 4), new WeightedModifierType(modifierTypes.QUICK_CLAW, 3), new WeightedModifierType(modifierTypes.WIDE_LENS, 7), ].map(m => { From db2235405710da32ba7d051bbf7ff22cbf3d58dd Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Mon, 17 Feb 2025 05:30:27 +0100 Subject: [PATCH 15/15] Update starter-select-ui-handler.ts Spnaish text size (#5356) --- src/ui/starter-select-ui-handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 65c159c62a8..b919679be00 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -88,7 +88,7 @@ const languageSettings: { [key: string]: LanguageSetting } = { starterInfoXPos: 33, }, "es-ES":{ - starterInfoTextSize: "56px", + starterInfoTextSize: "52px", instructionTextSize: "35px", }, "fr":{