From 75e66b4099899e7c254c3c6c12cba775a201ead5 Mon Sep 17 00:00:00 2001 From: Unicornpowerstar Date: Sun, 19 Jan 2025 18:50:19 +0100 Subject: [PATCH 01/12] [Sprite] Update Shelly sprite (#5155) Co-authored-by: damocleas --- public/images/trainer/shelly.png | Bin 865 -> 985 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/images/trainer/shelly.png b/public/images/trainer/shelly.png index 505dce1b1105c144b0fe43d26705340cd9575580..2885fbde48e6d99a641834e0237c03724540a9ff 100644 GIT binary patch delta 885 zcmV-*1B(3N2H6LYBnkm@Qb$4nuFf3kks(ok7IachQvm<}|NsC0|NsC0|NsC0|NsC0 z|Ns9~fsLa800SdQL_t(oh3(kcZrd;r1yEnET5Zc}|NmEeXGpC^5s^uOK6rp24gnnx zml;X9-9GV&PkiFP3;eV<{*ag%%o_-aYA-t*2#gZ7B<2-V5qP}Dv7W@7Gm{S_B)e6A ztXNet3{6E+9HHE6d_2m*C9gTBrXK_(^t#`R#k_V&TmlY)JKVEa1g1SO<^Vd#PuCTL z&u zAO?b#?KFpo!K~e}OcamceVRnc5v zt%qu!3+60fzz~8QooTuc=L8{tJ9phvk!P8^5G2XrP}d{oqUHoNO&w+fNP zD;^-EJ%hL62RcZj3Jr6~;C@G{9=jG$#4}hSYCE+-TepIzBU22T)Sc4<6GgN*oay2% z&b|5ePe6(a+I*j>5shzLvv>m9^bE0qg`)9nr7Os%L@uZGMvAQ}Mb4Oi8JfcY_dN}y zJ8Y>ZaRm90xD1q530ypbcpE7KoAc#x={xE`(^AhBTLn$?!N<@>I64%f3Y^% zr9ak+M=#^$~kMY~Z6q}|_G>x@~Zn%Qdv}-_Z*XN>OOSDd3PD;Jy zjpQB7Z>6Q>2YDZf?_ho*t*B=l?x8zU&Fe2GJMpjoEh~7}`A_2y)IvFnm9HsN00000 LNkvXXu0mjfs%5Uh delta 766 zcmVgB#|*re*tt-PE!Ct=GbNc00PZPL_t(|UhUP{j^jEE1W*@AEnc$U z`~SZ>B}R4C|Sp717&KtU-^*04^56x$EI{Y6tNE3BhRx30;rJe^!xH6`un`!3{@> z&7fZhA}^q!Jk!(+!Y>F3ApqD!5i=1Tnd|j*Y6MA&QgjpZJj2P+^nZdlvE`}BV?+_| zNi-&kq~yPmq8<1m(F#Hp8|dO#Guh$V2P$wE(+g;ICOx8naWVn(IMssvpyN&|Gmc)> z(6}G4fva7`nc@n5f4d`G+`!Fq5xnsXGvK=$hZay6?7&K5o^LlXl8i~qb@B8HQ&zgDD*l+ zdJY~hmmbcb+BDn_?Qup8hw0a>F5W@;?-qx)Xr1${) zMFd78JqK5>e;<_KB8Dnr1i@~xdV${WgDyJgBKkxL*)qKiRC)?H*dt0XGlDgcKrzSw z3|$o^l!o$hfI!goLZZ?0yn+F^gY91lEbT$8CtX3_gD^||pqRaZIsZVE`s1`sMU1In zf5Bw-1m>JqvA^I0^ndt%kX^iB#$zTch#oMi5_GQyblG_2E{}mSzWsMo{wcV5>yoYe zv0HovqcT4N@%351i1)L8Fy~D0P0YDZl&or5z5rEG$&Pg$WPcjem}au>zOO(}O4163 w#Jq!WEqV1;(S!ZDxGD5n1J9T9BKL3S4+3R5 Date: Sun, 19 Jan 2025 18:52:50 +0100 Subject: [PATCH 02/12] [Move] Improve implementation of Rage Fist damage increase (#5129) * implementation of rage fist * Apply suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update src/test/moves/rage_fist.test.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * added removed TODO from some test cases * Apply suggestions from code review Added changes to documentation and cleaning up code Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * added protected to updateHitReceivedCount() --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: damocleas --- src/data/custom-pokemon-data.ts | 10 +- src/data/move.ts | 28 ++++- src/field/pokemon.ts | 3 + src/phases/encounter-phase.ts | 6 + src/phases/new-biome-encounter-phase.ts | 1 + src/test/moves/rage_fist.test.ts | 143 ++++++++++++++++++++++++ 6 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 src/test/moves/rage_fist.test.ts diff --git a/src/data/custom-pokemon-data.ts b/src/data/custom-pokemon-data.ts index 1c3bbbc3180..4a5eb89aeed 100644 --- a/src/data/custom-pokemon-data.ts +++ b/src/data/custom-pokemon-data.ts @@ -5,7 +5,8 @@ import type { Nature } from "#enums/nature"; /** * Data that can customize a Pokemon in non-standard ways from its Species - * Currently only used by Mystery Encounters and Mints. + * Used by Mystery Encounters and Mints + * Also used as a counter how often a Pokemon got hit until new arena encounter */ export class CustomPokemonData { public spriteScale: number; @@ -13,6 +14,8 @@ export class CustomPokemonData { public passive: Abilities | -1; public nature: Nature | -1; public types: Type[]; + /** `hitsReceivedCount` aka `hitsRecCount` saves how often the pokemon got hit until a new arena encounter (used for Rage Fist) */ + public hitsRecCount: number; constructor(data?: CustomPokemonData | Partial) { if (!isNullOrUndefined(data)) { @@ -24,5 +27,10 @@ export class CustomPokemonData { this.passive = this.passive ?? -1; this.nature = this.nature ?? -1; this.types = this.types ?? []; + this.hitsRecCount = this.hitsRecCount ?? 0; + } + + resetHitReceivedCount(): void { + this.hitsRecCount = 0; } } diff --git a/src/data/move.ts b/src/data/move.ts index 572fbf4c2ac..06f3c85e9c4 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -3993,12 +3993,32 @@ export class FriendshipPowerAttr extends VariablePowerAttr { } } -export class HitCountPowerAttr extends VariablePowerAttr { +/** + * This Attribute calculates the current power of {@linkcode Moves.RAGE_FIST}. + * The counter for power calculation does not reset on every wave but on every new arena encounter + */ +export class RageFistPowerAttr extends VariablePowerAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.NumberHolder).value += Math.min(user.battleData.hitCount, 6) * 50; + const { hitCount, prevHitCount } = user.battleData; + const basePower: Utils.NumberHolder = args[0]; + + this.updateHitReceivedCount(user, hitCount, prevHitCount); + + basePower.value = 50 + (Math.min(user.customPokemonData.hitsRecCount, 6) * 50); return true; } + + /** + * Updates the number of hits the Pokemon has taken in battle + * @param user Pokemon calling Rage Fist + * @param hitCount The number of received hits this battle + * @param previousHitCount The number of received hits this battle since last time Rage Fist was used + */ + protected updateHitReceivedCount(user: Pokemon, hitCount: number, previousHitCount: number): void { + user.customPokemonData.hitsRecCount += (hitCount - previousHitCount); + user.battleData.prevHitCount = hitCount; + } } /** @@ -10991,8 +11011,8 @@ export function initMoves() { new AttackMove(Moves.TWIN_BEAM, Type.PSYCHIC, MoveCategory.SPECIAL, 40, 100, 10, -1, 0, 9) .attr(MultiHitAttr, MultiHitType._2), new AttackMove(Moves.RAGE_FIST, Type.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9) - .partial() // Counter resets every wave instead of on arena reset - .attr(HitCountPowerAttr) + .edgeCase() // Counter incorrectly increases on confusion self-hits + .attr(RageFistPowerAttr) .punchingMove(), new AttackMove(Moves.ARMOR_CANNON, Type.FIRE, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) .attr(StatStageChangeAttr, [ Stat.DEF, Stat.SPDEF ], -1, true), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 432f0a92fec..a833facd2f8 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5282,7 +5282,10 @@ export class PokemonSummonData { } export class PokemonBattleData { + /** counts the hits the pokemon received */ public hitCount: number = 0; + /** used for {@linkcode Moves.RAGE_FIST} in order to save hit Counts received before Rage Fist is applied */ + public prevHitCount: number = 0; public endured: boolean = false; public berriesEaten: BerryType[] = []; public abilitiesApplied: Abilities[] = []; diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 6dae7dff8f9..353dd6681cb 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -104,6 +104,12 @@ export class EncounterPhase extends BattlePhase { } if (!this.loaded) { if (battle.battleType === BattleType.TRAINER) { + //resets hitRecCount during Trainer ecnounter + for (const pokemon of globalScene.getPlayerParty()) { + if (pokemon) { + pokemon.customPokemonData.resetHitReceivedCount(); + } + } battle.enemyParty[e] = battle.trainer?.genPartyMember(e)!; // TODO:: is the bang correct here? } else { let enemySpecies = globalScene.randomSpecies(battle.waveIndex, level, true); diff --git a/src/phases/new-biome-encounter-phase.ts b/src/phases/new-biome-encounter-phase.ts index be6815333e5..2de9a4300c5 100644 --- a/src/phases/new-biome-encounter-phase.ts +++ b/src/phases/new-biome-encounter-phase.ts @@ -14,6 +14,7 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase { for (const pokemon of globalScene.getPlayerParty()) { if (pokemon) { pokemon.resetBattleData(); + pokemon.customPokemonData.resetHitReceivedCount(); } } diff --git a/src/test/moves/rage_fist.test.ts b/src/test/moves/rage_fist.test.ts new file mode 100644 index 00000000000..a85be5a88d9 --- /dev/null +++ b/src/test/moves/rage_fist.test.ts @@ -0,0 +1,143 @@ +import { BattlerIndex } from "#app/battle"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { allMoves } from "#app/data/move"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Moves - Rage Fist", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + const move = allMoves[Moves.RAGE_FIST]; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleType("single") + .moveset([ Moves.RAGE_FIST, Moves.SPLASH, Moves.SUBSTITUTE ]) + .startingLevel(100) + .enemyLevel(1) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.DOUBLE_KICK); + + vi.spyOn(move, "calculateBattlePower"); + }); + + it("should have 100 more power if hit twice before calling Rage Fist", async () => { + game.override + .enemySpecies(Species.MAGIKARP); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + }); + + it("should maintain its power during next battle if it is within the same arena encounter", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(1); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextWave(); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(250); + }); + + it("should reset the hitRecCounter if we enter new trainer battle", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(4); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextWave(); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + }); + + it("should not increase the hitCounter if Substitute is hit", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(4); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + game.move.select(Moves.SUBSTITUTE); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(game.scene.getPlayerPokemon()?.customPokemonData.hitsRecCount).toBe(0); + }); + + it("should reset the hitRecCounter if we enter new biome", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(10); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextTurn(); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + }); + + it("should not reset the hitRecCounter if switched out", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(1) + .enemyMoveset(Moves.TACKLE); + + await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); + + game.move.select(Moves.SPLASH); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextTurn(); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + game.move.select(Moves.RAGE_FIST); + await game.phaseInterceptor.to("MoveEndPhase"); + + expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(Species.CHARIZARD); + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + }); +}); From 05485aefdd3b6b439a38b0af17c8ac160ec7219b Mon Sep 17 00:00:00 2001 From: Unicornpowerstar Date: Sun, 19 Jan 2025 19:15:33 +0100 Subject: [PATCH 03/12] [Sprite] Flutter mane back sprite adjustments (#5057) Co-authored-by: damocleas --- public/images/pokemon/back/987.png | Bin 712 -> 748 bytes public/images/pokemon/back/shiny/987.png | Bin 713 -> 748 bytes public/images/pokemon/exp/back/987.png | Bin 2260 -> 2367 bytes public/images/pokemon/exp/back/shiny/987.png | Bin 2179 -> 2373 bytes public/images/pokemon/variant/back/987.json | 6 +++--- .../images/pokemon/variant/exp/back/987.json | 6 +++--- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/public/images/pokemon/back/987.png b/public/images/pokemon/back/987.png index 64a47fbf0ea70325c44db3510f11fd7b4fd575f6..ab4e628de28565fbd8bb625b0d3ffccc41e0caa4 100644 GIT binary patch delta 700 zcmV;t0z>`C1?&Zo7#auz0000hQ`;K=0004VQb$4nuFf3k0000dktHa9RE~%OSBm2R z000eiQchC<|NsC0|NsC0|NsC0Ed)WW00077Nkl$a;P41`Sr3n+d6=RKK_ zpw*tbxBa=D)yt}ekI4vhSq>`4OK()l$GXx#-*-gs{ZpCU-xcH?qeE?1R3K&^zo_py z`H{E9hG?&l;jVK^X@IDIp-KY!N)Z`|J){q@q@=IF$n*K+EoE>}VUT^#L{xNGV}TvT zkd`!1p0JbiLiO<&c2FSRkYr{k*-VX)!|TGcWTu%h$%;{bM9pGPP%n##EJ0fk zTM{_TgCc&#gGsf50g+w}2rP}KJ2@7vxR)dx9B@+z_t+?G>4>G==T`7^M=<2(m+3zk zRzPqo5+UnTCz=hZMnhVYoKuQO!N)2F#woUL=&)=Q#y*pB&?ONj!-b$Rdwk~Q&Bk?8 zJ}bJUu?7ggdZTH7#@B?k^o~R95Hm3;*jYvs_JAW^;~cso>k5z(kfH;f0w>{i#A}Hj zdm2&OiDQ27Jt+DO3I~PxUA8+Akuxw@F-|c%)64ncN`@Fil@eA4ha;CW4h3RhwiJtp z*uy`wvrG&*WC?S#?{ml&6Jw3@lcB3}U7K3R{%HOeN?sX%d|v+_MZi=k*Y6lu_&CEa zVRZQ1!a`JQJ|A;r*qQlY7qQsupb0=bPcm$rIDKM z!>l`4thGxNot}If1?&RG9xQDR19(;GXw{HCxE&T(agcjEXml5j#0000%-okU&znImNjSxmHy>wTGfN_3POW`j z)k+owgYTB(@n!EOv(|=^`Pj0-N9UVC3x*kXfi4p-ET@{eXV^HP2@E!~Nm4ri!U-T| zrYL1jjB};j43dQF8PL(y%Nzh9?M=U&hN6y4@XEd}=CQkC?+g))xy77&gezRQ*tvf> z7wZTnVyM3R3n`G)mENSc>p2@0p$EoQ&9y)#9G6q)+*HFD^2LVxb1B7r{J%PNW$w+C zNO?oeXo=DR x4t8amkpf0_#et|$iNhv1XdwQ#Jmet{`3){_x=B+S(u4p2002ovPDHLkV1n|CIc@*| diff --git a/public/images/pokemon/back/shiny/987.png b/public/images/pokemon/back/shiny/987.png index 8022d2f900a6beeb514bb881d0de2fbccd6fd28b..8c4c0c8b62a8a2656833ad7e9eb650696aedec01 100644 GIT binary patch delta 736 zcmV<60w4X!1?&Zo7=H)@0000hQ`;K=0004VQb$4nuFf3k0000dP)t-s0000F4-ZLO z5_=#3i=;uca{#>{7{%3M=9~cZ^z{E)DgVU)y}-LLZ8-!0000eiQchC<|NsC0|NsC0 z|NsC0Ed)WW00077NklYh8glWbmdY3`MA~C z&axbokC)yk=Z|%{f4=XC-utIAyT2<)J4T1vt|&vyJbqE%bJ8Piiw)6UA;VqgTI&E& zLzM*dl_D|_dq^K*sa0Qrk>~TtTgu>|!XW#ei74x^#sWKvAuVa3JYgrLh05bG?4Uvz zjNa)GsH!z)5r2UhY6>xoa_Es>D59-4%(|xl(cncXGFlo8h?G!@zJUQns}ysDSXd2r zIWV-P03p@PP_>yFA&1w6XUR-6W0Do4h?2yfpk5XeS%S78wj^+v2Sxmf2UAM{10uZ| z5Lg;dcXBLTaW7RkIN;V0?y*tW(h*C!&#mC;j$p{mFMrd2Fsy*!RwP2!r%p5*QjLbR zraC8Qk&KU342)B3-Oyp#D2#n3<)BL;Xr-#yNCF))gQ*AXx`G1x~{4h}RN5_B5il6UY4Edrx?qX5Z(K zEhfeq=O;r~rLs1)j{VX6FO;-0_`Lo2GI|)rCmI`Q@0MG2K{q=S4T>*Yk4l@;lY?6?|ZUTlT)>oeB-yy z?I!Bv)$N9sZYV!`TVFkUXzft&Wr^PlQ|j}Q;Lfm~ey9UZR? zlT@>sbPAbUW(>MoAVO(8O8Vyl9uf6R}Q@1F;M>X5mwb)GkaBuzQP zH*dal({z}BI6A;lbb3XgBXgvp(OG>x!TN=TpObJ)=&au{GKhOH6cmq4Uje> z5^gmaZ*VHqF#fz&TL}n34LT`Q|IUdaAAdlrUFL-+Mztk>Ku_}FWFO(=c>I1hIY^08 zW_>Z(O?ng5AbNLAZ;CM>!?0zIHvU~&cd1(Tn1mwEdToY`!7&rLu*LY-ol(+af+RFV z_(YexO{ffr?@}!>Nq~c0-Db3cFwI{*Lx diff --git a/public/images/pokemon/exp/back/987.png b/public/images/pokemon/exp/back/987.png index 1da8db869dc117a8f4bb73752fba78576c9260e6..4956b630d3eca7102acf6a0f9e2a6f8e7c7891a5 100644 GIT binary patch delta 2319 zcmV+q3GnvR5x)|UBn|;{Qb$4nuFf3k0000dktHa9RE~%OSBm2R000eiQchC<|NsC0 z|NsC0|NsC0Ed)WW000QBNkl&mMuG$-^+~+C$UHgY&hnKKLhihcBf}+MIJi(JeL4F_rOQT z>ovjq=Z75RkcN2H3XYn0v`iI1tjVh^5P4Cb0+E6TuLyAaJ5c&!YN(m;(&uJekL3s91Njw@KyxURqA-&PdvLo^c0B2G{93um+q7?SP3le zm#0e+9E=P6fu`04_F*J6aakzODG(=~`9>fH7vW^hx?A8IZhpTh5W)zr*gakh9a+>2 zrd0AYWN#h)whQbMFD8&zb zh9^uN6kp7|uq-8e3am(WUg8!uf5~7SmVRBB1 zD<8!;Svm~9DhA>lmqj6MC=aezjDmIHSBvtn6~{O@yCpZvvPknzZafSntJR{SEJ{sXM2*i}d=|%|#a0~)5I0Ph9DAjYG@j&ETrwGGddWvHdh;(bC zOr19tdm58KOfG_YHSHdMj#(gL7)?X_xp5%Ut-uhDX&{d857T5Ah&ID45G_Y{Al|E} zcWFomoSxZVF7+c~>D4_FPv7B7sibv);qvq|oEroWN%d@ZD!CWf8Pt&U&iMl3r zA$&~S)?7hKmGV?7@9<5RdZc0>s%uP4Jm%G*LS{0hTyp{=Che~08_pBd>W<4 zW;Dyko0W2ZNGrW&$+OfK@8|-J-{n&maaahwc2GmIfg~YSG~OsV>+54aO(E!t-&QEP z=v*m}K;bWIUC{zfS!D?v^jid^*4*MLRm$Ug5Pet8G}BE5iFA)fK82W0TRP}}evC>sb>%TjV3bR5;*3f*7s_MQ zLGSU5N;WO!F|I7Q`Pe=z+0^r?rVW~`Tldlil1)Q-l>caH-N3PvY#Pd=;$E6Ilx(UJ zcuE|1@|dM$GpsxsOE$w2xTR!cAc4pI+n`cDo=;6Hh~(x|>g9ZBg`y#tG4lJwiMEbEYbte8yU*$? z4KYinidDn8NMhVyBlUm4{+yk5q`wHv;M%)?kpQXGskKfOM-I(L+zHj$ME7JYsSwQS z$f@~gVpXl#dSo|Jsgrm9D2}8Sl-PiB&WbHNjh1+8)MkaSsO%|`%# zSs^$|6^=@a&0a$r9=EH!9$HY+ov!v+d^rPYsZMwfgxoDND=38A^1x?e*=wKFO(IIQ7@Fy zuWbpt1002ovPDHLkV1l07W7Gfu delta 2212 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 delta 2166 zcmV-+2#NQ_5`z(tB!3}LOjJbx000jU4|^a0i=;uca{#>{7{%3M=9~cZ^z{E)DgVU) z|5Br%00001bW%=J06^y0W&i*P5J^NqRCwC$n}KrUDhx$^BLXS^|G_UH0AYh|g3{fc zd7kZT)28HFTm;dHw(VcI%=}*%)BXO=^OfZoV~qFS5D~@4-hUf&^(Wq&nOB(6u z3{dzrMLiB@Mh|kry=6sdw4)JuQ6G#L%|k>KlViyNK%A3~hrr7s-56gl z5uVnFT_;90JXaPrg)7VXc|4!*uP_SYtJwG-ake@LGJombq@FaGm2%>}QP6U{CjgZ6 zAdiA9Cup%Y%1L^x(6bkmS1HNx2tADvZ8Tyx4e$-cTc@n?J<40l^N}(n%c1y>J?#w8 zQ&W~jV;^b6jYm2$B0za2vLGV+eCBw7D2Im!+H0xH!p883U&r`JBSt-O6kwP@k>-Q- zq=41=34eN0gu=8BvTa!x@`Zw))`)Q+02XF&LI8=EPWpFxQa0e(>Ux<|YVx6!gOL%5 z!Z=+^*Vi^Cd>JVR$)Y78_EMtbXQgE!{DZA)M6pae^Hsz+2LyxgBh%O?zFwU7{>+oe z2qYFu&xlk5-3<@`8$u4=%wVl?-tpMgT=Dy}jeop^n)CDCh$+%#UHG%X;=0Ll;6nOD zD~HIPZtP8xvK=F$8j;tA~=LbO^Y+%IfuIR(@vZx^fK*VxbO?ph2 zI)96gj7U|E1Fp`v5Yv-_1Kw?C)r^f;mc^aZchQ5arp&>8HMflDCiP5D(X|ni5#q*; z^Hq@!l275^&(xe6F$)5#zLxV4L0u>t42-w|gsEZD2v0noiLMET4X zQ`L%?Wh2JOr0L=qVMWZU5o;EY2PG`XQ7|G1NSPw5`drVt5&7s;#Bh`ryrW^nc(loy zHmsOO!-zFRAX-~kYDNq;+LrcnWh2I;z*-8_G~)XHplU>&OU;O?qGpYFucB^@`F|B7 z8h`yli8=j-5skkBTB(-p%$MdfzA-CRavaOEkAs*QXfsQX5?xDmAvo{7lTf2p%4?~7 zA~t4nZnB(IQVx2C1Sv9`IfOK&2Y_+jyFy3`(0W-xkRF?0HX)$*Ejep?rhQa-Rt8#c zK~1GR0m@Jra(CrKE6%BD@tOcyyMIb~VK#&J_okDOFv&s-?X!hz2%yze$`i8@2&uC~ zcfq(~kA3%)@L<~kEm0{yAf&ydg4e`0;9g_$ILPinP{wO5&}xuP1_=#9+6&4cv*ZS` zD7wqK>z>4g1kehC+DiFGJA`y7-ZNcms_hazKH3%6ul*-07rs^iQm0amJbzWWlG{)u z$-p~uY67Fp`XQ1B67MTB!Ge0ora?#px<(SN@wD4xJ{_RP4quDU9#zVzM5njgCb}lk zV+l{mr-iNg3y=VN2icHd>IaIS;o8>dY4T~%L)UsLUmGHu^v;$BL`%RmG;&(t_HOddr7i@EgcmGUI$oIDl|>TllO8nQVfj|~UKeKDUSn{hrx0grU^ zEu;dnIU$e8;L+Zaqlaux$YYj!IkY0O86xnSIB<6mC1kTq9+i>JG6L5`HVOz_vr@jE zPgN`B3i(vCQm%x+b$=@5Y6x7TQm&4`mynG<0$)Qm>Ii%l*{J5zW#A`P7s~f)JnclJw^g>ux@6`)jtd z_M8w#w+68;^Qm*Yb{}U44KZetVttrTxxXfrUJ?3p8g?WsKYz=OKFg=E)R}9Y8IJ6l zkGK!)ACRr#o z>H6lT(v~{02W#crluCVh>(5**#3 z8#?wG^+MI&BmCA!rEt}P!o|gJAFoA>E?ZED6!vzdLU69z|HAflRS3?d*Xw2EM(vqXp3#E9Z*Xo7R z5~I}%wfxpXwHIpreU54`)RLMn^g<~lWyM19YJmRHLhvuiQ3PuWyOkXwpSEdT%j07*qoM6N<$g7x(xIsgCw diff --git a/public/images/pokemon/variant/back/987.json b/public/images/pokemon/variant/back/987.json index 1773ba70c36..e28a34d5435 100644 --- a/public/images/pokemon/variant/back/987.json +++ b/public/images/pokemon/variant/back/987.json @@ -9,7 +9,7 @@ "de62a4": "ffc668", "4a83a4": "387fa7", "314a62": "244260", - "70bbb4": "f8d371", + "548e88": "2d60bb", "a4295a": "cc762f" }, "1": { @@ -22,7 +22,7 @@ "de62a4": "ffdf90", "4a83a4": "a1c8db", "314a62": "7396b4", - "70bbb4": "70bbb4", + "548e88": "a9c0c6", "a4295a": "e28c27" }, "2": { @@ -35,7 +35,7 @@ "de62a4": "e25038", "4a83a4": "e6aa47", "314a62": "b56f2a", - "70bbb4": "f8d371", + "548e88": "e0b544", "a4295a": "a62a21" } } \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/987.json b/public/images/pokemon/variant/exp/back/987.json index 385a9eeb29f..5fb59f6979d 100644 --- a/public/images/pokemon/variant/exp/back/987.json +++ b/public/images/pokemon/variant/exp/back/987.json @@ -8,7 +8,7 @@ "0f0f0f": "0f0f0f", "314a62": "244260", "621841": "71370f", - "70bbb4": "f8d371", + "548e88": "2d60bb", "de62a4": "ffc668", "a4295a": "cc762f" }, @@ -21,7 +21,7 @@ "0f0f0f": "0f0f0f", "314a62": "7396b4", "621841": "7b3c08", - "70bbb4": "70bbb4", + "548e88": "a9c0c6", "de62a4": "ffdf90", "a4295a": "e28c27" }, @@ -34,7 +34,7 @@ "0f0f0f": "0f0f0f", "314a62": "b56f2a", "621841": "5a0a05", - "70bbb4": "f8d371", + "548e88": "e0b544", "de62a4": "e25038", "a4295a": "a62a21" } From 58b7f67ca8faad7fda46e9cb02f47e59ab1c36eb Mon Sep 17 00:00:00 2001 From: Scooom <97370685+Scoooom@users.noreply.github.com> Date: Sun, 19 Jan 2025 13:15:59 -0600 Subject: [PATCH 04/12] [Challenge] Fix flip inverse achievement (#5145) * Actually issue FLIP_INVERSE achivement * Local to remote * Update src/system/achv.ts Fix correctly giving FLIP_INVERSE Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --------- Co-authored-by: Scooom Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: damocleas --- src/system/achv.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/system/achv.ts b/src/system/achv.ts index a2777101186..e0c9f0cf052 100644 --- a/src/system/achv.ts +++ b/src/system/achv.ts @@ -292,7 +292,6 @@ export function getAchievementDescription(localizationKey: string): string { } - export const achvs = { _10K_MONEY: new MoneyAchv("10K_MONEY", "", 10000, "nugget", 10), _100K_MONEY: new MoneyAchv("100K_MONEY", "", 100000, "big_nugget", 25).setSecret(true), @@ -365,7 +364,7 @@ export const achvs = { FRESH_START: new ChallengeAchv("FRESH_START", "", "FRESH_START.description", "reviver_seed", 100, (c) => c instanceof FreshStartChallenge && c.value > 0 && !globalScene.gameMode.challenges.some(c => [ Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT ].includes(c.id) && c.value > 0)), INVERSE_BATTLE: new ChallengeAchv("INVERSE_BATTLE", "", "INVERSE_BATTLE.description", "inverse", 100, (c) => c instanceof InverseBattleChallenge && c.value > 0), FLIP_STATS: new ChallengeAchv("FLIP_STATS", "", "FLIP_STATS.description", "dubious_disc", 100, (c) => c instanceof FlipStatChallenge && c.value > 0), - FLIP_INVERSE: new ChallengeAchv("FLIP_INVERSE", "", "FLIP_INVERSE.description", "cracked_pot", 100, (c) => c instanceof FlipStatChallenge && c.value > 0 && globalScene.gameMode.challenges.every(c => [ Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT ].includes(c.id) && c.value > 0)).setSecret(), + FLIP_INVERSE: new ChallengeAchv("FLIP_INVERSE", "", "FLIP_INVERSE.description", "cracked_pot", 100, (c) => c instanceof FlipStatChallenge && c.value > 0 && globalScene.gameMode.challenges.some(c => c.id === Challenges.INVERSE_BATTLE && c.value > 0)).setSecret(), BREEDERS_IN_SPACE: new Achv("BREEDERS_IN_SPACE", "", "BREEDERS_IN_SPACE.description", "moon_stone", 50).setSecret(), }; From ce30897c0a7dc593402b5372ffaaba7cc5d9e9a9 Mon Sep 17 00:00:00 2001 From: Unicornpowerstar Date: Mon, 20 Jan 2025 00:48:07 +0100 Subject: [PATCH 05/12] [Sprite] Update Primal Kyogre Backsprite (#5156) --- public/images/pokemon/exp/back/382-primal.png | Bin 14063 -> 16319 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/images/pokemon/exp/back/382-primal.png b/public/images/pokemon/exp/back/382-primal.png index 55c73cf877e6c93e144da8257dd8c7f70529a121..7bf840bcf24f07a53e50bc2e9df0a1f70af26824 100644 GIT binary patch literal 16319 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 E51hCr8UO$Q From f551c51413f948a74db28cf90e4a702a5b1a46cd Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Mon, 20 Jan 2025 18:01:42 +0100 Subject: [PATCH 06/12] [UI/UX] Adding options to see mons with only one or only two cost reductions (#5045) --- src/ui/dropdown.ts | 12 +++++++++++- src/ui/starter-select-ui-handler.ts | 13 ++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/ui/dropdown.ts b/src/ui/dropdown.ts index ec124312e14..d8ba88d3484 100644 --- a/src/ui/dropdown.ts +++ b/src/ui/dropdown.ts @@ -7,7 +7,9 @@ export enum DropDownState { ON = 0, OFF = 1, EXCLUDE = 2, - UNLOCKABLE = 3 + UNLOCKABLE = 3, + ONE = 4, + TWO = 5 } export enum DropDownType { @@ -55,6 +57,8 @@ export class DropDownOption extends Phaser.GameObjects.Container { private offColor = 0x272727; private excludeColor = 0xff5555; private unlockableColor = 0xffff00; + private oneColor = 0x33bbff; + private twoColor = 0x33bbff; constructor(val: any, labels: DropDownLabel | DropDownLabel[]) { super(globalScene); @@ -126,6 +130,12 @@ export class DropDownOption extends Phaser.GameObjects.Container { case DropDownState.UNLOCKABLE: this.toggle.setTint(this.unlockableColor); break; + case DropDownState.ONE: + this.toggle.setTint(this.oneColor); + break; + case DropDownState.TWO: + this.toggle.setTint(this.twoColor); + break; } } diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 40325d24af7..d99eb35cf4c 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -450,6 +450,8 @@ export default class StarterSelectUiHandler 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), ]; @@ -2585,13 +2587,18 @@ export default class StarterSelectUiHandler extends MessageUiHandler { }); // Cost Reduction Filter - const isCostReduced = starterData.valueReduction > 0; + const isCostReducedByOne = starterData.valueReduction === 1; + const isCostReducedByTwo = starterData.valueReduction === 2; const isCostReductionUnlockable = this.isValueReductionAvailable(container.species.speciesId); const fitsCostReduction = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => { if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.ON) { - return isCostReduced; + return isCostReducedByOne || isCostReducedByTwo; + } else if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.ONE) { + return isCostReducedByOne; + } else if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.TWO) { + return isCostReducedByTwo; } else if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.EXCLUDE) { - return isStarterProgressable && !isCostReduced; + return isStarterProgressable && !(isCostReducedByOne || isCostReducedByTwo); } else if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.UNLOCKABLE) { return isCostReductionUnlockable; } else if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.OFF) { From d495c487163e8f1cce131ee950f29db836b06363 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 20 Jan 2025 09:11:58 -0800 Subject: [PATCH 07/12] [i18n] Update locales submodule --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index 7bfcbccb9b8..e07ab625f20 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 7bfcbccb9b8192b1059ca7c4c7e7d24901cf579d +Subproject commit e07ab625f2080afe36b61fad291b0ec5eff4000c From d85aedbdfc87a59840f0cdad2f781761d212197a Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 20 Jan 2025 09:12:58 -0800 Subject: [PATCH 08/12] [Bug] Prevent pokemon with 0 HP from being statused (#5137) * [Bug] Prevent pokemon with 0 HP from being statused * Update test * Move check to `trySetStatus()` and update test --- src/field/pokemon.ts | 3 ++ ...s-effect.test.ts => status_effect.test.ts} | 38 +++++++++++++++++++ src/utils.ts | 10 ++--- 3 files changed, 46 insertions(+), 5 deletions(-) rename src/test/data/{status-effect.test.ts => status_effect.test.ts} (92%) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index a833facd2f8..a4b8603cbb0 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3606,6 +3606,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (!this.canSetStatus(effect, asPhase, false, sourcePokemon)) { return false; } + if (this.isFainted() && effect !== StatusEffect.FAINT) { + return false; + } /** * If this Pokemon falls asleep or freezes in the middle of a multi-hit attack, diff --git a/src/test/data/status-effect.test.ts b/src/test/data/status_effect.test.ts similarity index 92% rename from src/test/data/status-effect.test.ts rename to src/test/data/status_effect.test.ts index 4831e8de5de..7948549b8e8 100644 --- a/src/test/data/status-effect.test.ts +++ b/src/test/data/status_effect.test.ts @@ -400,4 +400,42 @@ describe("Status Effects", () => { expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); }); }); + + describe("Behavior", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([ Moves.SPLASH ]) + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.NUZZLE) + .enemyLevel(2000); + }); + + it("should not inflict a 0 HP mon with a status", async () => { + await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]); + + const player = game.scene.getPlayerPokemon()!; + player.hp = 0; + + expect(player.trySetStatus(StatusEffect.BURN)).toBe(false); + expect(player.status?.effect).not.toBe(StatusEffect.BURN); + }); + }); }); diff --git a/src/utils.ts b/src/utils.ts index be0aec84ecd..2235fb69633 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -349,14 +349,14 @@ export class IntegerHolder extends NumberHolder { } } -/** @deprecated Use {@linkcode NumberHolder}*/ -export class FixedInt extends IntegerHolder { - constructor(value: integer) { - super(value); +export class FixedInt { + public readonly value: number; + + constructor(value: number) { + this.value = value; } } -/** @deprecated */ export function fixedInt(value: integer): integer { return new FixedInt(value) as unknown as integer; } From 39283e373b0ad35bf9e2e2a36da30f9f0f134f4e Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Mon, 20 Jan 2025 17:43:55 -0500 Subject: [PATCH 09/12] [UI/UX] Add sort by caught/hatched count to starter select (#5161) --- src/ui/dropdown.ts | 4 +++- src/ui/starter-select-ui-handler.ts | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ui/dropdown.ts b/src/ui/dropdown.ts index d8ba88d3484..8c318b29d64 100644 --- a/src/ui/dropdown.ts +++ b/src/ui/dropdown.ts @@ -29,7 +29,9 @@ export enum SortCriteria { COST = 1, CANDY = 2, IV = 3, - NAME = 4 + NAME = 4, + CAUGHT = 5, + HATCHED = 6 } export class DropDownLabel { diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index d99eb35cf4c..dd427802083 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -502,7 +502,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { new DropDownOption(SortCriteria.COST, new DropDownLabel(i18next.t("filterBar:sortByCost"))), new DropDownOption(SortCriteria.CANDY, new DropDownLabel(i18next.t("filterBar:sortByCandies"))), new DropDownOption(SortCriteria.IV, new DropDownLabel(i18next.t("filterBar:sortByIVs"))), - new DropDownOption(SortCriteria.NAME, new DropDownLabel(i18next.t("filterBar:sortByName"))) + new DropDownOption(SortCriteria.NAME, new DropDownLabel(i18next.t("filterBar:sortByName"))), + new DropDownOption(SortCriteria.CAUGHT, new DropDownLabel(i18next.t("filterBar:sortByNumCaught"))), + new DropDownOption(SortCriteria.HATCHED, new DropDownLabel(i18next.t("filterBar:sortByNumHatched"))) ]; this.filterBar.addFilter(DropDownColumn.SORT, i18next.t("filterBar:sortFilter"), new DropDown(0, 0, sortOptions, this.updateStarters, DropDownType.SINGLE)); this.filterBarContainer.add(this.filterBar); @@ -2698,6 +2700,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { return (avgIVsA - avgIVsB) * -sort.dir; case SortCriteria.NAME: return a.species.name.localeCompare(b.species.name) * -sort.dir; + case SortCriteria.CAUGHT: + return (globalScene.gameData.dexData[a.species.speciesId].caughtCount - globalScene.gameData.dexData[b.species.speciesId].caughtCount) * -sort.dir; + case SortCriteria.HATCHED: + return (globalScene.gameData.dexData[a.species.speciesId].hatchedCount - globalScene.gameData.dexData[b.species.speciesId].hatchedCount) * -sort.dir; } return 0; }); From 93fc779350dca66e446e60211510a99c85efac50 Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Tue, 21 Jan 2025 16:34:18 -0600 Subject: [PATCH 10/12] [Bug] Fix G-Max Urshifus having wrong movesets (#5162) --- src/data/balance/pokemon-level-moves.ts | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/data/balance/pokemon-level-moves.ts b/src/data/balance/pokemon-level-moves.ts index 8e28300eb8a..8fe61da35c0 100644 --- a/src/data/balance/pokemon-level-moves.ts +++ b/src/data/balance/pokemon-level-moves.ts @@ -19718,6 +19718,44 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 48, Moves.CLOSE_COMBAT ], [ 52, Moves.FOCUS_PUNCH ], ], + 2: [ + [ EVOLVE_MOVE, Moves.WICKED_BLOW ], + [ 1, Moves.LEER ], + [ 1, Moves.FOCUS_ENERGY ], + [ 1, Moves.ENDURE ], + [ 1, Moves.ROCK_SMASH ], + [ 1, Moves.SUCKER_PUNCH ], + [ 12, Moves.AERIAL_ACE ], + [ 16, Moves.SCARY_FACE ], + [ 20, Moves.HEADBUTT ], + [ 24, Moves.BRICK_BREAK ], + [ 28, Moves.DETECT ], + [ 32, Moves.BULK_UP ], + [ 36, Moves.IRON_HEAD ], + [ 40, Moves.DYNAMIC_PUNCH ], + [ 44, Moves.COUNTER ], + [ 48, Moves.CLOSE_COMBAT ], + [ 52, Moves.FOCUS_PUNCH ], + ], + 3: [ + [ EVOLVE_MOVE, Moves.SURGING_STRIKES ], + [ 1, Moves.LEER ], + [ 1, Moves.FOCUS_ENERGY ], + [ 1, Moves.ENDURE ], + [ 1, Moves.ROCK_SMASH ], + [ 1, Moves.AQUA_JET ], + [ 12, Moves.AERIAL_ACE ], + [ 16, Moves.SCARY_FACE ], + [ 20, Moves.HEADBUTT ], + [ 24, Moves.BRICK_BREAK ], + [ 28, Moves.DETECT ], + [ 32, Moves.BULK_UP ], + [ 36, Moves.IRON_HEAD ], + [ 40, Moves.DYNAMIC_PUNCH ], + [ 44, Moves.COUNTER ], + [ 48, Moves.CLOSE_COMBAT ], + [ 52, Moves.FOCUS_PUNCH ], + ], }, [Species.CALYREX]: { 1: [ From 271e51be582134c5be30c292ebad99a8ed6c4c45 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:40:05 -0500 Subject: [PATCH 11/12] [Balance] [Feature] Match evil teams to monogen challenge (#4850) * Match evil teams to monogen challenge * Remove outdated comment * Remove BBL adjustment --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: damocleas --- src/battle.ts | 61 +++++++++++++++++++++++++++---------------- src/data/challenge.ts | 55 +++++++++++++++++++++++++++++++------- 2 files changed, 84 insertions(+), 32 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index b1196bb0139..287a981f83d 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -24,9 +24,26 @@ import { ModifierTier } from "#app/modifier/modifier-tier"; import type { MysteryEncounterType } from "#enums/mystery-encounter-type"; export enum ClassicFixedBossWaves { - // TODO: other fixed wave battles should be added here + TOWN_YOUNGSTER = 5, + RIVAL_1 = 8, + RIVAL_2 = 25, + EVIL_GRUNT_1 = 35, + RIVAL_3 = 55, + EVIL_GRUNT_2 = 62, + EVIL_GRUNT_3 = 64, + EVIL_ADMIN_1 = 66, + RIVAL_4 = 95, + EVIL_GRUNT_4 = 112, + EVIL_ADMIN_2 = 114, EVIL_BOSS_1 = 115, + RIVAL_5 = 145, EVIL_BOSS_2 = 165, + ELITE_FOUR_1 = 182, + ELITE_FOUR_2 = 184, + ELITE_FOUR_3 = 186, + ELITE_FOUR_4 = 188, + CHAMPION = 190, + RIVAL_6 = 195, } export enum BattleType { @@ -500,7 +517,7 @@ export class FixedBattleConfig { * @param seedOffset the seed offset to use for the random generation of the trainer * @returns the generated trainer */ -function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], randomGender: boolean = false, seedOffset: number = 0): GetTrainerFunc { +export function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], randomGender: boolean = false, seedOffset: number = 0): GetTrainerFunc { return () => { const rand = Utils.randSeedInt(trainerPool.length); const trainerTypes: TrainerType[] = []; @@ -544,51 +561,51 @@ export interface FixedBattleConfigs { * Champion on 190 */ export const classicFixedBattles: FixedBattleConfigs = { - [5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.TOWN_YOUNGSTER]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(() => new Trainer(TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), - [8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.RIVAL_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), - [25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.RIVAL_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_2, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }), - [35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.EVIL_GRUNT_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)), - [55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.RIVAL_3]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_3, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }), - [62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) + [ClassicFixedBossWaves.EVIL_GRUNT_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)), - [64]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) + [ClassicFixedBossWaves.EVIL_GRUNT_3]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)), - [66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) + [ClassicFixedBossWaves.EVIL_ADMIN_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1) .setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true)), - [95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.RIVAL_4]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_4, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }), - [112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) + [ClassicFixedBossWaves.EVIL_GRUNT_4]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)), - [114]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) + [ClassicFixedBossWaves.EVIL_ADMIN_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1) .setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true, 1)), - [ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) + [ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE, TrainerType.PENNY ])) .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }), - [145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.RIVAL_5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_5, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }), - [ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) + [ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2, TrainerType.PENNY_2 ])) .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }), - [182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.ELITE_FOUR_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])), - [184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) + [ClassicFixedBossWaves.ELITE_FOUR_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.ELITE_FOUR_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY, TrainerType.AMARYS ])), - [186]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) + [ClassicFixedBossWaves.ELITE_FOUR_3]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.ELITE_FOUR_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, [ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ], TrainerType.LARRY_ELITE, TrainerType.LACEY ])), - [188]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) + [ClassicFixedBossWaves.ELITE_FOUR_4]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.ELITE_FOUR_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL, TrainerType.DRAYTON ])), - [190]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) + [ClassicFixedBossWaves.CHAMPION]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.ELITE_FOUR_1) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])), - [195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) + [ClassicFixedBossWaves.RIVAL_6]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_6, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }) }; diff --git a/src/data/challenge.ts b/src/data/challenge.ts index a01ceab8aa3..fab5196601c 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -8,7 +8,7 @@ import { speciesStarterCosts } from "#app/data/balance/starters"; import type Pokemon from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon"; import type { FixedBattleConfig } from "#app/battle"; -import { BattleType } from "#app/battle"; +import { ClassicFixedBossWaves, BattleType, getRandomTrainerFunc } from "#app/battle"; import Trainer, { TrainerVariant } from "#app/field/trainer"; import type { GameMode } from "#app/game-mode"; import { Type } from "#enums/type"; @@ -20,6 +20,7 @@ import type { Moves } from "#enums/moves"; import { TypeColor, TypeShadow } from "#enums/color"; import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { pokemonFormChanges } from "#app/data/pokemon-forms"; +import { ModifierTier } from "#app/modifier/modifier-tier"; /** A constant for the default max cost of the starting party before a run */ const DEFAULT_PARTY_MAX_COST = 10; @@ -464,30 +465,64 @@ export class SingleGenerationChallenge extends Challenge { return false; } - applyFixedBattle(waveIndex: Number, battleConfig: FixedBattleConfig): boolean { - let trainerTypes: TrainerType[] = []; + applyFixedBattle(waveIndex: number, battleConfig: FixedBattleConfig): boolean { + let trainerTypes: (TrainerType | TrainerType[])[] = []; + const evilTeamWaves: number[] = [ ClassicFixedBossWaves.EVIL_GRUNT_1, ClassicFixedBossWaves.EVIL_GRUNT_2, ClassicFixedBossWaves.EVIL_GRUNT_3, ClassicFixedBossWaves.EVIL_ADMIN_1, ClassicFixedBossWaves.EVIL_GRUNT_4, ClassicFixedBossWaves.EVIL_ADMIN_2, ClassicFixedBossWaves.EVIL_BOSS_1, ClassicFixedBossWaves.EVIL_BOSS_2 ]; + const evilTeamGrunts = [[ TrainerType.ROCKET_GRUNT ], [ TrainerType.ROCKET_GRUNT ], [ TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT ], [ TrainerType.GALACTIC_GRUNT ], [ TrainerType.PLASMA_GRUNT ], [ TrainerType.FLARE_GRUNT ], [ TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT ], [ TrainerType.MACRO_GRUNT ], [ TrainerType.STAR_GRUNT ]]; + const evilTeamAdmins = [[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [[ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ]], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], [ TrainerType.FABA, TrainerType.PLUMERIA ], [ TrainerType.OLEANA ], [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]]; + const evilTeamBosses = [[ TrainerType.ROCKET_BOSS_GIOVANNI_1 ], [ TrainerType.ROCKET_BOSS_GIOVANNI_1 ], [ TrainerType.MAXIE, TrainerType.ARCHIE ], [ TrainerType.CYRUS ], [ TrainerType.GHETSIS ], [ TrainerType.LYSANDRE ], [ TrainerType.LUSAMINE, TrainerType.GUZMA ], [ TrainerType.ROSE ], [ TrainerType.PENNY ]]; + const evilTeamBossRematches = [[ TrainerType.ROCKET_BOSS_GIOVANNI_2 ], [ TrainerType.ROCKET_BOSS_GIOVANNI_2 ], [ TrainerType.MAXIE_2, TrainerType.ARCHIE_2 ], [ TrainerType.CYRUS_2 ], [ TrainerType.GHETSIS_2 ], [ TrainerType.LYSANDRE_2 ], [ TrainerType.LUSAMINE_2, TrainerType.GUZMA_2 ], [ TrainerType.ROSE_2 ], [ TrainerType.PENNY_2 ]]; switch (waveIndex) { - case 182: + case ClassicFixedBossWaves.EVIL_GRUNT_1: + trainerTypes = evilTeamGrunts[this.value - 1]; + battleConfig.setBattleType(BattleType.TRAINER).setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true)); + return true; + case ClassicFixedBossWaves.EVIL_GRUNT_2: + case ClassicFixedBossWaves.EVIL_GRUNT_3: + case ClassicFixedBossWaves.EVIL_GRUNT_4: + trainerTypes = evilTeamGrunts[this.value - 1]; + break; + case ClassicFixedBossWaves.EVIL_ADMIN_1: + case ClassicFixedBossWaves.EVIL_ADMIN_2: + trainerTypes = evilTeamAdmins[this.value - 1]; + break; + case ClassicFixedBossWaves.EVIL_BOSS_1: + trainerTypes = evilTeamBosses[this.value - 1]; + battleConfig.setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1).setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true)) + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }); + return true; + case ClassicFixedBossWaves.EVIL_BOSS_2: + trainerTypes = evilTeamBossRematches[this.value - 1]; + battleConfig.setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1).setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true)) + .setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }); + return true; + case ClassicFixedBossWaves.ELITE_FOUR_1: trainerTypes = [ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, Utils.randSeedItem([ TrainerType.HALA, TrainerType.MOLAYNE ]), TrainerType.MARNIE_ELITE, TrainerType.RIKA ]; break; - case 184: + case ClassicFixedBossWaves.ELITE_FOUR_2: trainerTypes = [ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY ]; break; - case 186: + case ClassicFixedBossWaves.ELITE_FOUR_3: trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ]), TrainerType.LARRY_ELITE ]; break; - case 188: + case ClassicFixedBossWaves.ELITE_FOUR_4: trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ]; break; - case 190: + case ClassicFixedBossWaves.CHAMPION: trainerTypes = [ TrainerType.BLUE, Utils.randSeedItem([ TrainerType.RED, TrainerType.LANCE_CHAMPION ]), Utils.randSeedItem([ TrainerType.STEVEN, TrainerType.WALLACE ]), TrainerType.CYNTHIA, Utils.randSeedItem([ TrainerType.ALDER, TrainerType.IRIS ]), TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, Utils.randSeedItem([ TrainerType.GEETA, TrainerType.NEMONA ]) ]; break; } if (trainerTypes.length === 0) { return false; - } else { - battleConfig.setBattleType(BattleType.TRAINER).setGetTrainerFunc(() => new Trainer(trainerTypes[this.value - 1], TrainerVariant.DEFAULT)); + } else if (evilTeamWaves.includes(waveIndex)) { + battleConfig.setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1).setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true)); return true; + } else if (waveIndex >= ClassicFixedBossWaves.ELITE_FOUR_1 && waveIndex <= ClassicFixedBossWaves.CHAMPION) { + const ttypes = trainerTypes as TrainerType[]; + battleConfig.setBattleType(BattleType.TRAINER).setGetTrainerFunc(() => new Trainer(ttypes[this.value - 1], TrainerVariant.DEFAULT)); + return true; + } else { + return false; } } From d10b7c05f73887902391a8cf7bfff56756b30373 Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Wed, 22 Jan 2025 00:42:27 +0100 Subject: [PATCH 12/12] [Refactor] Descriptions for evolution and form change requirements (#5147) * Adding extensions of the SpeciesEvolutionCondition class * Commented out logs * Introducing descriptions for form changes; new class SpeciesFormChangeAbilityTrigger which is functionally identical to SpeciesFormChangeManualTrigger but has appropriate description * Fix in description of compound trigger * Commenting out logs * Small fixes, clearing logs, implementing suggestions * Apply suggestions from code review Trigger functions are declared with no arguments when not needed. Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Removed exports for new classes --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: damocleas --- src/data/ability.ts | 12 +- src/data/balance/pokemon-evolutions.ts | 498 +++++++++++++----- src/data/battler-tags.ts | 10 +- .../the-winstrate-challenge-encounter.ts | 4 +- src/data/pokemon-forms.ts | 108 ++-- src/plugins/i18n.ts | 1 + 6 files changed, 433 insertions(+), 200 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 0e8b3c2392d..5e5231176b5 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -16,7 +16,7 @@ import type { ArenaTrapTag } from "./arena-tag"; import { ArenaTagSide } from "./arena-tag"; import { BerryModifier, HitHealModifier, PokemonHeldItemModifier } from "../modifier/modifier"; import { TerrainType } from "./terrain"; -import { SpeciesFormChangeManualTrigger, SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "./pokemon-forms"; +import { SpeciesFormChangeAbilityTrigger, SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "./pokemon-forms"; import i18next from "i18next"; import type { Localizable } from "#app/interfaces/locales"; import { Command } from "../ui/command-ui-handler"; @@ -232,7 +232,7 @@ export class PostBattleInitFormChangeAbAttr extends PostBattleInitAbAttr { applyPostBattleInit(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { const formIndex = this.formFunc(pokemon); if (formIndex !== pokemon.formIndex && !simulated) { - return globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); + return globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false); } return false; @@ -1875,7 +1875,7 @@ export class PostVictoryFormChangeAbAttr extends PostVictoryAbAttr { const formIndex = this.formFunc(pokemon); if (formIndex !== pokemon.formIndex) { if (!simulated) { - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false); } return true; } @@ -2306,7 +2306,7 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr { applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { const formIndex = this.formFunc(pokemon); if (formIndex !== pokemon.formIndex) { - return simulated || globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); + return simulated || globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false); } return false; @@ -2734,7 +2734,7 @@ export class PreSwitchOutFormChangeAbAttr extends PreSwitchOutAbAttr { const formIndex = this.formFunc(pokemon); if (formIndex !== pokemon.formIndex) { if (!simulated) { - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false); } return true; } @@ -3704,7 +3704,7 @@ export class PostTurnFormChangeAbAttr extends PostTurnAbAttr { const formIndex = this.formFunc(pokemon); if (formIndex !== pokemon.formIndex) { if (!simulated) { - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false); } return true; diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index bf34b5122dc..a8fe3b5f4ab 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -12,6 +12,8 @@ import { Species } from "#enums/species"; import { TimeOfDay } from "#enums/time-of-day"; import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier, TempExtraModifierModifier } from "#app/modifier/modifier"; import { SpeciesFormKey } from "#enums/species-form-key"; +import { speciesStarterCosts } from "./starters"; +import i18next from "i18next"; export enum SpeciesWildEvolutionDelay { @@ -120,17 +122,214 @@ export class FusionSpeciesFormEvolution extends SpeciesFormEvolution { export class SpeciesEvolutionCondition { public predicate: EvolutionConditionPredicate; - public enforceFunc: EvolutionConditionEnforceFunc | undefined; + public enforceFunc?: EvolutionConditionEnforceFunc; + public description: string; constructor(predicate: EvolutionConditionPredicate, enforceFunc?: EvolutionConditionEnforceFunc) { this.predicate = predicate; this.enforceFunc = enforceFunc; + this.description = ""; } } -export class SpeciesFriendshipEvolutionCondition extends SpeciesEvolutionCondition { - constructor(friendshipAmount: integer, predicate?: EvolutionConditionPredicate, enforceFunc?: EvolutionConditionEnforceFunc) { - super(p => p.friendship >= friendshipAmount && (!predicate || predicate(p)), enforceFunc); +class GenderEvolutionCondition extends SpeciesEvolutionCondition { + public gender: Gender; + constructor(gender: Gender) { + super(p => p.gender === gender, p => p.gender = gender); + this.gender = gender; + this.description = i18next.t("pokemonEvolutions:gender", { gender: i18next.t(`pokemonEvolutions:${Gender[gender]}`) }); + } +} + +class TimeOfDayEvolutionCondition extends SpeciesEvolutionCondition { + public timesOfDay: TimeOfDay[]; + constructor(tod: "day" | "night") { + if (tod === "day") { + super(() => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY); + this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ]; + } else if (tod === "night") { + super(() => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT); + this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]; + } else { + super(() => false); + this.timesOfDay = []; + } + this.description = i18next.t("pokemonEvolutions:timeOfDay", { tod: i18next.t(`pokemonEvolutions:${tod}`) }); + } +} + +class MoveEvolutionCondition extends SpeciesEvolutionCondition { + public move: Moves; + constructor(move: Moves) { + super(p => p.moveset.filter(m => m?.moveId === move).length > 0); + this.move = move; + const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); + this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) }); + } +} + +class FriendshipEvolutionCondition extends SpeciesEvolutionCondition { + public amount: integer; + constructor(amount: number) { + super(p => p.friendship >= amount); + this.amount = amount; + this.description = i18next.t("pokemonEvolutions:friendship"); + } +} + +class FriendshipTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition { + public amount: integer; + public timesOfDay: TimeOfDay[]; + constructor(amount: number, tod: "day" | "night") { + if (tod === "day") { + super(p => p.friendship >= amount && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)); + this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ]; + } else if (tod === "night") { + super(p => p.friendship >= amount && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)); + this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]; + } else { + super(p => false); + this.timesOfDay = []; + } + this.amount = amount; + this.description = i18next.t("pokemonEvolutions:friendshipTimeOfDay", { tod: i18next.t(`pokemonEvolutions:${tod}`) }); + } +} + +class FriendshipMoveTypeEvolutionCondition extends SpeciesEvolutionCondition { + public amount: integer; + public type: Type; + constructor(amount: number, type: Type) { + super(p => p.friendship >= amount && !!p.getMoveset().find(m => m?.getMove().type === type)); + this.amount = amount; + this.type = type; + this.description = i18next.t("pokemonEvolutions:friendshipMoveType", { type: i18next.t(`pokemonInfo:Type.${Type[this.type]}`) }); + } +} + +class ShedinjaEvolutionCondition extends SpeciesEvolutionCondition { + constructor() { + super(() => globalScene.getPlayerParty().length < 6 && globalScene.pokeballCounts[PokeballType.POKEBALL] > 0); + this.description = i18next.t("pokemonEvolutions:shedinja"); + } +} + +class PartyTypeEvolutionCondition extends SpeciesEvolutionCondition { + public type: Type; + constructor(type: Type) { + super(() => !!globalScene.getPlayerParty().find(p => p.getTypes(false, false, true).indexOf(type) > -1)); + this.type = type; + this.description = i18next.t("pokemonEvolutions:partyType", { type: i18next.t(`pokemonInfo:Type.${Type[this.type]}`) }); + } +} + +class CaughtEvolutionCondition extends SpeciesEvolutionCondition { + public species: Species; + constructor(species: Species) { + super(() => !!globalScene.gameData.dexData[species].caughtAttr); + this.species = species; + this.description = i18next.t("pokemonEvolutions:caught", { species: i18next.t(`pokemon:${Species[this.species].toLowerCase()}`) }); + } +} + +class WeatherEvolutionCondition extends SpeciesEvolutionCondition { + public weatherTypes: WeatherType[]; + constructor(weatherTypes: WeatherType[]) { + super(() => weatherTypes.indexOf(globalScene.arena.weather?.weatherType || WeatherType.NONE) > -1); + this.weatherTypes = weatherTypes; + } +} + +class MoveTypeEvolutionCondition extends SpeciesEvolutionCondition { + public type: Type; + constructor(type: Type) { + super(p => p.moveset.filter(m => m?.getMove().type === type).length > 0); + this.type = type; + this.description = i18next.t("pokemonEvolutions:moveType", { type: i18next.t(`pokemonInfo:Type.${Type[this.type]}`) }); + } +} + +class TreasureEvolutionCondition extends SpeciesEvolutionCondition { + constructor() { + super(p => p.evoCounter + + p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length + + globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier + || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9); + this.description = i18next.t("pokemonEvolutions:treasure"); + } +} + +class TyrogueEvolutionCondition extends SpeciesEvolutionCondition { + public move: Moves; + constructor(move: Moves) { + super(p => + p.getMoveset(true).find(m => m && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(m?.moveId))?.moveId === move); + this.move = move; + const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); + this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) }); + } +} + +class NatureEvolutionCondition extends SpeciesEvolutionCondition { + public natures: Nature[]; + constructor(natures: Nature[]) { + super(p => natures.indexOf(p.getNature()) > -1); + this.natures = natures; + this.description = i18next.t("pokemonEvolutions:nature"); + } +} + +class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition { + public move: Moves; + public timesOfDay: TimeOfDay[]; + constructor(move: Moves, tod: "day" | "night") { + if (tod === "day") { + super(p => p.moveset.filter(m => m?.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)); + this.move = move; + this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ]; + } else if (tod === "night") { + super(p => p.moveset.filter(m => m?.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)); + this.move = move; + this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ]; + } else { + super(() => false); + this.timesOfDay = []; + } + const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); + this.description = i18next.t("pokemonEvolutions:moveTimeOfDay", { move: i18next.t(`move:${moveKey}.name`), tod: i18next.t(`pokemonEvolutions:${tod}`) }); + } +} + +class BiomeEvolutionCondition extends SpeciesEvolutionCondition { + public biomes: Biome[]; + constructor(biomes: Biome[]) { + super(() => biomes.filter(b => b === globalScene.arena.biomeType).length > 0); + this.biomes = biomes; + this.description = i18next.t("pokemonEvolutions:biome"); + } +} + +class DunsparceEvolutionCondition extends SpeciesEvolutionCondition { + constructor() { + super(p => { + let ret = false; + if (p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0) { + globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); + } + return ret; + }); + const moveKey = Moves[Moves.HYPER_DRILL].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); + this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) }); + } +} + +class TandemausEvolutionCondition extends SpeciesEvolutionCondition { + constructor() { + super(p => { + let ret = false; + globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); + return ret; + }); } } @@ -267,8 +466,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ELECTRODE, 30, null, null) ], [Species.CUBONE]: [ - new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), - new SpeciesEvolution(Species.MAROWAK, 28, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new TimeOfDayEvolutionCondition("night")), + new SpeciesEvolution(Species.MAROWAK, 28, null, new TimeOfDayEvolutionCondition("day")) ], [Species.TYROGUE]: [ /** @@ -277,19 +476,13 @@ export const pokemonEvolutions: PokemonEvolutions = { * If Tyrogue knows multiple of these moves, its evolution is based on * the first qualifying move in its moveset. */ - new SpeciesEvolution(Species.HITMONLEE, 20, null, new SpeciesEvolutionCondition(p => - p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.LOW_SWEEP - )), - new SpeciesEvolution(Species.HITMONCHAN, 20, null, new SpeciesEvolutionCondition(p => - p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.MACH_PUNCH - )), - new SpeciesEvolution(Species.HITMONTOP, 20, null, new SpeciesEvolutionCondition(p => - p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.RAPID_SPIN - )), + new SpeciesEvolution(Species.HITMONLEE, 20, null, new TyrogueEvolutionCondition(Moves.LOW_SWEEP)), + new SpeciesEvolution(Species.HITMONCHAN, 20, null, new TyrogueEvolutionCondition(Moves.MACH_PUNCH)), + new SpeciesEvolution(Species.HITMONTOP, 20, null, new TyrogueEvolutionCondition(Moves.RAPID_SPIN)), ], [Species.KOFFING]: [ - new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), - new SpeciesEvolution(Species.WEEZING, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new TimeOfDayEvolutionCondition("night")), + new SpeciesEvolution(Species.WEEZING, 35, null, new TimeOfDayEvolutionCondition("day")) ], [Species.RHYHORN]: [ new SpeciesEvolution(Species.RHYDON, 42, null, null) @@ -334,8 +527,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.QUILAVA, 14, null, null) ], [Species.QUILAVA]: [ - new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), - new SpeciesEvolution(Species.TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new TimeOfDayEvolutionCondition("night")), + new SpeciesEvolution(Species.TYPHLOSION, 36, null, new TimeOfDayEvolutionCondition("day")) ], [Species.TOTODILE]: [ new SpeciesEvolution(Species.CROCONAW, 18, null, null) @@ -437,8 +630,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.LINOONE, 20, null, null) ], [Species.WURMPLE]: [ - new SpeciesEvolution(Species.SILCOON, 7, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)), - new SpeciesEvolution(Species.CASCOON, 7, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.SILCOON, 7, null, new TimeOfDayEvolutionCondition("day")), + new SpeciesEvolution(Species.CASCOON, 7, null, new TimeOfDayEvolutionCondition("night")) ], [Species.SILCOON]: [ new SpeciesEvolution(Species.BEAUTIFLY, 10, null, null) @@ -462,8 +655,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.KIRLIA, 20, null, null) ], [Species.KIRLIA]: [ - new SpeciesEvolution(Species.GARDEVOIR, 30, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)), - new SpeciesEvolution(Species.GALLADE, 30, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)) + new SpeciesEvolution(Species.GARDEVOIR, 30, null, new GenderEvolutionCondition(Gender.FEMALE)), + new SpeciesEvolution(Species.GALLADE, 30, null, new GenderEvolutionCondition(Gender.MALE)) ], [Species.SURSKIT]: [ new SpeciesEvolution(Species.MASQUERAIN, 22, null, null) @@ -479,7 +672,7 @@ export const pokemonEvolutions: PokemonEvolutions = { ], [Species.NINCADA]: [ new SpeciesEvolution(Species.NINJASK, 20, null, null), - new SpeciesEvolution(Species.SHEDINJA, 20, null, new SpeciesEvolutionCondition(p => globalScene.getPlayerParty().length < 6 && globalScene.pokeballCounts[PokeballType.POKEBALL] > 0)) + new SpeciesEvolution(Species.SHEDINJA, 20, null, new ShedinjaEvolutionCondition()) ], [Species.WHISMUR]: [ new SpeciesEvolution(Species.LOUDRED, 20, null, null) @@ -551,8 +744,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DUSCLOPS, 37, null, null) ], [Species.SNORUNT]: [ - new SpeciesEvolution(Species.GLALIE, 42, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)), - new SpeciesEvolution(Species.FROSLASS, 42, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)) + new SpeciesEvolution(Species.GLALIE, 42, null, new GenderEvolutionCondition(Gender.MALE)), + new SpeciesEvolution(Species.FROSLASS, 42, null, new GenderEvolutionCondition(Gender.FEMALE)) ], [Species.SPHEAL]: [ new SpeciesEvolution(Species.SEALEO, 32, null, null) @@ -615,11 +808,11 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.BASTIODON, 30, null, null) ], [Species.BURMY]: [ - new SpeciesEvolution(Species.MOTHIM, 20, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)), - new SpeciesEvolution(Species.WORMADAM, 20, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)) + new SpeciesEvolution(Species.MOTHIM, 20, null, new GenderEvolutionCondition(Gender.MALE)), + new SpeciesEvolution(Species.WORMADAM, 20, null, new GenderEvolutionCondition(Gender.FEMALE)) ], [Species.COMBEE]: [ - new SpeciesEvolution(Species.VESPIQUEN, 21, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)) + new SpeciesEvolution(Species.VESPIQUEN, 21, null, new GenderEvolutionCondition(Gender.FEMALE)) ], [Species.BUIZEL]: [ new SpeciesEvolution(Species.FLOATZEL, 26, null, null) @@ -661,7 +854,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.LUMINEON, 31, null, null) ], [Species.MANTYKE]: [ - new SpeciesEvolution(Species.MANTINE, 32, null, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.REMORAID].caughtAttr), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.MANTINE, 32, null, new CaughtEvolutionCondition(Species.REMORAID), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.SNOVER]: [ new SpeciesEvolution(Species.ABOMASNOW, 40, null, null) @@ -682,8 +875,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DEWOTT, 17, null, null) ], [Species.DEWOTT]: [ - new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), - new SpeciesEvolution(Species.SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new TimeOfDayEvolutionCondition("night")), + new SpeciesEvolution(Species.SAMUROTT, 36, null, new TimeOfDayEvolutionCondition("day")) ], [Species.PATRAT]: [ new SpeciesEvolution(Species.WATCHOG, 20, null, null) @@ -833,8 +1026,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.KINGAMBIT, 1, EvolutionItem.LEADERS_CREST, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.RUFFLET]: [ - new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), - new SpeciesEvolution(Species.BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new TimeOfDayEvolutionCondition("night")), + new SpeciesEvolution(Species.BRAVIARY, 54, null, new TimeOfDayEvolutionCondition("day")) ], [Species.VULLABY]: [ new SpeciesEvolution(Species.MANDIBUZZ, 54, null, null) @@ -891,11 +1084,11 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.GOGOAT, 32, null, null) ], [Species.PANCHAM]: [ - new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!globalScene.getPlayerParty().find(p => p.getTypes(false, false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.PANGORO, 32, null, new PartyTypeEvolutionCondition(Type.DARK), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.ESPURR]: [ - new SpeciesFormEvolution(Species.MEOWSTIC, "", "female", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)), - new SpeciesFormEvolution(Species.MEOWSTIC, "", "", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)) + new SpeciesFormEvolution(Species.MEOWSTIC, "", "female", 25, null, new GenderEvolutionCondition(Gender.FEMALE)), + new SpeciesFormEvolution(Species.MEOWSTIC, "", "", 25, null, new GenderEvolutionCondition(Gender.MALE)) ], [Species.HONEDGE]: [ new SpeciesEvolution(Species.DOUBLADE, 35, null, null) @@ -913,21 +1106,21 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CLAWITZER, 37, null, null) ], [Species.TYRUNT]: [ - new SpeciesEvolution(Species.TYRANTRUM, 39, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.TYRANTRUM, 39, null, new TimeOfDayEvolutionCondition("day")) ], [Species.AMAURA]: [ - new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.AURORUS, 39, null, new TimeOfDayEvolutionCondition("night")) ], [Species.GOOMY]: [ - new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), - new SpeciesEvolution(Species.SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new TimeOfDayEvolutionCondition("night")), + new SpeciesEvolution(Species.SLIGGOO, 40, null, new TimeOfDayEvolutionCondition("day")) ], [Species.SLIGGOO]: [ - new SpeciesEvolution(Species.GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(globalScene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.GOODRA, 50, null, new WeatherEvolutionCondition([ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ]), SpeciesWildEvolutionDelay.LONG) ], [Species.BERGMITE]: [ - new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), - new SpeciesEvolution(Species.AVALUGG, 37, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new TimeOfDayEvolutionCondition("night")), + new SpeciesEvolution(Species.AVALUGG, 37, null, new TimeOfDayEvolutionCondition("day")) ], [Species.NOIBAT]: [ new SpeciesEvolution(Species.NOIVERN, 48, null, null) @@ -936,8 +1129,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DARTRIX, 17, null, null) ], [Species.DARTRIX]: [ - new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), - new SpeciesEvolution(Species.DECIDUEYE, 34, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new TimeOfDayEvolutionCondition("night")), + new SpeciesEvolution(Species.DECIDUEYE, 34, null, new TimeOfDayEvolutionCondition("day")) ], [Species.LITTEN]: [ new SpeciesEvolution(Species.TORRACAT, 17, null, null) @@ -958,7 +1151,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.TOUCANNON, 28, null, null) ], [Species.YUNGOOS]: [ - new SpeciesEvolution(Species.GUMSHOOS, 20, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.GUMSHOOS, 20, null, new TimeOfDayEvolutionCondition("day")) ], [Species.GRUBBIN]: [ new SpeciesEvolution(Species.CHARJABUG, 20, null, null) @@ -976,13 +1169,13 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ARAQUANID, 22, null, null) ], [Species.FOMANTIS]: [ - new SpeciesEvolution(Species.LURANTIS, 34, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)) + new SpeciesEvolution(Species.LURANTIS, 34, null, new TimeOfDayEvolutionCondition("day")) ], [Species.MORELULL]: [ new SpeciesEvolution(Species.SHIINOTIC, 24, null, null) ], [Species.SALANDIT]: [ - new SpeciesEvolution(Species.SALAZZLE, 33, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)) + new SpeciesEvolution(Species.SALAZZLE, 33, null, new GenderEvolutionCondition(Gender.FEMALE)) ], [Species.STUFFUL]: [ new SpeciesEvolution(Species.BEWEAR, 27, null, null) @@ -1013,7 +1206,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.MELMETAL, 48, null, null) ], [Species.ALOLA_RATTATA]: [ - new SpeciesEvolution(Species.ALOLA_RATICATE, 20, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.ALOLA_RATICATE, 20, null, new TimeOfDayEvolutionCondition("night")) ], [Species.ALOLA_DIGLETT]: [ new SpeciesEvolution(Species.ALOLA_DUGTRIO, 26, null, null) @@ -1086,7 +1279,8 @@ export const pokemonEvolutions: PokemonEvolutions = { ], [Species.TOXEL]: [ new SpeciesFormEvolution(Species.TOXTRICITY, "", "lowkey", 30, null, - new SpeciesEvolutionCondition(p => [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ].indexOf(p.getNature()) > -1)), + new NatureEvolutionCondition([ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ]) + ), new SpeciesFormEvolution(Species.TOXTRICITY, "", "amped", 30, null, null) ], [Species.SIZZLIPEDE]: [ @@ -1136,7 +1330,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.GALAR_LINOONE, 20, null, null) ], [Species.GALAR_LINOONE]: [ - new SpeciesEvolution(Species.OBSTAGOON, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.OBSTAGOON, 35, null, new TimeOfDayEvolutionCondition("night")) ], [Species.GALAR_YAMASK]: [ new SpeciesEvolution(Species.RUNERIGUS, 34, null, null) @@ -1145,7 +1339,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.HISUI_ZOROARK, 30, null, null) ], [Species.HISUI_SLIGGOO]: [ - new SpeciesEvolution(Species.HISUI_GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(globalScene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.HISUI_GOODRA, 50, null, new WeatherEvolutionCondition([ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ]), SpeciesWildEvolutionDelay.LONG) ], [Species.SPRIGATITO]: [ new SpeciesEvolution(Species.FLORAGATO, 16, null, null) @@ -1166,8 +1360,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.QUAQUAVAL, 36, null, null) ], [Species.LECHONK]: [ - new SpeciesFormEvolution(Species.OINKOLOGNE, "", "female", 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)), - new SpeciesFormEvolution(Species.OINKOLOGNE, "", "", 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)) + new SpeciesFormEvolution(Species.OINKOLOGNE, "", "female", 18, null, new GenderEvolutionCondition(Gender.FEMALE)), + new SpeciesFormEvolution(Species.OINKOLOGNE, "", "", 18, null, new GenderEvolutionCondition(Gender.MALE)) ], [Species.TAROUNTULA]: [ new SpeciesEvolution(Species.SPIDOPS, 15, null, null) @@ -1182,11 +1376,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.PAWMOT, 32, null, null) ], [Species.TANDEMAUS]: [ - new SpeciesFormEvolution(Species.MAUSHOLD, "", "three", 25, null, new SpeciesEvolutionCondition(p => { - let ret = false; - globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); - return ret; - })), + new SpeciesFormEvolution(Species.MAUSHOLD, "", "three", 25, null, new TandemausEvolutionCondition()), new SpeciesEvolution(Species.MAUSHOLD, 25, null, null) ], [Species.FIDOUGH]: [ @@ -1244,7 +1434,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.GLIMMORA, 35, null, null) ], [Species.GREAVARD]: [ - new SpeciesEvolution(Species.HOUNDSTONE, 30, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)) + new SpeciesEvolution(Species.HOUNDSTONE, 30, null, new TimeOfDayEvolutionCondition("night")) ], [Species.FRIGIBAX]: [ new SpeciesEvolution(Species.ARCTIBAX, 35, null, null) @@ -1301,21 +1491,21 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.TANGELA]: [ - new SpeciesEvolution(Species.TANGROWTH, 34, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.TANGROWTH, 34, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG) ], [Species.LICKITUNG]: [ - new SpeciesEvolution(Species.LICKILICKY, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ROLLOUT).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.LICKILICKY, 32, null, new MoveEvolutionCondition(Moves.ROLLOUT), SpeciesWildEvolutionDelay.LONG) ], [Species.STARYU]: [ new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.EEVEE]: [ - new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.UMBREON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new FriendshipMoveTypeEvolutionCondition(120, Type.FAIRY), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new FriendshipMoveTypeEvolutionCondition(120, Type.FAIRY), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "day"), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "day"), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "night"), SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.UMBREON, "partner", "", 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "night"), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.VAPOREON, "", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.VAPOREON, "partner", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.JOLTEON, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG), @@ -1331,13 +1521,13 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.AIPOM]: [ - new SpeciesEvolution(Species.AMBIPOM, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DOUBLE_HIT).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.AMBIPOM, 32, null, new MoveEvolutionCondition(Moves.DOUBLE_HIT), SpeciesWildEvolutionDelay.LONG) ], [Species.SUNKERN]: [ new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.YANMA]: [ - new SpeciesEvolution(Species.YANMEGA, 33, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.YANMEGA, 33, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG) ], [Species.MURKROW]: [ new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1346,32 +1536,26 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.GIRAFARIG]: [ - new SpeciesEvolution(Species.FARIGIRAF, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.TWIN_BEAM).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.FARIGIRAF, 32, null, new MoveEvolutionCondition(Moves.TWIN_BEAM), SpeciesWildEvolutionDelay.LONG) ], [Species.DUNSPARCE]: [ - new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new SpeciesEvolutionCondition(p => { - let ret = false; - if (p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0) { - globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); - } - return ret; - }), SpeciesWildEvolutionDelay.LONG), - new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new DunsparceEvolutionCondition(), SpeciesWildEvolutionDelay.LONG), + new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new MoveEvolutionCondition(Moves.HYPER_DRILL), SpeciesWildEvolutionDelay.LONG) ], [Species.GLIGAR]: [ - new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new TimeOfDayEvolutionCondition("night") /* Razor fang at night*/, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SNEASEL]: [ - new SpeciesEvolution(Species.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor claw at night*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, new TimeOfDayEvolutionCondition("night") /* Razor claw at night*/, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.URSARING]: [ new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna ], [Species.PILOSWINE]: [ - new SpeciesEvolution(Species.MAMOSWINE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.MAMOSWINE, 1, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.STANTLER]: [ - new SpeciesEvolution(Species.WYRDEER, 25, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.PSYSHIELD_BASH).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.WYRDEER, 25, null, new MoveEvolutionCondition(Moves.PSYSHIELD_BASH), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.LOMBRE]: [ new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) @@ -1389,11 +1573,11 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.BONSLY]: [ - new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.SUDOWOODO, 1, null, new MoveEvolutionCondition(Moves.MIMIC), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.MIME_JR]: [ - new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), SpeciesWildEvolutionDelay.MEDIUM), - new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "night"), SpeciesWildEvolutionDelay.MEDIUM), + new SpeciesEvolution(Species.MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "day"), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.PANSAGE]: [ new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) @@ -1415,8 +1599,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.BASCULIN]: [ - new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "female", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "male", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "female", 40, null, new GenderEvolutionCondition(Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "male", 40, null, new GenderEvolutionCondition(Gender.MALE), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.MINCCINO]: [ new SpeciesEvolution(Species.CINCCINO, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG) @@ -1443,15 +1627,15 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CRABOMINABLE, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.ROCKRUFF]: [ - new SpeciesFormEvolution(Species.LYCANROC, "", "midday", 25, null, new SpeciesEvolutionCondition(p => (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY) && (p.formIndex === 0))), - new SpeciesFormEvolution(Species.LYCANROC, "own-tempo", "dusk", 25, null, new SpeciesEvolutionCondition(p => p.formIndex === 1)), - new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0))) + new SpeciesFormEvolution(Species.LYCANROC, "own-tempo", "dusk", 25, null, null), + new SpeciesFormEvolution(Species.LYCANROC, "", "midday", 25, null, new TimeOfDayEvolutionCondition("day")), + new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new TimeOfDayEvolutionCondition("night")) ], [Species.STEENEE]: [ - new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.TSAREENA, 28, null, new MoveEvolutionCondition(Moves.STOMP), SpeciesWildEvolutionDelay.LONG) ], [Species.POIPOLE]: [ - new SpeciesEvolution(Species.NAGANADEL, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DRAGON_PULSE).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.NAGANADEL, 1, null, new MoveEvolutionCondition(Moves.DRAGON_PULSE), SpeciesWildEvolutionDelay.LONG) ], [Species.ALOLA_SANDSHREW]: [ new SpeciesEvolution(Species.ALOLA_SANDSLASH, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) @@ -1465,22 +1649,40 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.APPLETUN, 1, EvolutionItem.SWEET_APPLE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.CLOBBOPUS]: [ - new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.TAUNT).length > 0)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/) + new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new MoveEvolutionCondition(Moves.TAUNT)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/) ], [Species.SINISTEA]: [ new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.POLTEAGEIST, "antique", "antique", 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG) ], [Species.MILCERY]: [ - new SpeciesFormEvolution(Species.ALCREMIE, "", "vanilla-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.TOWN || globalScene.arena.biomeType === Biome.PLAINS || globalScene.arena.biomeType === Biome.GRASS || globalScene.arena.biomeType === Biome.TALL_GRASS || globalScene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.BADLANDS || globalScene.arena.biomeType === Biome.VOLCANO || globalScene.arena.biomeType === Biome.GRAVEYARD || globalScene.arena.biomeType === Biome.FACTORY || globalScene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALCREMIE, "", "matcha-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.FOREST || globalScene.arena.biomeType === Biome.SWAMP || globalScene.arena.biomeType === Biome.MEADOW || globalScene.arena.biomeType === Biome.JUNGLE), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALCREMIE, "", "mint-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.SEA || globalScene.arena.biomeType === Biome.BEACH || globalScene.arena.biomeType === Biome.LAKE || globalScene.arena.biomeType === Biome.SEABED), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALCREMIE, "", "lemon-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.DESERT || globalScene.arena.biomeType === Biome.POWER_PLANT || globalScene.arena.biomeType === Biome.DOJO || globalScene.arena.biomeType === Biome.RUINS || globalScene.arena.biomeType === Biome.CONSTRUCTION_SITE), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALCREMIE, "", "salted-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.MOUNTAIN || globalScene.arena.biomeType === Biome.CAVE || globalScene.arena.biomeType === Biome.ICE_CAVE || globalScene.arena.biomeType === Biome.FAIRY_CAVE || globalScene.arena.biomeType === Biome.SNOWY_FOREST), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.WASTELAND || globalScene.arena.biomeType === Biome.LABORATORY), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALCREMIE, "", "caramel-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.TEMPLE || globalScene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.LONG), - new SpeciesFormEvolution(Species.ALCREMIE, "", "rainbow-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.ABYSS || globalScene.arena.biomeType === Biome.SPACE || globalScene.arena.biomeType === Biome.END), SpeciesWildEvolutionDelay.LONG) + new SpeciesFormEvolution(Species.ALCREMIE, "", "vanilla-cream", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.TOWN, Biome.PLAINS, Biome.GRASS, Biome.TALL_GRASS, Biome.METROPOLIS ]), + SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-cream", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.BADLANDS, Biome.VOLCANO, Biome.GRAVEYARD, Biome.FACTORY, Biome.SLUM ]), + SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALCREMIE, "", "matcha-cream", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.FOREST, Biome.SWAMP, Biome.MEADOW, Biome.JUNGLE ]), + SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALCREMIE, "", "mint-cream", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.SEA, Biome.BEACH, Biome.LAKE, Biome.SEABED ]), + SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALCREMIE, "", "lemon-cream", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.DESERT, Biome.POWER_PLANT, Biome.DOJO, Biome.RUINS, Biome.CONSTRUCTION_SITE ]), + SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALCREMIE, "", "salted-cream", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.MOUNTAIN, Biome.CAVE, Biome.ICE_CAVE, Biome.FAIRY_CAVE, Biome.SNOWY_FOREST ]), + SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.WASTELAND, Biome.LABORATORY ]), + SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALCREMIE, "", "caramel-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.TEMPLE, Biome.ISLAND ]), + SpeciesWildEvolutionDelay.LONG), + new SpeciesFormEvolution(Species.ALCREMIE, "", "rainbow-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, + new BiomeEvolutionCondition([ Biome.ABYSS, Biome.SPACE, Biome.END ]), + SpeciesWildEvolutionDelay.LONG) ], [Species.DURALUDON]: [ new SpeciesFormEvolution(Species.ARCHALUDON, "", "", 1, EvolutionItem.METAL_ALLOY, null, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1499,10 +1701,10 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.HISUI_ELECTRODE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) ], [Species.HISUI_QWILFISH]: [ - new SpeciesEvolution(Species.OVERQWIL, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.BARB_BARRAGE).length > 0), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.OVERQWIL, 28, null, new MoveEvolutionCondition(Moves.BARB_BARRAGE), SpeciesWildEvolutionDelay.LONG) ], [Species.HISUI_SNEASEL]: [ - new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY /* Razor claw at day*/), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new TimeOfDayEvolutionCondition("day") /* Razor claw at day*/, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.CHARCADET]: [ new SpeciesEvolution(Species.ARMAROUGE, 1, EvolutionItem.AUSPICIOUS_ARMOR, null, SpeciesWildEvolutionDelay.LONG), @@ -1522,7 +1724,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG) ], [Species.DIPPLIN]: [ - new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DRAGON_CHEER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new MoveEvolutionCondition(Moves.DRAGON_CHEER), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.KADABRA]: [ new SpeciesEvolution(Species.ALAKAZAM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1537,9 +1739,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.GENGAR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.ONIX]: [ - new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition( - p => p.moveset.filter(m => m?.getMove().type === Type.STEEL).length > 0), - SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new MoveTypeEvolutionCondition(Type.STEEL), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.RHYDON]: [ new SpeciesEvolution(Species.RHYPERIOR, 1, EvolutionItem.PROTECTOR, null, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1548,9 +1748,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.KINGDRA, 1, EvolutionItem.DRAGON_SCALE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SCYTHER]: [ - new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition( - p => p.moveset.filter(m => m?.getMove().type === Type.STEEL).length > 0), - SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new MoveTypeEvolutionCondition(Type.STEEL), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(Species.KLEAVOR, 1, EvolutionItem.BLACK_AUGURITE, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.ELECTABUZZ]: [ @@ -1572,8 +1770,8 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.DUSKNOIR, 1, EvolutionItem.REAPER_CLOTH, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.CLAMPERL]: [ - new SpeciesEvolution(Species.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE /* Deep Sea Tooth */), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesEvolution(Species.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE /* Deep Sea Scale */), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new GenderEvolutionCondition(Gender.MALE /* Deep Sea Tooth */), SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesEvolution(Species.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new GenderEvolutionCondition(Gender.FEMALE /* Deep Sea Scale */), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.BOLDORE]: [ new SpeciesEvolution(Species.GIGALITH, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1582,10 +1780,10 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.CONKELDURR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.KARRABLAST]: [ - new SpeciesEvolution(Species.ESCAVALIER, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.SHELMET].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.ESCAVALIER, 1, EvolutionItem.LINKING_CORD, new CaughtEvolutionCondition(Species.SHELMET), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SHELMET]: [ - new SpeciesEvolution(Species.ACCELGOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.KARRABLAST].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.ACCELGOR, 1, EvolutionItem.LINKING_CORD, new CaughtEvolutionCondition(Species.KARRABLAST), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.SPRITZEE]: [ new SpeciesEvolution(Species.AROMATISSE, 1, EvolutionItem.SACHET, null, SpeciesWildEvolutionDelay.VERY_LONG) @@ -1603,72 +1801,66 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.ALOLA_GOLEM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.PRIMEAPE]: [ - new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.RAGE_FIST).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new MoveEvolutionCondition(Moves.RAGE_FIST), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.GOLBAT]: [ - new SpeciesEvolution(Species.CROBAT, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(Species.CROBAT, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG) ], [Species.CHANSEY]: [ - new SpeciesEvolution(Species.BLISSEY, 1, null, new SpeciesFriendshipEvolutionCondition(200), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.BLISSEY, 1, null, new FriendshipEvolutionCondition(200), SpeciesWildEvolutionDelay.LONG) ], [Species.PICHU]: [ - new SpeciesFormEvolution(Species.PIKACHU, "spiky", "partner", 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT), - new SpeciesFormEvolution(Species.PIKACHU, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT), + new SpeciesFormEvolution(Species.PIKACHU, "spiky", "partner", 1, null, new FriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT), + new SpeciesFormEvolution(Species.PIKACHU, "", "", 1, null, new FriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT), ], [Species.CLEFFA]: [ - new SpeciesEvolution(Species.CLEFAIRY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT) + new SpeciesEvolution(Species.CLEFAIRY, 1, null, new FriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT) ], [Species.IGGLYBUFF]: [ - new SpeciesEvolution(Species.JIGGLYPUFF, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT) + new SpeciesEvolution(Species.JIGGLYPUFF, 1, null, new FriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT) ], [Species.TOGEPI]: [ - new SpeciesEvolution(Species.TOGETIC, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT) + new SpeciesEvolution(Species.TOGETIC, 1, null, new FriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT) ], [Species.AZURILL]: [ - new SpeciesEvolution(Species.MARILL, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT) + new SpeciesEvolution(Species.MARILL, 1, null, new FriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT) ], [Species.BUDEW]: [ - new SpeciesEvolution(Species.ROSELIA, 1, null, new SpeciesFriendshipEvolutionCondition(70, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.SHORT) + new SpeciesEvolution(Species.ROSELIA, 1, null, new FriendshipTimeOfDayEvolutionCondition(70, "day"), SpeciesWildEvolutionDelay.SHORT) ], [Species.BUNEARY]: [ - new SpeciesEvolution(Species.LOPUNNY, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.LOPUNNY, 1, null, new FriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.CHINGLING]: [ - new SpeciesEvolution(Species.CHIMECHO, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.CHIMECHO, 1, null, new FriendshipTimeOfDayEvolutionCondition(90, "night"), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.HAPPINY]: [ - new SpeciesEvolution(Species.CHANSEY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT) + new SpeciesEvolution(Species.CHANSEY, 1, null, new FriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT) ], [Species.MUNCHLAX]: [ - new SpeciesEvolution(Species.SNORLAX, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.SNORLAX, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) ], [Species.RIOLU]: [ - new SpeciesEvolution(Species.LUCARIO, 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.LUCARIO, 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "day"), SpeciesWildEvolutionDelay.LONG) ], [Species.WOOBAT]: [ - new SpeciesEvolution(Species.SWOOBAT, 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.SWOOBAT, 1, null, new FriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.SWADLOON]: [ - new SpeciesEvolution(Species.LEAVANNY, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.LEAVANNY, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) ], [Species.TYPE_NULL]: [ - new SpeciesEvolution(Species.SILVALLY, 1, null, new SpeciesFriendshipEvolutionCondition(100), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.SILVALLY, 1, null, new FriendshipEvolutionCondition(100), SpeciesWildEvolutionDelay.LONG) ], [Species.ALOLA_MEOWTH]: [ - new SpeciesEvolution(Species.ALOLA_PERSIAN, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) + new SpeciesEvolution(Species.ALOLA_PERSIAN, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG) ], [Species.SNOM]: [ - new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.FROSMOTH, 1, null, new FriendshipTimeOfDayEvolutionCondition(90, "night"), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.GIMMIGHOUL]: [ - new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter - + p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - + globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier - || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter - + p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - + globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier - || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new TreasureEvolutionCondition(), SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new TreasureEvolutionCondition(), SpeciesWildEvolutionDelay.VERY_LONG) ] }; @@ -1691,3 +1883,19 @@ export function initPokemonPrevolutions(): void { } }); } + + +// TODO: This may cause funny business for double starters such as Pichu/Pikachu +export const pokemonStarters: PokemonPrevolutions = {}; + +export function initPokemonStarters(): void { + const starterKeys = Object.keys(pokemonPrevolutions); + starterKeys.forEach(pk => { + const prevolution = pokemonPrevolutions[pk]; + if (speciesStarterCosts.hasOwnProperty(prevolution)) { + pokemonStarters[pk] = prevolution; + } else { + pokemonStarters[pk] = pokemonPrevolutions[prevolution]; + } + }); +} diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 3a58ff4a99d..4c68de5abc5 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -18,7 +18,7 @@ import { MoveFlags, StatusCategoryOnAllyAttr } from "#app/data/move"; -import { SpeciesFormChangeManualTrigger } from "#app/data/pokemon-forms"; +import { SpeciesFormChangeAbilityTrigger } from "#app/data/pokemon-forms"; import { getStatusEffectHealText } from "#app/data/status-effect"; import { TerrainType } from "#app/data/terrain"; import { Type } from "#enums/type"; @@ -2149,7 +2149,7 @@ export class FormBlockDamageTag extends BattlerTag { super.onAdd(pokemon); if (pokemon.formIndex !== 0) { - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger); + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger); } } @@ -2161,7 +2161,7 @@ export class FormBlockDamageTag extends BattlerTag { onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger); + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger); } } /** Provides the additional weather-based effects of the Ice Face ability */ @@ -2361,12 +2361,12 @@ export class GulpMissileTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger); + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger); } onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger); + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger); } } diff --git a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts index d0a44504763..ca6b384cfbb 100644 --- a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts @@ -16,7 +16,7 @@ import { Nature } from "#enums/nature"; import { Type } from "#enums/type"; import { BerryType } from "#enums/berry-type"; import { Stat } from "#enums/stat"; -import { SpeciesFormChangeManualTrigger } from "#app/data/pokemon-forms"; +import { SpeciesFormChangeAbilityTrigger } from "#app/data/pokemon-forms"; import { applyPostBattleInitAbAttrs, PostBattleInitAbAttr } from "#app/data/ability"; import { showEncounterDialogue, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { MysteryEncounterMode } from "#enums/mystery-encounter-mode"; @@ -198,7 +198,7 @@ function endTrainerBattleAndShowDialogue(): Promise { // Only trigger form change when Eiscue is in Noice form // Hardcoded Eiscue for now in case it is fused with another pokemon if (pokemon.species.speciesId === Species.EISCUE && pokemon.hasAbility(Abilities.ICE_FACE) && pokemon.formIndex === 1) { - globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger); + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger); } pokemon.resetBattleData(); diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index b1c3db47768..035cd6f1369 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -212,6 +212,8 @@ export class SpeciesFormChangeCondition { } export abstract class SpeciesFormChangeTrigger { + public description: string = ""; + canChange(pokemon: Pokemon): boolean { return true; } @@ -222,16 +224,19 @@ export abstract class SpeciesFormChangeTrigger { } export class SpeciesFormChangeManualTrigger extends SpeciesFormChangeTrigger { - canChange(pokemon: Pokemon): boolean { - return true; - } +} + +export class SpeciesFormChangeAbilityTrigger extends SpeciesFormChangeTrigger { + public description: string = i18next.t("pokemonEvolutions:Forms.ability"); } export class SpeciesFormChangeCompoundTrigger { + public description: string = ""; public triggers: SpeciesFormChangeTrigger[]; constructor(...triggers: SpeciesFormChangeTrigger[]) { this.triggers = triggers; + this.description = this.triggers.filter(trigger => trigger?.description?.length > 0).map(trigger => trigger.description).join(", "); } canChange(pokemon: Pokemon): boolean { @@ -257,6 +262,9 @@ export class SpeciesFormChangeItemTrigger extends SpeciesFormChangeTrigger { super(); this.item = item; this.active = active; + this.description = this.active ? + i18next.t("pokemonEvolutions:Forms.item", { item: i18next.t(`modifierType:FormChangeItem.${FormChangeItem[this.item]}`) }) : + i18next.t("pokemonEvolutions:Forms.deactivateItem", { item: i18next.t(`modifierType:FormChangeItem.${FormChangeItem[this.item]}`) }); } canChange(pokemon: Pokemon): boolean { @@ -270,6 +278,7 @@ export class SpeciesFormChangeTimeOfDayTrigger extends SpeciesFormChangeTrigger constructor(...timesOfDay: TimeOfDay[]) { super(); this.timesOfDay = timesOfDay; + this.description = i18next.t("pokemonEvolutions:Forms.timeOfDay"); } canChange(pokemon: Pokemon): boolean { @@ -283,6 +292,7 @@ export class SpeciesFormChangeActiveTrigger extends SpeciesFormChangeTrigger { constructor(active: boolean = false) { super(); this.active = active; + this.description = this.active ? i18next.t("pokemonEvolutions:Forms.enter") : i18next.t("pokemonEvolutions:Forms.leave"); } canChange(pokemon: Pokemon): boolean { @@ -301,6 +311,7 @@ export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigg } this.statusEffects = statusEffects; this.invert = invert; + this.description = i18next.t("pokemonEvolutions:Forms.statusEffect"); } canChange(pokemon: Pokemon): boolean { @@ -316,6 +327,8 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge super(); this.move = move; this.known = known; + const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string; + this.description = i18next.t("pokemonEvolutions:Forms.moveLearned", { move: i18next.t(`move:${moveKey}.name`) }); } canChange(pokemon: Pokemon): boolean { @@ -335,6 +348,8 @@ export abstract class SpeciesFormChangeMoveTrigger extends SpeciesFormChangeTrig } export class SpeciesFormChangePreMoveTrigger extends SpeciesFormChangeMoveTrigger { + description = i18next.t("pokemonEvolutions:Forms.preMove"); + canChange(pokemon: Pokemon): boolean { const command = globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]; return !!command?.move && this.movePredicate(command.move.move) === this.used; @@ -342,6 +357,8 @@ export class SpeciesFormChangePreMoveTrigger extends SpeciesFormChangeMoveTrigge } export class SpeciesFormChangePostMoveTrigger extends SpeciesFormChangeMoveTrigger { + description = i18next.t("pokemonEvolutions:Forms.postMove"); + canChange(pokemon: Pokemon): boolean { return pokemon.summonData && !!pokemon.getLastXMoves(1).filter(m => this.movePredicate(m.move)).length === this.used; } @@ -367,6 +384,7 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger { constructor(formKey: string) { super(); this.formKey = formKey; + this.description = ""; } canChange(pokemon: Pokemon): boolean { @@ -386,6 +404,7 @@ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger { constructor(teraType: Type) { super(); this.teraType = teraType; + this.description = i18next.t("pokemonEvolutions:Forms.tera", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) }); } /** @@ -404,6 +423,8 @@ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger { * @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); } @@ -424,6 +445,7 @@ export class SpeciesFormChangeWeatherTrigger extends SpeciesFormChangeTrigger { super(); this.ability = ability; this.weathers = weathers; + this.description = i18next.t("pokemonEvolutions:Forms.weather"); } /** @@ -457,6 +479,7 @@ export class SpeciesFormChangeRevertWeatherFormTrigger extends SpeciesFormChange super(); this.ability = ability; this.weathers = weathers; + this.description = i18next.t("pokemonEvolutions:Forms.weatherRevert"); } /** @@ -751,8 +774,8 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.ARCEUS, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.PIXIE_PLATE)) ], [Species.DARMANITAN]: [ - new SpeciesFormChange(Species.DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.DARMANITAN, "", "zen", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.DARMANITAN, "zen", "", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.GARBODOR]: [ new SpeciesFormChange(Species.GARBODOR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) @@ -785,12 +808,12 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.GENESECT, "", "douse", new SpeciesFormChangeItemTrigger(FormChangeItem.DOUSE_DRIVE)) ], [Species.GRENINJA]: [ - new SpeciesFormChange(Species.GRENINJA, "battle-bond", "ash", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.GRENINJA, "ash", "battle-bond", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.GRENINJA, "battle-bond", "ash", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.GRENINJA, "ash", "battle-bond", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.PALAFIN] : [ - new SpeciesFormChange(Species.PALAFIN, "zero", "hero", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.PALAFIN, "hero", "zero", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.PALAFIN, "zero", "hero", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.PALAFIN, "hero", "zero", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.AEGISLASH]: [ new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangePreMoveTrigger(Moves.KINGS_SHIELD), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))), @@ -802,10 +825,10 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.XERNEAS, "active", "neutral", new SpeciesFormChangeActiveTrigger(false), true) ], [Species.ZYGARDE]: [ - new SpeciesFormChange(Species.ZYGARDE, "50-pc", "complete", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.ZYGARDE, "complete", "50-pc", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.ZYGARDE, "10-pc", "10-complete", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.ZYGARDE, "10-complete", "10-pc", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.ZYGARDE, "50-pc", "complete", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.ZYGARDE, "complete", "50-pc", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.ZYGARDE, "10-pc", "10-complete", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.ZYGARDE, "10-complete", "10-pc", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.DIANCIE]: [ new SpeciesFormChange(Species.DIANCIE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE)) @@ -814,8 +837,8 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.HOOPA, "", "unbound", new SpeciesFormChangeItemTrigger(FormChangeItem.PRISON_BOTTLE)) ], [Species.WISHIWASHI]: [ - new SpeciesFormChange(Species.WISHIWASHI, "", "school", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.WISHIWASHI, "school", "", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.WISHIWASHI, "", "school", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.WISHIWASHI, "school", "", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.SILVALLY]: [ new SpeciesFormChange(Species.SILVALLY, "normal", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIGHTING_MEMORY)), @@ -837,24 +860,24 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.SILVALLY, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.FAIRY_MEMORY)) ], [Species.MINIOR]: [ - new SpeciesFormChange(Species.MINIOR, "red-meteor", "red", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "red", "red-meteor", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "orange-meteor", "orange", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "orange", "orange-meteor", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "yellow-meteor", "yellow", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "yellow", "yellow-meteor", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "green-meteor", "green", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "green", "green-meteor", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "blue-meteor", "blue", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "blue", "blue-meteor", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "indigo-meteor", "indigo", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "indigo", "indigo-meteor", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "violet-meteor", "violet", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MINIOR, "violet", "violet-meteor", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.MINIOR, "red-meteor", "red", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "red", "red-meteor", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "orange-meteor", "orange", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "orange", "orange-meteor", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "yellow-meteor", "yellow", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "yellow", "yellow-meteor", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "green-meteor", "green", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "green", "green-meteor", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "blue-meteor", "blue", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "blue", "blue-meteor", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "indigo-meteor", "indigo", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "indigo", "indigo-meteor", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "violet-meteor", "violet", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MINIOR, "violet", "violet-meteor", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.MIMIKYU]: [ - new SpeciesFormChange(Species.MIMIKYU, "disguised", "busted", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MIMIKYU, "busted", "disguised", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.MIMIKYU, "disguised", "busted", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MIMIKYU, "busted", "disguised", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.NECROZMA]: [ new SpeciesFormChange(Species.NECROZMA, "", "dawn-wings", new SpeciesFormChangeItemTrigger(FormChangeItem.N_LUNARIZER), false, getSpeciesDependentFormChangeCondition(Species.LUNALA)), @@ -896,10 +919,10 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.SANDACONDA, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) ], [Species.CRAMORANT]: [ - new SpeciesFormChange(Species.CRAMORANT, "", "gulping", new SpeciesFormChangeManualTrigger, true, new SpeciesFormChangeCondition(p => p.getHpRatio() >= .5)), - new SpeciesFormChange(Species.CRAMORANT, "", "gorging", new SpeciesFormChangeManualTrigger, true, new SpeciesFormChangeCondition(p => p.getHpRatio() < .5)), - new SpeciesFormChange(Species.CRAMORANT, "gulping", "", new SpeciesFormChangeManualTrigger, true), - new SpeciesFormChange(Species.CRAMORANT, "gorging", "", new SpeciesFormChangeManualTrigger, true), + new SpeciesFormChange(Species.CRAMORANT, "", "gulping", new SpeciesFormChangeAbilityTrigger, true, new SpeciesFormChangeCondition(p => p.getHpRatio() >= .5)), + new SpeciesFormChange(Species.CRAMORANT, "", "gorging", new SpeciesFormChangeAbilityTrigger, true, new SpeciesFormChangeCondition(p => p.getHpRatio() < .5)), + new SpeciesFormChange(Species.CRAMORANT, "gulping", "", new SpeciesFormChangeAbilityTrigger, true), + new SpeciesFormChange(Species.CRAMORANT, "gorging", "", new SpeciesFormChangeAbilityTrigger, true), new SpeciesFormChange(Species.CRAMORANT, "gulping", "", new SpeciesFormChangeActiveTrigger(false), true), new SpeciesFormChange(Species.CRAMORANT, "gorging", "", new SpeciesFormChangeActiveTrigger(false), true) ], @@ -930,12 +953,12 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.ALCREMIE, "rainbow-swirl", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) ], [Species.EISCUE]: [ - new SpeciesFormChange(Species.EISCUE, "", "no-ice", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.EISCUE, "no-ice", "", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.EISCUE, "", "no-ice", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.EISCUE, "no-ice", "", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.MORPEKO]: [ - new SpeciesFormChange(Species.MORPEKO, "full-belly", "hangry", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.MORPEKO, "hangry", "full-belly", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.MORPEKO, "full-belly", "hangry", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.MORPEKO, "hangry", "full-belly", new SpeciesFormChangeAbilityTrigger(), true) ], [Species.COPPERAJAH]: [ new SpeciesFormChange(Species.COPPERAJAH, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS)) @@ -978,13 +1001,13 @@ export const pokemonFormChanges: PokemonFormChanges = { new SpeciesFormChange(Species.OGERPON, "cornerstone-mask-tera", "cornerstone-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.ROCK)) ], [Species.TERAPAGOS]: [ - new SpeciesFormChange(Species.TERAPAGOS, "", "terastal", new SpeciesFormChangeManualTrigger(), true), + 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)) ], [Species.GALAR_DARMANITAN]: [ - new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true), - new SpeciesFormChange(Species.GALAR_DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true) + new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeAbilityTrigger(), true), + new SpeciesFormChange(Species.GALAR_DARMANITAN, "zen", "", new SpeciesFormChangeAbilityTrigger(), true) ], }; @@ -1002,3 +1025,4 @@ export function initPokemonForms() { formChanges.push(...newFormChanges); }); } + diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index 845739dfcac..cc798bc8585 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -204,6 +204,7 @@ export async function initI18n(): Promise { "nature", "pokeball", "pokemon", + "pokemonEvolutions", "pokemonForm", "pokemonInfo", "pokemonInfoContainer",