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
.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,9 +178,8 @@ export const DarkDealEncounter: MysteryEncounter =
})
.build()
)
.withOption(
new MysteryEncounterOptionBuilder()
.withDialogue({
.withSimpleOption(
{
buttonLabel: "mysteryEncounter:dark_deal_option_2_label",
buttonTooltip: "mysteryEncounter:dark_deal_option_2_tooltip",
selected: [
@ -186,13 +188,17 @@ export const DarkDealEncounter: MysteryEncounter =
text: "mysteryEncounter:dark_deal_option_2_selected",
},
],
})
.withOptionPhase(async (scene: BattleScene) => {
},
async (scene: BattleScene) => {
// Leave encounter with no rewards or exp
leaveEncounterWithoutBattle(scene, true);
return true;
})
.build()
}
)
.withOutroDialogue([
{
text: "mysteryEncounter:dark_deal_outro"
}
])
.build();

View File

@ -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;

View File

@ -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;

View File

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

View File

@ -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;

View File

@ -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;

View File

@ -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(() => {

View File

@ -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;

View File

@ -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<MysteryEncounter> {
* 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<MysteryEncounter> {
* @returns
*/
withIntroSpriteConfigs(spriteConfigs: MysteryEncounterSpriteConfig[]): this & Pick<MysteryEncounter, "spriteConfigs"> {
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<MysteryEncounter> {
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);
}

View File

@ -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 (+)/(-)