From 9b1689451a50302a9dff0b090b8e0c072ccb5bd5 Mon Sep 17 00:00:00 2001 From: muscode13 Date: Mon, 4 Nov 2024 20:09:49 -0600 Subject: [PATCH] implement corrosive gas --- src/data/move.ts | 10 ++- src/test/moves/corrosive_gas.test.ts | 110 +++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 src/test/moves/corrosive_gas.test.ts diff --git a/src/data/move.ts b/src/data/move.ts index 6e350315e65..0f251c723b8 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2374,8 +2374,10 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { * @returns {boolean} True if an item was removed */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - if (!this.berriesOnly && target.isPlayer()) { // "Wild Pokemon cannot knock off Player Pokemon's held items" (See Bulbapedia) - return false; + if (move.id !== Moves.CORROSIVE_GAS) { + if (!this.berriesOnly && target.isPlayer()) { // "Wild Pokemon cannot knock off Player Pokemon's held items" (See Bulbapedia) + return false; + } } if (move.hitsSubstitute(user, target)) { @@ -2407,6 +2409,8 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { if (this.berriesOnly) { user.scene.queueMessage(i18next.t("moveTriggers:incineratedItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); + } else if (move.id === Moves.CORROSIVE_GAS) { + user.scene.queueMessage(i18next.t("moveTriggers:corrosiveGasItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); } else { user.scene.queueMessage(i18next.t("moveTriggers:knockedOffItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); } @@ -10034,7 +10038,7 @@ export function initMoves() { .makesContact(false), new StatusMove(Moves.CORROSIVE_GAS, Type.POISON, 100, 40, -1, 0, 8) .target(MoveTarget.ALL_NEAR_OTHERS) - .unimplemented(), + .attr(RemoveHeldItemAttr, false), new StatusMove(Moves.COACHING, Type.FIGHTING, -1, 10, -1, 0, 8) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF ], 1) .target(MoveTarget.NEAR_ALLY), diff --git a/src/test/moves/corrosive_gas.test.ts b/src/test/moves/corrosive_gas.test.ts new file mode 100644 index 00000000000..aa410cf6ab8 --- /dev/null +++ b/src/test/moves/corrosive_gas.test.ts @@ -0,0 +1,110 @@ +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Corrosive Gas", () => { + 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, Moves.CORROSIVE_GAS ]) + .battleType("double") + .enemySpecies(Species.MAGIKARP) + .enemyMoveset(Moves.SPLASH); + }); + + it("should remove enemy and player items", async () => { + game.override + .enemyHeldItems([ + { name: "SOUL_DEW", count: 1 }, + { name: "LUCKY_EGG", count: 1 }, + { name: "LEFTOVERS", count: 1 }, + { name: "GRIP_CLAW", count: 1 }, + { name: "MULTI_LENS", count: 1 }, + ]) + .startingHeldItems( + [ + { name: "SOUL_DEW", count: 1 }, + { name: "LUCKY_EGG", count: 1 }, + { name: "LEFTOVERS", count: 1 }, + { name: "GRIP_CLAW", count: 1 }, + { name: "MULTI_LENS", count: 1 }, + ] + ); + await game.classicMode.startBattle([ Species.STAKATAKA, Species.SALAZZLE ]); + const playerPokemon = game.scene.getPlayerField()!; + const enemyPokemon = game.scene.getEnemyField()!; + + const staka = playerPokemon[0]; + const salazzle = playerPokemon[1]; + const karp1 = enemyPokemon[0]; + const karp2 = enemyPokemon[1]; + + const stakaHeldItemCt = staka.getHeldItems().length; + const salazzleHeldItemCt = salazzle.getHeldItems().length; + const magikarpItemCt1 = karp1.getHeldItems().length; + const magikarpItemCt2 = karp2.getHeldItems().length; + + game.move.select(Moves.SPLASH); + game.move.select(Moves.CORROSIVE_GAS); + await game.phaseInterceptor.to("BerryPhase"); + + expect(salazzle.getHeldItems().length).toEqual(salazzleHeldItemCt); + expect(staka.getHeldItems().length).toBeLessThan(stakaHeldItemCt); + expect(karp1.getHeldItems().length).toBeLessThan(magikarpItemCt1); + expect(karp2.getHeldItems().length).toBeLessThan(magikarpItemCt2); + }); + + it("should not remove untransferrable items", async () => { + game.override + .enemyMoveset(Moves.CORROSIVE_GAS) + .enemyHeldItems([ + { name: "BASE_STAT_BOOSTER", count: 1 }, + { name: "TEMP_STAT_STAGE_BOOSTER", count: 1 } + ]) + .startingHeldItems( + [ + { name: "FORM_CHANGE_ITEM", count: 1 }, + { name: "BASE_STAT_BOOSTER", count: 1 }, + { name: "TEMP_STAT_STAGE_BOOSTER", count: 1 } + ] + ); + await game.classicMode.startBattle([ Species.GIRATINA, Species.AGGRON ]); + const playerPokemon = game.scene.getPlayerField()!; + const enemyPokemon = game.scene.getEnemyField()!; + + const giratina = playerPokemon[0]; + const aggron = playerPokemon[1]; + const karp1 = enemyPokemon[0]; + const karp2 = enemyPokemon[1]; + + const giratinaHeldItemCt = giratina.getHeldItems().length; + const aggronHeldItemCt = aggron.getHeldItems().length; + const magikarpItemCt1 = karp1.getHeldItems().length; + const magikarpItemCt2 = karp2.getHeldItems().length; + + game.move.select(Moves.SPLASH); + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("BerryPhase"); + + expect(giratina.getHeldItems().length).toEqual(giratinaHeldItemCt); + expect(aggron.getHeldItems().length).toEqual(aggronHeldItemCt); + expect(karp1.getHeldItems().length).toEqual(magikarpItemCt1); + expect(karp2.getHeldItems().length).toEqual(magikarpItemCt2); + }); + +});