Merge pull request #4090 from ben-lear/mystery-encounters-feedback

bug fixes and balance changes for MEs
This commit is contained in:
ImperialSympathizer 2024-09-07 17:54:58 -04:00 committed by GitHub
commit 9e5df9e77e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 112 additions and 74 deletions

View File

@ -1361,7 +1361,6 @@ export default class BattleScene extends SceneBase {
case Species.ZARUDE: case Species.ZARUDE:
case Species.SQUAWKABILLY: case Species.SQUAWKABILLY:
case Species.TATSUGIRI: case Species.TATSUGIRI:
case Species.GIMMIGHOUL:
case Species.PALDEA_TAUROS: case Species.PALDEA_TAUROS:
return Utils.randSeedInt(species.forms.length); return Utils.randSeedInt(species.forms.length);
case Species.PIKACHU: case Species.PIKACHU:
@ -1387,6 +1386,13 @@ export default class BattleScene extends SceneBase {
return 1; return 1;
} }
return 0; return 0;
case Species.GIMMIGHOUL:
// Chest form can only be found in Mysterious Chest Encounter, if this is a game mode with MEs
if (this.gameMode.hasMysteryEncounters) {
return 1; // Wandering form
} else {
return Utils.randSeedInt(species.forms.length);
}
} }
if (ignoreArena) { if (ignoreArena) {

View File

@ -275,12 +275,12 @@ export const ClowningAroundEncounter: MysteryEncounter =
.forEach(m => { .forEach(m => {
const type = m.type.withTierFromPool(); const type = m.type.withTierFromPool();
const tier = type.tier ?? ModifierTier.ULTRA; const tier = type.tier ?? ModifierTier.ULTRA;
if (type.id === "LUCKY_EGG" || tier === ModifierTier.ULTRA) { if (type.id === "GOLDEN_EGG" || tier === ModifierTier.ROGUE) {
numUltra += m.stackCount;
scene.removeModifier(m);
} else if (type.id === "GOLDEN_EGG" || tier === ModifierTier.ROGUE) {
numRogue += m.stackCount; numRogue += m.stackCount;
scene.removeModifier(m); scene.removeModifier(m);
} else if (type.id === "LUCKY_EGG" || tier === ModifierTier.ULTRA) {
numUltra += m.stackCount;
scene.removeModifier(m);
} }
}); });

View File

@ -74,7 +74,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
const hardSpriteKey = hardConfig.getSpriteKey(female, hardConfig.doubleOnly); const hardSpriteKey = hardConfig.getSpriteKey(female, hardConfig.doubleOnly);
encounter.enemyPartyConfigs.push({ encounter.enemyPartyConfigs.push({
trainerConfig: hardConfig, trainerConfig: hardConfig,
levelAdditiveMultiplier: 0.5, levelAdditiveMultiplier: 1,
female: female, female: female,
}); });
@ -96,7 +96,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
const brutalSpriteKey = brutalConfig.getSpriteKey(female, brutalConfig.doubleOnly); const brutalSpriteKey = brutalConfig.getSpriteKey(female, brutalConfig.doubleOnly);
encounter.enemyPartyConfigs.push({ encounter.enemyPartyConfigs.push({
trainerConfig: brutalConfig, trainerConfig: brutalConfig,
levelAdditiveMultiplier: 1, levelAdditiveMultiplier: 1.5,
female: female, female: female,
}); });
@ -163,7 +163,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
}, },
async (scene: BattleScene) => { async (scene: BattleScene) => {
const encounter = scene.currentBattle.mysteryEncounter!; const encounter = scene.currentBattle.mysteryEncounter!;
// Spawn hard fight with ULTRA/GREAT reward (can improve with luck) // Spawn hard fight
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1]; const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true }); setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true });
@ -188,7 +188,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
}, },
async (scene: BattleScene) => { async (scene: BattleScene) => {
const encounter = scene.currentBattle.mysteryEncounter!; const encounter = scene.currentBattle.mysteryEncounter!;
// Spawn brutal fight with ROGUE/ULTRA/GREAT reward (can improve with luck) // Spawn brutal fight
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[2]; const config: EnemyPartyConfig = encounter.enemyPartyConfigs[2];
// To avoid player level snowballing from picking this option // To avoid player level snowballing from picking this option

View File

@ -1,5 +1,5 @@
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { leaveEncounterWithoutBattle, setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, loadCustomMovesForEncounter, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { getHighestLevelPlayerPokemon, koPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { getHighestLevelPlayerPokemon, koPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { ModifierTier } from "#app/modifier/modifier-tier"; import { ModifierTier } from "#app/modifier/modifier-tier";
import { randSeedInt } from "#app/utils.js"; import { randSeedInt } from "#app/utils.js";
@ -9,6 +9,9 @@ import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option"; import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Species } from "#enums/species";
import { Moves } from "#enums/moves";
/** i18n namespace for encounter */ /** i18n namespace for encounter */
const namespace = "mysteryEncounter:mysteriousChest"; const namespace = "mysteryEncounter:mysteriousChest";
@ -23,6 +26,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
.withEncounterTier(MysteryEncounterTier.COMMON) .withEncounterTier(MysteryEncounterTier.COMMON)
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180 .withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
.withAutoHideIntroVisuals(false) .withAutoHideIntroVisuals(false)
.withCatchAllowed(true)
.withIntroSpriteConfigs([ .withIntroSpriteConfigs([
{ {
spriteKey: "chest_blue", spriteKey: "chest_blue",
@ -51,6 +55,29 @@ export const MysteriousChestEncounter: MysteryEncounter =
.withTitle(`${namespace}.title`) .withTitle(`${namespace}.title`)
.withDescription(`${namespace}.description`) .withDescription(`${namespace}.description`)
.withQuery(`${namespace}.query`) .withQuery(`${namespace}.query`)
.withOnInit((scene: BattleScene) => {
const encounter = scene.currentBattle.mysteryEncounter!;
// Calculate boss mon
const config: EnemyPartyConfig = {
levelAdditiveMultiplier: 1,
disableSwitch: true,
pokemonConfigs: [
{
species: getPokemonSpecies(Species.GIMMIGHOUL),
formIndex: 0,
isBoss: true,
moveSet: [Moves.NASTY_PLOT, Moves.SHADOW_BALL, Moves.POWER_GEM, Moves.THIEF]
}
],
};
encounter.enemyPartyConfigs = [config];
loadCustomMovesForEncounter(scene, [Moves.CONFUSE_RAY, Moves.ASTONISH]);
return true;
})
.withOption( .withOption(
MysteryEncounterOptionBuilder MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT) .newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
@ -139,10 +166,10 @@ export const MysteriousChestEncounter: MysteryEncounter =
koPlayerPokemon(scene, highestLevelPokemon); koPlayerPokemon(scene, highestLevelPokemon);
encounter.setDialogueToken("pokeName", highestLevelPokemon.getNameToRender()); encounter.setDialogueToken("pokeName", highestLevelPokemon.getNameToRender());
// Show which Pokemon was KOed, then leave encounter with no rewards // Show which Pokemon was KOed, then start battle against Gimmighoul
// Does this synchronously so that game over doesn't happen over result message
await showEncounterText(scene, `${namespace}.option.1.bad`); await showEncounterText(scene, `${namespace}.option.1.bad`);
leaveEncounterWithoutBattle(scene); transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
} }
}) })
.build() .build()

View File

@ -1,5 +1,4 @@
import { generateModifierType, leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterExp, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { generateModifierType, leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterExp, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { StatusEffect } from "#app/data/status-effect";
import Pokemon, { PlayerPokemon } from "#app/field/pokemon"; import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
import { modifierTypes } from "#app/modifier/modifier-type"; import { modifierTypes } from "#app/modifier/modifier-type";
import { randSeedInt } from "#app/utils"; import { randSeedInt } from "#app/utils";
@ -13,6 +12,8 @@ import { getEncounterText, queueEncounterMessage } from "#app/data/mystery-encou
import { applyDamageToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { applyDamageToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
import { Nature } from "#enums/nature";
import { getNatureName } from "#app/data/nature";
/** the i18n namespace for this encounter */ /** the i18n namespace for this encounter */
const namespace = "mysteryEncounter:shadyVitaminDealer"; const namespace = "mysteryEncounter:shadyVitaminDealer";
@ -26,8 +27,8 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SHADY_VITAMIN_DEALER) MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SHADY_VITAMIN_DEALER)
.withEncounterTier(MysteryEncounterTier.COMMON) .withEncounterTier(MysteryEncounterTier.COMMON)
.withSceneWaveRangeRequirement(10, 180) .withSceneWaveRangeRequirement(10, 180)
.withPrimaryPokemonStatusEffectRequirement([StatusEffect.NONE]) // Pokemon must not have status .withSceneRequirement(new MoneyRequirement(0, 1.5)) // Must have the money for at least the cheap deal
.withPrimaryPokemonHealthRatioRequirement([0.34, 1]) // Pokemon must have above 1/3rd HP .withPrimaryPokemonHealthRatioRequirement([0.5, 1]) // At least 1 Pokemon must have above half HP
.withIntroSpriteConfigs([ .withIntroSpriteConfigs([
{ {
spriteKey: Species.KROOKODILE.toString(), spriteKey: Species.KROOKODILE.toString(),
@ -62,7 +63,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
.withOption( .withOption(
MysteryEncounterOptionBuilder MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
.withSceneMoneyRequirement(0, 2) // Wave scaling money multiplier of 2 .withSceneMoneyRequirement(0, 1.5)
.withDialogue({ .withDialogue({
buttonLabel: `${namespace}.option.1.label`, buttonLabel: `${namespace}.option.1.label`,
buttonTooltip: `${namespace}.option.1.tooltip`, buttonTooltip: `${namespace}.option.1.tooltip`,
@ -90,7 +91,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
}; };
}; };
// Only Pokemon that can gain benefits are above 1/3rd HP with no status // Only Pokemon that can gain benefits are above half HP with no status
const selectableFilter = (pokemon: Pokemon) => { const selectableFilter = (pokemon: Pokemon) => {
// If pokemon meets primary pokemon reqs, it can be selected // If pokemon meets primary pokemon reqs, it can be selected
const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon); const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon);
@ -118,26 +119,21 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
.withPostOptionPhase(async (scene: BattleScene) => { .withPostOptionPhase(async (scene: BattleScene) => {
// Damage and status applied after dealer leaves (to make thematic sense) // Damage and status applied after dealer leaves (to make thematic sense)
const encounter = scene.currentBattle.mysteryEncounter!; const encounter = scene.currentBattle.mysteryEncounter!;
const chosenPokemon = encounter.misc.chosenPokemon; const chosenPokemon = encounter.misc.chosenPokemon as PlayerPokemon;
// Pokemon takes 1/3 max HP damage // Pokemon takes half max HP damage and nature is randomized (does not update dex)
applyDamageToPokemon(scene, chosenPokemon, Math.floor(chosenPokemon.getMaxHp() / 3)); applyDamageToPokemon(scene, chosenPokemon, Math.floor(chosenPokemon.getMaxHp() / 2));
// Roll for poison (80%) const currentNature = chosenPokemon.nature;
if (randSeedInt(10) < 8) { let newNature = randSeedInt(25) as Nature;
if (chosenPokemon.trySetStatus(StatusEffect.TOXIC)) { while (newNature === currentNature) {
// Toxic applied newNature = randSeedInt(25) as Nature;
queueEncounterMessage(scene, `${namespace}.bad_poison`);
} else {
// Pokemon immune or something else prevents status
queueEncounterMessage(scene, `${namespace}.damage_only`);
}
} else {
queueEncounterMessage(scene, `${namespace}.damage_only`);
} }
chosenPokemon.nature = newNature;
encounter.setDialogueToken("newNature", getNatureName(newNature));
queueEncounterMessage(scene, `${namespace}.cheap_side_effects`);
setEncounterExp(scene, [chosenPokemon.id], 100); setEncounterExp(scene, [chosenPokemon.id], 100);
chosenPokemon.updateInfo(); chosenPokemon.updateInfo();
}) })
.build() .build()
@ -145,7 +141,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
.withOption( .withOption(
MysteryEncounterOptionBuilder MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
.withSceneMoneyRequirement(0, 5) // Wave scaling money multiplier of 5 .withSceneMoneyRequirement(0, 3.5)
.withDialogue({ .withDialogue({
buttonLabel: `${namespace}.option.2.label`, buttonLabel: `${namespace}.option.2.label`,
buttonTooltip: `${namespace}.option.2.tooltip`, buttonTooltip: `${namespace}.option.2.tooltip`,
@ -173,10 +169,10 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
}; };
}; };
// Only Pokemon that can gain benefits are above 1/3rd HP with no status // Only Pokemon that can gain benefits are unfainted
const selectableFilter = (pokemon: Pokemon) => { const selectableFilter = (pokemon: Pokemon) => {
// If pokemon meets primary pokemon reqs, it can be selected // If pokemon is unfainted it can be selected
const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon); const meetsReqs = !pokemon.isFainted(true);
if (!meetsReqs) { if (!meetsReqs) {
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null; return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
} }
@ -203,19 +199,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
const encounter = scene.currentBattle.mysteryEncounter!; const encounter = scene.currentBattle.mysteryEncounter!;
const chosenPokemon = encounter.misc.chosenPokemon; const chosenPokemon = encounter.misc.chosenPokemon;
// Roll for poison (20%) queueEncounterMessage(scene, `${namespace}.no_bad_effects`);
if (randSeedInt(10) < 2) {
if (chosenPokemon.trySetStatus(StatusEffect.POISON)) {
// Poison applied
queueEncounterMessage(scene, `${namespace}.poison`);
} else {
// Pokemon immune or something else prevents status
queueEncounterMessage(scene, `${namespace}.no_bad_effects`);
}
} else {
queueEncounterMessage(scene, `${namespace}.no_bad_effects`);
}
setEncounterExp(scene, [chosenPokemon.id], 100); setEncounterExp(scene, [chosenPokemon.id], 100);
chosenPokemon.updateInfo(); chosenPokemon.updateInfo();

View File

@ -15,11 +15,12 @@ import { BerryType } from "#enums/berry-type";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { SpeciesFormChangeManualTrigger } from "#app/data/pokemon-forms"; import { SpeciesFormChangeManualTrigger } from "#app/data/pokemon-forms";
import { applyPostBattleInitAbAttrs, PostBattleInitAbAttr } from "#app/data/ability"; import { applyPostBattleInitAbAttrs, PostBattleInitAbAttr } from "#app/data/ability";
import { showEncounterDialogue } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { showEncounterDialogue, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode"; import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
import { PartyHealPhase } from "#app/phases/party-heal-phase"; import { PartyHealPhase } from "#app/phases/party-heal-phase";
import { ShowTrainerPhase } from "#app/phases/show-trainer-phase"; import { ShowTrainerPhase } from "#app/phases/show-trainer-phase";
import { ReturnPhase } from "#app/phases/return-phase"; import { ReturnPhase } from "#app/phases/return-phase";
import i18next from "i18next";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounter:theWinstrateChallenge"; const namespace = "mysteryEncounter:theWinstrateChallenge";
@ -100,7 +101,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
buttonTooltip: `${namespace}.option.1.tooltip`, buttonTooltip: `${namespace}.option.1.tooltip`,
selected: [ selected: [
{ {
speaker: "trainerNames:victor", speaker: `${namespace}.speaker`,
text: `${namespace}.option.1.selected`, text: `${namespace}.option.1.selected`,
}, },
], ],
@ -140,6 +141,14 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) {
if (!nextConfig) { if (!nextConfig) {
await transitionMysteryEncounterIntroVisuals(scene, false, false); await transitionMysteryEncounterIntroVisuals(scene, false, false);
await showEncounterDialogue(scene, `${namespace}.victory`, `${namespace}.speaker`); await showEncounterDialogue(scene, `${namespace}.victory`, `${namespace}.speaker`);
// Give 10x Voucher
const newModifier = modifierTypes.VOUCHER_PREMIUM().newModifier();
scene.addModifier(newModifier);
scene.playSound("item_fanfare");
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }));
await showEncounterDialogue(scene, `${namespace}.victory_2`, `${namespace}.speaker`);
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE], fillRemaining: false }); setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE], fillRemaining: false });
encounter.doContinueEncounter = undefined; encounter.doContinueEncounter = undefined;
leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.TRAINER_BATTLE); leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.TRAINER_BATTLE);

View File

@ -991,10 +991,12 @@
"2": "I can feel my Pokémon shivering inside their Pokéballs!" "2": "I can feel my Pokémon shivering inside their Pokéballs!"
}, },
"victory": { "victory": {
"1": "Heeheehee!\nSo hot, you!" "1": "Heeheehee!\nSo hot, you!",
"2": "Heeheehee!\nSo hot, you!"
}, },
"defeat": { "defeat": {
"1": "Whoa! You're all out of gas, I guess." "1": "Whoa! You're all out of gas, I guess.",
"2": "Whoa! You're all out of gas, I guess."
} }
}, },
"stat_trainer_cheryl": { "stat_trainer_cheryl": {
@ -1003,10 +1005,12 @@
"2": "I should warn you, my Pokémon can be quite rambunctious." "2": "I should warn you, my Pokémon can be quite rambunctious."
}, },
"victory": { "victory": {
"1": "Striking the right balance of offense and defense... It's not easy to do." "1": "Striking the right balance of offense and defense... It's not easy to do.",
"2": "Striking the right balance of offense and defense... It's not easy to do."
}, },
"defeat": { "defeat": {
"1": "Do your Pokémon need any healing?" "1": "Do your Pokémon need any healing?",
"2": "Do your Pokémon need any healing?"
} }
}, },
"stat_trainer_marley": { "stat_trainer_marley": {
@ -1015,10 +1019,12 @@
"2": "... OK.\nI... won't lose...!" "2": "... OK.\nI... won't lose...!"
}, },
"victory": { "victory": {
"1": "... Awww." "1": "... Awww.",
"2": "... Awww."
}, },
"defeat": { "defeat": {
"1": "... Goodbye." "1": "... Goodbye.",
"2": "... Goodbye."
} }
}, },
"stat_trainer_mira": { "stat_trainer_mira": {
@ -1027,10 +1033,12 @@
"2": "Mira will show you that Mira doesn't get lost anymore!" "2": "Mira will show you that Mira doesn't get lost anymore!"
}, },
"victory": { "victory": {
"1": "Mira wonders if she can get very far in this land." "1": "Mira wonders if she can get very far in this land.",
"2": "Mira wonders if she can get very far in this land."
}, },
"defeat": { "defeat": {
"1": "Mira knew she would win!" "1": "Mira knew she would win!",
"2": "Mira knew she would win!"
} }
}, },
"stat_trainer_riley": { "stat_trainer_riley": {
@ -1039,10 +1047,12 @@
"2": "We're pulling out all the stops to put your Pokémon down." "2": "We're pulling out all the stops to put your Pokémon down."
}, },
"victory": { "victory": {
"1": "At times we battle, and sometimes we team up...$It's great how Trainers can interact." "1": "At times we battle, and sometimes we team up...$It's great how Trainers can interact.",
"2": "At times we battle, and sometimes we team up...$It's great how Trainers can interact."
}, },
"defeat": { "defeat": {
"1": "You put up quite the display.\nBetter luck next time." "1": "You put up quite the display.\nBetter luck next time.",
"2": "You put up quite the display.\nBetter luck next time."
} }
}, },
"winstrates_victor": { "winstrates_victor": {

View File

@ -12,7 +12,7 @@
"good": "Some pretty nice tools and items.", "good": "Some pretty nice tools and items.",
"great": "A couple great tools and items!", "great": "A couple great tools and items!",
"amazing": "Whoa! An amazing item!", "amazing": "Whoa! An amazing item!",
"bad": "Oh no!@d{32}\nThe chest was trapped!$Your {{pokeName}} jumps in front of you\nbut is KOed in the process." "bad": "Oh no!@d{32}\nThe chest was actually a Gimmighoul in disguise!$Your {{pokeName}} jumps in front of you\nbut is KOed in the process!"
}, },
"2": { "2": {
"label": "Too Risky, Leave", "label": "Too Risky, Leave",

View File

@ -13,7 +13,7 @@
}, },
"2": { "2": {
"label": "The Pricey Deal", "label": "The Pricey Deal",
"tooltip": "(-) Pay {{option2Money, money}}\n(-) Side Effects?\n(+) Chosen Pokémon Gains 2 Random Vitamins" "tooltip": "(-) Pay {{option2Money, money}}\n(+) Chosen Pokémon Gains 2 Random Vitamins"
}, },
"3": { "3": {
"label": "Leave", "label": "Leave",
@ -22,8 +22,6 @@
}, },
"selected": "The man hands you two bottles and quickly disappears.${{selectedPokemon}} gained {{boost1}} and {{boost2}} boosts!" "selected": "The man hands you two bottles and quickly disappears.${{selectedPokemon}} gained {{boost1}} and {{boost2}} boosts!"
}, },
"damage_only": "But the medicine had some side effects!$Your {{selectedPokemon}} takes some damage...", "cheap_side_effects": "But the medicine had some side effects!$Your {{selectedPokemon}} takes some damage,\nand its Nature is changed to {{newNature}}!",
"bad_poison": "But the medicine had some side effects!$Your {{selectedPokemon}} takes some damage\nand becomes badly poisoned...", "no_bad_effects": "Looks like there were no side-effects from the medicine!"
"poison": "But the medicine had some side effects!$Your {{selectedPokemon}} becomes poisoned...",
"no_bad_effects": "Looks like there were no side-effects this time."
} }

View File

@ -9,7 +9,7 @@
"1": { "1": {
"label": "Accept the Challenge", "label": "Accept the Challenge",
"tooltip": "(-) Brutal Battle\n(+) Special Item Reward", "tooltip": "(-) Brutal Battle\n(+) Special Item Reward",
"selected": "That's the spirit! I like you!" "selected": "Let the challenge begin!"
}, },
"2": { "2": {
"label": "Refuse the Challenge", "label": "Refuse the Challenge",
@ -17,5 +17,6 @@
"selected": "That's too bad. Say, your team looks worn out, why don't you stay awhile and rest?" "selected": "That's too bad. Say, your team looks worn out, why don't you stay awhile and rest?"
} }
}, },
"victory": "Congratulations on beating our challenge!$Our family uses this Macho Brace to strengthen our Pokémon more effectively during their training.$You may not need it, considering that you beat the whole lot of us, but we hope you'll accept it anyway!" "victory": "Congratulations on beating our challenge!$First off, we'd like you to have this Voucher.",
"victory_2": "Also, our family uses this Macho Brace to strengthen\nour Pokémon more effectively during training.$You may not need it considering that you beat the whole lot of us, but we hope you'll accept it anyway!"
} }

View File

@ -161,6 +161,7 @@
"iris_alder_double": "Iris & Alder", "iris_alder_double": "Iris & Alder",
"marnie_piers_double": "Marnie & Piers", "marnie_piers_double": "Marnie & Piers",
"piers_marnie_double": "Piers & Marnie", "piers_marnie_double": "Piers & Marnie",
"buck": "Buck", "buck": "Buck",
"cheryl": "Cheryl", "cheryl": "Cheryl",
"marley": "Marley", "marley": "Marley",

View File

@ -34,5 +34,7 @@
"flare_admin_female": "Team Flare Admin", "flare_admin_female": "Team Flare Admin",
"aether_admin": "Aether Foundation Admin", "aether_admin": "Aether Foundation Admin",
"skull_admin": "Team Skull Admin", "skull_admin": "Team Skull Admin",
"macro_admin": "Macro Cosmos" "macro_admin": "Macro Cosmos",
"the_winstrates": "The Winstrates'"
} }

View File

@ -117,12 +117,12 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
}, },
{ {
trainerConfig: expect.any(TrainerConfig), trainerConfig: expect.any(TrainerConfig),
levelAdditiveMultiplier: 0.5, levelAdditiveMultiplier: 1,
female: expect.any(Boolean), female: expect.any(Boolean),
}, },
{ {
trainerConfig: expect.any(TrainerConfig), trainerConfig: expect.any(TrainerConfig),
levelAdditiveMultiplier: 1, levelAdditiveMultiplier: 1.5,
female: expect.any(Boolean), female: expect.any(Boolean),
} }
]); ]);

View File

@ -267,7 +267,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
buttonTooltip: `${namespace}.option.1.tooltip`, buttonTooltip: `${namespace}.option.1.tooltip`,
selected: [ selected: [
{ {
speaker: "trainerNames:victor", speaker: `${namespace}.speaker`,
text: `${namespace}.option.1.selected`, text: `${namespace}.option.1.selected`,
}, },
], ],