From 29b55f925efb884f476c63431e79a334cecd122d Mon Sep 17 00:00:00 2001 From: innerthunder Date: Thu, 3 Oct 2024 18:42:06 -0700 Subject: [PATCH 1/3] Implement Electrify --- src/data/battler-tags.ts | 16 ++++++++ src/data/move.ts | 2 +- src/enums/battler-tag-type.ts | 1 + src/field/pokemon.ts | 3 ++ src/test/moves/electrify.test.ts | 69 ++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/test/moves/electrify.test.ts diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 42775775ac44..7297f6ac2afd 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2310,6 +2310,20 @@ export class TarShotTag extends BattlerTag { } } +/** + * Battler Tag implementing + */ +export class ElectrifiedTag extends BattlerTag { + constructor() { + super(BattlerTagType.ELECTRIFIED, BattlerTagLapseType.TURN_END, 1, Moves.ELECTRIFY); + } + + override onAdd(pokemon: Pokemon): void { + // "{pokemonNameWithAffix}'s moves have been electrified!" + pokemon.scene.queueMessage(i18next.t("battlerTags:electrifiedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } +} + /** * Battler Tag that keeps track of how many times the user has Autotomized * Each count of Autotomization reduces the weight by 100kg @@ -2811,6 +2825,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source return new GulpMissileTag(tagType, sourceMove); case BattlerTagType.TAR_SHOT: return new TarShotTag(); + case BattlerTagType.ELECTRIFIED: + return new ElectrifiedTag(); case BattlerTagType.THROAT_CHOPPED: return new ThroatChoppedTag(); case BattlerTagType.GORILLA_TACTICS: diff --git a/src/data/move.ts b/src/data/move.ts index 8c9e8b0fb991..63553fecc10d 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -8537,7 +8537,7 @@ export function initMoves() { .attr(TerrainChangeAttr, TerrainType.MISTY) .target(MoveTarget.BOTH_SIDES), new StatusMove(Moves.ELECTRIFY, Type.ELECTRIC, -1, 20, -1, 0, 6) - .unimplemented(), + .attr(AddBattlerTagAttr, BattlerTagType.ELECTRIFIED, false, true), new AttackMove(Moves.PLAY_ROUGH, Type.FAIRY, MoveCategory.PHYSICAL, 90, 90, 10, 10, 0, 6) .attr(StatStageChangeAttr, [ Stat.ATK ], -1), new AttackMove(Moves.FAIRY_WIND, Type.FAIRY, MoveCategory.SPECIAL, 40, 100, 30, -1, 0, 6) diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 209d36316f9f..9142a21199dc 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -86,4 +86,5 @@ export enum BattlerTagType { TAUNT = "TAUNT", IMPRISON = "IMPRISON", SYRUP_BOMB = "SYRUP_BOMB", + ELECTRIFIED = "ELECTRIFIED", } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index de18dfb74eb0..36b34194ef20 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1526,6 +1526,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder); this.scene.arena.applyTags(ArenaTagType.PLASMA_FISTS, moveTypeHolder); + if (this.getTag(BattlerTagType.ELECTRIFIED)) { + moveTypeHolder.value = Type.ELECTRIC; + } return moveTypeHolder.value as Type; } diff --git a/src/test/moves/electrify.test.ts b/src/test/moves/electrify.test.ts new file mode 100644 index 000000000000..e5b62d9bd896 --- /dev/null +++ b/src/test/moves/electrify.test.ts @@ -0,0 +1,69 @@ +import { BattlerIndex } from "#app/battle"; +import { Type } from "#app/data/type"; +import { Abilities } from "#enums/abilities"; +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, it, expect, vi } from "vitest"; + +describe("Moves - Electrify", () => { + 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.ELECTRIFY) + .battleType("single") + .startingLevel(100) + .enemySpecies(Species.SNORLAX) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.TACKLE) + .enemyLevel(100); + }); + + it("should convert attacks to Electric type", async () => { + await game.classicMode.startBattle([Species.EXCADRILL]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + vi.spyOn(enemyPokemon, "getMoveType"); + + game.move.select(Moves.ELECTRIFY); + + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); + expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); + }); + + it("should override type changes from abilities", async () => { + game.override.enemyAbility(Abilities.PIXILATE); + + await game.classicMode.startBattle([Species.EXCADRILL]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getPlayerPokemon()!; + vi.spyOn(enemyPokemon, "getMoveType"); + + game.move.select(Moves.ELECTRIFY); + + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); + expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp()); + }); +}); From a6faf1295cc3569c94ca8861de5d67958c57388d Mon Sep 17 00:00:00 2001 From: innerthunder Date: Thu, 3 Oct 2024 23:51:04 -0700 Subject: [PATCH 2/3] ESLint --- src/test/moves/electrify.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/moves/electrify.test.ts b/src/test/moves/electrify.test.ts index e5b62d9bd896..5d15a825688a 100644 --- a/src/test/moves/electrify.test.ts +++ b/src/test/moves/electrify.test.ts @@ -34,7 +34,7 @@ describe("Moves - Electrify", () => { }); it("should convert attacks to Electric type", async () => { - await game.classicMode.startBattle([Species.EXCADRILL]); + await game.classicMode.startBattle([ Species.EXCADRILL ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; @@ -42,7 +42,7 @@ describe("Moves - Electrify", () => { game.move.select(Moves.ELECTRIFY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("BerryPhase", false); expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); @@ -52,7 +52,7 @@ describe("Moves - Electrify", () => { it("should override type changes from abilities", async () => { game.override.enemyAbility(Abilities.PIXILATE); - await game.classicMode.startBattle([Species.EXCADRILL]); + await game.classicMode.startBattle([ Species.EXCADRILL ]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getPlayerPokemon()!; @@ -60,7 +60,7 @@ describe("Moves - Electrify", () => { game.move.select(Moves.ELECTRIFY); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("BerryPhase", false); expect(enemyPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); From 25fc0b8ea5f2904ff0403be3ad8c1fb9c0bc93f1 Mon Sep 17 00:00:00 2001 From: innerthunder Date: Fri, 4 Oct 2024 13:21:19 -0700 Subject: [PATCH 3/3] Fix docs --- src/data/battler-tags.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index a01eb3092006..a54a8c5f519a 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2311,7 +2311,8 @@ export class TarShotTag extends BattlerTag { } /** - * Battler Tag implementing + * Battler Tag implementing the type-changing effect of {@link https://bulbapedia.bulbagarden.net/wiki/Electrify_(move) | Electrify}. + * While this tag is in effect, the afflicted Pokemon's moves are changed to Electric type. */ export class ElectrifiedTag extends BattlerTag { constructor() {