diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index b677dd2bd11..f49863639f0 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -7425,7 +7425,12 @@ export function initAbilities() { .uncopiable() .attr(NoTransformAbilityAbAttr), new Ability(Abilities.GOOD_AS_GOLD, 9) - .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.category === MoveCategory.STATUS && ![ MoveTarget.ENEMY_SIDE, MoveTarget.BOTH_SIDES, MoveTarget.USER_SIDE ].includes(move.moveTarget)) + .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => + pokemon !== attacker + && move.category === MoveCategory.STATUS + && ![ MoveTarget.ENEMY_SIDE, MoveTarget.BOTH_SIDES, MoveTarget.USER_SIDE ].includes(move.moveTarget) + ) + .edgeCase() // Heal Bell should not cure the status of a Pokemon with Good As Gold .ignorable(), new Ability(Abilities.VESSEL_OF_RUIN, 9) .attr(FieldMultiplyStatAbAttr, Stat.SPATK, 0.75) diff --git a/test/abilities/good_as_gold.test.ts b/test/abilities/good_as_gold.test.ts index 09bdaafb11f..9b1d582f64c 100644 --- a/test/abilities/good_as_gold.test.ts +++ b/test/abilities/good_as_gold.test.ts @@ -1,6 +1,6 @@ import { BattlerIndex } from "#app/battle"; -import { allAbilities } from "#app/data/data-lists"; import { ArenaTagSide } from "#app/data/arena-tag"; +import { allAbilities } from "#app/data/data-lists"; import { ArenaTagType } from "#app/enums/arena-tag-type"; import { BattlerTagType } from "#app/enums/battler-tag-type"; import { Stat } from "#app/enums/stat"; @@ -107,35 +107,33 @@ describe("Abilities - Good As Gold", () => { expect(game.scene.getPlayerField()[1].getTag(BattlerTagType.HELPING_HAND)).toBeUndefined(); }); - it("should block the ally's heal bell, but only if the good as gold user is on the field", async () => { - game.override.battleStyle("double"); - game.override.moveset([Moves.HEAL_BELL, Moves.SPLASH]); - game.override.statusEffect(StatusEffect.BURN); - await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS, Species.ABRA]); - const [good_as_gold, ball_fetch] = game.scene.getPlayerField(); - - // Force second pokemon to have ball fetch to isolate to a single mon. - vi.spyOn(ball_fetch, "getAbility").mockReturnValue(allAbilities[Abilities.BALL_FETCH]); + // TODO: re-enable when heal bell is fixed + it.todo("should block the ally's heal bell, but only if the good as gold user is on the field", async () => { + game.override.battleStyle("double").statusEffect(StatusEffect.BURN); + await game.classicMode.startBattle([Species.MILOTIC, Species.FEEBAS, Species.ABRA]); + const [milotic, feebas, abra] = game.scene.getPlayerParty(); + game.field.mockAbility(milotic, Abilities.GOOD_AS_GOLD); + game.field.mockAbility(feebas, Abilities.BALL_FETCH); + game.field.mockAbility(abra, Abilities.BALL_FETCH); // turn 1 - game.move.select(Moves.SPLASH, 0); - game.move.select(Moves.HEAL_BELL, 1); + game.move.use(Moves.SPLASH, 0); + game.move.use(Moves.HEAL_BELL, 1); await game.toNextTurn(); - expect(good_as_gold.status?.effect).toBe(StatusEffect.BURN); + expect(milotic.status?.effect).toBe(StatusEffect.BURN); game.doSwitchPokemon(2); - game.move.select(Moves.HEAL_BELL, 0); + game.move.use(Moves.HEAL_BELL, 1); await game.toNextTurn(); - expect(good_as_gold.status?.effect).toBeUndefined(); + expect(milotic.status?.effect).toBeUndefined(); }); it("should not block field targeted effects like rain dance", async () => { game.override.battleStyle("single"); game.override.enemyMoveset([Moves.RAIN_DANCE]); - game.override.weather(WeatherType.NONE); await game.classicMode.startBattle([Species.MAGIKARP]); - game.move.select(Moves.SPLASH, 0); + game.move.use(Moves.SPLASH, 0); await game.phaseInterceptor.to("BerryPhase"); expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.RAIN); diff --git a/test/moves/alluring_voice.test.ts b/test/moves/alluring_voice.test.ts index 240e008f311..9265c5f970d 100644 --- a/test/moves/alluring_voice.test.ts +++ b/test/moves/alluring_voice.test.ts @@ -29,20 +29,18 @@ describe("Moves - Alluring Voice", () => { .disableCrits() .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.ICE_SCALES) - .enemyMoveset([Moves.HOWL]) + .enemyMoveset(Moves.HOWL) .startingLevel(10) .enemyLevel(10) - .starterSpecies(Species.FEEBAS) - .ability(Abilities.BALL_FETCH) - .moveset([Moves.ALLURING_VOICE]); + .ability(Abilities.BALL_FETCH); }); it("should confuse the opponent if their stat stages were raised", async () => { - await game.classicMode.startBattle(); + await game.classicMode.startBattle([Species.FEEBAS]); const enemy = game.scene.getEnemyPokemon()!; - game.move.select(Moves.ALLURING_VOICE); + game.move.use(Moves.ALLURING_VOICE); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.phaseInterceptor.to(BerryPhase); diff --git a/test/moves/chloroblast.test.ts b/test/moves/chloroblast.test.ts index 175227bbd5e..b2130da83eb 100644 --- a/test/moves/chloroblast.test.ts +++ b/test/moves/chloroblast.test.ts @@ -1,3 +1,4 @@ +import { MoveResult } from "#app/field/pokemon"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; @@ -22,21 +23,23 @@ describe("Moves - Chloroblast", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([Moves.CHLOROBLAST]) .ability(Abilities.BALL_FETCH) .battleStyle("single") .disableCrits() .enemySpecies(Species.MAGIKARP) - .enemyAbility(Abilities.BALL_FETCH) - .enemyMoveset(Moves.PROTECT); + .enemyAbility(Abilities.BALL_FETCH); }); it("should not deal recoil damage if the opponent uses protect", async () => { await game.classicMode.startBattle([Species.FEEBAS]); - game.move.select(Moves.CHLOROBLAST); - await game.phaseInterceptor.to("BerryPhase"); + game.move.use(Moves.CHLOROBLAST); + await game.move.forceEnemyMove(Moves.PROTECT); + await game.toEndOfTurn(); - expect(game.scene.getPlayerPokemon()!.isFullHp()).toBe(true); + const player = game.field.getPlayerPokemon(); + + expect(player.isFullHp()).toBe(true); + expect(player.getLastXMoves()[0]).toMatchObject({ result: MoveResult.MISS, move: Moves.CHLOROBLAST }); }); }); diff --git a/test/moves/powder.test.ts b/test/moves/powder.test.ts index 457beb60f91..c6114db3ff1 100644 --- a/test/moves/powder.test.ts +++ b/test/moves/powder.test.ts @@ -1,15 +1,15 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#test/testUtils/gameManager"; +import { BattlerIndex } from "#app/battle"; +import { MoveResult, PokemonMove } from "#app/field/pokemon"; +import { BerryPhase } from "#app/phases/berry-phase"; +import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; -import { Species } from "#enums/species"; -import { BerryPhase } from "#app/phases/berry-phase"; -import { MoveResult, PokemonMove } from "#app/field/pokemon"; import { PokemonType } from "#enums/pokemon-type"; -import { MoveEffectPhase } from "#app/phases/move-effect-phase"; +import { Species } from "#enums/species"; import { StatusEffect } from "#enums/status-effect"; -import { BattlerIndex } from "#app/battle"; +import GameManager from "#test/testUtils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Powder", () => { let phaserGame: Phaser.Game; @@ -161,7 +161,6 @@ describe("Moves - Powder", () => { game.move.select(Moves.ROAR, 0, BattlerIndex.ENEMY_2); game.move.select(Moves.SPLASH, 1); await game.toNextTurn(); - await game.toNextTurn(); // Requires game.toNextTurn() twice due to double battle // Turn 2: Enemy should activate Powder twice: From using Ember, and from copying Fiery Dance via Dancer playerPokemon.hp = playerPokemon.getMaxHp();