diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index cd7c7a8f48f..7bf84a2f6d5 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -120,14 +120,8 @@ export class MovePhase extends BattlePhase { console.log(MoveId[this.move.moveId], enumValueToKey(MoveUseMode, this.useMode)); - // Check if move is unusable (e.g. running out of PP due to a mid-turn Spite - // or the user no longer being on field), ending the phase early if not. - if (!this.canMove(true)) { - if (this.pokemon.isActive(true)) { - this.fail(); - this.showMoveText(); - this.showFailedText(); - } + if (!this.pokemon.isActive(true)) { + this.cancel(); this.end(); return; } @@ -155,6 +149,7 @@ export class MovePhase extends BattlePhase { this.resolveCounterAttackTarget(); + // Check status cancellation from sleep, freeze, etc. this.resolvePreMoveStatusEffects(); this.lapsePreMoveAndMoveTags(); @@ -180,6 +175,18 @@ export class MovePhase extends BattlePhase { const targets = this.getActiveTargetPokemon(); const moveQueue = this.pokemon.getMoveQueue(); + // Check if move is unusable (e.g. running out of PP due to a mid-turn Spite + // or the user no longer being on field) + + if (!this.canMove(true)) { + if (this.pokemon.isActive(true)) { + this.fail(); + this.showMoveText(); + this.showFailedText(); + } + return; + } + if ( (targets.length === 0 && !this.move.getMove().hasAttr("AddArenaTrapTagAttr")) || (moveQueue.length > 0 && moveQueue[0].move === MoveId.NONE) diff --git a/test/data/status-effect.test.ts b/test/data/status-effect.test.ts index ebfd9066b3c..70c29782e6e 100644 --- a/test/data/status-effect.test.ts +++ b/test/data/status-effect.test.ts @@ -353,7 +353,7 @@ describe("Status Effects", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([MoveId.SPLASH]) + .moveset([MoveId.SPLASH, MoveId.DRAGON_CHEER]) .ability(AbilityId.BALL_FETCH) .battleStyle("single") .criticalHits(false) @@ -390,6 +390,35 @@ describe("Status Effects", () => { expect(player.status).toBeFalsy(); expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.SUCCESS); }); + + it("Sleep turns should tick down when failing to use ally-targeting moves", async () => { + await game.classicMode.startBattle([SpeciesId.FEEBAS]); + + const player = game.field.getPlayerPokemon(); + player.status = new Status(StatusEffect.SLEEP, 0, 4); + + game.move.select(MoveId.DRAGON_CHEER); + await game.toNextTurn(); + + expect(player.status.effect).toBe(StatusEffect.SLEEP); + + game.move.select(MoveId.DRAGON_CHEER); + await game.toNextTurn(); + + expect(player.status.effect).toBe(StatusEffect.SLEEP); + + game.move.select(MoveId.DRAGON_CHEER); + await game.toNextTurn(); + + expect(player.status.effect).toBe(StatusEffect.SLEEP); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + + game.move.select(MoveId.DRAGON_CHEER); + await game.toNextTurn(); + + expect(player.status).toBeFalsy(); + expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); + }); }); describe("Behavior", () => {