Compare commits

...

17 Commits

Author SHA1 Message Date
Bertie690
7551f13d5f
Merge b4dd435d3e into f42237d415 2025-08-14 13:28:36 -04:00
Bertie690
f42237d415
[Refactor] Removed map(x => x) (#6256)
* Enforced a few usages of `toCamelCase`

* Removed `map(x => x)`

* Removed more maps and sufff

* Update test/mystery-encounter/encounters/weird-dream-encounter.test.ts

* Update game-data.ts types to work
2025-08-14 10:25:44 -07:00
fabske0
b44f0a4176
[Refactor] Remove bgm param from arena constructor (#6254) 2025-08-14 16:52:56 +00:00
NightKev
b4dd435d3e
Re-add ! and add TODO comment instead 2025-08-11 05:57:07 -07:00
Bertie690
817654341a
Update phase-interceptor.ts
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2025-08-11 08:47:55 -04:00
NightKev
d969d9f67b
Merge branch 'beta' into deprecated-func 2025-08-11 05:36:37 -07:00
Wlowscha
a9040f0048
Merge branch 'beta' into deprecated-func 2025-08-02 22:07:59 +02:00
Bertie690
5d7a3d28ff dddddd 2025-08-01 21:39:09 -04:00
Bertie690
040eaf8632 fixed another dumb error bc me big dumb bozo 2025-08-01 21:30:35 -04:00
Bertie690
c318a0cc59 Fixed tests 2025-08-01 21:25:12 -04:00
Bertie690
20582b43c0 maybe fixed? 2025-08-01 21:18:05 -04:00
Bertie690
c737a9206f Perhaps fixed things? 2025-08-01 20:52:05 -04:00
Bertie690
152f54ee7a somehow fixed reload bug by making things actively worse 2025-08-01 20:42:25 -04:00
Bertie690
1819712201 Fixed issues and syntax errors 2025-08-01 20:10:57 -04:00
Bertie690
9a19eac9ee Added selectStarterPhase to the end by set mode collection 2025-08-01 19:03:11 -04:00
Bertie690
bca9560f55 Added minor docs to the phase manager + renamed shift to shiftPhase 2025-08-01 18:57:31 -04:00
Bertie690
a1a3526c17 Removed deprecated functions from phase interceptor 2025-08-01 18:38:05 -04:00
47 changed files with 409 additions and 624 deletions

View File

@ -104,6 +104,7 @@ import {
getLuckString, getLuckString,
getLuckTextTint, getLuckTextTint,
getPartyLuckValue, getPartyLuckValue,
type ModifierType,
PokemonHeldItemModifierType, PokemonHeldItemModifierType,
} from "#modifiers/modifier-type"; } from "#modifiers/modifier-type";
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
@ -1203,7 +1204,9 @@ export class BattleScene extends SceneBase {
this.updateScoreText(); this.updateScoreText();
this.scoreText.setVisible(false); this.scoreText.setVisible(false);
[this.luckLabelText, this.luckText].map(t => t.setVisible(false)); [this.luckLabelText, this.luckText].forEach(t => {
t.setVisible(false);
});
this.newArena(Overrides.STARTING_BIOME_OVERRIDE || BiomeId.TOWN); this.newArena(Overrides.STARTING_BIOME_OVERRIDE || BiomeId.TOWN);
@ -1237,8 +1240,7 @@ export class BattleScene extends SceneBase {
Object.values(mp) Object.values(mp)
.flat() .flat()
.map(mt => mt.modifierType) .map(mt => mt.modifierType)
.filter(mt => "localize" in mt) .filter((mt): mt is ModifierType & Localizable => "localize" in mt && typeof mt.localize === "function"),
.map(lpb => lpb as unknown as Localizable),
), ),
]; ];
for (const item of localizable) { for (const item of localizable) {
@ -1513,8 +1515,8 @@ export class BattleScene extends SceneBase {
return this.currentBattle; return this.currentBattle;
} }
newArena(biome: BiomeId, playerFaints?: number): Arena { newArena(biome: BiomeId, playerFaints = 0): Arena {
this.arena = new Arena(biome, BiomeId[biome].toLowerCase(), playerFaints); this.arena = new Arena(biome, playerFaints);
this.eventTarget.dispatchEvent(new NewArenaEvent()); this.eventTarget.dispatchEvent(new NewArenaEvent());
this.arenaBg.pipelineData = { this.arenaBg.pipelineData = {
@ -2711,7 +2713,9 @@ export class BattleScene extends SceneBase {
} }
} }
this.party.map(p => p.updateInfo(instant)); this.party.forEach(p => {
p.updateInfo(instant);
});
} else { } else {
const args = [this]; const args = [this];
if (modifier.shouldApply(...args)) { if (modifier.shouldApply(...args)) {

View File

@ -74,6 +74,7 @@ import {
randSeedItem, randSeedItem,
toDmgValue, toDmgValue,
} from "#utils/common"; } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
export class Ability implements Localizable { export class Ability implements Localizable {
@ -109,13 +110,9 @@ export class Ability implements Localizable {
} }
localize(): void { localize(): void {
const i18nKey = AbilityId[this.id] const i18nKey = toCamelCase(AbilityId[this.id]);
.split("_")
.filter(f => f)
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join("") as string;
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : ""; this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`)}${this.nameAppend}` : "";
this.description = this.id ? (i18next.t(`ability:${i18nKey}.description`) as string) : ""; this.description = this.id ? (i18next.t(`ability:${i18nKey}.description`) as string) : "";
} }

View File

@ -1866,17 +1866,16 @@ interface PokemonPrevolutions {
export const pokemonPrevolutions: PokemonPrevolutions = {}; export const pokemonPrevolutions: PokemonPrevolutions = {};
export function initPokemonPrevolutions(): void { export function initPokemonPrevolutions(): void {
const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string); // TODO: Why do we have empty strings in our array?
const prevolutionKeys = Object.keys(pokemonEvolutions); const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ];
prevolutionKeys.forEach(pk => { for (const [pk, evolutions] of Object.entries(pokemonEvolutions)) {
const evolutions = pokemonEvolutions[pk];
for (const ev of evolutions) { for (const ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) { if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) {
continue; continue;
} }
pokemonPrevolutions[ev.speciesId] = Number.parseInt(pk) as SpeciesId; pokemonPrevolutions[ev.speciesId] = Number.parseInt(pk) as SpeciesId;
} }
}); }
} }

View File

@ -90,7 +90,7 @@ import type { ChargingMove, MoveAttrMap, MoveAttrString, MoveClassMap, MoveKindS
import type { TurnMove } from "#types/turn-move"; import type { TurnMove } from "#types/turn-move";
import { BooleanHolder, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common"; import { BooleanHolder, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
import { getEnumValues } from "#utils/enums"; import { getEnumValues } from "#utils/enums";
import { toTitleCase } from "#utils/strings"; import { toCamelCase, toTitleCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
@ -162,10 +162,16 @@ export abstract class Move implements Localizable {
} }
localize(): void { localize(): void {
const i18nKey = MoveId[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string; const i18nKey = toCamelCase(MoveId[this.id])
this.name = this.id ? `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}` : ""; if (this.id === MoveId.NONE) {
this.effect = this.id ? `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}` : ""; this.name = "";
this.effect = ""
return;
}
this.name = `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}`;
this.effect = `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}`;
} }
/** /**

View File

@ -12,6 +12,7 @@ import { WeatherType } from "#enums/weather-type";
import type { Pokemon } from "#field/pokemon"; import type { Pokemon } from "#field/pokemon";
import type { PokemonFormChangeItemModifier } from "#modifiers/modifier"; import type { PokemonFormChangeItemModifier } from "#modifiers/modifier";
import { type Constructor, coerceArray } from "#utils/common"; import { type Constructor, coerceArray } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
export abstract class SpeciesFormChangeTrigger { export abstract class SpeciesFormChangeTrigger {
@ -143,11 +144,7 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge
super(); super();
this.move = move; this.move = move;
this.known = known; this.known = known;
const moveKey = MoveId[this.move] const moveKey = toCamelCase(MoveId[this.move]);
.split("_")
.filter(f => f)
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join("") as unknown as string;
this.description = known this.description = known
? i18next.t("pokemonEvolutions:Forms.moveLearned", { ? i18next.t("pokemonEvolutions:Forms.moveLearned", {
move: i18next.t(`move:${moveKey}.name`), move: i18next.t(`move:${moveKey}.name`),

View File

@ -54,7 +54,7 @@ export class Arena {
public bgm: string; public bgm: string;
public ignoreAbilities: boolean; public ignoreAbilities: boolean;
public ignoringEffectSource: BattlerIndex | null; public ignoringEffectSource: BattlerIndex | null;
public playerTerasUsed: number; public playerTerasUsed = 0;
/** /**
* Saves the number of times a party pokemon faints during a arena encounter. * Saves the number of times a party pokemon faints during a arena encounter.
* {@linkcode globalScene.currentBattle.enemyFaints} is the corresponding faint counter for the enemy (this resets every wave). * {@linkcode globalScene.currentBattle.enemyFaints} is the corresponding faint counter for the enemy (this resets every wave).
@ -68,12 +68,11 @@ export class Arena {
public readonly eventTarget: EventTarget = new EventTarget(); public readonly eventTarget: EventTarget = new EventTarget();
constructor(biome: BiomeId, bgm: string, playerFaints = 0) { constructor(biome: BiomeId, playerFaints = 0) {
this.biomeType = biome; this.biomeType = biome;
this.bgm = bgm; this.bgm = BiomeId[biome].toLowerCase();
this.trainerPool = biomeTrainerPools[biome]; this.trainerPool = biomeTrainerPools[biome];
this.updatePoolsForTimeOfDay(); this.updatePoolsForTimeOfDay();
this.playerTerasUsed = 0;
this.playerFaints = playerFaints; this.playerFaints = playerFaints;
} }

View File

@ -447,7 +447,9 @@ export class LoadingScene extends SceneBase {
); );
if (!mobile) { if (!mobile) {
loadingGraphics.map(g => g.setVisible(false)); loadingGraphics.forEach(g => {
g.setVisible(false);
});
} }
const intro = this.add.video(0, 0); const intro = this.add.video(0, 0);

View File

@ -121,8 +121,8 @@ export class ModifierBar extends Phaser.GameObjects.Container {
} }
updateModifierOverflowVisibility(ignoreLimit: boolean) { updateModifierOverflowVisibility(ignoreLimit: boolean) {
const modifierIcons = this.getAll().reverse(); const modifierIcons = this.getAll().reverse() as Phaser.GameObjects.Container[];
for (const modifier of modifierIcons.map(m => m as Phaser.GameObjects.Container).slice(iconOverflowIndex)) { for (const modifier of modifierIcons.slice(iconOverflowIndex)) {
modifier.setVisible(ignoreLimit); modifier.setVisible(ignoreLimit);
} }
} }

View File

@ -2,8 +2,10 @@ import { globalScene } from "#app/global-scene";
import type { PhaseMap, PhaseString } from "#types/phase-types"; import type { PhaseMap, PhaseString } from "#types/phase-types";
export abstract class Phase { export abstract class Phase {
/** Start the current phase. */
start() {} start() {}
/** End the current phase and start a new one. */
end() { end() {
globalScene.phaseManager.shiftPhase(); globalScene.phaseManager.shiftPhase();
} }

View File

@ -207,10 +207,12 @@ export interface StarterData {
[key: number]: StarterDataEntry; [key: number]: StarterDataEntry;
} }
export interface TutorialFlags { // TODO: Rework into a bitmask
[key: string]: boolean; export type TutorialFlags = {
} [key in Tutorial]: boolean;
};
// TODO: Rework into a bitmask
export interface SeenDialogues { export interface SeenDialogues {
[key: string]: boolean; [key: string]: boolean;
} }
@ -823,52 +825,51 @@ export class GameData {
return true; // TODO: is `true` the correct return value? return true; // TODO: is `true` the correct return value?
} }
private loadGamepadSettings(): boolean { private loadGamepadSettings(): void {
Object.values(SettingGamepad) Object.values(SettingGamepad).forEach(setting => {
.map(setting => setting as SettingGamepad) setSettingGamepad(setting, settingGamepadDefaults[setting]);
.forEach(setting => setSettingGamepad(setting, settingGamepadDefaults[setting])); });
if (!localStorage.hasOwnProperty("settingsGamepad")) { if (!localStorage.hasOwnProperty("settingsGamepad")) {
return false; return;
} }
const settingsGamepad = JSON.parse(localStorage.getItem("settingsGamepad")!); // TODO: is this bang correct? const settingsGamepad = JSON.parse(localStorage.getItem("settingsGamepad")!); // TODO: is this bang correct?
for (const setting of Object.keys(settingsGamepad)) { for (const setting of Object.keys(settingsGamepad)) {
setSettingGamepad(setting as SettingGamepad, settingsGamepad[setting]); setSettingGamepad(setting as SettingGamepad, settingsGamepad[setting]);
} }
return true; // TODO: is `true` the correct return value?
} }
public saveTutorialFlag(tutorial: Tutorial, flag: boolean): boolean { /**
const key = getDataTypeKey(GameDataType.TUTORIALS); * Save the specified tutorial as having the specified completion status.
let tutorials: object = {}; * @param tutorial - The {@linkcode Tutorial} whose completion status is being saved
if (localStorage.hasOwnProperty(key)) { * @param status - The completion status to set
tutorials = JSON.parse(localStorage.getItem(key)!); // TODO: is this bang correct? */
public saveTutorialFlag(tutorial: Tutorial, status: boolean): void {
// Grab the prior save data tutorial
const saveDataKey = getDataTypeKey(GameDataType.TUTORIALS);
const tutorials: TutorialFlags = localStorage.hasOwnProperty(saveDataKey)
? JSON.parse(localStorage.getItem(saveDataKey)!)
: {};
// TODO: We shouldn't be storing this like that
for (const key of Object.values(Tutorial)) {
if (key === tutorial) {
tutorials[key] = status;
} else {
tutorials[key] ??= false;
}
} }
Object.keys(Tutorial) localStorage.setItem(saveDataKey, JSON.stringify(tutorials));
.map(t => t as Tutorial)
.forEach(t => {
const key = Tutorial[t];
if (key === tutorial) {
tutorials[key] = flag;
} else {
tutorials[key] ??= false;
}
});
localStorage.setItem(key, JSON.stringify(tutorials));
return true;
} }
public getTutorialFlags(): TutorialFlags { public getTutorialFlags(): TutorialFlags {
const key = getDataTypeKey(GameDataType.TUTORIALS); const key = getDataTypeKey(GameDataType.TUTORIALS);
const ret: TutorialFlags = {}; const ret: TutorialFlags = Object.values(Tutorial).reduce((acc, tutorial) => {
Object.values(Tutorial) acc[Tutorial[tutorial]] = false;
.map(tutorial => tutorial as Tutorial) return acc;
.forEach(tutorial => (ret[Tutorial[tutorial]] = false)); }, {} as TutorialFlags);
if (!localStorage.hasOwnProperty(key)) { if (!localStorage.hasOwnProperty(key)) {
return ret; return ret;

View File

@ -26,6 +26,7 @@ import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text";
import { UiHandler } from "#ui/ui-handler"; import { UiHandler } from "#ui/ui-handler";
import { addWindow } from "#ui/ui-theme"; import { addWindow } from "#ui/ui-theme";
import { formatFancyLargeNumber, formatLargeNumber, formatMoney, getPlayTimeString } from "#utils/common"; import { formatFancyLargeNumber, formatLargeNumber, formatMoney, getPlayTimeString } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
import RoundRectangle from "phaser3-rex-plugins/plugins/roundrectangle"; import RoundRectangle from "phaser3-rex-plugins/plugins/roundrectangle";
@ -706,10 +707,7 @@ export class RunInfoUiHandler extends UiHandler {
rules.push(i18next.t("challenges:inverseBattle.shortName")); rules.push(i18next.t("challenges:inverseBattle.shortName"));
break; break;
default: { default: {
const localizationKey = Challenges[this.runInfo.challenges[i].id] const localizationKey = toCamelCase(Challenges[this.runInfo.challenges[i].id]);
.split("_")
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join("");
rules.push(i18next.t(`challenges:${localizationKey}.name`)); rules.push(i18next.t(`challenges:${localizationKey}.name`));
break; break;
} }

View File

@ -31,7 +31,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler {
// we check for null or undefined here as per above - the typeof is still an object but the value is null so we need to exit out of this and pass the null key // we check for null or undefined here as per above - the typeof is still an object but the value is null so we need to exit out of this and pass the null key
// Return in the format expected by i18next // Return in the format expected by i18next
return middleKey ? `${topKey}:${middleKey.map(m => m).join(".")}.${t}` : `${topKey}:${t}`; return middleKey ? `${topKey}:${middleKey.join(".")}.${t}` : `${topKey}:${t}`;
} }
}) })
.filter(t => t); .filter(t => t);

View File

@ -3,9 +3,6 @@ import { BattlerIndex } from "#enums/battler-index";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { EnemyCommandPhase } from "#phases/enemy-command-phase";
import { TurnEndPhase } from "#phases/turn-end-phase";
import { VictoryPhase } from "#phases/victory-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -46,7 +43,7 @@ describe("Abilities - Moxie", () => {
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0);
game.move.select(moveToUse); game.move.select(moveToUse);
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(VictoryPhase); await game.phaseInterceptor.to("VictoryPhase");
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(1); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(1);
}); });
@ -67,7 +64,7 @@ describe("Abilities - Moxie", () => {
game.move.select(moveToUse, BattlerIndex.PLAYER_2); game.move.select(moveToUse, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(firstPokemon.getStatStage(Stat.ATK)).toBe(1); expect(firstPokemon.getStatStage(Stat.ATK)).toBe(1);
}, },

View File

@ -1,9 +1,7 @@
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { EnemyCommandPhase } from "#phases/enemy-command-phase"; import type { TurnStartPhase } from "#phases/turn-start-phase";
import { SelectTargetPhase } from "#phases/select-target-phase";
import { TurnStartPhase } from "#phases/turn-start-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
@ -41,7 +39,7 @@ describe("Battle order", () => {
vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set enemyPokemon's speed to 150 vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set enemyPokemon's speed to 150
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.run(EnemyCommandPhase); await game.phaseInterceptor.to("TurnStartPhase", false);
const playerPokemonIndex = playerPokemon.getBattlerIndex(); const playerPokemonIndex = playerPokemon.getBattlerIndex();
const enemyPokemonIndex = enemyPokemon.getBattlerIndex(); const enemyPokemonIndex = enemyPokemon.getBattlerIndex();
@ -60,7 +58,7 @@ describe("Battle order", () => {
vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 50]); // set enemyPokemon's speed to 50 vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 50]); // set enemyPokemon's speed to 50
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.run(EnemyCommandPhase); await game.phaseInterceptor.to("TurnStartPhase", false);
const playerPokemonIndex = playerPokemon.getBattlerIndex(); const playerPokemonIndex = playerPokemon.getBattlerIndex();
const enemyPokemonIndex = enemyPokemon.getBattlerIndex(); const enemyPokemonIndex = enemyPokemon.getBattlerIndex();
@ -84,7 +82,7 @@ describe("Battle order", () => {
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
game.move.select(MoveId.TACKLE, 1); game.move.select(MoveId.TACKLE, 1);
await game.phaseInterceptor.runFrom(SelectTargetPhase).to(TurnStartPhase, false); await game.phaseInterceptor.to("TurnStartPhase", false);
const phase = game.scene.phaseManager.getCurrentPhase() as TurnStartPhase; const phase = game.scene.phaseManager.getCurrentPhase() as TurnStartPhase;
const order = phase.getCommandOrder(); const order = phase.getCommandOrder();
@ -108,7 +106,7 @@ describe("Battle order", () => {
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
game.move.select(MoveId.TACKLE, 1); game.move.select(MoveId.TACKLE, 1);
await game.phaseInterceptor.runFrom(SelectTargetPhase).to(TurnStartPhase, false); await game.phaseInterceptor.to("TurnStartPhase", false);
const phase = game.scene.phaseManager.getCurrentPhase() as TurnStartPhase; const phase = game.scene.phaseManager.getCurrentPhase() as TurnStartPhase;
const order = phase.getCommandOrder(); const order = phase.getCommandOrder();
@ -132,7 +130,7 @@ describe("Battle order", () => {
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
game.move.select(MoveId.TACKLE, 1); game.move.select(MoveId.TACKLE, 1);
await game.phaseInterceptor.runFrom(SelectTargetPhase).to(TurnStartPhase, false); await game.phaseInterceptor.to("TurnStartPhase", false);
const phase = game.scene.phaseManager.getCurrentPhase() as TurnStartPhase; const phase = game.scene.phaseManager.getCurrentPhase() as TurnStartPhase;
const order = phase.getCommandOrder(); const order = phase.getCommandOrder();

View File

@ -1,28 +1,13 @@
import { getGameMode } from "#app/game-mode";
import { allSpecies } from "#data/data-lists"; import { allSpecies } from "#data/data-lists";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BiomeId } from "#enums/biome-id"; import { BiomeId } from "#enums/biome-id";
import { GameModes } from "#enums/game-modes";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { PlayerGender } from "#enums/player-gender";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { BattleEndPhase } from "#phases/battle-end-phase";
import { CommandPhase } from "#phases/command-phase"; import { CommandPhase } from "#phases/command-phase";
import { DamageAnimPhase } from "#phases/damage-anim-phase";
import { EncounterPhase } from "#phases/encounter-phase";
import { EnemyCommandPhase } from "#phases/enemy-command-phase";
import { LoginPhase } from "#phases/login-phase";
import { NextEncounterPhase } from "#phases/next-encounter-phase"; import { NextEncounterPhase } from "#phases/next-encounter-phase";
import { SelectGenderPhase } from "#phases/select-gender-phase";
import { SelectStarterPhase } from "#phases/select-starter-phase";
import { SummonPhase } from "#phases/summon-phase";
import { SwitchPhase } from "#phases/switch-phase";
import { TitlePhase } from "#phases/title-phase";
import { TurnInitPhase } from "#phases/turn-init-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import { generateStarter } from "#test/test-utils/game-manager-utils";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
@ -45,55 +30,11 @@ describe("Phase - Battle Phase", () => {
game.scene.gameData.gender = undefined!; // just for these tests! game.scene.gameData.gender = undefined!; // just for these tests!
}); });
it("test phase interceptor with prompt", async () => {
await game.phaseInterceptor.run(LoginPhase);
game.onNextPrompt("SelectGenderPhase", UiMode.OPTION_SELECT, () => {
game.scene.gameData.gender = PlayerGender.MALE;
game.endPhase();
});
await game.phaseInterceptor.run(SelectGenderPhase);
await game.phaseInterceptor.run(TitlePhase);
await game.waitMode(UiMode.TITLE);
expect(game.scene.ui?.getMode()).toBe(UiMode.TITLE);
expect(game.scene.gameData.gender).toBe(PlayerGender.MALE);
});
it("test phase interceptor with prompt with preparation for a future prompt", async () => {
await game.phaseInterceptor.run(LoginPhase);
game.onNextPrompt("SelectGenderPhase", UiMode.OPTION_SELECT, () => {
game.scene.gameData.gender = PlayerGender.MALE;
game.endPhase();
});
game.onNextPrompt("CheckSwitchPhase", UiMode.CONFIRM, () => {
game.setMode(UiMode.MESSAGE);
game.endPhase();
});
await game.phaseInterceptor.run(SelectGenderPhase);
await game.phaseInterceptor.run(TitlePhase);
await game.waitMode(UiMode.TITLE);
expect(game.scene.ui?.getMode()).toBe(UiMode.TITLE);
expect(game.scene.gameData.gender).toBe(PlayerGender.MALE);
});
it("newGame one-liner", async () => {
await game.classicMode.startBattle();
expect(game.scene.ui?.getMode()).toBe(UiMode.COMMAND);
expect(game.scene.phaseManager.getCurrentPhase()?.phaseName).toBe("CommandPhase");
});
it("do attack wave 3 - single battle - regular - OHKO", async () => { it("do attack wave 3 - single battle - regular - OHKO", async () => {
game.override.enemySpecies(SpeciesId.RATTATA).startingLevel(2000).battleStyle("single").startingWave(3); game.override.enemySpecies(SpeciesId.RATTATA).startingLevel(2000).battleStyle("single").startingWave(3);
await game.classicMode.startBattle([SpeciesId.MEWTWO]); await game.classicMode.startBattle([SpeciesId.MEWTWO]);
game.move.use(MoveId.TACKLE); game.move.use(MoveId.TACKLE);
await game.phaseInterceptor.to("SelectModifierPhase"); await game.toNextWave();
}); });
it("do attack wave 3 - single battle - regular - NO OHKO with opponent using non damage attack", async () => { it("do attack wave 3 - single battle - regular - NO OHKO with opponent using non damage attack", async () => {
@ -107,7 +48,7 @@ describe("Phase - Battle Phase", () => {
.battleStyle("single"); .battleStyle("single");
await game.classicMode.startBattle([SpeciesId.MEWTWO]); await game.classicMode.startBattle([SpeciesId.MEWTWO]);
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnInitPhase, false); await game.phaseInterceptor.to("TurnInitPhase", false);
}); });
it("load 100% data file", async () => { it("load 100% data file", async () => {
@ -135,68 +76,6 @@ describe("Phase - Battle Phase", () => {
} }
}); });
it("wrong phase", async () => {
await game.phaseInterceptor.run(LoginPhase);
await game.phaseInterceptor.run(LoginPhase).catch(e => {
expect(e).toBe("Wrong phase: this is SelectGenderPhase and not LoginPhase");
});
});
it("wrong phase but skip", async () => {
await game.phaseInterceptor.run(LoginPhase);
await game.phaseInterceptor.run(LoginPhase, () => game.isCurrentPhase(SelectGenderPhase));
});
it("good run", async () => {
await game.phaseInterceptor.run(LoginPhase);
game.onNextPrompt(
"SelectGenderPhase",
UiMode.OPTION_SELECT,
() => {
game.scene.gameData.gender = PlayerGender.MALE;
game.endPhase();
},
() => game.isCurrentPhase(TitlePhase),
);
await game.phaseInterceptor.run(SelectGenderPhase, () => game.isCurrentPhase(TitlePhase));
await game.phaseInterceptor.run(TitlePhase);
});
it("good run from select gender to title", async () => {
await game.phaseInterceptor.run(LoginPhase);
game.onNextPrompt(
"SelectGenderPhase",
UiMode.OPTION_SELECT,
() => {
game.scene.gameData.gender = PlayerGender.MALE;
game.endPhase();
},
() => game.isCurrentPhase(TitlePhase),
);
await game.phaseInterceptor.runFrom(SelectGenderPhase).to(TitlePhase);
});
it("good run to SummonPhase phase", async () => {
await game.phaseInterceptor.run(LoginPhase);
game.onNextPrompt(
"SelectGenderPhase",
UiMode.OPTION_SELECT,
() => {
game.scene.gameData.gender = PlayerGender.MALE;
game.endPhase();
},
() => game.isCurrentPhase(TitlePhase),
);
game.onNextPrompt("TitlePhase", UiMode.TITLE, () => {
game.scene.gameMode = getGameMode(GameModes.CLASSIC);
const starters = generateStarter(game.scene);
const selectStarterPhase = new SelectStarterPhase();
game.scene.phaseManager.pushPhase(new EncounterPhase(false));
selectStarterPhase.initBattle(starters);
});
await game.phaseInterceptor.runFrom(SelectGenderPhase).to(SummonPhase);
});
it.each([ it.each([
{ name: "1v1", double: false, qty: 1 }, { name: "1v1", double: false, qty: 1 },
{ name: "2v1", double: false, qty: 2 }, { name: "2v1", double: false, qty: 2 },
@ -232,7 +111,7 @@ describe("Phase - Battle Phase", () => {
await game.classicMode.startBattle([SpeciesId.DARMANITAN, SpeciesId.CHARIZARD]); await game.classicMode.startBattle([SpeciesId.DARMANITAN, SpeciesId.CHARIZARD]);
game.move.select(moveToUse); game.move.select(moveToUse);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
await game.killPokemon(game.scene.currentBattle.enemyParty[0]); await game.killPokemon(game.scene.currentBattle.enemyParty[0]);
expect(game.scene.currentBattle.enemyParty[0].isFainted()).toBe(true); expect(game.scene.currentBattle.enemyParty[0].isFainted()).toBe(true);
await game.phaseInterceptor.to("VictoryPhase"); await game.phaseInterceptor.to("VictoryPhase");
@ -296,7 +175,7 @@ describe("Phase - Battle Phase", () => {
game.field.getPlayerPokemon().hp = 1; game.field.getPlayerPokemon().hp = 1;
game.move.select(moveToUse); game.move.select(moveToUse);
await game.phaseInterceptor.to(BattleEndPhase); await game.phaseInterceptor.to("BattleEndPhase");
game.doRevivePokemon(0); // pretend max revive was picked game.doRevivePokemon(0); // pretend max revive was picked
game.doSelectModifier(); game.doSelectModifier();
@ -308,6 +187,6 @@ describe("Phase - Battle Phase", () => {
}, },
() => game.isCurrentPhase(NextEncounterPhase), () => game.isCurrentPhase(NextEncounterPhase),
); );
await game.phaseInterceptor.to(SwitchPhase); await game.phaseInterceptor.to("SwitchPhase");
}); });
}); });

View File

@ -6,7 +6,6 @@ import { SpeciesId } from "#enums/species-id";
import { BATTLE_STATS, Stat } from "#enums/stat"; import { BATTLE_STATS, Stat } from "#enums/stat";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { TempStatStageBoosterModifier } from "#modifiers/modifier"; import { TempStatStageBoosterModifier } from "#modifiers/modifier";
import { TurnEndPhase } from "#phases/turn-end-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler";
import Phaser from "phaser"; import Phaser from "phaser";
@ -47,7 +46,7 @@ describe("Items - Temporary Stat Stage Boosters", () => {
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.runFrom("EnemyCommandPhase").to(TurnEndPhase); await game.toEndOfTurn();
expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(1.3); expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(1.3);
}); });
@ -64,11 +63,11 @@ describe("Items - Temporary Stat Stage Boosters", () => {
// Raise ACC by +2 stat stages // Raise ACC by +2 stat stages
game.move.select(MoveId.HONE_CLAWS); game.move.select(MoveId.HONE_CLAWS);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
// ACC at +3 stat stages yields a x2 multiplier // ACC at +3 stat stages yields a x2 multiplier
expect(partyMember.getAccuracyMultiplier).toHaveReturnedWith(2); expect(partyMember.getAccuracyMultiplier).toHaveReturnedWith(2);
@ -84,11 +83,11 @@ describe("Items - Temporary Stat Stage Boosters", () => {
// Raise ATK by +1 stat stage // Raise ATK by +1 stat stage
game.move.select(MoveId.HONE_CLAWS); game.move.select(MoveId.HONE_CLAWS);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
// ATK at +1 stat stage yields a x1.5 multiplier, add 0.3 from X_ATTACK // ATK at +1 stat stage yields a x1.5 multiplier, add 0.3 from X_ATTACK
expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(1.8); expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(1.8);
@ -112,7 +111,7 @@ describe("Items - Temporary Stat Stage Boosters", () => {
game.move.select(MoveId.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(partyMember.getAccuracyMultiplier).toHaveReturnedWith(3); expect(partyMember.getAccuracyMultiplier).toHaveReturnedWith(3);
expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(4); expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(4);

View File

@ -4,10 +4,7 @@ import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import type { Move } from "#moves/move"; import type { Move } from "#moves/move";
import { DamageAnimPhase } from "#phases/damage-anim-phase"; import type { MoveEffectPhase } from "#phases/move-effect-phase";
import { MoveEffectPhase } from "#phases/move-effect-phase";
import { MoveEndPhase } from "#phases/move-end-phase";
import { MovePhase } from "#phases/move-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
@ -55,14 +52,14 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
// Force user party to act before enemy party // Force user party to act before enemy party
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200);
}); });
@ -75,14 +72,14 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
// Force user party to act before enemy party // Force user party to act before enemy party
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
}); });
@ -95,19 +92,19 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
// Force first enemy to act (and fail) in between party // Force first enemy to act (and fail) in between party
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100);
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to("MoveEndPhase");
// Skip enemy move; because the enemy is at full HP, Rest should fail // Skip enemy move; because the enemy is at full HP, Rest should fail
await game.phaseInterceptor.runFrom(MovePhase).to(MoveEndPhase); await game.phaseInterceptor.to("MoveEndPhase");
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200);
}); });
@ -121,18 +118,18 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
// Force first enemy to act in between party // Force first enemy to act in between party
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100);
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to("MoveEndPhase");
// Skip enemy move // Skip enemy move
await game.phaseInterceptor.runFrom(MovePhase).to(MoveEndPhase); await game.phaseInterceptor.to("MoveEndPhase");
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100);
}); });
@ -145,14 +142,14 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
// Force user party to act before enemy party // Force user party to act before enemy party
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
}); });
@ -189,24 +186,24 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
// Force first enemy to act in between party // Force first enemy to act in between party
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
}); });
@ -243,24 +240,24 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
// Force first enemy to act in between party // Force first enemy to act in between party
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to("MoveEffectPhase", false);
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to("DamageAnimPhase", false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
}); });
}); });

View File

@ -2,8 +2,6 @@ import { AbilityId } from "#enums/ability-id";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { EnemyCommandPhase } from "#phases/enemy-command-phase";
import { TurnInitPhase } from "#phases/turn-init-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -40,7 +38,7 @@ describe("Moves - Growth", () => {
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0);
game.move.select(MoveId.GROWTH); game.move.select(MoveId.GROWTH);
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnInitPhase); await game.toEndOfTurn();
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(1); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(1);
}); });

View File

@ -2,10 +2,6 @@ import { AbilityId } from "#enums/ability-id";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { BerryPhase } from "#phases/berry-phase";
import { FaintPhase } from "#phases/faint-phase";
import { MessagePhase } from "#phases/message-phase";
import { TurnInitPhase } from "#phases/turn-init-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, test } from "vitest";
@ -43,7 +39,7 @@ describe("Moves - Parting Shot", () => {
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
@ -58,7 +54,7 @@ describe("Moves - Parting Shot", () => {
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
@ -79,24 +75,24 @@ describe("Moves - Parting Shot", () => {
// use Memento 3 times to debuff enemy // use Memento 3 times to debuff enemy
game.move.select(MoveId.MEMENTO); game.move.select(MoveId.MEMENTO);
await game.phaseInterceptor.to(FaintPhase); await game.phaseInterceptor.to("FaintPhase");
expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true); expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true);
game.doSelectPartyPokemon(1); game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to(TurnInitPhase, false); await game.phaseInterceptor.to("TurnInitPhase", false);
game.move.select(MoveId.MEMENTO); game.move.select(MoveId.MEMENTO);
await game.phaseInterceptor.to(FaintPhase); await game.phaseInterceptor.to("FaintPhase");
expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true); expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true);
game.doSelectPartyPokemon(2); game.doSelectPartyPokemon(2);
await game.phaseInterceptor.to(TurnInitPhase, false); await game.phaseInterceptor.to("TurnInitPhase", false);
game.move.select(MoveId.MEMENTO); game.move.select(MoveId.MEMENTO);
await game.phaseInterceptor.to(FaintPhase); await game.phaseInterceptor.to("FaintPhase");
expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true); expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true);
game.doSelectPartyPokemon(3); game.doSelectPartyPokemon(3);
// set up done // set up done
await game.phaseInterceptor.to(TurnInitPhase, false); await game.phaseInterceptor.to("TurnInitPhase", false);
const enemyPokemon = game.field.getEnemyPokemon(); const enemyPokemon = game.field.getEnemyPokemon();
expect(enemyPokemon).toBeDefined(); expect(enemyPokemon).toBeDefined();
@ -106,7 +102,7 @@ describe("Moves - Parting Shot", () => {
// now parting shot should fail // now parting shot should fail
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-6); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-6);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-6); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-6);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
@ -125,7 +121,7 @@ describe("Moves - Parting Shot", () => {
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
@ -144,7 +140,7 @@ describe("Moves - Parting Shot", () => {
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
@ -153,43 +149,24 @@ describe("Moves - Parting Shot", () => {
it.todo( it.todo(
// TODO: fix this bug to pass the test! // TODO: fix this bug to pass the test!
"Parting shot should de-buff and not fail if no party available to switch - party size 1", "should lower stats without failing if no alive party members available to switch",
async () => {
await game.classicMode.startBattle([SpeciesId.MURKROW]);
const enemyPokemon = game.field.getEnemyPokemon();
expect(enemyPokemon).toBeDefined();
game.move.select(MoveId.PARTING_SHOT);
await game.phaseInterceptor.to(BerryPhase, false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-1);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW);
},
);
it.todo(
// TODO: fix this bug to pass the test!
"Parting shot regularly not fail if no party available to switch - party fainted",
async () => { async () => {
await game.classicMode.startBattle([SpeciesId.MURKROW, SpeciesId.MEOWTH]); await game.classicMode.startBattle([SpeciesId.MURKROW, SpeciesId.MEOWTH]);
const meowth = game.scene.getPlayerParty()[1];
meowth.hp = 0;
game.move.select(MoveId.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn();
// intentionally kill party pokemon, switch to second slot (now 1 party mon is fainted)
await game.killPokemon(game.scene.getPlayerParty()[0]);
expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true);
await game.phaseInterceptor.run(MessagePhase);
game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to(TurnInitPhase, false);
game.move.select(MoveId.PARTING_SHOT); game.move.select(MoveId.PARTING_SHOT);
game.doSelectPartyPokemon(1);
await game.toEndOfTurn();
await game.phaseInterceptor.to(BerryPhase, false);
const enemyPokemon = game.field.getEnemyPokemon(); const enemyPokemon = game.field.getEnemyPokemon();
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MEOWTH); expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.MURKROW);
}, },
); );
}); });

View File

@ -1,8 +1,6 @@
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { EnemyCommandPhase } from "#phases/enemy-command-phase";
import { TurnEndPhase } from "#phases/turn-end-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -41,7 +39,7 @@ describe("Moves - Tackle", () => {
await game.classicMode.startBattle([SpeciesId.MIGHTYENA]); await game.classicMode.startBattle([SpeciesId.MIGHTYENA]);
const hpOpponent = game.scene.currentBattle.enemyParty[0].hp; const hpOpponent = game.scene.currentBattle.enemyParty[0].hp;
game.move.select(moveToUse); game.move.select(moveToUse);
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnEndPhase); await game.toEndOfTurn();
const hpLost = hpOpponent - game.scene.currentBattle.enemyParty[0].hp; const hpLost = hpOpponent - game.scene.currentBattle.enemyParty[0].hp;
expect(hpLost).toBe(0); expect(hpLost).toBe(0);
}); });
@ -55,7 +53,7 @@ describe("Moves - Tackle", () => {
const hpOpponent = game.scene.currentBattle.enemyParty[0].hp; const hpOpponent = game.scene.currentBattle.enemyParty[0].hp;
game.move.select(moveToUse); game.move.select(moveToUse);
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnEndPhase); await game.toEndOfTurn();
const hpLost = hpOpponent - game.scene.currentBattle.enemyParty[0].hp; const hpLost = hpOpponent - game.scene.currentBattle.enemyParty[0].hp;
expect(hpLost).toBeGreaterThan(0); expect(hpLost).toBeGreaterThan(0);
expect(hpLost).toBeLessThan(4); expect(hpLost).toBeLessThan(4);

View File

@ -2,8 +2,6 @@ import { AbilityId } from "#enums/ability-id";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { EnemyCommandPhase } from "#phases/enemy-command-phase";
import { TurnInitPhase } from "#phases/turn-init-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -43,7 +41,7 @@ describe("Moves - Tail whip", () => {
expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(0); expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(0);
game.move.select(moveToUse); game.move.select(moveToUse);
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnInitPhase); await game.toEndOfTurn();
expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(-1); expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(-1);
}); });

View File

@ -9,7 +9,6 @@ import { MessagePhase } from "#phases/message-phase";
import { import {
MysteryEncounterBattlePhase, MysteryEncounterBattlePhase,
MysteryEncounterOptionSelectedPhase, MysteryEncounterOptionSelectedPhase,
MysteryEncounterPhase,
MysteryEncounterRewardsPhase, MysteryEncounterRewardsPhase,
} from "#phases/mystery-encounter-phases"; } from "#phases/mystery-encounter-phases";
import { VictoryPhase } from "#phases/victory-phase"; import { VictoryPhase } from "#phases/victory-phase";
@ -89,9 +88,9 @@ export async function runMysteryEncounterToEnd(
uiHandler.processInput(Button.ACTION); uiHandler.processInput(Button.ACTION);
}); });
await game.phaseInterceptor.to(CommandPhase); await game.toNextTurn();
} else { } else {
await game.phaseInterceptor.to(MysteryEncounterRewardsPhase); await game.phaseInterceptor.to("MysteryEncounterRewardsPhase");
} }
} }
@ -112,7 +111,7 @@ export async function runSelectMysteryEncounterOption(
); );
if (game.isCurrentPhase(MessagePhase)) { if (game.isCurrentPhase(MessagePhase)) {
await game.phaseInterceptor.run(MessagePhase); await game.phaseInterceptor.to("MessagePhase");
} }
// dispose of intro messages // dispose of intro messages
@ -126,7 +125,7 @@ export async function runSelectMysteryEncounterOption(
() => game.isCurrentPhase(MysteryEncounterOptionSelectedPhase), () => game.isCurrentPhase(MysteryEncounterOptionSelectedPhase),
); );
await game.phaseInterceptor.to(MysteryEncounterPhase, true); await game.phaseInterceptor.to("MysteryEncounterPhase", true);
// select the desired option // select the desired option
const uiHandler = game.scene.ui.getHandler<MysteryEncounterUiHandler>(); const uiHandler = game.scene.ui.getHandler<MysteryEncounterUiHandler>();
@ -205,7 +204,7 @@ export async function skipBattleRunMysteryEncounterRewardsPhase(game: GameManage
game.scene.field.remove(p); game.scene.field.remove(p);
}); });
game.scene.phaseManager.pushPhase(new VictoryPhase(0)); game.scene.phaseManager.pushPhase(new VictoryPhase(0));
game.phaseInterceptor.superEndPhase(); game.endPhase();
game.setMode(UiMode.MESSAGE); game.setMode(UiMode.MESSAGE);
await game.phaseInterceptor.to(MysteryEncounterRewardsPhase, runRewardsPhase); await game.phaseInterceptor.to("MysteryEncounterRewardsPhase", runRewardsPhase);
} }

View File

@ -134,7 +134,7 @@ describe("Berries Abound - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 1, undefined, true); await runMysteryEncounterToEnd(game, 1, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
const berriesAfter = scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[]; const berriesAfter = scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
@ -147,9 +147,7 @@ describe("Berries Abound - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
await runMysteryEncounterToEnd(game, 1, undefined, true); await runMysteryEncounterToEnd(game, 1, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase);
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -232,9 +230,9 @@ describe("Berries Abound - Mystery Encounter", () => {
}); });
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -368,9 +368,9 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterRewardsPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterRewardsPhase.name);
game.phaseInterceptor["prompts"] = []; // Clear out prompt handlers game.phaseInterceptor["prompts"] = []; // Clear out prompt handlers
game.onNextPrompt("MysteryEncounterRewardsPhase", UiMode.OPTION_SELECT, () => { game.onNextPrompt("MysteryEncounterRewardsPhase", UiMode.OPTION_SELECT, () => {
game.phaseInterceptor.superEndPhase(); game.endPhase();
}); });
await game.phaseInterceptor.run(MysteryEncounterRewardsPhase); await game.phaseInterceptor.to("MysteryEncounterRewardsPhase");
expect(selectOptionSpy).toHaveBeenCalledTimes(1); expect(selectOptionSpy).toHaveBeenCalledTimes(1);
const optionData = selectOptionSpy.mock.calls[0][0]; const optionData = selectOptionSpy.mock.calls[0][0];
@ -395,7 +395,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
it("should NOT be selectable if the player doesn't have any Bug types", async () => { it("should NOT be selectable if the player doesn't have any Bug types", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [SpeciesId.ABRA]); await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [SpeciesId.ABRA]);
await game.phaseInterceptor.to(MysteryEncounterPhase, false); await game.phaseInterceptor.to("MysteryEncounterPhase", false);
const encounterPhase = scene.phaseManager.getCurrentPhase(); const encounterPhase = scene.phaseManager.getCurrentPhase();
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
@ -417,7 +417,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -436,7 +436,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -458,7 +458,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -482,7 +482,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -530,7 +530,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
it("should NOT be selectable if the player doesn't have any Bug items", async () => { it("should NOT be selectable if the player doesn't have any Bug items", async () => {
game.scene.modifiers = []; game.scene.modifiers = [];
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
await game.phaseInterceptor.to(MysteryEncounterPhase, false); await game.phaseInterceptor.to("MysteryEncounterPhase", false);
game.scene.modifiers = []; game.scene.modifiers = [];
const encounterPhase = scene.phaseManager.getCurrentPhase(); const encounterPhase = scene.phaseManager.getCurrentPhase();
@ -558,7 +558,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 });
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -25,7 +25,6 @@ import * as MysteryEncounters from "#mystery-encounters/mystery-encounters";
import { CommandPhase } from "#phases/command-phase"; import { CommandPhase } from "#phases/command-phase";
import { MovePhase } from "#phases/move-phase"; import { MovePhase } from "#phases/move-phase";
import { PostMysteryEncounterPhase } from "#phases/mystery-encounter-phases"; import { PostMysteryEncounterPhase } from "#phases/mystery-encounter-phases";
import { NewBattlePhase } from "#phases/new-battle-phase";
import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { SelectModifierPhase } from "#phases/select-modifier-phase";
import { import {
runMysteryEncounterToEnd, runMysteryEncounterToEnd,
@ -200,9 +199,9 @@ describe("Clowning Around - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
await runMysteryEncounterToEnd(game, 1, undefined, true); await runMysteryEncounterToEnd(game, 1, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
const abilityToTrain = scene.currentBattle.mysteryEncounter?.misc.ability; const abilityToTrain = scene.currentBattle.mysteryEncounter?.misc.ability;
game.onNextPrompt("PostMysteryEncounterPhase", UiMode.MESSAGE, () => { game.onNextPrompt("PostMysteryEncounterPhase", UiMode.MESSAGE, () => {
@ -215,7 +214,7 @@ describe("Clowning Around - Mystery Encounter", () => {
const partyUiHandler = game.scene.ui.handlers[UiMode.PARTY] as PartyUiHandler; const partyUiHandler = game.scene.ui.handlers[UiMode.PARTY] as PartyUiHandler;
vi.spyOn(partyUiHandler, "show"); vi.spyOn(partyUiHandler, "show");
game.endPhase(); game.endPhase();
await game.phaseInterceptor.to(PostMysteryEncounterPhase); await game.phaseInterceptor.to("PostMysteryEncounterPhase");
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(PostMysteryEncounterPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(PostMysteryEncounterPhase.name);
// Wait for Yes/No confirmation to appear // Wait for Yes/No confirmation to appear
@ -228,7 +227,7 @@ describe("Clowning Around - Mystery Encounter", () => {
// Click "Select" on Pokemon // Click "Select" on Pokemon
partyUiHandler.processInput(Button.ACTION); partyUiHandler.processInput(Button.ACTION);
// Stop next battle before it runs // Stop next battle before it runs
await game.phaseInterceptor.to(NewBattlePhase, false); await game.phaseInterceptor.to("NewBattlePhase", false);
const leadPokemon = scene.getPlayerParty()[0]; const leadPokemon = scene.getPlayerParty()[0];
expect(leadPokemon.customPokemonData?.ability).toBe(abilityToTrain); expect(leadPokemon.customPokemonData?.ability).toBe(abilityToTrain);

View File

@ -126,9 +126,9 @@ describe("Dancing Lessons - Mystery Encounter", () => {
partyLead.calculateStats(); partyLead.calculateStats();
await runMysteryEncounterToEnd(game, 1, undefined, true); await runMysteryEncounterToEnd(game, 1, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -215,7 +215,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
const partyCountBefore = scene.getPlayerParty().length; const partyCountBefore = scene.getPlayerParty().length;
scene.getPlayerParty().forEach(p => (p.moveset = [])); scene.getPlayerParty().forEach(p => (p.moveset = []));
await game.phaseInterceptor.to(MysteryEncounterPhase, false); await game.phaseInterceptor.to("MysteryEncounterPhase", false);
const encounterPhase = scene.phaseManager.getCurrentPhase(); const encounterPhase = scene.phaseManager.getCurrentPhase();
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);

View File

@ -94,7 +94,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
await runMysteryEncounterToEnd(game, 1); await runMysteryEncounterToEnd(game, 1);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -131,7 +131,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -171,7 +171,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
await runMysteryEncounterToEnd(game, 3); await runMysteryEncounterToEnd(game, 3);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -211,7 +211,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
await runMysteryEncounterToEnd(game, 4); await runMysteryEncounterToEnd(game, 4);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -122,9 +122,9 @@ describe("Fight or Flight - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 1, undefined, true); await runMysteryEncounterToEnd(game, 1, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -155,7 +155,7 @@ describe("Fight or Flight - Mystery Encounter", () => {
it("should NOT be selectable if the player doesn't have a Stealing move", async () => { it("should NOT be selectable if the player doesn't have a Stealing move", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty);
scene.getPlayerParty().forEach(p => (p.moveset = [])); scene.getPlayerParty().forEach(p => (p.moveset = []));
await game.phaseInterceptor.to(MysteryEncounterPhase, false); await game.phaseInterceptor.to("MysteryEncounterPhase", false);
const encounterPhase = scene.phaseManager.getCurrentPhase(); const encounterPhase = scene.phaseManager.getCurrentPhase();
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
@ -182,9 +182,9 @@ describe("Fight or Flight - Mystery Encounter", () => {
const item = game.scene.currentBattle.mysteryEncounter!.misc; const item = game.scene.currentBattle.mysteryEncounter!.misc;
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -120,7 +120,7 @@ describe("Fun And Games! - Mystery Encounter", () => {
it("should NOT be selectable if the player doesn't have enough money", async () => { it("should NOT be selectable if the player doesn't have enough money", async () => {
game.scene.money = 0; game.scene.money = 0;
await game.runToMysteryEncounter(MysteryEncounterType.FUN_AND_GAMES, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.FUN_AND_GAMES, defaultParty);
await game.phaseInterceptor.to(MysteryEncounterPhase, false); await game.phaseInterceptor.to("MysteryEncounterPhase", false);
const encounterPhase = scene.phaseManager.getCurrentPhase(); const encounterPhase = scene.phaseManager.getCurrentPhase();
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
@ -162,7 +162,7 @@ describe("Fun And Games! - Mystery Encounter", () => {
// Turn 3 // Turn 3
(game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL); (game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
// Rewards // Rewards
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
@ -181,11 +181,11 @@ describe("Fun And Games! - Mystery Encounter", () => {
// Skip minigame // Skip minigame
scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0; scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0;
(game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL); (game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
// Rewards // Rewards
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -210,11 +210,11 @@ describe("Fun And Games! - Mystery Encounter", () => {
wobbuffet.hp = Math.floor(0.2 * wobbuffet.getMaxHp()); wobbuffet.hp = Math.floor(0.2 * wobbuffet.getMaxHp());
scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0; scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0;
(game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL); (game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
// Rewards // Rewards
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -240,11 +240,11 @@ describe("Fun And Games! - Mystery Encounter", () => {
wobbuffet.hp = Math.floor(0.1 * wobbuffet.getMaxHp()); wobbuffet.hp = Math.floor(0.1 * wobbuffet.getMaxHp());
scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0; scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0;
(game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL); (game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
// Rewards // Rewards
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -270,11 +270,11 @@ describe("Fun And Games! - Mystery Encounter", () => {
wobbuffet.hp = 1; wobbuffet.hp = 1;
scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0; scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0;
(game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL); (game.scene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, 0, MoveUseMode.NORMAL);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
// Rewards // Rewards
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -227,7 +227,7 @@ describe("Global Trade System - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 });
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -161,9 +161,9 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
await runMysteryEncounterToEnd(game, 1, undefined, true); await runMysteryEncounterToEnd(game, 1, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -205,9 +205,9 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
await runMysteryEncounterToEnd(game, 2, undefined, true); await runMysteryEncounterToEnd(game, 2, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -262,9 +262,9 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
await runMysteryEncounterToEnd(game, 3, undefined, true); await runMysteryEncounterToEnd(game, 3, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -146,7 +146,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => {
it("should NOT be selectable if the player doesn't have enough money", async () => { it("should NOT be selectable if the player doesn't have enough money", async () => {
game.scene.money = 0; game.scene.money = 0;
await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty);
await game.phaseInterceptor.to(MysteryEncounterPhase, false); await game.phaseInterceptor.to("MysteryEncounterPhase", false);
const encounterPhase = scene.phaseManager.getCurrentPhase(); const encounterPhase = scene.phaseManager.getCurrentPhase();
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
@ -218,7 +218,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => {
it("should NOT be selectable if the player doesn't the right type pokemon", async () => { it("should NOT be selectable if the player doesn't the right type pokemon", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [SpeciesId.BLASTOISE]); await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, [SpeciesId.BLASTOISE]);
await game.phaseInterceptor.to(MysteryEncounterPhase, false); await game.phaseInterceptor.to("MysteryEncounterPhase", false);
const encounterPhase = scene.phaseManager.getCurrentPhase(); const encounterPhase = scene.phaseManager.getCurrentPhase();
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
@ -299,9 +299,9 @@ describe("Teleporting Hijinks - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty);
await runMysteryEncounterToEnd(game, 3, undefined, true); await runMysteryEncounterToEnd(game, 3, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -13,7 +13,6 @@ import * as MysteryEncounters from "#mystery-encounters/mystery-encounters";
import { HUMAN_TRANSITABLE_BIOMES } from "#mystery-encounters/mystery-encounters"; import { HUMAN_TRANSITABLE_BIOMES } from "#mystery-encounters/mystery-encounters";
import { TheExpertPokemonBreederEncounter } from "#mystery-encounters/the-expert-pokemon-breeder-encounter"; import { TheExpertPokemonBreederEncounter } from "#mystery-encounters/the-expert-pokemon-breeder-encounter";
import { CommandPhase } from "#phases/command-phase"; import { CommandPhase } from "#phases/command-phase";
import { PostMysteryEncounterPhase } from "#phases/mystery-encounter-phases";
import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { SelectModifierPhase } from "#phases/select-modifier-phase";
import { import {
runMysteryEncounterToEnd, runMysteryEncounterToEnd,
@ -176,7 +175,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 1, undefined, true); await runMysteryEncounterToEnd(game, 1, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
const eggsAfter = scene.gameData.eggs; const eggsAfter = scene.gameData.eggs;
@ -187,8 +186,8 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => {
expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs);
expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs);
game.phaseInterceptor.superEndPhase(); game.endPhase();
await game.phaseInterceptor.to(PostMysteryEncounterPhase); await game.phaseInterceptor.to("PostMysteryEncounterPhase");
const friendshipAfter = scene.currentBattle.mysteryEncounter!.misc.pokemon1.friendship; const friendshipAfter = scene.currentBattle.mysteryEncounter!.misc.pokemon1.friendship;
// 20 from ME + extra from winning battle (that extra is not accurate to what happens in game. // 20 from ME + extra from winning battle (that extra is not accurate to what happens in game.
@ -261,7 +260,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 2, undefined, true); await runMysteryEncounterToEnd(game, 2, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
const eggsAfter = scene.gameData.eggs; const eggsAfter = scene.gameData.eggs;
@ -272,8 +271,8 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => {
expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs);
expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs);
game.phaseInterceptor.superEndPhase(); game.endPhase();
await game.phaseInterceptor.to(PostMysteryEncounterPhase); await game.phaseInterceptor.to("PostMysteryEncounterPhase");
const friendshipAfter = scene.currentBattle.mysteryEncounter!.misc.pokemon2.friendship; const friendshipAfter = scene.currentBattle.mysteryEncounter!.misc.pokemon2.friendship;
expect(friendshipAfter).toBe(friendshipBefore + 20 + FRIENDSHIP_GAIN_FROM_BATTLE); // 20 from ME + extra for friendship gained from winning battle expect(friendshipAfter).toBe(friendshipBefore + 20 + FRIENDSHIP_GAIN_FROM_BATTLE); // 20 from ME + extra for friendship gained from winning battle
@ -343,7 +342,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 3, undefined, true); await runMysteryEncounterToEnd(game, 3, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
const eggsAfter = scene.gameData.eggs; const eggsAfter = scene.gameData.eggs;
@ -354,8 +353,8 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => {
expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs);
expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs);
game.phaseInterceptor.superEndPhase(); game.endPhase();
await game.phaseInterceptor.to(PostMysteryEncounterPhase); await game.phaseInterceptor.to("PostMysteryEncounterPhase");
const friendshipAfter = scene.currentBattle.mysteryEncounter!.misc.pokemon3.friendship; const friendshipAfter = scene.currentBattle.mysteryEncounter!.misc.pokemon3.friendship;
expect(friendshipAfter).toBe(friendshipBefore + 20 + FRIENDSHIP_GAIN_FROM_BATTLE); // 20 + extra for friendship gained from winning battle expect(friendshipAfter).toBe(friendshipBefore + 20 + FRIENDSHIP_GAIN_FROM_BATTLE); // 20 + extra for friendship gained from winning battle

View File

@ -229,9 +229,9 @@ describe("The Strong Stuff - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.THE_STRONG_STUFF, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.THE_STRONG_STUFF, defaultParty);
await runMysteryEncounterToEnd(game, 2, undefined, true); await runMysteryEncounterToEnd(game, 2, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -16,7 +16,6 @@ import * as MysteryEncounters from "#mystery-encounters/mystery-encounters";
import { HUMAN_TRANSITABLE_BIOMES } from "#mystery-encounters/mystery-encounters"; import { HUMAN_TRANSITABLE_BIOMES } from "#mystery-encounters/mystery-encounters";
import { TheWinstrateChallengeEncounter } from "#mystery-encounters/the-winstrate-challenge-encounter"; import { TheWinstrateChallengeEncounter } from "#mystery-encounters/the-winstrate-challenge-encounter";
import { CommandPhase } from "#phases/command-phase"; import { CommandPhase } from "#phases/command-phase";
import { MysteryEncounterRewardsPhase } from "#phases/mystery-encounter-phases";
import { PartyHealPhase } from "#phases/party-heal-phase"; import { PartyHealPhase } from "#phases/party-heal-phase";
import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { SelectModifierPhase } from "#phases/select-modifier-phase";
import { VictoryPhase } from "#phases/victory-phase"; import { VictoryPhase } from "#phases/victory-phase";
@ -295,9 +294,9 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
// Should have Macho Brace in the rewards // Should have Macho Brace in the rewards
await skipBattleToNextBattle(game, true); await skipBattleToNextBattle(game, true);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -339,7 +338,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.THE_WINSTRATE_CHALLENGE, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.THE_WINSTRATE_CHALLENGE, defaultParty);
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -366,11 +365,10 @@ async function skipBattleToNextBattle(game: GameManager, isFinalBattle = false)
p.status = new Status(StatusEffect.FAINT); p.status = new Status(StatusEffect.FAINT);
game.scene.field.remove(p); game.scene.field.remove(p);
}); });
game.phaseInterceptor["onHold"] = [];
game.scene.phaseManager.pushPhase(new VictoryPhase(0)); game.scene.phaseManager.pushPhase(new VictoryPhase(0));
game.phaseInterceptor.superEndPhase(); game.endPhase();
if (isFinalBattle) { if (isFinalBattle) {
await game.phaseInterceptor.to(MysteryEncounterRewardsPhase); await game.phaseInterceptor.to("MysteryEncounterRewardsPhase");
} else { } else {
await game.toNextTurn(); await game.toNextTurn();
} }

View File

@ -172,7 +172,7 @@ describe("Trash to Treasure - Mystery Encounter", () => {
it("should give 2 Leftovers, 1 Shell Bell, and Black Sludge", async () => { it("should give 2 Leftovers, 1 Shell Bell, and Black Sludge", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
await runMysteryEncounterToEnd(game, 1); await runMysteryEncounterToEnd(game, 1);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
const leftovers = scene.findModifier(m => m instanceof TurnHealModifier) as TurnHealModifier; const leftovers = scene.findModifier(m => m instanceof TurnHealModifier) as TurnHealModifier;
@ -242,9 +242,9 @@ describe("Trash to Treasure - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
await runMysteryEncounterToEnd(game, 2, undefined, true); await runMysteryEncounterToEnd(game, 2, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -112,11 +112,11 @@ describe("Weird Dream - Mystery Encounter", () => {
it("should transform the new party into new species, 2 at +90/+110, the rest at +40/50 BST", async () => { it("should transform the new party into new species, 2 at +90/+110, the rest at +40/50 BST", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty);
const pokemonPrior = scene.getPlayerParty().map(pokemon => pokemon); const pokemonPrior = scene.getPlayerParty().slice();
const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal()); const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal());
await runMysteryEncounterToEnd(game, 1); await runMysteryEncounterToEnd(game, 1);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
const pokemonAfter = scene.getPlayerParty(); const pokemonAfter = scene.getPlayerParty();
@ -139,9 +139,9 @@ describe("Weird Dream - Mystery Encounter", () => {
it("should have 1 Memory Mushroom, 5 Rogue Balls, and 3 Mints in rewards", async () => { it("should have 1 Memory Mushroom, 5 Rogue Balls, and 3 Mints in rewards", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty);
await runMysteryEncounterToEnd(game, 1); await runMysteryEncounterToEnd(game, 1);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -196,9 +196,9 @@ describe("Weird Dream - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty);
await runMysteryEncounterToEnd(game, 2, undefined, true); await runMysteryEncounterToEnd(game, 2, undefined, true);
await skipBattleRunMysteryEncounterRewardsPhase(game); await skipBattleRunMysteryEncounterRewardsPhase(game);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to("SelectModifierPhase", false);
expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -37,7 +37,7 @@ describe("Mystery Encounter Phases", () => {
SpeciesId.VOLCARONA, SpeciesId.VOLCARONA,
]); ]);
await game.phaseInterceptor.to(MysteryEncounterPhase, false); await game.phaseInterceptor.to("MysteryEncounterPhase", false);
expect(game.scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name); expect(game.scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
}); });
@ -49,9 +49,9 @@ describe("Mystery Encounter Phases", () => {
game.onNextPrompt("MysteryEncounterPhase", UiMode.MYSTERY_ENCOUNTER, () => { game.onNextPrompt("MysteryEncounterPhase", UiMode.MYSTERY_ENCOUNTER, () => {
// End phase early for test // End phase early for test
game.phaseInterceptor.superEndPhase(); game.endPhase();
}); });
await game.phaseInterceptor.run(MysteryEncounterPhase); await game.phaseInterceptor.to("MysteryEncounterPhase");
expect(game.scene.mysteryEncounterSaveData.encounteredEvents.length).toBeGreaterThan(0); expect(game.scene.mysteryEncounterSaveData.encounteredEvents.length).toBeGreaterThan(0);
expect(game.scene.mysteryEncounterSaveData.encounteredEvents[0].type).toEqual( expect(game.scene.mysteryEncounterSaveData.encounteredEvents[0].type).toEqual(
@ -75,7 +75,7 @@ describe("Mystery Encounter Phases", () => {
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
}); });
await game.phaseInterceptor.run(MysteryEncounterPhase); await game.phaseInterceptor.to("MysteryEncounterPhase");
// Select option 1 for encounter // Select option 1 for encounter
const handler = game.scene.ui.getHandler() as MysteryEncounterUiHandler; const handler = game.scene.ui.getHandler() as MysteryEncounterUiHandler;

View File

@ -241,7 +241,7 @@ describe("SelectModifierPhase", () => {
const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers); const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers);
scene.phaseManager.unshiftPhase(selectModifierPhase); scene.phaseManager.unshiftPhase(selectModifierPhase);
game.move.select(MoveId.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(
@ -265,7 +265,7 @@ describe("SelectModifierPhase", () => {
const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers); const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers);
scene.phaseManager.unshiftPhase(selectModifierPhase); scene.phaseManager.unshiftPhase(selectModifierPhase);
game.move.select(MoveId.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.run(SelectModifierPhase); await game.phaseInterceptor.to("SelectModifierPhase");
expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT);
const modifierSelectHandler = scene.ui.handlers.find( const modifierSelectHandler = scene.ui.handlers.find(

View File

@ -20,13 +20,11 @@ import { ModifierTypeOption } from "#modifiers/modifier-type";
import { CheckSwitchPhase } from "#phases/check-switch-phase"; import { CheckSwitchPhase } from "#phases/check-switch-phase";
import { CommandPhase } from "#phases/command-phase"; import { CommandPhase } from "#phases/command-phase";
import { EncounterPhase } from "#phases/encounter-phase"; import { EncounterPhase } from "#phases/encounter-phase";
import { LoginPhase } from "#phases/login-phase";
import { MovePhase } from "#phases/move-phase"; import { MovePhase } from "#phases/move-phase";
import { MysteryEncounterPhase } from "#phases/mystery-encounter-phases"; import { MysteryEncounterPhase } from "#phases/mystery-encounter-phases";
import { NewBattlePhase } from "#phases/new-battle-phase"; import { NewBattlePhase } from "#phases/new-battle-phase";
import { SelectStarterPhase } from "#phases/select-starter-phase"; import { SelectStarterPhase } from "#phases/select-starter-phase";
import type { SelectTargetPhase } from "#phases/select-target-phase"; import type { SelectTargetPhase } from "#phases/select-target-phase";
import { TitlePhase } from "#phases/title-phase";
import { TurnEndPhase } from "#phases/turn-end-phase"; import { TurnEndPhase } from "#phases/turn-end-phase";
import { TurnInitPhase } from "#phases/turn-init-phase"; import { TurnInitPhase } from "#phases/turn-init-phase";
import { TurnStartPhase } from "#phases/turn-start-phase"; import { TurnStartPhase } from "#phases/turn-start-phase";
@ -188,10 +186,12 @@ export class GameManager {
* @returns A promise that resolves when the title phase is reached. * @returns A promise that resolves when the title phase is reached.
*/ */
async runToTitle(): Promise<void> { async runToTitle(): Promise<void> {
await this.phaseInterceptor.whenAboutToRun(LoginPhase); // Go to login phase and skip past it
this.phaseInterceptor.pop(); await this.phaseInterceptor.to("LoginPhase", false);
await this.phaseInterceptor.run(TitlePhase); this.phaseInterceptor.shiftPhase(true);
await this.phaseInterceptor.to("TitlePhase");
// TODO: This should be moved to a separate initialization method
this.scene.gameSpeed = 5; this.scene.gameSpeed = 5;
this.scene.moveAnimations = false; this.scene.moveAnimations = false;
this.scene.showLevelUpStats = false; this.scene.showLevelUpStats = false;
@ -270,7 +270,7 @@ export class GameManager {
true, true,
); );
await this.phaseInterceptor.run(EncounterPhase); await this.phaseInterceptor.to("EncounterPhase");
if (!isNullOrUndefined(encounterType)) { if (!isNullOrUndefined(encounterType)) {
expect(this.scene.currentBattle?.mysteryEncounter?.encounterType).toBe(encounterType); expect(this.scene.currentBattle?.mysteryEncounter?.encounterType).toBe(encounterType);
} }
@ -542,7 +542,7 @@ export class GameManager {
* ``` * ```
*/ */
async setTurnOrder(order: BattlerIndex[]): Promise<void> { async setTurnOrder(order: BattlerIndex[]): Promise<void> {
await this.phaseInterceptor.to(TurnStartPhase, false); await this.phaseInterceptor.to("TurnStartPhase", false);
vi.spyOn(this.scene.phaseManager.getCurrentPhase() as TurnStartPhase, "getSpeedOrder").mockReturnValue(order); vi.spyOn(this.scene.phaseManager.getCurrentPhase() as TurnStartPhase, "getSpeedOrder").mockReturnValue(order);
} }

View File

@ -49,7 +49,7 @@ export class ChallengeModeHelper extends GameManagerHelper {
selectStarterPhase.initBattle(starters); selectStarterPhase.initBattle(starters);
}); });
await this.game.phaseInterceptor.run(EncounterPhase); await this.game.phaseInterceptor.to("EncounterPhase");
if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0 && this.game.override.removeEnemyStartingItems) { if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0 && this.game.override.removeEnemyStartingItems) {
this.game.removeEnemyHeldItems(); this.game.removeEnemyHeldItems();
} }

View File

@ -57,7 +57,7 @@ export class ReloadHelper extends GameManagerHelper {
this.game.scene.modifiers = []; this.game.scene.modifiers = [];
} }
titlePhase.loadSaveSlot(-1); // Load the desired session data titlePhase.loadSaveSlot(-1); // Load the desired session data
this.game.phaseInterceptor.shift(); // Loading the save slot also ended TitlePhase, clean it up this.game.phaseInterceptor.shiftPhase(); // Loading the save slot also ended TitlePhase, clean it up
// Run through prompts for switching Pokemon, copied from classicModeHelper.ts // Run through prompts for switching Pokemon, copied from classicModeHelper.ts
if (this.game.scene.battleStyle === BattleStyle.SWITCH) { if (this.game.scene.battleStyle === BattleStyle.SWITCH) {

View File

@ -1,3 +1,4 @@
import type { BattleScene } from "#app/battle-scene";
import { Phase } from "#app/phase"; import { Phase } from "#app/phase";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { AttemptRunPhase } from "#phases/attempt-run-phase"; import { AttemptRunPhase } from "#phases/attempt-run-phase";
@ -64,6 +65,7 @@ import { UnlockPhase } from "#phases/unlock-phase";
import { VictoryPhase } from "#phases/victory-phase"; import { VictoryPhase } from "#phases/victory-phase";
import { ErrorInterceptor } from "#test/test-utils/error-interceptor"; import { ErrorInterceptor } from "#test/test-utils/error-interceptor";
import type { PhaseClass, PhaseString } from "#types/phase-types"; import type { PhaseClass, PhaseString } from "#types/phase-types";
import type { AwaitableUiHandler } from "#ui/awaitable-ui-handler";
import { UI } from "#ui/ui"; import { UI } from "#ui/ui";
export interface PromptHandler { export interface PromptHandler {
@ -76,20 +78,39 @@ export interface PromptHandler {
type PhaseInterceptorPhase = PhaseClass | PhaseString; type PhaseInterceptorPhase = PhaseClass | PhaseString;
interface PhaseStub {
start(): void;
endBySetMode: boolean;
}
interface InProgressStub {
name: string;
callback(): void;
onError(error: any): void;
}
interface onHoldStub {
name: string;
call(): void;
}
export class PhaseInterceptor { export class PhaseInterceptor {
public scene; public scene: BattleScene;
public phases = {}; // @ts-expect-error: initialized in `initPhases`
public log: string[]; public phases: Record<PhaseString, PhaseStub> = {};
private onHold; public log: PhaseString[];
private interval; /**
private promptInterval; * TODO: This should not be an array;
private intervalRun; * Our linear phase system means only 1 phase is ever started at once (if any)
*/
private onHold: onHoldStub[];
private interval: NodeJS.Timeout;
private promptInterval: NodeJS.Timeout;
private intervalRun: NodeJS.Timeout;
private prompts: PromptHandler[]; private prompts: PromptHandler[];
private phaseFrom; private inProgress?: InProgressStub;
private inProgress; private originalSetMode: UI["setMode"];
private originalSetMode; private originalSuperEnd: Phase["end"];
private originalSetOverlayMode;
private originalSuperEnd;
/** /**
* List of phases with their corresponding start methods. * List of phases with their corresponding start methods.
@ -100,72 +121,73 @@ export class PhaseInterceptor {
* `initPhases()` so that its subclasses can use `super.start()` properly. * `initPhases()` so that its subclasses can use `super.start()` properly.
*/ */
private PHASES = [ private PHASES = [
[LoginPhase, this.startPhase], LoginPhase,
[TitlePhase, this.startPhase], TitlePhase,
[SelectGenderPhase, this.startPhase], SelectGenderPhase,
[NewBiomeEncounterPhase, this.startPhase], NewBiomeEncounterPhase,
[SelectStarterPhase, this.startPhase], SelectStarterPhase,
[PostSummonPhase, this.startPhase], PostSummonPhase,
[SummonPhase, this.startPhase], SummonPhase,
[ToggleDoublePositionPhase, this.startPhase], ToggleDoublePositionPhase,
[CheckSwitchPhase, this.startPhase], CheckSwitchPhase,
[ShowAbilityPhase, this.startPhase], ShowAbilityPhase,
[MessagePhase, this.startPhase], MessagePhase,
[TurnInitPhase, this.startPhase], TurnInitPhase,
[CommandPhase, this.startPhase], CommandPhase,
[EnemyCommandPhase, this.startPhase], EnemyCommandPhase,
[TurnStartPhase, this.startPhase], TurnStartPhase,
[MovePhase, this.startPhase], MovePhase,
[MoveEffectPhase, this.startPhase], MoveEffectPhase,
[DamageAnimPhase, this.startPhase], DamageAnimPhase,
[FaintPhase, this.startPhase], FaintPhase,
[BerryPhase, this.startPhase], BerryPhase,
[TurnEndPhase, this.startPhase], TurnEndPhase,
[BattleEndPhase, this.startPhase], BattleEndPhase,
[EggLapsePhase, this.startPhase], EggLapsePhase,
[SelectModifierPhase, this.startPhase], SelectModifierPhase,
[NextEncounterPhase, this.startPhase], NextEncounterPhase,
[NewBattlePhase, this.startPhase], NewBattlePhase,
[VictoryPhase, this.startPhase], VictoryPhase,
[LearnMovePhase, this.startPhase], LearnMovePhase,
[MoveEndPhase, this.startPhase], MoveEndPhase,
[StatStageChangePhase, this.startPhase], StatStageChangePhase,
[ShinySparklePhase, this.startPhase], ShinySparklePhase,
[SelectTargetPhase, this.startPhase], SelectTargetPhase,
[UnavailablePhase, this.startPhase], UnavailablePhase,
[QuietFormChangePhase, this.startPhase], QuietFormChangePhase,
[SwitchPhase, this.startPhase], SwitchPhase,
[SwitchSummonPhase, this.startPhase], SwitchSummonPhase,
[PartyHealPhase, this.startPhase], PartyHealPhase,
[FormChangePhase, this.startPhase], FormChangePhase,
[EvolutionPhase, this.startPhase], EvolutionPhase,
[EndEvolutionPhase, this.startPhase], EndEvolutionPhase,
[LevelCapPhase, this.startPhase], LevelCapPhase,
[AttemptRunPhase, this.startPhase], AttemptRunPhase,
[SelectBiomePhase, this.startPhase], SelectBiomePhase,
[PositionalTagPhase, this.startPhase], PositionalTagPhase,
[PokemonTransformPhase, this.startPhase], PokemonTransformPhase,
[MysteryEncounterPhase, this.startPhase], MysteryEncounterPhase,
[MysteryEncounterOptionSelectedPhase, this.startPhase], MysteryEncounterOptionSelectedPhase,
[MysteryEncounterBattlePhase, this.startPhase], MysteryEncounterBattlePhase,
[MysteryEncounterRewardsPhase, this.startPhase], MysteryEncounterRewardsPhase,
[PostMysteryEncounterPhase, this.startPhase], PostMysteryEncounterPhase,
[RibbonModifierRewardPhase, this.startPhase], RibbonModifierRewardPhase,
[GameOverModifierRewardPhase, this.startPhase], GameOverModifierRewardPhase,
[ModifierRewardPhase, this.startPhase], ModifierRewardPhase,
[PartyExpPhase, this.startPhase], PartyExpPhase,
[ExpPhase, this.startPhase], ExpPhase,
[EncounterPhase, this.startPhase], EncounterPhase,
[GameOverPhase, this.startPhase], GameOverPhase,
[UnlockPhase, this.startPhase], UnlockPhase,
[PostGameOverPhase, this.startPhase], PostGameOverPhase,
[RevivalBlessingPhase, this.startPhase], RevivalBlessingPhase,
]; ];
private endBySetMode = [ private endBySetMode = [
TitlePhase, TitlePhase,
SelectGenderPhase, SelectGenderPhase,
CommandPhase, CommandPhase,
SelectStarterPhase,
SelectModifierPhase, SelectModifierPhase,
MysteryEncounterPhase, MysteryEncounterPhase,
PostMysteryEncounterPhase, PostMysteryEncounterPhase,
@ -175,7 +197,7 @@ export class PhaseInterceptor {
* Constructor to initialize the scene and properties, and to start the phase handling. * Constructor to initialize the scene and properties, and to start the phase handling.
* @param scene - The scene to be managed. * @param scene - The scene to be managed.
*/ */
constructor(scene) { constructor(scene: BattleScene) {
this.scene = scene; this.scene = scene;
this.onHold = []; this.onHold = [];
this.prompts = []; this.prompts = [];
@ -200,16 +222,6 @@ export class PhaseInterceptor {
} }
} }
/**
* Method to set the starting phase.
* @param phaseFrom - The phase to start from.
* @returns The instance of the PhaseInterceptor.
*/
runFrom(phaseFrom: PhaseInterceptorPhase): PhaseInterceptor {
this.phaseFrom = phaseFrom;
return this;
}
/** /**
* Method to transition to a target phase. * Method to transition to a target phase.
* @param phaseTo - The phase to transition to. * @param phaseTo - The phase to transition to.
@ -219,59 +231,50 @@ export class PhaseInterceptor {
async to(phaseTo: PhaseInterceptorPhase, runTarget = true): Promise<void> { async to(phaseTo: PhaseInterceptorPhase, runTarget = true): Promise<void> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
ErrorInterceptor.getInstance().add(this); ErrorInterceptor.getInstance().add(this);
if (this.phaseFrom) {
await this.run(this.phaseFrom).catch(e => reject(e));
this.phaseFrom = null;
}
const targetName = typeof phaseTo === "string" ? phaseTo : phaseTo.name; const targetName = typeof phaseTo === "string" ? phaseTo : phaseTo.name;
this.intervalRun = setInterval(async () => { this.intervalRun = setInterval(async () => {
const currentPhase = this.onHold?.length && this.onHold[0]; const currentPhase = this.onHold?.length && this.onHold[0];
if (currentPhase && currentPhase.name === targetName) { if (!currentPhase) {
clearInterval(this.intervalRun); // No current phase means the manager either hasn't started yet
if (!runTarget) { // or we were interrupted by prompt; wait for phase to finish
return resolve(); return;
} }
await this.run(currentPhase).catch(e => {
// If current phase is different, run it and wait for it to finish.
if (currentPhase.name !== targetName) {
await this.run().catch(e => {
clearInterval(this.intervalRun); clearInterval(this.intervalRun);
return reject(e); return reject(e);
}); });
return;
}
// Hit target phase; run it and resolve
clearInterval(this.intervalRun);
if (!runTarget) {
return resolve(); return resolve();
} }
if (currentPhase && currentPhase.name !== targetName) { await this.run().catch(e => {
await this.run(currentPhase).catch(e => { clearInterval(this.intervalRun);
clearInterval(this.intervalRun); return reject(e);
return reject(e); });
}); return resolve();
}
}); });
}); });
} }
/** /**
* Method to run a phase with an optional skip function. * Method to run the current phase with an optional skip function.
* @param phaseTarget - The phase to run.
* @param skipFn - Optional skip function.
* @returns A promise that resolves when the phase is run. * @returns A promise that resolves when the phase is run.
*/ */
run(phaseTarget: PhaseInterceptorPhase, skipFn?: (className: PhaseClass) => boolean): Promise<void> { private run(): Promise<void> {
const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name; // @ts-expect-error: This is apparently mandatory to avoid a crash; review if this is needed
this.scene.moveAnimations = null; // Mandatory to avoid crash this.scene.moveAnimations = null;
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
ErrorInterceptor.getInstance().add(this); ErrorInterceptor.getInstance().add(this);
const interval = setInterval(async () => { const interval = setInterval(async () => {
const currentPhase = this.onHold.shift(); const currentPhase = this.onHold.shift();
if (currentPhase) { if (currentPhase) {
if (currentPhase.name !== targetName) {
clearInterval(interval);
const skip = skipFn?.(currentPhase.name);
if (skip) {
this.onHold.unshift(currentPhase);
ErrorInterceptor.getInstance().remove(this);
return resolve();
}
clearInterval(interval);
return reject(`Wrong phase: this is ${currentPhase.name} and not ${targetName}`);
}
clearInterval(interval); clearInterval(interval);
this.inProgress = { this.inProgress = {
name: currentPhase.name, name: currentPhase.name,
@ -287,26 +290,6 @@ export class PhaseInterceptor {
}); });
} }
whenAboutToRun(phaseTarget: PhaseInterceptorPhase, _skipFn?: (className: PhaseClass) => boolean): Promise<void> {
const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name;
this.scene.moveAnimations = null; // Mandatory to avoid crash
return new Promise(async (resolve, _reject) => {
ErrorInterceptor.getInstance().add(this);
const interval = setInterval(async () => {
const currentPhase = this.onHold[0];
if (currentPhase?.name === targetName) {
clearInterval(interval);
resolve();
}
});
});
}
pop() {
this.onHold.pop();
this.scene.phaseManager.shiftPhase();
}
/** /**
* Remove the current phase from the phase interceptor. * Remove the current phase from the phase interceptor.
* *
@ -316,7 +299,7 @@ export class PhaseInterceptor {
* *
* @param shouldRun Whether or not the current scene should also be run. * @param shouldRun Whether or not the current scene should also be run.
*/ */
shift(shouldRun = false): void { shiftPhase(shouldRun = false): void {
this.onHold.shift(); this.onHold.shift();
if (shouldRun) { if (shouldRun) {
this.scene.phaseManager.shiftPhase(); this.scene.phaseManager.shiftPhase();
@ -328,17 +311,16 @@ export class PhaseInterceptor {
*/ */
initPhases() { initPhases() {
this.originalSetMode = UI.prototype.setMode; this.originalSetMode = UI.prototype.setMode;
this.originalSetOverlayMode = UI.prototype.setOverlayMode;
this.originalSuperEnd = Phase.prototype.end; this.originalSuperEnd = Phase.prototype.end;
UI.prototype.setMode = (mode, ...args) => this.setMode.call(this, mode, ...args); UI.prototype.setMode = (mode, ...args) => this.setMode.call(this, mode, ...args);
Phase.prototype.end = () => this.superEndPhase.call(this); Phase.prototype.end = () => this.superEndPhase.call(this);
for (const [phase, methodStart] of this.PHASES) { for (const phase of this.PHASES) {
const originalStart = phase.prototype.start; const originalStart = phase.prototype.start;
this.phases[phase.name] = { this.phases[phase.name] = {
start: originalStart, start: originalStart,
endBySetMode: this.endBySetMode.some(elm => elm.name === phase.name), endBySetMode: this.endBySetMode.some(elm => elm.name === phase.name),
}; };
phase.prototype.start = () => methodStart.call(this, phase); phase.prototype.start = () => this.startPhase.call(this, phase);
} }
} }
@ -347,7 +329,7 @@ export class PhaseInterceptor {
* @param phase - The phase to start. * @param phase - The phase to start.
*/ */
startPhase(phase: PhaseClass) { startPhase(phase: PhaseClass) {
this.log.push(phase.name); this.log.push(phase.name as PhaseString);
const instance = this.scene.phaseManager.getCurrentPhase(); const instance = this.scene.phaseManager.getCurrentPhase();
this.onHold.push({ this.onHold.push({
name: phase.name, name: phase.name,
@ -357,16 +339,11 @@ export class PhaseInterceptor {
}); });
} }
unlock() {
this.inProgress?.callback();
this.inProgress = undefined;
}
/** /**
* Method to end a phase and log it. * Method to end a phase and log it.
* @param phase - The phase to start. * @param phase - The phase to start.
*/ */
superEndPhase() { private superEndPhase() {
const instance = this.scene.phaseManager.getCurrentPhase(); const instance = this.scene.phaseManager.getCurrentPhase();
this.originalSuperEnd.apply(instance); this.originalSuperEnd.apply(instance);
this.inProgress?.callback(); this.inProgress?.callback();
@ -379,7 +356,8 @@ export class PhaseInterceptor {
* @param args - Additional arguments to pass to the original method. * @param args - Additional arguments to pass to the original method.
*/ */
setMode(mode: UiMode, ...args: unknown[]): Promise<void> { setMode(mode: UiMode, ...args: unknown[]): Promise<void> {
const currentPhase = this.scene.phaseManager.getCurrentPhase(); // TODO: remove the `!` in PR 6243 / after PR 6243 is merged
const currentPhase = this.scene.phaseManager.getCurrentPhase()!;
const instance = this.scene.ui; const instance = this.scene.ui;
console.log("setMode", `${UiMode[mode]} (=${mode})`, args); console.log("setMode", `${UiMode[mode]} (=${mode})`, args);
const ret = this.originalSetMode.apply(instance, [mode, ...args]); const ret = this.originalSetMode.apply(instance, [mode, ...args]);
@ -395,18 +373,6 @@ export class PhaseInterceptor {
return ret; return ret;
} }
/**
* mock to set overlay mode
* @param mode - The {@linkcode Mode} to set.
* @param args - Additional arguments to pass to the original method.
*/
setOverlayMode(mode: UiMode, ...args: unknown[]): Promise<void> {
const instance = this.scene.ui;
console.log("setOverlayMode", `${UiMode[mode]} (=${mode})`, args);
const ret = this.originalSetOverlayMode.apply(instance, [mode, ...args]);
return ret;
}
/** /**
* Method to start the prompt handler. * Method to start the prompt handler.
*/ */
@ -425,7 +391,7 @@ export class PhaseInterceptor {
currentPhase === actionForNextPrompt.phaseTarget && currentPhase === actionForNextPrompt.phaseTarget &&
currentHandler.active && currentHandler.active &&
(!actionForNextPrompt.awaitingActionInput || (!actionForNextPrompt.awaitingActionInput ||
(actionForNextPrompt.awaitingActionInput && currentHandler.awaitingActionInput)) (actionForNextPrompt.awaitingActionInput && (currentHandler as AwaitableUiHandler)["awaitingActionInput"]))
) { ) {
const prompt = this.prompts.shift(); const prompt = this.prompts.shift();
if (prompt?.callback) { if (prompt?.callback) {
@ -467,11 +433,10 @@ export class PhaseInterceptor {
* function stored in `this.phases`. Additionally, it clears the `promptInterval` and `interval`. * function stored in `this.phases`. Additionally, it clears the `promptInterval` and `interval`.
*/ */
restoreOg() { restoreOg() {
for (const [phase] of this.PHASES) { for (const phase of this.PHASES) {
phase.prototype.start = this.phases[phase.name].start; phase.prototype.start = this.phases[phase.name].start;
} }
UI.prototype.setMode = this.originalSetMode; UI.prototype.setMode = this.originalSetMode;
UI.prototype.setOverlayMode = this.originalSetOverlayMode;
Phase.prototype.end = this.originalSuperEnd; Phase.prototype.end = this.originalSuperEnd;
clearInterval(this.promptInterval); clearInterval(this.promptInterval);
clearInterval(this.interval); clearInterval(this.interval);

View File

@ -69,7 +69,7 @@ describe("UI - Pokedex", () => {
// Open the pokedex UI. // Open the pokedex UI.
await game.runToTitle(); await game.runToTitle();
await game.phaseInterceptor.setOverlayMode(UiMode.POKEDEX); await game.scene.ui.setOverlayMode(UiMode.POKEDEX);
// Get the handler for the current UI. // Get the handler for the current UI.
const handler = game.scene.ui.getHandler(); const handler = game.scene.ui.getHandler();
@ -89,7 +89,7 @@ describe("UI - Pokedex", () => {
// Open the pokedex UI. // Open the pokedex UI.
await game.runToTitle(); await game.runToTitle();
await game.phaseInterceptor.setOverlayMode(UiMode.POKEDEX_PAGE, species, starterAttributes); await game.scene.ui.setOverlayMode(UiMode.POKEDEX_PAGE, species, starterAttributes);
// Get the handler for the current UI. // Get the handler for the current UI.
const handler = game.scene.ui.getHandler(); const handler = game.scene.ui.getHandler();

View File

@ -6,8 +6,6 @@ import { GameModes } from "#enums/game-modes";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { EncounterPhase } from "#phases/encounter-phase";
import { SelectStarterPhase } from "#phases/select-starter-phase";
import type { TitlePhase } from "#phases/title-phase"; import type { TitlePhase } from "#phases/title-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler"; import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
@ -54,9 +52,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.RIGHT); handler.processInput(Button.RIGHT);
handler.processInput(Button.LEFT); handler.processInput(Button.LEFT);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -88,7 +85,7 @@ describe("UI - Starter select", () => {
resolve(); resolve();
}); });
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
expect(game.scene.getPlayerParty()[0].shiny).toBe(true); expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
@ -115,9 +112,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.LEFT); handler.processInput(Button.LEFT);
handler.processInput(Button.CYCLE_GENDER); handler.processInput(Button.CYCLE_GENDER);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -149,7 +145,7 @@ describe("UI - Starter select", () => {
resolve(); resolve();
}); });
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
expect(game.scene.getPlayerParty()[0].shiny).toBe(true); expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
@ -179,9 +175,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.CYCLE_NATURE); handler.processInput(Button.CYCLE_NATURE);
handler.processInput(Button.CYCLE_ABILITY); handler.processInput(Button.CYCLE_ABILITY);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -213,7 +208,7 @@ describe("UI - Starter select", () => {
resolve(); resolve();
}); });
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
expect(game.scene.getPlayerParty()[0].shiny).toBe(true); expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
@ -242,9 +237,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.LEFT); handler.processInput(Button.LEFT);
handler.processInput(Button.CYCLE_GENDER); handler.processInput(Button.CYCLE_GENDER);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -276,7 +270,7 @@ describe("UI - Starter select", () => {
resolve(); resolve();
}); });
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
expect(game.scene.getPlayerParty()[0].shiny).toBe(true); expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
@ -303,9 +297,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.LEFT); handler.processInput(Button.LEFT);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.CYCLE_SHINY);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -337,7 +330,7 @@ describe("UI - Starter select", () => {
resolve(); resolve();
}); });
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
expect(game.scene.getPlayerParty()[0].shiny).toBe(false); expect(game.scene.getPlayerParty()[0].shiny).toBe(false);
@ -365,9 +358,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.CYCLE_SHINY);
handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.CYCLE_SHINY);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -399,7 +391,7 @@ describe("UI - Starter select", () => {
resolve(); resolve();
}); });
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
expect(game.scene.getPlayerParty()[0].shiny).toBe(true); expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
@ -426,9 +418,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.CYCLE_SHINY);
handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.CYCLE_SHINY);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -460,7 +451,7 @@ describe("UI - Starter select", () => {
resolve(); resolve();
}); });
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
expect(game.scene.getPlayerParty()[0].shiny).toBe(true); expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
@ -486,9 +477,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.RIGHT); handler.processInput(Button.RIGHT);
handler.processInput(Button.RIGHT); handler.processInput(Button.RIGHT);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -527,7 +517,7 @@ describe("UI - Starter select", () => {
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler; const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
saveSlotSelectUiHandler.processInput(Button.ACTION); saveSlotSelectUiHandler.processInput(Button.ACTION);
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.CATERPIE); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.CATERPIE);
}); });
@ -551,9 +541,8 @@ describe("UI - Starter select", () => {
handler.processInput(Button.RIGHT); handler.processInput(Button.RIGHT);
handler.processInput(Button.DOWN); handler.processInput(Button.DOWN);
handler.processInput(Button.ACTION); handler.processInput(Button.ACTION);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.run(SelectStarterPhase); await game.phaseInterceptor.to("SelectStarterPhase");
let options: OptionSelectItem[] = []; let options: OptionSelectItem[] = [];
let optionSelectUiHandler: OptionSelectUiHandler | undefined; let optionSelectUiHandler: OptionSelectUiHandler | undefined;
await new Promise<void>(resolve => { await new Promise<void>(resolve => {
@ -593,7 +582,7 @@ describe("UI - Starter select", () => {
const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler; const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler;
saveSlotSelectUiHandler.processInput(Button.ACTION); saveSlotSelectUiHandler.processInput(Button.ACTION);
}); });
await game.phaseInterceptor.whenAboutToRun(EncounterPhase); await game.phaseInterceptor.to("EncounterPhase", false);
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.NIDORAN_M); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.NIDORAN_M);
}); });
}); });

View File

@ -72,8 +72,6 @@ describe("UI - Transfer Items", () => {
expect( expect(
handler.optionsContainer.list.some(option => RegExp(/Lum Berry\[color.*(2)/).exec((option as BBCodeText).text)), handler.optionsContainer.list.some(option => RegExp(/Lum Berry\[color.*(2)/).exec((option as BBCodeText).text)),
).toBe(true); ).toBe(true);
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.to("SelectModifierPhase"); await game.phaseInterceptor.to("SelectModifierPhase");
@ -93,8 +91,6 @@ describe("UI - Transfer Items", () => {
expect(handler.optionsContainer.list.some(option => (option as BBCodeText).text?.includes("Transfer"))).toBe( expect(handler.optionsContainer.list.some(option => (option as BBCodeText).text?.includes("Transfer"))).toBe(
true, true,
); );
game.phaseInterceptor.unlock();
}); });
await game.phaseInterceptor.to("SelectModifierPhase"); await game.phaseInterceptor.to("SelectModifierPhase");

View File

@ -2,7 +2,6 @@ import { Button } from "#enums/buttons";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { CommandPhase } from "#phases/command-phase";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import type { MockText } from "#test/test-utils/mocks/mocks-container/mock-text"; import type { MockText } from "#test/test-utils/mocks/mocks-container/mock-text";
import { FightUiHandler } from "#ui/fight-ui-handler"; import { FightUiHandler } from "#ui/fight-ui-handler";
@ -46,7 +45,6 @@ describe("UI - Type Hints", () => {
const { ui } = game.scene; const { ui } = game.scene;
const handler = ui.getHandler<FightUiHandler>(); const handler = ui.getHandler<FightUiHandler>();
handler.processInput(Button.ACTION); // select "Fight" handler.processInput(Button.ACTION); // select "Fight"
game.phaseInterceptor.unlock();
}); });
game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => { game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => {
@ -59,7 +57,7 @@ describe("UI - Type Hints", () => {
expect.soft(dragonClawText.color).toBe("#929292"); expect.soft(dragonClawText.color).toBe("#929292");
ui.getHandler().processInput(Button.ACTION); ui.getHandler().processInput(Button.ACTION);
}); });
await game.phaseInterceptor.to(CommandPhase); await game.phaseInterceptor.to("CommandPhase");
}); });
it("check status move color", async () => { it("check status move color", async () => {
@ -71,7 +69,6 @@ describe("UI - Type Hints", () => {
const { ui } = game.scene; const { ui } = game.scene;
const handler = ui.getHandler<FightUiHandler>(); const handler = ui.getHandler<FightUiHandler>();
handler.processInput(Button.ACTION); // select "Fight" handler.processInput(Button.ACTION); // select "Fight"
game.phaseInterceptor.unlock();
}); });
game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => { game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => {
@ -84,7 +81,7 @@ describe("UI - Type Hints", () => {
expect.soft(growlText.color).toBe(undefined); expect.soft(growlText.color).toBe(undefined);
ui.getHandler().processInput(Button.ACTION); ui.getHandler().processInput(Button.ACTION);
}); });
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 flees", async () => {
@ -107,7 +104,6 @@ describe("UI - Type Hints", () => {
const { ui } = game.scene; const { ui } = game.scene;
const handler = ui.getHandler<FightUiHandler>(); const handler = ui.getHandler<FightUiHandler>();
handler.processInput(Button.ACTION); // select "Fight" handler.processInput(Button.ACTION); // select "Fight"
game.phaseInterceptor.unlock();
}); });
game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => { game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => {
@ -121,6 +117,6 @@ describe("UI - Type Hints", () => {
expect.soft(shadowBallText.color).toBe(undefined); expect.soft(shadowBallText.color).toBe(undefined);
ui.getHandler().processInput(Button.ACTION); ui.getHandler().processInput(Button.ACTION);
}); });
await game.phaseInterceptor.to(CommandPhase); await game.phaseInterceptor.to("CommandPhase");
}); });
}); });