More cleanup
This commit is contained in:
parent
b400cbf0c1
commit
559097d309
|
@ -1,17 +1,16 @@
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { applyAbAttrs, BypassSpeedChanceAbAttr, PreventBypassSpeedChanceAbAttr, ChangeMovePriorityAbAttr } from "#app/data/ability";
|
import { applyAbAttrs, BypassSpeedChanceAbAttr, ChangeMovePriorityAbAttr, PreventBypassSpeedChanceAbAttr } from "#app/data/ability";
|
||||||
|
import { TrickRoomTag } from "#app/data/arena-tag";
|
||||||
import { allMoves, applyMoveAttrs, IncrementMovePriorityAttr, MoveHeaderAttr } from "#app/data/move";
|
import { allMoves, applyMoveAttrs, IncrementMovePriorityAttr, MoveHeaderAttr } from "#app/data/move";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#app/enums/abilities";
|
||||||
|
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||||
|
import { Moves } from "#app/enums/moves";
|
||||||
import { Stat } from "#app/enums/stat";
|
import { Stat } from "#app/enums/stat";
|
||||||
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
||||||
import { BypassSpeedChanceModifier } from "#app/modifier/modifier";
|
import { BypassSpeedChanceModifier } from "#app/modifier/modifier";
|
||||||
import { Command } from "#app/ui/command-ui-handler";
|
import { Command } from "#app/ui/command-ui-handler";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
|
|
||||||
import { BattlerIndex } from "#app/battle";
|
|
||||||
|
|
||||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
|
||||||
import { Moves } from "#app/enums/moves";
|
|
||||||
import { AttemptCapturePhase } from "./attempt-capture-phase";
|
import { AttemptCapturePhase } from "./attempt-capture-phase";
|
||||||
import { AttemptRunPhase } from "./attempt-run-phase";
|
import { AttemptRunPhase } from "./attempt-run-phase";
|
||||||
import { BerryPhase } from "./berry-phase";
|
import { BerryPhase } from "./berry-phase";
|
||||||
|
@ -22,8 +21,6 @@ import { PostTurnStatusEffectPhase } from "./post-turn-status-effect-phase";
|
||||||
import { SwitchSummonPhase } from "./switch-summon-phase";
|
import { SwitchSummonPhase } from "./switch-summon-phase";
|
||||||
import { TurnEndPhase } from "./turn-end-phase";
|
import { TurnEndPhase } from "./turn-end-phase";
|
||||||
import { WeatherEffectPhase } from "./weather-effect-phase";
|
import { WeatherEffectPhase } from "./weather-effect-phase";
|
||||||
import { BattlerIndex } from "#app/battle";
|
|
||||||
import { TrickRoomTag } from "#app/data/arena-tag";
|
|
||||||
|
|
||||||
export class TurnStartPhase extends FieldPhase {
|
export class TurnStartPhase extends FieldPhase {
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
|
@ -173,7 +170,7 @@ export class TurnStartPhase extends FieldPhase {
|
||||||
if (!queuedMove) {
|
if (!queuedMove) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move) || new PokemonMove(queuedMove.move);
|
const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move) ?? new PokemonMove(queuedMove.move);
|
||||||
if (move.getMove().hasAttr(MoveHeaderAttr)) {
|
if (move.getMove().hasAttr(MoveHeaderAttr)) {
|
||||||
this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move));
|
this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { allMoves } from "#app/data/move";
|
||||||
|
import { TerrainType } from "#app/data/terrain";
|
||||||
|
import { Abilities } from "#app/enums/abilities";
|
||||||
|
import { Moves } from "#app/enums/moves";
|
||||||
|
import { Species } from "#app/enums/species";
|
||||||
|
import { Stat } from "#app/enums/stat";
|
||||||
|
import Pokemon, { MoveResult } from "#app/field/pokemon";
|
||||||
|
import { EncounterPhase } from "#app/phases/encounter-phase";
|
||||||
|
import { EnemyCommandPhase } from "#app/phases/enemy-command-phase";
|
||||||
|
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
|
||||||
|
import { TurnStartPhase } from "#app/phases/turn-start-phase";
|
||||||
|
import GameManager from "#test/utils/gameManager";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import GameManager from "../utils/gameManager";
|
|
||||||
import { Moves } from "#app/enums/moves.js";
|
|
||||||
import { Species } from "#app/enums/species.js";
|
|
||||||
import { SPLASH_ONLY } from "../utils/testUtils";
|
|
||||||
import { allMoves } from "#app/data/move.js";
|
|
||||||
import { getMovePosition } from "../utils/gameManagerUtils";
|
|
||||||
import Pokemon, { MoveResult } from "#app/field/pokemon.js";
|
|
||||||
import { BattleStat } from "#app/data/battle-stat.js";
|
|
||||||
import { BattlerIndex } from "#app/battle.js";
|
|
||||||
import { TerrainType } from "#app/data/terrain.js";
|
|
||||||
import { Abilities } from "#app/enums/abilities.js";
|
|
||||||
import { EnemyCommandPhase } from "#app/phases/enemy-command-phase.js";
|
|
||||||
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase.js";
|
|
||||||
import { EncounterPhase } from "#app/phases/encounter-phase.js";
|
|
||||||
import { TurnStartPhase } from "#app/phases/turn-start-phase.js";
|
|
||||||
|
|
||||||
interface PokemonAssertionChainer {
|
interface PokemonAssertionChainer {
|
||||||
and(expectation: (p?: Pokemon) => PokemonAssertionChainer): PokemonAssertionChainer;
|
and(expectation: (p?: Pokemon) => PokemonAssertionChainer): PokemonAssertionChainer;
|
||||||
|
@ -45,11 +43,14 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
return game.startBattle([playerLead, Species.RAICHU, Species.ABSOL]);
|
return game.startBattle([playerLead, Species.RAICHU, Species.ABSOL]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runCombatTurn(to: string = "TurnInitPhase") {
|
/**
|
||||||
// many of these tests can't run only to BerryPhase because of interactions with fainting
|
* Many of these tests can't run only to {@linkcode BerryPhase} because of interactions with fainting
|
||||||
// during switches. we need to run tests all the way through to the start of the next turn
|
* during switches. We need to run tests all the way through to the start of the next turn
|
||||||
// to ensure that, for example, the game doesn't attempt to switch two pokemon into the same
|
* to ensure that, for example, the game doesn't attempt to switch two pokemon into the same
|
||||||
// slot (once in the originally queued summon phase, and the next as a result of FaintPhase)
|
* slot (once in the originally queued summon phase, and the next as a result of {@linkcode FaintPhase})
|
||||||
|
* @param to Phase to run to (default {@linkcode TurnInitPhase})
|
||||||
|
*/
|
||||||
|
async function runCombatTurn(to: string = "TurnInitPhase"): Promise<void> {
|
||||||
return await game.phaseInterceptor.to(to, false);
|
return await game.phaseInterceptor.to(to, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,22 +61,18 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
|
|
||||||
function playerDoesNothing() {
|
function playerDoesNothing() {
|
||||||
game.override.moveset(Moves.SPLASH);
|
game.override.moveset(Moves.SPLASH);
|
||||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
game.move.select(Moves.SPLASH);
|
||||||
if (game.scene.currentBattle.double) {
|
if (game.scene.currentBattle.double) {
|
||||||
game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH));
|
game.move.select(Moves.SPLASH, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function playerUsesPursuit(pokemonIndex: 0 | 1 = 0, targetIndex: BattlerIndex = BattlerIndex.ENEMY) {
|
function playerUsesPursuit(pokemonIndex: 0 | 1 = 0, targetIndex: BattlerIndex = BattlerIndex.ENEMY) {
|
||||||
game.doAttack(getMovePosition(game.scene, pokemonIndex, Moves.PURSUIT));
|
game.move.select(Moves.PURSUIT, pokemonIndex, targetIndex);
|
||||||
game.doSelectTarget(targetIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function playerUsesSwitchMove(pokemonIndex: 0 | 1 = 0) {
|
function playerUsesSwitchMove(pokemonIndex: 0 | 1 = 0) {
|
||||||
game.doAttack(getMovePosition(game.scene, pokemonIndex, Moves.U_TURN));
|
game.move.select(Moves.U_TURN, pokemonIndex);
|
||||||
if (game.scene.currentBattle.double) {
|
|
||||||
game.doSelectTarget(BattlerIndex.ENEMY);
|
|
||||||
}
|
|
||||||
game.doSelectPartyPokemon(2);
|
game.doSelectPartyPokemon(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +97,7 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
const moveOrder = ([...otherPkmn, ...pokemon].map(pkmn => pkmn.getBattlerIndex()));
|
const moveOrder = ([...otherPkmn, ...pokemon].map(pkmn => pkmn.getBattlerIndex()));
|
||||||
|
|
||||||
game.phaseInterceptor.onNextPhase(TurnStartPhase, p => {
|
game.phaseInterceptor.onNextPhase(TurnStartPhase, p => {
|
||||||
vi.spyOn(p, "getOrder").mockReturnValue(
|
vi.spyOn(p, "getCommandOrder").mockReturnValue(
|
||||||
// TurnStartPhase crashes if a BI returned by getOrder() is fainted.
|
// TurnStartPhase crashes if a BI returned by getOrder() is fainted.
|
||||||
// not an issue normally but some of the test setups can cause this
|
// not an issue normally but some of the test setups can cause this
|
||||||
moveOrder!.filter(i => game.scene.getField(false)[i]?.isActive(true))
|
moveOrder!.filter(i => game.scene.getField(false)[i]?.isActive(true))
|
||||||
|
@ -114,7 +111,7 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
const moveOrder = ([...pokemon, ...otherPkmn].map(pkmn => pkmn.getBattlerIndex()));
|
const moveOrder = ([...pokemon, ...otherPkmn].map(pkmn => pkmn.getBattlerIndex()));
|
||||||
|
|
||||||
game.phaseInterceptor.onNextPhase(TurnStartPhase, p => {
|
game.phaseInterceptor.onNextPhase(TurnStartPhase, p => {
|
||||||
vi.spyOn(p, "getOrder").mockReturnValue(
|
vi.spyOn(p, "getCommandOrder").mockReturnValue(
|
||||||
// TurnStartPhase crashes if a BI returned by getOrder() is fainted.
|
// TurnStartPhase crashes if a BI returned by getOrder() is fainted.
|
||||||
// not an issue normally but some of the test setups can cause this
|
// not an issue normally but some of the test setups can cause this
|
||||||
moveOrder!.filter(i => game.scene.getField(false)[i]?.isActive(true))
|
moveOrder!.filter(i => game.scene.getField(false)[i]?.isActive(true))
|
||||||
|
@ -201,7 +198,7 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
.startingLevel(20)
|
.startingLevel(20)
|
||||||
.startingWave(25)
|
.startingWave(25)
|
||||||
.moveset([Moves.PURSUIT, Moves.U_TURN, Moves.DRAGON_TAIL, Moves.FOLLOW_ME])
|
.moveset([Moves.PURSUIT, Moves.U_TURN, Moves.DRAGON_TAIL, Moves.FOLLOW_ME])
|
||||||
.enemyMoveset(SPLASH_ONLY)
|
.enemyMoveset(Moves.SPLASH)
|
||||||
.disableCrits();
|
.disableCrits();
|
||||||
|
|
||||||
vi.spyOn(pursuitMoveDef, "calculateBattlePower");
|
vi.spyOn(pursuitMoveDef, "calculateBattlePower");
|
||||||
|
@ -306,8 +303,8 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
it("should bypass accuracy checks when hitting a hard-switching target", async () => {
|
it("should bypass accuracy checks when hitting a hard-switching target", async () => {
|
||||||
// arrange
|
// arrange
|
||||||
await startBattle();
|
await startBattle();
|
||||||
game.scene.getPlayerPokemon()!.summonData.battleStats[BattleStat.ACC] = -6;
|
game.scene.getPlayerPokemon()!.summonData.statStages[Stat.ACC] = -6;
|
||||||
game.scene.getEnemyPokemon()!.summonData.battleStats[BattleStat.EVA] = 6;
|
game.scene.getEnemyPokemon()!.summonData.statStages[Stat.EVA] = 6;
|
||||||
|
|
||||||
// act
|
// act
|
||||||
playerUsesPursuit();
|
playerUsesPursuit();
|
||||||
|
@ -322,8 +319,8 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
// arrange
|
// arrange
|
||||||
await startBattle();
|
await startBattle();
|
||||||
forceMovesLast(game.scene.getPlayerPokemon());
|
forceMovesLast(game.scene.getPlayerPokemon());
|
||||||
game.scene.getEnemyPokemon()!.summonData.battleStats[BattleStat.ACC] = -6;
|
game.scene.getEnemyPokemon()!.summonData.statStages[Stat.ACC] = -6;
|
||||||
game.scene.getPlayerPokemon()!.summonData.battleStats[BattleStat.EVA] = 6;
|
game.scene.getPlayerPokemon()!.summonData.statStages[Stat.EVA] = 6;
|
||||||
|
|
||||||
// act
|
// act
|
||||||
playerUsesPursuit();
|
playerUsesPursuit();
|
||||||
|
@ -376,8 +373,8 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
// arrange
|
// arrange
|
||||||
await startBattle();
|
await startBattle();
|
||||||
forceMovesLast(game.scene.getPlayerPokemon());
|
forceMovesLast(game.scene.getPlayerPokemon());
|
||||||
game.scene.getEnemyPokemon()!.summonData.battleStats[BattleStat.ACC] = -6;
|
game.scene.getEnemyPokemon()!.summonData.statStages[Stat.ACC] = -6;
|
||||||
game.scene.getPlayerPokemon()!.summonData.battleStats[BattleStat.EVA] = 6;
|
game.scene.getPlayerPokemon()!.summonData.statStages[Stat.EVA] = 6;
|
||||||
|
|
||||||
// act
|
// act
|
||||||
playerUsesPursuit();
|
playerUsesPursuit();
|
||||||
|
@ -580,23 +577,21 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
|
|
||||||
describe("doubles interactions", () => {
|
describe("doubles interactions", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game.override.battleType("double");
|
game.override
|
||||||
|
.battleType("double")
|
||||||
|
.enemyMoveset([Moves.PURSUIT, Moves.U_TURN]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should bypass follow me when hitting a switching target", async () => {
|
it("should bypass follow me when hitting a switching target", async () => {
|
||||||
// arrange
|
|
||||||
await startBattle();
|
await startBattle();
|
||||||
forceMovesLast(game.scene.getEnemyPokemon());
|
forceMovesLast(game.scene.getEnemyPokemon());
|
||||||
|
|
||||||
// act
|
game.move.select(Moves.FOLLOW_ME);
|
||||||
game.doAttack(getMovePosition(game.scene, 0, Moves.FOLLOW_ME));
|
|
||||||
playerUsesSwitchMove(1);
|
playerUsesSwitchMove(1);
|
||||||
enemyUses(Moves.PURSUIT);
|
game.forceEnemyMove(Moves.PURSUIT, BattlerIndex.PLAYER_2);
|
||||||
game.move.forceAiTargets(game.scene.getEnemyPokemon(), BattlerIndex.PLAYER_2);
|
|
||||||
await game.killPokemon(game.scene.getEnemyField()[1]);
|
await game.killPokemon(game.scene.getEnemyField()[1]);
|
||||||
await runCombatTurn();
|
await runCombatTurn();
|
||||||
|
|
||||||
// assert
|
|
||||||
expectPursuitPowerDoubled();
|
expectPursuitPowerDoubled();
|
||||||
expectWasHit(findPartyMember(game.scene.getParty(), Species.RAICHU))
|
expectWasHit(findPartyMember(game.scene.getParty(), Species.RAICHU))
|
||||||
.and(expectNotOnField);
|
.and(expectNotOnField);
|
||||||
|
@ -604,57 +599,47 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not bypass follow me when hitting a non-switching target", async () => {
|
it("should not bypass follow me when hitting a non-switching target", async () => {
|
||||||
// arrange
|
|
||||||
await startBattle();
|
await startBattle();
|
||||||
forceMovesLast(game.scene.getEnemyPokemon());
|
forceMovesLast(game.scene.getEnemyPokemon());
|
||||||
|
|
||||||
// act
|
|
||||||
game.override.moveset([Moves.FOLLOW_ME, Moves.SPLASH]);
|
game.override.moveset([Moves.FOLLOW_ME, Moves.SPLASH]);
|
||||||
game.doAttack(getMovePosition(game.scene, 0, Moves.FOLLOW_ME));
|
game.move.select(Moves.FOLLOW_ME);
|
||||||
game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH));
|
game.move.select(Moves.SPLASH, 1);
|
||||||
enemyUses(Moves.PURSUIT);
|
game.forceEnemyMove(Moves.PURSUIT, BattlerIndex.PLAYER_2);
|
||||||
game.move.forceAiTargets(game.scene.getEnemyPokemon(), BattlerIndex.PLAYER_2);
|
|
||||||
await game.killPokemon(game.scene.getEnemyField()[1]);
|
await game.killPokemon(game.scene.getEnemyField()[1]);
|
||||||
await runCombatTurn();
|
await runCombatTurn();
|
||||||
|
|
||||||
// assert
|
|
||||||
expectPursuitPowerUnchanged();
|
expectPursuitPowerUnchanged();
|
||||||
expectWasHit(findPartyMember(game.scene.getParty(), playerLead));
|
expectWasHit(findPartyMember(game.scene.getParty(), playerLead));
|
||||||
expectWasNotHit(findPartyMember(game.scene.getParty(), Species.RAICHU));
|
expectWasNotHit(findPartyMember(game.scene.getParty(), Species.RAICHU));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not cause the enemy AI to send out a fainted pokemon if they command 2 switches and one of the outgoing pokemon faints to pursuit", async () => {
|
it("should not cause the enemy AI to send out a fainted pokemon if they command 2 switches and one of the outgoing pokemon faints to pursuit", async () => {
|
||||||
// arrange
|
|
||||||
await startBattle();
|
await startBattle();
|
||||||
forceMovesLast(game.scene.getPlayerField());
|
forceMovesLast(game.scene.getPlayerField());
|
||||||
game.scene.getEnemyField()[0]!.hp = 1;
|
game.scene.getEnemyField()[0]!.hp = 1;
|
||||||
|
|
||||||
// act
|
|
||||||
playerUsesPursuit(0);
|
playerUsesPursuit(0);
|
||||||
playerUsesPursuit(1);
|
playerUsesPursuit(1);
|
||||||
enemySwitches();
|
enemySwitches();
|
||||||
await runCombatTurn();
|
await runCombatTurn();
|
||||||
|
|
||||||
// assert
|
|
||||||
expect(game.scene.getEnemyParty().filter(p => p.isOnField())).toHaveLength(2);
|
expect(game.scene.getEnemyParty().filter(p => p.isOnField())).toHaveLength(2);
|
||||||
expect(game.scene.getEnemyParty().filter(p => p.isOnField() && p.isFainted())).toHaveLength(0);
|
expect(game.scene.getEnemyParty().filter(p => p.isOnField() && p.isFainted())).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: is this correct behavior?
|
// TODO: is this correct behavior?
|
||||||
it("should fail if both pokemon use pursuit on a target that is switching out and it faints after the first one with no other targets on field", async () => {
|
it("should fail if both pokemon use pursuit on a target that is switching out and it faints after the first one with no other targets on field", async () => {
|
||||||
// arrange
|
|
||||||
await startBattle();
|
await startBattle();
|
||||||
forceMovesLast(game.scene.getPlayerField());
|
forceMovesLast(game.scene.getPlayerField());
|
||||||
game.scene.getEnemyField()[0]!.hp = 1;
|
game.scene.getEnemyField()[0]!.hp = 1;
|
||||||
|
|
||||||
// act
|
|
||||||
playerUsesPursuit(0);
|
playerUsesPursuit(0);
|
||||||
playerUsesPursuit(1);
|
playerUsesPursuit(1);
|
||||||
enemySwitches();
|
enemySwitches();
|
||||||
await game.killPokemon(game.scene.getEnemyField()[1]);
|
await game.killPokemon(game.scene.getEnemyField()[1]);
|
||||||
await runCombatTurn();
|
await runCombatTurn();
|
||||||
|
|
||||||
// assert
|
|
||||||
expectPursuitPowerDoubled();
|
expectPursuitPowerDoubled();
|
||||||
expectPursuitSucceeded(game.scene.getPlayerField()[0]);
|
expectPursuitSucceeded(game.scene.getPlayerField()[0]);
|
||||||
expectPursuitFailed(game.scene.getPlayerField()[1]);
|
expectPursuitFailed(game.scene.getPlayerField()[1]);
|
||||||
|
@ -662,7 +647,6 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
|
|
||||||
// TODO: is this correct behavior?
|
// TODO: is this correct behavior?
|
||||||
it("should attack the second switching pokemon if both pokemon switch and the first is KOd", async () => {
|
it("should attack the second switching pokemon if both pokemon switch and the first is KOd", async () => {
|
||||||
// arrange
|
|
||||||
game.phaseInterceptor.onNextPhase(EncounterPhase, () => {
|
game.phaseInterceptor.onNextPhase(EncounterPhase, () => {
|
||||||
game.scene.currentBattle.enemyLevels = [...game.scene.currentBattle.enemyLevels!, game.scene.currentBattle.enemyLevels![0]];
|
game.scene.currentBattle.enemyLevels = [...game.scene.currentBattle.enemyLevels!, game.scene.currentBattle.enemyLevels![0]];
|
||||||
});
|
});
|
||||||
|
@ -670,7 +654,6 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
forceMovesLast(game.scene.getPlayerField());
|
forceMovesLast(game.scene.getPlayerField());
|
||||||
game.scene.getEnemyField()[0]!.hp = 1;
|
game.scene.getEnemyField()[0]!.hp = 1;
|
||||||
|
|
||||||
// act
|
|
||||||
playerUsesPursuit(0);
|
playerUsesPursuit(0);
|
||||||
playerUsesPursuit(1);
|
playerUsesPursuit(1);
|
||||||
enemySwitches();
|
enemySwitches();
|
||||||
|
@ -680,7 +663,6 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
});
|
});
|
||||||
await runCombatTurn();
|
await runCombatTurn();
|
||||||
|
|
||||||
// assert
|
|
||||||
expectPursuitPowerDoubled();
|
expectPursuitPowerDoubled();
|
||||||
expectPursuitSucceeded(game.scene.getPlayerField()[0]);
|
expectPursuitSucceeded(game.scene.getPlayerField()[0]);
|
||||||
expectPursuitSucceeded(game.scene.getPlayerField()[1]);
|
expectPursuitSucceeded(game.scene.getPlayerField()[1]);
|
||||||
|
@ -692,13 +674,10 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
// TODO: confirm correct behavior and add tests for other pursuit/switch combos in doubles
|
// TODO: confirm correct behavior and add tests for other pursuit/switch combos in doubles
|
||||||
|
|
||||||
it("should not hit a pokemon being forced out with dragon tail", async () => {
|
it("should not hit a pokemon being forced out with dragon tail", async () => {
|
||||||
// arrange
|
|
||||||
await startBattle();
|
await startBattle();
|
||||||
forceMovesLast(game.scene.getPlayerField());
|
forceMovesLast(game.scene.getPlayerField());
|
||||||
|
|
||||||
// act
|
game.move.select(Moves.DRAGON_TAIL);
|
||||||
game.doAttack(getMovePosition(game.scene, 0, Moves.DRAGON_TAIL));
|
|
||||||
game.doSelectTarget(BattlerIndex.ENEMY);
|
|
||||||
playerUsesPursuit(1);
|
playerUsesPursuit(1);
|
||||||
enemyUses(Moves.SPLASH);
|
enemyUses(Moves.SPLASH);
|
||||||
await runCombatTurn();
|
await runCombatTurn();
|
||||||
|
@ -805,18 +784,14 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not hit a switching ally for double damage (hard-switch, enemy field)", async () => {
|
it("should not hit a switching ally for double damage (hard-switch, enemy field)", async () => {
|
||||||
// arrange
|
|
||||||
await startBattle();
|
await startBattle();
|
||||||
forceMovesLast(game.scene.getEnemyField());
|
forceMovesLast(game.scene.getEnemyField());
|
||||||
|
|
||||||
// act
|
|
||||||
playerDoesNothing();
|
playerDoesNothing();
|
||||||
enemySwitches(true);
|
enemySwitches(true);
|
||||||
enemyUses(Moves.PURSUIT);
|
game.forceEnemyMove(Moves.PURSUIT, BattlerIndex.ENEMY);
|
||||||
game.move.forceAiTargets(game.scene.getEnemyField()[1], BattlerIndex.ENEMY);
|
|
||||||
await runCombatTurn();
|
await runCombatTurn();
|
||||||
|
|
||||||
// assert
|
|
||||||
expectPursuitPowerUnchanged();
|
expectPursuitPowerUnchanged();
|
||||||
expectWasNotHit(findPartyMember(game.scene.getEnemyParty(), enemyLead)).and(expectNotOnField);
|
expectWasNotHit(findPartyMember(game.scene.getEnemyParty(), enemyLead)).and(expectNotOnField);
|
||||||
expectWasHit(game.scene.getEnemyField()[0]);
|
expectWasHit(game.scene.getEnemyField()[0]);
|
||||||
|
@ -846,11 +821,8 @@ describe("Moves - Pursuit", { timeout: 10000 }, () => {
|
||||||
|
|
||||||
// act
|
// act
|
||||||
playerDoesNothing();
|
playerDoesNothing();
|
||||||
enemyUses(Moves.U_TURN);
|
game.forceEnemyMove(Moves.U_TURN);
|
||||||
await game.phaseInterceptor.to(EnemyCommandPhase);
|
game.forceEnemyMove(Moves.PURSUIT, BattlerIndex.ENEMY);
|
||||||
|
|
||||||
enemyUses(Moves.PURSUIT);
|
|
||||||
game.move.forceAiTargets(game.scene.getEnemyField()[1], BattlerIndex.ENEMY);
|
|
||||||
await runCombatTurn();
|
await runCombatTurn();
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
|
|
|
@ -461,11 +461,11 @@ export default class GameManager {
|
||||||
* await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2]);
|
* await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2]);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
async setTurnOrder(order: BattlerIndex[]): Promise<void> {
|
async setTurnOrder(order: BattlerIndex[], modifyPriority: boolean = false): Promise<void> {
|
||||||
await this.phaseInterceptor.to(TurnStartPhase, false);
|
await this.phaseInterceptor.to(TurnStartPhase, false);
|
||||||
console.log("Base turn order (before priority) set to:", order);
|
console.log(`${modifyPriority ? "Turn" : "Speed"} order modified to: `, order);
|
||||||
|
|
||||||
vi.spyOn(this.scene.getCurrentPhase() as TurnStartPhase, "getSpeedOrder").mockReturnValue(order);
|
vi.spyOn(this.scene.getCurrentPhase() as TurnStartPhase, (modifyPriority ? "getCommandOrder" : "getSpeedOrder")).mockReturnValue(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -336,6 +336,16 @@ export class OverridesHelper extends GameManagerHelper {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces the AI to always switch out, or reset to allow normal switching decisions
|
||||||
|
* @returns this
|
||||||
|
*/
|
||||||
|
forceTrainerSwitches(newValue: boolean = true) {
|
||||||
|
vi.spyOn(Overrides, "TRAINER_ALWAYS_SWITCHES_OVERRIDE", "get").mockReturnValue(newValue);
|
||||||
|
this.log("Trainers will always switch out set to:", newValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the encounter chance for a mystery encounter.
|
* Override the encounter chance for a mystery encounter.
|
||||||
* @param percentage the encounter chance in %
|
* @param percentage the encounter chance in %
|
||||||
|
|
Loading…
Reference in New Issue