From 171339509170803b1bd6a0036f337620822316d9 Mon Sep 17 00:00:00 2001 From: Felix Staud Date: Thu, 11 Jul 2024 13:54:44 -0700 Subject: [PATCH] migrate fight-or-flight encounter --- .../dialogue/fight-or-flight-dialogue.ts | 38 --- .../encounters/fight-or-flight.ts | 304 ++++++++++++------ .../mystery-encounter-dialogue.ts | 2 - 3 files changed, 202 insertions(+), 142 deletions(-) delete mode 100644 src/data/mystery-encounters/dialogue/fight-or-flight-dialogue.ts diff --git a/src/data/mystery-encounters/dialogue/fight-or-flight-dialogue.ts b/src/data/mystery-encounters/dialogue/fight-or-flight-dialogue.ts deleted file mode 100644 index 93d46548d7f..00000000000 --- a/src/data/mystery-encounters/dialogue/fight-or-flight-dialogue.ts +++ /dev/null @@ -1,38 +0,0 @@ -import MysteryEncounterDialogue from "#app/data/mystery-encounters/mystery-encounter-dialogue"; - -export const FightOrFlightDialogue: MysteryEncounterDialogue = { - intro: [ - { - text: "mysteryEncounter:fight_or_flight_intro_message" - } - ], - encounterOptionsDialogue: { - title: "mysteryEncounter:fight_or_flight_title", - description: "mysteryEncounter:fight_or_flight_description", - query: "mysteryEncounter:fight_or_flight_query", - options: [ - { - buttonLabel: "mysteryEncounter:fight_or_flight_option_1_label", - buttonTooltip: "mysteryEncounter:fight_or_flight_option_1_tooltip", - selected: [ - { - text: "mysteryEncounter:fight_or_flight_option_1_selected_message" - } - ] - }, - { - buttonLabel: "mysteryEncounter:fight_or_flight_option_2_label", - buttonTooltip: "mysteryEncounter:fight_or_flight_option_2_tooltip" - }, - { - buttonLabel: "mysteryEncounter:fight_or_flight_option_3_label", - buttonTooltip: "mysteryEncounter:fight_or_flight_option_3_tooltip", - selected: [ - { - text: "mysteryEncounter:fight_or_flight_option_3_selected" - } - ] - } - ] - } -}; diff --git a/src/data/mystery-encounters/encounters/fight-or-flight.ts b/src/data/mystery-encounters/encounters/fight-or-flight.ts index 2a362eaed37..3080ab76810 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight.ts @@ -1,11 +1,14 @@ import { BattleStat } from "#app/data/battle-stat"; +import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { EnemyPartyConfig, initBattleWithEnemyConfig, - leaveEncounterWithoutBattle, queueEncounterMessage, + leaveEncounterWithoutBattle, + queueEncounterMessage, setEncounterRewards, - showEncounterText + showEncounterText, } from "#app/data/mystery-encounters/mystery-encounter-utils"; +import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups"; import Pokemon from "#app/field/pokemon"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { @@ -13,123 +16,220 @@ import { getPlayerModifierTypeOptions, ModifierPoolType, ModifierTypeOption, - regenerateModifierPoolThresholds + regenerateModifierPoolThresholds, } from "#app/modifier/modifier-type"; import { StatChangePhase } from "#app/phases"; import { randSeedInt } from "#app/utils"; import { BattlerTagType } from "#enums/battler-tag-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "../../../battle-scene"; -import MysteryEncounter, { MysteryEncounterBuilder, MysteryEncounterTier } from "../mystery-encounter"; +import MysteryEncounter, { + MysteryEncounterBuilder, + MysteryEncounterTier, +} from "../mystery-encounter"; import { MoveRequirement } from "../mystery-encounter-requirements"; -import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; -import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups"; -export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder - .withEncounterType(MysteryEncounterType.FIGHT_OR_FLIGHT) - .withEncounterTier(MysteryEncounterTier.COMMON) - .withIntroSpriteConfigs([]) // Set in onInit() - .withSceneWaveRangeRequirement(10, 180) // waves 10 to 180 - .withCatchAllowed(true) - .withHideWildIntroMessage(true) - .withOnInit((scene: BattleScene) => { - const encounter = scene.currentBattle.mysteryEncounter; +/** the i18n namespace for the encounter */ +const namespace = "mysteryEncounter:fight_or_flight"; - // Calculate boss mon - const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true); - const config: EnemyPartyConfig = { - levelAdditiveMultiplier: 1, - pokemonConfigs: [{ species: bossSpecies, isBoss: true }] - }; - encounter.enemyPartyConfigs = [config]; - - // Calculate item - // 10-60 GREAT, 60-110 ULTRA, 110-160 ROGUE, 160-180 MASTER - const tier = scene.currentBattle.waveIndex > 160 ? ModifierTier.MASTER : scene.currentBattle.waveIndex > 110 ? ModifierTier.ROGUE : scene.currentBattle.waveIndex > 60 ? ModifierTier.ULTRA : ModifierTier.GREAT; - regenerateModifierPoolThresholds(scene.getParty(), ModifierPoolType.PLAYER, 0); // refresh player item pool - const item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier] })[0]; - encounter.setDialogueToken("itemName", item.type.name); - encounter.misc = item; - - encounter.spriteConfigs = [ +export const FightOrFlightEncounter: MysteryEncounter = + MysteryEncounterBuilder.withEncounterType( + MysteryEncounterType.FIGHT_OR_FLIGHT + ) + .withEncounterTier(MysteryEncounterTier.COMMON) + .withSceneWaveRangeRequirement(10, 180) // waves 10 to 180 + .withCatchAllowed(true) + .withHideWildIntroMessage(true) + .withIntroSpriteConfigs([]) // Set in onInit() + .withIntroDialogue([ { - spriteKey: item.type.iconImage, - fileRoot: "items", - hasShadow: false, - x: 35, - y: -5, - scale: 0.75, - isItem: true + text: `${namespace}_intro_message`, }, - { - spriteKey: bossSpecies.speciesId.toString(), - fileRoot: "pokemon", - hasShadow: true, - tint: 0.25, - x: -5, - repeat: true - } - ]; - - // If player has a stealing move, they succeed automatically - encounter.options[1].meetsRequirements(scene); - const primaryPokemon = encounter.options[1].primaryPokemon; - if (primaryPokemon) { - // Use primaryPokemon to execute the thievery - encounter.dialogue.encounterOptionsDialogue.options[1].buttonTooltip = "mysteryEncounter:fight_or_flight_option_2_steal_tooltip"; - } else { - encounter.dialogue.encounterOptionsDialogue.options[1].buttonTooltip = "mysteryEncounter:fight_or_flight_option_2_tooltip"; - } - - return true; - }) - .withSimpleOption(async (scene: BattleScene) => { - // Pick battle - const item = scene.currentBattle.mysteryEncounter.misc as ModifierTypeOption; - setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false }); - await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]); - }) - .withOption(new MysteryEncounterOptionBuilder() - .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically - .withDisabledOnRequirementsNotMet(false) - .withOptionPhase(async (scene: BattleScene) => { - // Pick steal + ]) + .withOnInit((scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; - const item = scene.currentBattle.mysteryEncounter.misc as ModifierTypeOption; - setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false }); + + // Calculate boss mon + const bossSpecies = scene.arena.randomSpecies( + scene.currentBattle.waveIndex, + scene.currentBattle.waveIndex, + 0, + getPartyLuckValue(scene.getParty()), + true + ); + const config: EnemyPartyConfig = { + levelAdditiveMultiplier: 1, + pokemonConfigs: [{ species: bossSpecies, isBoss: true }], + }; + encounter.enemyPartyConfigs = [config]; + + // Calculate item + // 10-60 GREAT, 60-110 ULTRA, 110-160 ROGUE, 160-180 MASTER + const tier = + scene.currentBattle.waveIndex > 160 + ? ModifierTier.MASTER + : scene.currentBattle.waveIndex > 110 + ? ModifierTier.ROGUE + : scene.currentBattle.waveIndex > 60 + ? ModifierTier.ULTRA + : ModifierTier.GREAT; + regenerateModifierPoolThresholds( + scene.getParty(), + ModifierPoolType.PLAYER, + 0 + ); // refresh player item pool + const item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { + guaranteedModifierTiers: [tier], + })[0]; + encounter.setDialogueToken("itemName", item.type.name); + encounter.misc = item; + + encounter.spriteConfigs = [ + { + spriteKey: item.type.iconImage, + fileRoot: "items", + hasShadow: false, + x: 35, + y: -5, + scale: 0.75, + isItem: true, + }, + { + spriteKey: bossSpecies.speciesId.toString(), + fileRoot: "pokemon", + hasShadow: true, + tint: 0.25, + x: -5, + repeat: true, + }, + ]; // If player has a stealing move, they succeed automatically + encounter.options[1].meetsRequirements(scene); const primaryPokemon = encounter.options[1].primaryPokemon; if (primaryPokemon) { // Use primaryPokemon to execute the thievery - await showEncounterText(scene, "mysteryEncounter:fight_or_flight_option_2_steal_result"); - leaveEncounterWithoutBattle(scene); - return; + encounter.options[1].dialogue.buttonTooltip = `${namespace}_option_2_steal_tooltip`; + } else { + encounter.options[1].dialogue.buttonTooltip = `${namespace}_option_2_tooltip`; } - const roll = randSeedInt(16); - if (roll > 6) { - // Noticed and attacked by boss, gets +1 to all stats at start of fight (62.5%) - const config = scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]; - config.pokemonConfigs[0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON]; - config.pokemonConfigs[0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => { - pokemon.scene.currentBattle.mysteryEncounter.setDialogueToken("enemyPokemon", pokemon.name); - queueEncounterMessage(pokemon.scene, "mysteryEncounter:fight_or_flight_boss_enraged"); - pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1)); - }; - await showEncounterText(scene, "mysteryEncounter:fight_or_flight_option_2_bad_result"); - await initBattleWithEnemyConfig(scene, config); - } else { - // Steal item (37.5%) - // Display result message then proceed to rewards - await showEncounterText(scene, "mysteryEncounter:fight_or_flight_option_2_good_result"); - leaveEncounterWithoutBattle(scene); - } + return true; }) - .build()) - .withSimpleOption(async (scene: BattleScene) => { - // Leave encounter with no rewards or exp - leaveEncounterWithoutBattle(scene, true); - return true; - }) - .build(); + .withTitle(`${namespace}_title`) + .withDescription(`${namespace}_description`) + .withQuery(`${namespace}_query`) + .withSimpleOption( + { + buttonLabel: `${namespace}_option_1_label`, + buttonTooltip: `${namespace}_option_1_tooltip`, + selected: [ + { + text: `${namespace}_option_1_selected_message`, + }, + ], + }, + async (scene: BattleScene) => { + // Pick battle + const item = scene.currentBattle.mysteryEncounter + .misc as ModifierTypeOption; + setEncounterRewards(scene, { + guaranteedModifierTypeOptions: [item], + fillRemaining: false, + }); + await initBattleWithEnemyConfig( + scene, + scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0] + ); + } + ) + .withOption( + new MysteryEncounterOptionBuilder() + .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically + .withDisabledOnRequirementsNotMet(false) + .withDialogue({ + buttonLabel: `${namespace}_option_2_label`, + buttonTooltip: `${namespace}_option_2_tooltip`, + }) + .withOptionPhase(async (scene: BattleScene) => { + // Pick steal + const encounter = scene.currentBattle.mysteryEncounter; + const item = scene.currentBattle.mysteryEncounter + .misc as ModifierTypeOption; + setEncounterRewards(scene, { + guaranteedModifierTypeOptions: [item], + fillRemaining: false, + }); + + // If player has a stealing move, they succeed automatically + const primaryPokemon = encounter.options[1].primaryPokemon; + if (primaryPokemon) { + // Use primaryPokemon to execute the thievery + await showEncounterText( + scene, + `${namespace}_option_2_steal_result` + ); + leaveEncounterWithoutBattle(scene); + return; + } + + const roll = randSeedInt(16); + if (roll > 6) { + // Noticed and attacked by boss, gets +1 to all stats at start of fight (62.5%) + const config = + scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]; + config.pokemonConfigs[0].tags = [ + BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON, + ]; + config.pokemonConfigs[0].mysteryEncounterBattleEffects = ( + pokemon: Pokemon + ) => { + pokemon.scene.currentBattle.mysteryEncounter.setDialogueToken( + "enemyPokemon", + pokemon.name + ); + queueEncounterMessage(pokemon.scene, `${namespace}_boss_enraged`); + pokemon.scene.unshiftPhase( + new StatChangePhase( + pokemon.scene, + pokemon.getBattlerIndex(), + true, + [ + BattleStat.ATK, + BattleStat.DEF, + BattleStat.SPATK, + BattleStat.SPDEF, + BattleStat.SPD, + ], + 1 + ) + ); + }; + await showEncounterText(scene, `${namespace}_option_2_bad_result`); + await initBattleWithEnemyConfig(scene, config); + } else { + // Steal item (37.5%) + // Display result message then proceed to rewards + await showEncounterText(scene, `${namespace}_option_2_good_result`); + leaveEncounterWithoutBattle(scene); + } + }) + .build() + ) + .withSimpleOption( + { + buttonLabel: `${namespace}_option_3_label`, + buttonTooltip: `${namespace}_option_3_tooltip`, + selected: [ + { + text: `${namespace}_option_3_selected`, + }, + ], + }, + async (scene: BattleScene) => { + // Leave encounter with no rewards or exp + leaveEncounterWithoutBattle(scene, true); + return true; + } + ) + .build(); diff --git a/src/data/mystery-encounters/mystery-encounter-dialogue.ts b/src/data/mystery-encounters/mystery-encounter-dialogue.ts index bfeb094c9a5..d9532ee4984 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 { 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"; import { ShadyVitaminDealerDialogue } from "#app/data/mystery-encounters/dialogue/shady-vitamin-dealer"; @@ -84,7 +83,6 @@ export const allMysteryEncounterDialogue: { [encounterType: number]: MysteryEnco export function initMysteryEncounterDialogue() { allMysteryEncounterDialogue[MysteryEncounterType.MYSTERIOUS_CHALLENGERS] = MysteriousChallengersDialogue; allMysteryEncounterDialogue[MysteryEncounterType.MYSTERIOUS_CHEST] = MysteriousChestDialogue; - allMysteryEncounterDialogue[MysteryEncounterType.FIGHT_OR_FLIGHT] = FightOrFlightDialogue; allMysteryEncounterDialogue[MysteryEncounterType.TRAINING_SESSION] = TrainingSessionDialogue; allMysteryEncounterDialogue[MysteryEncounterType.SLEEPING_SNORLAX] = SleepingSnorlaxDialogue; allMysteryEncounterDialogue[MysteryEncounterType.SHADY_VITAMIN_DEALER] = ShadyVitaminDealerDialogue;