diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 68b796ee5c0..97363838c9c 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1240,7 +1240,7 @@ export default class BattleScene extends SceneBase { this.field.add(newTrainer); } } else { - if (!this.gameMode.hasTrainers) { + if (!this.gameMode.hasTrainers || (Overrides.DISABLE_TRAINERS_OVERRIDE && isNullOrUndefined(trainerData))) { newBattleType = BattleType.WILD; } else if (battleType === undefined) { newBattleType = this.gameMode.isWaveTrainer(newWaveIndex, this.arena) ? BattleType.TRAINER : BattleType.WILD; diff --git a/src/overrides.ts b/src/overrides.ts index e53d3b766c4..aacd36b922e 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -244,6 +244,11 @@ class DefaultOverrides { * Note that, for all items in the array, `count` is not used. */ readonly ITEM_REWARD_OVERRIDE: ModifierOverride[] = []; + + /** + * If `true`, disable all non-scripted opponent trainer encounters. + */ + readonly DISABLE_TRAINERS_OVERRIDE: boolean = false; } export const defaultOverrides = new DefaultOverrides(); diff --git a/test/utils/gameManager.ts b/test/utils/gameManager.ts index 1a229969800..05fb82f6516 100644 --- a/test/utils/gameManager.ts +++ b/test/utils/gameManager.ts @@ -120,9 +120,11 @@ export default class GameManager { this.settings = new SettingsHelper(this); this.reload = new ReloadHelper(this); this.modifiers = new ModifierHelper(this); + this.field = new FieldHelper(this); + this.override.sanitizeOverrides(); - // Sanitize overrides for each test - this.override.mysteryEncounterChance(0).moveset([]).enemyMoveset([]).startingHeldItems([]).enemyHeldItems([]); + // Disables Mystery Encounters on all tests (can be overridden at test level) + this.override.mysteryEncounterChance(0); global.fetch = vi.fn(MockFetch) as any; } diff --git a/test/utils/helpers/overridesHelper.ts b/test/utils/helpers/overridesHelper.ts index 47358738048..2f318ff8035 100644 --- a/test/utils/helpers/overridesHelper.ts +++ b/test/utils/helpers/overridesHelper.ts @@ -1,12 +1,9 @@ import type { Variant } from "#app/data/variant"; import { Weather } from "#app/data/weather"; -import { Abilities } from "#app/enums/abilities"; -import * as GameMode from "#app/game-mode"; -import type { GameModes } from "#app/game-mode"; -import { getGameMode } from "#app/game-mode"; +import { Abilities } from "#enums/abilities"; import type { ModifierOverride } from "#app/modifier/modifier-type"; import type { BattleStyle } from "#app/overrides"; -import Overrides from "#app/overrides"; +import Overrides, { defaultOverrides } from "#app/overrides"; import type { Unlockables } from "#app/system/unlockables"; import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; @@ -15,8 +12,9 @@ import type { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { Species } from "#enums/species"; import { StatusEffect } from "#enums/status-effect"; import type { WeatherType } from "#enums/weather-type"; -import { vi } from "vitest"; -import { GameManagerHelper } from "./gameManagerHelper"; +import { expect, vi } from "vitest"; +import { GameManagerHelper } from "#test/utils/helpers/gameManagerHelper"; +import { shiftCharCodes } from "#app/utils"; /** * Helper to handle overrides in tests @@ -226,12 +224,7 @@ export class OverridesHelper extends GameManagerHelper { * @returns `this` */ public disableTrainerWaves(): this { - const realFn = getGameMode; - vi.spyOn(GameMode, "getGameMode").mockImplementation((gameMode: GameModes) => { - const mode = realFn(gameMode); - mode.hasTrainers = false; - return mode; - }); + vi.spyOn(Overrides, "DISABLE_TRAINERS_OVERRIDE", "get").mockReturnValue(true); this.log("Standard trainer waves are disabled!"); return this; } @@ -263,11 +256,8 @@ export class OverridesHelper extends GameManagerHelper { * @returns `this` */ public seed(seed: string): this { - vi.spyOn(this.game.scene, "resetSeed").mockImplementation(() => { - this.game.scene.waveSeed = seed; - Phaser.Math.RND.sow([ seed ]); - this.game.scene.rngCounter = 0; - }); + // Shift the seed here with a negative wave number, to compensate for `resetSeed()` shifting the seed itself. + this.game.scene.setSeed(shiftCharCodes(seed, (this.game.scene.currentBattle?.waveIndex ?? 0) * -1)); this.game.scene.resetSeed(); this.log(`Seed set to "${seed}"!`); return this; @@ -539,4 +529,14 @@ export class OverridesHelper extends GameManagerHelper { private log(...params: any[]) { console.log("Overrides:", ...params); } + + public sanitizeOverrides(): void { + for (const key of Object.keys(defaultOverrides)) { + if (Overrides[key] !== defaultOverrides[key]) { + vi.spyOn(Overrides, key as any, "get").mockReturnValue(defaultOverrides[key]); + } + } + expect(Overrides).toEqual(defaultOverrides); + this.log("Sanitizing all overrides!"); + } } diff --git a/test/vitest.setup.ts b/test/vitest.setup.ts index 9350f7f0eaf..f886a03d9bb 100644 --- a/test/vitest.setup.ts +++ b/test/vitest.setup.ts @@ -10,9 +10,10 @@ vi.mock("#app/overrides", async (importOriginal) => { return { default: defaultOverrides, - defaultOverrides, - // eslint-disable-next-line @typescript-eslint/consistent-type-imports - } satisfies typeof import("#app/overrides"); + // Export `defaultOverrides` as a *copy*. + // This ensures we can easily reset `overrides` back to its default values after modifying it. + defaultOverrides: { ...defaultOverrides }, + } satisfies typeof import("#app/overrides"); // eslint-disable-line }); /**