From e8670c4f00d2dfe9ee020a2fb70bedcdf796ada1 Mon Sep 17 00:00:00 2001
From: Felix Staud <felix.staud@headwire.com>
Date: Thu, 11 Jul 2024 15:01:30 -0700
Subject: [PATCH] rename MysteryEncounter interface to IMysteryEncounter

---
 src/battle-scene.ts                           | 16 +++----
 src/battle.ts                                 |  4 +-
 .../encounters/dark-deal.ts                   |  4 +-
 .../encounters/department-store-sale.ts       |  4 +-
 .../encounters/field-trip-encounter.ts        |  4 +-
 .../encounters/fight-or-flight.ts             |  4 +-
 .../encounters/mysterious-challengers.ts      |  4 +-
 .../encounters/mysterious-chest.ts            |  4 +-
 .../encounters/shady-vitamin-dealer.ts        |  4 +-
 .../encounters/sleeping-snorlax.ts            |  4 +-
 .../encounters/training-session.ts            |  4 +-
 .../mystery-encounters/mystery-encounter.ts   | 44 +++++++++----------
 .../mystery-encounters/mystery-encounters.ts  |  4 +-
 src/field/mystery-encounter-intro.ts          |  6 +--
 src/system/game-data.ts                       |  6 +--
 .../mystery-encounter-utils.test.ts           | 12 ++---
 16 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/src/battle-scene.ts b/src/battle-scene.ts
index be0e83b7976..729cc826886 100644
--- a/src/battle-scene.ts
+++ b/src/battle-scene.ts
@@ -67,7 +67,7 @@ import { Species } from "#enums/species";
 import { UiTheme } from "#enums/ui-theme";
 import { TimedEventManager } from "#app/timed-event-manager.js";
 import i18next from "i18next";
-import MysteryEncounter, { MysteryEncounterTier, MysteryEncounterVariant } from "./data/mystery-encounters/mystery-encounter";
+import IMysteryEncounter, { MysteryEncounterTier, MysteryEncounterVariant } from "./data/mystery-encounters/mystery-encounter";
 import { mysteryEncountersByBiome, allMysteryEncounters, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, WIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters";
 import { MysteryEncounterData } from "#app/data/mystery-encounters/mystery-encounter-data";
 import { MysteryEncounterType } from "#enums/mystery-encounter-type";
@@ -216,7 +216,7 @@ export default class BattleScene extends SceneBase {
   public pokemonInfoContainer: PokemonInfoContainer;
   private party: PlayerPokemon[];
   public mysteryEncounterData: MysteryEncounterData = new MysteryEncounterData(null);
-  public lastMysteryEncounter: MysteryEncounter;
+  public lastMysteryEncounter: IMysteryEncounter;
   /** Combined Biome and Wave count text */
   private biomeWaveText: Phaser.GameObjects.Text;
   private moneyText: Phaser.GameObjects.Text;
@@ -1026,7 +1026,7 @@ export default class BattleScene extends SceneBase {
     }
   }
 
-  newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean, mysteryEncounter?: MysteryEncounter): Battle {
+  newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean, mysteryEncounter?: IMysteryEncounter): Battle {
     const _startingWave = Overrides.STARTING_WAVE_OVERRIDE || startingWave;
     const newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (_startingWave - 1)) + 1);
     let newDouble: boolean;
@@ -2621,9 +2621,9 @@ export default class BattleScene extends SceneBase {
    * @param override - used to load session encounter when restarting game, etc.
    * @returns
    */
-  getMysteryEncounter(override: MysteryEncounter): MysteryEncounter {
+  getMysteryEncounter(override: IMysteryEncounter): IMysteryEncounter {
     // Loading override or session encounter
-    let encounter: MysteryEncounter;
+    let encounter: IMysteryEncounter;
     if (!isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_OVERRIDE) && allMysteryEncounters.hasOwnProperty(Overrides.MYSTERY_ENCOUNTER_OVERRIDE)) {
       encounter = allMysteryEncounters[Overrides.MYSTERY_ENCOUNTER_OVERRIDE];
     } else {
@@ -2645,7 +2645,7 @@ export default class BattleScene extends SceneBase {
     }
 
     if (encounter) {
-      encounter = new MysteryEncounter(encounter);
+      encounter = new IMysteryEncounter(encounter);
       encounter.populateDialogueTokensFromRequirements(this);
       return encounter;
     }
@@ -2674,7 +2674,7 @@ export default class BattleScene extends SceneBase {
       tier = Overrides.MYSTERY_ENCOUNTER_TIER_OVERRIDE;
     }
 
-    let availableEncounters: MysteryEncounter[] = [];
+    let availableEncounters: IMysteryEncounter[] = [];
     // New encounter will never be the same as the most recent encounter
     const previousEncounter = this.mysteryEncounterData.encounteredEvents?.length > 0 ? this.mysteryEncounterData.encounteredEvents[this.mysteryEncounterData.encounteredEvents.length - 1][0] : null;
     const biomeMysteryEncounters = mysteryEncountersByBiome.get(this.arena.biomeType);
@@ -2695,7 +2695,7 @@ export default class BattleScene extends SceneBase {
     }
     encounter = availableEncounters[Utils.randSeedInt(availableEncounters.length)];
     // New encounter object to not dirty flags
-    encounter = new MysteryEncounter(encounter);
+    encounter = new IMysteryEncounter(encounter);
     encounter.populateDialogueTokensFromRequirements(this);
     return encounter;
   }
diff --git a/src/battle.ts b/src/battle.ts
index 30543933f49..ab47eac7993 100644
--- a/src/battle.ts
+++ b/src/battle.ts
@@ -14,7 +14,7 @@ import { PlayerGender } from "#enums/player-gender";
 import { Species } from "#enums/species";
 import { TrainerType } from "#enums/trainer-type";
 import i18next from "#app/plugins/i18n";
-import MysteryEncounter, { MysteryEncounterVariant } from "./data/mystery-encounters/mystery-encounter";
+import IMysteryEncounter, { MysteryEncounterVariant } from "./data/mystery-encounters/mystery-encounter";
 
 export enum BattleType {
   WILD,
@@ -69,7 +69,7 @@ export default class Battle {
   public lastUsedPokeball: PokeballType;
   public playerFaints: number; // The amount of times pokemon on the players side have fainted
   public enemyFaints: number; // The amount of times pokemon on the enemies side have fainted
-  public mysteryEncounter: MysteryEncounter;
+  public mysteryEncounter: IMysteryEncounter;
 
   private rngCounter: integer = 0;
 
diff --git a/src/data/mystery-encounters/encounters/dark-deal.ts b/src/data/mystery-encounters/encounters/dark-deal.ts
index 8f13e373e9a..9d755ad9493 100644
--- a/src/data/mystery-encounters/encounters/dark-deal.ts
+++ b/src/data/mystery-encounters/encounters/dark-deal.ts
@@ -7,7 +7,7 @@ import BattleScene from "../../../battle-scene";
 import { AddPokeballModifierType } from "../../../modifier/modifier-type";
 import { PokeballType } from "../../pokeball";
 import { getPokemonSpecies } from "../../pokemon-species";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
@@ -73,7 +73,7 @@ const excludedBosses = [
   Species.PECHARUNT,
 ];
 
-export const DarkDealEncounter: MysteryEncounter =
+export const DarkDealEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DARK_DEAL)
     .withEncounterTier(MysteryEncounterTier.ROGUE)
     .withIntroSpriteConfigs([
diff --git a/src/data/mystery-encounters/encounters/department-store-sale.ts b/src/data/mystery-encounters/encounters/department-store-sale.ts
index 2dcee4455df..d821a952864 100644
--- a/src/data/mystery-encounters/encounters/department-store-sale.ts
+++ b/src/data/mystery-encounters/encounters/department-store-sale.ts
@@ -7,7 +7,7 @@ import { randSeedInt } from "#app/utils";
 import { MysteryEncounterType } from "#enums/mystery-encounter-type";
 import { Species } from "#enums/species";
 import BattleScene from "../../../battle-scene";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
@@ -15,7 +15,7 @@ import MysteryEncounter, {
 /** i18n namespace for encounter */
 const namespace = "mysteryEncounter:department_store_sale";
 
-export const DepartmentStoreSaleEncounter: MysteryEncounter =
+export const DepartmentStoreSaleEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(
     MysteryEncounterType.DEPARTMENT_STORE_SALE
   )
diff --git a/src/data/mystery-encounters/encounters/field-trip-encounter.ts b/src/data/mystery-encounters/encounters/field-trip-encounter.ts
index 8cb6fe65048..9235504e332 100644
--- a/src/data/mystery-encounters/encounters/field-trip-encounter.ts
+++ b/src/data/mystery-encounters/encounters/field-trip-encounter.ts
@@ -13,7 +13,7 @@ import { modifierTypes } from "#app/modifier/modifier-type";
 import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
 import { MysteryEncounterType } from "#enums/mystery-encounter-type";
 import BattleScene from "../../../battle-scene";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
@@ -21,7 +21,7 @@ import MysteryEncounter, {
 /** i18n namespace for the encounter */
 const namespace = "mysteryEncounter:field_trip";
 
-export const FieldTripEncounter: MysteryEncounter =
+export const FieldTripEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIELD_TRIP)
     .withEncounterTier(MysteryEncounterTier.COMMON)
     .withSceneWaveRangeRequirement(10, 180)
diff --git a/src/data/mystery-encounters/encounters/fight-or-flight.ts b/src/data/mystery-encounters/encounters/fight-or-flight.ts
index 3080ab76810..c98d7cd485f 100644
--- a/src/data/mystery-encounters/encounters/fight-or-flight.ts
+++ b/src/data/mystery-encounters/encounters/fight-or-flight.ts
@@ -23,7 +23,7 @@ import { randSeedInt } from "#app/utils";
 import { BattlerTagType } from "#enums/battler-tag-type";
 import { MysteryEncounterType } from "#enums/mystery-encounter-type";
 import BattleScene from "../../../battle-scene";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
@@ -32,7 +32,7 @@ import { MoveRequirement } from "../mystery-encounter-requirements";
 /** the i18n namespace for the encounter */
 const namespace = "mysteryEncounter:fight_or_flight";
 
-export const FightOrFlightEncounter: MysteryEncounter =
+export const FightOrFlightEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(
     MysteryEncounterType.FIGHT_OR_FLIGHT
   )
diff --git a/src/data/mystery-encounters/encounters/mysterious-challengers.ts b/src/data/mystery-encounters/encounters/mysterious-challengers.ts
index e8efc3470ed..1276d6e2226 100644
--- a/src/data/mystery-encounters/encounters/mysterious-challengers.ts
+++ b/src/data/mystery-encounters/encounters/mysterious-challengers.ts
@@ -15,7 +15,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
 import { PartyMemberStrength } from "#enums/party-member-strength";
 import BattleScene from "../../../battle-scene";
 import * as Utils from "../../../utils";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
@@ -23,7 +23,7 @@ import MysteryEncounter, {
 /** the i18n namespace for the encounter */
 const namespace = "mysteryEncounter:mysterious_challengers";
 
-export const MysteriousChallengersEncounter: MysteryEncounter =
+export const MysteriousChallengersEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(
     MysteryEncounterType.MYSTERIOUS_CHALLENGERS
   )
diff --git a/src/data/mystery-encounters/encounters/mysterious-chest.ts b/src/data/mystery-encounters/encounters/mysterious-chest.ts
index 9dd4f56f623..8d1f1c2eeb1 100644
--- a/src/data/mystery-encounters/encounters/mysterious-chest.ts
+++ b/src/data/mystery-encounters/encounters/mysterious-chest.ts
@@ -11,13 +11,13 @@ import { GameOverPhase } from "#app/phases";
 import { randSeedInt } from "#app/utils";
 import { MysteryEncounterType } from "#enums/mystery-encounter-type";
 import BattleScene from "../../../battle-scene";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
 import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
 
-export const MysteriousChestEncounter: MysteryEncounter =
+export const MysteriousChestEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(
     MysteryEncounterType.MYSTERIOUS_CHEST
   )
diff --git a/src/data/mystery-encounters/encounters/shady-vitamin-dealer.ts b/src/data/mystery-encounters/encounters/shady-vitamin-dealer.ts
index 773c4b97b0e..f26890cefbc 100644
--- a/src/data/mystery-encounters/encounters/shady-vitamin-dealer.ts
+++ b/src/data/mystery-encounters/encounters/shady-vitamin-dealer.ts
@@ -14,14 +14,14 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
 import { Species } from "#enums/species";
 import i18next from "i18next";
 import BattleScene from "../../../battle-scene";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
 import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
 import { MoneyRequirement } from "../mystery-encounter-requirements";
 
-export const ShadyVitaminDealerEncounter: MysteryEncounter =
+export const ShadyVitaminDealerEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(
     MysteryEncounterType.SHADY_VITAMIN_DEALER
   )
diff --git a/src/data/mystery-encounters/encounters/sleeping-snorlax.ts b/src/data/mystery-encounters/encounters/sleeping-snorlax.ts
index 324beb35e99..b0130c34419 100644
--- a/src/data/mystery-encounters/encounters/sleeping-snorlax.ts
+++ b/src/data/mystery-encounters/encounters/sleeping-snorlax.ts
@@ -7,7 +7,7 @@ import BattleScene from "../../../battle-scene";
 import * as Utils from "../../../utils";
 import { getPokemonSpecies } from "../../pokemon-species";
 import { Status, StatusEffect } from "../../status-effect";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
@@ -27,7 +27,7 @@ import {
 /** i18n namespace for the encounter */
 const namespace = "mysteryEncounter:sleeping_snorlax";
 
-export const SleepingSnorlaxEncounter: MysteryEncounter =
+export const SleepingSnorlaxEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(
     MysteryEncounterType.SLEEPING_SNORLAX
   )
diff --git a/src/data/mystery-encounters/encounters/training-session.ts b/src/data/mystery-encounters/encounters/training-session.ts
index e9b0461857d..4338f587583 100644
--- a/src/data/mystery-encounters/encounters/training-session.ts
+++ b/src/data/mystery-encounters/encounters/training-session.ts
@@ -20,13 +20,13 @@ import { randSeedShuffle } from "#app/utils";
 import { BattlerTagType } from "#enums/battler-tag-type";
 import { MysteryEncounterType } from "#enums/mystery-encounter-type";
 import BattleScene from "../../../battle-scene";
-import MysteryEncounter, {
+import IMysteryEncounter, {
   MysteryEncounterBuilder,
   MysteryEncounterTier,
 } from "../mystery-encounter";
 import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
 
-export const TrainingSessionEncounter: MysteryEncounter =
+export const TrainingSessionEncounter: IMysteryEncounter =
   MysteryEncounterBuilder.withEncounterType(
     MysteryEncounterType.TRAINING_SESSION
   )
diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts
index c367f2377b2..30e2e6682a6 100644
--- a/src/data/mystery-encounters/mystery-encounter.ts
+++ b/src/data/mystery-encounters/mystery-encounter.ts
@@ -35,7 +35,7 @@ export enum MysteryEncounterTier {
   MASTER // Not currently used
 }
 
-export default interface MysteryEncounter {
+export default interface IMysteryEncounter {
   /**
    * Required params
    */
@@ -130,8 +130,8 @@ export default interface MysteryEncounter {
  * These objects will be saved as part of session data any time the player is on a floor with an encounter
  * Unless you know what you're doing, you should use MysteryEncounterBuilder to create an instance for this class
  */
-export default class MysteryEncounter implements MysteryEncounter {
-  constructor(encounter: MysteryEncounter) {
+export default class IMysteryEncounter implements IMysteryEncounter {
+  constructor(encounter: IMysteryEncounter) {
     if (!isNullOrUndefined(encounter)) {
       Object.assign(this, encounter);
     }
@@ -339,7 +339,7 @@ export default class MysteryEncounter implements MysteryEncounter {
   }
 }
 
-export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
+export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
   encounterType?: MysteryEncounterType;
   options?: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]] = [null, null];
   spriteConfigs?: MysteryEncounterSpriteConfig[];
@@ -367,7 +367,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param encounterType
    * @returns this
    */
-  static withEncounterType(encounterType: MysteryEncounterType): MysteryEncounterBuilder & Pick<MysteryEncounter, "encounterType"> {
+  static withEncounterType(encounterType: MysteryEncounterType): MysteryEncounterBuilder & Pick<IMysteryEncounter, "encounterType"> {
     return Object.assign(new MysteryEncounterBuilder(), { encounterType: encounterType });
   }
 
@@ -377,7 +377,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param option - MysteryEncounterOption to add, can use MysteryEncounterOptionBuilder to create instance
    * @returns
    */
-  withOption(option: MysteryEncounterOption): this & Pick<MysteryEncounter, "options"> {
+  withOption(option: MysteryEncounterOption): this & Pick<IMysteryEncounter, "options"> {
     if (this.options[0] === null) {
       return Object.assign(this, { options: [option, this.options[0]] });
     } else if (this.options[1] === null) {
@@ -406,7 +406,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param spriteConfigs
    * @returns
    */
-  withIntroSpriteConfigs(spriteConfigs: MysteryEncounterSpriteConfig[]): this & Pick<MysteryEncounter, "spriteConfigs"> {
+  withIntroSpriteConfigs(spriteConfigs: MysteryEncounterSpriteConfig[]): this & Pick<IMysteryEncounter, "spriteConfigs"> {
     return Object.assign(this, { spriteConfigs: spriteConfigs });
   }
 
@@ -435,7 +435,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param encounterTier
    * @returns
    */
-  withEncounterTier(encounterTier: MysteryEncounterTier): this & Required<Pick<MysteryEncounter, "encounterTier">> {
+  withEncounterTier(encounterTier: MysteryEncounterTier): this & Required<Pick<IMysteryEncounter, "encounterTier">> {
     return Object.assign(this, { encounterTier: encounterTier });
   }
 
@@ -446,7 +446,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param requirement
    * @returns
    */
-  withSceneRequirement(requirement: EncounterSceneRequirement): this & Required<Pick<MysteryEncounter, "requirements">> {
+  withSceneRequirement(requirement: EncounterSceneRequirement): this & Required<Pick<IMysteryEncounter, "requirements">> {
     if (requirement instanceof EncounterPokemonRequirement) {
       Error("Incorrectly added pokemon requirement as scene requirement.");
     }
@@ -482,7 +482,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param requirement {@linkcode EncounterPokemonRequirement}
    * @returns
    */
-  withPrimaryPokemonRequirement(requirement: EncounterPokemonRequirement): this & Required<Pick<MysteryEncounter, "primaryPokemonRequirements">> {
+  withPrimaryPokemonRequirement(requirement: EncounterPokemonRequirement): this & Required<Pick<IMysteryEncounter, "primaryPokemonRequirements">> {
     this.primaryPokemonRequirements.push(requirement);
     return Object.assign(this, { primaryPokemonRequirements: this.primaryPokemonRequirements });
   }
@@ -495,7 +495,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param invertQuery if true will invert the query
    * @returns
    */
-  withPrimaryPokemonStatusEffectRequirement(statusEffect: StatusEffect | StatusEffect[], minNumberOfPokemon: number = 1, invertQuery: boolean = false): this & Required<Pick<MysteryEncounter, "primaryPokemonRequirements">> {
+  withPrimaryPokemonStatusEffectRequirement(statusEffect: StatusEffect | StatusEffect[], minNumberOfPokemon: number = 1, invertQuery: boolean = false): this & Required<Pick<IMysteryEncounter, "primaryPokemonRequirements">> {
     return this.withPrimaryPokemonRequirement(new StatusEffectRequirement(statusEffect, minNumberOfPokemon, invertQuery));
   }
 
@@ -507,14 +507,14 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param invertQuery if true will invert the query
    * @returns
    */
-  withPrimaryPokemonHealthRatioRequirement(requiredHealthRange: [number, number], minNumberOfPokemon: number = 1, invertQuery: boolean = false): this & Required<Pick<MysteryEncounter, "primaryPokemonRequirements">> {
+  withPrimaryPokemonHealthRatioRequirement(requiredHealthRange: [number, number], minNumberOfPokemon: number = 1, invertQuery: boolean = false): this & Required<Pick<IMysteryEncounter, "primaryPokemonRequirements">> {
     return this.withPrimaryPokemonRequirement(new HealthRatioRequirement(requiredHealthRange, minNumberOfPokemon, invertQuery));
   }
 
   // TODO: Maybe add an optional parameter for excluding primary pokemon from the support cast?
   // ex. if your only grass type pokemon, a snivy, is chosen as primary, if the support pokemon requires a grass type, the event won't trigger because
   // it's already been
-  withSecondaryPokemonRequirement(requirement: EncounterPokemonRequirement, excludePrimaryFromSecondaryRequirements: boolean = false): this & Required<Pick<MysteryEncounter, "secondaryPokemonRequirements">> {
+  withSecondaryPokemonRequirement(requirement: EncounterPokemonRequirement, excludePrimaryFromSecondaryRequirements: boolean = false): this & Required<Pick<IMysteryEncounter, "secondaryPokemonRequirements">> {
     this.secondaryPokemonRequirements.push(requirement);
     this.excludePrimaryFromSupportRequirements = excludePrimaryFromSecondaryRequirements;
     return Object.assign(this, { excludePrimaryFromSecondaryRequirements: this.excludePrimaryFromSupportRequirements, secondaryPokemonRequirements: this.secondaryPokemonRequirements });
@@ -530,7 +530,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param doEncounterRewards - synchronous callback function to perform during rewards phase of the encounter
    * @returns
    */
-  withRewards(doEncounterRewards: (scene: BattleScene) => boolean): this & Required<Pick<MysteryEncounter, "doEncounterRewards">> {
+  withRewards(doEncounterRewards: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterRewards">> {
     return Object.assign(this, { doEncounterRewards: doEncounterRewards });
   }
 
@@ -544,7 +544,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param doEncounterExp - synchronous callback function to perform during rewards phase of the encounter
    * @returns
    */
-  withExp(doEncounterExp: (scene: BattleScene) => boolean): this & Required<Pick<MysteryEncounter, "doEncounterExp">> {
+  withExp(doEncounterExp: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterExp">> {
     return Object.assign(this, { doEncounterExp: doEncounterExp });
   }
 
@@ -555,7 +555,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param onInit - synchronous callback function to perform as soon as the encounter is selected for the next phase
    * @returns
    */
-  withOnInit(onInit: (scene: BattleScene) => boolean): this & Required<Pick<MysteryEncounter, "onInit">> {
+  withOnInit(onInit: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "onInit">> {
     return Object.assign(this, { onInit: onInit });
   }
 
@@ -564,7 +564,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param enemyPartyConfig
    * @returns
    */
-  withEnemyPartyConfig(enemyPartyConfig: EnemyPartyConfig): this & Required<Pick<MysteryEncounter, "enemyPartyConfigs">> {
+  withEnemyPartyConfig(enemyPartyConfig: EnemyPartyConfig): this & Required<Pick<IMysteryEncounter, "enemyPartyConfigs">> {
     this.enemyPartyConfigs.push(enemyPartyConfig);
     return Object.assign(this, { enemyPartyConfigs: this.enemyPartyConfigs });
   }
@@ -575,7 +575,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param catchAllowed - if true, allows enemy pokemon to be caught during the encounter
    * @returns
    */
-  withCatchAllowed(catchAllowed: boolean): this & Required<Pick<MysteryEncounter, "catchAllowed">> {
+  withCatchAllowed(catchAllowed: boolean): this & Required<Pick<IMysteryEncounter, "catchAllowed">> {
     return Object.assign(this, { catchAllowed: catchAllowed });
   }
 
@@ -583,7 +583,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param hideBattleIntroMessage - if true, will not show the trainerAppeared/wildAppeared/bossAppeared message for an encounter
    * @returns
    */
-  withHideWildIntroMessage(hideBattleIntroMessage: boolean): this & Required<Pick<MysteryEncounter, "hideBattleIntroMessage">> {
+  withHideWildIntroMessage(hideBattleIntroMessage: boolean): this & Required<Pick<IMysteryEncounter, "hideBattleIntroMessage">> {
     return Object.assign(this, { hideBattleIntroMessage: hideBattleIntroMessage });
   }
 
@@ -591,7 +591,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param hideIntroVisuals - if false, will not hide the intro visuals that are displayed at the beginning of encounter
    * @returns
    */
-  withHideIntroVisuals(hideIntroVisuals: boolean): this & Required<Pick<MysteryEncounter, "hideIntroVisuals">> {
+  withHideIntroVisuals(hideIntroVisuals: boolean): this & Required<Pick<IMysteryEncounter, "hideIntroVisuals">> {
     return Object.assign(this, { hideIntroVisuals: hideIntroVisuals });
   }
 
@@ -672,7 +672,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
    * @param this - MysteryEncounter
    * @returns
    */
-  build(this: MysteryEncounter) {
-    return new MysteryEncounter(this);
+  build(this: IMysteryEncounter) {
+    return new IMysteryEncounter(this);
   }
 }
diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts
index 1651430e59d..602a01627c6 100644
--- a/src/data/mystery-encounters/mystery-encounters.ts
+++ b/src/data/mystery-encounters/mystery-encounters.ts
@@ -1,4 +1,4 @@
-import MysteryEncounter from "./mystery-encounter";
+import IMysteryEncounter from "./mystery-encounter";
 import { DarkDealEncounter } from "./encounters/dark-deal";
 import { MysteriousChallengersEncounter } from "./encounters/mysterious-challengers";
 import { MysteriousChestEncounter } from "./encounters/mysterious-chest";
@@ -117,7 +117,7 @@ export const CIVILIZATION_ENCOUNTER_BIOMES = [
   Biome.ISLAND
 ];
 
-export const allMysteryEncounters: { [encounterType: number]: MysteryEncounter } = {};
+export const allMysteryEncounters: { [encounterType: number]: IMysteryEncounter } = {};
 
 
 const extremeBiomeEncounters: MysteryEncounterType[] = [];
diff --git a/src/field/mystery-encounter-intro.ts b/src/field/mystery-encounter-intro.ts
index adb700b4854..1b0fb3bca01 100644
--- a/src/field/mystery-encounter-intro.ts
+++ b/src/field/mystery-encounter-intro.ts
@@ -1,6 +1,6 @@
 import { GameObjects } from "phaser";
 import BattleScene from "../battle-scene";
-import MysteryEncounter from "../data/mystery-encounters/mystery-encounter";
+import IMysteryEncounter from "../data/mystery-encounters/mystery-encounter";
 
 export class MysteryEncounterSpriteConfig {
   spriteKey: string; // e.g. "ace_trainer_f"
@@ -21,10 +21,10 @@ export class MysteryEncounterSpriteConfig {
  * Note: intro visuals are not "Trainers" or any other specific game object, though they may contain trainer sprites
  */
 export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container {
-  public encounter: MysteryEncounter;
+  public encounter: IMysteryEncounter;
   public spriteConfigs: MysteryEncounterSpriteConfig[];
 
-  constructor(scene: BattleScene, encounter: MysteryEncounter) {
+  constructor(scene: BattleScene, encounter: IMysteryEncounter) {
     super(scene, -72, 76);
     this.encounter = encounter;
     // Shallow copy configs to allow visual config updates at runtime without dirtying master copy of Encounter
diff --git a/src/system/game-data.ts b/src/system/game-data.ts
index 871e2458bbd..606d63d70fe 100644
--- a/src/system/game-data.ts
+++ b/src/system/game-data.ts
@@ -41,7 +41,7 @@ import { Moves } from "#enums/moves";
 import { PlayerGender } from "#enums/player-gender";
 import { Species } from "#enums/species";
 import { MysteryEncounterData } from "../data/mystery-encounters/mystery-encounter-data";
-import MysteryEncounter from "../data/mystery-encounters/mystery-encounter";
+import IMysteryEncounter from "../data/mystery-encounters/mystery-encounter";
 
 export const defaultStarterSpecies: Species[] = [
   Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE,
@@ -124,7 +124,7 @@ export interface SessionSaveData {
   gameVersion: string;
   timestamp: integer;
   challenges: ChallengeData[];
-  mysteryEncounter: MysteryEncounter;
+  mysteryEncounter: IMysteryEncounter;
   mysteryEncounterData: MysteryEncounterData;
 }
 
@@ -1155,7 +1155,7 @@ export class GameData {
       }
 
       if (k === "mysteryEncounter") {
-        return new MysteryEncounter(v);
+        return new IMysteryEncounter(v);
       }
 
       if (k === "mysteryEncounterData") {
diff --git a/src/test/mystery-encounter/mystery-encounter-utils.test.ts b/src/test/mystery-encounter/mystery-encounter-utils.test.ts
index e558fe7a95c..50853c05a2e 100644
--- a/src/test/mystery-encounter/mystery-encounter-utils.test.ts
+++ b/src/test/mystery-encounter/mystery-encounter-utils.test.ts
@@ -10,7 +10,7 @@ import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils";
 import { Species } from "#enums/species";
 import BattleScene from "#app/battle-scene";
 import { StatusEffect } from "#app/data/status-effect";
-import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
+import IMysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
 import { MessagePhase } from "#app/phases";
 import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
 import { Type } from "#app/data/type";
@@ -273,7 +273,7 @@ describe("Mystery Encounter Utils", () => {
 
   describe("getTextWithEncounterDialogueTokens", () => {
     it("injects dialogue tokens and color styling", () => {
-      scene.currentBattle.mysteryEncounter = new MysteryEncounter(null);
+      scene.currentBattle.mysteryEncounter = new IMysteryEncounter(null);
       scene.currentBattle.mysteryEncounter.setDialogueToken("test", "value");
 
       const result = getEncounterText(scene, "mysteryEncounter:unit_test_dialogue");
@@ -281,7 +281,7 @@ describe("Mystery Encounter Utils", () => {
     });
 
     it("can perform nested dialogue token injection", () => {
-      scene.currentBattle.mysteryEncounter = new MysteryEncounter(null);
+      scene.currentBattle.mysteryEncounter = new IMysteryEncounter(null);
       scene.currentBattle.mysteryEncounter.setDialogueToken("test", "value");
       scene.currentBattle.mysteryEncounter.setDialogueToken("testvalue", "new");
 
@@ -292,7 +292,7 @@ describe("Mystery Encounter Utils", () => {
 
   describe("queueEncounterMessage", () => {
     it("queues a message with encounter dialogue tokens", async () => {
-      scene.currentBattle.mysteryEncounter = new MysteryEncounter(null);
+      scene.currentBattle.mysteryEncounter = new IMysteryEncounter(null);
       scene.currentBattle.mysteryEncounter.setDialogueToken("test", "value");
       const spy = vi.spyOn(game.scene, "queueMessage");
       const phaseSpy = vi.spyOn(game.scene, "unshiftPhase");
@@ -305,7 +305,7 @@ describe("Mystery Encounter Utils", () => {
 
   describe("showEncounterText", () => {
     it("showText with dialogue tokens", async () => {
-      scene.currentBattle.mysteryEncounter = new MysteryEncounter(null);
+      scene.currentBattle.mysteryEncounter = new IMysteryEncounter(null);
       scene.currentBattle.mysteryEncounter.setDialogueToken("test", "value");
       const spy = vi.spyOn(game.scene.ui, "showText");
 
@@ -316,7 +316,7 @@ describe("Mystery Encounter Utils", () => {
 
   describe("showEncounterDialogue", () => {
     it("showText with dialogue tokens", async () => {
-      scene.currentBattle.mysteryEncounter = new MysteryEncounter(null);
+      scene.currentBattle.mysteryEncounter = new IMysteryEncounter(null);
       scene.currentBattle.mysteryEncounter.setDialogueToken("test", "value");
       const spy = vi.spyOn(game.scene.ui, "showDialogue");