diff --git a/public/locales b/public/locales index 17b353bd575..813e5a34739 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 17b353bd5752b7ce5c9e7051a17ec310e0b99c1e +Subproject commit 813e5a34739100efd5936bc8a63301dfe451ff8d diff --git a/src/data/challenge.ts b/src/data/challenge.ts index ea780f8aeb2..98b7878c42b 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -674,10 +674,10 @@ export class SingleGenerationChallenge extends Challenge { getDescription(overrideValue: number = this.value): string { if (overrideValue === 0) { - return i18next.t("challenges:singleGeneration.desc_default"); + return i18next.t("challenges:singleGeneration.descDefault"); } return i18next.t("challenges:singleGeneration.desc", { - gen: i18next.t(`challenges:singleGeneration.gen_${overrideValue}`), + gen: i18next.t(`challenges:singleGeneration.gen.${overrideValue}`), }); } @@ -758,7 +758,7 @@ export class SingleTypeChallenge extends Challenge { getDescription(overrideValue: number = this.value): string { const type = i18next.t(`pokemonInfo:type.${toCamelCase(PokemonType[overrideValue - 1])}`); const typeColor = `[color=${TypeColor[PokemonType[overrideValue - 1]]}][shadow=${TypeShadow[PokemonType[this.value - 1]]}]${type}[/shadow][/color]`; - const defaultDesc = i18next.t("challenges:singleType.desc_default"); + const defaultDesc = i18next.t("challenges:singleType.descDefault"); const typeDesc = i18next.t("challenges:singleType.desc", { type: typeColor, }); diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index 2f6b988f32e..6750051c3c4 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -514,7 +514,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde function getTrainerConfigForWave(waveIndex: number) { // Bug type superfan trainer config const config = trainerConfigs[TrainerType.BUG_TYPE_SUPERFAN].clone(); - config.name = i18next.t("trainerNames:bug_type_superfan"); + config.name = i18next.t("trainerNames:bugTypeSuperfan"); let pool3Copy = POOL_3_POKEMON.slice(0); pool3Copy = randSeedShuffle(pool3Copy); diff --git a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts index 6d0ff11f07a..5d97dd1fd67 100644 --- a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts @@ -33,7 +33,7 @@ import i18next from "i18next"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounters/theExpertPokemonBreeder"; -const trainerNameKey = "trainerNames:expert_pokemon_breeder"; +const trainerNameKey = "trainerNames:expertPokemonBreeder"; const FIRST_STAGE_EVOLUTION_WAVE = 45; const SECOND_STAGE_EVOLUTION_WAVE = 60; diff --git a/src/data/splash-messages.ts b/src/data/splash-messages.ts index 3223bbb019e..55ba185bfb2 100644 --- a/src/data/splash-messages.ts +++ b/src/data/splash-messages.ts @@ -100,7 +100,7 @@ const commonSplashMessages = [ "liveWoChienReaction", "itsAFeatureNotABug", "theEggsAreNotForEating", - "7.8outOf10TooManyWaterBiomes", + "tooManyWaterBiomes", "butNothingHappened", "thePowerOfScienceIsAmazing", "freeToPlay", @@ -152,7 +152,7 @@ const commonSplashMessages = [ "insertTextHere", "endingEndlessNotFound", "iLikeMyEggsVouchered", - "YOU", + "you", "noAddedSugar", "notSponsored", "notRated", diff --git a/src/data/trainers/trainer-config.ts b/src/data/trainers/trainer-config.ts index 67618df1ddd..b39795d2650 100644 --- a/src/data/trainers/trainer-config.ts +++ b/src/data/trainers/trainer-config.ts @@ -43,7 +43,7 @@ import type { } from "#types/trainer-funcs"; import { coerceArray, isNullOrUndefined, randSeedInt, randSeedIntRange, randSeedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; -import { toSnakeCase, toTitleCase } from "#utils/strings"; +import { toCamelCase, toTitleCase } from "#utils/strings"; import i18next from "i18next"; /** Minimum BST for Pokemon generated onto the Elite Four's teams */ @@ -193,8 +193,7 @@ export class TrainerConfig { initI18n(); } - // Make the title lowercase and replace spaces with underscores - title = title.toLowerCase().replace(/\s/g, "_"); + title = toCamelCase(title); // Get the title from the i18n file this.title = i18next.t(`titles:${title}`); @@ -288,7 +287,7 @@ export class TrainerConfig { initI18n(); } // Set the localized name for the female rival. - this.nameFemale = i18next.t("trainerNames:rival_female"); + this.nameFemale = i18next.t("trainerNames:rivalFemale"); } else { // Otherwise, assign the provided female name. this.nameFemale = nameFemale!; // TODO: is this bang correct? @@ -365,8 +364,7 @@ export class TrainerConfig { initI18n(); } - // Make the title lowercase and replace spaces with underscores - titleDouble = titleDouble.toLowerCase().replace(/\s/g, "_"); + titleDouble = toCamelCase(titleDouble); // Get the title from the i18n file this.titleDouble = i18next.t(`titles:${titleDouble}`); @@ -552,7 +550,7 @@ export class TrainerConfig { this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(coerceArray(speciesPool))); }); - const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); + const nameForCall = toCamelCase(this.name); this.name = i18next.t(`trainerNames:${nameForCall}`); this.setHasVoucher(false); this.setTitle(title); @@ -577,7 +575,7 @@ export class TrainerConfig { this.setPartyTemplates(trainerPartyTemplates.ELITE_FOUR); - const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); + const nameForCall = toCamelCase(this.name); this.name = i18next.t(`trainerNames:${nameForCall}`); this.setMoneyMultiplier(2); this.setBoss(); @@ -618,7 +616,7 @@ export class TrainerConfig { this.setSpeciesFilter(p => p.isOfType(specialtyType)); this.setSpecialtyType(specialtyType); } - const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); + const nameForCall = toCamelCase(this.name); this.name = i18next.t(`trainerNames:${nameForCall}`); this.setTitle(title); this.setMoneyMultiplier(2.5); @@ -665,14 +663,14 @@ export class TrainerConfig { this.setSpeciesFilter(p => p.isOfType(specialtyType)); this.setSpecialtyType(specialtyType); - // Localize the trainer's name by converting it to lowercase and replacing spaces with underscores. - const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); + // Localize the trainer's name by converting it to camel case. + const nameForCall = toCamelCase(this.name); this.name = i18next.t(`trainerNames:${nameForCall}`); - // Set the title to "gym_leader". (this is the key in the i18n file) - this.setTitle("gym_leader"); + // Set the title to "gymLeader". (this is the key in the i18n file) + this.setTitle("gymLeader"); if (!isMale) { - this.setTitle("gym_leader_female"); + this.setTitle("gymLeaderFemale"); } // Configure various properties for the Gym Leader. @@ -726,14 +724,14 @@ export class TrainerConfig { this.setSpeciesFilter(p => p.baseTotal >= ELITE_FOUR_MINIMUM_BST); } - // Localize the trainer's name by converting it to lowercase and replacing spaces with underscores. - const nameForCall = toSnakeCase(this.name); + // Localize the trainer's name by converting it to camel case. + const nameForCall = toCamelCase(this.name); this.name = i18next.t(`trainerNames:${nameForCall}`); // Set the title to "elite_four". (this is the key in the i18n file) - this.setTitle("elite_four"); + this.setTitle("eliteFour"); if (!isMale) { - this.setTitle("elite_four_female"); + this.setTitle("eliteFourFemale"); } // Configure various properties for the Elite Four member. @@ -763,14 +761,14 @@ export class TrainerConfig { // Set the party templates for the Champion. this.setPartyTemplates(trainerPartyTemplates.CHAMPION); - // Localize the trainer's name by converting it to lowercase and replacing spaces with underscores. - const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); + // Localize the trainer's name by converting it to camel case. + const nameForCall = toCamelCase(this.name); this.name = i18next.t(`trainerNames:${nameForCall}`); // Set the title to "champion". (this is the key in the i18n file) this.setTitle("champion"); if (!isMale) { - this.setTitle("champion_female"); + this.setTitle("championFemale"); } // Configure various properties for the Champion. @@ -794,7 +792,7 @@ export class TrainerConfig { if (!getIsInitialized()) { initI18n(); } - this.name = i18next.t(`trainerNames:${name.toLowerCase().replace(/\s/g, "_")}`); + this.name = i18next.t(`trainerNames:${toCamelCase(name)}`); return this; } @@ -830,9 +828,9 @@ export class TrainerConfig { initI18n(); } // Check if the female version exists in the i18n file - if (i18next.exists(`trainerClasses:${this.name.toLowerCase()}`)) { + if (i18next.exists(`trainerClasses:${toCamelCase(this.name)}Female`)) { // If it does, return - return ret + "_female"; + return ret + "Female"; } } } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 3a5d435fb36..e12485a7272 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5708,7 +5708,11 @@ export class PlayerPokemon extends Pokemon { } if (!dataSource) { - if (globalScene.gameMode.isDaily) { + if ( + globalScene.gameMode.isDaily || + // Keldeo is excluded due to crashes involving its signature move and the associated form change + (Overrides.STARTER_SPECIES_OVERRIDE && Overrides.STARTER_SPECIES_OVERRIDE !== SpeciesId.KELDEO) + ) { this.generateAndPopulateMoveset(); } else { this.moveset = []; diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 584c9310932..d3825aae26b 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -23,7 +23,7 @@ import { } from "#trainers/trainer-party-template"; import { randSeedInt, randSeedItem, randSeedWeightedItem } from "#utils/common"; import { getPokemonSpecies } from "#utils/pokemon-utils"; -import { toSnakeCase } from "#utils/strings"; +import { toCamelCase } from "#utils/strings"; import i18next from "i18next"; export class Trainer extends Phaser.GameObjects.Container { @@ -170,7 +170,7 @@ export class Trainer extends Phaser.GameObjects.Container { const evilTeamTitles = ["grunt"]; if (this.name === "" && evilTeamTitles.some(t => name.toLocaleLowerCase().includes(t))) { // This is a evil team grunt so we localize it by only using the "name" as the title - title = i18next.t(`trainerClasses:${toSnakeCase(name)}`); + title = i18next.t(`trainerClasses:${toCamelCase(name)}`); console.log("Localized grunt name: " + title); // Since grunts are not named we can just return the title return title; @@ -187,7 +187,7 @@ export class Trainer extends Phaser.GameObjects.Container { } // Get the localized trainer class name from the i18n file and set it as the title. // This is used for trainer class names, not titles like "Elite Four, Champion, etc." - title = i18next.t(`trainerClasses:${toSnakeCase(name)}`); + title = i18next.t(`trainerClasses:${toCamelCase(name)}`); } // If no specific trainer slot is set. @@ -208,7 +208,7 @@ export class Trainer extends Phaser.GameObjects.Container { if (this.config.titleDouble && this.variant === TrainerVariant.DOUBLE && !this.config.doubleOnly) { title = this.config.titleDouble; - name = i18next.t(`trainerNames:${toSnakeCase(this.config.nameDouble)}`); + name = i18next.t(`trainerNames:${toCamelCase(this.config.nameDouble)}`); } console.log(title ? `${title} ${name}` : name); diff --git a/src/overrides.ts b/src/overrides.ts index 48d7428cad9..b8212ea8fd6 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -78,15 +78,19 @@ class DefaultOverrides { readonly ARENA_TINT_OVERRIDE: TimeOfDay | null = null; /** Multiplies XP gained by this value including 0. Set to null to ignore the override. */ readonly XP_MULTIPLIER_OVERRIDE: number | null = null; - /** Sets the level cap to this number during experience gain calculations. Set to `0` to disable override & use normal wave-based level caps, - or any negative number to set it to 9 quadrillion (effectively disabling it). */ + /** + * Sets the level cap to this number during experience gain calculations. + * + * Set to `0` to disable override & use normal wave-based level caps, + * or any negative number to disable level caps entirely. + */ readonly LEVEL_CAP_OVERRIDE: number = 0; /** * If defined, overrides random critical hit rolls to always or never succeed. * Ignored if the move is guaranteed to always/never crit. */ readonly CRITICAL_HIT_OVERRIDE: boolean | null = null; - /** default 1000 */ + /** @defaultValue `1000` */ readonly STARTING_MONEY_OVERRIDE: number = 0; /** Sets all shop item prices to 0 */ readonly WAIVE_SHOP_FEES_OVERRIDE: boolean = false; @@ -130,8 +134,8 @@ class DefaultOverrides { // PLAYER OVERRIDES // ---------------- /** - * Set the form index of any starter in the party whose `speciesId` is inside this override - * @see {@link allSpecies} in `src/data/pokemon-species.ts` for form indexes + * Set the form index of any starter in the party whose {@linkcode SpeciesId} is inside this override + * @see `src/data/pokemon-species.ts` for form indexes * @example * ``` * const STARTER_FORM_OVERRIDES = { @@ -141,23 +145,14 @@ class DefaultOverrides { */ readonly STARTER_FORM_OVERRIDES: Partial> = {}; - /** default 5 or 20 for Daily */ + /** @defaultValue `20` for Daily and `5` for all other modes */ readonly STARTING_LEVEL_OVERRIDE: number = 0; - /** - * SPECIES OVERRIDE - * will only apply to the first starter in your party or each enemy pokemon - * default is 0 to not override - * @example SPECIES_OVERRIDE = SpeciesId.Bulbasaur; - */ - readonly STARTER_SPECIES_OVERRIDE: SpeciesId | number = 0; - /** - * This will force your starter to be a random fusion - */ + /** Will override the species of your pokemon when starting a new run */ + readonly STARTER_SPECIES_OVERRIDE: SpeciesId | 0 = 0; + /** This will force your starter to be a random fusion */ readonly STARTER_FUSION_OVERRIDE: boolean = false; - /** - * This will override the species of the fusion - */ - readonly STARTER_FUSION_SPECIES_OVERRIDE: SpeciesId | number = 0; + /** This will override the species of the fusion */ + readonly STARTER_FUSION_SPECIES_OVERRIDE: SpeciesId | 0 = 0; readonly ABILITY_OVERRIDE: AbilityId = AbilityId.NONE; readonly PASSIVE_ABILITY_OVERRIDE: AbilityId = AbilityId.NONE; readonly HAS_PASSIVE_ABILITY_OVERRIDE: boolean | null = null; @@ -180,13 +175,9 @@ class DefaultOverrides { // OPPONENT / ENEMY OVERRIDES // -------------------------- readonly ENEMY_SPECIES_OVERRIDE: SpeciesId | number = 0; - /** - * This will make all opponents fused Pokemon - */ + /** This will make all enemies fused Pokemon */ readonly ENEMY_FUSION_OVERRIDE: boolean = false; - /** - * This will override the species of the fusion only when the opponent is already a fusion - */ + /** This will override the species of the fusion only when the enemy is already a fusion */ readonly ENEMY_FUSION_SPECIES_OVERRIDE: SpeciesId | number = 0; readonly ENEMY_LEVEL_OVERRIDE: number = 0; readonly ENEMY_ABILITY_OVERRIDE: AbilityId = AbilityId.NONE; @@ -197,6 +188,7 @@ class DefaultOverrides { readonly ENEMY_MOVESET_OVERRIDE: MoveId | Array = []; readonly ENEMY_SHINY_OVERRIDE: boolean | null = null; readonly ENEMY_VARIANT_OVERRIDE: Variant | null = null; + /** * Overrides the IVs of enemy pokemon. Values must never be outside the range `0` to `31`! * - If set to a number between `0` and `31`, set all IVs of all enemy pokemon to that number. @@ -210,9 +202,9 @@ class DefaultOverrides { /** * Override to give the enemy Pokemon a given amount of health segments * - * 0 (default): the health segments will be handled normally based on wave, level and species - * 1: the Pokemon will have a single health segment and therefore will not be a boss - * 2+: the Pokemon will be a boss with the given number of health segments + * - `0` (default): the health segments will be handled normally based on wave, level and species + * - `1`: the Pokemon will have a single health segment and therefore will not be a boss + * - `2+`: the Pokemon will be a boss with the given number of health segments */ readonly ENEMY_HEALTH_SEGMENTS_OVERRIDE: number = 0; @@ -293,9 +285,7 @@ class DefaultOverrides { */ readonly ITEM_REWARD_OVERRIDE: ModifierOverride[] = []; - /** - * If `true`, disable all non-scripted opponent trainer encounters. - */ + /** If `true`, disable all non-scripted opponent trainer encounters. */ readonly DISABLE_STANDARD_TRAINERS_OVERRIDE: boolean = false; /** diff --git a/src/phase.ts b/src/phase.ts index eccbf3127e6..6fea6e3b0f0 100644 --- a/src/phase.ts +++ b/src/phase.ts @@ -2,8 +2,10 @@ import { globalScene } from "#app/global-scene"; import type { PhaseMap, PhaseString } from "#types/phase-types"; export abstract class Phase { + /** Start the current phase. */ start() {} + /** End the current phase and start a new one. */ end() { globalScene.phaseManager.shiftPhase(); } diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index ff9ee7cc197..87c33a4334b 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -474,20 +474,21 @@ export class CommandPhase extends FieldPhase { } if (trappedAbMessages.length > 0) { if (isSwitch) { - globalScene.ui.setMode(UiMode.MESSAGE); + globalScene.ui.setMode(UiMode.MESSAGE).then(() => { + globalScene.ui.showText( + trappedAbMessages[0], + null, + () => { + globalScene.ui.showText("", 0); + if (isSwitch) { + globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); + } + }, + null, + true, + ); + }); } - globalScene.ui.showText( - trappedAbMessages[0], - null, - () => { - globalScene.ui.showText("", 0); - if (isSwitch) { - globalScene.ui.setMode(UiMode.COMMAND, this.fieldIndex); - } - }, - null, - true, - ); } else { const trapTag = playerPokemon.getTag(TrappedTag); const fairyLockTag = globalScene.arena.getTagOnSide(ArenaTagType.FAIRY_LOCK, ArenaTagSide.PLAYER); diff --git a/src/phases/game-over-phase.ts b/src/phases/game-over-phase.ts index dc4a138c444..dcde244ecd3 100644 --- a/src/phases/game-over-phase.ts +++ b/src/phases/game-over-phase.ts @@ -120,18 +120,24 @@ export class GameOverPhase extends BattlePhase { */ private awardRibbons(): void { let ribbonFlags = 0n; - if (globalScene.gameMode.isClassic) { - ribbonFlags |= RibbonData.CLASSIC; - } - if (isNuzlockeChallenge()) { - ribbonFlags |= RibbonData.NUZLOCKE; - } for (const challenge of globalScene.gameMode.challenges) { const ribbon = challenge.ribbonAwarded; if (challenge.value && ribbon) { ribbonFlags |= ribbon; } } + // Block other ribbons if flip stats or inverse is active + const flip_or_inverse = ribbonFlags & (RibbonData.FLIP_STATS | RibbonData.INVERSE); + if (flip_or_inverse) { + ribbonFlags = flip_or_inverse; + } else { + if (globalScene.gameMode.isClassic) { + ribbonFlags |= RibbonData.CLASSIC; + } + if (isNuzlockeChallenge()) { + ribbonFlags |= RibbonData.NUZLOCKE; + } + } // Award ribbons to all Pokémon in the player's party that are considered valid // for the current game mode and challenges. for (const pokemon of globalScene.getPlayerParty()) { diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 32d9e0ee2be..86305b3f7ed 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -197,35 +197,35 @@ export const Setting: Array = [ options: [ { value: "1", - label: i18next.t("settings:gameSpeed1x"), + label: i18next.t("settings:gameSpeed100x"), }, { value: "1.25", - label: i18next.t("settings:gameSpeed1_25x"), + label: i18next.t("settings:gameSpeed125x"), }, { value: "1.5", - label: i18next.t("settings:gameSpeed1_5x"), + label: i18next.t("settings:gameSpeed150x"), }, { value: "2", - label: i18next.t("settings:gameSpeed2x"), + label: i18next.t("settings:gameSpeed200x"), }, { value: "2.5", - label: i18next.t("settings:gameSpeed2_5x"), + label: i18next.t("settings:gameSpeed250x"), }, { value: "3", - label: i18next.t("settings:gameSpeed3x"), + label: i18next.t("settings:gameSpeed300x"), }, { value: "4", - label: i18next.t("settings:gameSpeed4x"), + label: i18next.t("settings:gameSpeed400x"), }, { value: "5", - label: i18next.t("settings:gameSpeed5x"), + label: i18next.t("settings:gameSpeed500x"), }, ], default: 3, @@ -566,7 +566,7 @@ export const Setting: Array = [ }, { value: "Back", - label: i18next.t("settings:timeOfDay_back"), + label: i18next.t("settings:timeOfDayBack"), }, ], default: 0, diff --git a/src/ui/game-stats-ui-handler.ts b/src/ui/game-stats-ui-handler.ts index d2a9779f515..4ddb80fcc00 100644 --- a/src/ui/game-stats-ui-handler.ts +++ b/src/ui/game-stats-ui-handler.ts @@ -308,8 +308,8 @@ export class GameStatsUiHandler extends UiHandler { private getUsername(): string { const usernameReplacement = globalScene.gameData.gender === PlayerGender.FEMALE - ? i18next.t("trainerNames:player_f") - : i18next.t("trainerNames:player_m"); + ? i18next.t("trainerNames:playerF") + : i18next.t("trainerNames:playerM"); const displayName = !globalScene.hideUsername ? (loggedInUser?.username ?? i18next.t("common:guest")) diff --git a/src/ui/pokedex-page-ui-handler.ts b/src/ui/pokedex-page-ui-handler.ts index ae89a85c402..5b5dca29641 100644 --- a/src/ui/pokedex-page-ui-handler.ts +++ b/src/ui/pokedex-page-ui-handler.ts @@ -640,7 +640,7 @@ export class PokedexPageUiHandler extends MessageUiHandler { this.optionSelectText = addBBCodeTextObject( 0, 0, - this.menuOptions.map(o => `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`).join("\n"), + this.menuOptions.map(o => `${i18next.t(`pokedexUiHandler:${toCamelCase(`menu${MenuOptions[o]}`)}`)}`).join("\n"), TextStyle.WINDOW, { maxLines: this.menuOptions.length, lineSpacing: 12 }, ); @@ -757,7 +757,7 @@ export class PokedexPageUiHandler extends MessageUiHandler { return this.menuOptions .map(o => { - const label = `${i18next.t(`pokedexUiHandler:${MenuOptions[o]}`)}`; + const label = i18next.t(`pokedexUiHandler:${toCamelCase(`menu${MenuOptions[o]}`)}`); const isDark = !isSeen || (!isStarterCaught && (o === MenuOptions.TOGGLE_IVS || o === MenuOptions.NATURES)) || diff --git a/src/ui/rename-run-ui-handler.ts b/src/ui/rename-run-ui-handler.ts index 23ba0137f2d..a94b7b08fb9 100644 --- a/src/ui/rename-run-ui-handler.ts +++ b/src/ui/rename-run-ui-handler.ts @@ -5,7 +5,7 @@ import type { ModalConfig } from "./modal-ui-handler"; export class RenameRunFormUiHandler extends FormModalUiHandler { getModalTitle(_config?: ModalConfig): string { - return i18next.t("menu:renamerun"); + return i18next.t("menu:renameRun"); } getWidth(_config?: ModalConfig): number { diff --git a/src/ui/run-history-ui-handler.ts b/src/ui/run-history-ui-handler.ts index 457c48654a3..6f4d9024832 100644 --- a/src/ui/run-history-ui-handler.ts +++ b/src/ui/run-history-ui-handler.ts @@ -337,7 +337,7 @@ class RunEntryContainer extends Phaser.GameObjects.Container { // Because of the interesting mechanics behind rival names, the rival name and title have to be retrieved differently const RIVAL_TRAINER_ID_THRESHOLD = 375; if (data.trainer.trainerType >= RIVAL_TRAINER_ID_THRESHOLD) { - const rivalName = tObj.variant === TrainerVariant.FEMALE ? "trainerNames:rival_female" : "trainerNames:rival"; + const rivalName = tObj.variant === TrainerVariant.FEMALE ? "trainerNames:rivalFemale" : "trainerNames:rival"; const gameOutcomeLabel = addTextObject( 8, 5, diff --git a/src/ui/run-info-ui-handler.ts b/src/ui/run-info-ui-handler.ts index a5e21a3a0a1..5fc0f37c72d 100644 --- a/src/ui/run-info-ui-handler.ts +++ b/src/ui/run-info-ui-handler.ts @@ -337,7 +337,7 @@ export class RunInfoUiHandler extends UiHandler { if (this.runInfo.trainer.trainerType >= RIVAL_TRAINER_ID_THRESHOLD) { trainerName = trainerObj.variant === TrainerVariant.FEMALE - ? i18next.t("trainerNames:rival_female") + ? i18next.t("trainerNames:rivalFemale") : i18next.t("trainerNames:rival"); } else { trainerName = trainerObj.getName(0, true); @@ -805,7 +805,7 @@ export class RunInfoUiHandler extends UiHandler { const spdef = i18next.t("pokemonInfo:stat.spdefShortened") + ": " + pStats[4]; const speedLabel = currentLanguage === "es-ES" || currentLanguage === "pt_BR" - ? i18next.t("runHistory:SPDshortened") + ? i18next.t("runHistory:spdShortened") : i18next.t("pokemonInfo:stat.spdShortened"); const speed = speedLabel + ": " + pStats[5]; // Column 1: HP Atk Def diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 01d9b981563..b6447f03587 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -808,8 +808,8 @@ export class SummaryUiHandler extends UiHandler { globalScene.gameData.gender === PlayerGender.FEMALE ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY_BLUE; const usernameReplacement = globalScene.gameData.gender === PlayerGender.FEMALE - ? i18next.t("trainerNames:player_f") - : i18next.t("trainerNames:player_m"); + ? i18next.t("trainerNames:playerF") + : i18next.t("trainerNames:playerM"); // TODO: should add field for original trainer name to Pokemon object, to support gift/traded Pokemon from MEs const trainerText = addBBCodeTextObject( diff --git a/src/ui/title-ui-handler.ts b/src/ui/title-ui-handler.ts index 36e37500a64..5ae195231e5 100644 --- a/src/ui/title-ui-handler.ts +++ b/src/ui/title-ui-handler.ts @@ -122,8 +122,8 @@ export class TitleUiHandler extends OptionSelectUiHandler { genderSplash(): void { if (this.splashMessage === "splashMessages:aprilFools.helloKyleAmber") { globalScene.gameData.gender === PlayerGender.MALE - ? this.splashMessageText.setText(i18next.t(this.splashMessage, { name: i18next.t("trainerNames:player_m") })) - : this.splashMessageText.setText(i18next.t(this.splashMessage, { name: i18next.t("trainerNames:player_f") })); + ? this.splashMessageText.setText(i18next.t(this.splashMessage, { name: i18next.t("trainerNames:playerM") })) + : this.splashMessageText.setText(i18next.t(this.splashMessage, { name: i18next.t("trainerNames:playerF") })); } } diff --git a/test/abilities/disguise.test.ts b/test/abilities/disguise.test.ts index 4745d6ab609..f36501cb647 100644 --- a/test/abilities/disguise.test.ts +++ b/test/abilities/disguise.test.ts @@ -134,7 +134,7 @@ describe("Abilities - Disguise", () => { }); await game.classicMode.startBattle([SpeciesId.FURRET, SpeciesId.MIMIKYU]); - const mimikyu = game.scene.getPlayerParty()[1]!; + const mimikyu = game.scene.getPlayerParty()[1]; expect(mimikyu.formIndex).toBe(bustedForm); game.move.select(MoveId.SPLASH); diff --git a/test/abilities/moxie.test.ts b/test/abilities/moxie.test.ts index 042a8ddd058..d762187baba 100644 --- a/test/abilities/moxie.test.ts +++ b/test/abilities/moxie.test.ts @@ -3,9 +3,6 @@ import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; 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 Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -46,7 +43,7 @@ describe("Abilities - Moxie", () => { expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0); game.move.select(moveToUse); - await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(VictoryPhase); + await game.phaseInterceptor.to("VictoryPhase"); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(1); }); @@ -67,7 +64,7 @@ describe("Abilities - Moxie", () => { game.move.select(moveToUse, BattlerIndex.PLAYER_2); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(firstPokemon.getStatStage(Stat.ATK)).toBe(1); }, diff --git a/test/abilities/sheer-force.test.ts b/test/abilities/sheer-force.test.ts index 0e2ce85bfca..10fd454d6c2 100644 --- a/test/abilities/sheer-force.test.ts +++ b/test/abilities/sheer-force.test.ts @@ -121,8 +121,8 @@ describe("Abilities - Sheer Force", () => { await game.classicMode.startBattle([SpeciesId.PIDGEOT]); - const pidgeot = game.scene.getPlayerParty()[0]; - const onix = game.scene.getEnemyParty()[0]; + const pidgeot = game.field.getPlayerPokemon(); + const onix = game.field.getEnemyPokemon(); pidgeot.stats[Stat.DEF] = 10000; onix.stats[Stat.DEF] = 10000; diff --git a/test/abilities/sturdy.test.ts b/test/abilities/sturdy.test.ts index 28d3098a420..4480653c12f 100644 --- a/test/abilities/sturdy.test.ts +++ b/test/abilities/sturdy.test.ts @@ -1,7 +1,6 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import type { EnemyPokemon } from "#field/pokemon"; import { DamageAnimPhase } from "#phases/damage-anim-phase"; import { MoveEndPhase } from "#phases/move-end-phase"; import { GameManager } from "#test/test-utils/game-manager"; @@ -38,13 +37,13 @@ describe("Abilities - Sturdy", () => { await game.classicMode.startBattle(); game.move.select(MoveId.CLOSE_COMBAT); await game.phaseInterceptor.to(MoveEndPhase); - expect(game.scene.getEnemyParty()[0].hp).toBe(1); + expect(game.field.getEnemyPokemon().hp).toBe(1); }); test("Sturdy doesn't activate when user is not at full HP", async () => { await game.classicMode.startBattle(); - const enemyPokemon: EnemyPokemon = game.scene.getEnemyParty()[0]; + const enemyPokemon = game.field.getEnemyPokemon(); enemyPokemon.hp = enemyPokemon.getMaxHp() - 1; game.move.select(MoveId.CLOSE_COMBAT); @@ -59,19 +58,7 @@ describe("Abilities - Sturdy", () => { game.move.select(MoveId.FISSURE); await game.phaseInterceptor.to(MoveEndPhase); - const enemyPokemon: EnemyPokemon = game.scene.getEnemyParty()[0]; + const enemyPokemon = game.field.getEnemyPokemon(); expect(enemyPokemon.isFullHp()).toBe(true); }); - - test("Sturdy is ignored by pokemon with `AbilityId.MOLD_BREAKER`", async () => { - game.override.ability(AbilityId.MOLD_BREAKER); - - await game.classicMode.startBattle(); - game.move.select(MoveId.CLOSE_COMBAT); - await game.phaseInterceptor.to(DamageAnimPhase); - - const enemyPokemon: EnemyPokemon = game.scene.getEnemyParty()[0]; - expect(enemyPokemon.hp).toBe(0); - expect(enemyPokemon.isFainted()).toBe(true); - }); }); diff --git a/test/abilities/wimp-out.test.ts b/test/abilities/wimp-out.test.ts index 1e129f34a19..46fd5094255 100644 --- a/test/abilities/wimp-out.test.ts +++ b/test/abilities/wimp-out.test.ts @@ -336,7 +336,7 @@ describe("Abilities - Wimp Out", () => { game.move.select(MoveId.SPLASH); await game.phaseInterceptor.to("TurnEndPhase"); - expect(game.scene.getPlayerParty()[0].getHpRatio()).toEqual(0.51); + expect(game.field.getPlayerPokemon().getHpRatio()).toEqual(0.51); expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase"); expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.WIMPOD); }); @@ -344,8 +344,7 @@ describe("Abilities - Wimp Out", () => { it("Wimp Out activating should not cancel a double battle", async () => { game.override.battleStyle("double").enemyAbility(AbilityId.WIMP_OUT).enemyMoveset([MoveId.SPLASH]).enemyLevel(1); await game.classicMode.startBattle([SpeciesId.WIMPOD, SpeciesId.TYRUNT]); - const enemyLeadPokemon = game.scene.getEnemyParty()[0]; - const enemySecPokemon = game.scene.getEnemyParty()[1]; + const [enemyLeadPokemon, enemySecPokemon] = game.scene.getEnemyParty(); game.move.select(MoveId.FALSE_SWIPE, 0, BattlerIndex.ENEMY); game.move.select(MoveId.SPLASH, 1); diff --git a/test/abilities/zero-to-hero.test.ts b/test/abilities/zero-to-hero.test.ts index d9fa3580da2..003684894df 100644 --- a/test/abilities/zero-to-hero.test.ts +++ b/test/abilities/zero-to-hero.test.ts @@ -40,8 +40,7 @@ describe("Abilities - ZERO TO HERO", () => { await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.PALAFIN, SpeciesId.PALAFIN]); - const palafin1 = game.scene.getPlayerParty()[1]; - const palafin2 = game.scene.getPlayerParty()[2]; + const [, palafin1, palafin2] = game.scene.getPlayerParty(); expect(palafin1.formIndex).toBe(heroForm); expect(palafin2.formIndex).toBe(heroForm); palafin2.hp = 0; diff --git a/test/battle/battle-order.test.ts b/test/battle/battle-order.test.ts index 0ee23cd6418..0b24fcbfa7d 100644 --- a/test/battle/battle-order.test.ts +++ b/test/battle/battle-order.test.ts @@ -1,9 +1,7 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { EnemyCommandPhase } from "#phases/enemy-command-phase"; -import { SelectTargetPhase } from "#phases/select-target-phase"; -import { TurnStartPhase } from "#phases/turn-start-phase"; +import type { TurnStartPhase } from "#phases/turn-start-phase"; import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; 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 game.move.select(MoveId.TACKLE); - await game.phaseInterceptor.run(EnemyCommandPhase); + await game.phaseInterceptor.to("TurnStartPhase", false); const playerPokemonIndex = playerPokemon.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 game.move.select(MoveId.TACKLE); - await game.phaseInterceptor.run(EnemyCommandPhase); + await game.phaseInterceptor.to("TurnStartPhase", false); const playerPokemonIndex = playerPokemon.getBattlerIndex(); const enemyPokemonIndex = enemyPokemon.getBattlerIndex(); @@ -84,7 +82,7 @@ describe("Battle order", () => { game.move.select(MoveId.TACKLE); 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 order = phase.getCommandOrder(); @@ -108,7 +106,7 @@ describe("Battle order", () => { game.move.select(MoveId.TACKLE); 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 order = phase.getCommandOrder(); @@ -132,7 +130,7 @@ describe("Battle order", () => { game.move.select(MoveId.TACKLE); 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 order = phase.getCommandOrder(); diff --git a/test/battle/battle.test.ts b/test/battle/battle.test.ts index 3dd154cf4eb..36e9bdd17b0 100644 --- a/test/battle/battle.test.ts +++ b/test/battle/battle.test.ts @@ -1,28 +1,13 @@ -import { getGameMode } from "#app/game-mode"; import { allSpecies } from "#data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { BiomeId } from "#enums/biome-id"; -import { GameModes } from "#enums/game-modes"; import { MoveId } from "#enums/move-id"; -import { PlayerGender } from "#enums/player-gender"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import { UiMode } from "#enums/ui-mode"; -import { BattleEndPhase } from "#phases/battle-end-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 { 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 { generateStarter } from "#test/test-utils/game-manager-utils"; import Phaser from "phaser"; 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! }); - 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 () => { game.override.enemySpecies(SpeciesId.RATTATA).startingLevel(2000).battleStyle("single").startingWave(3); await game.classicMode.startBattle([SpeciesId.MEWTWO]); 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 () => { @@ -107,7 +48,7 @@ describe("Phase - Battle Phase", () => { .battleStyle("single"); await game.classicMode.startBattle([SpeciesId.MEWTWO]); 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 () => { @@ -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([ { name: "1v1", double: false, qty: 1 }, { name: "2v1", double: false, qty: 2 }, @@ -232,7 +111,7 @@ describe("Phase - Battle Phase", () => { await game.classicMode.startBattle([SpeciesId.DARMANITAN, SpeciesId.CHARIZARD]); game.move.select(moveToUse); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); await game.killPokemon(game.scene.currentBattle.enemyParty[0]); expect(game.scene.currentBattle.enemyParty[0].isFainted()).toBe(true); await game.phaseInterceptor.to("VictoryPhase"); @@ -296,7 +175,7 @@ describe("Phase - Battle Phase", () => { game.field.getPlayerPokemon().hp = 1; game.move.select(moveToUse); - await game.phaseInterceptor.to(BattleEndPhase); + await game.phaseInterceptor.to("BattleEndPhase"); game.doRevivePokemon(0); // pretend max revive was picked game.doSelectModifier(); @@ -308,6 +187,6 @@ describe("Phase - Battle Phase", () => { }, () => game.isCurrentPhase(NextEncounterPhase), ); - await game.phaseInterceptor.to(SwitchPhase); + await game.phaseInterceptor.to("SwitchPhase"); }); }); diff --git a/test/boss-pokemon.test.ts b/test/boss-pokemon.test.ts index b0dfbf19794..6ad405d58e6 100644 --- a/test/boss-pokemon.test.ts +++ b/test/boss-pokemon.test.ts @@ -64,11 +64,9 @@ describe("Boss Pokemon / Shields", () => { it("should reduce the number of shields if we are in a double battle", async () => { game.override.battleStyle("double").startingWave(150); // Floor 150 > 2 shields / 3 health segments - await game.classicMode.startBattle([SpeciesId.MEWTWO]); - const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!; - const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!; + const [boss1, boss2] = game.scene.getEnemyParty(); expect(boss1.isBoss()).toBe(true); expect(boss1.bossSegments).toBe(2); expect(boss2.isBoss()).toBe(true); @@ -112,7 +110,7 @@ describe("Boss Pokemon / Shields", () => { // In this test we want to break through 3 shields at once const brokenShields = 3; - const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!; + const boss1 = game.field.getEnemyPokemon(); const boss1SegmentHp = boss1.getMaxHp() / boss1.bossSegments; const requiredDamageBoss1 = boss1SegmentHp * (1 + Math.pow(2, brokenShields)); expect(boss1.isBoss()).toBe(true); @@ -124,7 +122,7 @@ describe("Boss Pokemon / Shields", () => { expect(boss1.bossSegmentIndex).toBe(1); expect(boss1.hp).toBe(boss1.getMaxHp() - toDmgValue(boss1SegmentHp * 3)); - const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!; + const boss2 = game.scene.getEnemyParty()[1]; const boss2SegmentHp = boss2.getMaxHp() / boss2.bossSegments; const requiredDamageBoss2 = boss2SegmentHp * (1 + Math.pow(2, brokenShields)); @@ -144,7 +142,7 @@ describe("Boss Pokemon / Shields", () => { await game.classicMode.startBattle([SpeciesId.MEWTWO]); - const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!; + const boss1 = game.field.getEnemyPokemon(); const boss1SegmentHp = boss1.getMaxHp() / boss1.bossSegments; const singleShieldDamage = Math.ceil(boss1SegmentHp); expect(boss1.isBoss()).toBe(true); @@ -167,7 +165,7 @@ describe("Boss Pokemon / Shields", () => { expect(getTotalStatStageBoosts(boss1)).toBe(totalStatStages); } - const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!; + const boss2 = game.scene.getEnemyParty()[1]; const boss2SegmentHp = boss2.getMaxHp() / boss2.bossSegments; const requiredDamage = boss2SegmentHp * (1 + Math.pow(2, shieldsToBreak - 1)); diff --git a/test/evolution.test.ts b/test/evolution.test.ts index afe557ff2c0..3fb763e9190 100644 --- a/test/evolution.test.ts +++ b/test/evolution.test.ts @@ -34,8 +34,7 @@ describe("Evolution", () => { it("should keep hidden ability after evolving", async () => { await game.classicMode.runToSummon([SpeciesId.EEVEE, SpeciesId.TRAPINCH]); - const eevee = game.scene.getPlayerParty()[0]; - const trapinch = game.scene.getPlayerParty()[1]; + const [eevee, trapinch] = game.scene.getPlayerParty(); eevee.abilityIndex = 2; trapinch.abilityIndex = 2; @@ -49,8 +48,7 @@ describe("Evolution", () => { it("should keep same ability slot after evolving", async () => { await game.classicMode.runToSummon([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER]); - const bulbasaur = game.scene.getPlayerParty()[0]; - const charmander = game.scene.getPlayerParty()[1]; + const [bulbasaur, charmander] = game.scene.getPlayerParty(); bulbasaur.abilityIndex = 0; charmander.abilityIndex = 1; @@ -80,8 +78,7 @@ describe("Evolution", () => { nincada.gender = 1; await nincada.evolve(pokemonEvolutions[SpeciesId.NINCADA][0], nincada.getSpeciesForm()); - const ninjask = game.scene.getPlayerParty()[0]; - const shedinja = game.scene.getPlayerParty()[1]; + const [ninjask, shedinja] = game.scene.getPlayerParty(); expect(ninjask.abilityIndex).toBe(2); expect(shedinja.abilityIndex).toBe(1); expect(ninjask.gender).toBe(1); diff --git a/test/field/pokemon.test.ts b/test/field/pokemon.test.ts index 02058ad6cb1..ec9434c99ea 100644 --- a/test/field/pokemon.test.ts +++ b/test/field/pokemon.test.ts @@ -85,17 +85,14 @@ describe("Spec - Pokemon", () => { }); describe("Get correct fusion type", () => { - let scene: BattleScene; - beforeEach(async () => { game.override.enemySpecies(SpeciesId.ZUBAT).starterSpecies(SpeciesId.ABRA).enableStarterFusion(); - scene = game.scene; }); it("Fusing two mons with a single type", async () => { game.override.starterFusionSpecies(SpeciesId.CHARMANDER); await game.classicMode.startBattle(); - const pokemon = scene.getPlayerParty()[0]; + const pokemon = game.field.getPlayerPokemon(); let types = pokemon.getTypes(); expect(types[0]).toBe(PokemonType.PSYCHIC); @@ -136,7 +133,7 @@ describe("Spec - Pokemon", () => { it("Fusing two mons with same single type", async () => { game.override.starterFusionSpecies(SpeciesId.DROWZEE); await game.classicMode.startBattle(); - const pokemon = scene.getPlayerParty()[0]; + const pokemon = game.field.getPlayerPokemon(); const types = pokemon.getTypes(); expect(types[0]).toBe(PokemonType.PSYCHIC); @@ -146,7 +143,7 @@ describe("Spec - Pokemon", () => { it("Fusing mons with one and two types", async () => { game.override.starterSpecies(SpeciesId.CHARMANDER).starterFusionSpecies(SpeciesId.HOUNDOUR); await game.classicMode.startBattle(); - const pokemon = scene.getPlayerParty()[0]; + const pokemon = game.field.getPlayerPokemon(); const types = pokemon.getTypes(); expect(types[0]).toBe(PokemonType.FIRE); @@ -156,7 +153,7 @@ describe("Spec - Pokemon", () => { it("Fusing mons with two and one types", async () => { game.override.starterSpecies(SpeciesId.NUMEL).starterFusionSpecies(SpeciesId.CHARMANDER); await game.classicMode.startBattle(); - const pokemon = scene.getPlayerParty()[0]; + const pokemon = game.field.getPlayerPokemon(); const types = pokemon.getTypes(); expect(types[0]).toBe(PokemonType.FIRE); @@ -166,7 +163,7 @@ describe("Spec - Pokemon", () => { it("Fusing two mons with two types", async () => { game.override.starterSpecies(SpeciesId.NATU).starterFusionSpecies(SpeciesId.HOUNDOUR); await game.classicMode.startBattle(); - const pokemon = scene.getPlayerParty()[0]; + const pokemon = game.field.getPlayerPokemon(); let types = pokemon.getTypes(); expect(types[0]).toBe(PokemonType.PSYCHIC); diff --git a/test/items/light-ball.test.ts b/test/items/light-ball.test.ts index a7f41255ff3..280b70f3d5a 100644 --- a/test/items/light-ball.test.ts +++ b/test/items/light-ball.test.ts @@ -33,7 +33,7 @@ describe("Items - Light Ball", () => { const consoleSpy = vi.spyOn(console, "log"); await game.classicMode.startBattle([SpeciesId.PIKACHU]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); // Checking console log to make sure Light Ball is applied when getEffectiveStat (with the appropriate stat) is called partyMember.getEffectiveStat(Stat.DEF); @@ -84,7 +84,7 @@ describe("Items - Light Ball", () => { it("LIGHT_BALL held by PIKACHU", async () => { await game.classicMode.startBattle([SpeciesId.PIKACHU]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const atkStat = partyMember.getStat(Stat.ATK); const spAtkStat = partyMember.getStat(Stat.SPATK); @@ -113,8 +113,7 @@ describe("Items - Light Ball", () => { it("LIGHT_BALL held by fused PIKACHU (base)", async () => { await game.classicMode.startBattle([SpeciesId.PIKACHU, SpeciesId.MAROWAK]); - const partyMember = game.scene.getPlayerParty()[0]; - const ally = game.scene.getPlayerParty()[1]; + const [partyMember, ally] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) partyMember.fusionSpecies = ally.species; @@ -152,8 +151,7 @@ describe("Items - Light Ball", () => { it("LIGHT_BALL held by fused PIKACHU (part)", async () => { await game.classicMode.startBattle([SpeciesId.MAROWAK, SpeciesId.PIKACHU]); - const partyMember = game.scene.getPlayerParty()[0]; - const ally = game.scene.getPlayerParty()[1]; + const [partyMember, ally] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) partyMember.fusionSpecies = ally.species; @@ -191,7 +189,7 @@ describe("Items - Light Ball", () => { it("LIGHT_BALL not held by PIKACHU", async () => { await game.classicMode.startBattle([SpeciesId.MAROWAK]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const atkStat = partyMember.getStat(Stat.ATK); const spAtkStat = partyMember.getStat(Stat.SPATK); diff --git a/test/items/metal-powder.test.ts b/test/items/metal-powder.test.ts index 4dac8dd39b1..1a749f0ac3d 100644 --- a/test/items/metal-powder.test.ts +++ b/test/items/metal-powder.test.ts @@ -33,7 +33,7 @@ describe("Items - Metal Powder", () => { const consoleSpy = vi.spyOn(console, "log"); await game.classicMode.startBattle([SpeciesId.DITTO]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); // Checking console log to make sure Metal Powder is applied when getEffectiveStat (with the appropriate stat) is called partyMember.getEffectiveStat(Stat.DEF); @@ -84,7 +84,7 @@ describe("Items - Metal Powder", () => { it("METAL_POWDER held by DITTO", async () => { await game.classicMode.startBattle([SpeciesId.DITTO]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const defStat = partyMember.getStat(Stat.DEF); @@ -107,8 +107,7 @@ describe("Items - Metal Powder", () => { it("METAL_POWDER held by fused DITTO (base)", async () => { await game.classicMode.startBattle([SpeciesId.DITTO, SpeciesId.MAROWAK]); - const partyMember = game.scene.getPlayerParty()[0]; - const ally = game.scene.getPlayerParty()[1]; + const [partyMember, ally] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) partyMember.fusionSpecies = ally.species; @@ -140,8 +139,7 @@ describe("Items - Metal Powder", () => { it("METAL_POWDER held by fused DITTO (part)", async () => { await game.classicMode.startBattle([SpeciesId.MAROWAK, SpeciesId.DITTO]); - const partyMember = game.scene.getPlayerParty()[0]; - const ally = game.scene.getPlayerParty()[1]; + const [partyMember, ally] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) partyMember.fusionSpecies = ally.species; @@ -173,7 +171,7 @@ describe("Items - Metal Powder", () => { it("METAL_POWDER not held by DITTO", async () => { await game.classicMode.startBattle([SpeciesId.MAROWAK]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const defStat = partyMember.getStat(Stat.DEF); diff --git a/test/items/quick-powder.test.ts b/test/items/quick-powder.test.ts index 2200e8cf96e..0295361ed13 100644 --- a/test/items/quick-powder.test.ts +++ b/test/items/quick-powder.test.ts @@ -33,7 +33,7 @@ describe("Items - Quick Powder", () => { const consoleSpy = vi.spyOn(console, "log"); await game.classicMode.startBattle([SpeciesId.DITTO]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); // Checking console log to make sure Quick Powder is applied when getEffectiveStat (with the appropriate stat) is called partyMember.getEffectiveStat(Stat.DEF); @@ -84,7 +84,7 @@ describe("Items - Quick Powder", () => { it("QUICK_POWDER held by DITTO", async () => { await game.classicMode.startBattle([SpeciesId.DITTO]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const spdStat = partyMember.getStat(Stat.SPD); @@ -107,8 +107,7 @@ describe("Items - Quick Powder", () => { it("QUICK_POWDER held by fused DITTO (base)", async () => { await game.classicMode.startBattle([SpeciesId.DITTO, SpeciesId.MAROWAK]); - const partyMember = game.scene.getPlayerParty()[0]; - const ally = game.scene.getPlayerParty()[1]; + const [partyMember, ally] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) partyMember.fusionSpecies = ally.species; @@ -140,8 +139,7 @@ describe("Items - Quick Powder", () => { it("QUICK_POWDER held by fused DITTO (part)", async () => { await game.classicMode.startBattle([SpeciesId.MAROWAK, SpeciesId.DITTO]); - const partyMember = game.scene.getPlayerParty()[0]; - const ally = game.scene.getPlayerParty()[1]; + const [partyMember, ally] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) partyMember.fusionSpecies = ally.species; @@ -173,7 +171,7 @@ describe("Items - Quick Powder", () => { it("QUICK_POWDER not held by DITTO", async () => { await game.classicMode.startBattle([SpeciesId.MAROWAK]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const spdStat = partyMember.getStat(Stat.SPD); diff --git a/test/items/temp-stat-stage-booster.test.ts b/test/items/temp-stat-stage-booster.test.ts index f95fe553faf..05ea5a03eae 100644 --- a/test/items/temp-stat-stage-booster.test.ts +++ b/test/items/temp-stat-stage-booster.test.ts @@ -6,7 +6,6 @@ import { SpeciesId } from "#enums/species-id"; import { BATTLE_STATS, Stat } from "#enums/stat"; import { UiMode } from "#enums/ui-mode"; import { TempStatStageBoosterModifier } from "#modifiers/modifier"; -import { TurnEndPhase } from "#phases/turn-end-phase"; import { GameManager } from "#test/test-utils/game-manager"; import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler"; import Phaser from "phaser"; @@ -47,7 +46,7 @@ describe("Items - Temporary Stat Stage Boosters", () => { game.move.select(MoveId.TACKLE); - await game.phaseInterceptor.runFrom("EnemyCommandPhase").to(TurnEndPhase); + await game.toEndOfTurn(); expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(1.3); }); @@ -64,11 +63,11 @@ describe("Items - Temporary Stat Stage Boosters", () => { // Raise ACC by +2 stat stages game.move.select(MoveId.HONE_CLAWS); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); game.move.select(MoveId.TACKLE); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); // ACC at +3 stat stages yields a x2 multiplier expect(partyMember.getAccuracyMultiplier).toHaveReturnedWith(2); @@ -84,11 +83,11 @@ describe("Items - Temporary Stat Stage Boosters", () => { // Raise ATK by +1 stat stage game.move.select(MoveId.HONE_CLAWS); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); 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 expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(1.8); @@ -112,7 +111,7 @@ describe("Items - Temporary Stat Stage Boosters", () => { game.move.select(MoveId.TACKLE); - await game.phaseInterceptor.to(TurnEndPhase); + await game.phaseInterceptor.to("TurnEndPhase"); expect(partyMember.getAccuracyMultiplier).toHaveReturnedWith(3); expect(partyMember.getStatStageMultiplier).toHaveReturnedWith(4); diff --git a/test/items/thick-club.test.ts b/test/items/thick-club.test.ts index c497cef6338..d14b4f955e7 100644 --- a/test/items/thick-club.test.ts +++ b/test/items/thick-club.test.ts @@ -33,7 +33,7 @@ describe("Items - Thick Club", () => { const consoleSpy = vi.spyOn(console, "log"); await game.classicMode.startBattle([SpeciesId.CUBONE]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); // Checking console log to make sure Thick Club is applied when getEffectiveStat (with the appropriate stat) is called partyMember.getEffectiveStat(Stat.DEF); @@ -84,7 +84,7 @@ describe("Items - Thick Club", () => { it("THICK_CLUB held by CUBONE", async () => { await game.classicMode.startBattle([SpeciesId.CUBONE]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const atkStat = partyMember.getStat(Stat.ATK); @@ -107,7 +107,7 @@ describe("Items - Thick Club", () => { it("THICK_CLUB held by MAROWAK", async () => { await game.classicMode.startBattle([SpeciesId.MAROWAK]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const atkStat = partyMember.getStat(Stat.ATK); @@ -130,7 +130,7 @@ describe("Items - Thick Club", () => { it("THICK_CLUB held by ALOLA_MAROWAK", async () => { await game.classicMode.startBattle([SpeciesId.ALOLA_MAROWAK]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const atkStat = partyMember.getStat(Stat.ATK); @@ -157,8 +157,7 @@ describe("Items - Thick Club", () => { await game.classicMode.startBattle([species[randSpecies], SpeciesId.PIKACHU]); - const partyMember = game.scene.getPlayerParty()[0]; - const ally = game.scene.getPlayerParty()[1]; + const [partyMember, ally] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) partyMember.fusionSpecies = ally.species; @@ -194,8 +193,7 @@ describe("Items - Thick Club", () => { await game.classicMode.startBattle([SpeciesId.PIKACHU, species[randSpecies]]); - const partyMember = game.scene.getPlayerParty()[0]; - const ally = game.scene.getPlayerParty()[1]; + const [partyMember, ally] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) partyMember.fusionSpecies = ally.species; @@ -227,7 +225,7 @@ describe("Items - Thick Club", () => { it("THICK_CLUB not held by CUBONE", async () => { await game.classicMode.startBattle([SpeciesId.PIKACHU]); - const partyMember = game.scene.getPlayerParty()[0]; + const partyMember = game.field.getPlayerPokemon(); const atkStat = partyMember.getStat(Stat.ATK); diff --git a/test/moves/dragon-rage.test.ts b/test/moves/dragon-rage.test.ts index c90e2b78abd..dffdbf9badc 100644 --- a/test/moves/dragon-rage.test.ts +++ b/test/moves/dragon-rage.test.ts @@ -46,7 +46,7 @@ describe("Moves - Dragon Rage", () => { await game.classicMode.startBattle(); - partyPokemon = game.scene.getPlayerParty()[0]; + partyPokemon = game.field.getPlayerPokemon(); enemyPokemon = game.field.getEnemyPokemon(); }); diff --git a/test/moves/dragon-tail.test.ts b/test/moves/dragon-tail.test.ts index 1cea6f908a0..e3a5bf459e8 100644 --- a/test/moves/dragon-tail.test.ts +++ b/test/moves/dragon-tail.test.ts @@ -76,10 +76,9 @@ describe("Moves - Dragon Tail", () => { game.override.battleStyle("double").enemyMoveset(MoveId.SPLASH).enemyAbility(AbilityId.ROUGH_SKIN); await game.classicMode.startBattle([SpeciesId.DRATINI, SpeciesId.DRATINI, SpeciesId.WAILORD, SpeciesId.WAILORD]); - const leadPokemon = game.scene.getPlayerParty()[0]!; + const leadPokemon = game.field.getPlayerPokemon(); - const enemyLeadPokemon = game.scene.getEnemyParty()[0]!; - const enemySecPokemon = game.scene.getEnemyParty()[1]!; + const [enemyLeadPokemon, enemySecPokemon] = game.scene.getEnemyParty(); game.move.select(MoveId.DRAGON_TAIL, 0, BattlerIndex.ENEMY); game.move.select(MoveId.SPLASH, 1); @@ -105,11 +104,9 @@ describe("Moves - Dragon Tail", () => { game.override.battleStyle("double").enemyMoveset(MoveId.SPLASH).enemyAbility(AbilityId.ROUGH_SKIN); await game.classicMode.startBattle([SpeciesId.DRATINI, SpeciesId.DRATINI, SpeciesId.WAILORD, SpeciesId.WAILORD]); - const leadPokemon = game.scene.getPlayerParty()[0]!; - const secPokemon = game.scene.getPlayerParty()[1]!; + const [leadPokemon, secPokemon] = game.scene.getPlayerParty(); - const enemyLeadPokemon = game.scene.getEnemyParty()[0]!; - const enemySecPokemon = game.scene.getEnemyParty()[1]!; + const [enemyLeadPokemon, enemySecPokemon] = game.scene.getEnemyParty(); game.move.select(MoveId.DRAGON_TAIL, 0, BattlerIndex.ENEMY); // target the same pokemon, second move should be redirected after first flees diff --git a/test/moves/fissure.test.ts b/test/moves/fissure.test.ts index b22b81906a6..b5255d75d73 100644 --- a/test/moves/fissure.test.ts +++ b/test/moves/fissure.test.ts @@ -42,7 +42,7 @@ describe("Moves - Fissure", () => { await game.classicMode.startBattle(); - partyPokemon = game.scene.getPlayerParty()[0]; + partyPokemon = game.field.getPlayerPokemon(); enemyPokemon = game.field.getEnemyPokemon(); }); diff --git a/test/moves/fusion-flare-bolt.test.ts b/test/moves/fusion-flare-bolt.test.ts index 42cc1248325..f5d556bde48 100644 --- a/test/moves/fusion-flare-bolt.test.ts +++ b/test/moves/fusion-flare-bolt.test.ts @@ -4,10 +4,7 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import type { Move } from "#moves/move"; -import { DamageAnimPhase } from "#phases/damage-anim-phase"; -import { MoveEffectPhase } from "#phases/move-effect-phase"; -import { MoveEndPhase } from "#phases/move-end-phase"; -import { MovePhase } from "#phases/move-phase"; +import type { MoveEffectPhase } from "#phases/move-effect-phase"; import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; 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 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); }); @@ -75,14 +72,14 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { // Force user party to act before enemy party 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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 - 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); }); @@ -121,18 +118,18 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { // Force first enemy to act in between party 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100); - await game.phaseInterceptor.to(MoveEndPhase); + await game.phaseInterceptor.to("MoveEndPhase"); // 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); }); @@ -145,14 +142,14 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { // Force user party to act before enemy party 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); }); @@ -189,24 +186,24 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { // Force first enemy to act in between party 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); }); @@ -243,24 +240,24 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => { // Force first enemy to act in between party 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); 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); - await game.phaseInterceptor.to(DamageAnimPhase, false); + await game.phaseInterceptor.to("DamageAnimPhase", false); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); }); }); diff --git a/test/moves/growth.test.ts b/test/moves/growth.test.ts index 4c892f0dee2..3d3b407f28b 100644 --- a/test/moves/growth.test.ts +++ b/test/moves/growth.test.ts @@ -2,8 +2,6 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; 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 Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -40,7 +38,7 @@ describe("Moves - Growth", () => { expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0); game.move.select(MoveId.GROWTH); - await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnInitPhase); + await game.toEndOfTurn(); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(1); }); diff --git a/test/moves/parting-shot.test.ts b/test/moves/parting-shot.test.ts index 660edc4565a..e9400aef29b 100644 --- a/test/moves/parting-shot.test.ts +++ b/test/moves/parting-shot.test.ts @@ -2,10 +2,6 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; 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 Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, test } from "vitest"; @@ -43,7 +39,7 @@ describe("Moves - 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.SPATK)).toBe(0); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); @@ -58,7 +54,7 @@ describe("Moves - 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.SPATK)).toBe(0); 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 game.move.select(MoveId.MEMENTO); - await game.phaseInterceptor.to(FaintPhase); - expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true); + await game.phaseInterceptor.to("FaintPhase"); + expect(game.field.getPlayerPokemon().isFainted()).toBe(true); game.doSelectPartyPokemon(1); - await game.phaseInterceptor.to(TurnInitPhase, false); + await game.phaseInterceptor.to("TurnInitPhase", false); game.move.select(MoveId.MEMENTO); - await game.phaseInterceptor.to(FaintPhase); - expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true); + await game.phaseInterceptor.to("FaintPhase"); + expect(game.field.getPlayerPokemon().isFainted()).toBe(true); game.doSelectPartyPokemon(2); - await game.phaseInterceptor.to(TurnInitPhase, false); + await game.phaseInterceptor.to("TurnInitPhase", false); game.move.select(MoveId.MEMENTO); - await game.phaseInterceptor.to(FaintPhase); - expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true); + await game.phaseInterceptor.to("FaintPhase"); + expect(game.field.getPlayerPokemon().isFainted()).toBe(true); game.doSelectPartyPokemon(3); // set up done - await game.phaseInterceptor.to(TurnInitPhase, false); + await game.phaseInterceptor.to("TurnInitPhase", false); const enemyPokemon = game.field.getEnemyPokemon(); expect(enemyPokemon).toBeDefined(); @@ -106,7 +102,7 @@ describe("Moves - Parting Shot", () => { // now parting shot should fail 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.SPATK)).toBe(-6); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); @@ -125,7 +121,7 @@ describe("Moves - 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.SPATK)).toBe(0); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); @@ -144,7 +140,7 @@ describe("Moves - 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.SPATK)).toBe(0); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(SpeciesId.MURKROW); @@ -153,43 +149,24 @@ describe("Moves - Parting Shot", () => { it.todo( // 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", - 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", + "should lower stats without failing if no alive party members available to switch", async () => { await game.classicMode.startBattle([SpeciesId.MURKROW, SpeciesId.MEOWTH]); + + const meowth = game.scene.getPlayerParty()[1]; + meowth.hp = 0; + 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.doSelectPartyPokemon(1); + await game.toEndOfTurn(); - await game.phaseInterceptor.to(BerryPhase, false); const enemyPokemon = game.field.getEnemyPokemon(); expect(enemyPokemon.getStatStage(Stat.ATK)).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); }, ); }); diff --git a/test/moves/revival-blessing.test.ts b/test/moves/revival-blessing.test.ts index d14fa89c738..4dc7cb97f2d 100644 --- a/test/moves/revival-blessing.test.ts +++ b/test/moves/revival-blessing.test.ts @@ -133,6 +133,6 @@ describe("Moves - Revival Blessing", () => { await game.toNextTurn(); // If there are incorrectly two switch phases into this slot, the fainted pokemon will end up in slot 3 // Make sure it's still in slot 1 - expect(game.scene.getEnemyParty()[0]).toBe(enemyFainting); + expect(game.field.getEnemyPokemon()).toBe(enemyFainting); }); }); diff --git a/test/moves/rollout.test.ts b/test/moves/rollout.test.ts index c1c66f4ab39..0e01725a188 100644 --- a/test/moves/rollout.test.ts +++ b/test/moves/rollout.test.ts @@ -44,10 +44,10 @@ describe("Moves - Rollout", () => { await game.classicMode.startBattle(); - const playerPkm = game.scene.getPlayerParty()[0]; + const playerPkm = game.field.getPlayerPokemon(); vi.spyOn(playerPkm, "stats", "get").mockReturnValue([500000, 1, 1, 1, 1, 1]); // HP, ATK, DEF, SPATK, SPDEF, SPD - const enemyPkm = game.scene.getEnemyParty()[0]; + const enemyPkm = game.field.getEnemyPokemon(); vi.spyOn(enemyPkm, "stats", "get").mockReturnValue([500000, 1, 1, 1, 1, 1]); // HP, ATK, DEF, SPATK, SPDEF, SPD vi.spyOn(enemyPkm, "getHeldItems").mockReturnValue([]); //no berries diff --git a/test/moves/sketch.test.ts b/test/moves/sketch.test.ts index ed010b8a883..0c2527bc09c 100644 --- a/test/moves/sketch.test.ts +++ b/test/moves/sketch.test.ts @@ -6,7 +6,6 @@ import { MoveResult } from "#enums/move-result"; import { SpeciesId } from "#enums/species-id"; import { StatusEffect } from "#enums/status-effect"; import { RandomMoveAttr } from "#moves/move"; -import { PokemonMove } from "#moves/pokemon-move"; import { GameManager } from "#test/test-utils/game-manager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; @@ -40,7 +39,7 @@ describe("Moves - Sketch", () => { await game.classicMode.startBattle([SpeciesId.REGIELEKI]); const playerPokemon = game.field.getPlayerPokemon(); // can't use normal moveset override because we need to check moveset changes - playerPokemon.moveset = [new PokemonMove(MoveId.SKETCH), new PokemonMove(MoveId.SKETCH)]; + game.move.changeMoveset(playerPokemon, [MoveId.SKETCH, MoveId.SKETCH]); game.move.select(MoveId.SKETCH); await game.phaseInterceptor.to("TurnEndPhase"); @@ -62,7 +61,7 @@ describe("Moves - Sketch", () => { await game.classicMode.startBattle([SpeciesId.REGIELEKI]); const playerPokemon = game.field.getPlayerPokemon(); const enemyPokemon = game.field.getEnemyPokemon(); - playerPokemon.moveset = [new PokemonMove(MoveId.SKETCH), new PokemonMove(MoveId.GROWL)]; + game.move.changeMoveset(playerPokemon, [MoveId.SKETCH, MoveId.GROWL]); game.move.select(MoveId.GROWL); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); @@ -88,8 +87,9 @@ describe("Moves - Sketch", () => { game.override.enemyMoveset([MoveId.METRONOME]); await game.classicMode.startBattle([SpeciesId.REGIELEKI]); + const playerPokemon = game.field.getPlayerPokemon(); - playerPokemon.moveset = [new PokemonMove(MoveId.SKETCH)]; + game.move.changeMoveset(playerPokemon, MoveId.SKETCH); // Opponent uses Metronome -> False Swipe, then player uses Sketch, which should sketch Metronome game.move.select(MoveId.SKETCH); diff --git a/test/moves/spikes.test.ts b/test/moves/spikes.test.ts index 0055945cef9..38b323a00a4 100644 --- a/test/moves/spikes.test.ts +++ b/test/moves/spikes.test.ts @@ -48,7 +48,7 @@ describe("Moves - Spikes", () => { game.doSwitchPokemon(1); await game.toNextTurn(); - const player = game.scene.getPlayerParty()[0]; + const player = game.field.getPlayerPokemon(); expect(player.hp).toBe(player.getMaxHp()); }); @@ -62,7 +62,7 @@ describe("Moves - Spikes", () => { game.move.select(MoveId.ROAR); await game.toNextTurn(); - const enemy = game.scene.getEnemyParty()[0]; + const enemy = game.field.getEnemyPokemon(); expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); }); @@ -77,7 +77,7 @@ describe("Moves - Spikes", () => { game.forceEnemyToSwitch(); await game.toNextTurn(); - const enemy = game.scene.getEnemyParty()[0]; + const enemy = game.field.getEnemyPokemon(); expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); }); diff --git a/test/moves/tackle.test.ts b/test/moves/tackle.test.ts index 23abd650e55..5418b16bba8 100644 --- a/test/moves/tackle.test.ts +++ b/test/moves/tackle.test.ts @@ -1,8 +1,6 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; 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 Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -41,7 +39,7 @@ describe("Moves - Tackle", () => { await game.classicMode.startBattle([SpeciesId.MIGHTYENA]); const hpOpponent = game.scene.currentBattle.enemyParty[0].hp; game.move.select(moveToUse); - await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnEndPhase); + await game.toEndOfTurn(); const hpLost = hpOpponent - game.scene.currentBattle.enemyParty[0].hp; expect(hpLost).toBe(0); }); @@ -50,12 +48,12 @@ describe("Moves - Tackle", () => { const moveToUse = MoveId.TACKLE; await game.classicMode.startBattle([SpeciesId.MIGHTYENA]); game.scene.currentBattle.enemyParty[0].stats[Stat.DEF] = 50; - game.scene.getPlayerParty()[0].stats[Stat.ATK] = 50; + game.field.getPlayerPokemon().stats[Stat.ATK] = 50; const hpOpponent = game.scene.currentBattle.enemyParty[0].hp; game.move.select(moveToUse); - await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnEndPhase); + await game.toEndOfTurn(); const hpLost = hpOpponent - game.scene.currentBattle.enemyParty[0].hp; expect(hpLost).toBeGreaterThan(0); expect(hpLost).toBeLessThan(4); diff --git a/test/moves/tail-whip.test.ts b/test/moves/tail-whip.test.ts index 8d2dfbda096..70476179b03 100644 --- a/test/moves/tail-whip.test.ts +++ b/test/moves/tail-whip.test.ts @@ -2,8 +2,6 @@ import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; 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 Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -43,7 +41,7 @@ describe("Moves - Tail whip", () => { expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(0); game.move.select(moveToUse); - await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnInitPhase); + await game.toEndOfTurn(); expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(-1); }); diff --git a/test/moves/tera-starstorm.test.ts b/test/moves/tera-starstorm.test.ts index 869cf597dde..178827c6b0a 100644 --- a/test/moves/tera-starstorm.test.ts +++ b/test/moves/tera-starstorm.test.ts @@ -72,7 +72,7 @@ describe("Moves - Tera Starstorm", () => { it("targets both opponents in a double battle when used by Terapagos immediately after terastallizing", async () => { await game.classicMode.startBattle([SpeciesId.TERAPAGOS]); - const terapagos = game.scene.getPlayerParty()[0]; + const terapagos = game.field.getPlayerPokemon(); terapagos.isTerastallized = false; game.move.selectWithTera(MoveId.TERA_STARSTORM, 0); @@ -89,7 +89,7 @@ describe("Moves - Tera Starstorm", () => { it("targets only one opponent in a double battle when used by Terapagos without terastallizing", async () => { await game.classicMode.startBattle([SpeciesId.TERAPAGOS]); - const terapagos = game.scene.getPlayerParty()[0]; + const terapagos = game.field.getPlayerPokemon(); terapagos.isTerastallized = false; game.move.select(MoveId.TERA_STARSTORM, 0, BattlerIndex.ENEMY); @@ -106,8 +106,7 @@ describe("Moves - Tera Starstorm", () => { it("applies the effects when Terapagos in Stellar Form is fused with another Pokemon", async () => { await game.classicMode.startBattle([SpeciesId.TERAPAGOS, SpeciesId.CHARMANDER, SpeciesId.MAGIKARP]); - const fusionedMon = game.scene.getPlayerParty()[0]; - const magikarp = game.scene.getPlayerParty()[2]; + const [fusionedMon, , magikarp] = game.scene.getPlayerParty(); // Fuse party members (taken from PlayerPokemon.fuse(...) function) fusionedMon.fusionSpecies = magikarp.species; diff --git a/test/mystery-encounter/encounter-test-utils.ts b/test/mystery-encounter/encounter-test-utils.ts index 784e8ae4950..7b2dbfc9aeb 100644 --- a/test/mystery-encounter/encounter-test-utils.ts +++ b/test/mystery-encounter/encounter-test-utils.ts @@ -9,7 +9,6 @@ import { MessagePhase } from "#phases/message-phase"; import { MysteryEncounterBattlePhase, MysteryEncounterOptionSelectedPhase, - MysteryEncounterPhase, MysteryEncounterRewardsPhase, } from "#phases/mystery-encounter-phases"; import { VictoryPhase } from "#phases/victory-phase"; @@ -89,9 +88,9 @@ export async function runMysteryEncounterToEnd( uiHandler.processInput(Button.ACTION); }); - await game.phaseInterceptor.to(CommandPhase); + await game.toNextTurn(); } else { - await game.phaseInterceptor.to(MysteryEncounterRewardsPhase); + await game.phaseInterceptor.to("MysteryEncounterRewardsPhase"); } } @@ -112,7 +111,7 @@ export async function runSelectMysteryEncounterOption( ); if (game.isCurrentPhase(MessagePhase)) { - await game.phaseInterceptor.run(MessagePhase); + await game.phaseInterceptor.to("MessagePhase"); } // dispose of intro messages @@ -126,7 +125,7 @@ export async function runSelectMysteryEncounterOption( () => game.isCurrentPhase(MysteryEncounterOptionSelectedPhase), ); - await game.phaseInterceptor.to(MysteryEncounterPhase, true); + await game.phaseInterceptor.to("MysteryEncounterPhase", true); // select the desired option const uiHandler = game.scene.ui.getHandler(); @@ -205,7 +204,7 @@ export async function skipBattleRunMysteryEncounterRewardsPhase(game: GameManage game.scene.field.remove(p); }); game.scene.phaseManager.pushPhase(new VictoryPhase(0)); - game.phaseInterceptor.superEndPhase(); + game.endPhase(); game.setMode(UiMode.MESSAGE); - await game.phaseInterceptor.to(MysteryEncounterRewardsPhase, runRewardsPhase); + await game.phaseInterceptor.to("MysteryEncounterRewardsPhase", runRewardsPhase); } diff --git a/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts b/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts index dfd102daa43..9cd1679c411 100644 --- a/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts +++ b/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts @@ -7,7 +7,6 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { ShinyRateBoosterModifier } from "#modifiers/modifier"; -import { PokemonMove } from "#moves/pokemon-move"; import { AnOfferYouCantRefuseEncounter } from "#mystery-encounters/an-offer-you-cant-refuse-encounter"; import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils"; import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; @@ -207,9 +206,8 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { it("should award EXP to a pokemon with a move in EXTORTION_MOVES", async () => { game.override.ability(AbilityId.SYNCHRONIZE); // Not an extortion ability, so we can test extortion move await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [SpeciesId.ABRA]); - const party = scene.getPlayerParty(); - const abra = party.find(pkm => pkm.species.speciesId === SpeciesId.ABRA)!; - abra.moveset = [new PokemonMove(MoveId.BEAT_UP)]; + const abra = game.field.getPlayerPokemon(); + game.move.changeMoveset(abra, MoveId.BEAT_UP); const expBefore = abra.exp; await runMysteryEncounterToEnd(game, 2); diff --git a/test/mystery-encounter/encounters/berries-abound-encounter.test.ts b/test/mystery-encounter/encounters/berries-abound-encounter.test.ts index ecd08b5e57b..12c5a6515bc 100644 --- a/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -134,7 +134,7 @@ describe("Berries Abound - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 1, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); 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 runMysteryEncounterToEnd(game, 1, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); - 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -232,9 +230,9 @@ describe("Berries Abound - Mystery Encounter", () => { }); 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); - await game.phaseInterceptor.run(SelectModifierPhase); + await game.phaseInterceptor.to("SelectModifierPhase"); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts b/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts index f0fe8be6a01..13d3c030c63 100644 --- a/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts +++ b/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts @@ -368,9 +368,9 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterRewardsPhase.name); game.phaseInterceptor["prompts"] = []; // Clear out prompt handlers 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); 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 () => { 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(); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); @@ -417,7 +417,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 2); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -436,7 +436,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 2); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -458,7 +458,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 2); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -482,7 +482,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 2); 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); 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 () => { game.scene.modifiers = []; await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); - await game.phaseInterceptor.to(MysteryEncounterPhase, false); + await game.phaseInterceptor.to("MysteryEncounterPhase", false); game.scene.modifiers = []; const encounterPhase = scene.phaseManager.getCurrentPhase(); @@ -558,7 +558,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); 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); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/clowning-around-encounter.test.ts b/test/mystery-encounter/encounters/clowning-around-encounter.test.ts index b0dacd0df08..f02a5c623af 100644 --- a/test/mystery-encounter/encounters/clowning-around-encounter.test.ts +++ b/test/mystery-encounter/encounters/clowning-around-encounter.test.ts @@ -25,7 +25,6 @@ import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; import { CommandPhase } from "#phases/command-phase"; import { MovePhase } from "#phases/move-phase"; import { PostMysteryEncounterPhase } from "#phases/mystery-encounter-phases"; -import { NewBattlePhase } from "#phases/new-battle-phase"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { runMysteryEncounterToEnd, @@ -200,9 +199,9 @@ describe("Clowning Around - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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; game.onNextPrompt("PostMysteryEncounterPhase", UiMode.MESSAGE, () => { @@ -215,7 +214,7 @@ describe("Clowning Around - Mystery Encounter", () => { const partyUiHandler = game.scene.ui.handlers[UiMode.PARTY] as PartyUiHandler; vi.spyOn(partyUiHandler, "show"); game.endPhase(); - await game.phaseInterceptor.to(PostMysteryEncounterPhase); + await game.phaseInterceptor.to("PostMysteryEncounterPhase"); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(PostMysteryEncounterPhase.name); // Wait for Yes/No confirmation to appear @@ -228,9 +227,9 @@ describe("Clowning Around - Mystery Encounter", () => { // Click "Select" on Pokemon partyUiHandler.processInput(Button.ACTION); // 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 = game.field.getPlayerPokemon(); expect(leadPokemon.customPokemonData?.ability).toBe(abilityToTrain); }); }); @@ -263,30 +262,30 @@ describe("Clowning Around - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty); // Set some moves on party for attack type booster generation - scene.getPlayerParty()[0].moveset = [new PokemonMove(MoveId.TACKLE), new PokemonMove(MoveId.THIEF)]; + game.move.changeMoveset(game.field.getPlayerPokemon(), [MoveId.TACKLE, MoveId.THIEF]); // 2 Sitrus Berries on lead scene.modifiers = []; let itemType = generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType; - await addItemToPokemon(scene, scene.getPlayerParty()[0], 2, itemType); + await addItemToPokemon(scene, game.field.getPlayerPokemon(), 2, itemType); // 2 Ganlon Berries on lead itemType = generateModifierType(modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType; - await addItemToPokemon(scene, scene.getPlayerParty()[0], 2, itemType); + await addItemToPokemon(scene, game.field.getPlayerPokemon(), 2, itemType); // 5 Golden Punch on lead (ultra) itemType = generateModifierType(modifierTypes.GOLDEN_PUNCH) as PokemonHeldItemModifierType; - await addItemToPokemon(scene, scene.getPlayerParty()[0], 5, itemType); + await addItemToPokemon(scene, game.field.getPlayerPokemon(), 5, itemType); // 5 Lucky Egg on lead (ultra) itemType = generateModifierType(modifierTypes.LUCKY_EGG) as PokemonHeldItemModifierType; - await addItemToPokemon(scene, scene.getPlayerParty()[0], 5, itemType); + await addItemToPokemon(scene, game.field.getPlayerPokemon(), 5, itemType); // 3 Soothe Bell on lead (great tier, but counted as ultra by this ME) itemType = generateModifierType(modifierTypes.SOOTHE_BELL) as PokemonHeldItemModifierType; - await addItemToPokemon(scene, scene.getPlayerParty()[0], 3, itemType); + await addItemToPokemon(scene, game.field.getPlayerPokemon(), 3, itemType); // 5 Soul Dew on lead (rogue) itemType = generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType; - await addItemToPokemon(scene, scene.getPlayerParty()[0], 5, itemType); + await addItemToPokemon(scene, game.field.getPlayerPokemon(), 5, itemType); // 2 Golden Egg on lead (rogue) itemType = generateModifierType(modifierTypes.GOLDEN_EGG) as PokemonHeldItemModifierType; - await addItemToPokemon(scene, scene.getPlayerParty()[0], 2, itemType); + await addItemToPokemon(scene, game.field.getPlayerPokemon(), 2, itemType); // 5 Soul Dew on second party pokemon (these should not change) itemType = generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType; @@ -294,7 +293,7 @@ describe("Clowning Around - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 2); - const leadItemsAfter = scene.getPlayerParty()[0].getHeldItems(); + const leadItemsAfter = game.field.getPlayerPokemon().getHeldItems(); const ultraCountAfter = leadItemsAfter .filter(m => m.type.tier === ModifierTier.ULTRA) .reduce((a, b) => a + b.stackCount, 0); @@ -348,14 +347,14 @@ describe("Clowning Around - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty); // Same type moves on lead - scene.getPlayerParty()[0].moveset = [new PokemonMove(MoveId.ICE_BEAM), new PokemonMove(MoveId.SURF)]; + game.move.changeMoveset(game.field.getPlayerPokemon(), [MoveId.ICE_BEAM, MoveId.SURF]); // Different type moves on second - scene.getPlayerParty()[1].moveset = [new PokemonMove(MoveId.GRASS_KNOT), new PokemonMove(MoveId.ELECTRO_BALL)]; + game.move.changeMoveset(scene.getPlayerParty()[1], [MoveId.GRASS_KNOT, MoveId.ELECTRO_BALL]); // No moves on third scene.getPlayerParty()[2].moveset = []; await runMysteryEncounterToEnd(game, 3); - const leadTypesAfter = scene.getPlayerParty()[0].getTypes(); + const leadTypesAfter = game.field.getPlayerPokemon().getTypes(); const secondaryTypesAfter = scene.getPlayerParty()[1].getTypes(); const thirdTypesAfter = scene.getPlayerParty()[2].getTypes(); diff --git a/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts b/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts index 95817abc1d8..de47b074089 100644 --- a/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts +++ b/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts @@ -6,7 +6,6 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; -import { PokemonMove } from "#moves/pokemon-move"; import { DancingLessonsEncounter } from "#mystery-encounters/dancing-lessons-encounter"; import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils"; import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; @@ -100,7 +99,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); // Make party lead's level arbitrarily high to not get KOed by move - const partyLead = scene.getPlayerParty()[0]; + const partyLead = game.field.getPlayerPokemon(); partyLead.level = 1000; partyLead.calculateStats(); await runMysteryEncounterToEnd(game, 1, undefined, true); @@ -121,14 +120,14 @@ describe("Dancing Lessons - Mystery Encounter", () => { it("should have a Baton in the rewards after battle", async () => { await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); // Make party lead's level arbitrarily high to not get KOed by move - const partyLead = scene.getPlayerParty()[0]; + const partyLead = game.field.getPlayerPokemon(); partyLead.level = 1000; partyLead.calculateStats(); await runMysteryEncounterToEnd(game, 1, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -159,7 +158,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { const phaseSpy = vi.spyOn(scene.phaseManager, "unshiftPhase"); await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); - scene.getPlayerParty()[0].moveset = []; + game.field.getPlayerPokemon().moveset = []; await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1 }); const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof LearnMovePhase).map(p => p[0]); @@ -171,7 +170,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); - scene.getPlayerParty()[0].moveset = []; + game.field.getPlayerPokemon().moveset = []; await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1 }); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); @@ -199,7 +198,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { it("should add Oricorio to the party", async () => { await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); const partyCountBefore = scene.getPlayerParty().length; - scene.getPlayerParty()[0].moveset = [new PokemonMove(MoveId.DRAGON_DANCE)]; + game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.DRAGON_DANCE); await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); const partyCountAfter = scene.getPlayerParty().length; @@ -215,7 +214,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); const partyCountBefore = scene.getPlayerParty().length; scene.getPlayerParty().forEach(p => (p.moveset = [])); - await game.phaseInterceptor.to(MysteryEncounterPhase, false); + await game.phaseInterceptor.to("MysteryEncounterPhase", false); const encounterPhase = scene.phaseManager.getCurrentPhase(); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); @@ -238,7 +237,7 @@ describe("Dancing Lessons - Mystery Encounter", () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty); - scene.getPlayerParty()[0].moveset = [new PokemonMove(MoveId.DRAGON_DANCE)]; + game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.DRAGON_DANCE); await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); diff --git a/test/mystery-encounter/encounters/delibirdy-encounter.test.ts b/test/mystery-encounter/encounters/delibirdy-encounter.test.ts index aac7a5f75f5..7398b639f1c 100644 --- a/test/mystery-encounter/encounters/delibirdy-encounter.test.ts +++ b/test/mystery-encounter/encounters/delibirdy-encounter.test.ts @@ -201,7 +201,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 2 Sitrus berries on party lead scene.modifiers = []; const sitrus = generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS])!; - const sitrusMod = sitrus.newModifier(scene.getPlayerParty()[0]) as BerryModifier; + const sitrusMod = sitrus.newModifier(game.field.getPlayerPokemon()) as BerryModifier; sitrusMod.stackCount = 2; scene.addModifier(sitrusMod, true, false, false, true); await scene.updateModifiers(true); @@ -222,7 +222,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 1 Reviver Seed on party lead scene.modifiers = []; const revSeed = generateModifierType(modifierTypes.REVIVER_SEED)!; - const modifier = revSeed.newModifier(scene.getPlayerParty()[0]) as PokemonInstantReviveModifier; + const modifier = revSeed.newModifier(game.field.getPlayerPokemon()) as PokemonInstantReviveModifier; modifier.stackCount = 1; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); @@ -248,7 +248,7 @@ describe("Delibird-y - Mystery Encounter", () => { const sitrus = generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS])!; // Sitrus berries on party - const sitrusMod = sitrus.newModifier(scene.getPlayerParty()[0]) as BerryModifier; + const sitrusMod = sitrus.newModifier(game.field.getPlayerPokemon()) as BerryModifier; sitrusMod.stackCount = 2; scene.addModifier(sitrusMod, true, false, false, true); await scene.updateModifiers(true); @@ -277,7 +277,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 1 Reviver Seed on party lead const revSeed = generateModifierType(modifierTypes.REVIVER_SEED)!; - const modifier = revSeed.newModifier(scene.getPlayerParty()[0]) as PokemonInstantReviveModifier; + const modifier = revSeed.newModifier(game.field.getPlayerPokemon()) as PokemonInstantReviveModifier; modifier.stackCount = 1; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); @@ -301,7 +301,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 1 Soul Dew on party lead scene.modifiers = []; const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!; - const modifier = soulDew.newModifier(scene.getPlayerParty()[0]); + const modifier = soulDew.newModifier(game.field.getPlayerPokemon()); scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); @@ -329,7 +329,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 1 Reviver Seed on party lead const revSeed = generateModifierType(modifierTypes.REVIVER_SEED)!; - const modifier = revSeed.newModifier(scene.getPlayerParty()[0]) as PokemonInstantReviveModifier; + const modifier = revSeed.newModifier(game.field.getPlayerPokemon()) as PokemonInstantReviveModifier; modifier.stackCount = 1; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); @@ -363,7 +363,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 2 Soul Dew on party lead scene.modifiers = []; const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!; - const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier; + const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier; modifier.stackCount = 2; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); @@ -384,7 +384,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 1 Soul Dew on party lead scene.modifiers = []; const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!; - const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier; + const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier; modifier.stackCount = 1; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); @@ -410,7 +410,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 1 Soul Dew on party lead const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!; - const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier; + const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier; modifier.stackCount = 1; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); @@ -434,7 +434,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 1 Reviver Seed on party lead scene.modifiers = []; const revSeed = generateModifierType(modifierTypes.REVIVER_SEED)!; - const modifier = revSeed.newModifier(scene.getPlayerParty()[0]); + const modifier = revSeed.newModifier(game.field.getPlayerPokemon()); scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); @@ -463,7 +463,7 @@ describe("Delibird-y - Mystery Encounter", () => { // Set 1 Soul Dew on party lead scene.modifiers = []; const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!; - const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier; + const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier; modifier.stackCount = 1; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); diff --git a/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts b/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts index f8ff6beaf30..3c19d458049 100644 --- a/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts +++ b/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts @@ -94,7 +94,7 @@ describe("Department Store Sale - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty); await runMysteryEncounterToEnd(game, 1); 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); 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 runMysteryEncounterToEnd(game, 2); 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); 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 runMysteryEncounterToEnd(game, 3); 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); 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 runMysteryEncounterToEnd(game, 4); 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); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts b/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts index e8cfd1ab79e..8650b42ce4d 100644 --- a/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts +++ b/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts @@ -6,7 +6,6 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; -import { PokemonMove } from "#moves/pokemon-move"; import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils"; import { FightOrFlightEncounter } from "#mystery-encounters/fight-or-flight-encounter"; import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; @@ -122,9 +121,9 @@ describe("Fight or Flight - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 1, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -155,7 +154,7 @@ describe("Fight or Flight - Mystery Encounter", () => { it("should NOT be selectable if the player doesn't have a Stealing move", async () => { await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty); scene.getPlayerParty().forEach(p => (p.moveset = [])); - await game.phaseInterceptor.to(MysteryEncounterPhase, false); + await game.phaseInterceptor.to("MysteryEncounterPhase", false); const encounterPhase = scene.phaseManager.getCurrentPhase(); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); @@ -178,13 +177,13 @@ describe("Fight or Flight - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty); // Mock moveset - scene.getPlayerParty()[0].moveset = [new PokemonMove(MoveId.KNOCK_OFF)]; + game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.KNOCK_OFF); const item = game.scene.currentBattle.mysteryEncounter!.misc; 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); - await game.phaseInterceptor.run(SelectModifierPhase); + await game.phaseInterceptor.to("SelectModifierPhase"); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts b/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts index 4b39aee2522..7bfaaac1141 100644 --- a/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts +++ b/test/mystery-encounter/encounters/fun-and-games-encounter.test.ts @@ -120,7 +120,7 @@ describe("Fun And Games! - Mystery Encounter", () => { it("should NOT be selectable if the player doesn't have enough money", async () => { game.scene.money = 0; 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(); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); @@ -162,7 +162,7 @@ describe("Fun And Games! - Mystery Encounter", () => { // Turn 3 (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 expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); @@ -181,11 +181,11 @@ describe("Fun And Games! - Mystery Encounter", () => { // Skip minigame scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0; (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 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -210,11 +210,11 @@ describe("Fun And Games! - Mystery Encounter", () => { wobbuffet.hp = Math.floor(0.2 * wobbuffet.getMaxHp()); scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0; (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 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -240,11 +240,11 @@ describe("Fun And Games! - Mystery Encounter", () => { wobbuffet.hp = Math.floor(0.1 * wobbuffet.getMaxHp()); scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0; (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 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -270,11 +270,11 @@ describe("Fun And Games! - Mystery Encounter", () => { wobbuffet.hp = 1; scene.currentBattle.mysteryEncounter!.misc.turnsRemaining = 0; (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 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); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts b/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts index 410b99c7ebc..bb56505ac48 100644 --- a/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts +++ b/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts @@ -105,14 +105,14 @@ describe("Global Trade System - Mystery Encounter", () => { it("Should trade a Pokemon from the player's party for the first of 3 Pokemon options", async () => { await game.runToMysteryEncounter(MysteryEncounterType.GLOBAL_TRADE_SYSTEM, defaultParty); - const speciesBefore = scene.getPlayerParty()[0].species.speciesId; + const speciesBefore = game.field.getPlayerPokemon().species.speciesId; await runMysteryEncounterToEnd(game, 1, { pokemonNo: 1, optionNo: 1 }); const speciesAfter = scene.getPlayerParty().at(-1)?.species.speciesId; expect(speciesAfter).toBeDefined(); expect(speciesBefore).not.toBe(speciesAfter); - expect(defaultParty.includes(speciesAfter!)).toBeFalsy(); + expect(defaultParty).not.toContain(speciesAfter); }); it("Should trade a Pokemon from the player's party for the second of 3 Pokemon options", async () => { @@ -220,14 +220,14 @@ describe("Global Trade System - Mystery Encounter", () => { // Set 2 Soul Dew on party lead scene.modifiers = []; const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!; - const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier; + const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier; modifier.stackCount = 2; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -247,7 +247,7 @@ describe("Global Trade System - Mystery Encounter", () => { // Set 1 Soul Dew on party lead scene.modifiers = []; const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!; - const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier; + const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier; modifier.stackCount = 1; scene.addModifier(modifier, true, false, false, true); await scene.updateModifiers(true); diff --git a/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts b/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts index 5412f269122..0c4e3044bbd 100644 --- a/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts +++ b/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts @@ -161,9 +161,9 @@ describe("Mysterious Challengers - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty); await runMysteryEncounterToEnd(game, 1, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -205,9 +205,9 @@ describe("Mysterious Challengers - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty); await runMysteryEncounterToEnd(game, 2, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -262,9 +262,9 @@ describe("Mysterious Challengers - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty); await runMysteryEncounterToEnd(game, 3, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/part-timer-encounter.test.ts b/test/mystery-encounter/encounters/part-timer-encounter.test.ts index ae07d4c2004..36a92b2b6bf 100644 --- a/test/mystery-encounter/encounters/part-timer-encounter.test.ts +++ b/test/mystery-encounter/encounters/part-timer-encounter.test.ts @@ -5,7 +5,6 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; -import { PokemonMove } from "#moves/pokemon-move"; import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils"; import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; import { CIVILIZATION_ENCOUNTER_BIOMES } from "#mystery-encounters/mystery-encounters"; @@ -110,7 +109,7 @@ describe("Part-Timer - Mystery Encounter", () => { expect(EncounterPhaseUtils.updatePlayerMoney).toHaveBeenCalledWith(scene.getWaveMoneyAmount(1), true, false); // Expect PP of mon's moves to have been reduced to 2 - const moves = scene.getPlayerParty()[0].moveset; + const moves = game.field.getPlayerPokemon().moveset; for (const move of moves) { expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2); } @@ -233,7 +232,9 @@ describe("Part-Timer - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.PART_TIMER, defaultParty); // Mock movesets - scene.getPlayerParty().forEach(p => (p.moveset = [])); + scene.getPlayerParty().forEach(p => { + p.moveset = []; + }); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.phaseManager.getCurrentPhase(); @@ -257,14 +258,14 @@ describe("Part-Timer - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.PART_TIMER, defaultParty); // Mock moveset - scene.getPlayerParty()[0].moveset = [new PokemonMove(MoveId.ATTRACT)]; + game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.ATTRACT); await runMysteryEncounterToEnd(game, 3); expect(EncounterPhaseUtils.updatePlayerMoney).toHaveBeenCalledWith(scene.getWaveMoneyAmount(2.5), true, false); // Expect PP of mon's moves to have been reduced to 2 - const moves = scene.getPlayerParty()[0].moveset; + const moves = game.field.getPlayerPokemon().moveset; for (const move of moves) { - expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2); + expect(move.getMovePp() - move.ppUsed).toBe(2); } }); diff --git a/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts b/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts index 5d53e57d2eb..4d006abc636 100644 --- a/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts +++ b/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts @@ -146,7 +146,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { it("should NOT be selectable if the player doesn't have enough money", async () => { game.scene.money = 0; await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty); - await game.phaseInterceptor.to(MysteryEncounterPhase, false); + await game.phaseInterceptor.to("MysteryEncounterPhase", false); const encounterPhase = scene.phaseManager.getCurrentPhase(); 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 () => { 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(); expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); @@ -299,9 +299,9 @@ describe("Teleporting Hijinks - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty); await runMysteryEncounterToEnd(game, 3, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts b/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts index 31584048c78..ade98bfa99f 100644 --- a/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts @@ -13,7 +13,6 @@ import * as MysteryEncounters 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 { CommandPhase } from "#phases/command-phase"; -import { PostMysteryEncounterPhase } from "#phases/mystery-encounter-phases"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { runMysteryEncounterToEnd, @@ -70,7 +69,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { text: `${namespace}:intro`, }, { - speaker: "trainerNames:expert_pokemon_breeder", + speaker: "trainerNames:expertPokemonBreeder", text: `${namespace}:introDialogue`, }, ]); @@ -123,7 +122,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { buttonTooltip: expect.any(String), // Varies based on pokemon selected: [ { - speaker: "trainerNames:expert_pokemon_breeder", + speaker: "trainerNames:expertPokemonBreeder", text: `${namespace}:option.selected`, }, ], @@ -176,7 +175,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 1, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); 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.RARE).length).toBe(rareEggs); - game.phaseInterceptor.superEndPhase(); - await game.phaseInterceptor.to(PostMysteryEncounterPhase); + game.endPhase(); + await game.phaseInterceptor.to("PostMysteryEncounterPhase"); 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. @@ -208,7 +207,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { buttonTooltip: expect.any(String), // Varies based on pokemon selected: [ { - speaker: "trainerNames:expert_pokemon_breeder", + speaker: "trainerNames:expertPokemonBreeder", text: `${namespace}:option.selected`, }, ], @@ -261,7 +260,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 2, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); 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.RARE).length).toBe(rareEggs); - game.phaseInterceptor.superEndPhase(); - await game.phaseInterceptor.to(PostMysteryEncounterPhase); + game.endPhase(); + await game.phaseInterceptor.to("PostMysteryEncounterPhase"); 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 @@ -290,7 +289,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { buttonTooltip: expect.any(String), // Varies based on pokemon selected: [ { - speaker: "trainerNames:expert_pokemon_breeder", + speaker: "trainerNames:expertPokemonBreeder", text: `${namespace}:option.selected`, }, ], @@ -343,7 +342,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { await runMysteryEncounterToEnd(game, 3, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); expect(scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); 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.RARE).length).toBe(rareEggs); - game.phaseInterceptor.superEndPhase(); - await game.phaseInterceptor.to(PostMysteryEncounterPhase); + game.endPhase(); + await game.phaseInterceptor.to("PostMysteryEncounterPhase"); 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 diff --git a/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts b/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts index 7c60cbcb4a9..3880c07c312 100644 --- a/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts @@ -71,7 +71,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { ]); const { title, description, query } = dialogue.encounterOptionsDialogue!; expect(title).toBe(`${namespace}:title`); - expect(description).toMatch(new RegExp(`^${namespace}\\:description(_shiny)?$`)); + expect(description).toMatch(new RegExp(`^${namespace}\\:description(Shiny)?$`)); expect(query).toBe(`${namespace}:query`); expect(options.length).toBe(2); }); @@ -117,7 +117,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { expect(dialogue).toBeDefined(); expect(dialogue).toStrictEqual({ buttonLabel: `${namespace}:option.1.label`, - buttonTooltip: expect.stringMatching(new RegExp(`^${namespace}\\:option\\.1\\.tooltip(_shiny)?$`)), + buttonTooltip: expect.stringMatching(new RegExp(`^${namespace}\\:option\\.1\\.tooltip(Shiny)?$`)), selected: [ { text: `${namespace}:option.1.selectedMessage`, diff --git a/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts b/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts index a314a14485f..3592e2dc774 100644 --- a/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts @@ -229,9 +229,9 @@ describe("The Strong Stuff - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.THE_STRONG_STUFF, defaultParty); await runMysteryEncounterToEnd(game, 2, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts b/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts index 2da246bebb1..cf0ff7a94bd 100644 --- a/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts +++ b/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts @@ -16,7 +16,6 @@ import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; import { HUMAN_TRANSITABLE_BIOMES } from "#mystery-encounters/mystery-encounters"; import { TheWinstrateChallengeEncounter } from "#mystery-encounters/the-winstrate-challenge-encounter"; import { CommandPhase } from "#phases/command-phase"; -import { MysteryEncounterRewardsPhase } from "#phases/mystery-encounter-phases"; import { PartyHealPhase } from "#phases/party-heal-phase"; import { SelectModifierPhase } from "#phases/select-modifier-phase"; import { VictoryPhase } from "#phases/victory-phase"; @@ -295,9 +294,9 @@ describe("The Winstrate Challenge - Mystery Encounter", () => { // Should have Macho Brace in the rewards 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); - await game.phaseInterceptor.run(SelectModifierPhase); + await game.phaseInterceptor.to("SelectModifierPhase"); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); 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 runMysteryEncounterToEnd(game, 2); 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); const modifierSelectHandler = scene.ui.handlers.find( @@ -366,11 +365,10 @@ async function skipBattleToNextBattle(game: GameManager, isFinalBattle = false) p.status = new Status(StatusEffect.FAINT); game.scene.field.remove(p); }); - game.phaseInterceptor["onHold"] = []; game.scene.phaseManager.pushPhase(new VictoryPhase(0)); - game.phaseInterceptor.superEndPhase(); + game.endPhase(); if (isFinalBattle) { - await game.phaseInterceptor.to(MysteryEncounterRewardsPhase); + await game.phaseInterceptor.to("MysteryEncounterRewardsPhase"); } else { await game.toNextTurn(); } diff --git a/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts b/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts index 133fbfb10ba..b32dcddadb8 100644 --- a/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts +++ b/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts @@ -172,7 +172,7 @@ describe("Trash to Treasure - Mystery Encounter", () => { it("should give 2 Leftovers, 1 Shell Bell, and Black Sludge", async () => { await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty); 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); 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 runMysteryEncounterToEnd(game, 2, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts b/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts index 4d7e10daa03..5aadaf5c29a 100644 --- a/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts +++ b/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts @@ -11,7 +11,6 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; import type { BerryModifier } from "#modifiers/modifier"; -import { PokemonMove } from "#moves/pokemon-move"; import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils"; import { generateModifierType } from "#mystery-encounters/encounter-phase-utils"; import * as MysteryEncounters from "#mystery-encounters/mystery-encounters"; @@ -214,11 +213,11 @@ describe("Uncommon Breed - Mystery Encounter", () => { // Berries on party lead const sitrus = generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS])!; - const sitrusMod = sitrus.newModifier(scene.getPlayerParty()[0]) as BerryModifier; + const sitrusMod = sitrus.newModifier(game.field.getPlayerPokemon()) as BerryModifier; sitrusMod.stackCount = 2; scene.addModifier(sitrusMod, true, false, false, true); const ganlon = generateModifierType(modifierTypes.BERRY, [BerryType.GANLON])!; - const ganlonMod = ganlon.newModifier(scene.getPlayerParty()[0]) as BerryModifier; + const ganlonMod = ganlon.newModifier(game.field.getPlayerPokemon()) as BerryModifier; ganlonMod.stackCount = 3; scene.addModifier(ganlonMod, true, false, false, true); await scene.updateModifiers(true); @@ -270,7 +269,7 @@ describe("Uncommon Breed - Mystery Encounter", () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty); // Mock moveset - scene.getPlayerParty()[0].moveset = [new PokemonMove(MoveId.CHARM)]; + game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.CHARM); await runMysteryEncounterToEnd(game, 3); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); diff --git a/test/mystery-encounter/encounters/weird-dream-encounter.test.ts b/test/mystery-encounter/encounters/weird-dream-encounter.test.ts index e2317d70896..e2ec7ae514a 100644 --- a/test/mystery-encounter/encounters/weird-dream-encounter.test.ts +++ b/test/mystery-encounter/encounters/weird-dream-encounter.test.ts @@ -116,7 +116,7 @@ describe("Weird Dream - Mystery Encounter", () => { const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal()); 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); 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 () => { await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); 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); - await game.phaseInterceptor.run(SelectModifierPhase); + await game.phaseInterceptor.to("SelectModifierPhase"); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find( @@ -196,9 +196,9 @@ describe("Weird Dream - Mystery Encounter", () => { await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); await runMysteryEncounterToEnd(game, 2, undefined, true); await skipBattleRunMysteryEncounterRewardsPhase(game); - await game.phaseInterceptor.to(SelectModifierPhase, false); + await game.phaseInterceptor.to("SelectModifierPhase", false); 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); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/phases/form-change-phase.test.ts b/test/phases/form-change-phase.test.ts index 3caf824b252..17fe7f4449c 100644 --- a/test/phases/form-change-phase.test.ts +++ b/test/phases/form-change-phase.test.ts @@ -38,7 +38,7 @@ describe("Form Change Phase", () => { await game.classicMode.startBattle([SpeciesId.ZACIAN]); // Before the form change: Should be Hero form - const zacian = game.scene.getPlayerParty()[0]; + const zacian = game.field.getPlayerPokemon(); expect(zacian.getFormKey()).toBe("hero-of-many-battles"); expect(zacian.getTypes()).toStrictEqual([PokemonType.FAIRY]); expect(zacian.calculateBaseStats()).toStrictEqual([92, 120, 115, 80, 115, 138]); diff --git a/test/phases/mystery-encounter-phase.test.ts b/test/phases/mystery-encounter-phase.test.ts index 2b6105c7034..a3dc779b02c 100644 --- a/test/phases/mystery-encounter-phase.test.ts +++ b/test/phases/mystery-encounter-phase.test.ts @@ -37,7 +37,7 @@ describe("Mystery Encounter Phases", () => { SpeciesId.VOLCARONA, ]); - await game.phaseInterceptor.to(MysteryEncounterPhase, false); + await game.phaseInterceptor.to("MysteryEncounterPhase", false); expect(game.scene.phaseManager.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name); }); @@ -49,9 +49,9 @@ describe("Mystery Encounter Phases", () => { game.onNextPrompt("MysteryEncounterPhase", UiMode.MYSTERY_ENCOUNTER, () => { // 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[0].type).toEqual( @@ -75,7 +75,7 @@ describe("Mystery Encounter Phases", () => { handler.processInput(Button.ACTION); }); - await game.phaseInterceptor.run(MysteryEncounterPhase); + await game.phaseInterceptor.to("MysteryEncounterPhase"); // Select option 1 for encounter const handler = game.scene.ui.getHandler() as MysteryEncounterUiHandler; diff --git a/test/phases/select-modifier-phase.test.ts b/test/phases/select-modifier-phase.test.ts index ae4cebb1866..b77e31e931f 100644 --- a/test/phases/select-modifier-phase.test.ts +++ b/test/phases/select-modifier-phase.test.ts @@ -241,7 +241,7 @@ describe("SelectModifierPhase", () => { const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers); scene.phaseManager.unshiftPhase(selectModifierPhase); game.move.select(MoveId.SPLASH); - await game.phaseInterceptor.run(SelectModifierPhase); + await game.phaseInterceptor.to("SelectModifierPhase"); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find( @@ -265,7 +265,7 @@ describe("SelectModifierPhase", () => { const selectModifierPhase = new SelectModifierPhase(0, undefined, customModifiers); scene.phaseManager.unshiftPhase(selectModifierPhase); game.move.select(MoveId.SPLASH); - await game.phaseInterceptor.run(SelectModifierPhase); + await game.phaseInterceptor.to("SelectModifierPhase"); expect(scene.ui.getMode()).to.equal(UiMode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find( diff --git a/test/test-utils/game-manager.ts b/test/test-utils/game-manager.ts index 05b3be21d26..57badd866b1 100644 --- a/test/test-utils/game-manager.ts +++ b/test/test-utils/game-manager.ts @@ -20,13 +20,11 @@ import { ModifierTypeOption } from "#modifiers/modifier-type"; import { CheckSwitchPhase } from "#phases/check-switch-phase"; import { CommandPhase } from "#phases/command-phase"; import { EncounterPhase } from "#phases/encounter-phase"; -import { LoginPhase } from "#phases/login-phase"; import { MovePhase } from "#phases/move-phase"; import { MysteryEncounterPhase } from "#phases/mystery-encounter-phases"; import { NewBattlePhase } from "#phases/new-battle-phase"; import { SelectStarterPhase } from "#phases/select-starter-phase"; import type { SelectTargetPhase } from "#phases/select-target-phase"; -import { TitlePhase } from "#phases/title-phase"; import { TurnEndPhase } from "#phases/turn-end-phase"; import { TurnInitPhase } from "#phases/turn-init-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. */ async runToTitle(): Promise { - await this.phaseInterceptor.whenAboutToRun(LoginPhase); - this.phaseInterceptor.pop(); - await this.phaseInterceptor.run(TitlePhase); + // Go to login phase and skip past it + await this.phaseInterceptor.to("LoginPhase", false); + 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.moveAnimations = false; this.scene.showLevelUpStats = false; @@ -270,7 +270,7 @@ export class GameManager { true, ); - await this.phaseInterceptor.run(EncounterPhase); + await this.phaseInterceptor.to("EncounterPhase"); if (!isNullOrUndefined(encounterType)) { expect(this.scene.currentBattle?.mysteryEncounter?.encounterType).toBe(encounterType); } @@ -542,7 +542,7 @@ export class GameManager { * ``` */ async setTurnOrder(order: BattlerIndex[]): Promise { - await this.phaseInterceptor.to(TurnStartPhase, false); + await this.phaseInterceptor.to("TurnStartPhase", false); vi.spyOn(this.scene.phaseManager.getCurrentPhase() as TurnStartPhase, "getSpeedOrder").mockReturnValue(order); } diff --git a/test/test-utils/helpers/challenge-mode-helper.ts b/test/test-utils/helpers/challenge-mode-helper.ts index a8a9ff89de6..a6d4b5c3b5a 100644 --- a/test/test-utils/helpers/challenge-mode-helper.ts +++ b/test/test-utils/helpers/challenge-mode-helper.ts @@ -49,7 +49,7 @@ export class ChallengeModeHelper extends GameManagerHelper { selectStarterPhase.initBattle(starters); }); - await this.game.phaseInterceptor.run(EncounterPhase); + await this.game.phaseInterceptor.to("EncounterPhase"); if (overrides.ENEMY_HELD_ITEMS_OVERRIDE.length === 0 && this.game.override.removeEnemyStartingItems) { this.game.removeEnemyHeldItems(); } diff --git a/test/test-utils/helpers/reload-helper.ts b/test/test-utils/helpers/reload-helper.ts index a8ed0e21307..7166f1b6cf9 100644 --- a/test/test-utils/helpers/reload-helper.ts +++ b/test/test-utils/helpers/reload-helper.ts @@ -57,7 +57,7 @@ export class ReloadHelper extends GameManagerHelper { this.game.scene.modifiers = []; } 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 if (this.game.scene.battleStyle === BattleStyle.SWITCH) { diff --git a/test/test-utils/phase-interceptor.ts b/test/test-utils/phase-interceptor.ts index 50de7e9f047..0d357a75557 100644 --- a/test/test-utils/phase-interceptor.ts +++ b/test/test-utils/phase-interceptor.ts @@ -1,3 +1,4 @@ +import type { BattleScene } from "#app/battle-scene"; import { Phase } from "#app/phase"; import { UiMode } from "#enums/ui-mode"; import { AttemptRunPhase } from "#phases/attempt-run-phase"; @@ -64,6 +65,7 @@ import { UnlockPhase } from "#phases/unlock-phase"; import { VictoryPhase } from "#phases/victory-phase"; import { ErrorInterceptor } from "#test/test-utils/error-interceptor"; import type { PhaseClass, PhaseString } from "#types/phase-types"; +import type { AwaitableUiHandler } from "#ui/awaitable-ui-handler"; import { UI } from "#ui/ui"; export interface PromptHandler { @@ -76,20 +78,39 @@ export interface PromptHandler { 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 { - public scene; - public phases = {}; - public log: string[]; - private onHold; - private interval; - private promptInterval; - private intervalRun; + public scene: BattleScene; + // @ts-expect-error: initialized in `initPhases` + public phases: Record = {}; + public log: PhaseString[]; + /** + * TODO: This should not be an array; + * 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 phaseFrom; - private inProgress; - private originalSetMode; - private originalSetOverlayMode; - private originalSuperEnd; + private inProgress?: InProgressStub; + private originalSetMode: UI["setMode"]; + private originalSuperEnd: Phase["end"]; /** * 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. */ private PHASES = [ - [LoginPhase, this.startPhase], - [TitlePhase, this.startPhase], - [SelectGenderPhase, this.startPhase], - [NewBiomeEncounterPhase, this.startPhase], - [SelectStarterPhase, this.startPhase], - [PostSummonPhase, this.startPhase], - [SummonPhase, this.startPhase], - [ToggleDoublePositionPhase, this.startPhase], - [CheckSwitchPhase, this.startPhase], - [ShowAbilityPhase, this.startPhase], - [MessagePhase, this.startPhase], - [TurnInitPhase, this.startPhase], - [CommandPhase, this.startPhase], - [EnemyCommandPhase, this.startPhase], - [TurnStartPhase, this.startPhase], - [MovePhase, this.startPhase], - [MoveEffectPhase, this.startPhase], - [DamageAnimPhase, this.startPhase], - [FaintPhase, this.startPhase], - [BerryPhase, this.startPhase], - [TurnEndPhase, this.startPhase], - [BattleEndPhase, this.startPhase], - [EggLapsePhase, this.startPhase], - [SelectModifierPhase, this.startPhase], - [NextEncounterPhase, this.startPhase], - [NewBattlePhase, this.startPhase], - [VictoryPhase, this.startPhase], - [LearnMovePhase, this.startPhase], - [MoveEndPhase, this.startPhase], - [StatStageChangePhase, this.startPhase], - [ShinySparklePhase, this.startPhase], - [SelectTargetPhase, this.startPhase], - [UnavailablePhase, this.startPhase], - [QuietFormChangePhase, this.startPhase], - [SwitchPhase, this.startPhase], - [SwitchSummonPhase, this.startPhase], - [PartyHealPhase, this.startPhase], - [FormChangePhase, this.startPhase], - [EvolutionPhase, this.startPhase], - [EndEvolutionPhase, this.startPhase], - [LevelCapPhase, this.startPhase], - [AttemptRunPhase, this.startPhase], - [SelectBiomePhase, this.startPhase], - [PositionalTagPhase, this.startPhase], - [PokemonTransformPhase, this.startPhase], - [MysteryEncounterPhase, this.startPhase], - [MysteryEncounterOptionSelectedPhase, this.startPhase], - [MysteryEncounterBattlePhase, this.startPhase], - [MysteryEncounterRewardsPhase, this.startPhase], - [PostMysteryEncounterPhase, this.startPhase], - [RibbonModifierRewardPhase, this.startPhase], - [GameOverModifierRewardPhase, this.startPhase], - [ModifierRewardPhase, this.startPhase], - [PartyExpPhase, this.startPhase], - [ExpPhase, this.startPhase], - [EncounterPhase, this.startPhase], - [GameOverPhase, this.startPhase], - [UnlockPhase, this.startPhase], - [PostGameOverPhase, this.startPhase], - [RevivalBlessingPhase, this.startPhase], + LoginPhase, + TitlePhase, + SelectGenderPhase, + NewBiomeEncounterPhase, + SelectStarterPhase, + PostSummonPhase, + SummonPhase, + ToggleDoublePositionPhase, + CheckSwitchPhase, + ShowAbilityPhase, + MessagePhase, + TurnInitPhase, + CommandPhase, + EnemyCommandPhase, + TurnStartPhase, + MovePhase, + MoveEffectPhase, + DamageAnimPhase, + FaintPhase, + BerryPhase, + TurnEndPhase, + BattleEndPhase, + EggLapsePhase, + SelectModifierPhase, + NextEncounterPhase, + NewBattlePhase, + VictoryPhase, + LearnMovePhase, + MoveEndPhase, + StatStageChangePhase, + ShinySparklePhase, + SelectTargetPhase, + UnavailablePhase, + QuietFormChangePhase, + SwitchPhase, + SwitchSummonPhase, + PartyHealPhase, + FormChangePhase, + EvolutionPhase, + EndEvolutionPhase, + LevelCapPhase, + AttemptRunPhase, + SelectBiomePhase, + PositionalTagPhase, + PokemonTransformPhase, + MysteryEncounterPhase, + MysteryEncounterOptionSelectedPhase, + MysteryEncounterBattlePhase, + MysteryEncounterRewardsPhase, + PostMysteryEncounterPhase, + RibbonModifierRewardPhase, + GameOverModifierRewardPhase, + ModifierRewardPhase, + PartyExpPhase, + ExpPhase, + EncounterPhase, + GameOverPhase, + UnlockPhase, + PostGameOverPhase, + RevivalBlessingPhase, ]; private endBySetMode = [ TitlePhase, SelectGenderPhase, CommandPhase, + SelectStarterPhase, SelectModifierPhase, MysteryEncounterPhase, PostMysteryEncounterPhase, @@ -175,7 +197,7 @@ export class PhaseInterceptor { * Constructor to initialize the scene and properties, and to start the phase handling. * @param scene - The scene to be managed. */ - constructor(scene) { + constructor(scene: BattleScene) { this.scene = scene; this.onHold = []; 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. * @param phaseTo - The phase to transition to. @@ -219,59 +231,50 @@ export class PhaseInterceptor { async to(phaseTo: PhaseInterceptorPhase, runTarget = true): Promise { return new Promise(async (resolve, reject) => { 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; this.intervalRun = setInterval(async () => { const currentPhase = this.onHold?.length && this.onHold[0]; - if (currentPhase && currentPhase.name === targetName) { - clearInterval(this.intervalRun); - if (!runTarget) { - return resolve(); - } - await this.run(currentPhase).catch(e => { + if (!currentPhase) { + // No current phase means the manager either hasn't started yet + // or we were interrupted by prompt; wait for phase to finish + return; + } + + // 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); return reject(e); }); + return; + } + + // Hit target phase; run it and resolve + clearInterval(this.intervalRun); + if (!runTarget) { return resolve(); } - if (currentPhase && currentPhase.name !== targetName) { - await this.run(currentPhase).catch(e => { - clearInterval(this.intervalRun); - return reject(e); - }); - } + await this.run().catch(e => { + clearInterval(this.intervalRun); + return reject(e); + }); + return resolve(); }); }); } /** - * Method to run a phase with an optional skip function. - * @param phaseTarget - The phase to run. - * @param skipFn - Optional skip function. + * Method to run the current phase with an optional skip function. * @returns A promise that resolves when the phase is run. */ - run(phaseTarget: PhaseInterceptorPhase, skipFn?: (className: PhaseClass) => boolean): Promise { - const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name; - this.scene.moveAnimations = null; // Mandatory to avoid crash + private run(): Promise { + // @ts-expect-error: This is apparently mandatory to avoid a crash; review if this is needed + this.scene.moveAnimations = null; return new Promise(async (resolve, reject) => { ErrorInterceptor.getInstance().add(this); const interval = setInterval(async () => { const currentPhase = this.onHold.shift(); 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); this.inProgress = { name: currentPhase.name, @@ -287,26 +290,6 @@ export class PhaseInterceptor { }); } - whenAboutToRun(phaseTarget: PhaseInterceptorPhase, _skipFn?: (className: PhaseClass) => boolean): Promise { - 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. * @@ -316,7 +299,7 @@ export class PhaseInterceptor { * * @param shouldRun Whether or not the current scene should also be run. */ - shift(shouldRun = false): void { + shiftPhase(shouldRun = false): void { this.onHold.shift(); if (shouldRun) { this.scene.phaseManager.shiftPhase(); @@ -328,17 +311,16 @@ export class PhaseInterceptor { */ initPhases() { this.originalSetMode = UI.prototype.setMode; - this.originalSetOverlayMode = UI.prototype.setOverlayMode; this.originalSuperEnd = Phase.prototype.end; UI.prototype.setMode = (mode, ...args) => this.setMode.call(this, mode, ...args); 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; this.phases[phase.name] = { start: originalStart, 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. */ startPhase(phase: PhaseClass) { - this.log.push(phase.name); + this.log.push(phase.name as PhaseString); const instance = this.scene.phaseManager.getCurrentPhase(); this.onHold.push({ 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. * @param phase - The phase to start. */ - superEndPhase() { + private superEndPhase() { const instance = this.scene.phaseManager.getCurrentPhase(); this.originalSuperEnd.apply(instance); this.inProgress?.callback(); @@ -379,7 +356,8 @@ export class PhaseInterceptor { * @param args - Additional arguments to pass to the original method. */ setMode(mode: UiMode, ...args: unknown[]): Promise { - 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; console.log("setMode", `${UiMode[mode]} (=${mode})`, args); const ret = this.originalSetMode.apply(instance, [mode, ...args]); @@ -395,18 +373,6 @@ export class PhaseInterceptor { 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 { - 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. */ @@ -425,7 +391,7 @@ export class PhaseInterceptor { currentPhase === actionForNextPrompt.phaseTarget && currentHandler.active && (!actionForNextPrompt.awaitingActionInput || - (actionForNextPrompt.awaitingActionInput && currentHandler.awaitingActionInput)) + (actionForNextPrompt.awaitingActionInput && (currentHandler as AwaitableUiHandler)["awaitingActionInput"])) ) { const prompt = this.prompts.shift(); if (prompt?.callback) { @@ -467,11 +433,10 @@ export class PhaseInterceptor { * function stored in `this.phases`. Additionally, it clears the `promptInterval` and `interval`. */ restoreOg() { - for (const [phase] of this.PHASES) { + for (const phase of this.PHASES) { phase.prototype.start = this.phases[phase.name].start; } UI.prototype.setMode = this.originalSetMode; - UI.prototype.setOverlayMode = this.originalSetOverlayMode; Phase.prototype.end = this.originalSuperEnd; clearInterval(this.promptInterval); clearInterval(this.interval); diff --git a/test/ui/pokedex.test.ts b/test/ui/pokedex.test.ts index 217c1f09a3b..edd9fa879d0 100644 --- a/test/ui/pokedex.test.ts +++ b/test/ui/pokedex.test.ts @@ -69,7 +69,7 @@ describe("UI - Pokedex", () => { // Open the pokedex UI. await game.runToTitle(); - await game.phaseInterceptor.setOverlayMode(UiMode.POKEDEX); + await game.scene.ui.setOverlayMode(UiMode.POKEDEX); // Get the handler for the current UI. const handler = game.scene.ui.getHandler(); @@ -89,7 +89,7 @@ describe("UI - Pokedex", () => { // Open the pokedex UI. 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. const handler = game.scene.ui.getHandler(); diff --git a/test/ui/starter-select.test.ts b/test/ui/starter-select.test.ts index 6dc9603c8b3..397f3d6086f 100644 --- a/test/ui/starter-select.test.ts +++ b/test/ui/starter-select.test.ts @@ -6,8 +6,6 @@ import { GameModes } from "#enums/game-modes"; import { Nature } from "#enums/nature"; import { SpeciesId } from "#enums/species-id"; 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 { GameManager } from "#test/test-utils/game-manager"; 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.LEFT); handler.processInput(Button.ACTION); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -88,12 +85,12 @@ describe("UI - Starter select", () => { 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].shiny).toBe(true); - expect(game.scene.getPlayerParty()[0].variant).toBe(2); - expect(game.scene.getPlayerParty()[0].gender).toBe(Gender.MALE); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR); + expect(game.field.getPlayerPokemon().shiny).toBe(true); + expect(game.field.getPlayerPokemon().variant).toBe(2); + expect(game.field.getPlayerPokemon().gender).toBe(Gender.MALE); }); it("Bulbasaur - shiny - variant 2 female hardy overgrow", async () => { @@ -115,9 +112,8 @@ describe("UI - Starter select", () => { handler.processInput(Button.LEFT); handler.processInput(Button.CYCLE_GENDER); handler.processInput(Button.ACTION); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -149,13 +145,13 @@ describe("UI - Starter select", () => { 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].shiny).toBe(true); - expect(game.scene.getPlayerParty()[0].variant).toBe(2); - expect(game.scene.getPlayerParty()[0].nature).toBe(Nature.HARDY); - expect(game.scene.getPlayerParty()[0].getAbility().id).toBe(AbilityId.OVERGROW); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR); + expect(game.field.getPlayerPokemon().shiny).toBe(true); + expect(game.field.getPlayerPokemon().variant).toBe(2); + expect(game.field.getPlayerPokemon().nature).toBe(Nature.HARDY); + expect(game.field.getPlayerPokemon().getAbility().id).toBe(AbilityId.OVERGROW); }); it("Bulbasaur - shiny - variant 2 female lonely chlorophyl", async () => { @@ -179,9 +175,8 @@ describe("UI - Starter select", () => { handler.processInput(Button.CYCLE_NATURE); handler.processInput(Button.CYCLE_ABILITY); handler.processInput(Button.ACTION); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -213,14 +208,14 @@ describe("UI - Starter select", () => { 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].shiny).toBe(true); - expect(game.scene.getPlayerParty()[0].variant).toBe(2); - expect(game.scene.getPlayerParty()[0].gender).toBe(Gender.FEMALE); - expect(game.scene.getPlayerParty()[0].nature).toBe(Nature.LONELY); - expect(game.scene.getPlayerParty()[0].getAbility().id).toBe(AbilityId.CHLOROPHYLL); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR); + expect(game.field.getPlayerPokemon().shiny).toBe(true); + expect(game.field.getPlayerPokemon().variant).toBe(2); + expect(game.field.getPlayerPokemon().gender).toBe(Gender.FEMALE); + expect(game.field.getPlayerPokemon().nature).toBe(Nature.LONELY); + expect(game.field.getPlayerPokemon().getAbility().id).toBe(AbilityId.CHLOROPHYLL); }); it("Bulbasaur - shiny - variant 2 female", async () => { @@ -242,9 +237,8 @@ describe("UI - Starter select", () => { handler.processInput(Button.LEFT); handler.processInput(Button.CYCLE_GENDER); handler.processInput(Button.ACTION); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -276,12 +270,12 @@ describe("UI - Starter select", () => { 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].shiny).toBe(true); - expect(game.scene.getPlayerParty()[0].variant).toBe(2); - expect(game.scene.getPlayerParty()[0].gender).toBe(Gender.FEMALE); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR); + expect(game.field.getPlayerPokemon().shiny).toBe(true); + expect(game.field.getPlayerPokemon().variant).toBe(2); + expect(game.field.getPlayerPokemon().gender).toBe(Gender.FEMALE); }); it("Bulbasaur - not shiny", async () => { @@ -303,9 +297,8 @@ describe("UI - Starter select", () => { handler.processInput(Button.LEFT); handler.processInput(Button.ACTION); handler.processInput(Button.CYCLE_SHINY); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -337,11 +330,11 @@ describe("UI - Starter select", () => { 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].shiny).toBe(false); - expect(game.scene.getPlayerParty()[0].variant).toBe(0); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR); + expect(game.field.getPlayerPokemon().shiny).toBe(false); + expect(game.field.getPlayerPokemon().variant).toBe(0); }); it("Bulbasaur - shiny - variant 1", async () => { @@ -365,9 +358,8 @@ describe("UI - Starter select", () => { handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.ACTION); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -399,11 +391,11 @@ describe("UI - Starter select", () => { 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].shiny).toBe(true); - expect(game.scene.getPlayerParty()[0].variant).toBe(1); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR); + expect(game.field.getPlayerPokemon().shiny).toBe(true); + expect(game.field.getPlayerPokemon().variant).toBe(1); }); it("Bulbasaur - shiny - variant 0", async () => { @@ -426,9 +418,8 @@ describe("UI - Starter select", () => { handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.CYCLE_SHINY); handler.processInput(Button.ACTION); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -460,11 +451,11 @@ describe("UI - Starter select", () => { 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].shiny).toBe(true); - expect(game.scene.getPlayerParty()[0].variant).toBe(0); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR); + expect(game.field.getPlayerPokemon().shiny).toBe(true); + expect(game.field.getPlayerPokemon().variant).toBe(0); }); it("Check if first pokemon in party is caterpie from gen 1 and 1rd row, 3rd column", async () => { @@ -486,9 +477,8 @@ describe("UI - Starter select", () => { handler.processInput(Button.RIGHT); handler.processInput(Button.RIGHT); handler.processInput(Button.ACTION); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -527,8 +517,8 @@ describe("UI - Starter select", () => { const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler; saveSlotSelectUiHandler.processInput(Button.ACTION); }); - await game.phaseInterceptor.whenAboutToRun(EncounterPhase); - expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.CATERPIE); + await game.phaseInterceptor.to("EncounterPhase", false); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.CATERPIE); }); it("Check if first pokemon in party is nidoran_m from gen 1 and 2nd row, 4th column (cursor (9+4)-1)", async () => { @@ -551,9 +541,8 @@ describe("UI - Starter select", () => { handler.processInput(Button.RIGHT); handler.processInput(Button.DOWN); handler.processInput(Button.ACTION); - game.phaseInterceptor.unlock(); }); - await game.phaseInterceptor.run(SelectStarterPhase); + await game.phaseInterceptor.to("SelectStarterPhase"); let options: OptionSelectItem[] = []; let optionSelectUiHandler: OptionSelectUiHandler | undefined; await new Promise(resolve => { @@ -593,7 +582,7 @@ describe("UI - Starter select", () => { const saveSlotSelectUiHandler = game.scene.ui.getHandler() as SaveSlotSelectUiHandler; saveSlotSelectUiHandler.processInput(Button.ACTION); }); - await game.phaseInterceptor.whenAboutToRun(EncounterPhase); - expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.NIDORAN_M); + await game.phaseInterceptor.to("EncounterPhase", false); + expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.NIDORAN_M); }); }); diff --git a/test/ui/transfer-item.test.ts b/test/ui/transfer-item.test.ts index 0d101b5b4ef..8e42149acc3 100644 --- a/test/ui/transfer-item.test.ts +++ b/test/ui/transfer-item.test.ts @@ -72,8 +72,6 @@ describe("UI - Transfer Items", () => { expect( handler.optionsContainer.list.some(option => RegExp(/Lum Berry\[color.*(2)/).exec((option as BBCodeText).text)), ).toBe(true); - - game.phaseInterceptor.unlock(); }); 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( true, ); - - game.phaseInterceptor.unlock(); }); await game.phaseInterceptor.to("SelectModifierPhase"); diff --git a/test/ui/type-hints.test.ts b/test/ui/type-hints.test.ts index f1f27322a64..b5fe0d9585a 100644 --- a/test/ui/type-hints.test.ts +++ b/test/ui/type-hints.test.ts @@ -2,7 +2,6 @@ import { Button } from "#enums/buttons"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { UiMode } from "#enums/ui-mode"; -import { CommandPhase } from "#phases/command-phase"; import { GameManager } from "#test/test-utils/game-manager"; import type { MockText } from "#test/test-utils/mocks/mocks-container/mock-text"; import { FightUiHandler } from "#ui/fight-ui-handler"; @@ -46,7 +45,6 @@ describe("UI - Type Hints", () => { const { ui } = game.scene; const handler = ui.getHandler(); handler.processInput(Button.ACTION); // select "Fight" - game.phaseInterceptor.unlock(); }); game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => { @@ -59,7 +57,7 @@ describe("UI - Type Hints", () => { expect.soft(dragonClawText.color).toBe("#929292"); ui.getHandler().processInput(Button.ACTION); }); - await game.phaseInterceptor.to(CommandPhase); + await game.phaseInterceptor.to("CommandPhase"); }); it("check status move color", async () => { @@ -71,7 +69,6 @@ describe("UI - Type Hints", () => { const { ui } = game.scene; const handler = ui.getHandler(); handler.processInput(Button.ACTION); // select "Fight" - game.phaseInterceptor.unlock(); }); game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => { @@ -84,7 +81,7 @@ describe("UI - Type Hints", () => { expect.soft(growlText.color).toBe(undefined); 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 () => { @@ -107,7 +104,6 @@ describe("UI - Type Hints", () => { const { ui } = game.scene; const handler = ui.getHandler(); handler.processInput(Button.ACTION); // select "Fight" - game.phaseInterceptor.unlock(); }); game.onNextPrompt("CommandPhase", UiMode.FIGHT, () => { @@ -121,6 +117,6 @@ describe("UI - Type Hints", () => { expect.soft(shadowBallText.color).toBe(undefined); ui.getHandler().processInput(Button.ACTION); }); - await game.phaseInterceptor.to(CommandPhase); + await game.phaseInterceptor.to("CommandPhase"); }); });