PR review changes

Fix type hints test name

Update Dig/Dive test name

Separate TSDoc imports in `pokemon-utils.ts`

Add missing `@returns` in `move-phase.ts`

Fix comment typos

Separate TSDoc imports in `move-phase.ts`

Add return hints to `trySelectMove`

Minor formatting

Remove duplicate `.affectedByGravity()` on Telekinesis

Fix docs for `checkRestrictions`

Manually format method definition

Fix comment spacing

Fix variable naming
This commit is contained in:
NightKev 2025-08-19 17:23:11 -07:00 committed by Sirz Benjie
parent 2eed38dc55
commit 9e49162012
No known key found for this signature in database
GPG Key ID: 4A524B4D196C759E
8 changed files with 50 additions and 49 deletions

View File

@ -156,7 +156,7 @@ export const failAgainstFinalBossCondition = new MoveCondition((_user, target) =
* a high-priority attack (after factoring in priority-boosting effects) and * a high-priority attack (after factoring in priority-boosting effects) and
* hasn't moved yet this turn. * hasn't moved yet this turn.
*/ */
export const UpperHandCondition = new MoveCondition((_user, target) => { export const upperHandCondition = new MoveCondition((_user, target) => {
const targetCommand = globalScene.currentBattle.turnCommands[target.getBattlerIndex()]; const targetCommand = globalScene.currentBattle.turnCommands[target.getBattlerIndex()];
return ( return (
targetCommand?.command === Command.FIGHT && targetCommand?.command === Command.FIGHT &&
@ -252,13 +252,13 @@ export class MoveRestriction {
* @remarks * @remarks
* Used by {@link https://bulbapedia.bulbagarden.net/wiki/Blood_Moon_(move) | Blood Moon} and {@link https://bulbapedia.bulbagarden.net/wiki/Gigaton_Hammer_(move) | Gigaton Hammer} * Used by {@link https://bulbapedia.bulbagarden.net/wiki/Blood_Moon_(move) | Blood Moon} and {@link https://bulbapedia.bulbagarden.net/wiki/Gigaton_Hammer_(move) | Gigaton Hammer}
*/ */
export const ConsecutiveUseRestriction = new MoveRestriction( export const consecutiveUseRestriction = new MoveRestriction(
(user, move) => user.getLastXMoves(1)[0]?.move === move.id, (user, move) => user.getLastXMoves(1)[0]?.move === move.id,
"battle:moveDisabledConsecutive", "battle:moveDisabledConsecutive",
); );
/** Prevents a move from being selected if Gravity is in effect */ /** Prevents a move from being selected if Gravity is in effect */
export const GravityUseRestriction = new MoveRestriction( export const gravityUseRestriction = new MoveRestriction(
() => globalScene.arena.hasTag(ArenaTagType.GRAVITY), () => globalScene.arena.hasTag(ArenaTagType.GRAVITY),
"battle:moveDisabledGravity", "battle:moveDisabledGravity",
); );

View File

@ -82,7 +82,7 @@ import {
} from "#modifiers/modifier"; } from "#modifiers/modifier";
import { applyMoveAttrs } from "#moves/apply-attrs"; import { applyMoveAttrs } from "#moves/apply-attrs";
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSketchMoves, invalidSleepTalkMoves } from "#moves/invalid-moves"; import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSketchMoves, invalidSleepTalkMoves } from "#moves/invalid-moves";
import { ConsecutiveUseRestriction, counterAttackConditionBoth, counterAttackConditionPhysical, counterAttackConditionSpecial, failAgainstFinalBossCondition, FailIfInsufficientHpCondition, failIfTargetNotAttackingCondition, failTeleportCondition, FirstMoveCondition, GravityUseRestriction, lastResortCondition, MoveCondition, MoveRestriction, UpperHandCondition } from "#moves/move-condition"; import { consecutiveUseRestriction, counterAttackConditionBoth, counterAttackConditionPhysical, counterAttackConditionSpecial, failAgainstFinalBossCondition, FailIfInsufficientHpCondition, failIfTargetNotAttackingCondition, failTeleportCondition, FirstMoveCondition, gravityUseRestriction, lastResortCondition, MoveCondition, MoveRestriction, upperHandCondition } from "#moves/move-condition";
import { frenzyMissFunc, getCounterAttackTarget, getMoveTargets } from "#moves/move-utils"; import { frenzyMissFunc, getCounterAttackTarget, getMoveTargets } from "#moves/move-utils";
import { PokemonMove } from "#moves/pokemon-move"; import { PokemonMove } from "#moves/pokemon-move";
import { MovePhase } from "#phases/move-phase"; import { MovePhase } from "#phases/move-phase";
@ -172,8 +172,14 @@ export abstract class Move implements Localizable {
* @see {@link https://www.smogon.com/forums/threads/sword-shield-battle-mechanics-research.3655528/page-54#post-8548957} * @see {@link https://www.smogon.com/forums/threads/sword-shield-battle-mechanics-research.3655528/page-54#post-8548957}
*/ */
private conditionsSeq3: MoveCondition[] = []; private conditionsSeq3: MoveCondition[] = [];
<<<<<<< HEAD
/** Conditions that must be false for a move to be able to be selected. /** Conditions that must be false for a move to be able to be selected.
* *
=======
/**
* Conditions that must be false for a move to be able to be selected.
*
>>>>>>> 02f941b3a05 (PR review changes)
* @remarks Different from {@linkcode conditions}, which is checked when the move is invoked * @remarks Different from {@linkcode conditions}, which is checked when the move is invoked
*/ */
private restrictions: MoveRestriction[] = []; private restrictions: MoveRestriction[] = [];
@ -452,7 +458,7 @@ export abstract class Move implements Localizable {
* @returns `this` for method chaining * @returns `this` for method chaining
*/ */
public restriction(restriction: MoveRestriction): this; public restriction(restriction: MoveRestriction): this;
/** /**
* Adds a restriction condition to this move. * Adds a restriction condition to this move.
* The move will not be selectable if at least 1 of its restrictions is met. * The move will not be selectable if at least 1 of its restrictions is met.
* @param restriction - The function or `MoveRestriction` that evaluates to `true` if the move is restricted from * @param restriction - The function or `MoveRestriction` that evaluates to `true` if the move is restricted from
@ -476,7 +482,12 @@ export abstract class Move implements Localizable {
* is false * is false
* @returns `this` for method chaining * @returns `this` for method chaining
*/ */
public restriction<T extends UserMoveConditionFunc | MoveRestriction>(restriction: T, i18nkey?: string, alsoCondition: typeof restriction extends MoveRestriction ? false : boolean = false, conditionSeq = 4): this { public restriction<T extends UserMoveConditionFunc | MoveRestriction>(
restriction: T,
i18nkey?: string,
alsoCondition: typeof restriction extends MoveRestriction ? false : boolean = false,
conditionSeq = 4,
): this {
if (typeof restriction === "function") { if (typeof restriction === "function") {
this.restrictions.push(new MoveRestriction(restriction)); this.restrictions.push(new MoveRestriction(restriction));
if (alsoCondition) { if (alsoCondition) {
@ -700,7 +711,7 @@ export abstract class Move implements Localizable {
} }
/** /**
* Sets the {@linkcode MoveFlags.GRAVITY} flag for the calling Move and adds {@linkcode GravityUseRestriction} to the * Sets the {@linkcode MoveFlags.GRAVITY} flag for the calling Move and adds {@linkcode gravityUseRestriction} to the
* move's restrictions. * move's restrictions.
* *
* @returns `this` * @returns `this`
@ -713,7 +724,7 @@ export abstract class Move implements Localizable {
*/ */
affectedByGravity(): this { affectedByGravity(): this {
this.setFlag(MoveFlags.GRAVITY, true); this.setFlag(MoveFlags.GRAVITY, true);
this.restrictions.push(GravityUseRestriction); this.restrictions.push(gravityUseRestriction);
return this; return this;
} }
@ -859,9 +870,9 @@ export abstract class Move implements Localizable {
* *
* @param user - The Pokemon using the move * @param user - The Pokemon using the move
* @returns - An array whose first element is `false` if the move is restricted, and the second element is a string * @returns - An array whose first element is `false` if the move is restricted, and the second element is a string
* with the reason for the restriction, otherwise, `false` and the empty string. * with the reason for the restriction, otherwise, `true` and the empty string.
*/ */
public checkRestrictions(user: Pokemon): [boolean, string] { public checkRestrictions(user: Pokemon): [isUsable: boolean, restrictionMessage: string] {
for (const restriction of this.restrictions) { for (const restriction of this.restrictions) {
if (restriction.apply(user, this)) { if (restriction.apply(user, this)) {
return [false, restriction.getSelectionDeniedText(user, this)]; return [false, restriction.getSelectionDeniedText(user, this)];
@ -10034,7 +10045,6 @@ export function initMoves() {
.condition((_user, target, _move) => target.getTag(BattlerTagType.INGRAIN) == null && target.getTag(BattlerTagType.IGNORE_FLYING) == null) .condition((_user, target, _move) => target.getTag(BattlerTagType.INGRAIN) == null && target.getTag(BattlerTagType.IGNORE_FLYING) == null)
.attr(AddBattlerTagAttr, BattlerTagType.TELEKINESIS, false, true, 3) .attr(AddBattlerTagAttr, BattlerTagType.TELEKINESIS, false, true, 3)
.attr(AddBattlerTagAttr, BattlerTagType.FLOATING, false, true, 3) .attr(AddBattlerTagAttr, BattlerTagType.FLOATING, false, true, 3)
.affectedByGravity()
.reflectable(), .reflectable(),
new StatusMove(MoveId.MAGIC_ROOM, PokemonType.PSYCHIC, -1, 10, -1, 0, 5) new StatusMove(MoveId.MAGIC_ROOM, PokemonType.PSYCHIC, -1, 10, -1, 0, 5)
.ignoresProtect() .ignoresProtect()
@ -10677,10 +10687,7 @@ export function initMoves() {
.attr(HealOnAllyAttr, 0.5, true, false) .attr(HealOnAllyAttr, 0.5, true, false)
.ballBombMove() .ballBombMove()
// Fail if used against an ally that is affected by heal block, during the second failure check // Fail if used against an ally that is affected by heal block, during the second failure check
.condition( .condition((user, target) => target.isOpponent(user) || !!target.getTag(BattlerTagType.HEAL_BLOCK), 2),
(user, target) => target.isOpponent(user) || !!target.getTag(BattlerTagType.HEAL_BLOCK),
2
),
new AttackMove(MoveId.ANCHOR_SHOT, PokemonType.STEEL, MoveCategory.PHYSICAL, 80, 100, 20, 100, 0, 7) new AttackMove(MoveId.ANCHOR_SHOT, PokemonType.STEEL, MoveCategory.PHYSICAL, 80, 100, 20, 100, 0, 7)
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1, 1, true), .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1, 1, true),
new StatusMove(MoveId.PSYCHIC_TERRAIN, PokemonType.PSYCHIC, -1, 10, -1, 0, 7) new StatusMove(MoveId.PSYCHIC_TERRAIN, PokemonType.PSYCHIC, -1, 10, -1, 0, 7)
@ -10693,11 +10700,8 @@ export function initMoves() {
new AttackMove(MoveId.POWER_TRIP, PokemonType.DARK, MoveCategory.PHYSICAL, 20, 100, 10, -1, 0, 7) new AttackMove(MoveId.POWER_TRIP, PokemonType.DARK, MoveCategory.PHYSICAL, 20, 100, 10, -1, 0, 7)
.attr(PositiveStatStagePowerAttr), .attr(PositiveStatStagePowerAttr),
new AttackMove(MoveId.BURN_UP, PokemonType.FIRE, MoveCategory.SPECIAL, 130, 100, 5, -1, 0, 7) new AttackMove(MoveId.BURN_UP, PokemonType.FIRE, MoveCategory.SPECIAL, 130, 100, 5, -1, 0, 7)
.condition( // Pass `true` to `ForDefend` as it should fail if the user is terastallized to a type that is not FIRE
// Pass `true` to `ForDefend` as it should fail if the user is terastallized to a type that is not FIRE .condition(user => user.isOfType(PokemonType.FIRE, true, true), 2)
user => user.isOfType(PokemonType.FIRE, true, true),
2
)
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
.attr(AddBattlerTagAttr, BattlerTagType.BURNED_UP, true, false) .attr(AddBattlerTagAttr, BattlerTagType.BURNED_UP, true, false)
.attr(RemoveTypeAttr, PokemonType.FIRE, (user) => { .attr(RemoveTypeAttr, PokemonType.FIRE, (user) => {
@ -10798,10 +10802,7 @@ export function initMoves() {
.attr(AddBattlerTagHeaderAttr, BattlerTagType.SHELL_TRAP) .attr(AddBattlerTagHeaderAttr, BattlerTagType.SHELL_TRAP)
.target(MoveTarget.ALL_NEAR_ENEMIES) .target(MoveTarget.ALL_NEAR_ENEMIES)
// Fails if the user was not hit by a physical attack during the turn // Fails if the user was not hit by a physical attack during the turn
.condition( .condition(user => user.getTag(ShellTrapTag)?.activated === true, 3),
user => user.getTag(ShellTrapTag)?.activated === true,
3
),
new AttackMove(MoveId.FLEUR_CANNON, PokemonType.FAIRY, MoveCategory.SPECIAL, 130, 90, 5, -1, 0, 7) new AttackMove(MoveId.FLEUR_CANNON, PokemonType.FAIRY, MoveCategory.SPECIAL, 130, 90, 5, -1, 0, 7)
.attr(StatStageChangeAttr, [ Stat.SPATK ], -2, true), .attr(StatStageChangeAttr, [ Stat.SPATK ], -2, true),
new AttackMove(MoveId.PSYCHIC_FANGS, PokemonType.PSYCHIC, MoveCategory.PHYSICAL, 85, 100, 10, -1, 0, 7) new AttackMove(MoveId.PSYCHIC_FANGS, PokemonType.PSYCHIC, MoveCategory.PHYSICAL, 85, 100, 10, -1, 0, 7)
@ -10949,11 +10950,8 @@ export function initMoves() {
new SelfStatusMove(MoveId.NO_RETREAT, PokemonType.FIGHTING, -1, 5, -1, 0, 8) new SelfStatusMove(MoveId.NO_RETREAT, PokemonType.FIGHTING, -1, 5, -1, 0, 8)
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true)
.attr(AddBattlerTagAttr, BattlerTagType.NO_RETREAT, true, true /* NOT ADDED if already trapped */) .attr(AddBattlerTagAttr, BattlerTagType.NO_RETREAT, true, true /* NOT ADDED if already trapped */)
.condition( // fails if the user is currently trapped specifically from no retreat
// fails if the user is currently trapped specifically from no retreat .condition(user => user.getTag(TrappedTag)?.tagType !== BattlerTagType.NO_RETREAT, 2),
user => user.getTag(TrappedTag)?.tagType !== BattlerTagType.NO_RETREAT,
2
),
new StatusMove(MoveId.TAR_SHOT, PokemonType.ROCK, 100, 15, -1, 0, 8) new StatusMove(MoveId.TAR_SHOT, PokemonType.ROCK, 100, 15, -1, 0, 8)
.attr(StatStageChangeAttr, [ Stat.SPD ], -1) .attr(StatStageChangeAttr, [ Stat.SPD ], -1)
.attr(AddBattlerTagAttr, BattlerTagType.TAR_SHOT, false) .attr(AddBattlerTagAttr, BattlerTagType.TAR_SHOT, false)
@ -11515,18 +11513,15 @@ export function initMoves() {
.slicingMove() .slicingMove()
.triageMove(), .triageMove(),
new AttackMove(MoveId.DOUBLE_SHOCK, PokemonType.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 9) new AttackMove(MoveId.DOUBLE_SHOCK, PokemonType.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 9)
.condition( // Pass `true` to `isOfType` to fail if the user is terastallized to a type other than ELECTRIC
// Pass `true` to `isOfType` to fail if the user is terastallized to a type other than ELECTRIC .condition(user => user.isOfType(PokemonType.ELECTRIC, true, true), 2)
user => user.isOfType(PokemonType.ELECTRIC, true, true),
2
)
.attr(AddBattlerTagAttr, BattlerTagType.DOUBLE_SHOCKED, true, false) .attr(AddBattlerTagAttr, BattlerTagType.DOUBLE_SHOCKED, true, false)
.attr(RemoveTypeAttr, PokemonType.ELECTRIC, (user) => { .attr(RemoveTypeAttr, PokemonType.ELECTRIC, (user) => {
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", { pokemonName: getPokemonNameWithAffix(user) })); globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", { pokemonName: getPokemonNameWithAffix(user) }));
}), }),
new AttackMove(MoveId.GIGATON_HAMMER, PokemonType.STEEL, MoveCategory.PHYSICAL, 160, 100, 5, -1, 0, 9) new AttackMove(MoveId.GIGATON_HAMMER, PokemonType.STEEL, MoveCategory.PHYSICAL, 160, 100, 5, -1, 0, 9)
.makesContact(false) .makesContact(false)
.restriction(ConsecutiveUseRestriction), .restriction(consecutiveUseRestriction),
new AttackMove(MoveId.COMEUPPANCE, PokemonType.DARK, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 9) new AttackMove(MoveId.COMEUPPANCE, PokemonType.DARK, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 9)
.attr(CounterDamageAttr, 1.5) .attr(CounterDamageAttr, 1.5)
.attr(CounterRedirectAttr) .attr(CounterRedirectAttr)
@ -11552,7 +11547,7 @@ export function initMoves() {
.attr(ConfuseAttr) .attr(ConfuseAttr)
.makesContact(false), .makesContact(false),
new AttackMove(MoveId.BLOOD_MOON, PokemonType.NORMAL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 9) new AttackMove(MoveId.BLOOD_MOON, PokemonType.NORMAL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 9)
.restriction(ConsecutiveUseRestriction), .restriction(consecutiveUseRestriction),
new AttackMove(MoveId.MATCHA_GOTCHA, PokemonType.GRASS, MoveCategory.SPECIAL, 80, 90, 15, 20, 0, 9) new AttackMove(MoveId.MATCHA_GOTCHA, PokemonType.GRASS, MoveCategory.SPECIAL, 80, 90, 15, 20, 0, 9)
.attr(HitHealAttr) .attr(HitHealAttr)
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
@ -11613,7 +11608,7 @@ export function initMoves() {
.attr(AddBattlerTagAttr, BattlerTagType.HEAL_BLOCK, false, false, 2), .attr(AddBattlerTagAttr, BattlerTagType.HEAL_BLOCK, false, false, 2),
new AttackMove(MoveId.UPPER_HAND, PokemonType.FIGHTING, MoveCategory.PHYSICAL, 65, 100, 15, 100, 3, 9) new AttackMove(MoveId.UPPER_HAND, PokemonType.FIGHTING, MoveCategory.PHYSICAL, 65, 100, 15, 100, 3, 9)
.attr(FlinchAttr) .attr(FlinchAttr)
.condition(UpperHandCondition, 3), .condition(upperHandCondition, 3),
new AttackMove(MoveId.MALIGNANT_CHAIN, PokemonType.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9) new AttackMove(MoveId.MALIGNANT_CHAIN, PokemonType.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9)
.attr(StatusEffectAttr, StatusEffect.TOXIC) .attr(StatusEffectAttr, StatusEffect.TOXIC)
); );

View File

@ -3138,7 +3138,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @param ignorePp - Whether to ignore PP when checking if the move is usable (defaults to false) * @param ignorePp - Whether to ignore PP when checking if the move is usable (defaults to false)
* @returns A tuple containing a boolean indicating if the move can be selected, and a string with the reason if it cannot be selected * @returns A tuple containing a boolean indicating if the move can be selected, and a string with the reason if it cannot be selected
*/ */
public trySelectMove(moveIndex: number, ignorePp?: boolean): [boolean, string] { public trySelectMove(moveIndex: number, ignorePp?: boolean): [isUsable: boolean, failureMessage: string] {
const move = this.getMoveset().length > moveIndex ? this.getMoveset()[moveIndex] : null; const move = this.getMoveset().length > moveIndex ? this.getMoveset()[moveIndex] : null;
return move?.isUsable(this, ignorePp, true) ?? [false, ""]; return move?.isUsable(this, ignorePp, true) ?? [false, ""];
} }

View File

@ -1,3 +1,7 @@
// biome-ignore-start lint/correctness/noUnusedImports: Used in a tsdoc comment
import type { Move, PreUseInterruptAttr } from "#types/move-types";
// biome-ignore-end lint/correctness/noUnusedImports: Used in a tsdoc comment
import { applyAbAttrs } from "#abilities/apply-ab-attrs"; import { applyAbAttrs } from "#abilities/apply-ab-attrs";
import { MOVE_COLOR } from "#app/constants/colors"; import { MOVE_COLOR } from "#app/constants/colors";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
@ -28,8 +32,6 @@ import type { Pokemon } from "#field/pokemon";
import { applyMoveAttrs } from "#moves/apply-attrs"; import { applyMoveAttrs } from "#moves/apply-attrs";
import { frenzyMissFunc } from "#moves/move-utils"; import { frenzyMissFunc } from "#moves/move-utils";
import type { PokemonMove } from "#moves/pokemon-move"; import type { PokemonMove } from "#moves/pokemon-move";
// biome-ignore lint/correctness/noUnusedImports: Used in a tsdoc comment
import type { Move, PreUseInterruptAttr } from "#types/move-types";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
import { BooleanHolder, NumberHolder } from "#utils/common"; import { BooleanHolder, NumberHolder } from "#utils/common";
import { enumValueToKey } from "#utils/enums"; import { enumValueToKey } from "#utils/enums";
@ -205,7 +207,7 @@ export class MovePhase extends PokemonPhase {
* *
* @remarks * @remarks
* Other than powder, each failure condition is mutually exclusive (as they are tied to specific moves), so order does not matter. * Other than powder, each failure condition is mutually exclusive (as they are tied to specific moves), so order does not matter.
* Notably, this failure check only includes failure conditions intrinsic to the move itself, ther than Powder (which marks the end of this failure check) * Notably, this failure check only includes failure conditions intrinsic to the move itself, other than Powder (which marks the end of this failure check)
* *
* *
* - Pollen puff used on an ally that is under effect of heal block * - Pollen puff used on an ally that is under effect of heal block
@ -512,13 +514,14 @@ export class MovePhase extends PokemonPhase {
* - Checking if the pokemon will thaw from random chance, OR from a thawing move. * - Checking if the pokemon will thaw from random chance, OR from a thawing move.
* Thawing from a freeze move is not applied until AFTER all other failure checks. * Thawing from a freeze move is not applied until AFTER all other failure checks.
* - Activating the freeze status effect (cancelling the move, playing the message, and displaying the animation) * - Activating the freeze status effect (cancelling the move, playing the message, and displaying the animation)
* @returns Whether the move was cancelled due to the pokemon being frozen
*/ */
protected checkFreeze(): boolean { protected checkFreeze(): boolean {
if (this.pokemon.status?.effect !== StatusEffect.FREEZE) { if (this.pokemon.status?.effect !== StatusEffect.FREEZE) {
return false; return false;
} }
// For some reason, dancer will immediately its user // For some reason, dancer will immediately thaw its user
if (this.useMode === MoveUseMode.INDIRECT) { if (this.useMode === MoveUseMode.INDIRECT) {
this.pokemon.resetStatus(false); this.pokemon.resetStatus(false);
return false; return false;
@ -644,6 +647,7 @@ export class MovePhase extends PokemonPhase {
* Lapse the tag type and check if the move is cancelled from it. Meant to be used during the first failure check * Lapse the tag type and check if the move is cancelled from it. Meant to be used during the first failure check
* @param tag - The tag type whose lapse method will be called with {@linkcode BattlerTagLapseType.PRE_MOVE} * @param tag - The tag type whose lapse method will be called with {@linkcode BattlerTagLapseType.PRE_MOVE}
* @param checkIgnoreStatus - Whether to check {@link isIgnoreStatus} for the current {@linkcode MoveUseMode} to skip this check * @param checkIgnoreStatus - Whether to check {@link isIgnoreStatus} for the current {@linkcode MoveUseMode} to skip this check
* @returns Whether the move was cancelled due to a `BattlerTag` effect
*/ */
private checkTagCancel(tag: BattlerTagType): boolean { private checkTagCancel(tag: BattlerTagType): boolean {
this.pokemon.lapseTag(tag, BattlerTagLapseType.PRE_MOVE); this.pokemon.lapseTag(tag, BattlerTagLapseType.PRE_MOVE);
@ -652,7 +656,7 @@ export class MovePhase extends PokemonPhase {
/** /**
* Handle move failures due to Gravity, cancelling the move and showing the failure text * Handle move failures due to Gravity, cancelling the move and showing the failure text
* @returns - Whether the move was cancelled due to Gravity * @returns Whether the move was cancelled due to Gravity
*/ */
private checkGravity(): boolean { private checkGravity(): boolean {
const move = this.move.getMove(); const move = this.move.getMove();

View File

@ -1,11 +1,13 @@
// biome-ignore-start lint/correctness/noUnusedImports: Used in a TSDoc comment
import type { Pokemon } from "#field/pokemon";
// biome-ignore-end lint/correctness/noUnusedImports: Used in a TSDoc comment
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { POKERUS_STARTER_COUNT, speciesStarterCosts } from "#balance/starters"; import { POKERUS_STARTER_COUNT, speciesStarterCosts } from "#balance/starters";
import { allSpecies } from "#data/data-lists"; import { allSpecies } from "#data/data-lists";
import type { PokemonSpecies, PokemonSpeciesForm } from "#data/pokemon-species"; import type { PokemonSpecies, PokemonSpeciesForm } from "#data/pokemon-species";
import { BattlerIndex } from "#enums/battler-index"; import { BattlerIndex } from "#enums/battler-index";
import type { SpeciesId } from "#enums/species-id"; import type { SpeciesId } from "#enums/species-id";
// biome-ignore lint/correctness/noUnusedImports: Used in a TSDoc comment
import type { Pokemon } from "#field/pokemon";
import { randSeedItem } from "./common"; import { randSeedItem } from "./common";
/** /**

View File

@ -90,7 +90,7 @@ describe("Moves - Dig", () => {
expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS);
}); });
it("should expend PP when the attack phase is cancelled", async () => { it("should expend PP when the attack phase is cancelled by sleep", async () => {
game.override.enemyAbility(AbilityId.NO_GUARD).enemyMoveset(MoveId.SPORE); game.override.enemyAbility(AbilityId.NO_GUARD).enemyMoveset(MoveId.SPORE);
await game.classicMode.startBattle([SpeciesId.MAGIKARP]); await game.classicMode.startBattle([SpeciesId.MAGIKARP]);

View File

@ -74,7 +74,7 @@ describe("Moves - Dive", () => {
expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); expect(enemyPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS);
}); });
it("should expend PP when the attack phase is cancelled", async () => { it("should expend PP when the attack phase is cancelled by sleep", async () => {
game.override.enemyAbility(AbilityId.NO_GUARD).enemyMoveset(MoveId.SPORE); game.override.enemyAbility(AbilityId.NO_GUARD).enemyMoveset(MoveId.SPORE);
await game.classicMode.startBattle([SpeciesId.MAGIKARP]); await game.classicMode.startBattle([SpeciesId.MAGIKARP]);

View File

@ -84,7 +84,7 @@ describe("UI - Type Hints", () => {
await game.phaseInterceptor.to("CommandPhase"); await game.phaseInterceptor.to("CommandPhase");
}); });
it("should show the proper hint for a move in doubles after one of the enemy pokemon flees", async () => { it("should show the proper hint for a move in doubles after one of the enemy pokemon faints", async () => {
game.override game.override
.enemySpecies(SpeciesId.ABRA) .enemySpecies(SpeciesId.ABRA)
.moveset([MoveId.SPLASH, MoveId.SHADOW_BALL, MoveId.SOAK]) .moveset([MoveId.SPLASH, MoveId.SHADOW_BALL, MoveId.SOAK])