diff --git a/src/data/mystery-encounters/dialogue/dark-deal-dialogue.ts b/src/data/mystery-encounters/dialogue/dark-deal-dialogue.ts deleted file mode 100644 index 9ee7ce5472b..00000000000 --- a/src/data/mystery-encounters/dialogue/dark-deal-dialogue.ts +++ /dev/null @@ -1,48 +0,0 @@ -import MysteryEncounterDialogue from "#app/data/mystery-encounters/mystery-encounter-dialogue"; - -export const DarkDealDialogue: MysteryEncounterDialogue = { - // intro: [ - // { - // text: "mysteryEncounter:dark_deal_intro_message" - // }, - // { - // speaker: "mysteryEncounter:dark_deal_speaker", - // text: "mysteryEncounter:dark_deal_intro_dialogue" - // } - // ], - encounterOptionsDialogue: { - title: "mysteryEncounter:dark_deal_title", - description: "mysteryEncounter:dark_deal_description", - query: "mysteryEncounter:dark_deal_query", - // options: [ - // { - // buttonLabel: "mysteryEncounter:dark_deal_option_1_label", - // buttonTooltip: "mysteryEncounter:dark_deal_option_1_tooltip", - // selected: [ - // { - // speaker: "mysteryEncounter:dark_deal_speaker", - // text: "mysteryEncounter:dark_deal_option_1_selected" - // }, - // { - // text: "mysteryEncounter:dark_deal_option_1_selected_message" - // } - // ] - // }, - // { - // buttonLabel: "mysteryEncounter:dark_deal_option_2_label", - // buttonTooltip: "mysteryEncounter:dark_deal_option_2_tooltip", - // selected: [ - // { - // speaker: "mysteryEncounter:dark_deal_speaker", - // text: "mysteryEncounter:dark_deal_option_2_selected" - // } - // ] - // } - // ] - }, - outro: [ - { - text: "mysteryEncounter:dark_deal_outro" - } - ] -}; diff --git a/src/data/mystery-encounters/encounters/dark-deal.ts b/src/data/mystery-encounters/encounters/dark-deal.ts index c1651aa8dec..740c4e86c28 100644 --- a/src/data/mystery-encounters/encounters/dark-deal.ts +++ b/src/data/mystery-encounters/encounters/dark-deal.ts @@ -98,6 +98,9 @@ export const DarkDealEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(30, 180) // waves 30 to 180 .withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party .withCatchAllowed(true) + .withTitle("mysteryEncounter:dark_deal_title") + .withDescription("mysteryEncounter:dark_deal_description") + .withQuery("mysteryEncounter:dark_deal_query") .withOption( new MysteryEncounterOptionBuilder() .withDialogue({ @@ -175,24 +178,27 @@ export const DarkDealEncounter: MysteryEncounter = }) .build() ) - .withOption( - new MysteryEncounterOptionBuilder() - .withDialogue({ - buttonLabel: "mysteryEncounter:dark_deal_option_2_label", - buttonTooltip: "mysteryEncounter:dark_deal_option_2_tooltip", - selected: [ - { - speaker: "mysteryEncounter:dark_deal_speaker", - text: "mysteryEncounter:dark_deal_option_2_selected", - }, - ], - }) - .withOptionPhase(async (scene: BattleScene) => { - // Leave encounter with no rewards or exp + .withSimpleOption( + { + buttonLabel: "mysteryEncounter:dark_deal_option_2_label", + buttonTooltip: "mysteryEncounter:dark_deal_option_2_tooltip", + selected: [ + { + speaker: "mysteryEncounter:dark_deal_speaker", + text: "mysteryEncounter:dark_deal_option_2_selected", + }, + ], + }, + async (scene: BattleScene) => { + // Leave encounter with no rewards or exp - leaveEncounterWithoutBattle(scene, true); - return true; - }) - .build() + leaveEncounterWithoutBattle(scene, true); + return true; + } ) + .withOutroDialogue([ + { + text: "mysteryEncounter:dark_deal_outro" + } + ]) .build(); diff --git a/src/data/mystery-encounters/encounters/department-store-sale.ts b/src/data/mystery-encounters/encounters/department-store-sale.ts index 19269a774f3..4323fc15434 100644 --- a/src/data/mystery-encounters/encounters/department-store-sale.ts +++ b/src/data/mystery-encounters/encounters/department-store-sale.ts @@ -29,7 +29,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu ]) // .withHideIntroVisuals(false) .withSceneWaveRangeRequirement(10, 100) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Choose TMs const modifiers = []; let i = 0; @@ -49,7 +49,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false }); leaveEncounterWithoutBattle(scene); }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Choose Vitamins const modifiers = []; let i = 0; @@ -67,7 +67,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false }); leaveEncounterWithoutBattle(scene); }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Choose X Items const modifiers = []; let i = 0; @@ -85,7 +85,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false }); leaveEncounterWithoutBattle(scene); }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Choose Pokeballs const modifiers = []; let i = 0; diff --git a/src/data/mystery-encounters/encounters/fight-or-flight.ts b/src/data/mystery-encounters/encounters/fight-or-flight.ts index 8a82439772c..2a362eaed37 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight.ts @@ -83,7 +83,7 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder return true; }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Pick battle const item = scene.currentBattle.mysteryEncounter.misc as ModifierTypeOption; setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false }); @@ -127,7 +127,7 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder } }) .build()) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Leave encounter with no rewards or exp leaveEncounterWithoutBattle(scene, true); return true; diff --git a/src/data/mystery-encounters/encounters/mysterious-challengers.ts b/src/data/mystery-encounters/encounters/mysterious-challengers.ts index 880c7be4ca2..db794c58e9f 100644 --- a/src/data/mystery-encounters/encounters/mysterious-challengers.ts +++ b/src/data/mystery-encounters/encounters/mysterious-challengers.ts @@ -95,7 +95,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter return true; }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; // Spawn standard trainer battle with memory mushroom reward const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0]; @@ -109,7 +109,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter }, scene.currentBattle.waveIndex * 10); return ret; }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; // Spawn hard fight with ULTRA/GREAT reward (can improve with luck) const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1]; @@ -123,7 +123,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter }, scene.currentBattle.waveIndex * 100); return ret; }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; // Spawn brutal fight with ROGUE/ULTRA/GREAT reward (can improve with luck) const config: EnemyPartyConfig = encounter.enemyPartyConfigs[2]; diff --git a/src/data/mystery-encounters/encounters/mysterious-chest.ts b/src/data/mystery-encounters/encounters/mysterious-chest.ts index 5e572131562..69ae93f312f 100644 --- a/src/data/mystery-encounters/encounters/mysterious-chest.ts +++ b/src/data/mystery-encounters/encounters/mysterious-chest.ts @@ -85,7 +85,7 @@ export const MysteriousChestEncounter: MysteryEncounter = MysteryEncounterBuilde }) .build() ) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Leave encounter with no rewards or exp leaveEncounterWithoutBattle(scene, true); return true; diff --git a/src/data/mystery-encounters/encounters/shady-vitamin-dealer.ts b/src/data/mystery-encounters/encounters/shady-vitamin-dealer.ts index 21e1b199e04..6ab668d73a6 100644 --- a/src/data/mystery-encounters/encounters/shady-vitamin-dealer.ts +++ b/src/data/mystery-encounters/encounters/shady-vitamin-dealer.ts @@ -186,7 +186,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBui chosenPokemon.updateInfo(); }) .build()) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Leave encounter with no rewards or exp leaveEncounterWithoutBattle(scene, true); return true; diff --git a/src/data/mystery-encounters/encounters/sleeping-snorlax.ts b/src/data/mystery-encounters/encounters/sleeping-snorlax.ts index 444ce5a6581..6a820812ae1 100644 --- a/src/data/mystery-encounters/encounters/sleeping-snorlax.ts +++ b/src/data/mystery-encounters/encounters/sleeping-snorlax.ts @@ -55,13 +55,13 @@ export const SleepingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuilde encounter.enemyPartyConfigs = [config]; return true; }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { // Pick battle // TODO: do we want special rewards for this? // setCustomEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: true}); await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]); }) - .withOptionPhase(async (scene: BattleScene) => { + .withSimpleOption(async (scene: BattleScene) => { const instance = scene.currentBattle.mysteryEncounter; let roll: integer; scene.executeWithSeedOffset(() => { diff --git a/src/data/mystery-encounters/mystery-encounter-dialogue.ts b/src/data/mystery-encounters/mystery-encounter-dialogue.ts index c0eb3fdfec7..11135a58085 100644 --- a/src/data/mystery-encounters/mystery-encounter-dialogue.ts +++ b/src/data/mystery-encounters/mystery-encounter-dialogue.ts @@ -1,7 +1,6 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteriousChallengersDialogue } from "#app/data/mystery-encounters/dialogue/mysterious-challengers-dialogue"; import { MysteriousChestDialogue } from "#app/data/mystery-encounters/dialogue/mysterious-chest-dialogue"; -import { DarkDealDialogue } from "#app/data/mystery-encounters/dialogue/dark-deal-dialogue"; import { FightOrFlightDialogue } from "#app/data/mystery-encounters/dialogue/fight-or-flight-dialogue"; import { TrainingSessionDialogue } from "#app/data/mystery-encounters/dialogue/training-session-dialogue"; import { SleepingSnorlaxDialogue } from "./dialogue/sleeping-snorlax-dialogue"; @@ -26,15 +25,15 @@ export class OptionTextDisplay { } export class EncounterOptionsDialogue { - title: TemplateStringsArray | `mysteryEncounter:${string}`; - description: TemplateStringsArray | `mysteryEncounter:${string}`; + title?: TemplateStringsArray | `mysteryEncounter:${string}`; + description?: TemplateStringsArray | `mysteryEncounter:${string}`; query?: TemplateStringsArray | `mysteryEncounter:${string}`; options?: [...OptionTextDisplay[]]; // Options array with minimum 2 options } export default class MysteryEncounterDialogue { intro?: TextDisplay[]; - encounterOptionsDialogue: EncounterOptionsDialogue; + encounterOptionsDialogue?: EncounterOptionsDialogue; outro?: TextDisplay[]; } @@ -87,7 +86,6 @@ export const allMysteryEncounterDialogue: { [encounterType: number]: MysteryEnco export function initMysteryEncounterDialogue() { allMysteryEncounterDialogue[MysteryEncounterType.MYSTERIOUS_CHALLENGERS] = MysteriousChallengersDialogue; allMysteryEncounterDialogue[MysteryEncounterType.MYSTERIOUS_CHEST] = MysteriousChestDialogue; - allMysteryEncounterDialogue[MysteryEncounterType.DARK_DEAL] = DarkDealDialogue; allMysteryEncounterDialogue[MysteryEncounterType.FIGHT_OR_FLIGHT] = FightOrFlightDialogue; allMysteryEncounterDialogue[MysteryEncounterType.TRAINING_SESSION] = TrainingSessionDialogue; allMysteryEncounterDialogue[MysteryEncounterType.SLEEPING_SNORLAX] = SleepingSnorlaxDialogue; diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index 6c8c0b4381d..0780aa33ae4 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -7,7 +7,8 @@ import MysteryEncounterIntroVisuals, { MysteryEncounterSpriteConfig } from "../. import * as Utils from "../../utils"; import { StatusEffect } from "../status-effect"; import MysteryEncounterDialogue, { - allMysteryEncounterDialogue + allMysteryEncounterDialogue, + OptionTextDisplay } from "./mystery-encounter-dialogue"; import MysteryEncounterOption, { MysteryEncounterOptionBuilder, OptionPhaseCallback } from "./mystery-encounter-option"; import { @@ -136,9 +137,7 @@ export default class MysteryEncounter implements MysteryEncounter { Object.assign(this, encounter); } this.encounterTier = this.encounterTier ? this.encounterTier : MysteryEncounterTier.COMMON; - this.dialogue = Object.assign((this.dialogue ?? {}), allMysteryEncounterDialogue[this.encounterType]); - // this.dialogue = allMysteryEncounterDialogue[this.encounterType]; - console.log(`${MysteryEncounterType[encounter.encounterType]} Encounter Dialogue:`, this.dialogue); + this.dialogue = Object.assign((this.dialogue ?? {}), allMysteryEncounterDialogue[this.encounterType] ?? {}); this.encounterVariant = MysteryEncounterVariant.DEFAULT; this.requirements = this.requirements ? this.requirements : []; this.hideBattleIntroMessage = !isNullOrUndefined(this.hideBattleIntroMessage) ? this.hideBattleIntroMessage : false; @@ -399,11 +398,12 @@ export class MysteryEncounterBuilder implements Partial { * Adds a streamlined option phase. * Only use if no pre-/post-options or condtions necessary. * - * @param callback - OptionPhaseCallback + * @param dialogue - {@linkcode OptionTextDisplay} + * @param callback - {@linkcode OptionPhaseCallback} * @returns */ - withOptionPhase(callback: OptionPhaseCallback) { - return this.withOption(new MysteryEncounterOptionBuilder().withOptionPhase(callback).build()); + withSimpleOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback) { + return this.withOption(new MysteryEncounterOptionBuilder().withDialogue(dialogue).withOptionPhase(callback).build()); } /** @@ -413,12 +413,10 @@ export class MysteryEncounterBuilder implements Partial { * @returns */ withIntroSpriteConfigs(spriteConfigs: MysteryEncounterSpriteConfig[]): this & Pick { - console.debug("with intro sprite configs: ", spriteConfigs); return Object.assign(this, { spriteConfigs: spriteConfigs }); } - withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []): this { - console.debug("with intro dialogue: ", dialogue); + withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []) { this.dialogue = {...this.dialogue, intro: dialogue }; return this; } @@ -581,6 +579,56 @@ export class MysteryEncounterBuilder implements Partial { return Object.assign(this, { hideIntroVisuals: hideIntroVisuals }); } + withTitle(title: TemplateStringsArray | `mysteryEncounter:${string}`) { + const dialogue = this.dialogue ?? {}; + const encounterOptionsDialogue = this.dialogue?.encounterOptionsDialogue ?? {}; + + this.dialogue = { + ...dialogue, + encounterOptionsDialogue: { + ...encounterOptionsDialogue, + title, + } + }; + + return this; + } + + withDescription(description: TemplateStringsArray | `mysteryEncounter:${string}`) { + const dialogue = this.dialogue ?? {}; + const encounterOptionsDialogue = this.dialogue?.encounterOptionsDialogue ?? {}; + + this.dialogue = { + ...dialogue, + encounterOptionsDialogue: { + ...encounterOptionsDialogue, + description, + } + }; + + return this; + } + + withQuery(query: TemplateStringsArray | `mysteryEncounter:${string}`) { + const dialogue = this.dialogue ?? {}; + const encounterOptionsDialogue = this.dialogue?.encounterOptionsDialogue ?? {}; + + this.dialogue = { + ...dialogue, + encounterOptionsDialogue: { + ...encounterOptionsDialogue, + query, + } + }; + + return this; + } + + withOutroDialogue(dialogue: MysteryEncounterDialogue["outro"] = []) { + this.dialogue = {...this.dialogue, outro: dialogue }; + return this; + } + build(this: MysteryEncounter) { return new MysteryEncounter(this); } diff --git a/src/ui/mystery-encounter-ui-handler.ts b/src/ui/mystery-encounter-ui-handler.ts index 5c0ceac4964..c446481b744 100644 --- a/src/ui/mystery-encounter-ui-handler.ts +++ b/src/ui/mystery-encounter-ui-handler.ts @@ -424,12 +424,13 @@ export default class MysteryEncounterUiHandler extends UiHandler { } const mysteryEncounter = this.scene.currentBattle.mysteryEncounter; - let text; - const option = mysteryEncounter.dialogue.encounterOptionsDialogue.options[cursor]; - if (!this.optionsMeetsReqs[cursor] && this.filteredEncounterOptions[cursor].isDisabledOnRequirementsNotMet && option.disabledTooltip) { - text = getEncounterText(this.scene, option.disabledTooltip, TextStyle.TOOLTIP_CONTENT); + let text: string; + const option = this.filteredEncounterOptions[cursor]; + const optionDialogue = option.dialogue ?? mysteryEncounter.dialogue.encounterOptionsDialogue.options[cursor]; + if (!this.optionsMeetsReqs[cursor] && this.filteredEncounterOptions[cursor].isDisabledOnRequirementsNotMet && optionDialogue.disabledTooltip) { + text = getEncounterText(this.scene, optionDialogue.disabledTooltip, TextStyle.TOOLTIP_CONTENT); } else { - text = getEncounterText(this.scene, option.buttonTooltip, TextStyle.TOOLTIP_CONTENT); + text = getEncounterText(this.scene, optionDialogue.buttonTooltip, TextStyle.TOOLTIP_CONTENT); } // Auto-color options green/blue for good/bad by looking for (+)/(-)