migrate dark-deal encounter to new dialogue setup

This commit is contained in:
Felix Staud 2024-07-11 13:26:21 -07:00
parent 37248f1885
commit c589689a6c
11 changed files with 104 additions and 99 deletions

View File

@ -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"
}
]
};

View File

@ -98,6 +98,9 @@ export const DarkDealEncounter: MysteryEncounter =
.withSceneWaveRangeRequirement(30, 180) // waves 30 to 180 .withSceneWaveRangeRequirement(30, 180) // waves 30 to 180
.withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party .withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party
.withCatchAllowed(true) .withCatchAllowed(true)
.withTitle("mysteryEncounter:dark_deal_title")
.withDescription("mysteryEncounter:dark_deal_description")
.withQuery("mysteryEncounter:dark_deal_query")
.withOption( .withOption(
new MysteryEncounterOptionBuilder() new MysteryEncounterOptionBuilder()
.withDialogue({ .withDialogue({
@ -175,9 +178,8 @@ export const DarkDealEncounter: MysteryEncounter =
}) })
.build() .build()
) )
.withOption( .withSimpleOption(
new MysteryEncounterOptionBuilder() {
.withDialogue({
buttonLabel: "mysteryEncounter:dark_deal_option_2_label", buttonLabel: "mysteryEncounter:dark_deal_option_2_label",
buttonTooltip: "mysteryEncounter:dark_deal_option_2_tooltip", buttonTooltip: "mysteryEncounter:dark_deal_option_2_tooltip",
selected: [ selected: [
@ -186,13 +188,17 @@ export const DarkDealEncounter: MysteryEncounter =
text: "mysteryEncounter:dark_deal_option_2_selected", text: "mysteryEncounter:dark_deal_option_2_selected",
}, },
], ],
}) },
.withOptionPhase(async (scene: BattleScene) => { async (scene: BattleScene) => {
// Leave encounter with no rewards or exp // Leave encounter with no rewards or exp
leaveEncounterWithoutBattle(scene, true); leaveEncounterWithoutBattle(scene, true);
return true; return true;
}) }
.build()
) )
.withOutroDialogue([
{
text: "mysteryEncounter:dark_deal_outro"
}
])
.build(); .build();

View File

@ -29,7 +29,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
]) ])
// .withHideIntroVisuals(false) // .withHideIntroVisuals(false)
.withSceneWaveRangeRequirement(10, 100) .withSceneWaveRangeRequirement(10, 100)
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Choose TMs // Choose TMs
const modifiers = []; const modifiers = [];
let i = 0; let i = 0;
@ -49,7 +49,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false }); setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false });
leaveEncounterWithoutBattle(scene); leaveEncounterWithoutBattle(scene);
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Choose Vitamins // Choose Vitamins
const modifiers = []; const modifiers = [];
let i = 0; let i = 0;
@ -67,7 +67,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false }); setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false });
leaveEncounterWithoutBattle(scene); leaveEncounterWithoutBattle(scene);
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Choose X Items // Choose X Items
const modifiers = []; const modifiers = [];
let i = 0; let i = 0;
@ -85,7 +85,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false }); setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false });
leaveEncounterWithoutBattle(scene); leaveEncounterWithoutBattle(scene);
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Choose Pokeballs // Choose Pokeballs
const modifiers = []; const modifiers = [];
let i = 0; let i = 0;

View File

@ -83,7 +83,7 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder
return true; return true;
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Pick battle // Pick battle
const item = scene.currentBattle.mysteryEncounter.misc as ModifierTypeOption; const item = scene.currentBattle.mysteryEncounter.misc as ModifierTypeOption;
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false }); setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
@ -127,7 +127,7 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder
} }
}) })
.build()) .build())
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Leave encounter with no rewards or exp // Leave encounter with no rewards or exp
leaveEncounterWithoutBattle(scene, true); leaveEncounterWithoutBattle(scene, true);
return true; return true;

View File

@ -95,7 +95,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
return true; return true;
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
const encounter = scene.currentBattle.mysteryEncounter; const encounter = scene.currentBattle.mysteryEncounter;
// Spawn standard trainer battle with memory mushroom reward // Spawn standard trainer battle with memory mushroom reward
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0]; const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
@ -109,7 +109,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
}, scene.currentBattle.waveIndex * 10); }, scene.currentBattle.waveIndex * 10);
return ret; return ret;
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
const encounter = scene.currentBattle.mysteryEncounter; const encounter = scene.currentBattle.mysteryEncounter;
// Spawn hard fight with ULTRA/GREAT reward (can improve with luck) // Spawn hard fight with ULTRA/GREAT reward (can improve with luck)
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1]; const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
@ -123,7 +123,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
}, scene.currentBattle.waveIndex * 100); }, scene.currentBattle.waveIndex * 100);
return ret; return ret;
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
const encounter = scene.currentBattle.mysteryEncounter; const encounter = scene.currentBattle.mysteryEncounter;
// Spawn brutal fight with ROGUE/ULTRA/GREAT reward (can improve with luck) // Spawn brutal fight with ROGUE/ULTRA/GREAT reward (can improve with luck)
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[2]; const config: EnemyPartyConfig = encounter.enemyPartyConfigs[2];

View File

@ -85,7 +85,7 @@ export const MysteriousChestEncounter: MysteryEncounter = MysteryEncounterBuilde
}) })
.build() .build()
) )
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Leave encounter with no rewards or exp // Leave encounter with no rewards or exp
leaveEncounterWithoutBattle(scene, true); leaveEncounterWithoutBattle(scene, true);
return true; return true;

View File

@ -186,7 +186,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBui
chosenPokemon.updateInfo(); chosenPokemon.updateInfo();
}) })
.build()) .build())
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Leave encounter with no rewards or exp // Leave encounter with no rewards or exp
leaveEncounterWithoutBattle(scene, true); leaveEncounterWithoutBattle(scene, true);
return true; return true;

View File

@ -55,13 +55,13 @@ export const SleepingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuilde
encounter.enemyPartyConfigs = [config]; encounter.enemyPartyConfigs = [config];
return true; return true;
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
// Pick battle // Pick battle
// TODO: do we want special rewards for this? // TODO: do we want special rewards for this?
// setCustomEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: true}); // setCustomEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: true});
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]); await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]);
}) })
.withOptionPhase(async (scene: BattleScene) => { .withSimpleOption(async (scene: BattleScene) => {
const instance = scene.currentBattle.mysteryEncounter; const instance = scene.currentBattle.mysteryEncounter;
let roll: integer; let roll: integer;
scene.executeWithSeedOffset(() => { scene.executeWithSeedOffset(() => {

View File

@ -1,7 +1,6 @@
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { MysteriousChallengersDialogue } from "#app/data/mystery-encounters/dialogue/mysterious-challengers-dialogue"; import { MysteriousChallengersDialogue } from "#app/data/mystery-encounters/dialogue/mysterious-challengers-dialogue";
import { MysteriousChestDialogue } from "#app/data/mystery-encounters/dialogue/mysterious-chest-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 { FightOrFlightDialogue } from "#app/data/mystery-encounters/dialogue/fight-or-flight-dialogue";
import { TrainingSessionDialogue } from "#app/data/mystery-encounters/dialogue/training-session-dialogue"; import { TrainingSessionDialogue } from "#app/data/mystery-encounters/dialogue/training-session-dialogue";
import { SleepingSnorlaxDialogue } from "./dialogue/sleeping-snorlax-dialogue"; import { SleepingSnorlaxDialogue } from "./dialogue/sleeping-snorlax-dialogue";
@ -26,15 +25,15 @@ export class OptionTextDisplay {
} }
export class EncounterOptionsDialogue { export class EncounterOptionsDialogue {
title: TemplateStringsArray | `mysteryEncounter:${string}`; title?: TemplateStringsArray | `mysteryEncounter:${string}`;
description: TemplateStringsArray | `mysteryEncounter:${string}`; description?: TemplateStringsArray | `mysteryEncounter:${string}`;
query?: TemplateStringsArray | `mysteryEncounter:${string}`; query?: TemplateStringsArray | `mysteryEncounter:${string}`;
options?: [...OptionTextDisplay[]]; // Options array with minimum 2 options options?: [...OptionTextDisplay[]]; // Options array with minimum 2 options
} }
export default class MysteryEncounterDialogue { export default class MysteryEncounterDialogue {
intro?: TextDisplay[]; intro?: TextDisplay[];
encounterOptionsDialogue: EncounterOptionsDialogue; encounterOptionsDialogue?: EncounterOptionsDialogue;
outro?: TextDisplay[]; outro?: TextDisplay[];
} }
@ -87,7 +86,6 @@ export const allMysteryEncounterDialogue: { [encounterType: number]: MysteryEnco
export function initMysteryEncounterDialogue() { export function initMysteryEncounterDialogue() {
allMysteryEncounterDialogue[MysteryEncounterType.MYSTERIOUS_CHALLENGERS] = MysteriousChallengersDialogue; allMysteryEncounterDialogue[MysteryEncounterType.MYSTERIOUS_CHALLENGERS] = MysteriousChallengersDialogue;
allMysteryEncounterDialogue[MysteryEncounterType.MYSTERIOUS_CHEST] = MysteriousChestDialogue; allMysteryEncounterDialogue[MysteryEncounterType.MYSTERIOUS_CHEST] = MysteriousChestDialogue;
allMysteryEncounterDialogue[MysteryEncounterType.DARK_DEAL] = DarkDealDialogue;
allMysteryEncounterDialogue[MysteryEncounterType.FIGHT_OR_FLIGHT] = FightOrFlightDialogue; allMysteryEncounterDialogue[MysteryEncounterType.FIGHT_OR_FLIGHT] = FightOrFlightDialogue;
allMysteryEncounterDialogue[MysteryEncounterType.TRAINING_SESSION] = TrainingSessionDialogue; allMysteryEncounterDialogue[MysteryEncounterType.TRAINING_SESSION] = TrainingSessionDialogue;
allMysteryEncounterDialogue[MysteryEncounterType.SLEEPING_SNORLAX] = SleepingSnorlaxDialogue; allMysteryEncounterDialogue[MysteryEncounterType.SLEEPING_SNORLAX] = SleepingSnorlaxDialogue;

View File

@ -7,7 +7,8 @@ import MysteryEncounterIntroVisuals, { MysteryEncounterSpriteConfig } from "../.
import * as Utils from "../../utils"; import * as Utils from "../../utils";
import { StatusEffect } from "../status-effect"; import { StatusEffect } from "../status-effect";
import MysteryEncounterDialogue, { import MysteryEncounterDialogue, {
allMysteryEncounterDialogue allMysteryEncounterDialogue,
OptionTextDisplay
} from "./mystery-encounter-dialogue"; } from "./mystery-encounter-dialogue";
import MysteryEncounterOption, { MysteryEncounterOptionBuilder, OptionPhaseCallback } from "./mystery-encounter-option"; import MysteryEncounterOption, { MysteryEncounterOptionBuilder, OptionPhaseCallback } from "./mystery-encounter-option";
import { import {
@ -136,9 +137,7 @@ export default class MysteryEncounter implements MysteryEncounter {
Object.assign(this, encounter); Object.assign(this, encounter);
} }
this.encounterTier = this.encounterTier ? this.encounterTier : MysteryEncounterTier.COMMON; this.encounterTier = this.encounterTier ? this.encounterTier : MysteryEncounterTier.COMMON;
this.dialogue = Object.assign((this.dialogue ?? {}), allMysteryEncounterDialogue[this.encounterType]); this.dialogue = Object.assign((this.dialogue ?? {}), allMysteryEncounterDialogue[this.encounterType] ?? {});
// this.dialogue = allMysteryEncounterDialogue[this.encounterType];
console.log(`${MysteryEncounterType[encounter.encounterType]} Encounter Dialogue:`, this.dialogue);
this.encounterVariant = MysteryEncounterVariant.DEFAULT; this.encounterVariant = MysteryEncounterVariant.DEFAULT;
this.requirements = this.requirements ? this.requirements : []; this.requirements = this.requirements ? this.requirements : [];
this.hideBattleIntroMessage = !isNullOrUndefined(this.hideBattleIntroMessage) ? this.hideBattleIntroMessage : false; this.hideBattleIntroMessage = !isNullOrUndefined(this.hideBattleIntroMessage) ? this.hideBattleIntroMessage : false;
@ -399,11 +398,12 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
* Adds a streamlined option phase. * Adds a streamlined option phase.
* Only use if no pre-/post-options or condtions necessary. * Only use if no pre-/post-options or condtions necessary.
* *
* @param callback - OptionPhaseCallback * @param dialogue - {@linkcode OptionTextDisplay}
* @param callback - {@linkcode OptionPhaseCallback}
* @returns * @returns
*/ */
withOptionPhase(callback: OptionPhaseCallback) { withSimpleOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback) {
return this.withOption(new MysteryEncounterOptionBuilder().withOptionPhase(callback).build()); return this.withOption(new MysteryEncounterOptionBuilder().withDialogue(dialogue).withOptionPhase(callback).build());
} }
/** /**
@ -413,12 +413,10 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
* @returns * @returns
*/ */
withIntroSpriteConfigs(spriteConfigs: MysteryEncounterSpriteConfig[]): this & Pick<MysteryEncounter, "spriteConfigs"> { withIntroSpriteConfigs(spriteConfigs: MysteryEncounterSpriteConfig[]): this & Pick<MysteryEncounter, "spriteConfigs"> {
console.debug("with intro sprite configs: ", spriteConfigs);
return Object.assign(this, { spriteConfigs: spriteConfigs }); return Object.assign(this, { spriteConfigs: spriteConfigs });
} }
withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []): this { withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []) {
console.debug("with intro dialogue: ", dialogue);
this.dialogue = {...this.dialogue, intro: dialogue }; this.dialogue = {...this.dialogue, intro: dialogue };
return this; return this;
} }
@ -581,6 +579,56 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
return Object.assign(this, { hideIntroVisuals: hideIntroVisuals }); 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) { build(this: MysteryEncounter) {
return new MysteryEncounter(this); return new MysteryEncounter(this);
} }

View File

@ -424,12 +424,13 @@ export default class MysteryEncounterUiHandler extends UiHandler {
} }
const mysteryEncounter = this.scene.currentBattle.mysteryEncounter; const mysteryEncounter = this.scene.currentBattle.mysteryEncounter;
let text; let text: string;
const option = mysteryEncounter.dialogue.encounterOptionsDialogue.options[cursor]; const option = this.filteredEncounterOptions[cursor];
if (!this.optionsMeetsReqs[cursor] && this.filteredEncounterOptions[cursor].isDisabledOnRequirementsNotMet && option.disabledTooltip) { const optionDialogue = option.dialogue ?? mysteryEncounter.dialogue.encounterOptionsDialogue.options[cursor];
text = getEncounterText(this.scene, option.disabledTooltip, TextStyle.TOOLTIP_CONTENT); if (!this.optionsMeetsReqs[cursor] && this.filteredEncounterOptions[cursor].isDisabledOnRequirementsNotMet && optionDialogue.disabledTooltip) {
text = getEncounterText(this.scene, optionDialogue.disabledTooltip, TextStyle.TOOLTIP_CONTENT);
} else { } 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 (+)/(-) // Auto-color options green/blue for good/bad by looking for (+)/(-)