From 76cc1344a0eb1d2d819203522c306113623c88c1 Mon Sep 17 00:00:00 2001 From: Acelynn Zhang Date: Mon, 18 Aug 2025 19:06:25 -0500 Subject: [PATCH 1/3] Fix Embody Aspect triggers --- src/data/abilities/ability.ts | 18 +++++--- test/abilities/embody-aspect.test.ts | 64 ++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 test/abilities/embody-aspect.test.ts diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 199e0af3efb..f77af3393e6 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -7824,25 +7824,33 @@ export function initAbilities() { new Ability(AbilityId.TOXIC_CHAIN, 9) .attr(PostAttackApplyStatusEffectAbAttr, false, 30, StatusEffect.TOXIC), new Ability(AbilityId.EMBODY_ASPECT_TEAL, 9) - .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPD ], 1) + .attr(PostSummonStatStageChangeAbAttr, [ Stat.SPD ], 1, true) //Activiates on switch in when tera'd + .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPD ], 1) //Activates mid round when tera'd .uncopiable() .unreplaceable() // TODO is this true? - .attr(NoTransformAbilityAbAttr), + .attr(NoTransformAbilityAbAttr) + .condition(pokemon => pokemon.isTerastallized), new Ability(AbilityId.EMBODY_ASPECT_WELLSPRING, 9) + .attr(PostSummonStatStageChangeAbAttr, [ Stat.SPDEF ], 1, true) .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPDEF ], 1) .uncopiable() .unreplaceable() - .attr(NoTransformAbilityAbAttr), + .attr(NoTransformAbilityAbAttr) + .condition(pokemon => pokemon.isTerastallized), new Ability(AbilityId.EMBODY_ASPECT_HEARTHFLAME, 9) + .attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true) .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.ATK ], 1) .uncopiable() .unreplaceable() - .attr(NoTransformAbilityAbAttr), + .attr(NoTransformAbilityAbAttr) + .condition(pokemon => pokemon.isTerastallized), new Ability(AbilityId.EMBODY_ASPECT_CORNERSTONE, 9) + .attr(PostSummonStatStageChangeAbAttr, [ Stat.SPD ], 1, true) .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.DEF ], 1) .uncopiable() .unreplaceable() - .attr(NoTransformAbilityAbAttr), + .attr(NoTransformAbilityAbAttr) + .condition(pokemon => pokemon.isTerastallized), new Ability(AbilityId.TERA_SHIFT, 9, 2) .attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1) .uncopiable() diff --git a/test/abilities/embody-aspect.test.ts b/test/abilities/embody-aspect.test.ts new file mode 100644 index 00000000000..95f1df06a82 --- /dev/null +++ b/test/abilities/embody-aspect.test.ts @@ -0,0 +1,64 @@ +import { AbilityId } from "#enums/ability-id"; +import { MoveId } from "#enums/move-id"; +import { PokemonType } from "#enums/pokemon-type"; +import { SpeciesId } from "#enums/species-id"; +import { Stat } from "#enums/stat"; +import { GameManager } from "#test/test-utils/game-manager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Ability - Embody Aspect", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + // const teraForm = 4; + const baseForm = 0; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .ability(AbilityId.EMBODY_ASPECT_TEAL) + .battleStyle("single") + .criticalHits(false) + .enemySpecies(SpeciesId.MAGIKARP) + .enemyMoveset(MoveId.SPLASH); + }); + + it("Embody Aspect should activate on switching in if user is terrestrialized", async () => { + await game.classicMode.startBattle([SpeciesId.OGERPON, SpeciesId.ABOMASNOW]); + + const Ogerpon = game.scene.getPlayerParty()[0]; + expect(Ogerpon.formIndex).toBe(baseForm); + + game.field.forceTera(Ogerpon, PokemonType.GRASS); + game.move.use(MoveId.SPLASH); + + // todo: add helper function to activiate tera related abilities + // await game.phaseInterceptor.to(QuietFormChangePhase); + // expect(Ogerpon.formIndex).toBe(teraForm); + // expect(Ogerpon.getStatStage(Stat.SPD)).toBe(1); + + await game.toNextTurn(); + + //Switch Ogerpon out + game.doSwitchPokemon(1); + await game.toNextTurn(); + + //Switch Ogerpon back in + game.doSwitchPokemon(1); + await game.toNextTurn(); + + //Ability activated + expect(Ogerpon.getStatStage(Stat.SPD)).toBe(1); + }); +}); From 2786efe57c8c888462c9f026adebe3a3375afc63 Mon Sep 17 00:00:00 2001 From: Acelynn Zhang Date: Mon, 18 Aug 2025 19:54:00 -0500 Subject: [PATCH 2/3] Use selectWithTera --- src/data/abilities/ability.ts | 4 ++-- test/abilities/embody-aspect.test.ts | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index f77af3393e6..b42b2ba07e7 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -7824,8 +7824,8 @@ export function initAbilities() { new Ability(AbilityId.TOXIC_CHAIN, 9) .attr(PostAttackApplyStatusEffectAbAttr, false, 30, StatusEffect.TOXIC), new Ability(AbilityId.EMBODY_ASPECT_TEAL, 9) - .attr(PostSummonStatStageChangeAbAttr, [ Stat.SPD ], 1, true) //Activiates on switch in when tera'd - .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPD ], 1) //Activates mid round when tera'd + .attr(PostSummonStatStageChangeAbAttr, [ Stat.SPD ], 1, true) //Activiates on switch in when Terastallized + .attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPD ], 1) //Activates mid round when Terastallized .uncopiable() .unreplaceable() // TODO is this true? .attr(NoTransformAbilityAbAttr) diff --git a/test/abilities/embody-aspect.test.ts b/test/abilities/embody-aspect.test.ts index 95f1df06a82..00fe53071fb 100644 --- a/test/abilities/embody-aspect.test.ts +++ b/test/abilities/embody-aspect.test.ts @@ -1,8 +1,8 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; -import { PokemonType } from "#enums/pokemon-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; +import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -11,7 +11,7 @@ describe("Ability - Embody Aspect", () => { let phaserGame: Phaser.Game; let game: GameManager; - // const teraForm = 4; + const teraForm = 4; const baseForm = 0; beforeAll(() => { @@ -27,6 +27,7 @@ describe("Ability - Embody Aspect", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override + .moveset([MoveId.SPLASH]) .ability(AbilityId.EMBODY_ASPECT_TEAL) .battleStyle("single") .criticalHits(false) @@ -40,15 +41,13 @@ describe("Ability - Embody Aspect", () => { const Ogerpon = game.scene.getPlayerParty()[0]; expect(Ogerpon.formIndex).toBe(baseForm); - game.field.forceTera(Ogerpon, PokemonType.GRASS); - game.move.use(MoveId.SPLASH); - - // todo: add helper function to activiate tera related abilities - // await game.phaseInterceptor.to(QuietFormChangePhase); - // expect(Ogerpon.formIndex).toBe(teraForm); - // expect(Ogerpon.getStatStage(Stat.SPD)).toBe(1); + //Also terastallizes Ogerpon + game.move.selectWithTera(MoveId.SPLASH); + await game.phaseInterceptor.to(QuietFormChangePhase); + expect(Ogerpon.formIndex).toBe(teraForm); await game.toNextTurn(); + expect(Ogerpon.getStatStage(Stat.SPD)).toBe(1); //Switch Ogerpon out game.doSwitchPokemon(1); From 580702c9c8f41bc69eafc7a7bfa8a07b47fd95d5 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 18 Aug 2025 18:48:32 -0700 Subject: [PATCH 3/3] Update test --- test/abilities/embody-aspect.test.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/abilities/embody-aspect.test.ts b/test/abilities/embody-aspect.test.ts index 00fe53071fb..43e4f9015dd 100644 --- a/test/abilities/embody-aspect.test.ts +++ b/test/abilities/embody-aspect.test.ts @@ -2,7 +2,6 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; -import { QuietFormChangePhase } from "#phases/quiet-form-change-phase"; import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -27,7 +26,7 @@ describe("Ability - Embody Aspect", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([MoveId.SPLASH]) + .moveset(MoveId.SPLASH) .ability(AbilityId.EMBODY_ASPECT_TEAL) .battleStyle("single") .criticalHits(false) @@ -38,16 +37,17 @@ describe("Ability - Embody Aspect", () => { it("Embody Aspect should activate on switching in if user is terrestrialized", async () => { await game.classicMode.startBattle([SpeciesId.OGERPON, SpeciesId.ABOMASNOW]); - const Ogerpon = game.scene.getPlayerParty()[0]; - expect(Ogerpon.formIndex).toBe(baseForm); + const ogerpon = game.field.getPlayerPokemon(); + expect(ogerpon.formIndex).toBe(baseForm); + expect(ogerpon.getStatStage(Stat.SPD)).toBe(0); //Also terastallizes Ogerpon game.move.selectWithTera(MoveId.SPLASH); - await game.phaseInterceptor.to(QuietFormChangePhase); - expect(Ogerpon.formIndex).toBe(teraForm); + await game.phaseInterceptor.to("QuietFormChangePhase"); + expect(ogerpon.formIndex).toBe(teraForm); await game.toNextTurn(); - expect(Ogerpon.getStatStage(Stat.SPD)).toBe(1); + expect(ogerpon.getStatStage(Stat.SPD)).toBe(1); //Switch Ogerpon out game.doSwitchPokemon(1); @@ -58,6 +58,6 @@ describe("Ability - Embody Aspect", () => { await game.toNextTurn(); //Ability activated - expect(Ogerpon.getStatStage(Stat.SPD)).toBe(1); + expect(ogerpon.getStatStage(Stat.SPD)).toBe(1); }); });