un-reverted stuff

This commit is contained in:
Bertie690 2025-09-03 20:29:40 -04:00
parent 69966719d1
commit 6132726342
6 changed files with 73 additions and 43 deletions

View File

@ -360,7 +360,11 @@ export class BattleScene extends SceneBase {
);
}
async preload() {
/**
* Load game assets necessary for the scene to run.
* Called by Phaser on new game start.
*/
public async preload(): Promise<void> {
if (DEBUG_RNG) {
const originalRealInRange = Phaser.Math.RND.realInRange;
Phaser.Math.RND.realInRange = function (min: number, max: number): number {
@ -395,7 +399,7 @@ export class BattleScene extends SceneBase {
* Create game objects with loaded assets.
* Called by Phaser on new game start.
*/
create(): void {
public create(): void {
this.scene.remove(LoadingScene.KEY);
initGameSpeed.apply(this);
this.inputController = new InputsController();
@ -1264,6 +1268,7 @@ export class BattleScene extends SceneBase {
this.uiContainer.remove(this.ui, true);
this.uiContainer.destroy();
this.children.removeAll(true);
// TODO: Do we even need this?
this.game.domContainer.innerHTML = "";
// TODO: `launchBattle` calls `reset(false, false, true)`
this.launchBattle();

View File

@ -117,8 +117,14 @@ export class GameManager {
global.fetch = vi.fn(MockFetch) as any;
}
/** Reset a prior `BattleScene` instance to the proper initial state. */
/**
* Reset a prior `BattleScene` instance to the proper initial state.
* @todo Review why our UI doesn't reset between runs and why we need to do it manually
*/
private resetScene(): void {
// NB: We can't pass `clearScene=true` to `reset` as it will only launch the battle after a fadeout tween
// (along with initializing a bunch of sprites we don't really care about)
this.scene.reset(false, true);
(this.scene.ui.handlers[UiMode.STARTER_SELECT] as StarterSelectUiHandler).clearStarterPreferences();
@ -131,7 +137,7 @@ export class GameManager {
/**
* Initialize various default overrides for starting tests, typically to alleviate randomness.
*/
// TODO: This should not be here
// TODO: Move this to overrides-helper.ts
private initDefaultOverrides(): void {
// Disables Mystery Encounters on all tests (can be overridden at test level)
this.override.mysteryEncounterChance(0);

View File

@ -77,16 +77,22 @@ 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
* @returns A Promise that resolves once the initialization process has completed.
* @todo Is loading files actually necessary for a headless renderer?
*/
// TODO: is asset loading & method overriding actually needed for a headless renderer?
async setScene(scene: BattleScene): Promise<void> {
public async setScene(scene: BattleScene): Promise<void> {
this.scene = scene;
this.injectMandatory();
this.scene.preload();
this.scene.create();
}
injectMandatory() {
/**
* Override this scene and stub out various properties to avoid crashes with headless games.
* @todo Review what parts of this are actually NEEDED
* @todo Overhaul this to work with a multi-scene project
*/
private injectMandatory(): void {
this.game.config = {
seed: ["test"],
gameVersion: version,
@ -160,9 +166,12 @@ export class GameWrapper {
this.scene.scale = this.game.scale;
this.scene.textures = this.game.textures;
this.scene.events = this.game.events;
// TODO: Why is this needed? The `manager` property isn't used anywhere
this.scene.manager = new InputManager(this.game, {});
this.scene.manager.keyboard = new KeyboardManager(this.scene);
this.scene.pluginEvents = new EventEmitter();
this.game.domContainer = {} as HTMLDivElement;
// TODO: scenes don't have dom containers
this.scene.domContainer = {} as HTMLDivElement;
this.scene.spritePipeline = {};
this.scene.fieldSpritePipeline = {};
@ -204,7 +213,7 @@ export class GameWrapper {
this.scene.sys.updateList = new UpdateList(this.scene);
this.scene.systems = this.scene.sys;
this.scene.input = this.game.input;
this.scene.scene = this.scene;
this.scene.scene = this.scene; // TODO: This seems wacky
this.scene.input.keyboard = new KeyboardPlugin(this.scene);
this.scene.input.gamepad = new GamepadPlugin(this.scene);
this.scene.cachedFetch = (url, _init) => {

View File

@ -62,9 +62,7 @@ export class PromptHandler extends GameManagerHelper {
this.originalSetModeInternal = this.game.scene.ui["setModeInternal"];
// `any` assertion needed as we are mocking private property
vi.spyOn(
this.game.scene.ui as unknown as {
setModeInternal: UI["setModeInternal"];
},
this.game.scene.ui as UI & Pick<{ setModeInternal: UI["setModeInternal"] }, "setModeInternal">,
"setModeInternal",
).mockImplementation((...args) => this.setMode(args));
@ -83,7 +81,9 @@ export class PromptHandler extends GameManagerHelper {
private setMode(args: Parameters<typeof this.originalSetModeInternal>) {
const mode = args[0];
this.doLog(`UI mode changed to ${getEnumStr(UiMode, mode)}!`);
this.doLog(
`UI mode changed from ${getEnumStr(UiMode, this.game.scene.ui.getMode())} to ${getEnumStr(UiMode, mode)}!`,
);
const ret = this.originalSetModeInternal.apply(this.game.scene.ui, args);
const currentPhase = this.game.scene.phaseManager.getCurrentPhase()?.phaseName!;
@ -156,8 +156,9 @@ export class PromptHandler extends GameManagerHelper {
/**
* Wrapper function to add coloration to phase logs.
* @param args - Arguments to original logging function.
* @param args - Arguments to original logging function
*/
// TODO: Move this to colors.ts & change color after mock console PR
private doLog(...args: unknown[]): void {
console.log(chalk.hex("#008B8B")(...args));
}

View File

@ -1,6 +1,7 @@
import { Phase } from "#app/phase";
/**
* A rudimentary mock of a phase.
* A rudimentary mock of a phase used for unit tests.
* Ends upon starting by default.
*/
export abstract class mockPhase extends Phase {

View File

@ -3,13 +3,15 @@ import { Button } from "#enums/buttons";
import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id";
import { UiMode } from "#enums/ui-mode";
import type { Pokemon } from "#field/pokemon";
import { GameManager } from "#test/test-utils/game-manager";
import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler";
import { type PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("UI - Item Manage Button", () => {
// TODO: Resolve issues with UI test state corruption
describe.todo("UI - Transfer Items", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
@ -39,14 +41,11 @@ describe("UI - Item Manage Button", () => {
await game.classicMode.startBattle([SpeciesId.RAYQUAZA, SpeciesId.RAYQUAZA, SpeciesId.RAYQUAZA]);
game.move.use(MoveId.DRAGON_CLAW);
});
it("foo", () => {
expect(1).toBe(1);
});
it("manage button exists in the proper screen", async () => {
await game.phaseInterceptor.to("SelectModifierPhase");
});
it("manage button exists in the proper screen", async () => {
let handlerLength: Phaser.GameObjects.GameObject[] | undefined;
await new Promise<void>(resolve => {
@ -78,7 +77,6 @@ describe("UI - Item Manage Button", () => {
});
it("manage button doesn't exist in the other screens", async () => {
await game.phaseInterceptor.to("SelectModifierPhase");
let handlerLength: Phaser.GameObjects.GameObject[] | undefined;
await new Promise<void>(resolve => {
@ -111,8 +109,7 @@ describe("UI - Item Manage Button", () => {
// Test that the manage button actually discards items, needs proofreading
it("should discard items when button is selected", async () => {
await game.phaseInterceptor.to("SelectModifierPhase");
const pokemon = game.field.getPlayerPokemon();
let pokemon: Pokemon | undefined;
await new Promise<void>(resolve => {
game.onNextPrompt("SelectModifierPhase", UiMode.MODIFIER_SELECT, async () => {
@ -132,13 +129,17 @@ describe("UI - Item Manage Button", () => {
handler.processInput(Button.ACTION);
handler.setCursor(0);
handler.processInput(Button.ACTION);
pokemon = game.field.getPlayerPokemon();
resolve();
});
});
expect(pokemon.getHeldItems()).toHaveLength(3);
expect(pokemon.getHeldItems().map(h => h.stackCount)).toEqual([1, 2, 2]);
expect(pokemon).toBeDefined();
if (pokemon) {
expect(pokemon.getHeldItems()).toHaveLength(3);
expect(pokemon.getHeldItems().map(h => h.stackCount)).toEqual([1, 2, 2]);
}
await new Promise<void>(resolve => {
game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => {
@ -155,18 +156,25 @@ describe("UI - Item Manage Button", () => {
const handler = game.scene.ui.getHandler() as PartyUiHandler;
handler.processInput(Button.ACTION);
pokemon = game.field.getPlayerPokemon();
handler.processInput(Button.CANCEL);
resolve();
});
});
// Sitrus berry was discarded, leaving 2 stacks of 2 berries behind
expect(pokemon.getHeldItems()).toHaveLength(2);
expect(pokemon.getHeldItems().map(h => h.stackCount)).toEqual([2, 2]);
expect(pokemon).toBeDefined();
if (pokemon) {
// Sitrus berry was discarded, leaving 2 stacks of 2 berries behind
expect(pokemon.getHeldItems()).toHaveLength(2);
expect(pokemon.getHeldItems().map(h => h.stackCount)).toEqual([2, 2]);
}
});
// TODO: This test breaks when running all tests on github. Fix this once hotfix period is over.
it.todo("should not allow changing to discard mode when transfering items", async () => {
let handler: PartyUiHandler | undefined;
const { resolve, promise } = Promise.withResolvers<void>();
game.onNextPrompt("SelectModifierPhase", UiMode.MODIFIER_SELECT, async () => {
@ -180,7 +188,7 @@ describe("UI - Item Manage Button", () => {
game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => {
await new Promise(r => setTimeout(r, 100));
const handler = game.scene.ui.getHandler() as PartyUiHandler;
handler = game.scene.ui.getHandler() as PartyUiHandler;
handler.setCursor(0);
handler.processInput(Button.ACTION);
@ -192,21 +200,21 @@ describe("UI - Item Manage Button", () => {
});
await promise;
expect(handler).toBeDefined();
if (handler) {
const partyMode = handler["partyUiMode"];
expect(partyMode).toBe(PartyUiMode.MODIFIER_TRANSFER);
const handler = game.scene.ui.getHandler() as PartyUiHandler;
handler.setCursor(7);
handler.processInput(Button.ACTION);
// Should not change mode to discard
expect(handler["partyUiMode"]).toBe(PartyUiMode.MODIFIER_TRANSFER);
const partyMode = handler["partyUiMode"];
expect(partyMode).toBe(PartyUiMode.MODIFIER_TRANSFER);
handler.setCursor(7);
handler.processInput(Button.ACTION);
// Should not change mode to discard
expect(handler["partyUiMode"]).toBe(PartyUiMode.MODIFIER_TRANSFER);
handler.processInput(Button.CANCEL);
handler.setCursor(7);
handler.processInput(Button.ACTION);
// Should change mode to discard
expect(handler["partyUiMode"]).toBe(PartyUiMode.DISCARD);
handler.processInput(Button.CANCEL);
handler.setCursor(7);
handler.processInput(Button.ACTION);
// Should change mode to discard
expect(handler["partyUiMode"]).toBe(PartyUiMode.DISCARD);
}
});
});