From 5072460f4c33dbec9a138a0bd7cebdf8ac60fdc0 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:16:41 -0600 Subject: [PATCH] [Bug] Fix endless tokens allowing attacks to deal 0 damage (#5347) --- src/data/ability.ts | 2 +- src/modifier/modifier.ts | 2 +- src/test/battle/damage_calculation.test.ts | 24 ++++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 940b5f0c7d7..95601dc2010 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -1404,7 +1404,7 @@ export class DamageBoostAbAttr extends PreAttackAbAttr { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { if (this.condition(pokemon, defender, move)) { const power = args[0] as Utils.NumberHolder; - power.value = Math.floor(power.value * this.damageMultiplier); + power.value = Utils.toDmgValue(power.value * this.damageMultiplier); return true; } diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index fe61eadaccd..3af2aa2144f 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -3390,7 +3390,7 @@ abstract class EnemyDamageMultiplierModifier extends EnemyPersistentModifier { * @returns always `true` */ override apply(multiplier: NumberHolder): boolean { - multiplier.value = Math.floor(multiplier.value * Math.pow(this.damageMultiplier, this.getStackCount())); + multiplier.value = toDmgValue(multiplier.value * Math.pow(this.damageMultiplier, this.getStackCount())); return true; } diff --git a/src/test/battle/damage_calculation.test.ts b/src/test/battle/damage_calculation.test.ts index e6aca828156..22d072f313c 100644 --- a/src/test/battle/damage_calculation.test.ts +++ b/src/test/battle/damage_calculation.test.ts @@ -1,4 +1,6 @@ import { allMoves } from "#app/data/move"; +import type { EnemyPersistentModifier } from "#app/modifier/modifier"; +import { modifierTypes } from "#app/modifier/modifier-type"; import { Abilities } from "#enums/abilities"; import { ArenaTagType } from "#enums/arena-tag-type"; import { Moves } from "#enums/moves"; @@ -65,6 +67,28 @@ describe("Battle Mechanics - Damage Calculation", () => { expect(aggron.hp).toBe(aggron.getMaxHp() - 1); }); + it("Attacks deal 1 damage at minimum even with many tokens", async () => { + game.override + .startingLevel(1) + .enemySpecies(Species.AGGRON) + .enemyAbility(Abilities.STURDY) + .enemyLevel(10000); + + await game.classicMode.startBattle([ Species.SHUCKLE ]); + + const dmg_redux_modifier = modifierTypes.ENEMY_DAMAGE_REDUCTION().newModifier() as EnemyPersistentModifier; + dmg_redux_modifier.stackCount = 1000; + await game.scene.addEnemyModifier(modifierTypes.ENEMY_DAMAGE_REDUCTION().newModifier() as EnemyPersistentModifier); + + const aggron = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TACKLE); + + await game.phaseInterceptor.to("BerryPhase", false); + + expect(aggron.hp).toBe(aggron.getMaxHp() - 1); + }); + it("Fixed-damage moves ignore damage multipliers", async () => { game.override .enemySpecies(Species.DRAGONITE)