From 4f0af296b1efd3c8d34d3a84d17ae84edd2768d2 Mon Sep 17 00:00:00 2001 From: frutescens Date: Wed, 25 Sep 2024 18:46:44 -0700 Subject: [PATCH] Syrup Bomb + Tests --- src/data/battler-tags.ts | 25 ++++++++++ src/data/move.ts | 5 +- src/enums/battler-tag-type.ts | 1 + src/locales/en/battler-tags.json | 3 +- src/test/moves/syrup_bomb.test.ts | 77 +++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 src/test/moves/syrup_bomb.test.ts diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 579d068e882..e3ba1f21270 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2589,6 +2589,29 @@ export class ImprisonTag extends MoveRestrictionBattlerTag { } } +export class SyrupBombTag extends BattlerTag { + constructor() { + super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB); + } + + override onAdd(pokemon: Pokemon) { + if (Utils.isNullOrUndefined(pokemon.getTag(BattlerTagType.SYRUP_BOMB))) { + super.onAdd(pokemon); + pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } + } + + override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean { + if (!pokemon.isActive(true)) { + return false; + } + pokemon.scene.unshiftPhase(new StatStageChangePhase( + pokemon.scene, pokemon.getBattlerIndex(), true, + [Stat.SPD], -1, true, false, true + )); + return --this.turnCount > 0; + } +} /** * Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID. @@ -2763,6 +2786,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source return new TauntTag(); case BattlerTagType.IMPRISON: return new ImprisonTag(sourceId); + case BattlerTagType.SYRUP_BOMB: + return new SyrupBombTag(); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/data/move.ts b/src/data/move.ts index 71d97e4fb5c..ffa8d39792f 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -9584,9 +9584,8 @@ export function initMoves() { .target(MoveTarget.ALL_NEAR_ENEMIES) .triageMove(), new AttackMove(Moves.SYRUP_BOMB, Type.GRASS, MoveCategory.SPECIAL, 60, 85, 10, -1, 0, 9) - .attr(StatStageChangeAttr, [ Stat.SPD ], -1) //Temporary - .ballBombMove() - .partial(), + .attr(AddBattlerTagAttr, BattlerTagType.SYRUP_BOMB, false, false, 3) + .ballBombMove(), new AttackMove(Moves.IVY_CUDGEL, Type.GRASS, MoveCategory.PHYSICAL, 100, 100, 10, -1, 0, 9) .attr(IvyCudgelTypeAttr) .attr(HighCritAttr) diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 9ed3b629746..6c6c08b4362 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -85,4 +85,5 @@ export enum BattlerTagType { TORMENT = "TORMENT", TAUNT = "TAUNT", IMPRISON = "IMPRISON", + SYRUP_BOMB = "SYRUP_BOMB" } diff --git a/src/locales/en/battler-tags.json b/src/locales/en/battler-tags.json index 520ac2a6202..f95396e443c 100644 --- a/src/locales/en/battler-tags.json +++ b/src/locales/en/battler-tags.json @@ -78,5 +78,6 @@ "tormentOnAdd": "{{pokemonNameWithAffix}} was subjected to torment!", "tauntOnAdd": "{{pokemonNameWithAffix}} fell for the taunt!", "imprisonOnAdd": "{{pokemonNameWithAffix}} sealed the opponents move(s)!", - "autotomizeOnAdd": "{{pokemonNameWithAffix}} became nimble!" + "autotomizeOnAdd": "{{pokemonNameWithAffix}} became nimble!", + "syrupBombOnAdd": "{{pokemonNameWithAffix}} got covered in sticky, candy syrup!" } diff --git a/src/test/moves/syrup_bomb.test.ts b/src/test/moves/syrup_bomb.test.ts new file mode 100644 index 00000000000..324bccc7330 --- /dev/null +++ b/src/test/moves/syrup_bomb.test.ts @@ -0,0 +1,77 @@ +import { allMoves } from "#app/data/move"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-types"; +import { Stat } from "#enums/stat"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; + +describe("Moves - SYRUP BOMB", () => { + 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 + .starterSpecies(Species.MAGIKARP) + .enemySpecies(Species.SNORLAX) + .startingLevel(30) + .enemyLevel(100) + .moveset([Moves.SYRUP_BOMB, Moves.SPLASH]) + .enemyMoveset(Moves.SPLASH); + vi.spyOn(allMoves[Moves.SYRUP_BOMB], "accuracy", "get").mockReturnValue(100); + }); + + //Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/syrup_bomb_(move) + + test("decreases the target Pokemon's speed stat once per turn for 3 turns", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const targetPokemon = game.scene.getEnemyPokemon()!; + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0); + + game.move.select(Moves.SYRUP_BOMB); + await game.toNextTurn(); + expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeDefined(); + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(-1); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeDefined(); + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(-2); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeUndefined(); + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(-3); + } + ); + + test("does not affect Pokemon with the ability Bulletproof", + async() => { + game.override.enemyAbility(Abilities.BULLETPROOF); + await game.startBattle([Species.MAGIKARP]); + + const targetPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.SYRUP_BOMB); + await game.toNextTurn(); + expect(targetPokemon.getMaxHp()).toBe(targetPokemon.hp); + expect(targetPokemon.getTag(BattlerTagType.SYRUP_BOMB)).toBeUndefined(); + expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0); + } + ); +});