diff --git a/src/data/ability.ts b/src/data/ability.ts index dac5ae2eaba..6acae2b203f 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -776,9 +776,9 @@ export class MoveImmunityStatStageChangeAbAttr extends MoveImmunityAbAttr { /** * Class for abilities that make drain moves deal damage to user instead of healing them. * @extends PostDefendAbAttr - * @see {@linkcode applyPreDefend} + * @see {@linkcode applyPostDefend} */ -export class ReverseDrainAbAttr extends PreDefendAbAttr { +export class ReverseDrainAbAttr extends PostDefendAbAttr { private attacker: Pokemon; /** @@ -787,13 +787,19 @@ export class ReverseDrainAbAttr extends PreDefendAbAttr { * * If so, this ability should cause the move user should be damaged instead of healed */ - override canApplyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { + override canApplyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult | null, args: any[]): boolean { this.attacker = attacker; return move.hasAttr(HitHealAttr) && !move.hitsSubstitute(attacker, pokemon); } - override applyPreDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): void { - cancelled.value = true; + override applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult | null, args: any[]): void { + const cancelled = new Utils.BooleanHolder(false); + applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); + if (!cancelled.value) { + const damageAmount = move.getAttrs(HitHealAttr)[0].getHealAmount(attacker, pokemon); + pokemon.turnData.damageTaken += damageAmount; + globalScene.unshiftPhase(new PokemonHealPhase(attacker.getBattlerIndex(), -damageAmount, null, false, true)); + } } public override getTriggerMessage(pokemon: Pokemon, _abilityName: string, ..._args: any[]): string | null { diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index f11d8fe2688..b40f35191f5 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -2174,29 +2174,18 @@ export class HitHealAttr extends MoveEffectAttr { * @returns true if the function succeeds */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - let healAmount = 0; + if (target.hasAbilityWithAttr(ReverseDrainAbAttr)) { + return false; + } + + const healAmount = this.getHealAmount(user, target); let message = ""; - const reverseDrain = new Utils.BooleanHolder(false); - applyPreDefendAbAttrs(ReverseDrainAbAttr, target, user, move, reverseDrain); if (this.healStat !== null) { - // Strength Sap formula - healAmount = target.getEffectiveStat(this.healStat); message = i18next.t("battle:drainMessage", { pokemonName: getPokemonNameWithAffix(target) }); } else { - // Default healing formula used by draining moves like Absorb, Draining Kiss, Bitter Blade, etc. - healAmount = Utils.toDmgValue(user.turnData.singleHitDamageDealt * this.healRatio); message = i18next.t("battle:regainHealth", { pokemonName: getPokemonNameWithAffix(user) }); } - if (reverseDrain.value) { - if (user.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { - healAmount = 0; - message = ""; - } else { - user.turnData.damageTaken += healAmount; - healAmount = healAmount * -1; - message = ""; - } - } + globalScene.unshiftPhase(new PokemonHealPhase(user.getBattlerIndex(), healAmount, message, false, true)); return true; } @@ -2215,6 +2204,10 @@ export class HitHealAttr extends MoveEffectAttr { } return Math.floor(Math.max((1 - user.getHpRatio()) - 0.33, 0) * (move.power / 4)); } + + public getHealAmount(user: Pokemon, target: Pokemon): number { + return (this.healStat) ? target.getEffectiveStat(this.healStat) : Utils.toDmgValue(user.turnData.singleHitDamageDealt * this.healRatio); + } } /**