From ce573629abe804a08174d21fa211c8c9fa1317d3 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer Date: Fri, 13 Sep 2024 12:48:23 -0400 Subject: [PATCH] locales updates and bug fixes for safari zone --- .../encounters/field-trip-encounter.ts | 4 ++-- .../encounters/mysterious-chest-encounter.ts | 18 +++++++++----- .../encounters/safari-zone-encounter.ts | 24 +++++++++++++++---- .../utils/encounter-phase-utils.ts | 4 +--- .../en/modifier-select-ui-handler.json | 4 +++- .../en/mystery-encounter-messages.json | 3 ++- .../bug-type-superfan-dialogue.json | 2 +- .../berries-abound-encounter.test.ts | 3 ++- .../uncommon-breed-encounter.test.ts | 9 +++---- src/ui/modifier-select-ui-handler.ts | 4 ++-- src/ui/mystery-encounter-ui-handler.ts | 2 +- 11 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/data/mystery-encounters/encounters/field-trip-encounter.ts b/src/data/mystery-encounters/encounters/field-trip-encounter.ts index ce6e3382158..5174e189c2c 100644 --- a/src/data/mystery-encounters/encounters/field-trip-encounter.ts +++ b/src/data/mystery-encounters/encounters/field-trip-encounter.ts @@ -194,6 +194,8 @@ export const FieldTripEncounter: MysteryEncounter = function pokemonAndMoveChosen(scene: BattleScene, pokemon: PlayerPokemon, move: PokemonMove, correctMoveCategory: MoveCategory) { const encounter = scene.currentBattle.mysteryEncounter!; const correctMove = move.getMove().category === correctMoveCategory; + encounter.setDialogueToken("pokeName", pokemon.getNameToRender()); + encounter.setDialogueToken("move", move.getName()); if (!correctMove) { encounter.selectedOption!.dialogue!.selected = [ { @@ -209,8 +211,6 @@ function pokemonAndMoveChosen(scene: BattleScene, pokemon: PlayerPokemon, move: ]; setEncounterExp(scene, scene.getParty().map((p) => p.id), 50); } else { - encounter.setDialogueToken("pokeName", pokemon.getNameToRender()); - encounter.setDialogueToken("move", move.getName()); encounter.selectedOption!.dialogue!.selected = [ { text: `${namespace}.option.selected`, diff --git a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts index 599524e22f8..d1d1f19662a 100644 --- a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts @@ -17,6 +17,12 @@ import { GameOverPhase } from "#app/phases/game-over-phase"; /** i18n namespace for encounter */ const namespace = "mysteryEncounter:mysteriousChest"; +const RAND_LENGTH = 100; +const COMMON_REWARDS_WEIGHT = 20; // 20% +const ULTRA_REWARDS_WEIGHT = 50; // 30% +const ROGUE_REWARDS_WEIGHT = 60; // 10% +const MASTER_REWARDS_WEIGHT = 65; // 5% + /** * Mysterious Chest encounter. * @see {@link https://github.com/pagefaultgames/pokerogue/issues/3796 | GitHub Issue #3796} @@ -97,12 +103,12 @@ export const MysteriousChestEncounter: MysteryEncounter = const introVisuals = encounter.introVisuals!; // Determine roll first - const roll = randSeedInt(100); + const roll = randSeedInt(RAND_LENGTH); encounter.misc = { roll }; - if (roll <= 35) { + if (roll >= MASTER_REWARDS_WEIGHT) { // Chest is springing trap, change to red chest sprite const blueChestSprites = introVisuals.getSpriteAtIndex(0); const redChestSprites = introVisuals.getSpriteAtIndex(1); @@ -117,7 +123,7 @@ export const MysteriousChestEncounter: MysteryEncounter = // Open the chest const encounter = scene.currentBattle.mysteryEncounter!; const roll = encounter.misc.roll; - if (roll > 80) { + if (roll < COMMON_REWARDS_WEIGHT) { // Choose between 2 COMMON / 2 GREAT tier items (20%) setEncounterRewards(scene, { guaranteedModifierTiers: [ @@ -130,7 +136,7 @@ export const MysteriousChestEncounter: MysteryEncounter = // Display result message then proceed to rewards queueEncounterMessage(scene, `${namespace}.option.1.normal`); leaveEncounterWithoutBattle(scene); - } else if (roll > 50) { + } else if (roll < ULTRA_REWARDS_WEIGHT) { // Choose between 3 ULTRA tier items (30%) setEncounterRewards(scene, { guaranteedModifierTiers: [ @@ -142,13 +148,13 @@ export const MysteriousChestEncounter: MysteryEncounter = // Display result message then proceed to rewards queueEncounterMessage(scene, `${namespace}.option.1.good`); leaveEncounterWithoutBattle(scene); - } else if (roll > 40) { + } else if (roll < ROGUE_REWARDS_WEIGHT) { // Choose between 2 ROGUE tier items (10%) setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE] }); // Display result message then proceed to rewards queueEncounterMessage(scene, `${namespace}.option.1.great`); leaveEncounterWithoutBattle(scene); - } else if (roll > 35) { + } else if (roll < MASTER_REWARDS_WEIGHT) { // Choose 1 MASTER tier item (5%) setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.MASTER] }); // Display result message then proceed to rewards diff --git a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts index a26652c4e0d..e5d9b8687a7 100644 --- a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts +++ b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts @@ -1,4 +1,4 @@ -import { initSubsequentOptionSelect, leaveEncounterWithoutBattle, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { initSubsequentOptionSelect, leaveEncounterWithoutBattle, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"; @@ -36,6 +36,7 @@ export const SafariZoneEncounter: MysteryEncounter = .withEncounterTier(MysteryEncounterTier.GREAT) .withSceneWaveRangeRequirement(10, 180) .withSceneRequirement(new MoneyRequirement(0, SAFARI_MONEY_MULTIPLIER)) // Cost equal to 1 Max Revive + .withAutoHideIntroVisuals(false) .withIntroSpriteConfigs([ { spriteKey: "safari_zone", @@ -79,6 +80,9 @@ export const SafariZoneEncounter: MysteryEncounter = scene.loadSe("PRSFX- Taunt2", "battle_anims", "PRSFX- Taunt2.wav"); scene.loadAtlas("bait", "mystery-encounters"); scene.loadAtlas("mud", "mystery-encounters"); + // Clear enemy party + scene.currentBattle.enemyParty = []; + await transitionMysteryEncounterIntroVisuals(scene); await summonSafariPokemon(scene); initSubsequentOptionSelect(scene, { overrideOptions: safariZoneGameOptions, hideDescription: true }); return true; @@ -250,9 +254,9 @@ async function summonSafariPokemon(scene: BattleScene) { let pokemon; scene.executeWithSeedOffset(() => { enemySpecies = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5])); - enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(scene.currentBattle.waveIndex, true, false, scene.gameMode)); - scene.currentBattle.enemyParty = []; - pokemon = scene.addEnemyPokemon(enemySpecies, scene.currentBattle.waveIndex, TrainerSlot.NONE, false); + const level = scene.currentBattle.getLevelForWave(); + enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(level, true, false, scene.gameMode)); + pokemon = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, false); // Roll shiny twice if (!pokemon.shiny) { @@ -276,7 +280,7 @@ async function summonSafariPokemon(scene: BattleScene) { pokemon.calculateStats(); - scene.currentBattle.enemyParty[0] = pokemon; + scene.currentBattle.enemyParty.unshift(pokemon); }, scene.currentBattle.waveIndex * 1000 + encounter.misc.safariPokemonRemaining); scene.gameData.setPokemonSeen(pokemon, true); @@ -481,6 +485,16 @@ function tryChangeCatchStage(scene: BattleScene, change: number, chance?: number } async function doEndTurn(scene: BattleScene, cursorIndex: number) { + // First cleanup and destroy old Pokemon objects that were left in the enemyParty + // They are left in enemyParty temporarily so that VictoryPhase properly handles EXP + const party = scene.getEnemyParty(); + if (party.length > 1) { + for (let i = 1; i < party.length; i++) { + party[i].destroy(); + } + scene.currentBattle.enemyParty = party.slice(0, 1); + } + const encounter = scene.currentBattle.mysteryEncounter!; const pokemon = encounter.misc.pokemon; const isFlee = isPokemonFlee(pokemon, encounter.misc.fleeStage); diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index e8e92aea490..07f7f941842 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -330,9 +330,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig: const customModifierTypes = partyConfig?.pokemonConfigs ?.filter(config => config?.modifierConfigs) .map(config => config.modifierConfigs!); - if (customModifierTypes) { - scene.generateEnemyModifiers(customModifierTypes); - } + scene.generateEnemyModifiers(customModifierTypes); } } diff --git a/src/locales/en/modifier-select-ui-handler.json b/src/locales/en/modifier-select-ui-handler.json index bc49ce25931..15c930fb65e 100644 --- a/src/locales/en/modifier-select-ui-handler.json +++ b/src/locales/en/modifier-select-ui-handler.json @@ -8,5 +8,7 @@ "lockRaritiesDesc": "Lock item rarities on reroll (affects reroll cost).", "checkTeamDesc": "Check your team or use a form changing item.", "rerollCost": "₽{{formattedMoney}}", - "itemCost": "₽{{formattedMoney}}" + "itemCost": "₽{{formattedMoney}}", + "continueNextWaveButton": "Continue", + "continueNextWaveDescription": "Continue to the next wave." } \ No newline at end of file diff --git a/src/locales/en/mystery-encounter-messages.json b/src/locales/en/mystery-encounter-messages.json index 4e2ab639192..3b81c8e46f0 100644 --- a/src/locales/en/mystery-encounter-messages.json +++ b/src/locales/en/mystery-encounter-messages.json @@ -2,5 +2,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." + "cancel_option": "Return to encounter option select.", + "view_party_button": "View Party" } 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 62873453ead..7df01326aed 100644 --- a/src/locales/en/mystery-encounters/bug-type-superfan-dialogue.json +++ b/src/locales/en/mystery-encounters/bug-type-superfan-dialogue.json @@ -17,7 +17,7 @@ "disabled_tooltip": "You need at least 1 Bug Type Pokémon on your team to select this.", "selected": "You show the trainer all your Bug Type Pokémon...", "selected_0_to_1": "Huh? You only have {{numBugTypes}}...$Guess I'm wasting my breath on someone like you...", - "selected_2_3": "Hey, you've got {{numBugTypes}} Bug Types!\nNot bad.$Here, this might help you on your journey to catch more!", + "selected_2_to_3": "Hey, you've got {{numBugTypes}} Bug Types!\nNot bad.$Here, this might help you on your journey to catch more!", "selected_4_to_5": "What? You have {{numBugTypes}} Bug Types?\nNice!$You're not quite at my level, but I can see shades of myself in you!\n$Take this, my young apprentice!", "selected_6": "Whoa! {{numBugTypes}} Bug Types!\n$You must love Bug Types almost as much as I do!$Here, take this as a token of our camaraderie!" }, 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 3bad3e0d0da..73ffad36258 100644 --- a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -133,7 +133,8 @@ describe("Berries Abound - Mystery Encounter", () => { expect(enemyField[0].species.speciesId).toBe(speciesToSpawn); }); - it("should reward the player with X berries based on wave", { retry: 5 }, async () => { + // TODO: there is some severe test flakiness occurring for this file, needs to be looked at/addressed in separate issue + it.skip("should reward the player with X berries based on wave", async () => { await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); const numBerries = game.scene.currentBattle.mysteryEncounter!.misc.numBerries; diff --git a/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts b/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts index 6b43a532b69..ce9e37b8d68 100644 --- a/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts @@ -30,8 +30,7 @@ const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; const defaultBiome = Biome.CAVE; const defaultWave = 45; -// TODO: there is some severe test flakiness occurring for this file, needs to be looked at/addressed in separate issue -describe.skip("Uncommon Breed - Mystery Encounter", () => { +describe("Uncommon Breed - Mystery Encounter", () => { let phaserGame: Phaser.Game; let game: GameManager; let scene: BattleScene; @@ -168,7 +167,8 @@ describe.skip("Uncommon Breed - Mystery Encounter", () => { }); }); - it("should NOT be selectable if the player doesn't have enough berries", async () => { + // TODO: there is some severe test flakiness occurring for this file, needs to be looked at/addressed in separate issue + it.skip("should NOT be selectable if the player doesn't have enough berries", async () => { await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty); // Clear out any pesky mods that slipped through test spin-up scene.modifiers.forEach(mod => { @@ -192,7 +192,8 @@ describe.skip("Uncommon Breed - Mystery Encounter", () => { expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled(); }); - it("Should skip fight when player meets requirements", { retry: 5 }, async () => { + // TODO: there is some severe test flakiness occurring for this file, needs to be looked at/addressed in separate issue + it.skip("Should skip fight when player meets requirements", { retry: 5 }, async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty); diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index a7fe6d4285b..8e27a4352b5 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -194,7 +194,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { // Add continue button if (this.options.length === 0) { - const continueButtonText = addTextObject(this.scene, -24, optionsYOffset - 5, "Continue", TextStyle.MESSAGE); + const continueButtonText = addTextObject(this.scene, -24, optionsYOffset - 5, i18next.t("modifierSelectUiHandler:continueNextWaveButton"), TextStyle.MESSAGE); continueButtonText.setName("text-continue-btn"); this.continueButtonContainer.add(continueButtonText); } @@ -449,7 +449,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { // Continue button when no shop items this.cursorObj.setScale(1.25); this.cursorObj.setPosition((this.scene.game.canvas.width / 18) + 23, (-this.scene.game.canvas.height / 12) - (this.shopOptionsRows.length > 1 ? 6 : 22)); - ui.showText("Continue to the next wave."); + ui.showText(i18next.t("modifierSelectUiHandler:continueNextWaveDescription")); return ret; } diff --git a/src/ui/mystery-encounter-ui-handler.ts b/src/ui/mystery-encounter-ui-handler.ts index 1c9268641f7..307bab0a3af 100644 --- a/src/ui/mystery-encounter-ui-handler.ts +++ b/src/ui/mystery-encounter-ui-handler.ts @@ -419,7 +419,7 @@ export default class MysteryEncounterUiHandler extends UiHandler { } // View Party Button - const viewPartyText = addBBCodeTextObject(this.scene, 256, -24, getBBCodeFrag("View Party", TextStyle.PARTY), TextStyle.PARTY); + const viewPartyText = addBBCodeTextObject(this.scene, 256, -24, getBBCodeFrag(i18next.t("mysteryEncounterMessages:view_party_button"), TextStyle.PARTY), TextStyle.PARTY); this.optionsContainer.add(viewPartyText); // Description Window