mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-30 21:42:20 +02:00
WIP
This commit is contained in:
parent
da6443562b
commit
4bac0ed3ec
@ -4454,10 +4454,10 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
|
|||||||
// TODO: fix in main dancer PR (currently keeping this purely semantic rather than actually fixing bug)
|
// TODO: fix in main dancer PR (currently keeping this purely semantic rather than actually fixing bug)
|
||||||
if (move.getMove() instanceof AttackMove || move.getMove() instanceof StatusMove) {
|
if (move.getMove() instanceof AttackMove || move.getMove() instanceof StatusMove) {
|
||||||
const target = this.getTarget(dancer, source, targets);
|
const target = this.getTarget(dancer, source, targets);
|
||||||
globalScene.unshiftPhase(new MovePhase(dancer, target, move, MoveUseType.FOLLOW_UP));
|
globalScene.unshiftPhase(new MovePhase(dancer, target, move, MoveUseType.INDIRECT));
|
||||||
} else if (move.getMove() instanceof SelfStatusMove) {
|
} else if (move.getMove() instanceof SelfStatusMove) {
|
||||||
// If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself
|
// If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself
|
||||||
globalScene.unshiftPhase(new MovePhase(dancer, [ dancer.getBattlerIndex() ], move, MoveUseType.FOLLOW_UP))
|
globalScene.unshiftPhase(new MovePhase(dancer, [ dancer.getBattlerIndex() ], move, MoveUseType.INDIRECT))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,8 @@ export class DisabledTag extends MoveRestrictionBattlerTag {
|
|||||||
* and showing a message.
|
* and showing a message.
|
||||||
*/
|
*/
|
||||||
override onAdd(pokemon: Pokemon): void {
|
override onAdd(pokemon: Pokemon): void {
|
||||||
// Disable fails against struggle or an empty move history
|
// Disable fails against struggle or an empty move history, but we still need to check for
|
||||||
|
// Cursed Body
|
||||||
const move = pokemon.getLastNonVirtualMove();
|
const move = pokemon.getLastNonVirtualMove();
|
||||||
if (isNullOrUndefined(move) || move.move === Moves.STRUGGLE) {
|
if (isNullOrUndefined(move) || move.move === Moves.STRUGGLE) {
|
||||||
return;
|
return;
|
||||||
|
@ -5419,9 +5419,13 @@ export class FrenzyAttr extends MoveEffectAttr {
|
|||||||
// TODO: Disable if used via dancer
|
// TODO: Disable if used via dancer
|
||||||
// TODO: Add support for moves that don't add the frenzy tag (Uproar, Rollout, etc.)
|
// TODO: Add support for moves that don't add the frenzy tag (Uproar, Rollout, etc.)
|
||||||
|
|
||||||
if (!user.getTag(BattlerTagType.FRENZY) && !user.getMoveQueue().length) {
|
// If frenzy is not active, add a tag and push 1-2 extra turns of attacks to the user's move queue.
|
||||||
|
// Otherwise, tick down the existing tag.
|
||||||
|
if (!user.getTag(BattlerTagType.FRENZY) && user.getMoveQueue().length === 0) {
|
||||||
const turnCount = user.randSeedIntRange(1, 2);
|
const turnCount = user.randSeedIntRange(1, 2);
|
||||||
new Array(turnCount).fill(null).map(() => user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true }));
|
for (let x = 0; x < turnCount; x++) {
|
||||||
|
user.pushMoveQueue({move: move.id, targets: [target.getBattlerIndex()], useType: MoveUseType.IGNORE_PP})
|
||||||
|
}
|
||||||
user.addTag(BattlerTagType.FRENZY, turnCount, move.id, user.id);
|
user.addTag(BattlerTagType.FRENZY, turnCount, move.id, user.id);
|
||||||
} else {
|
} else {
|
||||||
applyMoveAttrs(AddBattlerTagAttr, user, target, move, args);
|
applyMoveAttrs(AddBattlerTagAttr, user, target, move, args);
|
||||||
@ -6746,7 +6750,9 @@ class CallMoveAttr extends OverrideMoveEffectAttr {
|
|||||||
// If not, target the Mirror Move recipient or else a random enemy in our target list
|
// If not, target the Mirror Move recipient or else a random enemy in our target list
|
||||||
const targets = moveTargets.multiple || moveTargets.targets.length === 1
|
const targets = moveTargets.multiple || moveTargets.targets.length === 1
|
||||||
? moveTargets.targets
|
? moveTargets.targets
|
||||||
: [ this.hasTarget ? target.getBattlerIndex() : moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ]; // account for Mirror Move having a target already
|
: [this.hasTarget
|
||||||
|
? target.getBattlerIndex()
|
||||||
|
: moveTargets.targets[user.randSeedInt(moveTargets.targets.length)]];
|
||||||
globalScene.unshiftPhase(new LoadMoveAnimPhase(move.id));
|
globalScene.unshiftPhase(new LoadMoveAnimPhase(move.id));
|
||||||
globalScene.unshiftPhase(new MovePhase(user, targets, new PokemonMove(move.id), MoveUseType.FOLLOW_UP));
|
globalScene.unshiftPhase(new MovePhase(user, targets, new PokemonMove(move.id), MoveUseType.FOLLOW_UP));
|
||||||
return true;
|
return true;
|
||||||
@ -7083,6 +7089,7 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||||||
Moves.PETAL_DANCE,
|
Moves.PETAL_DANCE,
|
||||||
Moves.THRASH,
|
Moves.THRASH,
|
||||||
Moves.ICE_BALL,
|
Moves.ICE_BALL,
|
||||||
|
Moves.UPROAR,
|
||||||
// Multi-turn Moves
|
// Multi-turn Moves
|
||||||
Moves.BIDE,
|
Moves.BIDE,
|
||||||
Moves.SHELL_TRAP,
|
Moves.SHELL_TRAP,
|
||||||
@ -7120,8 +7127,17 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||||||
Moves.SOLAR_BEAM,
|
Moves.SOLAR_BEAM,
|
||||||
Moves.SOLAR_BLADE,
|
Moves.SOLAR_BLADE,
|
||||||
Moves.METEOR_BEAM,
|
Moves.METEOR_BEAM,
|
||||||
// Other moves
|
// Copying/Move-Calling moves
|
||||||
|
Moves.ASSIST,
|
||||||
|
Moves.COPYCAT,
|
||||||
|
Moves.ME_FIRST,
|
||||||
|
Moves.METRONOME,
|
||||||
|
Moves.MIRROR_MOVE,
|
||||||
|
Moves.NATURE_POWER,
|
||||||
|
Moves.SLEEP_TALK,
|
||||||
|
Moves.SNATCH,
|
||||||
Moves.INSTRUCT,
|
Moves.INSTRUCT,
|
||||||
|
// Misc moves
|
||||||
Moves.KINGS_SHIELD,
|
Moves.KINGS_SHIELD,
|
||||||
Moves.SKETCH,
|
Moves.SKETCH,
|
||||||
Moves.TRANSFORM,
|
Moves.TRANSFORM,
|
||||||
@ -7132,7 +7148,8 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
if (!lastMove?.move // no move to instruct
|
if (!lastMove?.move // no move to instruct
|
||||||
|| !movesetMove // called move not in target's moveset (forgetting the move, etc.)
|
|| !movesetMove // called move not in target's moveset (forgetting the move, etc.)
|
||||||
|| !movesetMove.isUsable(target) // Move unusable due to PP shortage or similar
|
|| movesetMove.ppUsed === movesetMove.getMovePp() // move out of pp
|
||||||
|
|| allMoves[lastMove.move].isChargingMove() // called move is a charging/recharging move
|
||||||
|| uninstructableMoves.includes(lastMove.move)) { // called move is in the banlist
|
|| uninstructableMoves.includes(lastMove.move)) { // called move is in the banlist
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -15,22 +15,23 @@ export enum MoveUseType {
|
|||||||
NORMAL,
|
NORMAL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identical to {@linkcode MoveUseType.NORMAL}, except the move **does not consume PP** on use
|
* This move was called by an effect that ignores PP, such as a consecutively executed move.
|
||||||
* and **will not fail** if none is left before its execution.
|
* Identical to {@linkcode MoveUseType.NORMAL}, except the move **does not consume PP** on use
|
||||||
* PP can still be reduced by other effects (such as Spite or Eerie Spell).
|
* and **will not fail** if none is left before its execution.
|
||||||
*/
|
* PP can still be reduced by other effects (such as Spite or Eerie Spell).
|
||||||
|
*/
|
||||||
IGNORE_PP,
|
IGNORE_PP,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This move was called indirectly by another effect other than Instruct or the user's previous move.
|
* This move was called indirectly by an out-of-turn effect other than Instruct or the user's previous move.
|
||||||
* Currently only used by {@linkcode PostDancingMoveAbAttr | Dancer}.
|
* Currently only used by {@linkcode PostDancingMoveAbAttr | Dancer}.
|
||||||
|
|
||||||
* Indirect moves ignore PP checks similar to {@linkcode MoveUseType.IGNORE_PP}, but additionally **cannot be copied**
|
* Indirect moves ignore PP checks similar to {@linkcode MoveUseType.IGNORE_PP}, but additionally **cannot be copied**
|
||||||
* by all move-copying effects (barring reflection).
|
* by all move-copying effects (barring reflection).
|
||||||
* They are also **"skipped over" by most moveset and move history-related effects** (PP reduction, Last Resort, etc).
|
* They are also **"skipped over" by most moveset and move history-related effects** (PP reduction, Last Resort, etc).
|
||||||
|
|
||||||
* They still respect the user's volatile status conditions and confusion (though will uniquely _cure freeze and sleep before use_).
|
* They still respect the user's volatile status conditions and confusion (though will uniquely _cure freeze and sleep before use_).
|
||||||
*/
|
*/
|
||||||
INDIRECT,
|
INDIRECT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,3 +57,9 @@ export enum MoveUseType {
|
|||||||
*/
|
*/
|
||||||
REFLECTED
|
REFLECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comment block to prevent auto-import removal.
|
||||||
|
* {@linkcode BattlerTagLapseType}
|
||||||
|
* {@linkcode PostDancingMoveAbAttr}
|
||||||
|
*/
|
@ -86,6 +86,8 @@ export class MoveChargePhase extends PokemonPhase {
|
|||||||
result: MoveResult.OTHER,
|
result: MoveResult.OTHER,
|
||||||
useType: this.useType,
|
useType: this.useType,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
super.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUserPokemon(): Pokemon {
|
public getUserPokemon(): Pokemon {
|
||||||
|
@ -150,7 +150,8 @@ export class MovePhase extends BattlePhase {
|
|||||||
|
|
||||||
console.log(Moves[this.move.moveId], MoveUseType[this.useType]);
|
console.log(Moves[this.move.moveId], MoveUseType[this.useType]);
|
||||||
|
|
||||||
// Check if move is unusable (e.g. because it's out of PP due to a mid-turn Spite).
|
// 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.canMove(true)) {
|
||||||
if (this.pokemon.isActive(true)) {
|
if (this.pokemon.isActive(true)) {
|
||||||
this.fail();
|
this.fail();
|
||||||
@ -241,6 +242,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.pokemon.status.incrementTurn();
|
||||||
/** Whether to prevent us from using the move */
|
/** Whether to prevent us from using the move */
|
||||||
let activated = false;
|
let activated = false;
|
||||||
/** Whether to cure the status */
|
/** Whether to cure the status */
|
||||||
|
@ -41,6 +41,7 @@ describe("Abilities - Early Bird", () => {
|
|||||||
|
|
||||||
game.move.select(Moves.BELLY_DRUM);
|
game.move.select(Moves.BELLY_DRUM);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
game.move.select(Moves.REST);
|
game.move.select(Moves.REST);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ describe("Moves - After You", () => {
|
|||||||
|
|
||||||
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||||
game.move.select(Moves.OUTRAGE, BattlerIndex.PLAYER_2);
|
game.move.select(Moves.OUTRAGE, BattlerIndex.PLAYER_2);
|
||||||
await game.toNextTurn();
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
|
||||||
const outrageMove = rattata.getMoveset().find(m => m.moveId === Moves.OUTRAGE);
|
const outrageMove = rattata.getMoveset().find(m => m.moveId === Moves.OUTRAGE);
|
||||||
expect(outrageMove?.ppUsed).toBe(1);
|
expect(outrageMove?.ppUsed).toBe(1);
|
||||||
|
@ -58,9 +58,11 @@ describe("Moves - Dig", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should deduct PP only on the 2nd turn of the move", async () => {
|
it("should deduct PP only on the 2nd turn of the move", async () => {
|
||||||
|
game.override.moveset([]);
|
||||||
await game.classicMode.startBattle([Species.MAGIKARP]);
|
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||||
|
|
||||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||||
|
game.move.changeMoveset(playerPokemon, Moves.DIG);
|
||||||
|
|
||||||
game.move.select(Moves.DIG);
|
game.move.select(Moves.DIG);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase");
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
@ -48,7 +48,7 @@ describe("Moves - Disable", () => {
|
|||||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
expect(enemyMon.getLastXMoves(-1)).toHaveLength(1);
|
expect(enemyMon.getLastXMoves(-1)).toHaveLength(2);
|
||||||
expect(enemyMon.isMoveRestricted(Moves.SPLASH)).toBe(true);
|
expect(enemyMon.isMoveRestricted(Moves.SPLASH)).toBe(true);
|
||||||
expect(enemyMon.isMoveRestricted(Moves.GROWL)).toBe(false);
|
expect(enemyMon.isMoveRestricted(Moves.GROWL)).toBe(false);
|
||||||
});
|
});
|
||||||
@ -87,7 +87,7 @@ describe("Moves - Disable", () => {
|
|||||||
expect(enemyHistory.map(m => m.move)).toEqual([Moves.STRUGGLE, Moves.SPLASH]);
|
expect(enemyHistory.map(m => m.move)).toEqual([Moves.STRUGGLE, Moves.SPLASH]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("cannot disable STRUGGLE", async () => {
|
it("should fail if it would otherwise disable struggle", async () => {
|
||||||
game.override.enemyMoveset([Moves.STRUGGLE]);
|
game.override.enemyMoveset([Moves.STRUGGLE]);
|
||||||
await game.classicMode.startBattle([Species.PIKACHU]);
|
await game.classicMode.startBattle([Species.PIKACHU]);
|
||||||
|
|
||||||
@ -120,28 +120,29 @@ describe("Moves - Disable", () => {
|
|||||||
|
|
||||||
const enemyHistory = enemyMon.getLastXMoves(-1);
|
const enemyHistory = enemyMon.getLastXMoves(-1);
|
||||||
expect(enemyHistory).toHaveLength(2);
|
expect(enemyHistory).toHaveLength(2);
|
||||||
expect(enemyHistory[0]).toMatchObject({
|
expect(enemyHistory[0].result).toBe(MoveResult.FAIL);
|
||||||
move: Moves.SPLASH,
|
|
||||||
result: MoveResult.FAIL,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
{ name: "Nature Power", moveId: Moves.NATURE_POWER },
|
{ name: "Nature Power", moveId: Moves.NATURE_POWER },
|
||||||
{ name: "Mirror Move", moveId: Moves.MIRROR_MOVE },
|
{ name: "Mirror Move", moveId: Moves.MIRROR_MOVE },
|
||||||
{ name: "Copycat", moveId: Moves.COPYCAT },
|
{ name: "Copycat", moveId: Moves.COPYCAT },
|
||||||
{ name: "Copycat", moveId: Moves.COPYCAT },
|
{ name: "Metronome", moveId: Moves.METRONOME },
|
||||||
])("should ignore virtual moves called by $name", async ({ moveId }) => {
|
])("should ignore virtual moves called by $name", async ({ moveId }) => {
|
||||||
game.override.enemyMoveset(moveId);
|
game.override.enemyMoveset(moveId);
|
||||||
await game.classicMode.startBattle([Species.PIKACHU]);
|
await game.classicMode.startBattle([Species.PIKACHU]);
|
||||||
|
|
||||||
const enemyMon = game.scene.getEnemyPokemon()!;
|
const playerMon = game.scene.getEnemyPokemon()!;
|
||||||
|
playerMon.pushMoveHistory({ move: Moves.SPLASH, targets: [BattlerIndex.ENEMY], useType: MoveUseType.NORMAL });
|
||||||
|
game.scene.currentBattle.lastMove = Moves.SPLASH;
|
||||||
|
|
||||||
game.move.select(Moves.DISABLE);
|
game.move.select(Moves.DISABLE);
|
||||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
const enemyMon = game.scene.getEnemyPokemon()!;
|
||||||
expect.soft(enemyMon.isMoveRestricted(moveId), `calling move ${Moves[moveId]} was not disabled`).toBe(true);
|
expect.soft(enemyMon.isMoveRestricted(moveId), `calling move ${Moves[moveId]} was not disabled`).toBe(true);
|
||||||
|
expect.soft(enemyMon.getLastXMoves(-1)).toHaveLength(2);
|
||||||
const calledMove = enemyMon.getLastXMoves()[0].move;
|
const calledMove = enemyMon.getLastXMoves()[0].move;
|
||||||
expect(
|
expect(
|
||||||
enemyMon.isMoveRestricted(calledMove),
|
enemyMon.isMoveRestricted(calledMove),
|
||||||
@ -154,7 +155,6 @@ describe("Moves - Disable", () => {
|
|||||||
.enemyAbility(Abilities.DANCER)
|
.enemyAbility(Abilities.DANCER)
|
||||||
.moveset([Moves.DISABLE, Moves.SWORDS_DANCE])
|
.moveset([Moves.DISABLE, Moves.SWORDS_DANCE])
|
||||||
.enemyMoveset([Moves.SPLASH, Moves.SWORDS_DANCE]);
|
.enemyMoveset([Moves.SPLASH, Moves.SWORDS_DANCE]);
|
||||||
|
|
||||||
await game.classicMode.startBattle([Species.PIKACHU]);
|
await game.classicMode.startBattle([Species.PIKACHU]);
|
||||||
|
|
||||||
game.move.select(Moves.SWORDS_DANCE);
|
game.move.select(Moves.SWORDS_DANCE);
|
||||||
@ -173,6 +173,6 @@ describe("Moves - Disable", () => {
|
|||||||
expect.soft(shuckle.isMoveRestricted(Moves.SPLASH)).toBe(true);
|
expect.soft(shuckle.isMoveRestricted(Moves.SPLASH)).toBe(true);
|
||||||
expect.soft(shuckle.isMoveRestricted(Moves.SWORDS_DANCE)).toBe(false);
|
expect.soft(shuckle.isMoveRestricted(Moves.SWORDS_DANCE)).toBe(false);
|
||||||
expect(shuckle.getLastXMoves()[0]).toMatchObject({ move: Moves.SWORDS_DANCE, result: MoveResult.SUCCESS });
|
expect(shuckle.getLastXMoves()[0]).toMatchObject({ move: Moves.SWORDS_DANCE, result: MoveResult.SUCCESS });
|
||||||
expect(shuckle.getStatStage(Stat.ATK)).toBe(2);
|
expect(shuckle.getStatStage(Stat.ATK)).toBe(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { RandomMoveAttr } from "#app/data/moves/move";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { MoveResult } from "#app/field/pokemon";
|
import { MoveResult } from "#app/field/pokemon";
|
||||||
import type { MovePhase } from "#app/phases/move-phase";
|
import type { MovePhase } from "#app/phases/move-phase";
|
||||||
@ -8,7 +9,7 @@ import { Moves } from "#enums/moves";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
describe("Moves - Instruct", () => {
|
describe("Moves - Instruct", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
@ -139,6 +140,22 @@ describe("Moves - Instruct", () => {
|
|||||||
expect(game.scene.getPlayerPokemon()!.turnData.attacksReceived.length).toBe(3);
|
expect(game.scene.getPlayerPokemon()!.turnData.attacksReceived.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should fail on metronomed moves, even if also in moveset", async () => {
|
||||||
|
game.override.moveset(Moves.INSTRUCT);
|
||||||
|
vi.spyOn(RandomMoveAttr.prototype, "getMoveOverride").mockReturnValue(Moves.ABSORB);
|
||||||
|
await game.classicMode.startBattle([Species.AMOONGUSS]);
|
||||||
|
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
game.move.changeMoveset(enemy, [Moves.METRONOME, Moves.ABSORB]);
|
||||||
|
|
||||||
|
game.move.select(Moves.INSTRUCT);
|
||||||
|
await game.forceEnemyMove(Moves.METRONOME);
|
||||||
|
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
|
expect(game.scene.getPlayerPokemon()!.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
||||||
|
});
|
||||||
|
|
||||||
it("should respect enemy's status condition", async () => {
|
it("should respect enemy's status condition", async () => {
|
||||||
game.override.moveset([Moves.INSTRUCT, Moves.THUNDER_WAVE]).enemyMoveset(Moves.SONIC_BOOM);
|
game.override.moveset([Moves.INSTRUCT, Moves.THUNDER_WAVE]).enemyMoveset(Moves.SONIC_BOOM);
|
||||||
await game.classicMode.startBattle([Species.AMOONGUSS]);
|
await game.classicMode.startBattle([Species.AMOONGUSS]);
|
||||||
@ -249,15 +266,9 @@ describe("Moves - Instruct", () => {
|
|||||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]);
|
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
expect(game.scene.getPlayerField()[0].getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
|
expect(game.scene.getPlayerPokemon()!.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
|
||||||
const enemyMove = game.scene.getEnemyField()[0]!.getLastXMoves()[0];
|
expect(enemy1.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
||||||
expect(enemyMove.result).toBe(MoveResult.FAIL);
|
expect(enemy1.getMoveset().find(m => m.moveId === Moves.SONIC_BOOM)?.ppUsed).toBe(1);
|
||||||
expect(
|
|
||||||
game.scene
|
|
||||||
.getEnemyField()[0]
|
|
||||||
.getMoveset()
|
|
||||||
.find(m => m?.moveId === Moves.SONIC_BOOM)?.ppUsed,
|
|
||||||
).toBe(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not repeat enemy's move through protect", async () => {
|
it("should not repeat enemy's move through protect", async () => {
|
||||||
|
@ -72,7 +72,7 @@ describe("Moves - Quash", () => {
|
|||||||
|
|
||||||
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||||
game.move.select(Moves.OUTRAGE, BattlerIndex.PLAYER_2);
|
game.move.select(Moves.OUTRAGE, BattlerIndex.PLAYER_2);
|
||||||
await game.toNextTurn();
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
|
||||||
const outrageMove = rattata.getMoveset().find(m => m.moveId === Moves.OUTRAGE);
|
const outrageMove = rattata.getMoveset().find(m => m.moveId === Moves.OUTRAGE);
|
||||||
expect(outrageMove?.ppUsed).toBe(1);
|
expect(outrageMove?.ppUsed).toBe(1);
|
||||||
|
@ -427,6 +427,7 @@ export default class GameManager {
|
|||||||
* If all active player Pokemon are using a rampaging, charging, recharging or other move that
|
* If all active player Pokemon are using a rampaging, charging, recharging or other move that
|
||||||
* disables user input, this **will not resolve** until at least 1 player pokemon becomes actionable.
|
* disables user input, this **will not resolve** until at least 1 player pokemon becomes actionable.
|
||||||
*/
|
*/
|
||||||
|
// TODO: Make this not need to be called twice in doubles tests
|
||||||
async toNextTurn() {
|
async toNextTurn() {
|
||||||
await this.phaseInterceptor.to(CommandPhase);
|
await this.phaseInterceptor.to(CommandPhase);
|
||||||
console.log("==================[New Turn]==================");
|
console.log("==================[New Turn]==================");
|
||||||
@ -519,9 +520,9 @@ export default class GameManager {
|
|||||||
* @returns A promise that resolves once the fainted pokemon's FaintPhase finishes running.
|
* @returns A promise that resolves once the fainted pokemon's FaintPhase finishes running.
|
||||||
*/
|
*/
|
||||||
async killPokemon(pokemon: PlayerPokemon | EnemyPokemon) {
|
async killPokemon(pokemon: PlayerPokemon | EnemyPokemon) {
|
||||||
pokemon.hp = 0;
|
|
||||||
this.scene.unshiftPhase(new FaintPhase(pokemon.getBattlerIndex(), true));
|
|
||||||
return new Promise<void>(async (resolve, reject) => {
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
|
pokemon.hp = 0;
|
||||||
|
this.scene.pushPhase(new FaintPhase(pokemon.getBattlerIndex(), true));
|
||||||
await this.phaseInterceptor.to(FaintPhase).catch(e => reject(e));
|
await this.phaseInterceptor.to(FaintPhase).catch(e => reject(e));
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user