diff --git a/src/field/arena.ts b/src/field/arena.ts index e8defbd1a8e..8d0906c649f 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -391,16 +391,16 @@ export class Arena { return true; } - isMoveWeatherCancelled(move: Move) { - return this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(move); + isMoveWeatherCancelled(move: Move): boolean { + return (this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(move)) as boolean; } - isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move) { - return this.terrain && this.terrain.isMoveTerrainCancelled(user, targets, move); + isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean { + return (this.terrain && this.terrain.isMoveTerrainCancelled(user, targets, move)) as boolean; } - getTerrainType() : TerrainType { - return this.terrain?.terrainType || TerrainType.NONE; + getTerrainType(): TerrainType { + return this.terrain?.terrainType ?? TerrainType.NONE; } getAttackTypeMultiplier(attackType: Type, grounded: boolean): number { diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8594d5b769b..34eb6b7a512 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4368,8 +4368,8 @@ export class PokemonBattleSummonData { export class PokemonTurnData { public flinched: boolean = false; public acted: boolean = false; - public hitCount: number; - public hitsLeft: number; + public hitCount: number = 0; + public hitsLeft: number = 0; public damageDealt: number = 0; public currDamageDealt: number = 0; public damageTaken: number = 0; diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index d841825b333..cba5d18fa2e 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -1,27 +1,27 @@ -import BattleScene from "#app/battle-scene.js"; -import { BattlerIndex } from "#app/battle.js"; -import { applyAbAttrs, applyPostMoveUsedAbAttrs, applyPreAttackAbAttrs, BlockRedirectAbAttr, IncreasePpAbAttr, PokemonTypeChangeAbAttr, PostMoveUsedAbAttr, RedirectMoveAbAttr } from "#app/data/ability.js"; -import { CommonAnim } from "#app/data/battle-anims.js"; -import { BattlerTagLapseType, CenterOfAttentionTag } from "#app/data/battler-tags.js"; -import { allMoves, applyMoveAttrs, BypassRedirectAttr, BypassSleepAttr, ChargeAttr, CopyMoveAttr, HealStatusEffectAttr, MoveFlags, PreMoveMessageAttr } from "#app/data/move.js"; -import { SpeciesFormChangePreMoveTrigger } from "#app/data/pokemon-forms.js"; -import { getStatusEffectActivationText, getStatusEffectHealText } from "#app/data/status-effect.js"; -import { Type } from "#app/data/type.js"; -import { getTerrainBlockMessage } from "#app/data/weather.js"; -import { Abilities } from "#app/enums/abilities.js"; -import { BattlerTagType } from "#app/enums/battler-tag-type.js"; -import { Moves } from "#app/enums/moves.js"; -import { StatusEffect } from "#app/enums/status-effect.js"; -import { MoveUsedEvent } from "#app/events/battle-scene.js"; -import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon.js"; -import { getPokemonNameWithAffix } from "#app/messages.js"; -import * as Utils from "#app/utils.js"; +import { BattlerIndex } from "#app/battle"; +import BattleScene from "#app/battle-scene"; +import { applyAbAttrs, applyPostMoveUsedAbAttrs, applyPreAttackAbAttrs, BlockRedirectAbAttr, IncreasePpAbAttr, PokemonTypeChangeAbAttr, PostMoveUsedAbAttr, RedirectMoveAbAttr } from "#app/data/ability"; +import { CommonAnim } from "#app/data/battle-anims"; +import { BattlerTagLapseType, CenterOfAttentionTag } from "#app/data/battler-tags"; +import { allMoves, applyMoveAttrs, BypassRedirectAttr, BypassSleepAttr, ChargeAttr, CopyMoveAttr, HealStatusEffectAttr, MoveFlags, PreMoveMessageAttr } from "#app/data/move"; +import { SpeciesFormChangePreMoveTrigger } from "#app/data/pokemon-forms"; +import { getStatusEffectActivationText, getStatusEffectHealText } from "#app/data/status-effect"; +import { Type } from "#app/data/type"; +import { getTerrainBlockMessage } from "#app/data/weather"; +import { Abilities } from "#app/enums/abilities"; +import { BattlerTagType } from "#app/enums/battler-tag-type"; +import { Moves } from "#app/enums/moves"; +import { StatusEffect } from "#app/enums/status-effect"; +import { MoveUsedEvent } from "#app/events/battle-scene"; +import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon"; +import { getPokemonNameWithAffix } from "#app/messages"; +import { BattlePhase } from "#app/phases/battle-phase"; +import { CommonAnimPhase } from "#app/phases/common-anim-phase"; +import { MoveEffectPhase } from "#app/phases/move-effect-phase"; +import { MoveEndPhase } from "#app/phases/move-end-phase"; +import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; +import * as Utils from "#app/utils"; import i18next from "i18next"; -import { BattlePhase } from "./battle-phase"; -import { CommonAnimPhase } from "./common-anim-phase"; -import { MoveEffectPhase } from "./move-effect-phase"; -import { MoveEndPhase } from "./move-end-phase"; -import { ShowAbilityPhase } from "./show-ability-phase"; export class MovePhase extends BattlePhase { public pokemon: Pokemon; @@ -86,8 +86,8 @@ export class MovePhase extends BattlePhase { // Reset hit-related turn data when starting follow-up moves (e.g. Metronomed moves, Dancer repeats) if (this.followUp) { - this.pokemon.turnData.hitsLeft = undefined; - this.pokemon.turnData.hitCount = undefined; + this.pokemon.turnData.hitsLeft = 0; + this.pokemon.turnData.hitCount = 0; } /** @@ -188,7 +188,7 @@ export class MovePhase extends BattlePhase { // TODO: Clean up implementation of two-turn moves. if (moveQueue.length > 0) { // Using .shift here clears out two turn moves once they've been used - this.ignorePp = moveQueue.shift().ignorePP; + this.ignorePp = moveQueue.shift()?.ignorePP ?? false; } // "commit" to using the move, deducting PP. @@ -220,7 +220,7 @@ export class MovePhase extends BattlePhase { // Move conditions assume the move has a single target (is this sustainable?) const passesConditions = move.applyConditions(this.pokemon, targets[0], move); - const failureMessage = move.getFailedText(this.pokemon, targets[0], move, null); + const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new Utils.BooleanHolder(false)); const failedWithMessage = failureMessage !== null && failureMessage !== undefined; let failedDueToWeather: boolean, failedDueToTerrain: boolean; @@ -233,6 +233,7 @@ export class MovePhase extends BattlePhase { } } + // @ts-expect-error const success = passesConditions && !failedWithMessage && !failedDueToWeather && !failedDueToTerrain; /** @@ -258,7 +259,7 @@ export class MovePhase extends BattlePhase { if (failedWithMessage) { failedText = failureMessage; - + // @ts-expect-error } else if (failedDueToTerrain) { failedText = getTerrainBlockMessage(this.pokemon, this.scene.arena.getTerrainType()); } @@ -305,7 +306,7 @@ export class MovePhase extends BattlePhase { const redirectTarget = new Utils.IntegerHolder(currentTarget); // check move redirection abilities of every pokemon *except* the user. - this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, this.move.moveId, redirectTarget)); + this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, redirectTarget)); // check for center-of-attention tags (note that this will override redirect abilities) this.pokemon.getOpponents().forEach(p => { @@ -411,10 +412,10 @@ export class MovePhase extends BattlePhase { pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon), moveName: this.move.getName() }), 500); - applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents().find(() => true), this.move.getMove()); + applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents().find(() => true) ?? null, this.move.getMove()); } - showFailedText(failedText: string = null): void { - this.scene.queueMessage(failedText || i18next.t("battle:attackFailed")); + showFailedText(failedText?: string): void { + this.scene.queueMessage(failedText ?? i18next.t("battle:attackFailed")); } }