diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 17c18c3b2fe..8228bdb54e6 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -22,8 +22,7 @@ import { getModifierPoolForType, getModifierType, getPartyLuckValue, - modifierTypes, - PokemonHeldItemModifierType + modifierTypes } from "./modifier/modifier-type"; import AbilityBar from "./ui/ability-bar"; import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, ChangeMovePriorityAbAttr, PostBattleInitAbAttr, applyAbAttrs, applyPostBattleInitAbAttrs } from "./data/ability"; @@ -49,7 +48,7 @@ import PokemonData from "./system/pokemon-data"; import { Nature } from "./data/nature"; import { SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger, pokemonFormChanges, FormChangeItem, SpeciesFormChange } from "./data/pokemon-forms"; import { FormChangePhase } from "./phases/form-change-phase"; -import { getTypeRgb, Type } from "./data/type"; +import { getTypeRgb } from "./data/type"; import PokemonSpriteSparkleHandler from "./field/pokemon-sprite-sparkle-handler"; import CharSprite from "./ui/char-sprite"; import DamageNumberHandler from "./field/damage-number-handler"; @@ -102,8 +101,6 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterMode } from "#enums/mystery-encounter-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import HeldModifierConfig from "#app/interfaces/held-modifier-config"; -import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1"; @@ -1115,11 +1112,6 @@ export default class BattleScene extends SceneBase { const playerField = this.getPlayerField(); - const mod = generateModifierType(this, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.BUG]); - if (mod) { - applyModifierTypeToPlayerPokemon(this, this.getParty()[0], mod as PokemonHeldItemModifierType); - } - if (this.gameMode.isFixedBattle(newWaveIndex) && trainerData === undefined) { battleConfig = this.gameMode.getFixedBattle(newWaveIndex); newDouble = battleConfig.double; 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 9042ea4b8de..227e128fe20 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -238,7 +238,6 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = text: `${namespace}.option.1.selected`, }, ], - secondOptionPrompt: `${namespace}.option.3.select_prompt`, }, async (scene: BattleScene) => { // Select battle the bug trainer @@ -552,7 +551,13 @@ function getTrainerConfigForWave(waveIndex: number) { p.generateAndPopulateMoveset(); p.generateName(); })) - .setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { + if (!isNullOrUndefined(pool3Mon.formIndex)) { + p.formIndex = pool3Mon.formIndex!; + p.generateAndPopulateMoveset(); + p.generateName(); + } + })) .setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => { if (!isNullOrUndefined(pool3Mon.formIndex)) { p.formIndex = pool3Mon.formIndex!; @@ -614,7 +619,7 @@ function doBugTypeMoveTutor(scene: BattleScene): Promise { moveInfoOverlay.setVisible(false); }; - const result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.option.3.select_prompt`, undefined, onHoverOverCancel); + const result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel); // let forceExit = !!result; if (!result) { moveInfoOverlay.active = false; @@ -635,7 +640,7 @@ function doBugTypeMoveTutor(scene: BattleScene): Promise { // forceExit = true; // } else { // // Re-show learn menu - // result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.option.3.select_prompt`, undefined, onHoverOverCancel); + // result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel); // if (!result) { // moveInfoOverlay.active = false; // moveInfoOverlay.setVisible(false); diff --git a/src/data/mystery-encounters/encounters/part-timer-encounter.ts b/src/data/mystery-encounters/encounters/part-timer-encounter.ts index bfd977babfd..d7797f133ce 100644 --- a/src/data/mystery-encounters/encounters/part-timer-encounter.ts +++ b/src/data/mystery-encounters/encounters/part-timer-encounter.ts @@ -140,7 +140,7 @@ export const PartTimerEncounter: MysteryEncounter = } const moneyChange = scene.getWaveMoneyAmount(moneyMultiplier); updatePlayerMoney(scene, moneyChange, true, false); - await showEncounterText(scene, i18next.t("mysteryEncounter:receive_money", { amount: moneyChange })); + await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange })); await showEncounterText(scene, `${namespace}.pokemon_tired`); setEncounterRewards(scene, { fillRemaining: true }); @@ -221,7 +221,7 @@ export const PartTimerEncounter: MysteryEncounter = } const moneyChange = scene.getWaveMoneyAmount(moneyMultiplier); updatePlayerMoney(scene, moneyChange, true, false); - await showEncounterText(scene, i18next.t("mysteryEncounter:receive_money", { amount: moneyChange })); + await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange })); await showEncounterText(scene, `${namespace}.pokemon_tired`); setEncounterRewards(scene, { fillRemaining: true }); @@ -273,7 +273,7 @@ export const PartTimerEncounter: MysteryEncounter = await showEncounterDialogue(scene, `${namespace}.job_complete_good`, `${namespace}.speaker`); const moneyChange = scene.getWaveMoneyAmount(2.5); updatePlayerMoney(scene, moneyChange, true, false); - await showEncounterText(scene, i18next.t("mysteryEncounter:receive_money", { amount: moneyChange })); + await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange })); await showEncounterText(scene, `${namespace}.pokemon_tired`); setEncounterRewards(scene, { fillRemaining: true }); diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts index 6ba73357f42..a4c4d57daca 100644 --- a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -143,7 +143,6 @@ export const TeleportingHijinksEncounter: MysteryEncounter = const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.STEEL])!; const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.ELECTRIC])!; setEncounterRewards(scene, { guaranteedModifierTypeOptions: [magnet, metalCoat], fillRemaining: true }); - setEncounterExp(scene, encounter.selectedOption!.primaryPokemon!.id, 100); transitionMysteryEncounterIntroVisuals(scene, true, true); await initBattleWithEnemyConfig(scene, config); } diff --git a/src/data/mystery-encounters/mystery-encounter-option.ts b/src/data/mystery-encounters/mystery-encounter-option.ts index 086706075e7..aa0e1865a12 100644 --- a/src/data/mystery-encounters/mystery-encounter-option.ts +++ b/src/data/mystery-encounters/mystery-encounter-option.ts @@ -81,7 +81,7 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption { } meetsPrimaryRequirementAndPrimaryPokemonSelected(scene: BattleScene) { - if (!this.primaryPokemonRequirements) { + if (!this.primaryPokemonRequirements || this.primaryPokemonRequirements.length === 0) { return true; } let qualified: PlayerPokemon[] = scene.getParty(); @@ -101,7 +101,7 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption { return false; } - if (this.excludePrimaryFromSecondaryRequirements && this.secondaryPokemon) { + if (this.excludePrimaryFromSecondaryRequirements && this.secondaryPokemon && this.secondaryPokemon.length > 0) { const truePrimaryPool: PlayerPokemon[] = []; const overlap: PlayerPokemon[] = []; for (const qp of qualified) { @@ -135,7 +135,7 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption { } meetsSupportingRequirementAndSupportingPokemonSelected(scene: BattleScene) { - if (!this.secondaryPokemonRequirements) { + if (!this.secondaryPokemonRequirements || this.secondaryPokemonRequirements.length === 0) { this.secondaryPokemon = []; return true; } diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index 8efac442e7c..4bbd4bcb1b6 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -263,7 +263,7 @@ export default class MysteryEncounter implements IMysteryEncounter { } meetsPrimaryRequirementAndPrimaryPokemonSelected(scene: BattleScene): boolean { - if (this.primaryPokemonRequirements.length === 0) { + if (!this.primaryPokemonRequirements || this.primaryPokemonRequirements.length === 0) { const activeMon = scene.getParty().filter(p => p.isActive(true)); if (activeMon.length > 0) { this.primaryPokemon = activeMon[0]; @@ -286,7 +286,7 @@ export default class MysteryEncounter implements IMysteryEncounter { return false; } - if (this.excludePrimaryFromSupportRequirements && this.secondaryPokemon) { + if (this.excludePrimaryFromSupportRequirements && this.secondaryPokemon && this.secondaryPokemon.length > 0) { const truePrimaryPool: PlayerPokemon[] = []; const overlap: PlayerPokemon[] = []; for (const qp of qualified) { @@ -320,7 +320,7 @@ export default class MysteryEncounter implements IMysteryEncounter { } meetsSecondaryRequirementAndSecondaryPokemonSelected(scene: BattleScene): boolean { - if (!this.secondaryPokemonRequirements) { + if (!this.secondaryPokemonRequirements || this.secondaryPokemonRequirements.length === 0) { this.secondaryPokemon = []; return true; } diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index b4942b01c15..dab7cb8c826 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -367,9 +367,9 @@ export function updatePlayerMoney(scene: BattleScene, changeValue: number, playS } if (showMessage) { if (changeValue < 0) { - scene.queueMessage(i18next.t("mysteryEncounter:paid_money", { amount: -changeValue }), null, true); + scene.queueMessage(i18next.t("mysteryEncounterMessages:paid_money", { amount: -changeValue }), null, true); } else { - scene.queueMessage(i18next.t("mysteryEncounter:receive_money", { amount: changeValue }), null, true); + scene.queueMessage(i18next.t("mysteryEncounterMessages:receive_money", { amount: changeValue }), null, true); } } } @@ -457,7 +457,7 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p return true; }, onHover: () => { - scene.ui.showText(i18next.t("mysteryEncounter:cancel_option")); + scene.ui.showText(i18next.t("mysteryEncounterMessages:cancel_option")); } }); @@ -571,7 +571,7 @@ export function selectOptionThenPokemon(scene: BattleScene, options: OptionSelec if (onHoverOverCancelOption) { onHoverOverCancelOption(); } - scene.ui.showText(i18next.t("mysteryEncounter:cancel_option")); + scene.ui.showText(i18next.t("mysteryEncounterMessages:cancel_option")); } }); diff --git a/src/locales/en/config.ts b/src/locales/en/config.ts index 0752a393711..bf764801272 100644 --- a/src/locales/en/config.ts +++ b/src/locales/en/config.ts @@ -59,6 +59,7 @@ import modifierSelectUiHandler from "./modifier-select-ui-handler.json"; import moveTriggers from "./move-trigger.json"; import runHistory from "./run-history.json"; import { mysteryEncounter } from "#app/locales/en/mystery-encounter"; +import mysteryEncounterMessages from "./mystery-encounter-messages.json"; export const enConfig = { ability, @@ -121,5 +122,6 @@ export const enConfig = { modifierSelectUiHandler, moveTriggers, runHistory, - mysteryEncounter: mysteryEncounter + mysteryEncounter: mysteryEncounter, + mysteryEncounterMessages }; diff --git a/src/locales/en/mystery-encounter-messages.json b/src/locales/en/mystery-encounter-messages.json new file mode 100644 index 00000000000..4e2ab639192 --- /dev/null +++ b/src/locales/en/mystery-encounter-messages.json @@ -0,0 +1,6 @@ +{ + "paid_money": "You paid ₽{{amount, number}}.", + "receive_money": "You received ₽{{amount, number}}!", + "affects_pokedex": "Affects Pokédex Data", + "cancel_option": "Return to encounter option select." +} diff --git a/src/locales/en/mystery-encounter.ts b/src/locales/en/mystery-encounter.ts index 5578cf6fe1b..8ed2d597523 100644 --- a/src/locales/en/mystery-encounter.ts +++ b/src/locales/en/mystery-encounter.ts @@ -45,12 +45,6 @@ export const mysteryEncounter = { // DO NOT REMOVE "unit_test_dialogue": "{{test}}{{test}} {{test{{test}}}} {{test1}} {{test\}} {{test\\}} {{test\\\}} {test}}", - // General use content - "paid_money": "You paid ₽{{amount, number}}.", - "receive_money": "You received ₽{{amount, number}}!", - "affects_pokedex": "Affects Pokédex Data", - "cancel_option": "Return to encounter option select.", - mysteriousChallengers: mysteriousChallengersDialogue, mysteriousChest: mysteriousChestDialogue, darkDeal: darkDealDialogue, diff --git a/src/locales/en/mystery-encounters/bug-type-superfan-dialogue.json b/src/locales/en/mystery-encounters/bug-type-superfan-dialogue.json index 13087c1d932..58bdf942eb3 100644 --- a/src/locales/en/mystery-encounters/bug-type-superfan-dialogue.json +++ b/src/locales/en/mystery-encounters/bug-type-superfan-dialogue.json @@ -32,6 +32,7 @@ } }, "battle_won": "Your knowledge and skill were perfect at exploiting our weaknesses!$In exchange for the valuable lesson,\nallow me to teach one of your Pokémon a Bug Type Move!", + "teach_move_prompt": "Select a move to teach a Pokémon.", "confirm_no_teach": "You sure you don't want to learn one of these great moves?", "outro": "I see great Bug Pokémon in your future!\nMay our paths cross again!$Bug out!" } \ No newline at end of file diff --git a/src/overrides.ts b/src/overrides.ts index 41f261b73df..cbde74314c6 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -130,10 +130,11 @@ class DefaultOverrides { // ------------------------- // MYSTERY ENCOUNTER OVERRIDES // ------------------------- - // 1 to 256, set to null to ignore - readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number | null = 256; + + /** 1 to 256, set to null to ignore */ + readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number | null = null; readonly MYSTERY_ENCOUNTER_TIER_OVERRIDE: MysteryEncounterTier | null = null; - readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType | null = MysteryEncounterType.BUG_TYPE_SUPERFAN; + readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType | null = null; // ------------------------- // MODIFIER / ITEM OVERRIDES diff --git a/src/test/final_boss.test.ts b/src/test/final_boss.test.ts index 0f59572619b..c9d9404affa 100644 --- a/src/test/final_boss.test.ts +++ b/src/test/final_boss.test.ts @@ -53,7 +53,7 @@ describe("Final Boss", () => { expect(game.scene.getEnemyPokemon()!.species.speciesId).not.toBe(Species.ETERNATUS); }); - it("should not have passive enabled on Eternatus", async () => { + it("should NOT have passive enabled on Eternatus", async () => { await game.runToFinalBossEncounter(game, [Species.BIDOOF], GameModes.CLASSIC); const eternatus = game.scene.getEnemyPokemon(); diff --git a/src/test/mystery-encounter/encounterTestUtils.ts b/src/test/mystery-encounter/encounter-test-utils.ts similarity index 97% rename from src/test/mystery-encounter/encounterTestUtils.ts rename to src/test/mystery-encounter/encounter-test-utils.ts index a157f87c1ba..9fb6c52cef3 100644 --- a/src/test/mystery-encounter/encounterTestUtils.ts +++ b/src/test/mystery-encounter/encounter-test-utils.ts @@ -150,8 +150,9 @@ async function handleSecondaryOptionSelect(game: GameManager, pokemonNo: number, /** * For any MysteryEncounter that has a battle, can call this to skip battle and proceed to MysteryEncounterRewardsPhase * @param game + * @param runRewardsPhase */ -export async function skipBattleRunMysteryEncounterRewardsPhase(game: GameManager) { +export async function skipBattleRunMysteryEncounterRewardsPhase(game: GameManager, runRewardsPhase: boolean = true) { game.scene.clearPhaseQueue(); game.scene.clearPhaseQueueSplice(); game.scene.getEnemyParty().forEach(p => { @@ -161,5 +162,5 @@ export async function skipBattleRunMysteryEncounterRewardsPhase(game: GameManage }); game.scene.pushPhase(new VictoryPhase(game.scene, 0)); game.phaseInterceptor.superEndPhase(); - await game.phaseInterceptor.to(MysteryEncounterRewardsPhase, true); + await game.phaseInterceptor.to(MysteryEncounterRewardsPhase, runRewardsPhase); } diff --git a/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts b/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts index 6b405b9e5b3..b4cc186864c 100644 --- a/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts @@ -6,7 +6,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; diff --git a/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts b/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts index b5999f69897..3bf17b61b2a 100644 --- a/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts @@ -4,7 +4,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; diff --git a/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts b/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts index bbc1a968b5c..19aa04b7a7a 100644 --- a/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts @@ -6,7 +6,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { PlayerPokemon, PokemonMove } from "#app/field/pokemon"; import { AnOfferYouCantRefuseEncounter } from "#app/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter"; diff --git a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts index 23ec94683ee..3e772c9fb4c 100644 --- a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { Mode } from "#app/ui/ui"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; diff --git a/src/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts b/src/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts new file mode 100644 index 00000000000..70adf93d502 --- /dev/null +++ b/src/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts @@ -0,0 +1,585 @@ +import * as MysteryEncounters from "#app/data/mystery-encounters/mystery-encounters"; +import { Biome } from "#app/enums/biome"; +import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; +import { Species } from "#app/enums/species"; +import GameManager from "#app/test/utils/gameManager"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; +import { Moves } from "#enums/moves"; +import BattleScene from "#app/battle-scene"; +import { PokemonMove } from "#app/field/pokemon"; +import { Mode } from "#app/ui/ui"; +import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; +import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; +import { TrainerType } from "#enums/trainer-type"; +import { MysteryEncounterPhase, MysteryEncounterRewardsPhase } from "#app/phases/mystery-encounter-phases"; +import { ContactHeldItemTransferChanceModifier } from "#app/modifier/modifier"; +import { CommandPhase } from "#app/phases/command-phase"; +import { BugTypeSuperfanEncounter } from "#app/data/mystery-encounters/encounters/bug-type-superfan-encounter"; +import * as encounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; +import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; + +const namespace = "mysteryEncounter:bugTypeSuperfan"; +const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.WEEDLE]; +const defaultBiome = Biome.CAVE; +const defaultWave = 24; + +const POOL_1_POKEMON = [ + Species.PARASECT, + Species.VENOMOTH, + Species.LEDIAN, + Species.ARIADOS, + Species.YANMA, + Species.BEAUTIFLY, + Species.DUSTOX, + Species.MASQUERAIN, + Species.NINJASK, + Species.VOLBEAT, + Species.ILLUMISE, + Species.ANORITH, + Species.KRICKETUNE, + Species.WORMADAM, + Species.MOTHIM, + Species.SKORUPI, + Species.JOLTIK, + Species.LARVESTA, + Species.VIVILLON, + Species.CHARJABUG, + Species.RIBOMBEE, + Species.SPIDOPS, + Species.LOKIX +]; + +const POOL_2_POKEMON = [ + Species.SCYTHER, + Species.PINSIR, + Species.HERACROSS, + Species.FORRETRESS, + Species.SCIZOR, + Species.SHUCKLE, + Species.SHEDINJA, + Species.ARMALDO, + Species.VESPIQUEN, + Species.DRAPION, + Species.YANMEGA, + Species.LEAVANNY, + Species.SCOLIPEDE, + Species.CRUSTLE, + Species.ESCAVALIER, + Species.ACCELGOR, + Species.GALVANTULA, + Species.VIKAVOLT, + Species.ARAQUANID, + Species.ORBEETLE, + Species.CENTISKORCH, + Species.FROSMOTH, + Species.KLEAVOR, +]; + +const POOL_3_POKEMON: { species: Species, formIndex?: number }[] = [ + { + species: Species.PINSIR, + formIndex: 1 + }, + { + species: Species.SCIZOR, + formIndex: 1 + }, + { + species: Species.HERACROSS, + formIndex: 1 + }, + { + species: Species.ORBEETLE, + formIndex: 1 + }, + { + species: Species.CENTISKORCH, + formIndex: 1 + }, + { + species: Species.DURANT, + }, + { + species: Species.VOLCARONA, + }, + { + species: Species.GOLISOPOD, + }, +]; + +const POOL_4_POKEMON = [ + Species.GENESECT, + Species.SLITHER_WING, + Species.BUZZWOLE, + Species.PHEROMOSA +]; + +const PHYSICAL_TUTOR_MOVES = [ + Moves.MEGAHORN, + Moves.X_SCISSOR, + Moves.ATTACK_ORDER, + Moves.PIN_MISSILE, + Moves.FIRST_IMPRESSION +]; + +const SPECIAL_TUTOR_MOVES = [ + Moves.SILVER_WIND, + Moves.BUG_BUZZ, + Moves.SIGNAL_BEAM, + Moves.POLLEN_PUFF +]; + +const STATUS_TUTOR_MOVES = [ + Moves.STRING_SHOT, + Moves.STICKY_WEB, + Moves.SILK_TRAP, + Moves.RAGE_POWDER, + Moves.HEAL_ORDER +]; + +const MISC_TUTOR_MOVES = [ + Moves.BUG_BITE, + Moves.LEECH_LIFE, + Moves.DEFEND_ORDER, + Moves.QUIVER_DANCE, + Moves.TAIL_GLOW, + Moves.INFESTATION, + Moves.U_TURN +]; + +describe("Bug-Type Superfan - Mystery Encounter", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + let scene: BattleScene; + + beforeAll(() => { + phaserGame = new Phaser.Game({ type: Phaser.HEADLESS }); + }); + + beforeEach(async () => { + game = new GameManager(phaserGame); + scene = game.scene; + game.override.mysteryEncounterChance(100); + game.override.startingWave(defaultWave); + game.override.startingBiome(defaultBiome); + game.override.disableTrainerWaves(); + + vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( + new Map([ + [Biome.CAVE, [MysteryEncounterType.BUG_TYPE_SUPERFAN]], + ]) + ); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + vi.clearAllMocks(); + vi.resetAllMocks(); + }); + + it("should have the correct properties", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + + expect(BugTypeSuperfanEncounter.encounterType).toBe(MysteryEncounterType.BUG_TYPE_SUPERFAN); + expect(BugTypeSuperfanEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT); + expect(BugTypeSuperfanEncounter.dialogue).toBeDefined(); + expect(BugTypeSuperfanEncounter.dialogue.intro).toStrictEqual([ + { + text: `${namespace}.intro`, + }, + { + speaker: `${namespace}.speaker`, + text: `${namespace}.intro_dialogue`, + }, + ]); + expect(BugTypeSuperfanEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`); + expect(BugTypeSuperfanEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`); + expect(BugTypeSuperfanEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`); + expect(BugTypeSuperfanEncounter.options.length).toBe(3); + }); + + it("should not run below wave 10", async () => { + game.override.startingWave(9); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.BUG_TYPE_SUPERFAN); + }); + + it("should not run above wave 179", async () => { + game.override.startingWave(181); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle.mysteryEncounter).toBeUndefined(); + }); + + it("should initialize fully", async () => { + initSceneWithoutEncounterPhase(scene, defaultParty); + scene.currentBattle.mysteryEncounter = BugTypeSuperfanEncounter; + + const { onInit } = BugTypeSuperfanEncounter; + + expect(BugTypeSuperfanEncounter.onInit).toBeDefined(); + + BugTypeSuperfanEncounter.populateDialogueTokensFromRequirements(scene); + const onInitResult = onInit!(scene); + const config = BugTypeSuperfanEncounter.enemyPartyConfigs[0]; + + expect(config).toBeDefined(); + expect(config.trainerConfig?.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(config.trainerConfig?.partyTemplates).toBeDefined(); + expect(config.female).toBe(true); + expect(onInitResult).toBe(true); + }); + + describe("Option 1 - Battle the Bug-Type Superfan", () => { + it("should have the correct properties", () => { + const option = BugTypeSuperfanEncounter.options[0]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, + selected: [ + { + speaker: `${namespace}.speaker`, + text: `${namespace}.option.1.selected`, + }, + ], + }); + }); + + it("should start battle against the Bug-Type Superfan with wave 30 party template", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + + const enemyParty = scene.getEnemyParty(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyParty.length).toBe(2); + expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL); + expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE); + }); + + it("should start battle against the Bug-Type Superfan with wave 50 party template", async () => { + game.override.startingWave(43); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + + const enemyParty = scene.getEnemyParty(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyParty.length).toBe(3); + expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL); + expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE); + expect(POOL_1_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true); + }); + + it("should start battle against the Bug-Type Superfan with wave 70 party template", async () => { + game.override.startingWave(61); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + + const enemyParty = scene.getEnemyParty(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyParty.length).toBe(4); + expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL); + expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE); + expect(POOL_1_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true); + expect(POOL_2_POKEMON.includes(enemyParty[3].species.speciesId)).toBe(true); + }); + + it("should start battle against the Bug-Type Superfan with wave 100 party template", async () => { + game.override.startingWave(81); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + + const enemyParty = scene.getEnemyParty(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyParty.length).toBe(5); + expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL); + expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE); + expect(POOL_1_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true); + expect(POOL_2_POKEMON.includes(enemyParty[3].species.speciesId)).toBe(true); + expect(POOL_2_POKEMON.includes(enemyParty[4].species.speciesId)).toBe(true); + }); + + it("should start battle against the Bug-Type Superfan with wave 120 party template", async () => { + game.override.startingWave(111); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + + const enemyParty = scene.getEnemyParty(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyParty.length).toBe(5); + expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL); + expect(enemyParty[0].formIndex).toBe(1); + expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE); + expect(enemyParty[1].formIndex).toBe(1); + expect(POOL_2_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true); + expect(POOL_2_POKEMON.includes(enemyParty[3].species.speciesId)).toBe(true); + expect(POOL_3_POKEMON.some(config => enemyParty[4].species.speciesId === config.species)).toBe(true); + }); + + it("should start battle against the Bug-Type Superfan with wave 140 party template", async () => { + game.override.startingWave(131); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + + const enemyParty = scene.getEnemyParty(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyParty.length).toBe(5); + expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL); + expect(enemyParty[0].formIndex).toBe(1); + expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE); + expect(enemyParty[1].formIndex).toBe(1); + expect(POOL_2_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true); + expect(POOL_3_POKEMON.some(config => enemyParty[3].species.speciesId === config.species)).toBe(true); + expect(POOL_3_POKEMON.some(config => enemyParty[4].species.speciesId === config.species)).toBe(true); + }); + + it("should start battle against the Bug-Type Superfan with wave 160 party template", async () => { + game.override.startingWave(151); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + + const enemyParty = scene.getEnemyParty(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyParty.length).toBe(5); + expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL); + expect(enemyParty[0].formIndex).toBe(1); + expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE); + expect(enemyParty[1].formIndex).toBe(1); + expect(POOL_2_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true); + expect(POOL_3_POKEMON.some(config => enemyParty[3].species.speciesId === config.species)).toBe(true); + expect(POOL_4_POKEMON.includes(enemyParty[4].species.speciesId)).toBe(true); + }); + + it("should start battle against the Bug-Type Superfan with wave 180 party template", async () => { + game.override.startingWave(171); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + + const enemyParty = scene.getEnemyParty(); + expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name); + expect(enemyParty.length).toBe(5); + expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN); + expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL); + expect(enemyParty[0].formIndex).toBe(1); + expect(enemyParty[0].isBoss()).toBe(true); + expect(enemyParty[0].bossSegments).toBe(2); + expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE); + expect(enemyParty[1].formIndex).toBe(1); + expect(enemyParty[1].isBoss()).toBe(true); + expect(enemyParty[1].bossSegments).toBe(2); + expect(POOL_3_POKEMON.some(config => enemyParty[2].species.speciesId === config.species)).toBe(true); + expect(POOL_3_POKEMON.some(config => enemyParty[3].species.speciesId === config.species)).toBe(true); + expect(POOL_4_POKEMON.includes(enemyParty[4].species.speciesId)).toBe(true); + }); + + it("should let the player learn a Bug move after battle ends", async () => { + const selectOptionSpy = vi.spyOn(encounterPhaseUtils, "selectOptionThenPokemon"); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 1, undefined, true); + await skipBattleRunMysteryEncounterRewardsPhase(game, false); + + expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterRewardsPhase.name); + game.phaseInterceptor["prompts"] = []; // Clear out prompt handlers + game.onNextPrompt("MysteryEncounterRewardsPhase", Mode.OPTION_SELECT, () => { + game.phaseInterceptor.superEndPhase(); + }); + await game.phaseInterceptor.run(MysteryEncounterRewardsPhase); + + expect(selectOptionSpy).toHaveBeenCalledTimes(1); + const optionData = selectOptionSpy.mock.calls[0][1]; + expect(PHYSICAL_TUTOR_MOVES.some(move => new PokemonMove(move).getName() === optionData[0].label)).toBe(true); + expect(SPECIAL_TUTOR_MOVES.some(move => new PokemonMove(move).getName() === optionData[1].label)).toBe(true); + expect(STATUS_TUTOR_MOVES.some(move => new PokemonMove(move).getName() === optionData[2].label)).toBe(true); + expect(MISC_TUTOR_MOVES.some(move => new PokemonMove(move).getName() === optionData[3].label)).toBe(true); + }); + }); + + describe("Option 2 - Show off Bug Types", () => { + it("should have the correct properties", () => { + const option = BugTypeSuperfanEncounter.options[1]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip` + }); + }); + + it("should NOT be selectable if the player doesn't have any Bug types", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.ABRA]); + await game.phaseInterceptor.to(MysteryEncounterPhase, false); + + const encounterPhase = scene.getCurrentPhase(); + expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); + const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase; + vi.spyOn(mysteryEncounterPhase, "continueEncounter"); + vi.spyOn(mysteryEncounterPhase, "handleOptionSelect"); + vi.spyOn(scene.ui, "playError"); + + await runSelectMysteryEncounterOption(game, 2); + + expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name); + expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled + expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled(); + expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled(); + }); + + it("should proceed to rewards screen with 0-1 Bug Types reward options", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 2); + + expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); + await game.phaseInterceptor.run(SelectModifierPhase); + + expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); + const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; + expect(modifierSelectHandler.options.length).toEqual(2); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("SUPER_LURE"); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("GREAT_BALL"); + }); + + it("should proceed to rewards screen with 2-3 Bug Types reward options", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL]); + await runMysteryEncounterToEnd(game, 2); + + expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); + await game.phaseInterceptor.run(SelectModifierPhase); + + expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); + const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; + expect(modifierSelectHandler.options.length).toEqual(3); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("QUICK_CLAW"); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("MAX_LURE"); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toBe("ULTRA_BALL"); + }); + + it("should proceed to rewards screen with 4-5 Bug Types reward options", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL, Species.GALVANTULA, Species.VOLCARONA]); + await runMysteryEncounterToEnd(game, 2); + + expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); + await game.phaseInterceptor.run(SelectModifierPhase); + + expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); + const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; + expect(modifierSelectHandler.options.length).toEqual(3); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("GRIP_CLAW"); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("MAX_LURE"); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toBe("ROGUE_BALL"); + }); + + it("should proceed to rewards screen with 6 Bug Types reward options (including form change item)", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL, Species.GALVANTULA, Species.VOLCARONA, Species.ANORITH, Species.GENESECT]); + await runMysteryEncounterToEnd(game, 2); + + expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); + await game.phaseInterceptor.run(SelectModifierPhase); + + expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); + const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; + expect(modifierSelectHandler.options.length).toEqual(3); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("MASTER_BALL"); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("MAX_LURE"); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toBe("FORM_CHANGE_ITEM"); + }); + + it("should leave encounter without battle", async () => { + const leaveEncounterWithoutBattleSpy = vi.spyOn(encounterPhaseUtils, "leaveEncounterWithoutBattle"); + + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty); + await runMysteryEncounterToEnd(game, 2); + + expect(leaveEncounterWithoutBattleSpy).toBeCalled(); + }); + }); + + describe("Option 3 - Give a Bug Item", () => { + it("should have the correct properties", () => { + const option = BugTypeSuperfanEncounter.options[2]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`, + selected: [ + { + text: `${namespace}.option.3.selected`, + }, + { + speaker: `${namespace}.speaker`, + text: `${namespace}.option.3.selected_dialogue`, + }, + ], + secondOptionPrompt: `${namespace}.option.3.select_prompt`, + }); + }); + + 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); + + game.scene.modifiers = []; + const encounterPhase = scene.getCurrentPhase(); + expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name); + const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase; + vi.spyOn(mysteryEncounterPhase, "continueEncounter"); + vi.spyOn(mysteryEncounterPhase, "handleOptionSelect"); + vi.spyOn(scene.ui, "playError"); + + await runSelectMysteryEncounterOption(game, 3); + + expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name); + expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled + expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled(); + expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled(); + }); + + it("should remove the gifted item and proceed to rewards screen", async () => { + game.override.startingHeldItems([{name: "GRIP_CLAW", count: 1}]); + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE]); + + const gripClawCountBefore = scene.findModifier(m => m instanceof ContactHeldItemTransferChanceModifier)?.stackCount ?? 0; + + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); + + expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name); + await game.phaseInterceptor.run(SelectModifierPhase); + + expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); + const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; + expect(modifierSelectHandler.options.length).toEqual(2); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("MYSTERY_ENCOUNTER_GOLDEN_BUG_NET"); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("REVIVER_SEED"); + + const gripClawCountAfter = scene.findModifier(m => m instanceof ContactHeldItemTransferChanceModifier)?.stackCount ?? 0; + expect(gripClawCountBefore - 1).toBe(gripClawCountAfter); + }); + + it("should leave encounter without battle", async () => { + game.override.startingHeldItems([{name: "GRIP_CLAW", count: 1}]); + const leaveEncounterWithoutBattleSpy = vi.spyOn(encounterPhaseUtils, "leaveEncounterWithoutBattle"); + + await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE]); + await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 }); + + expect(leaveEncounterWithoutBattleSpy).toBeCalled(); + }); + }); +}); diff --git a/src/test/mystery-encounter/encounters/clowning-around-encounter.test.ts b/src/test/mystery-encounter/encounters/clowning-around-encounter.test.ts index ebe0a28dd4f..273bb903f15 100644 --- a/src/test/mystery-encounter/encounters/clowning-around-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/clowning-around-encounter.test.ts @@ -8,7 +8,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species"; import * as BattleAnims from "#app/data/battle-anims"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import { Moves } from "#enums/moves"; import BattleScene from "#app/battle-scene"; import Pokemon, { PokemonMove } from "#app/field/pokemon"; @@ -301,7 +301,7 @@ describe("Clowning Around - Mystery Encounter", () => { expect(secondItemsAfter.length).toBe(1); expect(secondItemsAfter[0].type.id).toBe("SOUL_DEW"); expect(secondItemsAfter[0]?.stackCount).toBe(5); - }, 2000000); + }); it("should leave encounter without battle", async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); diff --git a/src/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts b/src/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts index 8e31c6d822d..ac4128e80f9 100644 --- a/src/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/dancing-lessons-encounter.test.ts @@ -4,7 +4,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; diff --git a/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts b/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts index 0fe8e27b44f..44701f71de8 100644 --- a/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts @@ -4,7 +4,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; diff --git a/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts b/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts index 2a050d2d835..e7a019e5d8f 100644 --- a/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts @@ -5,7 +5,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { Mode } from "#app/ui/ui"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; diff --git a/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts b/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts index ccb4e998486..376c05297b7 100644 --- a/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts @@ -9,7 +9,7 @@ import { Gender } from "#app/data/gender"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import * as BattleAnims from "#app/data/battle-anims"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import { Moves } from "#enums/moves"; import BattleScene from "#app/battle-scene"; import { PokemonHeldItemModifier } from "#app/modifier/modifier"; diff --git a/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts b/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts index fe23be61d26..918e8a60c1e 100644 --- a/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts @@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import { Moves } from "#enums/moves"; import BattleScene from "#app/battle-scene"; import { PokemonMove } from "#app/field/pokemon"; diff --git a/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts b/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts index f77d9962f01..f2ea020ca88 100644 --- a/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts @@ -8,7 +8,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "../encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "../encounter-test-utils"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; diff --git a/src/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts b/src/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts index ad596078738..996149046b1 100644 --- a/src/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/mysterious-challengers-encounter.test.ts @@ -5,7 +5,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { Mode } from "#app/ui/ui"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; diff --git a/src/test/mystery-encounter/encounters/part-timer-encounter.test.ts b/src/test/mystery-encounter/encounters/part-timer-encounter.test.ts index 4eb44af5f24..f73c1f437d0 100644 --- a/src/test/mystery-encounter/encounters/part-timer-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/part-timer-encounter.test.ts @@ -5,7 +5,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { CIVILIZATION_ENCOUNTER_BIOMES } from "#app/data/mystery-encounters/mystery-encounters"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; diff --git a/src/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts b/src/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts index f4a3b41bf1d..9d7f1655c93 100644 --- a/src/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/teleporting-hijinks-encounter.test.ts @@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; @@ -151,7 +151,6 @@ 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); - scene.getParty().forEach(p => p.moveset = []); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.getCurrentPhase(); diff --git a/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts b/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts index 7dcf10669d6..35fbd0b51af 100644 --- a/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts @@ -5,7 +5,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { PlayerPokemon } from "#app/field/pokemon"; import { HUMAN_TRANSITABLE_BIOMES } from "#app/data/mystery-encounters/mystery-encounters"; diff --git a/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts b/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts index 41554cf10de..a8405ebfbfb 100644 --- a/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts @@ -7,7 +7,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite import { getPokemonSpecies } from "#app/data/pokemon-species"; import * as BattleAnims from "#app/data/battle-anims"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import { Moves } from "#enums/moves"; import BattleScene from "#app/battle-scene"; import { TheStrongStuffEncounter } from "#app/data/mystery-encounters/encounters/the-strong-stuff-encounter"; @@ -164,9 +164,10 @@ describe("The Strong Stuff - Mystery Encounter", () => { return baseStats.reduce((a, b) => a + b); }); - expect(bstsAfter[0]).toEqual(bstsPrior[0] - 20 * 6); - expect(bstsAfter[1]).toEqual(bstsPrior[1] + 10 * 6); - expect(bstsAfter[2]).toEqual(bstsPrior[2] + 10 * 6); + // HP stat changes are halved compared to other values + expect(bstsAfter[0]).toEqual(bstsPrior[0] - 20 * 5 - 10); + expect(bstsAfter[1]).toEqual(bstsPrior[1] + 10 * 5 + 5); + expect(bstsAfter[2]).toEqual(bstsPrior[2] + 10 * 5 + 5); }); it("should leave encounter without battle", async () => { diff --git a/src/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts b/src/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts index e322c63b3c9..e21bb08f165 100644 --- a/src/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-winstrate-challenge-encounter.test.ts @@ -5,7 +5,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { Mode } from "#app/ui/ui"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; diff --git a/src/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts b/src/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts index 319a5daa38b..a4bfaea659a 100644 --- a/src/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts @@ -7,7 +7,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite import { getPokemonSpecies } from "#app/data/pokemon-species"; import * as BattleAnims from "#app/data/battle-anims"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils"; import { Moves } from "#enums/moves"; import BattleScene from "#app/battle-scene"; import { PokemonMove } from "#app/field/pokemon"; diff --git a/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts b/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts index 99c4b2fdb13..635dac0eaee 100644 --- a/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts @@ -5,7 +5,7 @@ import { Species } from "#app/enums/species"; import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils"; import BattleScene from "#app/battle-scene"; import { Mode } from "#app/ui/ui"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; diff --git a/src/ui/mystery-encounter-ui-handler.ts b/src/ui/mystery-encounter-ui-handler.ts index 094b8264bb1..a93167c8a96 100644 --- a/src/ui/mystery-encounter-ui-handler.ts +++ b/src/ui/mystery-encounter-ui-handler.ts @@ -554,7 +554,7 @@ export default class MysteryEncounterUiHandler extends UiHandler { duration: 750, onComplete: () => { this.dexProgressContainer.on("pointerover", () => { - (this.scene as BattleScene).ui.showTooltip("", i18next.t("mysteryEncounter:affects_pokedex"), true); + (this.scene as BattleScene).ui.showTooltip("", i18next.t("mysteryEncounterMessages:affects_pokedex"), true); }); this.dexProgressContainer.on("pointerout", () => { (this.scene as BattleScene).ui.hideTooltip();