diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index a39234668e1..50bb61fa972 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -141,6 +141,14 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag { */ abstract isMoveRestricted(move: Moves): boolean; + /** + * Checks if this tag is restricting a move based on a user's decisions during the target selection phase + * + * @param {Moves} move {@linkcode Moves} move ID to check restriction for + * @param {Pokemon} user {@linkcode Pokemon} the user of the above move + * @param {Pokemon} target {@linkcode Pokemon} the target of the above move + * @returns {boolean} `false` unless overridden by the child tag + */ isMoveTargetRestricted(move: Moves, user: Pokemon, target: Pokemon): boolean { return false; } @@ -2183,25 +2191,32 @@ export class ExposedTag extends BattlerTag { } /** - * Describes the behavior of a Heal Block Tag. + * Tag that prevents HP recovery from held items and move effects. It also blocks the usage of recovery moves. + * Applied by moves: {@linkcode Moves.HEAL_BLOCK | Heal Block (5 turns)}, {@linkcode Moves.PSYCHIC_NOISE | Psychic Noise (2 turns)} + * + * @extends MoveRestrictionBattlerTag */ export class HealBlockTag extends MoveRestrictionBattlerTag { constructor(turnCount: number, sourceMove: Moves) { super(BattlerTagType.HEAL_BLOCK, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END ], turnCount, sourceMove); } + /** + * Uses the default onAdd method + */ override onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); } - override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { - return super.lapse(pokemon, lapseType); - } - onActivation(pokemon: Pokemon): string { return i18next.t("battle:battlerTagsHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } + /** + * Checks if a move is disabled under Heal Block + * @param {Moves} move {@linkcode Moves} the move ID + * @returns {boolean} T/F if the move has a TRIAGE_MOVE flag and is a status move + */ override isMoveRestricted(move: Moves): boolean { if (allMoves[move].hasFlag(MoveFlags.TRIAGE_MOVE) && allMoves[move].category === MoveCategory.STATUS) { return true; @@ -2209,6 +2224,14 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { return false; } + /** + * Checks if a move is disabled under Heal Block because of its choice of target + * Implemented b/c of Pollen Puff + * @param {Moves} move {@linkcode Moves} the move ID + * @param {Pokemon} user {@linkcode Pokemon} the move user + * @param {Pokemon} target {@linkcode Pokemon} the target of the move + * @returns {boolean} the move cannot be used b/c the target is an ally + */ override isMoveTargetRestricted(move: Moves, user: Pokemon, target: Pokemon) { const moveCategory = new Utils.IntegerHolder(allMoves[move].category); applyMoveAttrs(StatusCategoryOnAllyAttr, user, target, allMoves[move], moveCategory); @@ -2218,6 +2241,9 @@ export class HealBlockTag extends MoveRestrictionBattlerTag { return false; } + /** + * Uses DisabledTag's selectionDeniedText() message + */ override selectionDeniedText(pokemon: Pokemon, move: Moves): string { return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name }); } diff --git a/src/data/move.ts b/src/data/move.ts index a2ed156b519..28f17c639a6 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -3969,6 +3969,7 @@ export class StatusCategoryOnAllyAttr extends VariableMoveCategoryAttr { */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const category = (args[0] as Utils.IntegerHolder); + // Need to check for strict equality or something better than this. const isAlly = (user.isPlayer() && target.isPlayer()) || (!user.isPlayer() && !target.isPlayer()); if (isAlly) { diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 51566408d91..f3d8d7ebada 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -2972,8 +2972,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } /** + * Gets whether the given move is currently disabled for the user based on the player's target selection * + * @param {Moves} moveId {@linkcode Moves} ID of the move to check + * @param {Pokemon} user {@linkcode Pokemon} the move user + * @param {Pokemon} target {@linkcode Pokemon} the target of the move * + * @returns {boolean} `true` if the move is disabled for this Pokemon due to the player's target selection + * + * @see {@linkcode MoveRestrictionBattlerTag} */ isMoveTargetRestricted(moveId: Moves, user: Pokemon, target: Pokemon): boolean { for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) { @@ -2988,11 +2995,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * Gets the {@link MoveRestrictionBattlerTag} that is restricting a move, if it exists. * * @param {Moves} moveId {@linkcode Moves} ID of the move to check + * @param {Pokemon} user {@linkcode Pokemon} the move user, optional and used when the target is a factor in the move's restricted status + * @param {Pokemon} target {@linkcode Pokemon} the target of the move, optional and used when the target is a factor in the move's restricted status * @returns {MoveRestrictionBattlerTag | null} the first tag on this Pokemon that restricts the move, or `null` if the move is not restricted. */ - getRestrictingTag(moveId: Moves, hasTargetRestriction: boolean = false): MoveRestrictionBattlerTag | null { + getRestrictingTag(moveId: Moves, user?: Pokemon, target?: Pokemon): MoveRestrictionBattlerTag | null { for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) { - if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId) || hasTargetRestriction ) { + if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId)) { + return tag as MoveRestrictionBattlerTag; + } else if (user && target && (tag as MoveRestrictionBattlerTag).isMoveTargetRestricted(moveId, user, target)) { return tag as MoveRestrictionBattlerTag; } } diff --git a/src/phases/select-target-phase.ts b/src/phases/select-target-phase.ts index df4c04fc581..b9291d7d92b 100644 --- a/src/phases/select-target-phase.ts +++ b/src/phases/select-target-phase.ts @@ -22,9 +22,8 @@ export class SelectTargetPhase extends PokemonPhase { const fieldSide = this.scene.getField(); const user = fieldSide[this.fieldIndex]; const moveObject = allMoves[move!]; - const hasTargetRestriction = user.isMoveTargetRestricted(moveObject.id, user, fieldSide[targets[0]]); - if (moveObject && hasTargetRestriction) { - const errorMessage = user.getRestrictingTag(move!, hasTargetRestriction)!.selectionDeniedText(user, moveObject.id); + if (moveObject && user.isMoveTargetRestricted(moveObject.id, user, fieldSide[targets[0]])) { + const errorMessage = user.getRestrictingTag(move!, user, fieldSide[targets[0]])!.selectionDeniedText(user, moveObject.id); user.scene.queueMessage(i18next.t(errorMessage, { moveName: moveObject.name }), 0, true); targets.length = 0; }