mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-20 06:19:29 +02:00
Compare commits
9 Commits
7d86449d86
...
f027967a6e
Author | SHA1 | Date | |
---|---|---|---|
|
f027967a6e | ||
|
076ef81691 | ||
|
23271901cf | ||
|
1517e0512e | ||
|
5a445e3633 | ||
|
c18c2e0dce | ||
|
554b154e8b | ||
|
028bc1ed1a | ||
|
c657e61312 |
@ -90,9 +90,13 @@ If this feature requires new text, the text should be integrated into the code w
|
||||
- For any feature pulled from the mainline Pokémon games (e.g. a Move or Ability implementation), it's best practice to include a source link for any added text.
|
||||
[Poké Corpus](https://abcboy101.github.io/poke-corpus/) is a great resource for finding text from the mainline games; otherwise, a video/picture showing the text being displayed should suffice.
|
||||
- You should also [notify the current Head of Translation](#notifying-translation) to ensure a fast response.
|
||||
3. At this point, you may begin [testing locales integration in your main PR](#documenting-locales-changes).
|
||||
4. The Translation Team will approve the locale PR (after corrections, if necessary), then merge it into `pokerogue-locales`.
|
||||
5. The Dev Team will approve your main PR for your feature, then merge it into PokéRogue's beta environment.
|
||||
3. Your locales should use the following format:
|
||||
- File names should be in `kebab-case`. Example: `trainer-names.json`
|
||||
- Key names should be in `camelCase`. Example: `aceTrainer`
|
||||
- If you make use of i18next's inbuilt [context support](https://www.i18next.com/translation-function/context), you need to use `snake_case` for the context key. Example: `aceTrainer_male`
|
||||
4. At this point, you may begin [testing locales integration in your main PR](#documenting-locales-changes).
|
||||
5. The Translation Team will approve the locale PR (after corrections, if necessary), then merge it into `pokerogue-locales`.
|
||||
6. The Dev Team will approve your main PR for your feature, then merge it into PokéRogue's beta environment.
|
||||
|
||||
[^2]: For those wondering, the reason for choosing English specifically is due to it being the master language set in Pontoon (the program used by the Translation Team to perform locale updates).
|
||||
If a key is present in any language _except_ the master language, it won't appear anywhere else in the translation tool, rendering missing English keys quite a hassle.
|
||||
|
@ -82,7 +82,7 @@ export const ATrainersTestEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
encounter.dialogue.intro = [
|
||||
{
|
||||
speaker: `trainerNames:${trainerNameKey}`,
|
||||
text: `${namespace}:${trainerNameKey}.intro_dialogue`,
|
||||
text: `${namespace}:${trainerNameKey}.introDialogue`,
|
||||
},
|
||||
];
|
||||
encounter.options[0].dialogue!.selected = [
|
||||
|
@ -237,7 +237,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
modifierConfigs: bossModifierConfigs,
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.1.boss_enraged`);
|
||||
queueEncounterMessage(`${namespace}:option.1.bossEnraged`);
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"StatStageChangePhase",
|
||||
pokemon.getBattlerIndex(),
|
||||
@ -300,7 +300,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
globalScene.addModifier(seedModifier, false, false, false, true);
|
||||
}
|
||||
});
|
||||
queueEncounterMessage(`${namespace}:option.1.food_stash`);
|
||||
queueEncounterMessage(`${namespace}:option.1.foodStash`);
|
||||
};
|
||||
|
||||
setEncounterRewards({ fillRemaining: true }, undefined, givePartyPokemonReviverSeeds);
|
||||
|
@ -71,7 +71,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = MysteryEncounterB
|
||||
text: `${namespace}:intro`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
])
|
||||
@ -152,7 +152,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = MysteryEncounterB
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.tooltip_disabled`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.tooltipDisabled`,
|
||||
selected: [
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
|
@ -254,7 +254,7 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
undefined,
|
||||
doBerryRewards,
|
||||
);
|
||||
await showEncounterText(`${namespace}:option.2.selected_bad`);
|
||||
await showEncounterText(`${namespace}:option.2.selectedBad`);
|
||||
await initBattleWithEnemyConfig(config);
|
||||
return;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
])
|
||||
.withOnInit(() => {
|
||||
@ -312,7 +312,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabledTooltip`,
|
||||
})
|
||||
.withPreOptionPhase(async () => {
|
||||
// Player shows off their bug types
|
||||
@ -333,7 +333,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
encounter.selectedOption!.dialogue!.selected = [
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.2.selected_0_to_1`,
|
||||
text: `${namespace}:option.2.selected0To1`,
|
||||
},
|
||||
];
|
||||
} else if (numBugTypes < 4) {
|
||||
@ -344,7 +344,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
encounter.selectedOption!.dialogue!.selected = [
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.2.selected_2_to_3`,
|
||||
text: `${namespace}:option.2.selected2To3`,
|
||||
},
|
||||
];
|
||||
} else if (numBugTypes < 6) {
|
||||
@ -355,7 +355,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
encounter.selectedOption!.dialogue!.selected = [
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.2.selected_4_to_5`,
|
||||
text: `${namespace}:option.2.selected4To5`,
|
||||
},
|
||||
];
|
||||
} else {
|
||||
@ -398,7 +398,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
encounter.selectedOption!.dialogue!.selected = [
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.2.selected_6`,
|
||||
text: `${namespace}:option.2.selected6`,
|
||||
},
|
||||
];
|
||||
}
|
||||
@ -421,17 +421,17 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.3.selected_dialogue`,
|
||||
text: `${namespace}:option.3.selectedDialogue`,
|
||||
},
|
||||
],
|
||||
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.3.selectPrompt`,
|
||||
})
|
||||
.withPreOptionPhase(async (): Promise<boolean> => {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
@ -476,7 +476,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
);
|
||||
});
|
||||
if (!hasValidItem) {
|
||||
return getEncounterText(`${namespace}:option.3.invalid_selection`) ?? null;
|
||||
return getEncounterText(`${namespace}:option.3.invalidSelection`) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -713,7 +713,7 @@ function doBugTypeMoveTutor(): Promise<void> {
|
||||
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: TODO explain
|
||||
return new Promise<void>(async resolve => {
|
||||
const moveOptions = globalScene.currentBattle.mysteryEncounter!.misc.moveTutorOptions;
|
||||
await showEncounterDialogue(`${namespace}:battle_won`, `${namespace}:speaker`);
|
||||
await showEncounterDialogue(`${namespace}:battleWon`, `${namespace}:speaker`);
|
||||
|
||||
const moveInfoOverlay = new MoveInfoOverlay({
|
||||
delayVisibility: false,
|
||||
@ -748,7 +748,7 @@ function doBugTypeMoveTutor(): Promise<void> {
|
||||
|
||||
const result = await selectOptionThenPokemon(
|
||||
optionSelectItems,
|
||||
`${namespace}:teach_move_prompt`,
|
||||
`${namespace}:teachMovePrompt`,
|
||||
undefined,
|
||||
onHoverOverCancel,
|
||||
);
|
||||
|
@ -119,7 +119,7 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
text: `${namespace}:intro`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
])
|
||||
@ -233,7 +233,7 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
// After the battle, offer the player the opportunity to permanently swap ability
|
||||
const abilityWasSwapped = await handleSwapAbility();
|
||||
if (abilityWasSwapped) {
|
||||
await showEncounterText(`${namespace}:option.1.ability_gained`);
|
||||
await showEncounterText(`${namespace}:option.1.abilityGained`);
|
||||
}
|
||||
|
||||
// Play animations once ability swap is complete
|
||||
@ -267,10 +267,10 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:option.2.selected_2`,
|
||||
text: `${namespace}:option.2.selected2`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:option.2.selected_3`,
|
||||
text: `${namespace}:option.2.selected3`,
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
],
|
||||
@ -359,10 +359,10 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:option.3.selected_2`,
|
||||
text: `${namespace}:option.3.selected2`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:option.3.selected_3`,
|
||||
text: `${namespace}:option.3.selected3`,
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
],
|
||||
@ -432,8 +432,8 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
async function handleSwapAbility() {
|
||||
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: TODO: Consider refactoring to avoid async promise executor
|
||||
return new Promise<boolean>(async resolve => {
|
||||
await showEncounterDialogue(`${namespace}:option.1.apply_ability_dialogue`, `${namespace}:speaker`);
|
||||
await showEncounterText(`${namespace}:option.1.apply_ability_message`);
|
||||
await showEncounterDialogue(`${namespace}:option.1.applyAbilityDialogue`, `${namespace}:speaker`);
|
||||
await showEncounterText(`${namespace}:option.1.applyAbilityMessage`);
|
||||
|
||||
globalScene.ui.setMode(UiMode.MESSAGE).then(() => {
|
||||
displayYesNoOptions(resolve);
|
||||
@ -442,7 +442,7 @@ async function handleSwapAbility() {
|
||||
}
|
||||
|
||||
function displayYesNoOptions(resolve) {
|
||||
showEncounterText(`${namespace}:option.1.ability_prompt`, null, 500, false);
|
||||
showEncounterText(`${namespace}:option.1.abilityPrompt`, null, 500, false);
|
||||
const fullOptions = [
|
||||
{
|
||||
label: i18next.t("menu:yes"),
|
||||
|
@ -174,7 +174,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
// Gets +1 to all stats except SPD on battle start
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.1.boss_enraged`);
|
||||
queueEncounterMessage(`${namespace}:option.1.bossEnraged`);
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"StatStageChangePhase",
|
||||
pokemon.getBattlerIndex(),
|
||||
@ -273,8 +273,8 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.selectPrompt`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
@ -316,7 +316,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
}
|
||||
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(pokemon);
|
||||
if (!meetsReqs) {
|
||||
return getEncounterText(`${namespace}:invalid_selection`) ?? null;
|
||||
return getEncounterText(`${namespace}:invalidSelection`) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -118,7 +118,7 @@ export const DarkDealEncounter: MysteryEncounter = MysteryEncounterBuilder.withE
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
])
|
||||
.withSceneWaveRangeRequirement(30, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
@ -136,10 +136,10 @@ export const DarkDealEncounter: MysteryEncounter = MysteryEncounterBuilder.withE
|
||||
selected: [
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.1.selected_dialogue`,
|
||||
text: `${namespace}:option.1.selectedDialogue`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:option.1.selected_message`,
|
||||
text: `${namespace}:option.1.selectedMessage`,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
@ -193,7 +193,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.2.select_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.2.selectPrompt`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
@ -229,7 +229,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
// If pokemon has valid item, it can be selected
|
||||
const meetsReqs = encounter.options[1].pokemonMeetsPrimaryRequirements(pokemon);
|
||||
if (!meetsReqs) {
|
||||
return getEncounterText(`${namespace}:invalid_selection`) ?? null;
|
||||
return getEncounterText(`${namespace}:invalidSelection`) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -303,7 +303,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.3.selectPrompt`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
@ -341,7 +341,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
// If pokemon has valid item, it can be selected
|
||||
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(pokemon);
|
||||
if (!meetsReqs) {
|
||||
return getEncounterText(`${namespace}:invalid_selection`) ?? null;
|
||||
return getEncounterText(`${namespace}:invalidSelection`) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -43,7 +43,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
|
||||
text: `${namespace}:intro`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
])
|
||||
|
@ -56,7 +56,7 @@ export const FieldTripEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
text: `${namespace}:intro`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
])
|
||||
@ -70,7 +70,7 @@ export const FieldTripEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.1.label`,
|
||||
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||
secondOptionPrompt: `${namespace}:secondOptionPrompt`,
|
||||
})
|
||||
.withPreOptionPhase(async (): Promise<boolean> => {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
@ -118,7 +118,7 @@ export const FieldTripEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||
secondOptionPrompt: `${namespace}:secondOptionPrompt`,
|
||||
})
|
||||
.withPreOptionPhase(async (): Promise<boolean> => {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
@ -166,7 +166,7 @@ export const FieldTripEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||
secondOptionPrompt: `${namespace}:secondOptionPrompt`,
|
||||
})
|
||||
.withPreOptionPhase(async (): Promise<boolean> => {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
@ -226,7 +226,7 @@ function pokemonAndMoveChosen(pokemon: PlayerPokemon, move: PokemonMove, correct
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:incorrect_exp`,
|
||||
text: `${namespace}:incorrectExp`,
|
||||
},
|
||||
];
|
||||
setEncounterExp(
|
||||
@ -243,7 +243,7 @@ function pokemonAndMoveChosen(pokemon: PlayerPokemon, move: PokemonMove, correct
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:correct_exp`,
|
||||
text: `${namespace}:correctExp`,
|
||||
},
|
||||
];
|
||||
setEncounterExp([pokemon.id], 100);
|
||||
|
@ -247,7 +247,7 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w
|
||||
// Burn applied
|
||||
encounter.setDialogueToken("burnedPokemon", chosenPokemon.getNameToRender());
|
||||
encounter.setDialogueToken("abilityName", allAbilities[AbilityId.HEATPROOF].name);
|
||||
queueEncounterMessage(`${namespace}:option.2.target_burned`);
|
||||
queueEncounterMessage(`${namespace}:option.2.targetBurned`);
|
||||
|
||||
// Also permanently change the burned Pokemon's ability to Heatproof
|
||||
applyAbilityOverrideToPokemon(chosenPokemon, AbilityId.HEATPROOF);
|
||||
@ -269,7 +269,7 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
@ -313,6 +313,6 @@ function giveLeadPokemonAttackTypeBoostItem() {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
encounter.setDialogueToken("itemName", boosterModifierType.name);
|
||||
encounter.setDialogueToken("leadPokemon", leadPokemon.getNameToRender());
|
||||
queueEncounterMessage(`${namespace}:found_item`);
|
||||
queueEncounterMessage(`${namespace}:foundItem`);
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
isBoss: true,
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.1.stat_boost`);
|
||||
queueEncounterMessage(`${namespace}:option.1.statBoost`);
|
||||
// Randomly boost 1 stat 2 stages
|
||||
// Cannot boost Spd, Acc, or Evasion
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
@ -165,7 +165,7 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
|
@ -78,7 +78,7 @@ export const FunAndGamesEncounter: MysteryEncounter = MysteryEncounterBuilder.wi
|
||||
.withIntroDialogue([
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
])
|
||||
.setLocalizationKey(`${namespace}`)
|
||||
@ -118,7 +118,7 @@ export const FunAndGamesEncounter: MysteryEncounter = MysteryEncounterBuilder.wi
|
||||
|
||||
// Only Pokemon that are not KOed/legal can be selected
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalid_selection`);
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalidSelection`);
|
||||
};
|
||||
|
||||
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
|
||||
@ -284,25 +284,25 @@ function handleNextTurn() {
|
||||
guaranteedModifierTypeFuncs: [modifierTypes.MULTI_LENS],
|
||||
fillRemaining: false,
|
||||
});
|
||||
resultMessageKey = `${namespace}:best_result`;
|
||||
resultMessageKey = `${namespace}:bestResult`;
|
||||
} else if (healthRatio < 0.15) {
|
||||
// 2nd prize
|
||||
setEncounterRewards({
|
||||
guaranteedModifierTypeFuncs: [modifierTypes.SCOPE_LENS],
|
||||
fillRemaining: false,
|
||||
});
|
||||
resultMessageKey = `${namespace}:great_result`;
|
||||
resultMessageKey = `${namespace}:greatResult`;
|
||||
} else if (healthRatio < 0.33) {
|
||||
// 3rd prize
|
||||
setEncounterRewards({
|
||||
guaranteedModifierTypeFuncs: [modifierTypes.WIDE_LENS],
|
||||
fillRemaining: false,
|
||||
});
|
||||
resultMessageKey = `${namespace}:good_result`;
|
||||
resultMessageKey = `${namespace}:goodResult`;
|
||||
} else {
|
||||
// No prize
|
||||
isHealPhase = true;
|
||||
resultMessageKey = `${namespace}:bad_result`;
|
||||
resultMessageKey = `${namespace}:badResult`;
|
||||
}
|
||||
|
||||
// End the battle
|
||||
@ -312,7 +312,7 @@ function handleNextTurn() {
|
||||
globalScene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
|
||||
leaveEncounterWithoutBattle(isHealPhase);
|
||||
// Must end the TurnInit phase prematurely so battle phases aren't added to queue
|
||||
queueEncounterMessage(`${namespace}:end_game`);
|
||||
queueEncounterMessage(`${namespace}:endGame`);
|
||||
queueEncounterMessage(resultMessageKey);
|
||||
|
||||
// Skip remainder of TurnInitPhase
|
||||
@ -320,9 +320,9 @@ function handleNextTurn() {
|
||||
}
|
||||
if (encounter.misc.turnsRemaining < 3) {
|
||||
// Display charging messages on turns that aren't the initial turn
|
||||
queueEncounterMessage(`${namespace}:charging_continue`);
|
||||
queueEncounterMessage(`${namespace}:chargingContinue`);
|
||||
}
|
||||
queueEncounterMessage(`${namespace}:turn_remaining_${encounter.misc.turnsRemaining}`);
|
||||
queueEncounterMessage(`${namespace}:turnRemaining${encounter.misc.turnsRemaining}`);
|
||||
encounter.misc.turnsRemaining--;
|
||||
|
||||
// Don't skip remainder of TurnInitPhase
|
||||
|
@ -158,7 +158,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.1.label`,
|
||||
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.1.trade_options_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.1.tradeOptionsPrompt`,
|
||||
})
|
||||
.withPreOptionPhase(async (): Promise<boolean> => {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
@ -248,7 +248,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
// Show the trade animation
|
||||
await showTradeBackground();
|
||||
await doPokemonTradeSequence(tradedPokemon, newPlayerPokemon);
|
||||
await showEncounterText(`${namespace}:trade_received`, null, 0, true, 4000);
|
||||
await showEncounterText(`${namespace}:tradeReceived`, null, 0, true, 4000);
|
||||
globalScene.playBgm(encounter.misc.bgmKey);
|
||||
await addPokemonDataToDexAndValidateAchievements(newPlayerPokemon);
|
||||
await hideTradeBackground();
|
||||
@ -369,7 +369,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
// Show the trade animation
|
||||
await showTradeBackground();
|
||||
await doPokemonTradeSequence(tradedPokemon, newPlayerPokemon);
|
||||
await showEncounterText(`${namespace}:trade_received`, null, 0, true, 4000);
|
||||
await showEncounterText(`${namespace}:tradeReceived`, null, 0, true, 4000);
|
||||
globalScene.playBgm(encounter.misc.bgmKey);
|
||||
await addPokemonDataToDexAndValidateAchievements(newPlayerPokemon);
|
||||
await hideTradeBackground();
|
||||
@ -384,7 +384,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.trade_options_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.3.tradeOptionsPrompt`,
|
||||
})
|
||||
.withPreOptionPhase(async (): Promise<boolean> => {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
@ -416,7 +416,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
return it.isTransferable;
|
||||
}).length > 0;
|
||||
if (!meetsReqs) {
|
||||
return getEncounterText(`${namespace}:option.3.invalid_selection`) ?? null;
|
||||
return getEncounterText(`${namespace}:option.3.invalidSelection`) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -468,7 +468,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
// Generate a trainer name
|
||||
const traderName = generateRandomTraderName();
|
||||
encounter.setDialogueToken("tradeTrainerName", traderName.trim());
|
||||
await showEncounterText(`${namespace}:item_trade_selected`);
|
||||
await showEncounterText(`${namespace}:itemTradeSelected`);
|
||||
leaveEncounterWithoutBattle();
|
||||
})
|
||||
.build(),
|
||||
@ -740,10 +740,10 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
|
||||
duration: 500,
|
||||
onComplete: async () => {
|
||||
globalScene.fadeOutBgm(1000, false);
|
||||
await showEncounterText(`${namespace}:pokemon_trade_selected`);
|
||||
await showEncounterText(`${namespace}:pokemonTradeSelected`);
|
||||
tradedPokemon.cry();
|
||||
globalScene.playBgm("evolution");
|
||||
await showEncounterText(`${namespace}:pokemon_trade_goodbye`);
|
||||
await showEncounterText(`${namespace}:pokemonTradeGoodbye`);
|
||||
|
||||
tradedPokeball.setAlpha(0);
|
||||
tradedPokeball.setVisible(true);
|
||||
|
@ -63,9 +63,9 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withPokemonCanLearnMoveRequirement(OPTION_1_REQUIRED_MOVE)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.1.label`,
|
||||
disabledButtonLabel: `${namespace}:option.1.label_disabled`,
|
||||
disabledButtonLabel: `${namespace}:option.1.labelDisabled`,
|
||||
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.1.tooltip_disabled`,
|
||||
disabledButtonTooltip: `${namespace}:option.1.tooltipDisabled`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.1.selected`,
|
||||
@ -81,9 +81,9 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withPokemonCanLearnMoveRequirement(OPTION_2_REQUIRED_MOVE)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
disabledButtonLabel: `${namespace}:option.2.label_disabled`,
|
||||
disabledButtonLabel: `${namespace}:option.2.labelDisabled`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.tooltip_disabled`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.tooltipDisabled`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
|
@ -58,7 +58,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
])
|
||||
.withOnInit(() => {
|
||||
@ -128,7 +128,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
|
||||
// Only Pokemon non-KOd pokemon can be selected
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalid_selection`);
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalidSelection`);
|
||||
};
|
||||
|
||||
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
|
||||
@ -142,9 +142,9 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
|
||||
// Give money and do dialogue
|
||||
if (moneyMultiplier > 2.5) {
|
||||
await showEncounterDialogue(`${namespace}:job_complete_good`, `${namespace}:speaker`);
|
||||
await showEncounterDialogue(`${namespace}:jobCompleteGood`, `${namespace}:speaker`);
|
||||
} else {
|
||||
await showEncounterDialogue(`${namespace}:job_complete_bad`, `${namespace}:speaker`);
|
||||
await showEncounterDialogue(`${namespace}:jobCompleteBad`, `${namespace}:speaker`);
|
||||
}
|
||||
const moneyChange = globalScene.getWaveMoneyAmount(moneyMultiplier);
|
||||
updatePlayerMoney(moneyChange, true, false);
|
||||
@ -153,7 +153,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
amount: moneyChange,
|
||||
}),
|
||||
);
|
||||
await showEncounterText(`${namespace}:pokemon_tired`);
|
||||
await showEncounterText(`${namespace}:pokemonTired`);
|
||||
|
||||
setEncounterRewards({ fillRemaining: true });
|
||||
leaveEncounterWithoutBattle();
|
||||
@ -210,7 +210,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
|
||||
// Only Pokemon non-KOd pokemon can be selected
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalid_selection`);
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalidSelection`);
|
||||
};
|
||||
|
||||
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
|
||||
@ -224,9 +224,9 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
|
||||
// Give money and do dialogue
|
||||
if (moneyMultiplier > 2.5) {
|
||||
await showEncounterDialogue(`${namespace}:job_complete_good`, `${namespace}:speaker`);
|
||||
await showEncounterDialogue(`${namespace}:jobCompleteGood`, `${namespace}:speaker`);
|
||||
} else {
|
||||
await showEncounterDialogue(`${namespace}:job_complete_bad`, `${namespace}:speaker`);
|
||||
await showEncounterDialogue(`${namespace}:jobCompleteBad`, `${namespace}:speaker`);
|
||||
}
|
||||
const moneyChange = globalScene.getWaveMoneyAmount(moneyMultiplier);
|
||||
updatePlayerMoney(moneyChange, true, false);
|
||||
@ -235,7 +235,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
amount: moneyChange,
|
||||
}),
|
||||
);
|
||||
await showEncounterText(`${namespace}:pokemon_tired`);
|
||||
await showEncounterText(`${namespace}:pokemonTired`);
|
||||
|
||||
setEncounterRewards({ fillRemaining: true });
|
||||
leaveEncounterWithoutBattle();
|
||||
@ -248,7 +248,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
@ -282,7 +282,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
await transitionMysteryEncounterIntroVisuals(false, false);
|
||||
|
||||
// Give money and do dialogue
|
||||
await showEncounterDialogue(`${namespace}:job_complete_good`, `${namespace}:speaker`);
|
||||
await showEncounterDialogue(`${namespace}:jobCompleteGood`, `${namespace}:speaker`);
|
||||
const moneyChange = globalScene.getWaveMoneyAmount(2.5);
|
||||
updatePlayerMoney(moneyChange, true, false);
|
||||
await showEncounterText(
|
||||
@ -290,7 +290,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
amount: moneyChange,
|
||||
}),
|
||||
);
|
||||
await showEncounterText(`${namespace}:pokemon_tired`);
|
||||
await showEncounterText(`${namespace}:pokemonTired`);
|
||||
|
||||
setEncounterRewards({ fillRemaining: true });
|
||||
leaveEncounterWithoutBattle();
|
||||
|
@ -205,7 +205,7 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
||||
// 80% chance to increase flee stage +1
|
||||
const fleeChangeResult = tryChangeFleeStage(1, 8);
|
||||
if (!fleeChangeResult) {
|
||||
await showEncounterText(getEncounterText(`${namespace}:safari.busy_eating`) ?? "", null, 1000, false);
|
||||
await showEncounterText(getEncounterText(`${namespace}:safari.busyEating`) ?? "", null, 1000, false);
|
||||
} else {
|
||||
await showEncounterText(getEncounterText(`${namespace}:safari.eating`) ?? "", null, 1000, false);
|
||||
}
|
||||
@ -233,7 +233,7 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
||||
// 80% chance to decrease catch stage -1
|
||||
const catchChangeResult = tryChangeCatchStage(-1, 8);
|
||||
if (!catchChangeResult) {
|
||||
await showEncounterText(getEncounterText(`${namespace}:safari.beside_itself_angry`) ?? "", null, 1000, false);
|
||||
await showEncounterText(getEncounterText(`${namespace}:safari.besideItselfAngry`) ?? "", null, 1000, false);
|
||||
} else {
|
||||
await showEncounterText(getEncounterText(`${namespace}:safari.angry`) ?? "", null, 1000, false);
|
||||
}
|
||||
@ -274,7 +274,7 @@ async function summonSafariPokemon() {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
// Message pokemon remaining
|
||||
encounter.setDialogueToken("remainingCount", encounter.misc.safariPokemonRemaining);
|
||||
globalScene.phaseManager.queueMessage(getEncounterText(`${namespace}:safari.remaining_count`) ?? "", null, true);
|
||||
globalScene.phaseManager.queueMessage(getEncounterText(`${namespace}:safari.remainingCount`) ?? "", null, true);
|
||||
|
||||
// Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken
|
||||
// Safari pokemon roll twice on shiny and HA chances, but are otherwise normal
|
||||
|
@ -70,7 +70,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
text: `${namespace}:intro`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
])
|
||||
@ -119,7 +119,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
);
|
||||
}
|
||||
if (!encounter.pokemonMeetsPrimaryRequirements(pokemon)) {
|
||||
return getEncounterText(`${namespace}:invalid_selection`) ?? null;
|
||||
return getEncounterText(`${namespace}:invalidSelection`) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -155,7 +155,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
|
||||
chosenPokemon.setCustomNature(newNature);
|
||||
encounter.setDialogueToken("newNature", getNatureName(newNature));
|
||||
queueEncounterMessage(`${namespace}:cheap_side_effects`);
|
||||
queueEncounterMessage(`${namespace}:cheapSideEffects`);
|
||||
setEncounterExp([chosenPokemon.id], 100);
|
||||
await chosenPokemon.updateInfo();
|
||||
})
|
||||
@ -193,7 +193,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
|
||||
// Only Pokemon that can gain benefits are unfainted
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalid_selection`);
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalidSelection`);
|
||||
};
|
||||
|
||||
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
|
||||
@ -215,7 +215,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
const chosenPokemon = encounter.misc.chosenPokemon;
|
||||
|
||||
queueEncounterMessage(`${namespace}:no_bad_effects`);
|
||||
queueEncounterMessage(`${namespace}:noBadEffects`);
|
||||
setEncounterExp([chosenPokemon.id], 100);
|
||||
|
||||
await chosenPokemon.updateInfo();
|
||||
|
@ -157,7 +157,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
// Fall asleep waiting for Snorlax
|
||||
// Full heal party
|
||||
globalScene.phaseManager.unshiftNew("PartyHealPhase", true);
|
||||
queueEncounterMessage(`${namespace}:option.2.rest_result`);
|
||||
queueEncounterMessage(`${namespace}:option.2.restResult`);
|
||||
leaveEncounterWithoutBattle();
|
||||
},
|
||||
)
|
||||
@ -167,7 +167,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
|
@ -122,7 +122,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
@ -227,7 +227,7 @@ async function doBiomeTransitionDialogueAndBattleInit() {
|
||||
isBoss: true,
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:boss_enraged`);
|
||||
queueEncounterMessage(`${namespace}:bossEnraged`);
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"StatStageChangePhase",
|
||||
pokemon.getBattlerIndex(),
|
||||
|
@ -139,7 +139,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
},
|
||||
{
|
||||
speaker: trainerNameKey,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
])
|
||||
.withOnInit(() => {
|
||||
@ -189,13 +189,13 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
|
||||
// Dialogue and egg calcs for Pokemon 1
|
||||
const [pokemon1CommonEggs, pokemon1RareEggs] = calculateEggRewardsForPokemon(pokemon1);
|
||||
let pokemon1Tooltip = getEncounterText(`${namespace}:option.1.tooltip_base`)!;
|
||||
let pokemon1Tooltip = getEncounterText(`${namespace}:option.1.tooltipBase`)!;
|
||||
if (pokemon1RareEggs > 0) {
|
||||
const eggsText = i18next.t(`${namespace}:numEggs`, {
|
||||
count: pokemon1RareEggs,
|
||||
rarity: i18next.t("egg:greatTier"),
|
||||
});
|
||||
pokemon1Tooltip += i18next.t(`${namespace}:eggs_tooltip`, {
|
||||
pokemon1Tooltip += i18next.t(`${namespace}:eggsTooltip`, {
|
||||
eggs: eggsText,
|
||||
});
|
||||
encounter.setDialogueToken("pokemon1RareEggs", eggsText);
|
||||
@ -205,7 +205,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
count: pokemon1CommonEggs,
|
||||
rarity: i18next.t("egg:defaultTier"),
|
||||
});
|
||||
pokemon1Tooltip += i18next.t(`${namespace}:eggs_tooltip`, {
|
||||
pokemon1Tooltip += i18next.t(`${namespace}:eggsTooltip`, {
|
||||
eggs: eggsText,
|
||||
});
|
||||
encounter.setDialogueToken("pokemon1CommonEggs", eggsText);
|
||||
@ -214,13 +214,13 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
|
||||
// Dialogue and egg calcs for Pokemon 2
|
||||
const [pokemon2CommonEggs, pokemon2RareEggs] = calculateEggRewardsForPokemon(pokemon2);
|
||||
let pokemon2Tooltip = getEncounterText(`${namespace}:option.2.tooltip_base`)!;
|
||||
let pokemon2Tooltip = getEncounterText(`${namespace}:option.2.tooltipBase`)!;
|
||||
if (pokemon2RareEggs > 0) {
|
||||
const eggsText = i18next.t(`${namespace}:numEggs`, {
|
||||
count: pokemon2RareEggs,
|
||||
rarity: i18next.t("egg:greatTier"),
|
||||
});
|
||||
pokemon2Tooltip += i18next.t(`${namespace}:eggs_tooltip`, {
|
||||
pokemon2Tooltip += i18next.t(`${namespace}:eggsTooltip`, {
|
||||
eggs: eggsText,
|
||||
});
|
||||
encounter.setDialogueToken("pokemon2RareEggs", eggsText);
|
||||
@ -230,7 +230,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
count: pokemon2CommonEggs,
|
||||
rarity: i18next.t("egg:defaultTier"),
|
||||
});
|
||||
pokemon2Tooltip += i18next.t(`${namespace}:eggs_tooltip`, {
|
||||
pokemon2Tooltip += i18next.t(`${namespace}:eggsTooltip`, {
|
||||
eggs: eggsText,
|
||||
});
|
||||
encounter.setDialogueToken("pokemon2CommonEggs", eggsText);
|
||||
@ -239,13 +239,13 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
|
||||
// Dialogue and egg calcs for Pokemon 3
|
||||
const [pokemon3CommonEggs, pokemon3RareEggs] = calculateEggRewardsForPokemon(pokemon3);
|
||||
let pokemon3Tooltip = getEncounterText(`${namespace}:option.3.tooltip_base`)!;
|
||||
let pokemon3Tooltip = getEncounterText(`${namespace}:option.3.tooltipBase`)!;
|
||||
if (pokemon3RareEggs > 0) {
|
||||
const eggsText = i18next.t(`${namespace}:numEggs`, {
|
||||
count: pokemon3RareEggs,
|
||||
rarity: i18next.t("egg:greatTier"),
|
||||
});
|
||||
pokemon3Tooltip += i18next.t(`${namespace}:eggs_tooltip`, {
|
||||
pokemon3Tooltip += i18next.t(`${namespace}:eggsTooltip`, {
|
||||
eggs: eggsText,
|
||||
});
|
||||
encounter.setDialogueToken("pokemon3RareEggs", eggsText);
|
||||
@ -255,7 +255,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
count: pokemon3CommonEggs,
|
||||
rarity: i18next.t("egg:defaultTier"),
|
||||
});
|
||||
pokemon3Tooltip += i18next.t(`${namespace}:eggs_tooltip`, {
|
||||
pokemon3Tooltip += i18next.t(`${namespace}:eggsTooltip`, {
|
||||
eggs: eggsText,
|
||||
});
|
||||
encounter.setDialogueToken("pokemon3CommonEggs", eggsText);
|
||||
@ -321,14 +321,14 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
];
|
||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon1CommonEggs")) {
|
||||
encounter.dialogue.outro.push({
|
||||
text: i18next.t(`${namespace}:gained_eggs`, {
|
||||
text: i18next.t(`${namespace}:gainedEggs`, {
|
||||
numEggs: encounter.dialogueTokens["pokemon1CommonEggs"],
|
||||
}),
|
||||
});
|
||||
}
|
||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon1RareEggs")) {
|
||||
encounter.dialogue.outro.push({
|
||||
text: i18next.t(`${namespace}:gained_eggs`, {
|
||||
text: i18next.t(`${namespace}:gainedEggs`, {
|
||||
numEggs: encounter.dialogueTokens["pokemon1RareEggs"],
|
||||
}),
|
||||
});
|
||||
@ -380,14 +380,14 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
];
|
||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon2CommonEggs")) {
|
||||
encounter.dialogue.outro.push({
|
||||
text: i18next.t(`${namespace}:gained_eggs`, {
|
||||
text: i18next.t(`${namespace}:gainedEggs`, {
|
||||
numEggs: encounter.dialogueTokens["pokemon2CommonEggs"],
|
||||
}),
|
||||
});
|
||||
}
|
||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon2RareEggs")) {
|
||||
encounter.dialogue.outro.push({
|
||||
text: i18next.t(`${namespace}:gained_eggs`, {
|
||||
text: i18next.t(`${namespace}:gainedEggs`, {
|
||||
numEggs: encounter.dialogueTokens["pokemon2RareEggs"],
|
||||
}),
|
||||
});
|
||||
@ -439,14 +439,14 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
||||
];
|
||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon3CommonEggs")) {
|
||||
encounter.dialogue.outro.push({
|
||||
text: i18next.t(`${namespace}:gained_eggs`, {
|
||||
text: i18next.t(`${namespace}:gainedEggs`, {
|
||||
numEggs: encounter.dialogueTokens["pokemon3CommonEggs"],
|
||||
}),
|
||||
});
|
||||
}
|
||||
if (encounter.dialogueTokens.hasOwnProperty("pokemon3RareEggs")) {
|
||||
encounter.dialogue.outro.push({
|
||||
text: i18next.t(`${namespace}:gained_eggs`, {
|
||||
text: i18next.t(`${namespace}:gainedEggs`, {
|
||||
numEggs: encounter.dialogueTokens["pokemon3RareEggs"],
|
||||
}),
|
||||
});
|
||||
@ -482,7 +482,7 @@ function getPartyConfig(): EnemyPartyConfig {
|
||||
trainerType: TrainerType.EXPERT_POKEMON_BREEDER,
|
||||
pokemonConfigs: [
|
||||
{
|
||||
nickname: i18next.t(`${namespace}:cleffa_1_nickname`, {
|
||||
nickname: i18next.t(`${namespace}:cleffa1Nickname`, {
|
||||
speciesName: getPokemonSpecies(cleffaSpecies).getName(),
|
||||
}),
|
||||
species: getPokemonSpecies(cleffaSpecies),
|
||||
@ -501,7 +501,7 @@ function getPartyConfig(): EnemyPartyConfig {
|
||||
// All 3 members always Cleffa line, but different configs
|
||||
baseConfig.pokemonConfigs!.push(
|
||||
{
|
||||
nickname: i18next.t(`${namespace}:cleffa_2_nickname`, {
|
||||
nickname: i18next.t(`${namespace}:cleffa2Nickname`, {
|
||||
speciesName: getPokemonSpecies(cleffaSpecies).getName(),
|
||||
}),
|
||||
species: getPokemonSpecies(cleffaSpecies),
|
||||
@ -514,7 +514,7 @@ function getPartyConfig(): EnemyPartyConfig {
|
||||
ivs: [31, 31, 31, 31, 31, 31],
|
||||
},
|
||||
{
|
||||
nickname: i18next.t(`${namespace}:cleffa_3_nickname`, {
|
||||
nickname: i18next.t(`${namespace}:cleffa3Nickname`, {
|
||||
speciesName: getPokemonSpecies(cleffaSpecies).getName(),
|
||||
}),
|
||||
species: getPokemonSpecies(cleffaSpecies),
|
||||
@ -647,7 +647,7 @@ function onGameOver() {
|
||||
encounter.dialogue.outro = [
|
||||
{
|
||||
speaker: trainerNameKey,
|
||||
text: `${namespace}:outro_failed`,
|
||||
text: `${namespace}:outroFailed`,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -66,7 +66,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
text: `${namespace}:intro`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
speaker: `${namespace}:speaker`,
|
||||
},
|
||||
])
|
||||
@ -178,8 +178,8 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
// Always max price for shiny (flip HA back to normal), and add special messaging
|
||||
priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER;
|
||||
pokemon.abilityIndex = 0;
|
||||
encounter.dialogue.encounterOptionsDialogue!.description = `${namespace}:description_shiny`;
|
||||
encounter.options[0].dialogue!.buttonTooltip = `${namespace}:option.1.tooltip_shiny`;
|
||||
encounter.dialogue.encounterOptionsDialogue!.description = `${namespace}:descriptionShiny`;
|
||||
encounter.options[0].dialogue!.buttonTooltip = `${namespace}:option.1.tooltipShiny`;
|
||||
}
|
||||
const price = globalScene.getWaveMoneyAmount(priceMultiplier);
|
||||
encounter.setDialogueToken("purchasePokemon", pokemon.getNameToRender());
|
||||
@ -202,7 +202,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.1.selected_message`,
|
||||
text: `${namespace}:option.1.selectedMessage`,
|
||||
},
|
||||
],
|
||||
})
|
||||
@ -215,7 +215,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
updatePlayerMoney(-price, true, false);
|
||||
|
||||
// Show dialogue
|
||||
await showEncounterDialogue(`${namespace}:option.1.selected_dialogue`, `${namespace}:speaker`);
|
||||
await showEncounterDialogue(`${namespace}:option.1.selectedDialogue`, `${namespace}:speaker`);
|
||||
await transitionMysteryEncounterIntroVisuals();
|
||||
|
||||
// "Catch" purchased pokemon
|
||||
|
@ -115,7 +115,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
],
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.2.stat_boost`);
|
||||
queueEncounterMessage(`${namespace}:option.2.statBoost`);
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"StatStageChangePhase",
|
||||
pokemon.getBattlerIndex(),
|
||||
@ -181,7 +181,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
|
||||
|
||||
encounter.setDialogueToken("reductionValue", HIGH_BST_REDUCTION_VALUE.toString());
|
||||
encounter.setDialogueToken("increaseValue", BST_INCREASE_VALUE.toString());
|
||||
await showEncounterText(`${namespace}:option.1.selected_2`, null, undefined, true);
|
||||
await showEncounterText(`${namespace}:option.1.selected2`, null, undefined, true);
|
||||
|
||||
encounter.dialogue.outro = [
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = MysteryEncounter
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
])
|
||||
.withAutoHideIntroVisuals(false)
|
||||
@ -163,7 +163,7 @@ async function spawnNextTrainerOrEndEncounter() {
|
||||
globalScene.playSound("item_fanfare");
|
||||
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }));
|
||||
|
||||
await showEncounterDialogue(`${namespace}:victory_2`, `${namespace}:speaker`);
|
||||
await showEncounterDialogue(`${namespace}:victory2`, `${namespace}:speaker`);
|
||||
globalScene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
|
||||
const machoBrace = generateModifierTypeOption(modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
|
||||
machoBrace.type.tier = ModifierTier.MASTER;
|
||||
|
@ -90,7 +90,7 @@ export const TrainingSessionEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
|
||||
// Only Pokemon that are not KOed/legal can be trained
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalid_selection`);
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalidSelection`);
|
||||
};
|
||||
|
||||
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
|
||||
@ -174,7 +174,7 @@ export const TrainingSessionEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.2.select_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.2.selectPrompt`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.selected`,
|
||||
@ -205,7 +205,7 @@ export const TrainingSessionEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
|
||||
// Only Pokemon that are not KOed/legal can be trained
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalid_selection`);
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalidSelection`);
|
||||
};
|
||||
|
||||
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
|
||||
@ -248,7 +248,7 @@ export const TrainingSessionEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.3.selectPrompt`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.selected`,
|
||||
@ -295,7 +295,7 @@ export const TrainingSessionEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
|
||||
// Only Pokemon that are not KOed/legal can be trained
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalid_selection`);
|
||||
return isPokemonValidForEncounterOptionSelection(pokemon, `${namespace}:invalidSelection`);
|
||||
};
|
||||
|
||||
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
|
||||
|
@ -194,7 +194,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
.withOptionPhase(async () => {
|
||||
// Investigate garbage, battle Gmax Garbodor
|
||||
globalScene.setFieldScale(0.75);
|
||||
await showEncounterText(`${namespace}:option.2.selected_2`);
|
||||
await showEncounterText(`${namespace}:option.2.selected2`);
|
||||
await transitionMysteryEncounterIntroVisuals();
|
||||
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
|
@ -97,7 +97,7 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
isBoss: false,
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.1.stat_boost`);
|
||||
queueEncounterMessage(`${namespace}:option.1.statBoost`);
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"StatStageChangePhase",
|
||||
pokemon.getBattlerIndex(),
|
||||
@ -191,7 +191,7 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
@ -236,7 +236,7 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
|
@ -143,7 +143,7 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
])
|
||||
.setLocalizationKey(`${namespace}`)
|
||||
@ -216,7 +216,7 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
||||
await cutsceneDialoguePromise;
|
||||
|
||||
doHideDreamBackground();
|
||||
await showEncounterText(`${namespace}:option.1.dream_complete`);
|
||||
await showEncounterText(`${namespace}:option.1.dreamComplete`);
|
||||
|
||||
await doNewTeamPostProcess(transformations);
|
||||
setEncounterRewards({
|
||||
@ -329,7 +329,7 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
||||
onBeforeRewards,
|
||||
);
|
||||
|
||||
await showEncounterText(`${namespace}:option.2.selected_2`, null, undefined, true);
|
||||
await showEncounterText(`${namespace}:option.2.selected2`, null, undefined, true);
|
||||
await initBattleWithEnemyConfig(enemyPartyConfig);
|
||||
},
|
||||
)
|
||||
|
@ -38,6 +38,7 @@ export enum UiMode {
|
||||
UNAVAILABLE,
|
||||
CHALLENGE_SELECT,
|
||||
RENAME_POKEMON,
|
||||
RENAME_RUN,
|
||||
RUN_HISTORY,
|
||||
RUN_INFO,
|
||||
TEST_DIALOGUE,
|
||||
|
@ -127,6 +127,7 @@ export interface SessionSaveData {
|
||||
battleType: BattleType;
|
||||
trainer: TrainerData;
|
||||
gameVersion: string;
|
||||
runNameText: string;
|
||||
timestamp: number;
|
||||
challenges: ChallengeData[];
|
||||
mysteryEncounterType: MysteryEncounterType | -1; // Only defined when current wave is ME,
|
||||
@ -979,6 +980,54 @@ export class GameData {
|
||||
});
|
||||
}
|
||||
|
||||
async renameSession(slotId: number, newName: string): Promise<boolean> {
|
||||
return new Promise(async resolve => {
|
||||
if (slotId < 0) {
|
||||
return resolve(false);
|
||||
}
|
||||
const sessionData: SessionSaveData | null = await this.getSession(slotId);
|
||||
|
||||
if (!sessionData) {
|
||||
return resolve(false);
|
||||
}
|
||||
|
||||
if (newName === "") {
|
||||
return resolve(true);
|
||||
}
|
||||
|
||||
sessionData.runNameText = newName;
|
||||
const updatedDataStr = JSON.stringify(sessionData);
|
||||
const encrypted = encrypt(updatedDataStr, bypassLogin);
|
||||
const secretId = this.secretId;
|
||||
const trainerId = this.trainerId;
|
||||
|
||||
if (bypassLogin) {
|
||||
localStorage.setItem(
|
||||
`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`,
|
||||
encrypt(updatedDataStr, bypassLogin),
|
||||
);
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
pokerogueApi.savedata.session
|
||||
.update({ slot: slotId, trainerId, secretId, clientSessionId }, encrypted)
|
||||
.then(error => {
|
||||
if (error) {
|
||||
console.error("Failed to update session name:", error);
|
||||
resolve(false);
|
||||
} else {
|
||||
localStorage.setItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`, encrypted);
|
||||
updateUserInfo().then(success => {
|
||||
if (success !== null && !success) {
|
||||
return resolve(false);
|
||||
}
|
||||
});
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
loadSession(slotId: number, sessionData?: SessionSaveData): Promise<boolean> {
|
||||
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: TODO: fix this
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
54
src/ui/rename-run-ui-handler.ts
Normal file
54
src/ui/rename-run-ui-handler.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import i18next from "i18next";
|
||||
import type { InputFieldConfig } from "./form-modal-ui-handler";
|
||||
import { FormModalUiHandler } from "./form-modal-ui-handler";
|
||||
import type { ModalConfig } from "./modal-ui-handler";
|
||||
|
||||
export class RenameRunFormUiHandler extends FormModalUiHandler {
|
||||
getModalTitle(_config?: ModalConfig): string {
|
||||
return i18next.t("menu:renamerun");
|
||||
}
|
||||
|
||||
getWidth(_config?: ModalConfig): number {
|
||||
return 160;
|
||||
}
|
||||
|
||||
getMargin(_config?: ModalConfig): [number, number, number, number] {
|
||||
return [0, 0, 48, 0];
|
||||
}
|
||||
|
||||
getButtonLabels(_config?: ModalConfig): string[] {
|
||||
return [i18next.t("menu:rename"), i18next.t("menu:cancel")];
|
||||
}
|
||||
|
||||
getReadableErrorMessage(error: string): string {
|
||||
const colonIndex = error?.indexOf(":");
|
||||
if (colonIndex > 0) {
|
||||
error = error.slice(0, colonIndex);
|
||||
}
|
||||
|
||||
return super.getReadableErrorMessage(error);
|
||||
}
|
||||
|
||||
override getInputFieldConfigs(): InputFieldConfig[] {
|
||||
return [{ label: i18next.t("menu:runName") }];
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
if (!super.show(args)) {
|
||||
return false;
|
||||
}
|
||||
if (this.inputs?.length) {
|
||||
this.inputs.forEach(input => {
|
||||
input.text = "";
|
||||
});
|
||||
}
|
||||
const config = args[0] as ModalConfig;
|
||||
this.submitAction = _ => {
|
||||
this.sanitizeInputs();
|
||||
const sanitizedName = btoa(encodeURIComponent(this.inputs[0].text));
|
||||
config.buttonActions[0](sanitizedName);
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
}
|
@ -207,6 +207,10 @@ export class RunInfoUiHandler extends UiHandler {
|
||||
headerText.setOrigin(0, 0);
|
||||
headerText.setPositionRelative(headerBg, 8, 4);
|
||||
this.runContainer.add(headerText);
|
||||
const runName = addTextObject(0, 0, this.runInfo.runNameText, TextStyle.WINDOW);
|
||||
runName.setOrigin(0, 0);
|
||||
runName.setPositionRelative(headerBg, 60, 4);
|
||||
this.runContainer.add(runName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { GameMode } from "#app/game-mode";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { Button } from "#enums/buttons";
|
||||
import { GameModes } from "#enums/game-modes";
|
||||
import { TextStyle } from "#enums/text-style";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
// biome-ignore lint/performance/noNamespaceImport: See `src/system/game-data.ts`
|
||||
import * as Modifier from "#modifiers/modifier";
|
||||
import type { SessionSaveData } from "#system/game-data";
|
||||
import type { PokemonData } from "#system/pokemon-data";
|
||||
import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler";
|
||||
import { MessageUiHandler } from "#ui/message-ui-handler";
|
||||
import { RunDisplayMode } from "#ui/run-info-ui-handler";
|
||||
import { addTextObject } from "#ui/text";
|
||||
@ -15,7 +17,7 @@ import { fixedInt, formatLargeNumber, getPlayTimeString, isNullOrUndefined } fro
|
||||
import i18next from "i18next";
|
||||
|
||||
const SESSION_SLOTS_COUNT = 5;
|
||||
const SLOTS_ON_SCREEN = 3;
|
||||
const SLOTS_ON_SCREEN = 2;
|
||||
|
||||
export enum SaveSlotUiMode {
|
||||
LOAD,
|
||||
@ -33,6 +35,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
|
||||
private uiMode: SaveSlotUiMode;
|
||||
private saveSlotSelectCallback: SaveSlotSelectCallback | null;
|
||||
protected manageDataConfig: OptionSelectConfig;
|
||||
|
||||
private scrollCursor = 0;
|
||||
|
||||
@ -101,6 +104,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
const manageDataOptions: any[] = [];
|
||||
|
||||
let success = false;
|
||||
let error = false;
|
||||
@ -109,14 +113,115 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
const originalCallback = this.saveSlotSelectCallback;
|
||||
if (button === Button.ACTION) {
|
||||
const cursor = this.cursor + this.scrollCursor;
|
||||
if (this.uiMode === SaveSlotUiMode.LOAD && !this.sessionSlots[cursor].hasData) {
|
||||
const sessionSlot = this.sessionSlots[cursor];
|
||||
if (this.uiMode === SaveSlotUiMode.LOAD && !sessionSlot.hasData) {
|
||||
error = true;
|
||||
} else {
|
||||
switch (this.uiMode) {
|
||||
case SaveSlotUiMode.LOAD:
|
||||
this.saveSlotSelectCallback = null;
|
||||
originalCallback?.(cursor);
|
||||
if (!sessionSlot.malformed) {
|
||||
manageDataOptions.push({
|
||||
label: i18next.t("menu:loadGame"),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
originalCallback?.(cursor);
|
||||
return true;
|
||||
},
|
||||
keepOpen: false,
|
||||
});
|
||||
|
||||
manageDataOptions.push({
|
||||
label: i18next.t("saveSlotSelectUiHandler:renameRun"),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
ui.setOverlayMode(
|
||||
UiMode.RENAME_RUN,
|
||||
{
|
||||
buttonActions: [
|
||||
(sanitizedName: string) => {
|
||||
const name = decodeURIComponent(atob(sanitizedName));
|
||||
globalScene.gameData.renameSession(cursor, name).then(response => {
|
||||
if (response[0] === false) {
|
||||
globalScene.reset(true);
|
||||
} else {
|
||||
this.clearSessionSlots();
|
||||
this.cursorObj = null;
|
||||
this.populateSessionSlots();
|
||||
this.setScrollCursor(0);
|
||||
this.setCursor(0);
|
||||
ui.revertMode();
|
||||
ui.showText("", 0);
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
ui.revertMode();
|
||||
},
|
||||
],
|
||||
},
|
||||
"",
|
||||
);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.manageDataConfig = {
|
||||
xOffset: 0,
|
||||
yOffset: 48,
|
||||
options: manageDataOptions,
|
||||
maxOptions: 4,
|
||||
};
|
||||
|
||||
manageDataOptions.push({
|
||||
label: i18next.t("saveSlotSelectUiHandler:deleteRun"),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
ui.showText(i18next.t("saveSlotSelectUiHandler:deleteData"), null, () => {
|
||||
ui.setOverlayMode(
|
||||
UiMode.CONFIRM,
|
||||
() => {
|
||||
globalScene.gameData.tryClearSession(cursor).then(response => {
|
||||
if (response[0] === false) {
|
||||
globalScene.reset(true);
|
||||
} else {
|
||||
this.clearSessionSlots();
|
||||
this.cursorObj = null;
|
||||
this.populateSessionSlots();
|
||||
this.setScrollCursor(0);
|
||||
this.setCursor(0);
|
||||
ui.revertMode();
|
||||
ui.showText("", 0);
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
ui.revertMode();
|
||||
ui.showText("", 0);
|
||||
},
|
||||
false,
|
||||
0,
|
||||
19,
|
||||
import.meta.env.DEV ? 300 : 2000,
|
||||
);
|
||||
});
|
||||
return true;
|
||||
},
|
||||
keepOpen: false,
|
||||
});
|
||||
|
||||
manageDataOptions.push({
|
||||
label: i18next.t("menuUiHandler:cancel"),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
return true;
|
||||
},
|
||||
keepOpen: true,
|
||||
});
|
||||
|
||||
ui.setOverlayMode(UiMode.MENU_OPTION_SELECT, this.manageDataConfig);
|
||||
break;
|
||||
|
||||
case SaveSlotUiMode.SAVE: {
|
||||
const saveAndCallback = () => {
|
||||
const originalCallback = this.saveSlotSelectCallback;
|
||||
@ -161,6 +266,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
} else {
|
||||
this.saveSlotSelectCallback = null;
|
||||
ui.showText("", 0);
|
||||
originalCallback?.(-1);
|
||||
success = true;
|
||||
}
|
||||
@ -267,33 +373,34 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
this.cursorObj = globalScene.add.container(0, 0);
|
||||
const cursorBox = globalScene.add.nineslice(
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
"select_cursor_highlight_thick",
|
||||
undefined,
|
||||
296,
|
||||
44,
|
||||
294,
|
||||
this.sessionSlots[prevSlotIndex ?? 0]?.saveData?.runNameText ? 50 : 60,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
);
|
||||
const rightArrow = globalScene.add.image(0, 0, "cursor");
|
||||
rightArrow.setPosition(160, 0);
|
||||
rightArrow.setPosition(160, 15);
|
||||
rightArrow.setName("rightArrow");
|
||||
this.cursorObj.add([cursorBox, rightArrow]);
|
||||
this.sessionSlotsContainer.add(this.cursorObj);
|
||||
}
|
||||
const cursorPosition = cursor + this.scrollCursor;
|
||||
const cursorIncrement = cursorPosition * 56;
|
||||
const cursorIncrement = cursorPosition * 76;
|
||||
if (this.sessionSlots[cursorPosition] && this.cursorObj) {
|
||||
const hasData = this.sessionSlots[cursorPosition].hasData;
|
||||
const session = this.sessionSlots[cursorPosition];
|
||||
const hasData = session.hasData && !session.malformed;
|
||||
// If the session slot lacks session data, it does not move from its default, central position.
|
||||
// Only session slots with session data will move leftwards and have a visible arrow.
|
||||
if (!hasData) {
|
||||
this.cursorObj.setPosition(151, 26 + cursorIncrement);
|
||||
this.cursorObj.setPosition(151, 20 + cursorIncrement);
|
||||
this.sessionSlots[cursorPosition].setPosition(0, cursorIncrement);
|
||||
} else {
|
||||
this.cursorObj.setPosition(145, 26 + cursorIncrement);
|
||||
this.cursorObj.setPosition(145, 20 + cursorIncrement);
|
||||
this.sessionSlots[cursorPosition].setPosition(-6, cursorIncrement);
|
||||
}
|
||||
this.setArrowVisibility(hasData);
|
||||
@ -311,7 +418,8 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
revertSessionSlot(slotIndex: number): void {
|
||||
const sessionSlot = this.sessionSlots[slotIndex];
|
||||
if (sessionSlot) {
|
||||
sessionSlot.setPosition(0, slotIndex * 56);
|
||||
const valueHeight = 76;
|
||||
sessionSlot.setPosition(0, slotIndex * valueHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,7 +448,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
this.setCursor(this.cursor, prevSlotIndex);
|
||||
globalScene.tweens.add({
|
||||
targets: this.sessionSlotsContainer,
|
||||
y: this.sessionSlotsContainerInitialY - 56 * scrollCursor,
|
||||
y: this.sessionSlotsContainerInitialY - 76 * scrollCursor,
|
||||
duration: fixedInt(325),
|
||||
ease: "Sine.easeInOut",
|
||||
});
|
||||
@ -374,12 +482,14 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
class SessionSlot extends Phaser.GameObjects.Container {
|
||||
public slotId: number;
|
||||
public hasData: boolean;
|
||||
/** Indicates the save slot ran into an error while being loaded */
|
||||
public malformed: boolean;
|
||||
private slotWindow: Phaser.GameObjects.NineSlice;
|
||||
private loadingLabel: Phaser.GameObjects.Text;
|
||||
|
||||
public saveData: SessionSaveData;
|
||||
|
||||
constructor(slotId: number) {
|
||||
super(globalScene, 0, slotId * 56);
|
||||
super(globalScene, 0, slotId * 76);
|
||||
|
||||
this.slotId = slotId;
|
||||
|
||||
@ -387,32 +497,89 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
setup() {
|
||||
const slotWindow = addWindow(0, 0, 304, 52);
|
||||
this.add(slotWindow);
|
||||
this.slotWindow = addWindow(0, 0, 304, 70);
|
||||
this.add(this.slotWindow);
|
||||
|
||||
this.loadingLabel = addTextObject(152, 26, i18next.t("saveSlotSelectUiHandler:loading"), TextStyle.WINDOW);
|
||||
this.loadingLabel = addTextObject(152, 33, i18next.t("saveSlotSelectUiHandler:loading"), TextStyle.WINDOW);
|
||||
this.loadingLabel.setOrigin(0.5, 0.5);
|
||||
this.add(this.loadingLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a name for sessions that don't have a name yet.
|
||||
* @param data - The {@linkcode SessionSaveData} being checked
|
||||
* @returns The default name for the given data.
|
||||
*/
|
||||
decideFallback(data: SessionSaveData): string {
|
||||
let fallbackName = `${GameMode.getModeName(data.gameMode)}`;
|
||||
switch (data.gameMode) {
|
||||
case GameModes.CLASSIC:
|
||||
fallbackName += ` (${globalScene.gameData.gameStats.classicSessionsPlayed + 1})`;
|
||||
break;
|
||||
case GameModes.ENDLESS:
|
||||
case GameModes.SPLICED_ENDLESS:
|
||||
fallbackName += ` (${globalScene.gameData.gameStats.endlessSessionsPlayed + 1})`;
|
||||
break;
|
||||
case GameModes.DAILY: {
|
||||
const runDay = new Date(data.timestamp).toLocaleDateString();
|
||||
fallbackName += ` (${runDay})`;
|
||||
break;
|
||||
}
|
||||
case GameModes.CHALLENGE: {
|
||||
const activeChallenges = data.challenges.filter(c => c.value !== 0);
|
||||
if (activeChallenges.length === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
fallbackName = "";
|
||||
for (const challenge of activeChallenges.slice(0, 3)) {
|
||||
if (fallbackName !== "") {
|
||||
fallbackName += ", ";
|
||||
}
|
||||
fallbackName += challenge.toChallenge().getName();
|
||||
}
|
||||
|
||||
if (activeChallenges.length > 3) {
|
||||
fallbackName += ", ...";
|
||||
} else if (fallbackName === "") {
|
||||
// Something went wrong when retrieving the names of the active challenges,
|
||||
// so fall back to just naming the run "Challenge"
|
||||
fallbackName = `${GameMode.getModeName(data.gameMode)}`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fallbackName;
|
||||
}
|
||||
|
||||
async setupWithData(data: SessionSaveData) {
|
||||
const hasName = data?.runNameText;
|
||||
this.remove(this.loadingLabel, true);
|
||||
if (hasName) {
|
||||
const nameLabel = addTextObject(8, 5, data.runNameText, TextStyle.WINDOW);
|
||||
this.add(nameLabel);
|
||||
} else {
|
||||
const fallbackName = this.decideFallback(data);
|
||||
await globalScene.gameData.renameSession(this.slotId, fallbackName);
|
||||
const nameLabel = addTextObject(8, 5, fallbackName, TextStyle.WINDOW);
|
||||
this.add(nameLabel);
|
||||
}
|
||||
|
||||
const gameModeLabel = addTextObject(
|
||||
8,
|
||||
5,
|
||||
19,
|
||||
`${GameMode.getModeName(data.gameMode) || i18next.t("gameMode:unknown")} - ${i18next.t("saveSlotSelectUiHandler:wave")} ${data.waveIndex}`,
|
||||
TextStyle.WINDOW,
|
||||
);
|
||||
this.add(gameModeLabel);
|
||||
|
||||
const timestampLabel = addTextObject(8, 19, new Date(data.timestamp).toLocaleString(), TextStyle.WINDOW);
|
||||
const timestampLabel = addTextObject(8, 33, new Date(data.timestamp).toLocaleString(), TextStyle.WINDOW);
|
||||
this.add(timestampLabel);
|
||||
|
||||
const playTimeLabel = addTextObject(8, 33, getPlayTimeString(data.playTime), TextStyle.WINDOW);
|
||||
const playTimeLabel = addTextObject(8, 47, getPlayTimeString(data.playTime), TextStyle.WINDOW);
|
||||
this.add(playTimeLabel);
|
||||
|
||||
const pokemonIconsContainer = globalScene.add.container(144, 4);
|
||||
const pokemonIconsContainer = globalScene.add.container(144, 16);
|
||||
data.party.forEach((p: PokemonData, i: number) => {
|
||||
const iconContainer = globalScene.add.container(26 * i, 0);
|
||||
iconContainer.setScale(0.75);
|
||||
@ -427,13 +594,9 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
TextStyle.PARTY,
|
||||
{ fontSize: "54px", color: "#f8f8f8" },
|
||||
);
|
||||
text.setShadow(0, 0, undefined);
|
||||
text.setStroke("#424242", 14);
|
||||
text.setOrigin(1, 0);
|
||||
|
||||
iconContainer.add(icon);
|
||||
iconContainer.add(text);
|
||||
text.setShadow(0, 0, undefined).setStroke("#424242", 14).setOrigin(1, 0);
|
||||
|
||||
iconContainer.add([icon, text]);
|
||||
pokemonIconsContainer.add(iconContainer);
|
||||
|
||||
pokemon.destroy();
|
||||
@ -441,7 +604,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
|
||||
this.add(pokemonIconsContainer);
|
||||
|
||||
const modifierIconsContainer = globalScene.add.container(148, 30);
|
||||
const modifierIconsContainer = globalScene.add.container(148, 38);
|
||||
modifierIconsContainer.setScale(0.5);
|
||||
let visibleModifierIndex = 0;
|
||||
for (const m of data.modifiers) {
|
||||
@ -464,22 +627,33 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
|
||||
load(): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
globalScene.gameData.getSession(this.slotId).then(async sessionData => {
|
||||
// Ignore the results if the view was exited
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
if (!sessionData) {
|
||||
this.hasData = false;
|
||||
this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty"));
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
this.hasData = true;
|
||||
this.saveData = sessionData;
|
||||
await this.setupWithData(sessionData);
|
||||
resolve(true);
|
||||
});
|
||||
globalScene.gameData
|
||||
.getSession(this.slotId)
|
||||
.then(async sessionData => {
|
||||
// Ignore the results if the view was exited
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
this.hasData = !!sessionData;
|
||||
if (!sessionData) {
|
||||
this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty"));
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
this.saveData = sessionData;
|
||||
this.setupWithData(sessionData);
|
||||
resolve(true);
|
||||
})
|
||||
.catch(e => {
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
console.warn(`Failed to load session slot #${this.slotId}:`, e);
|
||||
this.loadingLabel.setText(i18next.t("menu:failedToLoadSession"));
|
||||
this.hasData = true;
|
||||
this.malformed = true;
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ import { addWindow } from "#ui/ui-theme";
|
||||
import { UnavailableModalUiHandler } from "#ui/unavailable-modal-ui-handler";
|
||||
import { executeIf } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
import { RenameRunFormUiHandler } from "./rename-run-ui-handler";
|
||||
|
||||
const transitionModes = [
|
||||
UiMode.SAVE_SLOT,
|
||||
@ -98,6 +99,7 @@ const noTransitionModes = [
|
||||
UiMode.SESSION_RELOAD,
|
||||
UiMode.UNAVAILABLE,
|
||||
UiMode.RENAME_POKEMON,
|
||||
UiMode.RENAME_RUN,
|
||||
UiMode.TEST_DIALOGUE,
|
||||
UiMode.AUTO_COMPLETE,
|
||||
UiMode.ADMIN,
|
||||
@ -168,6 +170,7 @@ export class UI extends Phaser.GameObjects.Container {
|
||||
new UnavailableModalUiHandler(),
|
||||
new GameChallengesUiHandler(),
|
||||
new RenameFormUiHandler(),
|
||||
new RenameRunFormUiHandler(),
|
||||
new RunHistoryUiHandler(),
|
||||
new RunInfoUiHandler(),
|
||||
new TestDialogueUiHandler(UiMode.TEST_DIALOGUE),
|
||||
|
@ -66,7 +66,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
||||
expect(AnOfferYouCantRefuseEncounter.dialogue).toBeDefined();
|
||||
expect(AnOfferYouCantRefuseEncounter.dialogue.intro).toStrictEqual([
|
||||
{ text: `${namespace}:intro` },
|
||||
{ speaker: `${namespace}:speaker`, text: `${namespace}:intro_dialogue` },
|
||||
{ speaker: `${namespace}:speaker`, text: `${namespace}:introDialogue` },
|
||||
]);
|
||||
expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue?.description).toBe(
|
||||
@ -180,7 +180,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.tooltip_disabled`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.tooltipDisabled`,
|
||||
selected: [
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
|
@ -194,7 +194,7 @@ describe("Berries Abound - Mystery Encounter", () => {
|
||||
|
||||
// Should be enraged
|
||||
expect(enemyField[0].summonData.statStages).toEqual([0, 1, 0, 1, 1, 0, 0]);
|
||||
expect(encounterTextSpy).toHaveBeenCalledWith(`${namespace}:option.2.selected_bad`);
|
||||
expect(encounterTextSpy).toHaveBeenCalledWith(`${namespace}:option.2.selectedBad`);
|
||||
});
|
||||
|
||||
it("should start battle if fastest pokemon is slower than boss above wave 50", async () => {
|
||||
@ -218,7 +218,7 @@ describe("Berries Abound - Mystery Encounter", () => {
|
||||
|
||||
// Should be enraged
|
||||
expect(enemyField[0].summonData.statStages).toEqual([1, 1, 1, 1, 1, 0, 0]);
|
||||
expect(encounterTextSpy).toHaveBeenCalledWith(`${namespace}:option.2.selected_bad`);
|
||||
expect(encounterTextSpy).toHaveBeenCalledWith(`${namespace}:option.2.selectedBad`);
|
||||
});
|
||||
|
||||
it("Should skip battle when fastest pokemon is faster than boss", async () => {
|
||||
|
@ -181,7 +181,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(BugTypeSuperfanEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
@ -389,7 +389,7 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabledTooltip`,
|
||||
});
|
||||
});
|
||||
|
||||
@ -513,17 +513,17 @@ describe("Bug-Type Superfan - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.3.selected_dialogue`,
|
||||
text: `${namespace}:option.3.selectedDialogue`,
|
||||
},
|
||||
],
|
||||
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.3.selectPrompt`,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -80,7 +80,7 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
{ text: `${namespace}:intro` },
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(ClowningAroundEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
@ -249,11 +249,11 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
text: `${namespace}:option.2.selected`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:option.2.selected_2`,
|
||||
text: `${namespace}:option.2.selected2`,
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.2.selected_3`,
|
||||
text: `${namespace}:option.2.selected3`,
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -334,11 +334,11 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
text: `${namespace}:option.3.selected`,
|
||||
},
|
||||
{
|
||||
text: `${namespace}:option.3.selected_2`,
|
||||
text: `${namespace}:option.3.selected2`,
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:option.3.selected_3`,
|
||||
text: `${namespace}:option.3.selected3`,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -186,8 +186,8 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.selectPrompt`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
|
@ -186,7 +186,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.2.select_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.2.selectPrompt`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
@ -348,7 +348,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.3.selectPrompt`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
|
@ -61,7 +61,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
|
||||
{ text: `${namespace}:intro` },
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
|
@ -61,7 +61,7 @@ describe("Field Trip - Mystery Encounter", () => {
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(FieldTripEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
@ -78,7 +78,7 @@ describe("Field Trip - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.1.label`,
|
||||
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||
secondOptionPrompt: `${namespace}:secondOptionPrompt`,
|
||||
});
|
||||
});
|
||||
|
||||
@ -139,7 +139,7 @@ describe("Field Trip - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||
secondOptionPrompt: `${namespace}:secondOptionPrompt`,
|
||||
});
|
||||
});
|
||||
|
||||
@ -200,7 +200,7 @@ describe("Field Trip - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:second_option_prompt`,
|
||||
secondOptionPrompt: `${namespace}:secondOptionPrompt`,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -253,7 +253,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
||||
expect(option1.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
|
@ -143,7 +143,7 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
|
@ -71,7 +71,7 @@ describe("Fun And Games! - Mystery Encounter", () => {
|
||||
expect(FunAndGamesEncounter.dialogue.intro).toStrictEqual([
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(FunAndGamesEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
|
@ -98,7 +98,7 @@ describe("Global Trade System - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.1.label`,
|
||||
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.1.trade_options_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.1.tradeOptionsPrompt`,
|
||||
});
|
||||
});
|
||||
|
||||
@ -210,7 +210,7 @@ describe("Global Trade System - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
secondOptionPrompt: `${namespace}:option.3.trade_options_prompt`,
|
||||
secondOptionPrompt: `${namespace}:option.3.tradeOptionsPrompt`,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -99,9 +99,9 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
||||
expect(option1.dialogue).toBeDefined();
|
||||
expect(option1.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.1.label`,
|
||||
disabledButtonLabel: `${namespace}:option.1.label_disabled`,
|
||||
disabledButtonLabel: `${namespace}:option.1.labelDisabled`,
|
||||
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.1.tooltip_disabled`,
|
||||
disabledButtonTooltip: `${namespace}:option.1.tooltipDisabled`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.1.selected`,
|
||||
@ -162,9 +162,9 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
||||
expect(option2.dialogue).toBeDefined();
|
||||
expect(option2.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
disabledButtonLabel: `${namespace}:option.2.label_disabled`,
|
||||
disabledButtonLabel: `${namespace}:option.2.labelDisabled`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.tooltip_disabled`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.tooltipDisabled`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
|
@ -65,7 +65,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
||||
{ text: `${namespace}:intro` },
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(PartTimerEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
@ -219,7 +219,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
|
@ -207,7 +207,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
|
@ -71,7 +71,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => {
|
||||
},
|
||||
{
|
||||
speaker: "trainerNames:expert_pokemon_breeder",
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(TheExpertPokemonBreederEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
|
@ -67,7 +67,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
|
||||
expect(dialogue).toBeDefined();
|
||||
expect(dialogue.intro).toStrictEqual([
|
||||
{ text: `${namespace}:intro` },
|
||||
{ speaker: `${namespace}:speaker`, text: `${namespace}:intro_dialogue` },
|
||||
{ speaker: `${namespace}:speaker`, text: `${namespace}:introDialogue` },
|
||||
]);
|
||||
const { title, description, query } = dialogue.encounterOptionsDialogue!;
|
||||
expect(title).toBe(`${namespace}:title`);
|
||||
@ -120,7 +120,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
|
||||
buttonTooltip: expect.stringMatching(new RegExp(`^${namespace}\\:option\\.1\\.tooltip(_shiny)?$`)),
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.1.selected_message`,
|
||||
text: `${namespace}:option.1.selectedMessage`,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -73,7 +73,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
|
||||
{ text: `${namespace}:intro` },
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(TheWinstrateChallengeEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
|
@ -172,7 +172,7 @@ describe("Uncommon Breed - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.2.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
@ -237,7 +237,7 @@ describe("Uncommon Breed - Mystery Encounter", () => {
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabled_tooltip`,
|
||||
disabledButtonTooltip: `${namespace}:option.3.disabledTooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.3.selected`,
|
||||
|
@ -68,7 +68,7 @@ describe("Weird Dream - Mystery Encounter", () => {
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}:speaker`,
|
||||
text: `${namespace}:intro_dialogue`,
|
||||
text: `${namespace}:introDialogue`,
|
||||
},
|
||||
]);
|
||||
expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}:title`);
|
||||
|
82
test/system/rename-run.test.ts
Normal file
82
test/system/rename-run.test.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import * as account from "#app/account";
|
||||
import * as bypassLoginModule from "#app/global-vars/bypass-login";
|
||||
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
||||
import type { SessionSaveData } from "#app/system/game-data";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
describe("System - Rename Run", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.moveset([MoveId.SPLASH])
|
||||
.battleStyle("single")
|
||||
.enemyAbility(AbilityId.BALL_FETCH)
|
||||
.enemyMoveset(MoveId.SPLASH);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
describe("renameSession", () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(false);
|
||||
vi.spyOn(account, "updateUserInfo").mockImplementation(async () => [true, 1]);
|
||||
});
|
||||
|
||||
it("should return false if slotId < 0", async () => {
|
||||
const result = await game.scene.gameData.renameSession(-1, "Named Run");
|
||||
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false if getSession returns null", async () => {
|
||||
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue(null as unknown as SessionSaveData);
|
||||
|
||||
const result = await game.scene.gameData.renameSession(-1, "Named Run");
|
||||
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return true if bypassLogin is true", async () => {
|
||||
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(true);
|
||||
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue({} as SessionSaveData);
|
||||
|
||||
const result = await game.scene.gameData.renameSession(0, "Named Run");
|
||||
|
||||
expect(result).toEqual(true);
|
||||
});
|
||||
|
||||
it("should return false if api returns error", async () => {
|
||||
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue({} as SessionSaveData);
|
||||
vi.spyOn(pokerogueApi.savedata.session, "update").mockResolvedValue("Unknown Error!");
|
||||
|
||||
const result = await game.scene.gameData.renameSession(0, "Named Run");
|
||||
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return true if api is succesfull", async () => {
|
||||
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue({} as SessionSaveData);
|
||||
vi.spyOn(pokerogueApi.savedata.session, "update").mockResolvedValue("");
|
||||
|
||||
const result = await game.scene.gameData.renameSession(0, "Named Run");
|
||||
|
||||
expect(result).toEqual(true);
|
||||
expect(account.updateUserInfo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user