diff --git a/test/test-utils/game-manager.ts b/test/test-utils/game-manager.ts index d28cd5082fb..db3865f693f 100644 --- a/test/test-utils/game-manager.ts +++ b/test/test-utils/game-manager.ts @@ -37,12 +37,14 @@ import { FieldHelper } from "#test/test-utils/helpers/field-helper"; import { ModifierHelper } from "#test/test-utils/helpers/modifiers-helper"; import { MoveHelper } from "#test/test-utils/helpers/move-helper"; import { OverridesHelper } from "#test/test-utils/helpers/overrides-helper"; +import { PromptHandler } from "#test/test-utils/helpers/prompt-handler"; import { ReloadHelper } from "#test/test-utils/helpers/reload-helper"; import { SettingsHelper } from "#test/test-utils/helpers/settings-helper"; import type { InputsHandler } from "#test/test-utils/inputs-handler"; import { MockFetch } from "#test/test-utils/mocks/mock-fetch"; import { PhaseInterceptor } from "#test/test-utils/phase-interceptor"; import { TextInterceptor } from "#test/test-utils/text-interceptor"; +import type { PhaseString } from "#types/phase-types"; import type { BallUiHandler } from "#ui/ball-ui-handler"; import type { BattleMessageUiHandler } from "#ui/battle-message-ui-handler"; import type { CommandUiHandler } from "#ui/command-ui-handler"; @@ -64,6 +66,7 @@ export class GameManager { public phaseInterceptor: PhaseInterceptor; public textInterceptor: TextInterceptor; public inputsHandler: InputsHandler; + public readonly promptHandler: PromptHandler; public readonly override: OverridesHelper; public readonly move: MoveHelper; public readonly classicMode: ClassicModeHelper; @@ -88,14 +91,14 @@ export class GameManager { if (globalScene) { this.scene = globalScene; + this.phaseInterceptor = new PhaseInterceptor(this.scene); } else { this.scene = new BattleScene(); + this.phaseInterceptor = new PhaseInterceptor(this.scene); this.gameWrapper.setScene(this.scene); firstTimeScene = true; } - this.phaseInterceptor = new PhaseInterceptor(this.scene); - if (!firstTimeScene) { this.scene.reset(false, true); (this.scene.ui.handlers[UiMode.STARTER_SELECT] as StarterSelectUiHandler).clearStarterPreferences(); @@ -103,11 +106,10 @@ export class GameManager { // Must be run after phase interceptor has been initialized. this.scene.phaseManager.toTitleScreen(true); this.scene.phaseManager.shiftPhase(); - - this.gameWrapper.scene = this.scene; } this.textInterceptor = new TextInterceptor(this.scene); + this.promptHandler = new PromptHandler(this); this.override = new OverridesHelper(this); this.move = new MoveHelper(this); this.classicMode = new ClassicModeHelper(this); @@ -139,7 +141,7 @@ export class GameManager { */ waitMode(mode: UiMode): Promise { return new Promise(async resolve => { - await waitUntil(() => this.scene.ui?.getMode() === mode); + await vi.waitUntil(() => this.scene.ui?.getMode() === mode); return resolve(); }); } @@ -158,15 +160,18 @@ export class GameManager { * @param mode - The mode to wait for. * @param callback - The callback function to execute on next prompt. * @param expireFn - Optional function to determine if the prompt has expired. + * @param awaitingActionInput - If true, will prevent the prompt from activating until the current {@linkcode AwaitableUiHandler} + * is awaiting input; default `false` + * @todo Remove in favor of {@linkcode promptHandler.addToNextPrompt} */ onNextPrompt( - phaseTarget: string, + phaseTarget: PhaseString, mode: UiMode, callback: () => void, - expireFn?: () => void, + expireFn?: () => boolean, awaitingActionInput = false, ) { - this.phaseInterceptor.addToNextPrompt(phaseTarget, mode, callback, expireFn, awaitingActionInput); + this.promptHandler.addToNextPrompt(phaseTarget, mode, callback, expireFn, awaitingActionInput); } /** @@ -487,7 +492,7 @@ export class GameManager { * @param inPhase - Which phase to expect the selection to occur in. Defaults to `SwitchPhase` * (which is where the majority of non-command switch operations occur). */ - doSelectPartyPokemon(slot: number, inPhase = "SwitchPhase") { + doSelectPartyPokemon(slot: number, inPhase: PhaseString = "SwitchPhase") { this.onNextPrompt(inPhase, UiMode.PARTY, () => { const partyHandler = this.scene.ui.getHandler() as PartyUiHandler; diff --git a/test/test-utils/game-wrapper.ts b/test/test-utils/game-wrapper.ts index 9f59fadc646..8069da027ef 100644 --- a/test/test-utils/game-wrapper.ts +++ b/test/test-utils/game-wrapper.ts @@ -75,7 +75,7 @@ export class GameWrapper { /** * Initialize the given {@linkcode BattleScene} and override various properties to avoid crashes with headless games. - * @param scene - The {@linkcode BattleScene} to initialize. + * @param scene - The {@linkcode BattleScene} to initialize * @returns A Promise that resolves once the initialization process has completed. */ // TODO: is asset loading & method overriding actually needed for a headless renderer? diff --git a/test/test-utils/phase-interceptor.ts b/test/test-utils/phase-interceptor.ts index e84fbecaa04..aa51f87d1b0 100644 --- a/test/test-utils/phase-interceptor.ts +++ b/test/test-utils/phase-interceptor.ts @@ -90,7 +90,7 @@ export class PhaseInterceptor { currentPhase = pm.getCurrentPhase()!; // TODO: Remove proof-of-concept error throw after signature update if (!currentPhase) { - throw new Error("currentPhase is null after being started!"); + throw new Error("currentPhase is null after being started! aaaaaaaaaaa"); } if (currentPhase.is(this.target)) {