From fa60e002e89c6d5d5da2f451ac4370aeffb758b6 Mon Sep 17 00:00:00 2001 From: Matt Ross <13306707+mattrossdev@users.noreply.github.com> Date: Mon, 13 May 2024 11:05:09 -0700 Subject: [PATCH] Fixes some variable damage moves not working with tinted lens (#759) * Fixes some variable damage moves not working with abilities * Rework as new ability attribute * Update variable base power check to original location * formatting * Add tsdoc comments * add floor for potential non int multipliers * Update pokemon.ts --------- Co-authored-by: Benjamin Odom --- src/data/ability.ts | 38 +++++++++++++++++++++++++++++++++++++- src/field/pokemon.ts | 5 ++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 662cd3715..fee574e4a 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -991,6 +991,42 @@ export class MoveTypeChangeAttr extends PreAttackAbAttr { } } +/** + * Class for abilities that boost the damage of moves + * For abilities that boost the base power of moves, see VariableMovePowerAbAttr + * @param damageMultiplier the amount to multiply the damage by + * @param condition the condition for this ability to be applied + */ +export class DamageBoostAbAttr extends PreAttackAbAttr { + private damageMultiplier: number; + private condition: PokemonAttackCondition; + + constructor(damageMultiplier: number, condition: PokemonAttackCondition){ + super(true); + this.damageMultiplier = damageMultiplier; + this.condition = condition; + } + + /** + * + * @param pokemon the attacker pokemon + * @param passive N/A + * @param defender the target pokemon + * @param move the move used by the attacker pokemon + * @param args Utils.NumberHolder as damage + * @returns true if the function succeeds + */ + applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean { + if (this.condition(pokemon, defender, move.getMove())) { + const power = args[0] as Utils.NumberHolder; + power.value = Math.floor(power.value * this.damageMultiplier); + return true; + } + + return false; + } +} + export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr { private condition: PokemonAttackCondition; private powerMultiplier: number; @@ -3121,7 +3157,7 @@ export function initAbilities() { .attr(IgnoreOpponentStatChangesAbAttr) .ignorable(), new Ability(Abilities.TINTED_LENS, 4) - .attr(MovePowerBoostAbAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) <= 0.5, 2), + .attr(DamageBoostAbAttr, 2, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) <= 0.5), new Ability(Abilities.FILTER, 4) .attr(ReceivedMoveDamageMultiplierAbAttr,(target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75) .ignorable(), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 807be3f8d..307f98f2f 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -27,7 +27,7 @@ import { TempBattleStat } from '../data/temp-battle-stat'; import { ArenaTagSide, WeakenMoveScreenTag, WeakenMoveTypeTag } from '../data/arena-tag'; import { ArenaTagType } from "../data/enums/arena-tag-type"; import { Biome } from "../data/enums/biome"; -import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr } from '../data/ability'; +import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr } from '../data/ability'; import { Abilities } from "#app/data/enums/abilities"; import PokemonData from '../system/pokemon-data'; import Battle, { BattlerIndex } from '../battle'; @@ -1545,6 +1545,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (!burnDamageReductionCancelled.value) damage.value = Math.floor(damage.value / 2); } + + applyPreAttackAbAttrs(DamageBoostAbAttr, source, this, battlerMove, damage); + move.getAttrs(HitsTagAttr).map(hta => hta as HitsTagAttr).filter(hta => hta.doubleDamage).forEach(hta => { if (this.getTag(hta.tagType)) damage.value *= 2;