Merge pull request #4216 from ben-lear/mystery-encounters

locales updates and bug fixes for safari zone
This commit is contained in:
ImperialSympathizer 2024-09-13 12:49:03 -04:00 committed by GitHub
commit 6ef8312f6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 50 additions and 27 deletions

View File

@ -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`,

View File

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

View File

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

View File

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

View File

@ -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."
}

View File

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

View File

@ -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!"
},

View File

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

View File

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

View File

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

View File

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