From 27c01bbbc4e38911d42499d831debc80b0d2f68d Mon Sep 17 00:00:00 2001 From: Christopher Schmidt Date: Thu, 20 Feb 2025 20:42:21 -0500 Subject: [PATCH] Rename HitResult.OTHER to INDIRECT, create INDIRECT_KO for PSong/DBond, add functionality for INDIRECT_KO to damageanim/number handler --- src/data/ability.ts | 12 ++++++------ src/data/arena-tag.ts | 2 +- src/data/battler-tags.ts | 10 +++++----- src/data/move.ts | 18 +++++++++--------- src/field/damage-number-handler.ts | 1 + src/field/pokemon.ts | 9 +++++---- src/phases/damage-anim-phase.ts | 5 +++-- src/phases/faint-phase.ts | 2 +- src/phases/pokemon-heal-phase.ts | 2 +- src/phases/weather-effect-phase.ts | 2 +- 10 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 3a43c767357..320db93a445 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -958,7 +958,7 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr { override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !move.hitsSubstitute(attacker, pokemon)) { - attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); + attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.INDIRECT); attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)); return true; } @@ -3469,7 +3469,7 @@ export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr { if (!simulated) { const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name; globalScene.queueMessage(i18next.t("abilityTriggers:postWeatherLapseDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName })); - pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / (16 / this.damageFactor)), HitResult.OTHER); + pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / (16 / this.damageFactor)), HitResult.INDIRECT); } return true; @@ -3781,7 +3781,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr { for (const opp of pokemon.getOpponents()) { if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !opp.switchOutStatus) { if (!simulated) { - opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER); + opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.INDIRECT); globalScene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) })); } hadEffect = true; @@ -4236,7 +4236,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr { return false; } if (!simulated) { - attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); + attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.INDIRECT); attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)); } return true; @@ -4261,7 +4261,7 @@ export class PostFaintHPDamageAbAttr extends PostFaintAbAttr { applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean { if (move !== undefined && attacker !== undefined && !simulated) { //If the mon didn't die to indirect damage const damage = pokemon.turnData.attacksReceived[0].damage; - attacker.damageAndUpdate((damage), HitResult.OTHER); + attacker.damageAndUpdate((damage), HitResult.INDIRECT); attacker.turnData.damageTaken += damage; } return true; @@ -4675,7 +4675,7 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr { (args[0] as Utils.NumberHolder).value = this.multiplier; pokemon.removeTag(this.tagType); if (this.recoilDamageFunc) { - pokemon.damageAndUpdate(this.recoilDamageFunc(pokemon), HitResult.OTHER, false, true, true); + pokemon.damageAndUpdate(this.recoilDamageFunc(pokemon), HitResult.INDIRECT, false, true, true); } } return true; diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 2fa4593fd6c..06c87f33d08 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -698,7 +698,7 @@ class SpikesTag extends ArenaTrapTag { const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); globalScene.queueMessage(i18next.t("arenaTag:spikesActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); - pokemon.damageAndUpdate(damage, HitResult.OTHER); + pokemon.damageAndUpdate(damage, HitResult.INDIRECT); if (pokemon.turnData) { pokemon.turnData.damageTaken += damage; } diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 7c769ee7af7..c8b804ea919 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -723,7 +723,7 @@ export class DestinyBondTag extends BattlerTag { pokemonNameWithAffix2: getPokemonNameWithAffix(pokemon) }) ); - pokemon.damageAndUpdate(pokemon.hp, HitResult.OTHER, false, true); + pokemon.damageAndUpdate(pokemon.hp, HitResult.INDIRECT_KO, false, true); return false; } } @@ -898,7 +898,7 @@ export class PowderTag extends BattlerTag { const cancelDamage = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelDamage); if (!cancelDamage.value) { - pokemon.damageAndUpdate(Math.floor(pokemon.getMaxHp() / 4), HitResult.OTHER); + pokemon.damageAndUpdate(Math.floor(pokemon.getMaxHp() / 4), HitResult.INDIRECT); } // "When the flame touched the powder\non the Pokémon, it exploded!" @@ -1459,7 +1459,7 @@ export class ContactDamageProtectedTag extends ProtectedTag { if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) { const attacker = effectPhase.getPokemon(); if (!attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { - attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); + attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.INDIRECT); } } } @@ -1613,7 +1613,7 @@ export class PerishSongTag extends BattlerTag { }) ); } else { - pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, true); + pokemon.damageAndUpdate(pokemon.hp, HitResult.INDIRECT_KO, false, true); } return ret; @@ -2327,7 +2327,7 @@ export class GulpMissileTag extends BattlerTag { applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled); if (!cancelled.value) { - attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), HitResult.OTHER); + attacker.damageAndUpdate(Math.max(1, Math.floor(attacker.getMaxHp() / 4)), HitResult.INDIRECT); } if (this.tagType === BattlerTagType.GULP_MISSILE_ARROKUDA) { diff --git a/src/data/move.ts b/src/data/move.ts index fda3555c1a3..364d9f51164 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1568,7 +1568,7 @@ export class RecoilAttr extends MoveEffectAttr { return false; } - user.damageAndUpdate(recoilDamage, HitResult.OTHER, false, true); + user.damageAndUpdate(recoilDamage, HitResult.INDIRECT, false, true); globalScene.queueMessage(i18next.t("moveTriggers:hitWithRecoil", { pokemonName: getPokemonNameWithAffix(user) })); user.turnData.damageTaken += recoilDamage; @@ -1600,7 +1600,7 @@ export class SacrificialAttr extends MoveEffectAttr { * @returns true if the function succeeds **/ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - user.damageAndUpdate(user.hp, HitResult.OTHER, false, true); + user.damageAndUpdate(user.hp, HitResult.INDIRECT, false, true); user.turnData.damageTaken += user.hp; return true; @@ -1638,7 +1638,7 @@ export class SacrificialAttrOnHit extends MoveEffectAttr { return false; } - user.damageAndUpdate(user.hp, HitResult.OTHER, false, true); + user.damageAndUpdate(user.hp, HitResult.INDIRECT, false, true); user.turnData.damageTaken += user.hp; return true; @@ -1680,7 +1680,7 @@ export class HalfSacrificialAttr extends MoveEffectAttr { // Check to see if the Pokemon has an ability that blocks non-direct damage applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled); if (!cancelled.value) { - user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), HitResult.OTHER, false, true); + user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), HitResult.INDIRECT, false, true); globalScene.queueMessage(i18next.t("moveTriggers:cutHpPowerUpMove", { pokemonName: getPokemonNameWithAffix(user) })); // Queue recoil message } return true; @@ -1723,7 +1723,7 @@ export class AddSubstituteAttr extends MoveEffectAttr { return false; } - user.damageAndUpdate(Math.floor(user.getMaxHp() * this.hpCost), HitResult.OTHER, false, true); + user.damageAndUpdate(Math.floor(user.getMaxHp() * this.hpCost), HitResult.INDIRECT, false, true); user.addTag(BattlerTagType.SUBSTITUTE, 0, move.id, user.id); return true; } @@ -1878,7 +1878,7 @@ export class FlameBurstAttr extends MoveEffectAttr { return false; } - targetAlly.damageAndUpdate(Math.max(1, Math.floor(1 / 16 * targetAlly.getMaxHp())), HitResult.OTHER); + targetAlly.damageAndUpdate(Math.max(1, Math.floor(1 / 16 * targetAlly.getMaxHp())), HitResult.INDIRECT); return true; } @@ -3326,7 +3326,7 @@ export class CutHpStatStageBoostAttr extends StatStageChangeAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { return new Promise(resolve => { - user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / this.cutRatio), HitResult.OTHER, false); + user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / this.cutRatio), HitResult.INDIRECT, false); user.updateInfo().then(() => { const ret = super.apply(user, target, move, args); if (this.messageCallback) { @@ -5236,7 +5236,7 @@ const crashDamageFunc = (user: Pokemon, move: Move) => { return false; } - user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), HitResult.OTHER, false); + user.damageAndUpdate(Utils.toDmgValue(user.getMaxHp() / 2), HitResult.INDIRECT, false); globalScene.queueMessage(i18next.t("moveTriggers:keptGoingAndCrashed", { pokemonName: getPokemonNameWithAffix(user) })); user.turnData.damageTaken += Utils.toDmgValue(user.getMaxHp() / 2); @@ -5532,7 +5532,7 @@ export class CurseAttr extends MoveEffectAttr { return false; } const curseRecoilDamage = Math.max(1, Math.floor(user.getMaxHp() / 2)); - user.damageAndUpdate(curseRecoilDamage, HitResult.OTHER, false, true); + user.damageAndUpdate(curseRecoilDamage, HitResult.INDIRECT, false, true); globalScene.queueMessage( i18next.t("battlerTags:cursedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(user), diff --git a/src/field/damage-number-handler.ts b/src/field/damage-number-handler.ts index 1551edc9697..ad05051c276 100644 --- a/src/field/damage-number-handler.ts +++ b/src/field/damage-number-handler.ts @@ -36,6 +36,7 @@ export default class DamageNumberHandler { case HitResult.NOT_VERY_EFFECTIVE: [ textColor, shadowColor ] = [ "#f08030", "#c03028" ]; break; + case HitResult.INDIRECT_KO: case HitResult.ONE_HIT_KO: [ textColor, shadowColor ] = [ "#a040a0", "#483850" ]; break; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 46e75019420..2f3060c04a4 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3163,7 +3163,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { damageAndUpdate(damage: number, result?: DamageResult, critical: boolean = false, ignoreSegments: boolean = false, ignoreFaintPhase: boolean = false, source?: Pokemon): number { let isIndirectDamage: boolean = true; if (result !== undefined) { - if (result === HitResult.OTHER) { + if (result === HitResult.INDIRECT || result === HitResult.INDIRECT_KO) { isIndirectDamage = true; } else { isIndirectDamage = false; @@ -5506,12 +5506,13 @@ export enum HitResult { HEAL, FAIL, MISS, - OTHER, + INDIRECT, IMMUNE, - CONFUSION + CONFUSION, + INDIRECT_KO } -export type DamageResult = HitResult.EFFECTIVE | HitResult.SUPER_EFFECTIVE | HitResult.NOT_VERY_EFFECTIVE | HitResult.ONE_HIT_KO | HitResult.CONFUSION | HitResult.OTHER; +export type DamageResult = HitResult.EFFECTIVE | HitResult.SUPER_EFFECTIVE | HitResult.NOT_VERY_EFFECTIVE | HitResult.ONE_HIT_KO | HitResult.CONFUSION | HitResult.INDIRECT_KO | HitResult.INDIRECT; /** Interface containing the results of a damage calculation for a given move */ export interface DamageCalculationResult { diff --git a/src/phases/damage-anim-phase.ts b/src/phases/damage-anim-phase.ts index 5d7d0b1e2ae..3874dd570eb 100644 --- a/src/phases/damage-anim-phase.ts +++ b/src/phases/damage-anim-phase.ts @@ -21,7 +21,7 @@ export class DamageAnimPhase extends PokemonPhase { start() { super.start(); - if (this.damageResult === HitResult.ONE_HIT_KO) { + if (this.damageResult === HitResult.ONE_HIT_KO || this.damageResult === HitResult.INDIRECT_KO) { if (globalScene.moveAnimations) { globalScene.toggleInvert(true); } @@ -46,6 +46,7 @@ export class DamageAnimPhase extends PokemonPhase { globalScene.playSound("se/hit"); break; case HitResult.SUPER_EFFECTIVE: + case HitResult.INDIRECT_KO: case HitResult.ONE_HIT_KO: globalScene.playSound("se/hit_strong"); break; @@ -58,7 +59,7 @@ export class DamageAnimPhase extends PokemonPhase { globalScene.damageNumberHandler.add(this.getPokemon(), this.amount, this.damageResult, this.critical); } - if (this.damageResult !== HitResult.OTHER && this.amount > 0) { + if (this.damageResult !== HitResult.INDIRECT && this.amount > 0) { const flashTimer = globalScene.time.addEvent({ delay: 100, repeat: 5, diff --git a/src/phases/faint-phase.ts b/src/phases/faint-phase.ts index f354bc8031e..f507d7d9594 100644 --- a/src/phases/faint-phase.ts +++ b/src/phases/faint-phase.ts @@ -210,7 +210,7 @@ export class FaintPhase extends PokemonPhase { } else { // Final boss' HP threshold has been bypassed; cancel faint and force check for 2nd phase enemy.hp++; - globalScene.unshiftPhase(new DamageAnimPhase(enemy.getBattlerIndex(), 0, HitResult.OTHER)); + globalScene.unshiftPhase(new DamageAnimPhase(enemy.getBattlerIndex(), 0, HitResult.INDIRECT)); this.end(); } return true; diff --git a/src/phases/pokemon-heal-phase.ts b/src/phases/pokemon-heal-phase.ts index 9eedde26916..c99cf2e0329 100644 --- a/src/phases/pokemon-heal-phase.ts +++ b/src/phases/pokemon-heal-phase.ts @@ -68,7 +68,7 @@ export class PokemonHealPhase extends CommonAnimPhase { } const healAmount = new Utils.NumberHolder(Math.floor(this.hpHealed * hpRestoreMultiplier.value)); if (healAmount.value < 0) { - pokemon.damageAndUpdate(healAmount.value * -1, HitResult.OTHER as DamageResult); + pokemon.damageAndUpdate(healAmount.value * -1, HitResult.INDIRECT as DamageResult); healAmount.value = 0; } // Prevent healing to full if specified (in case of healing tokens so Sturdy doesn't cause a softlock) diff --git a/src/phases/weather-effect-phase.ts b/src/phases/weather-effect-phase.ts index e5915837f9f..3a9d0357e79 100644 --- a/src/phases/weather-effect-phase.ts +++ b/src/phases/weather-effect-phase.ts @@ -49,7 +49,7 @@ export class WeatherEffectPhase extends CommonAnimPhase { const damage = Utils.toDmgValue(pokemon.getMaxHp() / 16); globalScene.queueMessage(getWeatherDamageMessage(this.weather?.weatherType!, pokemon)!); // TODO: are those bangs correct? - pokemon.damageAndUpdate(damage, HitResult.OTHER, false, true); + pokemon.damageAndUpdate(damage, HitResult.INDIRECT, false, true); }; this.executeForAll((pokemon: Pokemon) => {