Merge pull request #4090 from ben-lear/mystery-encounters-feedback
bug fixes and balance changes for MEs
This commit is contained in:
commit
9e5df9e77e
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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%)
|
|
||||||
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`);
|
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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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": {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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."
|
|
||||||
}
|
}
|
|
@ -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!"
|
||||||
}
|
}
|
|
@ -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",
|
||||||
|
|
|
@ -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'"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -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`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue