mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-06 00:12:16 +02:00
Compare commits
No commits in common. "a00bc7e8ef137f4455368d2ac566b2660baaf87e" and "a38a66dd781a915b3a2c5b1a670e7c5200dc0b93" have entirely different histories.
a00bc7e8ef
...
a38a66dd78
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Binary file not shown.
Before Width: | Height: | Size: 561 B |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 4.0 KiB |
@ -13,17 +13,7 @@ import { Arena, ArenaBase } from "./field/arena";
|
||||
import { GameData } from "./system/game-data";
|
||||
import { addTextObject, getTextColor, TextStyle } from "./ui/text";
|
||||
import { allMoves } from "./data/move";
|
||||
import {
|
||||
ModifierPoolType,
|
||||
getDefaultModifierTypeForTier,
|
||||
getEnemyModifierTypesForWave,
|
||||
getLuckString,
|
||||
getLuckTextTint,
|
||||
getModifierPoolForType,
|
||||
getModifierType,
|
||||
getPartyLuckValue,
|
||||
modifierTypes
|
||||
} from "./modifier/modifier-type";
|
||||
import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, modifierTypes } from "./modifier/modifier-type";
|
||||
import AbilityBar from "./ui/ability-bar";
|
||||
import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, ChangeMovePriorityAbAttr, PostBattleInitAbAttr, applyAbAttrs, applyPostBattleInitAbAttrs } from "./data/ability";
|
||||
import { allAbilities } from "./data/ability";
|
||||
|
@ -19,7 +19,7 @@ const namespace = "mysteryEncounter:aTrainersTest";
|
||||
|
||||
/**
|
||||
* A Trainer's Test encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3816 | GitHub Issue #3816}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/115 | GitHub Issue #115}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const ATrainersTestEncounter: MysteryEncounter =
|
||||
|
@ -29,7 +29,7 @@ const namespace = "mysteryEncounter:absoluteAvarice";
|
||||
|
||||
/**
|
||||
* Absolute Avarice encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3805 | GitHub Issue #3805}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/58 | GitHub Issue #58}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const AbsoluteAvariceEncounter: MysteryEncounter =
|
||||
@ -249,10 +249,8 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
||||
const givePartyPokemonReviverSeeds = () => {
|
||||
const party = scene.getParty();
|
||||
party.forEach(p => {
|
||||
if (revSeed) {
|
||||
const seedModifier = revSeed.newModifier(p);
|
||||
scene.addModifier(seedModifier, false, false, false, true);
|
||||
}
|
||||
const seedModifier = revSeed.newModifier(p);
|
||||
scene.addModifier(seedModifier, false, false, false, true);
|
||||
});
|
||||
queueEncounterMessage(scene, `${namespace}.option.1.food_stash`);
|
||||
};
|
||||
@ -351,7 +349,7 @@ function doGreedentSpriteSteal(scene: BattleScene) {
|
||||
|
||||
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals?.getSpriteAtIndex(1);
|
||||
|
||||
scene.playSound("battle-anims/Follow Me");
|
||||
scene.playSound("Follow Me");
|
||||
scene.tweens.chain({
|
||||
targets: greedentSprites,
|
||||
tweens: [
|
||||
@ -433,11 +431,11 @@ function doGreedentEatBerries(scene: BattleScene) {
|
||||
y: "-=8",
|
||||
loop: 5,
|
||||
onStart: () => {
|
||||
scene.playSound("battle_anims/PRSFX- Bug Bite");
|
||||
scene.playSound("PRSFX- Bug Bite");
|
||||
},
|
||||
onLoop: () => {
|
||||
if (index % 2 === 0) {
|
||||
scene.playSound("battle_anims/PRSFX- Bug Bite");
|
||||
scene.playSound("PRSFX- Bug Bite");
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ const namespace = "mysteryEncounter:offerYouCantRefuse";
|
||||
|
||||
/**
|
||||
* An Offer You Can't Refuse encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3808 | GitHub Issue #3808}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/72 | GitHub Issue #72}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
||||
|
@ -37,7 +37,7 @@ const namespace = "mysteryEncounter:berriesAbound";
|
||||
|
||||
/**
|
||||
* Berries Abound encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3810 | GitHub Issue #3810}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/24 | GitHub Issue #24}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const BerriesAboundEncounter: MysteryEncounter =
|
||||
@ -131,7 +131,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
||||
const doBerryRewards = async () => {
|
||||
const berryText = numBerries + " " + i18next.t(`${namespace}.berries`);
|
||||
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText }));
|
||||
|
||||
// Generate a random berry and give it to the first Pokemon with room for it
|
||||
@ -143,10 +143,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
||||
const shopOptions: ModifierTypeOption[] = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
// Generate shop berries
|
||||
const mod = generateModifierTypeOption(scene, modifierTypes.BERRY);
|
||||
if (mod) {
|
||||
shopOptions.push(mod);
|
||||
}
|
||||
shopOptions.push(generateModifierTypeOption(scene, modifierTypes.BERRY));
|
||||
}
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
|
||||
@ -171,10 +168,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
||||
const shopOptions: ModifierTypeOption[] = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
// Generate shop berries
|
||||
const mod = generateModifierTypeOption(scene, modifierTypes.BERRY);
|
||||
if (mod) {
|
||||
shopOptions.push(mod);
|
||||
}
|
||||
shopOptions.push(generateModifierTypeOption(scene, modifierTypes.BERRY));
|
||||
}
|
||||
|
||||
if (speedDiff < 1) {
|
||||
@ -182,7 +176,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
||||
const doBerryRewards = async () => {
|
||||
const berryText = numBerries + " " + i18next.t(`${namespace}.berries`);
|
||||
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText }));
|
||||
|
||||
// Generate a random berry and give it to the first Pokemon with room for it
|
||||
@ -208,7 +202,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
||||
const doFasterBerryRewards = async () => {
|
||||
const berryText = numBerriesGrabbed + " " + i18next.t(`${namespace}.berries`);
|
||||
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText }));
|
||||
|
||||
// Generate a random berry and give it to the first Pokemon with room for it (trying to give to fastest first)
|
||||
|
@ -1,659 +0,0 @@
|
||||
import {
|
||||
EnemyPartyConfig,
|
||||
generateModifierTypeOption,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
selectOptionThenPokemon,
|
||||
selectPokemonForOption,
|
||||
setEncounterRewards,
|
||||
transitionMysteryEncounterIntroVisuals,
|
||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import {
|
||||
trainerConfigs,
|
||||
TrainerPartyCompoundTemplate,
|
||||
TrainerPartyTemplate,
|
||||
TrainerSlot,
|
||||
} from "#app/data/trainer-config";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import * as Utils from "#app/utils";
|
||||
import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { Species } from "#enums/species";
|
||||
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import { getEncounterText, showEncounterDialogue } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import {
|
||||
AttackTypeBoosterHeldItemTypeRequirement,
|
||||
CombinationPokemonRequirement,
|
||||
HeldItemRequirement,
|
||||
TypeRequirement
|
||||
} from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import { Type } from "#app/data/type";
|
||||
import { AttackTypeBoosterModifierType, ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type";
|
||||
import {
|
||||
AttackTypeBoosterModifier,
|
||||
BypassSpeedChanceModifier,
|
||||
ContactHeldItemTransferChanceModifier,
|
||||
PokemonHeldItemModifier
|
||||
} from "#app/modifier/modifier";
|
||||
import i18next from "i18next";
|
||||
import MoveInfoOverlay from "#app/ui/move-info-overlay";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:bugTypeSuperfan";
|
||||
|
||||
const POOL_1_POKEMON = [
|
||||
Species.PARASECT,
|
||||
Species.VENOMOTH,
|
||||
Species.LEDIAN,
|
||||
Species.ARIADOS,
|
||||
Species.YANMA,
|
||||
Species.BEAUTIFLY,
|
||||
Species.DUSTOX,
|
||||
Species.MASQUERAIN,
|
||||
Species.NINJASK,
|
||||
Species.VOLBEAT,
|
||||
Species.ILLUMISE,
|
||||
Species.ANORITH,
|
||||
Species.KRICKETUNE,
|
||||
Species.WORMADAM,
|
||||
Species.MOTHIM,
|
||||
Species.SKORUPI,
|
||||
Species.JOLTIK,
|
||||
Species.LARVESTA,
|
||||
Species.VIVILLON,
|
||||
Species.CHARJABUG,
|
||||
Species.RIBOMBEE,
|
||||
Species.SPIDOPS,
|
||||
Species.LOKIX
|
||||
];
|
||||
|
||||
const POOL_2_POKEMON = [
|
||||
Species.SCYTHER,
|
||||
Species.PINSIR,
|
||||
Species.HERACROSS,
|
||||
Species.FORRETRESS,
|
||||
Species.SCIZOR,
|
||||
Species.SHUCKLE,
|
||||
Species.SHEDINJA,
|
||||
Species.ARMALDO,
|
||||
Species.VESPIQUEN,
|
||||
Species.DRAPION,
|
||||
Species.YANMEGA,
|
||||
Species.LEAVANNY,
|
||||
Species.SCOLIPEDE,
|
||||
Species.CRUSTLE,
|
||||
Species.ESCAVALIER,
|
||||
Species.ACCELGOR,
|
||||
Species.GALVANTULA,
|
||||
Species.VIKAVOLT,
|
||||
Species.ARAQUANID,
|
||||
Species.ORBEETLE,
|
||||
Species.CENTISKORCH,
|
||||
Species.FROSMOTH,
|
||||
Species.KLEAVOR,
|
||||
];
|
||||
|
||||
const POOL_3_POKEMON: { species: Species, formIndex?: number }[] = [
|
||||
{
|
||||
species: Species.PINSIR,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.SCIZOR,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.HERACROSS,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.ORBEETLE,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.CENTISKORCH,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.DURANT,
|
||||
},
|
||||
{
|
||||
species: Species.VOLCARONA,
|
||||
},
|
||||
{
|
||||
species: Species.GOLISOPOD,
|
||||
},
|
||||
];
|
||||
|
||||
const POOL_4_POKEMON = [
|
||||
Species.GENESECT,
|
||||
Species.SLITHER_WING,
|
||||
Species.BUZZWOLE,
|
||||
Species.PHEROMOSA
|
||||
];
|
||||
|
||||
const PHYSICAL_TUTOR_MOVES = [
|
||||
Moves.MEGAHORN,
|
||||
Moves.X_SCISSOR,
|
||||
Moves.ATTACK_ORDER,
|
||||
Moves.PIN_MISSILE,
|
||||
Moves.FIRST_IMPRESSION
|
||||
];
|
||||
|
||||
const SPECIAL_TUTOR_MOVES = [
|
||||
Moves.SILVER_WIND,
|
||||
Moves.BUG_BUZZ,
|
||||
Moves.SIGNAL_BEAM,
|
||||
Moves.POLLEN_PUFF
|
||||
];
|
||||
|
||||
const STATUS_TUTOR_MOVES = [
|
||||
Moves.STRING_SHOT,
|
||||
Moves.STICKY_WEB,
|
||||
Moves.SILK_TRAP,
|
||||
Moves.RAGE_POWDER,
|
||||
Moves.HEAL_ORDER
|
||||
];
|
||||
|
||||
const MISC_TUTOR_MOVES = [
|
||||
Moves.BUG_BITE,
|
||||
Moves.LEECH_LIFE,
|
||||
Moves.DEFEND_ORDER,
|
||||
Moves.QUIVER_DANCE,
|
||||
Moves.TAIL_GLOW,
|
||||
Moves.INFESTATION,
|
||||
Moves.U_TURN
|
||||
];
|
||||
|
||||
/**
|
||||
* Bug Type Superfan encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3810 | GitHub Issue #3810}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const BugTypeSuperfanEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.BUG_TYPE_SUPERFAN)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||
// Must have at least 1 Bug type on team, OR have a bug item somewhere on the team
|
||||
new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1),
|
||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
||||
new TypeRequirement(Type.BUG, false, 1)
|
||||
))
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withIntroDialogue([
|
||||
{
|
||||
text: `${namespace}.intro`,
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.intro_dialogue`,
|
||||
},
|
||||
])
|
||||
.withOnInit((scene: BattleScene) => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
// Calculates what trainers are available for battle in the encounter
|
||||
|
||||
// Bug type superfan trainer config
|
||||
const config = getTrainerConfigForWave(scene.currentBattle.waveIndex);
|
||||
const spriteKey = config.getSpriteKey();
|
||||
encounter.enemyPartyConfigs.push({
|
||||
trainerConfig: config,
|
||||
female: true,
|
||||
});
|
||||
|
||||
encounter.spriteConfigs = [
|
||||
{
|
||||
spriteKey: spriteKey,
|
||||
fileRoot: "trainer",
|
||||
hasShadow: true,
|
||||
},
|
||||
];
|
||||
|
||||
return true;
|
||||
})
|
||||
.withTitle(`${namespace}.title`)
|
||||
.withDescription(`${namespace}.description`)
|
||||
.withQuery(`${namespace}.query`)
|
||||
.withSimpleOption(
|
||||
{
|
||||
buttonLabel: `${namespace}.option.1.label`,
|
||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.option.1.selected`,
|
||||
},
|
||||
],
|
||||
},
|
||||
async (scene: BattleScene) => {
|
||||
// Select battle the bug trainer
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||
|
||||
// Init the moves available for tutor
|
||||
const moveTutorOptions: PokemonMove[] = [];
|
||||
moveTutorOptions.push(new PokemonMove(PHYSICAL_TUTOR_MOVES[randSeedInt(PHYSICAL_TUTOR_MOVES.length)]));
|
||||
moveTutorOptions.push(new PokemonMove(SPECIAL_TUTOR_MOVES[randSeedInt(SPECIAL_TUTOR_MOVES.length)]));
|
||||
moveTutorOptions.push(new PokemonMove(STATUS_TUTOR_MOVES[randSeedInt(STATUS_TUTOR_MOVES.length)]));
|
||||
moveTutorOptions.push(new PokemonMove(MISC_TUTOR_MOVES[randSeedInt(MISC_TUTOR_MOVES.length)]));
|
||||
encounter.misc = {
|
||||
moveTutorOptions
|
||||
};
|
||||
|
||||
// Assigns callback that teaches move before continuing to rewards
|
||||
encounter.onRewards = doBugTypeMoveTutor;
|
||||
|
||||
setEncounterRewards(scene, { fillRemaining: true });
|
||||
await transitionMysteryEncounterIntroVisuals(scene, true, true);
|
||||
await initBattleWithEnemyConfig(scene, config);
|
||||
}
|
||||
)
|
||||
.withOption(MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||
.withPrimaryPokemonRequirement(new TypeRequirement(Type.BUG, false, 1)) // Must have 1 Bug type on team
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}.option.2.label`,
|
||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`
|
||||
})
|
||||
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||
// Player shows off their bug types
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
|
||||
// Player gets different rewards depending on the number of bug types they have
|
||||
const numBugTypes = scene.getParty().filter(p => p.isOfType(Type.BUG, true)).length;
|
||||
encounter.setDialogueToken("numBugTypes", numBugTypes.toString());
|
||||
|
||||
if (numBugTypes < 2) {
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL], fillRemaining: false });
|
||||
encounter.selectedOption!.dialogue!.selected = [
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.option.2.selected_0_to_1`,
|
||||
},
|
||||
];
|
||||
} else if (numBugTypes < 4) {
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL], fillRemaining: false });
|
||||
encounter.selectedOption!.dialogue!.selected = [
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.option.2.selected_2_to_3`,
|
||||
},
|
||||
];
|
||||
} else if (numBugTypes < 6) {
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL], fillRemaining: false });
|
||||
encounter.selectedOption!.dialogue!.selected = [
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.option.2.selected_4_to_5`,
|
||||
},
|
||||
];
|
||||
} else {
|
||||
// If player has any evolution/form change items that are valid for their party, will spawn one of those items in addition to a Master Ball
|
||||
const modifierOptions: ModifierTypeOption[] = [generateModifierTypeOption(scene, modifierTypes.MASTER_BALL)!, generateModifierTypeOption(scene, modifierTypes.MAX_LURE)!];
|
||||
const specialOptions: ModifierTypeOption[] = [];
|
||||
|
||||
const nonRareEvolutionModifier = generateModifierTypeOption(scene, modifierTypes.EVOLUTION_ITEM);
|
||||
if (nonRareEvolutionModifier) {
|
||||
specialOptions.push(nonRareEvolutionModifier);
|
||||
}
|
||||
const rareEvolutionModifier = generateModifierTypeOption(scene, modifierTypes.RARE_EVOLUTION_ITEM);
|
||||
if (rareEvolutionModifier) {
|
||||
specialOptions.push(rareEvolutionModifier);
|
||||
}
|
||||
const formChangeModifier = generateModifierTypeOption(scene, modifierTypes.FORM_CHANGE_ITEM);
|
||||
if (formChangeModifier) {
|
||||
specialOptions.push(formChangeModifier);
|
||||
}
|
||||
if (specialOptions.length > 0) {
|
||||
modifierOptions.push(specialOptions[randSeedInt(specialOptions.length)]);
|
||||
}
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifierOptions, fillRemaining: false });
|
||||
encounter.selectedOption!.dialogue!.selected = [
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.option.2.selected_6`,
|
||||
},
|
||||
];
|
||||
}
|
||||
})
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Player shows off their bug types
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.build())
|
||||
.withOption(MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||
// Meets one or both of the below reqs
|
||||
new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1),
|
||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
|
||||
))
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}.option.3.label`,
|
||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}.option.3.selected`,
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.option.3.selected_dialogue`,
|
||||
},
|
||||
],
|
||||
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
||||
})
|
||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||
// Get Pokemon held items and filter for valid ones
|
||||
const validItems = pokemon.getHeldItems().filter(item => {
|
||||
return item instanceof BypassSpeedChanceModifier ||
|
||||
item instanceof ContactHeldItemTransferChanceModifier ||
|
||||
(item instanceof AttackTypeBoosterModifier && (item.type as AttackTypeBoosterModifierType).moveType === Type.BUG);
|
||||
});
|
||||
|
||||
return validItems.map((modifier: PokemonHeldItemModifier) => {
|
||||
const option: OptionSelectItem = {
|
||||
label: modifier.type.name,
|
||||
handler: () => {
|
||||
// Pokemon and item selected
|
||||
encounter.setDialogueToken("selectedItem", modifier.type.name);
|
||||
encounter.misc = {
|
||||
chosenPokemon: pokemon,
|
||||
chosenModifier: modifier,
|
||||
};
|
||||
return true;
|
||||
},
|
||||
};
|
||||
return option;
|
||||
});
|
||||
};
|
||||
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
// If pokemon has valid item, it can be selected
|
||||
const hasValidItem = pokemon.getHeldItems().some(item => {
|
||||
return item instanceof BypassSpeedChanceModifier ||
|
||||
item instanceof ContactHeldItemTransferChanceModifier ||
|
||||
(item instanceof AttackTypeBoosterModifier && (item.type as AttackTypeBoosterModifierType).moveType === Type.BUG);
|
||||
});
|
||||
if (!hasValidItem) {
|
||||
return getEncounterText(scene, `${namespace}.option.3.invalid_selection`) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||
})
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
const modifier = encounter.misc.chosenModifier;
|
||||
|
||||
// Remove the modifier if its stacks go to 0
|
||||
modifier.stackCount -= 1;
|
||||
if (modifier.stackCount === 0) {
|
||||
scene.removeModifier(modifier);
|
||||
}
|
||||
scene.updateModifiers(true, true);
|
||||
|
||||
const bugNet = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!;
|
||||
bugNet.type.tier = ModifierTier.MASTER;
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [bugNet], guaranteedModifierTypeFuncs: [modifierTypes.REVIVER_SEED], fillRemaining: false });
|
||||
leaveEncounterWithoutBattle(scene, true);
|
||||
})
|
||||
.build())
|
||||
.withOutroDialogue([
|
||||
{
|
||||
text: `${namespace}.outro`,
|
||||
},
|
||||
])
|
||||
.build();
|
||||
|
||||
function getTrainerConfigForWave(waveIndex: number) {
|
||||
// Bug type superfan trainer config
|
||||
const config = trainerConfigs[TrainerType.BUG_TYPE_SUPERFAN].copy();
|
||||
config.name = i18next.t("trainerNames:bug_type_superfan");
|
||||
|
||||
const pool3Copy = POOL_3_POKEMON.slice(0);
|
||||
randSeedShuffle(pool3Copy);
|
||||
const pool3Mon = pool3Copy.pop()!;
|
||||
|
||||
if (waveIndex < 30) {
|
||||
// Use default template (2 AVG)
|
||||
config
|
||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true));
|
||||
} else if (waveIndex < 50) {
|
||||
config
|
||||
.setPartyTemplates(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE))
|
||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true));
|
||||
} else if (waveIndex < 70) {
|
||||
config
|
||||
.setPartyTemplates(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE))
|
||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true));
|
||||
} else if (waveIndex < 100) {
|
||||
config
|
||||
.setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE))
|
||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true));
|
||||
} else if (waveIndex < 120) {
|
||||
config
|
||||
.setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE))
|
||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => {
|
||||
p.formIndex = 1;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}))
|
||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true, p => {
|
||||
p.formIndex = 1;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}))
|
||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||
p.formIndex = pool3Mon.formIndex!;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}
|
||||
}));
|
||||
} else if (waveIndex < 140) {
|
||||
randSeedShuffle(pool3Copy);
|
||||
const pool3Mon2 = pool3Copy.pop()!;
|
||||
config
|
||||
.setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE))
|
||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => {
|
||||
p.formIndex = 1;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}))
|
||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true, p => {
|
||||
p.formIndex = 1;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}))
|
||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||
p.formIndex = pool3Mon.formIndex!;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}
|
||||
}))
|
||||
.setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => {
|
||||
if (!isNullOrUndefined(pool3Mon2.formIndex)) {
|
||||
p.formIndex = pool3Mon2.formIndex!;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}
|
||||
}));
|
||||
} else if (waveIndex < 160) {
|
||||
config
|
||||
.setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG)))
|
||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => {
|
||||
p.formIndex = 1;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}))
|
||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true, p => {
|
||||
p.formIndex = 1;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}))
|
||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||
p.formIndex = pool3Mon.formIndex!;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}
|
||||
}))
|
||||
.setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_4_POKEMON, TrainerSlot.TRAINER, true));
|
||||
} else {
|
||||
config
|
||||
.setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG)))
|
||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => {
|
||||
p.setBoss(true, 2);
|
||||
p.formIndex = 1;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}))
|
||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true, p => {
|
||||
p.setBoss(true, 2);
|
||||
p.formIndex = 1;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}))
|
||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||
p.formIndex = pool3Mon.formIndex!;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}
|
||||
}))
|
||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||
p.formIndex = pool3Mon.formIndex!;
|
||||
p.generateAndPopulateMoveset();
|
||||
p.generateName();
|
||||
}
|
||||
}))
|
||||
.setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_4_POKEMON, TrainerSlot.TRAINER, true));
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function getRandomPartyMemberFunc(speciesPool: Species[], trainerSlot: TrainerSlot = TrainerSlot.TRAINER, ignoreEvolution: boolean = false, postProcess?: (enemyPokemon: EnemyPokemon) => void) {
|
||||
return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => {
|
||||
let species = Utils.randSeedItem(speciesPool);
|
||||
if (!ignoreEvolution) {
|
||||
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength);
|
||||
}
|
||||
return scene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, undefined, postProcess);
|
||||
};
|
||||
}
|
||||
|
||||
function doBugTypeMoveTutor(scene: BattleScene): Promise<void> {
|
||||
return new Promise<void>(async resolve => {
|
||||
const moveOptions = scene.currentBattle.mysteryEncounter.misc.moveTutorOptions;
|
||||
await showEncounterDialogue(scene, `${namespace}.battle_won`, `${namespace}.speaker`);
|
||||
|
||||
const overlayScale = 1;
|
||||
const moveInfoOverlay = new MoveInfoOverlay(scene, {
|
||||
delayVisibility: false,
|
||||
scale: overlayScale,
|
||||
onSide: true,
|
||||
right: true,
|
||||
x: 1,
|
||||
y: -MoveInfoOverlay.getHeight(overlayScale, true) - 1,
|
||||
width: (scene.game.canvas.width / 6) - 2,
|
||||
});
|
||||
scene.ui.add(moveInfoOverlay);
|
||||
|
||||
const optionSelectItems = moveOptions.map((move: PokemonMove) => {
|
||||
const option: OptionSelectItem = {
|
||||
label: move.getName(),
|
||||
handler: () => {
|
||||
moveInfoOverlay.active = false;
|
||||
moveInfoOverlay.setVisible(false);
|
||||
return true;
|
||||
},
|
||||
onHover: () => {
|
||||
moveInfoOverlay.active = true;
|
||||
moveInfoOverlay.show(allMoves[move.moveId]);
|
||||
},
|
||||
};
|
||||
return option;
|
||||
});
|
||||
|
||||
const onHoverOverCancel = () => {
|
||||
moveInfoOverlay.active = false;
|
||||
moveInfoOverlay.setVisible(false);
|
||||
};
|
||||
|
||||
const result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel);
|
||||
// let forceExit = !!result;
|
||||
if (!result) {
|
||||
moveInfoOverlay.active = false;
|
||||
moveInfoOverlay.setVisible(false);
|
||||
}
|
||||
|
||||
// TODO: add menu to confirm player doesn't want to teach a move
|
||||
// while (!result && !forceExit) {
|
||||
// // Didn't teach a move, ask the player to confirm they don't want to teach a move
|
||||
// await showEncounterDialogue(scene, `${namespace}.confirm_no_teach`, `${namespace}.speaker`);
|
||||
// const confirm = await new Promise<boolean>(confirmResolve => {
|
||||
// scene.ui.setMode(Mode.CONFIRM, () => confirmResolve(true), () => confirmResolve(false));
|
||||
// });
|
||||
// scene.ui.clearText();
|
||||
// await scene.ui.setMode(Mode.MESSAGE);
|
||||
// if (confirm) {
|
||||
// // No teach, break out of loop
|
||||
// forceExit = true;
|
||||
// } else {
|
||||
// // Re-show learn menu
|
||||
// result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel);
|
||||
// if (!result) {
|
||||
// moveInfoOverlay.active = false;
|
||||
// moveInfoOverlay.setVisible(false);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Option select complete, handle if they are learning a move
|
||||
if (result && result.selectedOptionIndex < moveOptions.length) {
|
||||
scene.unshiftPhase(new LearnMovePhase(scene, result.selectedPokemonIndex, moveOptions[result.selectedOptionIndex].moveId));
|
||||
}
|
||||
|
||||
// Complete battle and go to rewards
|
||||
resolve();
|
||||
});
|
||||
}
|
@ -53,7 +53,7 @@ const RANDOM_ABILITY_POOL = [
|
||||
|
||||
/**
|
||||
* Clowning Around encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3807 | GitHub Issue #3807}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/69 | GitHub Issue #69}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const ClowningAroundEncounter: MysteryEncounter =
|
||||
@ -334,13 +334,13 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
||||
randSeedShuffle(priorityTypes);
|
||||
}
|
||||
|
||||
let newTypes: Type[];
|
||||
let newTypes;
|
||||
if (!originalTypes || originalTypes.length < 1) {
|
||||
newTypes = priorityTypes && priorityTypes.length > 0 ? [priorityTypes.pop()!] : [(randSeedInt(18) as Type)];
|
||||
newTypes = priorityTypes?.length > 0 ? [priorityTypes.pop()] : [(randSeedInt(18) as Type)];
|
||||
} else {
|
||||
newTypes = originalTypes.map(m => {
|
||||
if (priorityTypes && priorityTypes.length > 0) {
|
||||
const ret = priorityTypes.pop()!;
|
||||
if (priorityTypes?.length > 0) {
|
||||
const ret = priorityTypes.pop();
|
||||
randSeedShuffle(priorityTypes);
|
||||
return ret;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ const SENSU_STYLE_BIOMES = [
|
||||
|
||||
/**
|
||||
* Dancing Lessons encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3823 | GitHub Issue #3823}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/130 | GitHub Issue #130}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const DancingLessonsEncounter: MysteryEncounter =
|
||||
|
@ -71,7 +71,7 @@ const excludedBosses = [
|
||||
|
||||
/**
|
||||
* Dark Deal encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3806 | GitHub Issue #3806}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/61 | GitHub Issue #61}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const DarkDealEncounter: MysteryEncounter =
|
||||
|
@ -33,7 +33,7 @@ const OPTION_3_DISALLOWED_MODIFIERS = [
|
||||
|
||||
/**
|
||||
* Delibird-y encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3804 | GitHub Issue #3804}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/57 | GitHub Issue #57}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const DelibirdyEncounter: MysteryEncounter =
|
||||
@ -115,7 +115,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), undefined, true);
|
||||
} else {
|
||||
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.ABILITY_CHARM));
|
||||
@ -190,7 +190,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), undefined, true);
|
||||
} else {
|
||||
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.CANDY_JAR));
|
||||
@ -203,7 +203,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), undefined, true);
|
||||
} else {
|
||||
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.HEALING_CHARM));
|
||||
@ -283,7 +283,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), undefined, true);
|
||||
} else {
|
||||
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.BERRY_POUCH));
|
||||
|
@ -17,7 +17,7 @@ const namespace = "mysteryEncounter:departmentStoreSale";
|
||||
|
||||
/**
|
||||
* Department Store Sale encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3797 | GitHub Issue #3797}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/33 | GitHub Issue #33}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
||||
|
@ -16,7 +16,7 @@ const namespace = "mysteryEncounter:fieldTrip";
|
||||
|
||||
/**
|
||||
* Field Trip encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3794 | GitHub Issue #3794}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/17 | GitHub Issue #17}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const FieldTripEncounter: MysteryEncounter =
|
||||
@ -126,10 +126,10 @@ export const FieldTripEncounter: MysteryEncounter =
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
if (encounter.misc.correctMove) {
|
||||
const modifiers = [
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.ATK])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.DEF])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPD])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.ATK]),
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.DEF]),
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPD]),
|
||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT),
|
||||
];
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||
@ -218,10 +218,10 @@ export const FieldTripEncounter: MysteryEncounter =
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
if (encounter.misc.correctMove) {
|
||||
const modifiers = [
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPATK])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPDEF])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPD])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPATK]),
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPDEF]),
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPD]),
|
||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT),
|
||||
];
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||
@ -304,10 +304,10 @@ export const FieldTripEncounter: MysteryEncounter =
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
if (encounter.misc.correctMove) {
|
||||
const modifiers = [
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.ACC])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPD])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!,
|
||||
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.ACC]),
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_BOOSTER, [TempBattleStat.SPD]),
|
||||
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL),
|
||||
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER),
|
||||
];
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||
|
@ -33,7 +33,7 @@ const DAMAGE_PERCENTAGE: number = 20;
|
||||
|
||||
/**
|
||||
* Fiery Fallout encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3814 | GitHub Issue #3814}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/88 | GitHub Issue #88}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const FieryFalloutEncounter: MysteryEncounter =
|
||||
|
@ -30,7 +30,7 @@ const namespace = "mysteryEncounter:fightOrFlight";
|
||||
|
||||
/**
|
||||
* Fight or Flight encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3795 | GitHub Issue #3795}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/24 | GitHub Issue #24}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const FightOrFlightEncounter: MysteryEncounter =
|
||||
|
@ -23,7 +23,7 @@ const namespace = "mysteryEncounter:lostAtSea";
|
||||
|
||||
/**
|
||||
* Lost at sea encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3793 | GitHub Issue #3793}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/9 | GitHub Issue #9}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.LOST_AT_SEA)
|
||||
@ -125,6 +125,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
* Generic handler for using a guiding pokemon to guide you back.
|
||||
*
|
||||
* @param scene Battle scene
|
||||
* @param guidePokemon pokemon choosen as a guide
|
||||
*/
|
||||
async function handlePokemonGuidingYouPhase(scene: BattleScene) {
|
||||
const laprasSpecies = getPokemonSpecies(Species.LAPRAS);
|
||||
|
@ -23,7 +23,7 @@ const namespace = "mysteryEncounter:mysteriousChallengers";
|
||||
|
||||
/**
|
||||
* Mysterious Challengers encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3801 | GitHub Issue #3801}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/41 | GitHub Issue #41}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const MysteriousChallengersEncounter: MysteryEncounter =
|
||||
|
@ -15,7 +15,7 @@ const namespace = "mysteryEncounter:mysteriousChest";
|
||||
|
||||
/**
|
||||
* Mysterious Chest encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3796 | GitHub Issue #3796}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/32 | GitHub Issue #32}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const MysteriousChestEncounter: MysteryEncounter =
|
||||
|
@ -17,7 +17,7 @@ const namespace = "mysteryEncounter:partTimer";
|
||||
|
||||
/**
|
||||
* Part Timer encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3813 | GitHub Issue #3813}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/82 | GitHub Issue #82}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const PartTimerEncounter: MysteryEncounter =
|
||||
@ -140,7 +140,7 @@ export const PartTimerEncounter: MysteryEncounter =
|
||||
}
|
||||
const moneyChange = scene.getWaveMoneyAmount(moneyMultiplier);
|
||||
updatePlayerMoney(scene, moneyChange, true, false);
|
||||
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
||||
await showEncounterText(scene, i18next.t("mysteryEncounter:receive_money", { amount: moneyChange }));
|
||||
await showEncounterText(scene, `${namespace}.pokemon_tired`);
|
||||
|
||||
setEncounterRewards(scene, { fillRemaining: true });
|
||||
@ -221,7 +221,7 @@ export const PartTimerEncounter: MysteryEncounter =
|
||||
}
|
||||
const moneyChange = scene.getWaveMoneyAmount(moneyMultiplier);
|
||||
updatePlayerMoney(scene, moneyChange, true, false);
|
||||
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
||||
await showEncounterText(scene, i18next.t("mysteryEncounter:receive_money", { amount: moneyChange }));
|
||||
await showEncounterText(scene, `${namespace}.pokemon_tired`);
|
||||
|
||||
setEncounterRewards(scene, { fillRemaining: true });
|
||||
@ -273,7 +273,7 @@ export const PartTimerEncounter: MysteryEncounter =
|
||||
await showEncounterDialogue(scene, `${namespace}.job_complete_good`, `${namespace}.speaker`);
|
||||
const moneyChange = scene.getWaveMoneyAmount(2.5);
|
||||
updatePlayerMoney(scene, moneyChange, true, false);
|
||||
await showEncounterText(scene, i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
|
||||
await showEncounterText(scene, i18next.t("mysteryEncounter:receive_money", { amount: moneyChange }));
|
||||
await showEncounterText(scene, `${namespace}.pokemon_tired`);
|
||||
|
||||
setEncounterRewards(scene, { fillRemaining: true });
|
||||
@ -290,50 +290,50 @@ export const PartTimerEncounter: MysteryEncounter =
|
||||
.build();
|
||||
|
||||
function doStrongWorkSfx(scene: BattleScene) {
|
||||
scene.playSound("battle_anims/PRSFX- Horn Drill1");
|
||||
scene.playSound("battle_anims/PRSFX- Horn Drill1");
|
||||
scene.playSound("PRSFX- Horn Drill1");
|
||||
scene.playSound("PRSFX- Horn Drill1");
|
||||
|
||||
scene.time.delayedCall(1000, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Guillotine2");
|
||||
scene.playSound("PRSFX- Guillotine2");
|
||||
});
|
||||
|
||||
scene.time.delayedCall(2000, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Heavy Slam2");
|
||||
scene.playSound("PRSFX- Heavy Slam2");
|
||||
});
|
||||
|
||||
scene.time.delayedCall(2500, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Guillotine2");
|
||||
scene.playSound("PRSFX- Guillotine2");
|
||||
});
|
||||
}
|
||||
|
||||
function doDeliverySfx(scene: BattleScene) {
|
||||
scene.playSound("battle_anims/PRSFX- Accelerock1");
|
||||
scene.playSound("PRSFX- Accelerock1");
|
||||
|
||||
scene.time.delayedCall(1500, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Extremespeed1");
|
||||
scene.playSound("PRSFX- Extremespeed1");
|
||||
});
|
||||
|
||||
scene.time.delayedCall(2000, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Extremespeed1");
|
||||
scene.playSound("PRSFX- Extremespeed1");
|
||||
});
|
||||
|
||||
scene.time.delayedCall(2250, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Agility");
|
||||
scene.playSound("PRSFX- Agility");
|
||||
});
|
||||
}
|
||||
|
||||
function doSalesSfx(scene: BattleScene) {
|
||||
scene.playSound("battle_anims/PRSFX- Captivate");
|
||||
scene.playSound("PRSFX- Captivate");
|
||||
|
||||
scene.time.delayedCall(1500, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Attract2");
|
||||
scene.playSound("PRSFX- Attract2");
|
||||
});
|
||||
|
||||
scene.time.delayedCall(2000, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Aurora Veil2");
|
||||
scene.playSound("PRSFX- Aurora Veil2");
|
||||
});
|
||||
|
||||
scene.time.delayedCall(3000, () => {
|
||||
scene.playSound("battle_anims/PRSFX- Attract2");
|
||||
scene.playSound("PRSFX- Attract2");
|
||||
});
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ const TRAINER_THROW_ANIMATION_TIMES = [512, 184, 768];
|
||||
|
||||
/**
|
||||
* Safari Zone encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3800 | GitHub Issue #3800}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/39 | GitHub Issue #39}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const SafariZoneEncounter: MysteryEncounter =
|
||||
@ -322,7 +322,7 @@ async function throwBait(scene: BattleScene, pokemon: EnemyPokemon): Promise<boo
|
||||
return new Promise(resolve => {
|
||||
scene.trainer.setTexture(`trainer_${scene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
|
||||
scene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[0], () => {
|
||||
scene.playSound("se/pb_throw");
|
||||
scene.playSound("pb_throw");
|
||||
|
||||
// Trainer throw frames
|
||||
scene.trainer.setFrame("2");
|
||||
@ -351,12 +351,12 @@ async function throwBait(scene: BattleScene, pokemon: EnemyPokemon): Promise<boo
|
||||
y: originalY - 5,
|
||||
loop: 6,
|
||||
onStart: () => {
|
||||
scene.playSound("battle-anims/PRSFX- Bug Bite");
|
||||
scene.playSound("PRSFX- Bug Bite");
|
||||
bait.setFrame("0002.png");
|
||||
},
|
||||
onLoop: () => {
|
||||
if (index % 2 === 0) {
|
||||
scene.playSound("battle-anims/PRSFX- Bug Bite");
|
||||
scene.playSound("PRSFX- Bug Bite");
|
||||
}
|
||||
if (index === 4) {
|
||||
bait.setFrame("0003.png");
|
||||
@ -388,7 +388,7 @@ async function throwMud(scene: BattleScene, pokemon: EnemyPokemon): Promise<bool
|
||||
return new Promise(resolve => {
|
||||
scene.trainer.setTexture(`trainer_${scene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
|
||||
scene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[0], () => {
|
||||
scene.playSound("se/pb_throw");
|
||||
scene.playSound("pb_throw");
|
||||
|
||||
// Trainer throw frames
|
||||
scene.trainer.setFrame("2");
|
||||
@ -407,7 +407,7 @@ async function throwMud(scene: BattleScene, pokemon: EnemyPokemon): Promise<bool
|
||||
duration: 500,
|
||||
onComplete: () => {
|
||||
// Mud frame 2
|
||||
scene.playSound("battle-anims/PRSFX- Sludge Bomb2");
|
||||
scene.playSound("PRSFX- Sludge Bomb2");
|
||||
mud.setFrame("0002.png");
|
||||
// Mud splat
|
||||
scene.time.delayedCall(200, () => {
|
||||
@ -433,10 +433,10 @@ async function throwMud(scene: BattleScene, pokemon: EnemyPokemon): Promise<bool
|
||||
y: originalY - 20,
|
||||
loop: 1,
|
||||
onStart: () => {
|
||||
scene.playSound("battle-anims/PRSFX- Taunt2");
|
||||
scene.playSound("PRSFX- Taunt2");
|
||||
},
|
||||
onLoop: () => {
|
||||
scene.playSound("battle-anims/PRSFX- Taunt2");
|
||||
scene.playSound("PRSFX- Taunt2");
|
||||
},
|
||||
onComplete: () => {
|
||||
resolve(true);
|
||||
|
@ -19,7 +19,7 @@ const namespace = "mysteryEncounter:shadyVitaminDealer";
|
||||
|
||||
/**
|
||||
* Shady Vitamin Dealer encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3798 | GitHub Issue #3798}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/34 | GitHub Issue #34}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
||||
@ -79,8 +79,8 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
||||
updatePlayerMoney(scene, -(encounter.options[0].requirements[0] as MoneyRequirement).requiredMoney);
|
||||
// Calculate modifiers and dialogue tokens
|
||||
const modifiers = [
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER)!,
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER)!,
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER),
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER),
|
||||
];
|
||||
encounter.setDialogueToken("boost1", modifiers[0].name);
|
||||
encounter.setDialogueToken("boost2", modifiers[1].name);
|
||||
@ -162,8 +162,8 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
||||
updatePlayerMoney(scene, -(encounter.options[1].requirements[0] as MoneyRequirement).requiredMoney);
|
||||
// Calculate modifiers and dialogue tokens
|
||||
const modifiers = [
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER)!,
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER)!,
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER),
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER),
|
||||
];
|
||||
encounter.setDialogueToken("boost1", modifiers[0].name);
|
||||
encounter.setDialogueToken("boost2", modifiers[1].name);
|
||||
|
@ -22,7 +22,7 @@ const namespace = "mysteryEncounter:slumberingSnorlax";
|
||||
|
||||
/**
|
||||
* Sleeping Snorlax encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3815 | GitHub Issue #3815}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/103 | GitHub Issue #103}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
||||
|
@ -29,7 +29,7 @@ const MACHINE_INTERFACING_TYPES = [Type.ELECTRIC, Type.STEEL];
|
||||
|
||||
/**
|
||||
* Teleporting Hijinks encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3817 | GitHub Issue #3817}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/119 | GitHub Issue #119}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const TeleportingHijinksEncounter: MysteryEncounter =
|
||||
@ -140,9 +140,10 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
||||
}],
|
||||
};
|
||||
|
||||
const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.STEEL])!;
|
||||
const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.ELECTRIC])!;
|
||||
const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.STEEL]);
|
||||
const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.ELECTRIC]);
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [magnet, metalCoat], fillRemaining: true });
|
||||
setEncounterExp(scene, encounter.selectedOption!.primaryPokemon!.id, 100);
|
||||
transitionMysteryEncounterIntroVisuals(scene, true, true);
|
||||
await initBattleWithEnemyConfig(scene, config);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ const MAX_POKEMON_PRICE_MULTIPLIER = 6;
|
||||
|
||||
/**
|
||||
* Pokemon Salesman encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3799 | GitHub Issue #3799}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/36 | GitHub Issue #36}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
||||
|
@ -23,7 +23,7 @@ const namespace = "mysteryEncounter:theStrongStuff";
|
||||
|
||||
/**
|
||||
* The Strong Stuff encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3803 | GitHub Issue #3803}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/54 | GitHub Issue #54}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const TheStrongStuffEncounter: MysteryEncounter =
|
||||
|
@ -26,7 +26,7 @@ const namespace = "mysteryEncounter:theWinstrateChallenge";
|
||||
|
||||
/**
|
||||
* The Winstrate Challenge encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3821 | GitHub Issue #3821}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/136 | GitHub Issue #136}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
||||
|
@ -24,7 +24,7 @@ const namespace = "mysteryEncounter:trainingSession";
|
||||
|
||||
/**
|
||||
* Training Session encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3802 | GitHub Issue #3802}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/43 | GitHub Issue #43}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const TrainingSessionEncounter: MysteryEncounter =
|
||||
|
@ -25,7 +25,7 @@ const SOUND_EFFECT_WAIT_TIME = 700;
|
||||
|
||||
/**
|
||||
* Trash to Treasure encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3809 | GitHub Issue #3809}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/74 | GitHub Issue #74}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const TrashToTreasureEncounter: MysteryEncounter =
|
||||
@ -177,7 +177,7 @@ async function tryApplyDigRewardItems(scene: BattleScene) {
|
||||
}
|
||||
}
|
||||
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: "2 " + leftovers.name }), undefined, true);
|
||||
|
||||
// First Shell bell
|
||||
@ -204,17 +204,17 @@ async function tryApplyDigRewardItems(scene: BattleScene) {
|
||||
}
|
||||
}
|
||||
|
||||
scene.playSound("bgm/item_fanfare");
|
||||
scene.playSound("item_fanfare");
|
||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: "2 " + shellBell.name }), undefined, true);
|
||||
}
|
||||
|
||||
async function doGarbageDig(scene: BattleScene) {
|
||||
scene.playSound("battle-anims/PRSFX- Dig2");
|
||||
scene.playSound("PRSFX- Dig2");
|
||||
scene.time.delayedCall(SOUND_EFFECT_WAIT_TIME, () => {
|
||||
scene.playSound("battle-anims/PRSFX- Dig2");
|
||||
scene.playSound("battle-anims/PRSFX- Venom Drench", { volume: 2 });
|
||||
scene.playSound("PRSFX- Dig2");
|
||||
scene.playSound("PRSFX- Venom Drench", { volume: 2 });
|
||||
});
|
||||
scene.time.delayedCall(SOUND_EFFECT_WAIT_TIME * 2, () => {
|
||||
scene.playSound("battle-anims/PRSFX- Dig2");
|
||||
scene.playSound("PRSFX- Dig2");
|
||||
});
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ import { getLevelTotalExp } from "#app/data/exp";
|
||||
/** i18n namespace for encounter */
|
||||
const namespace = "mysteryEncounter:weirdDream";
|
||||
|
||||
/** Exclude Ultra Beasts, Paradox, Eternatus, and all legendary/mythical/trio pokemon that are below 570 BST */
|
||||
const EXCLUDED_TRANSFORMATION_SPECIES = [
|
||||
/** Exclude Ultra Beasts (inludes Cosmog/Solgaleo/Lunala/Necrozma), Paradox (includes Miraidon/Koraidon), Eternatus, Urshifu, the Poison Chain trio, Ogerpon */
|
||||
const excludedPokemon = [
|
||||
Species.ETERNATUS,
|
||||
/** UBs */
|
||||
Species.NIHILEGO,
|
||||
@ -77,18 +77,9 @@ const EXCLUDED_TRANSFORMATION_SPECIES = [
|
||||
Species.FEZANDIPITI,
|
||||
];
|
||||
|
||||
const SUPER_LEGENDARY_BST_THRESHOLD = 600;
|
||||
const NON_LEGENDARY_BST_THRESHOLD = 570;
|
||||
const GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD = 450;
|
||||
|
||||
/** Value ranges of the resulting species BST transformations after adding values to original species */
|
||||
|
||||
const HIGH_BST_TRANSFORM_BASE_VALUES = [90, 110];
|
||||
const STANDARD_BST_TRANSFORM_BASE_VALUES = [40, 50];
|
||||
|
||||
/**
|
||||
* Weird Dream encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3822 | GitHub Issue #3822}
|
||||
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/137 | GitHub Issue #137}
|
||||
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||
*/
|
||||
export const WeirdDreamEncounter: MysteryEncounter =
|
||||
@ -234,9 +225,9 @@ function getTeamTransformations(scene: BattleScene): PokemonTransformation[] {
|
||||
});
|
||||
|
||||
// Only 1 Pokemon can be transformed into BST higher than 600
|
||||
let hasPokemonInSuperLegendaryBstThreshold = false;
|
||||
let hasPokemonBstHigherThan600 = false;
|
||||
// Only 1 other Pokemon can be transformed into BST between 570-600
|
||||
let hasPokemonInLegendaryBstThreshold = false;
|
||||
let hasPokemonBstBetween570And600 = false;
|
||||
|
||||
// First, roll 2 of the party members to new Pokemon at a +90 to +110 BST difference
|
||||
// Then, roll the remainder of the party members at a +40 to +50 BST difference
|
||||
@ -250,19 +241,19 @@ function getTeamTransformations(scene: BattleScene): PokemonTransformation[] {
|
||||
const bst = getOriginalBst(scene, removed);
|
||||
let newBstRange;
|
||||
if (i < 2) {
|
||||
newBstRange = HIGH_BST_TRANSFORM_BASE_VALUES;
|
||||
newBstRange = [90, 110];
|
||||
} else {
|
||||
newBstRange = STANDARD_BST_TRANSFORM_BASE_VALUES;
|
||||
newBstRange = [40, 50];
|
||||
}
|
||||
|
||||
const newSpecies = getTransformedSpecies(bst, newBstRange, hasPokemonInSuperLegendaryBstThreshold, hasPokemonInLegendaryBstThreshold, alreadyUsedSpecies);
|
||||
const newSpecies = getTransformedSpecies(bst, newBstRange, hasPokemonBstHigherThan600, hasPokemonBstBetween570And600, alreadyUsedSpecies);
|
||||
|
||||
const newSpeciesBst = newSpecies.getBaseStatTotal();
|
||||
if (newSpeciesBst > SUPER_LEGENDARY_BST_THRESHOLD) {
|
||||
hasPokemonInSuperLegendaryBstThreshold = true;
|
||||
if (newSpeciesBst > 600) {
|
||||
hasPokemonBstHigherThan600 = true;
|
||||
}
|
||||
if (newSpeciesBst <= SUPER_LEGENDARY_BST_THRESHOLD && newSpeciesBst >= NON_LEGENDARY_BST_THRESHOLD) {
|
||||
hasPokemonInLegendaryBstThreshold = true;
|
||||
if (newSpeciesBst <= 600 && newSpeciesBst >= 570) {
|
||||
hasPokemonBstBetween570And600 = true;
|
||||
}
|
||||
|
||||
|
||||
@ -308,8 +299,9 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
|
||||
return newValue > iv ? newValue : iv;
|
||||
});
|
||||
|
||||
|
||||
// For pokemon at/below 570 BST or any shiny pokemon, unlock it permanently as if you had caught it
|
||||
if (newPokemon.getSpeciesForm().getBaseStatTotal() <= NON_LEGENDARY_BST_THRESHOLD || newPokemon.isShiny()) {
|
||||
if (newPokemon.getSpeciesForm().getBaseStatTotal() <= 570 || newPokemon.isShiny()) {
|
||||
if (newPokemon.getSpeciesForm().abilityHidden && newPokemon.abilityIndex === newPokemon.getSpeciesForm().getAbilityCount() - 1) {
|
||||
scene.validateAchv(achvs.HIDDEN_ABILITY);
|
||||
}
|
||||
@ -380,8 +372,8 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
|
||||
scene.addModifier(item, false, false, false, true);
|
||||
}
|
||||
|
||||
// Any pokemon that is at or below 450 BST gets +20 permanent BST to 3 stats: HP (halved, +10), lowest of Atk/SpAtk, and lowest of Def/SpDef
|
||||
if (newPokemon.getSpeciesForm().getBaseStatTotal() <= GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD) {
|
||||
// Any pokemon that is at or below 450 BST gets +20 permanent BST to 3 stats: HP, lowest of Atk/SpAtk, and lowest of Def/SpDef
|
||||
if (newPokemon.getSpeciesForm().getBaseStatTotal() <= 450) {
|
||||
const stats: Stat[] = [Stat.HP];
|
||||
const baseStats = newPokemon.getSpeciesForm().baseStats.slice(0);
|
||||
// Attack or SpAtk
|
||||
@ -443,9 +435,9 @@ function getTransformedSpecies(originalBst: number, bstSearchRange: [number, num
|
||||
const speciesBst = s.getBaseStatTotal();
|
||||
const bstInRange = speciesBst >= bstMin && speciesBst <= bstCap;
|
||||
// Checks that a Pokemon has not already been added in the +600 or 570-600 slots;
|
||||
const validBst = (!hasPokemonBstBetween570And600 || (speciesBst < NON_LEGENDARY_BST_THRESHOLD || speciesBst > SUPER_LEGENDARY_BST_THRESHOLD)) &&
|
||||
(!hasPokemonBstHigherThan600 || speciesBst <= SUPER_LEGENDARY_BST_THRESHOLD);
|
||||
return bstInRange && validBst && !EXCLUDED_TRANSFORMATION_SPECIES.includes(s.speciesId);
|
||||
const validBst = (!hasPokemonBstBetween570And600 || (speciesBst < 570 || speciesBst > 600)) &&
|
||||
(!hasPokemonBstHigherThan600 || speciesBst <= 600);
|
||||
return bstInRange && validBst && !excludedPokemon.includes(s.speciesId);
|
||||
});
|
||||
|
||||
// There must be at least 20 species available before it will choose one
|
||||
|
@ -81,7 +81,7 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption {
|
||||
}
|
||||
|
||||
meetsPrimaryRequirementAndPrimaryPokemonSelected(scene: BattleScene) {
|
||||
if (!this.primaryPokemonRequirements || this.primaryPokemonRequirements.length === 0) {
|
||||
if (!this.primaryPokemonRequirements) {
|
||||
return true;
|
||||
}
|
||||
let qualified: PlayerPokemon[] = scene.getParty();
|
||||
@ -101,7 +101,7 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.excludePrimaryFromSecondaryRequirements && this.secondaryPokemon && this.secondaryPokemon.length > 0) {
|
||||
if (this.excludePrimaryFromSecondaryRequirements && this.secondaryPokemon) {
|
||||
const truePrimaryPool: PlayerPokemon[] = [];
|
||||
const overlap: PlayerPokemon[] = [];
|
||||
for (const qp of qualified) {
|
||||
@ -135,7 +135,7 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption {
|
||||
}
|
||||
|
||||
meetsSupportingRequirementAndSupportingPokemonSelected(scene: BattleScene) {
|
||||
if (!this.secondaryPokemonRequirements || this.secondaryPokemonRequirements.length === 0) {
|
||||
if (!this.secondaryPokemonRequirements) {
|
||||
this.secondaryPokemon = [];
|
||||
return true;
|
||||
}
|
||||
|
@ -13,8 +13,6 @@ import { StatusEffect } from "../status-effect";
|
||||
import { Type } from "../type";
|
||||
import { WeatherType } from "../weather";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { AttackTypeBoosterModifier } from "#app/modifier/modifier";
|
||||
import { AttackTypeBoosterModifierType } from "#app/modifier/modifier-type";
|
||||
|
||||
export interface EncounterRequirement {
|
||||
meetsRequirement(scene: BattleScene): boolean; // Boolean to see if a requirement is met
|
||||
@ -422,11 +420,11 @@ export class TypeRequirement extends EncounterPokemonRequirement {
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
let partyPokemon = scene.getParty();
|
||||
|
||||
if (isNullOrUndefined(partyPokemon)) {
|
||||
if (isNullOrUndefined(partyPokemon) || this?.requiredType?.length < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.excludeFainted) {
|
||||
if (!this.excludeFainted) {
|
||||
partyPokemon = partyPokemon.filter((pokemon) => !pokemon.isFainted());
|
||||
}
|
||||
|
||||
@ -797,7 +795,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon)) {
|
||||
if (isNullOrUndefined(partyPokemon) || this?.requiredHeldItemModifiers?.length < 0) {
|
||||
return false;
|
||||
}
|
||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
@ -830,53 +828,6 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
||||
}
|
||||
}
|
||||
|
||||
export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRequirement {
|
||||
requiredHeldItemTypes: Type[];
|
||||
minNumberOfPokemon: number;
|
||||
invertQuery: boolean;
|
||||
|
||||
constructor(heldItemTypes: Type | Type[], minNumberOfPokemon: number = 1, invertQuery: boolean = false) {
|
||||
super();
|
||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||
this.invertQuery = invertQuery;
|
||||
this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [heldItemTypes];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon)) {
|
||||
return false;
|
||||
}
|
||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredHeldItemTypes.some((heldItemType) => {
|
||||
return pokemon.getHeldItems().some((it) => {
|
||||
return it instanceof AttackTypeBoosterModifier && (it.type as AttackTypeBoosterModifierType).moveType === heldItemType;
|
||||
});
|
||||
}));
|
||||
} else {
|
||||
// for an inverted query, we only want to get the pokemon that have any held items that are NOT in requiredHeldItemModifiers
|
||||
// E.g. functions as a blacklist
|
||||
return partyPokemon.filter((pokemon) => pokemon.getHeldItems().filter((it) => {
|
||||
return !this.requiredHeldItemTypes.some(heldItemType => it instanceof AttackTypeBoosterModifier && (it.type as AttackTypeBoosterModifierType).moveType === heldItemType);
|
||||
}).length > 0);
|
||||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const requiredItems = pokemon?.getHeldItems().filter((it) => {
|
||||
return this.requiredHeldItemTypes.some(heldItemType => it instanceof AttackTypeBoosterModifier && (it.type as AttackTypeBoosterModifierType).moveType === heldItemType);
|
||||
});
|
||||
if (requiredItems && requiredItems.length > 0) {
|
||||
return ["heldItem", requiredItems[0].type.name];
|
||||
}
|
||||
return ["heldItem", ""];
|
||||
}
|
||||
}
|
||||
|
||||
export class LevelRequirement extends EncounterPokemonRequirement {
|
||||
requiredLevelRange: [number, number];
|
||||
minNumberOfPokemon: number;
|
||||
|
@ -122,8 +122,6 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
||||
onInit?: (scene: BattleScene) => boolean;
|
||||
/** Event when battlefield visuals have finished sliding in and the encounter dialogue begins */
|
||||
onVisualsStart?: (scene: BattleScene) => boolean;
|
||||
/** Event prior to any rewards logic in {@link MysteryEncounterRewardsPhase} */
|
||||
onRewards?: (scene: BattleScene) => Promise<void>;
|
||||
/** Will provide the player party EXP before rewards are displayed for that wave */
|
||||
doEncounterExp?: (scene: BattleScene) => boolean;
|
||||
/** Will provide the player a rewards shop for that wave */
|
||||
@ -263,7 +261,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
||||
}
|
||||
|
||||
meetsPrimaryRequirementAndPrimaryPokemonSelected(scene: BattleScene): boolean {
|
||||
if (!this.primaryPokemonRequirements || this.primaryPokemonRequirements.length === 0) {
|
||||
if (this.primaryPokemonRequirements.length === 0) {
|
||||
const activeMon = scene.getParty().filter(p => p.isActive(true));
|
||||
if (activeMon.length > 0) {
|
||||
this.primaryPokemon = activeMon[0];
|
||||
@ -286,7 +284,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.excludePrimaryFromSupportRequirements && this.secondaryPokemon && this.secondaryPokemon.length > 0) {
|
||||
if (this.excludePrimaryFromSupportRequirements && this.secondaryPokemon) {
|
||||
const truePrimaryPool: PlayerPokemon[] = [];
|
||||
const overlap: PlayerPokemon[] = [];
|
||||
for (const qp of qualified) {
|
||||
@ -320,7 +318,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
||||
}
|
||||
|
||||
meetsSecondaryRequirementAndSecondaryPokemonSelected(scene: BattleScene): boolean {
|
||||
if (!this.secondaryPokemonRequirements || this.secondaryPokemonRequirements.length === 0) {
|
||||
if (!this.secondaryPokemonRequirements) {
|
||||
this.secondaryPokemon = [];
|
||||
return true;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import { DancingLessonsEncounter } from "#app/data/mystery-encounters/encounters
|
||||
import { WeirdDreamEncounter } from "#app/data/mystery-encounters/encounters/weird-dream-encounter";
|
||||
import { TheWinstrateChallengeEncounter } from "#app/data/mystery-encounters/encounters/the-winstrate-challenge-encounter";
|
||||
import { TeleportingHijinksEncounter } from "#app/data/mystery-encounters/encounters/teleporting-hijinks-encounter";
|
||||
import { BugTypeSuperfanEncounter } from "#app/data/mystery-encounters/encounters/bug-type-superfan-encounter";
|
||||
|
||||
// Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * <number of missed spawns>) / 256
|
||||
export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 1;
|
||||
@ -172,8 +171,7 @@ const anyBiomeEncounters: MysteryEncounterType[] = [
|
||||
MysteryEncounterType.BERRIES_ABOUND,
|
||||
MysteryEncounterType.CLOWNING_AROUND,
|
||||
MysteryEncounterType.WEIRD_DREAM,
|
||||
MysteryEncounterType.TELEPORTING_HIJINKS,
|
||||
MysteryEncounterType.BUG_TYPE_SUPERFAN
|
||||
MysteryEncounterType.TELEPORTING_HIJINKS
|
||||
];
|
||||
|
||||
/**
|
||||
@ -278,7 +276,6 @@ export function initMysteryEncounters() {
|
||||
allMysteryEncounters[MysteryEncounterType.WEIRD_DREAM] = WeirdDreamEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.THE_WINSTRATE_CHALLENGE] = TheWinstrateChallengeEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.TELEPORTING_HIJINKS] = TeleportingHijinksEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.BUG_TYPE_SUPERFAN] = BugTypeSuperfanEncounter;
|
||||
|
||||
// Add extreme encounters to biome map
|
||||
extremeBiomeEncounters.forEach(encounter => {
|
||||
|
@ -36,7 +36,8 @@ export const DANCING_MOVES = [
|
||||
Moves.QUIVER_DANCE,
|
||||
Moves.SWORDS_DANCE,
|
||||
Moves.TEETER_DANCE,
|
||||
Moves.VICTORY_DANCE
|
||||
Moves.VICTORY_DANCE,
|
||||
Moves.KNOCK_OFF
|
||||
];
|
||||
|
||||
export const DISTRACTION_MOVES = [
|
||||
|
@ -64,7 +64,7 @@ export function doTrainerExclamation(scene: BattleScene) {
|
||||
}
|
||||
});
|
||||
|
||||
scene.playSound("battle_anims/GEN8- Exclaim", { volume: 0.7 });
|
||||
scene.playSound("GEN8- Exclaim", { volume: 0.7 });
|
||||
}
|
||||
|
||||
export interface EnemyPokemonConfig {
|
||||
@ -363,13 +363,13 @@ export function updatePlayerMoney(scene: BattleScene, changeValue: number, playS
|
||||
scene.updateMoneyText();
|
||||
scene.animateMoneyChanged(false);
|
||||
if (playSound) {
|
||||
scene.playSound("se/buy");
|
||||
scene.playSound("buy");
|
||||
}
|
||||
if (showMessage) {
|
||||
if (changeValue < 0) {
|
||||
scene.queueMessage(i18next.t("mysteryEncounterMessages:paid_money", { amount: -changeValue }), null, true);
|
||||
scene.queueMessage(i18next.t("mysteryEncounter:paid_money", { amount: -changeValue }), null, true);
|
||||
} else {
|
||||
scene.queueMessage(i18next.t("mysteryEncounterMessages:receive_money", { amount: changeValue }), null, true);
|
||||
scene.queueMessage(i18next.t("mysteryEncounter:receive_money", { amount: changeValue }), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -380,20 +380,17 @@ export function updatePlayerMoney(scene: BattleScene, changeValue: number, playS
|
||||
* @param modifier
|
||||
* @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
||||
*/
|
||||
export function generateModifierType(scene: BattleScene, modifier: () => ModifierType, pregenArgs?: any[]): ModifierType | null {
|
||||
const modifierId = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifier);
|
||||
if (!modifierId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let result: ModifierType = modifierTypes[modifierId]();
|
||||
export function generateModifierType(scene: BattleScene, modifier: () => ModifierType, pregenArgs?: any[]): ModifierType {
|
||||
const modifierId = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifier)!;
|
||||
let result: ModifierType = modifierTypes[modifierId]?.();
|
||||
|
||||
// Populates item id and tier (order matters)
|
||||
result = result
|
||||
.withIdFromFunc(modifierTypes[modifierId])
|
||||
.withTierFromPool();
|
||||
|
||||
return result instanceof ModifierTypeGenerator ? result.generateType(scene.getParty(), pregenArgs) : result;
|
||||
const generatedResult = result instanceof ModifierTypeGenerator ? result.generateType(scene.getParty(), pregenArgs) : result;
|
||||
return generatedResult ?? result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -402,12 +399,9 @@ export function generateModifierType(scene: BattleScene, modifier: () => Modifie
|
||||
* @param modifier
|
||||
* @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
||||
*/
|
||||
export function generateModifierTypeOption(scene: BattleScene, modifier: () => ModifierType, pregenArgs?: any[]): ModifierTypeOption | null {
|
||||
export function generateModifierTypeOption(scene: BattleScene, modifier: () => ModifierType, pregenArgs?: any[]): ModifierTypeOption {
|
||||
const result = generateModifierType(scene, modifier, pregenArgs);
|
||||
if (result) {
|
||||
return new ModifierTypeOption(result, 0);
|
||||
}
|
||||
return result;
|
||||
return new ModifierTypeOption(result, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -422,7 +416,7 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p
|
||||
return new Promise(resolve => {
|
||||
const modeToSetOnExit = scene.ui.getMode();
|
||||
|
||||
// Open party screen to choose pokemon
|
||||
// Open party screen to choose pokemon to train
|
||||
scene.ui.setMode(Mode.PARTY, PartyUiMode.SELECT, -1, (slotIndex: integer, option: PartyOption) => {
|
||||
if (slotIndex < scene.getParty().length) {
|
||||
scene.ui.setMode(modeToSetOnExit).then(() => {
|
||||
@ -452,12 +446,12 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p
|
||||
label: i18next.t("menu:cancel"),
|
||||
handler: () => {
|
||||
scene.ui.clearText();
|
||||
scene.ui.setMode(modeToSetOnExit);
|
||||
scene.ui.setMode(Mode.MYSTERY_ENCOUNTER);
|
||||
resolve(false);
|
||||
return true;
|
||||
},
|
||||
onHover: () => {
|
||||
scene.ui.showText(i18next.t("mysteryEncounterMessages:cancel_option"));
|
||||
scene.ui.showText(i18next.t("mysteryEncounter:cancel_option"));
|
||||
}
|
||||
});
|
||||
|
||||
@ -467,11 +461,6 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p
|
||||
yOffset: 0,
|
||||
supportHover: true
|
||||
};
|
||||
|
||||
// Do hover over the starting selection option
|
||||
if (fullOptions[0].onHover) {
|
||||
fullOptions[0].onHover();
|
||||
}
|
||||
scene.ui.setModeWithoutClear(Mode.OPTION_SELECT, config, null, true);
|
||||
};
|
||||
|
||||
@ -495,97 +484,6 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p
|
||||
});
|
||||
}
|
||||
|
||||
interface PokemonAndOptionSelected {
|
||||
selectedPokemonIndex: number;
|
||||
selectedOptionIndex: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is intended for use inside onPreOptionPhase() of an encounter option
|
||||
* @param scene
|
||||
* If a second option needs to be selected, onPokemonSelected should return a OptionSelectItem[] object
|
||||
* @param options
|
||||
* @param optionSelectPromptKey
|
||||
* @param selectablePokemonFilter
|
||||
* @param onHoverOverCancelOption
|
||||
*/
|
||||
export function selectOptionThenPokemon(scene: BattleScene, options: OptionSelectItem[], optionSelectPromptKey: string, selectablePokemonFilter?: PokemonSelectFilter, onHoverOverCancelOption?: () => void): Promise<PokemonAndOptionSelected | null> {
|
||||
return new Promise<PokemonAndOptionSelected | null>(resolve => {
|
||||
const modeToSetOnExit = scene.ui.getMode();
|
||||
|
||||
const displayOptions = (config: OptionSelectConfig) => {
|
||||
scene.ui.setMode(Mode.MESSAGE).then(() => {
|
||||
if (!optionSelectPromptKey) {
|
||||
// Do hover over the starting selection option
|
||||
if (fullOptions[0].onHover) {
|
||||
fullOptions[0].onHover();
|
||||
}
|
||||
scene.ui.setMode(Mode.OPTION_SELECT, config);
|
||||
} else {
|
||||
showEncounterText(scene, optionSelectPromptKey).then(() => {
|
||||
// Do hover over the starting selection option
|
||||
if (fullOptions[0].onHover) {
|
||||
fullOptions[0].onHover();
|
||||
}
|
||||
scene.ui.setMode(Mode.OPTION_SELECT, config);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const selectPokemonAfterOption = (selectedOptionIndex: number) => {
|
||||
// Open party screen to choose a Pokemon
|
||||
scene.ui.setMode(Mode.PARTY, PartyUiMode.SELECT, -1, (slotIndex: integer, option: PartyOption) => {
|
||||
if (slotIndex < scene.getParty().length) {
|
||||
// Pokemon and option selected
|
||||
scene.ui.setMode(modeToSetOnExit).then(() => {
|
||||
const result: PokemonAndOptionSelected = { selectedPokemonIndex: slotIndex, selectedOptionIndex: selectedOptionIndex };
|
||||
resolve(result);
|
||||
});
|
||||
} else {
|
||||
// Back to first option select screen
|
||||
displayOptions(config);
|
||||
}
|
||||
}, selectablePokemonFilter);
|
||||
};
|
||||
|
||||
// Always appends a cancel option to bottom of options
|
||||
const fullOptions = options.map((option, index) => {
|
||||
// Update handler to resolve promise
|
||||
const onSelect = option.handler;
|
||||
option.handler = () => {
|
||||
onSelect();
|
||||
selectPokemonAfterOption(index);
|
||||
return true;
|
||||
};
|
||||
return option;
|
||||
}).concat({
|
||||
label: i18next.t("menu:cancel"),
|
||||
handler: () => {
|
||||
scene.ui.clearText();
|
||||
scene.ui.setMode(modeToSetOnExit);
|
||||
resolve(null);
|
||||
return true;
|
||||
},
|
||||
onHover: () => {
|
||||
if (onHoverOverCancelOption) {
|
||||
onHoverOverCancelOption();
|
||||
}
|
||||
scene.ui.showText(i18next.t("mysteryEncounterMessages:cancel_option"));
|
||||
}
|
||||
});
|
||||
|
||||
const config: OptionSelectConfig = {
|
||||
options: fullOptions,
|
||||
maxOptions: 7,
|
||||
yOffset: 0,
|
||||
supportHover: true
|
||||
};
|
||||
|
||||
displayOptions(config);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Will initialize reward phases to follow the mystery encounter
|
||||
* Can have shop displayed or skipped
|
||||
|
@ -335,7 +335,7 @@ export function trainerThrowPokeball(scene: BattleScene, pokemon: EnemyPokemon,
|
||||
return new Promise(resolve => {
|
||||
scene.trainer.setTexture(`trainer_${scene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
|
||||
scene.time.delayedCall(512, () => {
|
||||
scene.playSound("se/pb_throw");
|
||||
scene.playSound("pb_throw");
|
||||
|
||||
// Trainer throw frames
|
||||
scene.trainer.setFrame("2");
|
||||
@ -355,7 +355,7 @@ export function trainerThrowPokeball(scene: BattleScene, pokemon: EnemyPokemon,
|
||||
onComplete: () => {
|
||||
pokeball.setTexture("pb", `${pokeballAtlasKey}_opening`);
|
||||
scene.time.delayedCall(17, () => pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
|
||||
scene.playSound("se/pb_rel");
|
||||
scene.playSound("pb_rel");
|
||||
pokemon.tint(getPokeballTintColor(pokeballType));
|
||||
|
||||
addPokeballOpenParticles(scene, pokeball.x, pokeball.y, pokeballType);
|
||||
@ -369,7 +369,7 @@ export function trainerThrowPokeball(scene: BattleScene, pokemon: EnemyPokemon,
|
||||
onComplete: () => {
|
||||
pokeball.setTexture("pb", `${pokeballAtlasKey}_opening`);
|
||||
pokemon.setVisible(false);
|
||||
scene.playSound("se/pb_catch");
|
||||
scene.playSound("pb_catch");
|
||||
scene.time.delayedCall(17, () => pokeball.setTexture("pb", `${pokeballAtlasKey}`));
|
||||
|
||||
const doShake = () => {
|
||||
@ -397,13 +397,13 @@ export function trainerThrowPokeball(scene: BattleScene, pokemon: EnemyPokemon,
|
||||
failCatch(scene, pokemon, originalY, pokeball, pokeballType).then(() => resolve(false));
|
||||
} else if (shakeCount++ < 3) {
|
||||
if (randSeedInt(65536) < ballTwitchRate) {
|
||||
scene.playSound("se/pb_move");
|
||||
scene.playSound("pb_move");
|
||||
} else {
|
||||
shakeCounter.stop();
|
||||
failCatch(scene, pokemon, originalY, pokeball, pokeballType).then(() => resolve(false));
|
||||
}
|
||||
} else {
|
||||
scene.playSound("se/pb_lock");
|
||||
scene.playSound("pb_lock");
|
||||
addPokeballCaptureStars(scene, pokeball);
|
||||
|
||||
const pbTint = scene.add.sprite(pokeball.x, pokeball.y, "pb", "pb");
|
||||
@ -445,7 +445,7 @@ export function trainerThrowPokeball(scene: BattleScene, pokemon: EnemyPokemon,
|
||||
|
||||
function failCatch(scene: BattleScene, pokemon: EnemyPokemon, originalY: number, pokeball: Phaser.GameObjects.Sprite, pokeballType: PokeballType) {
|
||||
return new Promise<void>(resolve => {
|
||||
scene.playSound("se/pb_rel");
|
||||
scene.playSound("pb_rel");
|
||||
pokemon.setY(originalY);
|
||||
if (pokemon.status?.effect !== StatusEffect.SLEEP) {
|
||||
pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 });
|
||||
@ -591,7 +591,7 @@ function removePb(scene: BattleScene, pokeball: Phaser.GameObjects.Sprite) {
|
||||
|
||||
export async function doPokemonFlee(scene: BattleScene, pokemon: EnemyPokemon): Promise<void> {
|
||||
await new Promise<void>(resolve => {
|
||||
scene.playSound("se/flee");
|
||||
scene.playSound("flee");
|
||||
// Ease pokemon out
|
||||
scene.tweens.add({
|
||||
targets: pokemon,
|
||||
@ -635,50 +635,3 @@ export function doPlayerFlee(scene: BattleScene, pokemon: EnemyPokemon): Promise
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Bug Species and their corresponding weights
|
||||
const GOLDEN_BUG_NET_SPECIES_POOL: [Species, number][] = [
|
||||
[Species.SCYTHER, 40],
|
||||
[Species.SCIZOR, 40],
|
||||
[Species.KLEAVOR, 40],
|
||||
[Species.PINSIR, 40],
|
||||
[Species.HERACROSS, 40],
|
||||
[Species.YANMA, 40],
|
||||
[Species.YANMEGA, 40],
|
||||
[Species.SHUCKLE, 40],
|
||||
[Species.ANORITH, 40],
|
||||
[Species.ARMALDO, 40],
|
||||
[Species.ESCAVALIER, 40],
|
||||
[Species.ACCELGOR, 40],
|
||||
[Species.JOLTIK, 40],
|
||||
[Species.GALVANTULA, 40],
|
||||
[Species.DURANT, 40],
|
||||
[Species.LARVESTA, 40],
|
||||
[Species.VOLCARONA, 40],
|
||||
[Species.DEWPIDER, 40],
|
||||
[Species.ARAQUANID, 40],
|
||||
[Species.WIMPOD, 40],
|
||||
[Species.GOLISOPOD, 40],
|
||||
[Species.SIZZLIPEDE, 40],
|
||||
[Species.CENTISKORCH, 40],
|
||||
[Species.NYMBLE, 40],
|
||||
[Species.LOKIX, 40],
|
||||
[Species.BUZZWOLE, 1],
|
||||
[Species.PHEROMOSA, 1],
|
||||
];
|
||||
|
||||
export function getGoldenBugNetSpecies(scene: BattleScene, waveIndex: integer, level: integer): PokemonSpecies {
|
||||
const totalWeight = GOLDEN_BUG_NET_SPECIES_POOL.reduce((a, b) => a + b[1], 0);
|
||||
const roll = randSeedInt(totalWeight);
|
||||
|
||||
let w = 0;
|
||||
for (const species of GOLDEN_BUG_NET_SPECIES_POOL) {
|
||||
w += species[1];
|
||||
if (roll < w) {
|
||||
return getPokemonSpecies(species);
|
||||
}
|
||||
}
|
||||
|
||||
// Defaults to Scyther
|
||||
return getPokemonSpecies(GOLDEN_BUG_NET_SPECIES_POOL[0][0]);
|
||||
}
|
||||
|
@ -2104,7 +2104,5 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
.setPartyTemplates(trainerPartyTemplates.ONE_AVG),
|
||||
[TrainerType.VITO]: new TrainerConfig(++t).setName("Vito").setTitle("The Winstrates")
|
||||
.setMoneyMultiplier(2)
|
||||
.setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(2, PartyMemberStrength.STRONG))),
|
||||
[TrainerType.BUG_TYPE_SUPERFAN]: new TrainerConfig(++t).setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER)
|
||||
.setPartyTemplates(new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE))
|
||||
.setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(2, PartyMemberStrength.STRONG)))
|
||||
};
|
||||
|
@ -24,6 +24,5 @@ export enum MysteryEncounterType {
|
||||
DANCING_LESSONS,
|
||||
WEIRD_DREAM,
|
||||
THE_WINSTRATE_CHALLENGE,
|
||||
TELEPORTING_HIJINKS,
|
||||
BUG_TYPE_SUPERFAN
|
||||
TELEPORTING_HIJINKS
|
||||
}
|
||||
|
@ -94,7 +94,6 @@ export enum TrainerType {
|
||||
VIVI,
|
||||
VICKY,
|
||||
VITO,
|
||||
BUG_TYPE_SUPERFAN,
|
||||
|
||||
BROCK = 200,
|
||||
MISTY,
|
||||
|
@ -59,7 +59,6 @@ import modifierSelectUiHandler from "./modifier-select-ui-handler.json";
|
||||
import moveTriggers from "./move-trigger.json";
|
||||
import runHistory from "./run-history.json";
|
||||
import { mysteryEncounter } from "#app/locales/en/mystery-encounter";
|
||||
import mysteryEncounterMessages from "./mystery-encounter-messages.json";
|
||||
|
||||
export const enConfig = {
|
||||
ability,
|
||||
@ -122,6 +121,5 @@ export const enConfig = {
|
||||
modifierSelectUiHandler,
|
||||
moveTriggers,
|
||||
runHistory,
|
||||
mysteryEncounter: mysteryEncounter,
|
||||
mysteryEncounterMessages
|
||||
mysteryEncounter: mysteryEncounter
|
||||
};
|
||||
|
@ -841,7 +841,7 @@
|
||||
"2": "We're pulling out all the stops to put your Pokémon down."
|
||||
},
|
||||
"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...\n $It's great how Trainers can interact."
|
||||
},
|
||||
"defeat": {
|
||||
"1": "You put up quite the display.\nBetter luck next time."
|
||||
@ -857,7 +857,7 @@
|
||||
},
|
||||
"winstrates_victoria": {
|
||||
"encounter": {
|
||||
"1": "My goodness! Aren't you young?$You must be quite the trainer to beat my husband, though.$Now I suppose it's my turn to battle!"
|
||||
"1": "My goodness! Aren't you young?\n $You must be quite the trainer to beat my husband, though.\n $Now I suppose it's my turn to battle!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Uwah! Just how strong are you?!"
|
||||
@ -865,7 +865,7 @@
|
||||
},
|
||||
"winstrates_vivi": {
|
||||
"encounter": {
|
||||
"1": "You're stronger than Mom? Wow!$But I'm strong, too!\nReally! Honestly!"
|
||||
"1": "You're stronger than Mom? Wow!\n $But I'm strong, too!\nReally! Honestly!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Huh? Did I really lose?\nSnivel... Grandmaaa!"
|
||||
@ -873,7 +873,7 @@
|
||||
},
|
||||
"winstrates_vicky": {
|
||||
"encounter": {
|
||||
"1": "How dare you make my precious\ngranddaughter cry!$I see I need to teach you a lesson.\nPrepare to feel the sting of defeat!"
|
||||
"1": "How dare you make my precious\ngranddaughter cry!\n $I see I need to teach you a lesson.\nPrepare to feel the sting of defeat!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Whoa! So strong!\nMy granddaughter wasn't lying."
|
||||
@ -881,7 +881,7 @@
|
||||
},
|
||||
"winstrates_vito": {
|
||||
"encounter": {
|
||||
"1": "I trained together with my whole family,\nevery one of us!$I'm not losing to anyone!"
|
||||
"1": "I trained together with my whole family,\nevery one of us!\n $I'm not losing to anyone!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "I was better than everyone in my family.\nI've never lost before..."
|
||||
|
@ -841,7 +841,7 @@
|
||||
"2": "We're pulling out all the stops to put your Pokémon down."
|
||||
},
|
||||
"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...\n $It's great how Trainers can interact."
|
||||
},
|
||||
"defeat": {
|
||||
"1": "You put up quite the display.\nBetter luck next time."
|
||||
@ -857,7 +857,7 @@
|
||||
},
|
||||
"winstrates_victoria": {
|
||||
"encounter": {
|
||||
"1": "My goodness! Aren't you young?$You must be quite the trainer to beat my husband, though.$Now I suppose it's my turn to battle!"
|
||||
"1": "My goodness! Aren't you young?\n $You must be quite the trainer to beat my husband, though.\n $Now I suppose it's my turn to battle!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Uwah! Just how strong are you?!"
|
||||
@ -865,7 +865,7 @@
|
||||
},
|
||||
"winstrates_vivi": {
|
||||
"encounter": {
|
||||
"1": "You're stronger than Mom? Wow!$But I'm strong, too!\nReally! Honestly!"
|
||||
"1": "You're stronger than Mom? Wow!\n $But I'm strong, too!\nReally! Honestly!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Huh? Did I really lose?\nSnivel... Grandmaaa!"
|
||||
@ -873,7 +873,7 @@
|
||||
},
|
||||
"winstrates_vicky": {
|
||||
"encounter": {
|
||||
"1": "How dare you make my precious\ngranddaughter cry!$I see I need to teach you a lesson.\nPrepare to feel the sting of defeat!"
|
||||
"1": "How dare you make my precious\ngranddaughter cry!\n $I see I need to teach you a lesson.\nPrepare to feel the sting of defeat!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Whoa! So strong!\nMy granddaughter wasn't lying."
|
||||
@ -881,7 +881,7 @@
|
||||
},
|
||||
"winstrates_vito": {
|
||||
"encounter": {
|
||||
"1": "I trained together with my whole family,\nevery one of us!$I'm not losing to anyone!"
|
||||
"1": "I trained together with my whole family,\nevery one of us!\n $I'm not losing to anyone!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "I was better than everyone in my family.\nI've never lost before..."
|
||||
|
@ -259,10 +259,9 @@
|
||||
"ENEMY_FUSED_CHANCE": { "name": "Fusion Token", "description": "Adds a 1% chance that a wild Pokémon will be a fusion." },
|
||||
|
||||
"MYSTERY_ENCOUNTER_SHUCKLE_JUICE": { "name": "Shuckle Juice" },
|
||||
"MYSTERY_ENCOUNTER_BLACK_SLUDGE": { "name": "Black Sludge", "description": "The stench is so powerful that shops will only sell you items at a steep cost increase." },
|
||||
"MYSTERY_ENCOUNTER_BLACK_SLUDGE": { "name": "Black Sludge", "description": "The stench is so powerful that healing items are no longer available to purchase in shops." },
|
||||
"MYSTERY_ENCOUNTER_MACHO_BRACE": { "name": "Macho Brace", "description": "Defeating a Pokémon grants the holder a Macho Brace stack. Each stack slightly boosts stats, with an extra bonus at max stacks." },
|
||||
"MYSTERY_ENCOUNTER_OLD_GATEAU": { "name": "Old Gateau", "description": "Increases the holder's {{stats}} stats by {{statValue}}." },
|
||||
"MYSTERY_ENCOUNTER_GOLDEN_BUG_NET": { "name": "Golden Bug Net", "description": "Imbues the owner with luck to find Bug Type Pokémon more often. Has a strange heft to it." }
|
||||
"MYSTERY_ENCOUNTER_OLD_GATEAU": { "name": "Old Gateau", "description": "Increases the holder's {{stats}} stats by {{statValue}}." }
|
||||
},
|
||||
"SpeciesBoosterItem": {
|
||||
"LIGHT_BALL": { "name": "Light Ball", "description": "It's a mysterious orb that boosts Pikachu's Attack and Sp. Atk stats." },
|
||||
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"paid_money": "You paid ₽{{amount, number}}.",
|
||||
"receive_money": "You received ₽{{amount, number}}!",
|
||||
"affects_pokedex": "Affects Pokédex Data",
|
||||
"cancel_option": "Return to encounter option select."
|
||||
}
|
@ -24,7 +24,6 @@ import dancingLessonsDialogue from "#app/locales/en/mystery-encounters/dancing-l
|
||||
import weirdDreamDialogue from "#app/locales/en/mystery-encounters/weird-dream-dialogue.json";
|
||||
import theWinstrateChallengeDialogue from "#app/locales/en/mystery-encounters/the-winstrate-challenge-dialogue.json";
|
||||
import teleportingHijinksDialogue from "#app/locales/en/mystery-encounters/teleporting-hijinks-dialogue.json";
|
||||
import bugTypeSuperfanDialogue from "#app/locales/en/mystery-encounters/bug-type-superfan-dialogue.json";
|
||||
|
||||
/**
|
||||
* Injection patterns that can be used:
|
||||
@ -45,6 +44,12 @@ export const mysteryEncounter = {
|
||||
// DO NOT REMOVE
|
||||
"unit_test_dialogue": "{{test}}{{test}} {{test{{test}}}} {{test1}} {{test\}} {{test\\}} {{test\\\}} {test}}",
|
||||
|
||||
// General use content
|
||||
"paid_money": "You paid ₽{{amount, number}}.",
|
||||
"receive_money": "You received ₽{{amount, number}}!",
|
||||
"affects_pokedex": "Affects Pokédex Data",
|
||||
"cancel_option": "Return to encounter option select.",
|
||||
|
||||
mysteriousChallengers: mysteriousChallengersDialogue,
|
||||
mysteriousChest: mysteriousChestDialogue,
|
||||
darkDeal: darkDealDialogue,
|
||||
@ -70,6 +75,5 @@ export const mysteryEncounter = {
|
||||
dancingLessons: dancingLessonsDialogue,
|
||||
weirdDream: weirdDreamDialogue,
|
||||
theWinstrateChallenge: theWinstrateChallengeDialogue,
|
||||
teleportingHijinks: teleportingHijinksDialogue,
|
||||
bugTypeSuperfan: bugTypeSuperfanDialogue
|
||||
teleportingHijinks: teleportingHijinksDialogue
|
||||
} as const;
|
||||
|
@ -1,29 +1,29 @@
|
||||
{
|
||||
"intro": "An extremely strong trainer approaches you...",
|
||||
"buck": {
|
||||
"intro_dialogue": "Yo, trainer! My name's Buck.$I have a super awesome proposal\nfor a strong trainer such as yourself!$I'm carrying two rare Pokémon Eggs with me,\nbut I'd like someone else to care for one.$If you can prove your strength as a trainer to me,\nI'll give you the rarer egg!",
|
||||
"intro_dialogue": "Yo, trainer! My name's Buck.\n $I have a super awesome proposal\nfor a strong trainer such as yourself!\n $I'm carrying two rare Pokémon Eggs with me,\nbut I'd like someone else to care for one.\n $If you can prove your strength as a trainer to me,\nI'll give you the rarer egg!",
|
||||
"accept": "Whoooo, I'm getting fired up!",
|
||||
"decline": "Darn, it looks like your\nteam isn't in peak condition.$Here, let me help with that."
|
||||
"decline": "Darn, it looks like your\nteam isn't in peak condition.\n $Here, let me help with that."
|
||||
},
|
||||
"cheryl": {
|
||||
"intro_dialogue": "Hello, my name's Cheryl.$I have a particularly interesting request,\nfor a strong trainer such as yourself.$I'm carrying two rare Pokémon Eggs with me,\nbut I'd like someone else to care for one.$If you can prove your strength as a trainer to me,\nI'll give you the rarer Egg!",
|
||||
"intro_dialogue": "Hello, my name's Cheryl.\n $I have a particularly interesting request,\nfor a strong trainer such as yourself.\n $I'm carrying two rare Pokémon Eggs with me,\nbut I'd like someone else to care for one.\n $If you can prove your strength as a trainer to me,\nI'll give you the rarer Egg!",
|
||||
"accept": "I hope you're ready!",
|
||||
"decline": "I understand, it looks like your team\nisn't in the best condition at the moment.$Here, let me help with that."
|
||||
"decline": "I understand, it looks like your team\nisn't in the best condition at the moment.\n $Here, let me help with that."
|
||||
},
|
||||
"marley": {
|
||||
"intro_dialogue": "...@d{64} I'm Marley.$I have an offer for you...$I'm carrying two Pokémon Eggs with me,\nbut I'd like someone else to care for one.$If you're stronger than me,\nI'll give you the rarer Egg.",
|
||||
"intro_dialogue": "...@d{64} I'm Marley.\n $I have an offer for you...\n $I'm carrying two Pokémon Eggs with me,\nbut I'd like someone else to care for one.\n $If you're stronger than me,\nI'll give you the rarer Egg.",
|
||||
"accept": "... I see.",
|
||||
"decline": "... I see.$Your Pokémon look hurt...\nLet me help."
|
||||
"decline": "... I see.\n $Your Pokémon look hurt...\nLet me help."
|
||||
},
|
||||
"mira": {
|
||||
"intro_dialogue": "Hi! I'm Mira!$Mira has a request\nfor a strong trainer like you!$Mira has two rare Pokémon Eggs,\nbut Mira wants someone else to take one!$If you show Mira that you're strong,\nMira will give you the rarer Egg!",
|
||||
"intro_dialogue": "Hi! I'm Mira!\n $Mira has a request\nfor a strong trainer like you!\n $Mira has two rare Pokémon Eggs,\nbut Mira wants someone else to take one!\n $If you show Mira that you're strong,\nMira will give you the rarer Egg!",
|
||||
"accept": "You'll battle Mira?\nYay!",
|
||||
"decline": "Aww, no battle?\nThat's okay!$Here, Mira will heal your team!"
|
||||
"decline": "Aww, no battle?\nThat's okay!\n $Here, Mira will heal your team!"
|
||||
},
|
||||
"riley": {
|
||||
"intro_dialogue": "I'm Riley.$I have an odd proposal\nfor a strong trainer such as yourself.$I'm carrying two rare Pokémon Eggs with me,\nbut I'd like to give one to another trainer.$If you can prove your strength to me,\nI'll give you the rarer Egg!",
|
||||
"intro_dialogue": "I'm Riley.\n $I have an odd proposal\nfor a strong trainer such as yourself.\n $I'm carrying two rare Pokémon Eggs with me,\nbut I'd like to give one to another trainer.\n $If you can prove your strength to me,\nI'll give you the rarer Egg!",
|
||||
"accept": "That look you have...\nLet's do this.",
|
||||
"decline": "I understand, your team looks beat up.$Here, let me help with that."
|
||||
"decline": "I understand, your team looks beat up.\n $Here, let me help with that."
|
||||
},
|
||||
"title": "A Trainer's Test",
|
||||
"description": "It seems this trainer is willing to give you an Egg regardless of your decision. However, if you can manage to defeat this strong trainer, you'll receive a much rarer Egg.",
|
||||
|
@ -9,17 +9,17 @@
|
||||
"tooltip": "(-) Tough Battle\n(+) Rewards from its Berry Hoard",
|
||||
"selected": "The Greedent stuffs its cheeks\nand prepares for battle!",
|
||||
"boss_enraged": "Greedent's fierce love for food has it incensed!",
|
||||
"food_stash": "It looks like the Greedent was guarding an enormous stash of food!$@s{item_fanfare}Each Pokémon in your party gains 1x Reviver Seed!"
|
||||
"food_stash": "It looks like the Greedent was guarding an enormous stash of food!\n $@s{item_fanfare}Each Pokémon in your party gains 1x Reviver Seed!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Reason with It",
|
||||
"tooltip": "(+) Regain Some Lost Berries",
|
||||
"selected": "Your pleading strikes a chord with the Greedent.$It doesn't give all your berries back, but still tosses a few in your direction."
|
||||
"selected": "Your pleading strikes a chord with the Greedent.\n $It doesn't give all your berries back, but still tosses a few in your direction."
|
||||
},
|
||||
"3": {
|
||||
"label": "Let It Have the Food",
|
||||
"tooltip": "(-) Lose All Berries\n(?) The Greedent Will Like You",
|
||||
"selected": "The Greedent devours the entire\nstash of berries in a flash!$Patting its stomach,\nit looks at you appreciatively.$Perhaps you could feed it\nmore berries on your adventure...$@s{level_up_fanfare}The Greedent wants to join your party!"
|
||||
"selected": "The Greedent devours the entire\nstash of berries in a flash!\n $Patting its stomach,\nit looks at you appreciatively.\n $Perhaps you could feed it\nmore berries on your adventure...\n $@s{level_up_fanfare}The Greedent wants to join your party!"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"intro": "You're stopped by a rich looking boy.",
|
||||
"speaker": "Rich Boy",
|
||||
"intro_dialogue": "Good day to you.$I can't help but notice that your\n{{strongestPokemon}} looks positively divine!$I've always wanted to have a pet like that!$I'd pay you handsomely,\nand also give you this old bauble!",
|
||||
"intro_dialogue": "Good day to you.\n $I can't help but notice that your\n{{strongestPokemon}} looks positively divine!\n $I've always wanted to have a pet like that!\n $I'd pay you handsomely,\nand also give you this old bauble!",
|
||||
"title": "An Offer You Can't Refuse",
|
||||
"description": "You're being offered a @[TOOLTIP_TITLE]{Shiny Charm} and {{price, money}} for your {{strongestPokemon}}!\n\nIt's an extremely good deal, but can you really bear to part with such a strong team member?",
|
||||
"query": "What will you do?",
|
||||
@ -9,7 +9,7 @@
|
||||
"1": {
|
||||
"label": "Accept the Deal",
|
||||
"tooltip": "(-) Lose {{strongestPokemon}}\n(+) Gain a @[TOOLTIP_TITLE]{Shiny Charm}\n(+) Gain {{price, money}}",
|
||||
"selected": "Wonderful!@d{32} Come along, {{strongestPokemon}}!$It's time to show you off to everyone at the yacht club!$They'll be so jealous!"
|
||||
"selected": "Wonderful!@d{32} Come along, {{strongestPokemon}}!\n $It's time to show you off to everyone at the yacht club!\n $They'll be so jealous!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Extort the Kid",
|
||||
@ -20,7 +20,7 @@
|
||||
"3": {
|
||||
"label": "Leave",
|
||||
"tooltip": "(-) No Rewards",
|
||||
"selected": "What a rotten day...$Ah, well. Let's return to the yacht club then, Liepard."
|
||||
"selected": "What a rotten day...\n $Ah, well. Let's return to the yacht club then, Liepard."
|
||||
}
|
||||
}
|
||||
}
|
@ -13,8 +13,8 @@
|
||||
"2": {
|
||||
"label": "Race to the Bush",
|
||||
"tooltip": "(-) {{fastestPokemon}} Uses its Speed\n(+) Gain Berries",
|
||||
"selected": "Your {{fastestPokemon}} races for the berry bush!$It manages to nab {{numBerries}} before the {{enemyPokemon}} can react!$You quickly retreat with your newfound prize.",
|
||||
"selected_bad": "Your {{fastestPokemon}} races for the berry bush!$Oh no! The {{enemyPokemon}} was faster and blocked off the approach!",
|
||||
"selected": "Your {{fastestPokemon}} races for the berry bush!\n $It manages to nab {{numBerries}} before the {{enemyPokemon}} can react!\n $You quickly retreat with your newfound prize.",
|
||||
"selected_bad": "Your {{fastestPokemon}} races for the berry bush!\n $Oh no! The {{enemyPokemon}} was faster and blocked off the approach!",
|
||||
"boss_enraged": "The opposing {{enemyPokemon}} has become enraged!"
|
||||
},
|
||||
"3": {
|
||||
|
@ -1,38 +0,0 @@
|
||||
{
|
||||
"intro": "An unusual trainer with all kinds of Bug paraphernalia blocks your way!",
|
||||
"intro_dialogue": "Hey, trainer! I'm on a mission to find the rarest Bug Pokémon in existence!$You must love Bug Pokémon too, right?\nEveryone loves Bug Pokémon!",
|
||||
"title": "The Bug-Type Superfan",
|
||||
"speaker": "Bug-Type Superfan",
|
||||
"description": "The trainer prattles, not even waiting for a response...\n\nIt seems the only way to get out of this situation is by catching the trainer's attention!",
|
||||
"query": "What will you do?",
|
||||
"option": {
|
||||
"1": {
|
||||
"label": "Offer to Battle",
|
||||
"tooltip": "(-) Challenging Battle\n(+) Teach a Pokémon a Bug Type Move",
|
||||
"selected": "A challenge, eh?\nMy bugs are more than ready for you!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Show Your Bug Types",
|
||||
"tooltip": "(+) Receive a Gift Item",
|
||||
"disabled_tooltip": "You need at least 1 Bug Type Pokémon on your team to select this.",
|
||||
"selected": "You show the trainer all your Bug Type Pokémon...",
|
||||
"selected_0_to_1": "Huh? You only have {{numBugTypes}}...$Guess I'm wasting my breath on someone like you...",
|
||||
"selected_2_3": "Hey, you've got {{numBugTypes}} Bug Types!\nNot bad.$Here, this might help you on your journey to catch more!",
|
||||
"selected_4_to_5": "What? You have {{numBugTypes}} Bug Types?\nNice!$You're not quite at my level, but I can see shades of myself in you!\n$Take this, my young apprentice!",
|
||||
"selected_6": "Whoa! {{numBugTypes}} Bug Types!\n$You must love Bug Types almost as much as I do!$Here, take this as a token of our camaraderie!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Gift a Bug Item",
|
||||
"tooltip": "(-) Give the trainer a Quick Claw, Grip Claw, or Silver Powder\n(+) Receive a Gift Item",
|
||||
"disabled_tooltip": "You need to have a Quick Claw, Grip Claw, or Silver Powder to select this.",
|
||||
"select_prompt": "Select an item to give.",
|
||||
"invalid_selection": "Pokémon doesn't have that kind of item.",
|
||||
"selected": "You hand the trainer a {{selectedItem}}.",
|
||||
"selected_dialogue": "Whoa! A {{selectedItem}}, for me?\nYou're not so bad, kid!$As a token of my appreciation,\nI want you to have this special gift!$It's been passed all through my family, and now I want you to have it!"
|
||||
}
|
||||
},
|
||||
"battle_won": "Your knowledge and skill were perfect at exploiting our weaknesses!$In exchange for the valuable lesson,\nallow me to teach one of your Pokémon a Bug Type Move!",
|
||||
"teach_move_prompt": "Select a move to teach a Pokémon.",
|
||||
"confirm_no_teach": "You sure you don't want to learn one of these great moves?",
|
||||
"outro": "I see great Bug Pokémon in your future!\nMay our paths cross again!$Bug out!"
|
||||
}
|
@ -13,14 +13,14 @@
|
||||
"2": {
|
||||
"label": "Learn Its Dance",
|
||||
"tooltip": "(+) Teach a Pokémon Revelation Dance",
|
||||
"selected": "You watch the Oricorio closely as it performs its dance...$@s{level_up_fanfare}Your {{selectedPokemon}} wants to learn Revelation Dance!"
|
||||
"selected": "You watch the Oricorio closely as it performs its dance...\n $@s{level_up_fanfare}Your {{selectedPokemon}} wants to learn Revelation Dance!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Show It a Dance",
|
||||
"tooltip": "(-) Teach the Oricorio a Dance Move\n(+) The Oricorio Will Like You",
|
||||
"disabled_tooltip": "Your Pokémon need to know a Dance move for this.",
|
||||
"select_prompt": "Select a Dance type move to use.",
|
||||
"selected": "The Oricorio watches in fascination as\n{{selectedPokemon}} shows off {{selectedMove}}!$It loves the display!$@s{level_up_fanfare}The Oricorio wants to join your party!"
|
||||
"selected": "The Oricorio watches in fascination as\n{{selectedPokemon}} shows off {{selectedMove}}!\n $It loves the display!\n $@s{level_up_fanfare}The Oricorio wants to join your party!"
|
||||
}
|
||||
},
|
||||
"invalid_selection": "This Pokémon doesn't know a Dance move"
|
||||
|
@ -3,7 +3,7 @@
|
||||
{
|
||||
"intro": "A strange man in a tattered coat\nstands in your way...",
|
||||
"speaker": "Shady Guy",
|
||||
"intro_dialogue": "Hey, you!$I've been working on a new device\nto bring out a Pokémon's latent power!$It completely rebinds the Pokémon's atoms\nat a molecular level into a far more powerful form.$Hehe...@d{64} I just need some sac-@d{32}\nErr, test subjects, to prove it works.",
|
||||
"intro_dialogue": "Hey, you!\n $I've been working on a new device\nto bring out a Pokémon's latent power!\n $It completely rebinds the Pokémon's atoms\nat a molecular level into a far more powerful form.\n $Hehe...@d{64} I just need some sac-@d{32}\nErr, test subjects, to prove it works.",
|
||||
"title": "Dark Deal",
|
||||
"description": "The disturbing fellow holds up some Pokéballs.\n\"I'll make it worth your while! You can have these strong Pokéballs as payment, All I need is a Pokémon from your team! Hehe...\"",
|
||||
"query": "What will you do?",
|
||||
@ -11,8 +11,8 @@
|
||||
"1": {
|
||||
"label": "Accept",
|
||||
"tooltip": "(+) 5 Rogue Balls\n(?) Enhance a Random Pokémon",
|
||||
"selected_dialogue": "Let's see, that {{pokeName}} will do nicely!$Remember, I'm not responsible\nif anything bad happens!@d{32} Hehe...",
|
||||
"selected_message": "The man hands you 5 Rogue Balls.${{pokeName}} hops into the strange machine...$Flashing lights and weird noises\nstart coming from the machine!$...@d{96} Something emerges\nfrom the device, raging wildly!"
|
||||
"selected_dialogue": "Let's see, that {{pokeName}} will do nicely!\n $Remember, I'm not responsible\nif anything bad happens!@d{32} Hehe...",
|
||||
"selected_message": "The man hands you 5 Rogue Balls.\n ${{pokeName}} hops into the strange machine...\n $Flashing lights and weird noises\nstart coming from the machine!\n $...@d{96} Something emerges\nfrom the device, raging wildly!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Refuse",
|
||||
|
@ -10,20 +10,20 @@
|
||||
"1": {
|
||||
"label": "Give Money",
|
||||
"tooltip": "(-) Give the Delibirds {{money, money}}\n(+) Receive a Gift Item",
|
||||
"selected": "You toss the money to the Delibirds,\nwho chatter amongst themselves excitedly.$They turn back to you and happily give you a present!"
|
||||
"selected": "You toss the money to the Delibirds,\nwho chatter amongst themselves excitedly.\n $They turn back to you and happily give you a present!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Give Food",
|
||||
"tooltip": "(-) Give the Delibirds a Berry or Reviver Seed\n(+) Receive a Gift Item",
|
||||
"select_prompt": "Select an item to give.",
|
||||
"selected": "You toss the {{chosenItem}} to the Delibirds,\nwho chatter amongst themselves excitedly.$They turn back to you and happily give you a present!"
|
||||
"selected": "You toss the {{chosenItem}} to the Delibirds,\nwho chatter amongst themselves excitedly.\n $They turn back to you and happily give you a present!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Give an Item",
|
||||
"tooltip": "(-) Give the Delibirds a Held Item\n(+) Receive a Gift Item",
|
||||
"select_prompt": "Select an item to give.",
|
||||
"selected": "You toss the {{chosenItem}} to the Delibirds,\nwho chatter amongst themselves excitedly.$They turn back to you and happily give you a present!"
|
||||
"selected": "You toss the {{chosenItem}} to the Delibirds,\nwho chatter amongst themselves excitedly.\n $They turn back to you and happily give you a present!"
|
||||
}
|
||||
},
|
||||
"outro": "The Delibird pack happily waddles off into the distance.$What a curious little exchange!"
|
||||
"outro": "The Delibird pack happily waddles off into the distance.\n $What a curious little exchange!"
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"intro": "It's a lady with a ton of shopping bags.",
|
||||
"speaker": "Shopper",
|
||||
"intro_dialogue": "Hello! Are you here for\nthe amazing sales too?$There's a special coupon that you can\nredeem for a free item during the sale!$I have an extra one. Here you go!",
|
||||
"intro_dialogue": "Hello! Are you here for\nthe amazing sales too?\n $There's a special coupon that you can\nredeem for a free item during the sale!\n $I have an extra one. Here you go!",
|
||||
"title": "Department Store Sale",
|
||||
"description": "There is merchandise in every direction! It looks like there are 4 counters where you can redeem the coupon for various items. The possibilities are endless!",
|
||||
"query": "Which counter will you go to?",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"intro": "It's a teacher and some school children!",
|
||||
"speaker": "Teacher",
|
||||
"intro_dialogue": "Hello, there! Would you be able to\nspare a minute for my students?$I'm teaching them about Pokémon moves\nand would love to show them a demonstration.$Would you mind showing us one of\nthe moves your Pokémon can use?",
|
||||
"intro_dialogue": "Hello, there! Would you be able to\nspare a minute for my students?\n $I'm teaching them about Pokémon moves\nand would love to show them a demonstration.\n $Would you mind showing us one of\nthe moves your Pokémon can use?",
|
||||
"title": "Field Trip",
|
||||
"description": "A teacher is requesting a move demonstration from a Pokémon. Depending on the move you choose, she might have something useful for you in exchange.",
|
||||
"query": "Which move category will you show off?",
|
||||
@ -19,8 +19,8 @@
|
||||
"tooltip": "(+) Status Item Rewards"
|
||||
},
|
||||
"selected": "{{pokeName}} shows off an awesome display of {{move}}!",
|
||||
"incorrect": "...$That isn't a {{moveCategory}} move!$I'm sorry, but I can't give you anything.",
|
||||
"lesson_learned": "Looks like you learned a valuable lesson?$Your Pokémon also gained some knowledge."
|
||||
"incorrect": "...\n $That isn't a {{moveCategory}} move!\n $I'm sorry, but I can't give you anything.",
|
||||
"lesson_learned": "Looks like you learned a valuable lesson?\n $Your Pokémon also gained some knowledge."
|
||||
},
|
||||
"second_option_prompt": "Choose a move for your Pokémon to use.",
|
||||
"outro_good": "Thank you so much for your kindness!\nI hope the items I had were helpful!",
|
||||
|
@ -7,20 +7,20 @@
|
||||
"1": {
|
||||
"label": "Find the Source",
|
||||
"tooltip": "(?) Discover the source\n(-) Hard Battle",
|
||||
"selected": "You push through the storm, and find two Volcarona in the middle of a mating dance!$They don't take kindly to the interruption and attack!"
|
||||
"selected": "You push through the storm, and find two Volcarona in the middle of a mating dance!\n $They don't take kindly to the interruption and attack!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Hunker Down",
|
||||
"tooltip": "(-) Suffer the effects of the weather",
|
||||
"selected": "The weather effects cause significant\nharm as you struggle to find shelter!$Your party takes 20% Max HP damage!",
|
||||
"selected": "The weather effects cause significant\nharm as you struggle to find shelter!\n $Your party takes 20% Max HP damage!",
|
||||
"target_burned": "Your {{burnedPokemon}} also became burned!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Your Fire Types Help",
|
||||
"tooltip": "(+) End the conditions\n(+) Gain a Charcoal",
|
||||
"disabled_tooltip": "You need at least 2 Fire Type Pokémon to choose this",
|
||||
"selected": "Your {{option3PrimaryName}} and {{option3SecondaryName}} guide you to where two Volcarona are in the middle of a mating dance!$Thankfully, your Pokémon are able to calm them,\nand they depart without issue."
|
||||
"selected": "Your {{option3PrimaryName}} and {{option3SecondaryName}} guide you to where two Volcarona are in the middle of a mating dance!\n $Thankfully, your Pokémon are able to calm them,\nand they depart without issue."
|
||||
}
|
||||
},
|
||||
"found_charcoal": "After the weather clears,\nyour {{leadPokemon}} spots something on the ground.$@s{item_fanfare}{{leadPokemon}} gained a Charcoal!"
|
||||
"found_charcoal": "After the weather clears,\nyour {{leadPokemon}} spots something on the ground.\n $@s{item_fanfare}{{leadPokemon}} gained a Charcoal!"
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
"label": "Steal the Item",
|
||||
"disabled_tooltip": "Your Pokémon need to know certain moves to choose this",
|
||||
"tooltip": "(+) {{option2PrimaryName}} uses {{option2PrimaryMove}}",
|
||||
"selected": ".@d{32}.@d{32}.@d{32}$Your {{option2PrimaryName}} helps you out and uses {{option2PrimaryMove}}!$You nabbed the item!"
|
||||
"selected": ".@d{32}.@d{32}.@d{32}\n $Your {{option2PrimaryName}} helps you out and uses {{option2PrimaryMove}}!\n $You nabbed the item!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Leave",
|
||||
|
@ -9,19 +9,19 @@
|
||||
"label_disabled": "Can't {{option1RequiredMove}}",
|
||||
"tooltip": "(+) {{option1PrimaryName}} saves you\n(+) {{option1PrimaryName}} gains some EXP",
|
||||
"tooltip_disabled": "You have no Pokémon to {{option1RequiredMove}} on",
|
||||
"selected": "{{option1PrimaryName}} swims ahead, guiding you back on track.${{option1PrimaryName}} seems to also have gotten stronger in this time of need!"
|
||||
"selected": "{{option1PrimaryName}} swims ahead, guiding you back on track.\n ${{option1PrimaryName}} seems to also have gotten stronger in this time of need!"
|
||||
},
|
||||
"2": {
|
||||
"label": "{{option2PrimaryName}} Might Help",
|
||||
"label_disabled": "Can't {{option2RequiredMove}}",
|
||||
"tooltip": "(+) {{option2PrimaryName}} saves you\n(+) {{option2PrimaryName}} gains some EXP",
|
||||
"tooltip_disabled": "You have no Pokémon to {{option2RequiredMove}} with",
|
||||
"selected": "{{option2PrimaryName}} flies ahead of your boat, guiding you back on track.${{option2PrimaryName}} seems to also have gotten stronger in this time of need!"
|
||||
"selected": "{{option2PrimaryName}} flies ahead of your boat, guiding you back on track.\n ${{option2PrimaryName}} seems to also have gotten stronger in this time of need!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Wander Aimlessly",
|
||||
"tooltip": "(-) Each of your Pokémon lose {{damagePercentage}}% of their total HP",
|
||||
"selected": "You float about in the boat, steering without direction until you finally spot a landmark you remember.$You and your Pokémon are fatigued from the whole ordeal."
|
||||
"selected": "You float about in the boat, steering without direction until you finally spot a landmark you remember.\n $You and your Pokémon are fatigued from the whole ordeal."
|
||||
}
|
||||
},
|
||||
"outro": "You are back on track."
|
||||
|
@ -12,7 +12,7 @@
|
||||
"good": "Some pretty nice tools and items.",
|
||||
"great": "A couple great tools and items!",
|
||||
"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 trapped!\n $Your {{pokeName}} jumps in front of you\nbut is KOed in the process."
|
||||
},
|
||||
"2": {
|
||||
"label": "Too Risky, Leave",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"intro": "A busy worker flags you down.",
|
||||
"speaker": "Worker",
|
||||
"intro_dialogue": "You look like someone with lots of capable Pokémon!$We can pay you if you're able to help us with some part-time work!",
|
||||
"intro_dialogue": "You look like someone with lots of capable Pokémon!\n $We can pay you if you're able to help us with some part-time work!",
|
||||
"title": "Part-Timer",
|
||||
"description": "Looks like there are plenty of tasks that need to be done. Depending how well-suited your Pokémon is to a task, they might earn more or less money.",
|
||||
"query": "Which job will you choose?",
|
||||
@ -24,8 +24,8 @@
|
||||
"selected": "Your {{option3PrimaryName}} spends the day using {{option3PrimaryMove}} to attract customers to the business!"
|
||||
}
|
||||
},
|
||||
"job_complete_good": "Thanks for the assistance!\nYour {{selectedPokemon}} was incredibly helpful!$Here's your check for the day.",
|
||||
"job_complete_bad": "Your {{selectedPokemon}} helped us out a bit!$Here's your check for the day.",
|
||||
"job_complete_good": "Thanks for the assistance!\nYour {{selectedPokemon}} was incredibly helpful!\n $Here's your check for the day.",
|
||||
"job_complete_bad": "Your {{selectedPokemon}} helped us out a bit!\n $Here's your check for the day.",
|
||||
"pokemon_tired": "Your {{selectedPokemon}} is worn out!\nThe PP of all its moves was reduced to 2!",
|
||||
"outro": "Come back and help out again sometime!"
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"intro": "A man in a dark coat approaches you.",
|
||||
"speaker": "Shady Salesman",
|
||||
"intro_dialogue": ".@d{16}.@d{16}.@d{16}$I've got the goods if you've got the money.$Make sure your Pokémon can handle it though.",
|
||||
"intro_dialogue": ".@d{16}.@d{16}.@d{16}\n $I've got the goods if you've got the money.\n $Make sure your Pokémon can handle it though.",
|
||||
"title": "The Vitamin Dealer",
|
||||
"description": "The man opens his jacket to reveal some Pokémon vitamins. The numbers he quotes seem like a really good deal. Almost too good...\nHe offers two package deals to choose from.",
|
||||
"query": "Which deal will choose?",
|
||||
@ -20,10 +20,10 @@
|
||||
"tooltip": "(-) No Rewards",
|
||||
"selected": "Heh, wouldn't have figured you for a coward."
|
||||
},
|
||||
"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.\n ${{selectedPokemon}} gained {{boost1}} and {{boost2}} boosts!"
|
||||
},
|
||||
"damage_only": "But the medicine had some side effects!$Your {{selectedPokemon}} takes some damage...",
|
||||
"bad_poison": "But the medicine had some side effects!$Your {{selectedPokemon}} takes some damage\nand becomes badly poisoned...",
|
||||
"poison": "But the medicine had some side effects!$Your {{selectedPokemon}} becomes poisoned...",
|
||||
"damage_only": "But the medicine had some side effects!\n $Your {{selectedPokemon}} takes some damage...",
|
||||
"bad_poison": "But the medicine had some side effects!\n $Your {{selectedPokemon}} takes some damage\nand becomes badly poisoned...",
|
||||
"poison": "But the medicine had some side effects!\n $Your {{selectedPokemon}} becomes poisoned...",
|
||||
"no_bad_effects": "Looks like there were no side-effects this time."
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"intro": "As you walk down a narrow pathway, you see a towering silhouette blocking your path.$You get closer to see a Snorlax sleeping peacefully.\nIt seems like there's no way around it.",
|
||||
"intro": "As you walk down a narrow pathway, you see a towering silhouette blocking your path.\n $You get closer to see a Snorlax sleeping peacefully.\nIt seems like there's no way around it.",
|
||||
"title": "Slumbering Snorlax",
|
||||
"description": "You could attack it to try and get it to move, or simply wait for it to wake up. Who knows how long that could take, though...",
|
||||
"query": "What will you do?",
|
||||
@ -12,14 +12,14 @@
|
||||
"2": {
|
||||
"label": "Wait for It to Move",
|
||||
"tooltip": "(-) Wait a Long Time\n(+) Recover Party",
|
||||
"selected": ".@d{32}.@d{32}.@d{32}$You wait for a time, but the Snorlax's yawns make your party sleepy...",
|
||||
"selected": ".@d{32}.@d{32}.@d{32}\n $You wait for a time, but the Snorlax's yawns make your party sleepy...",
|
||||
"rest_result": "When you all awaken, the Snorlax is no where to be found -\nbut your Pokémon are all healed!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Steal Its Item",
|
||||
"tooltip": "(+) {{option3PrimaryName}} uses {{option3PrimaryMove}}\n(+) Special Reward",
|
||||
"disabled_tooltip": "Your Pokémon need to know certain moves to choose this",
|
||||
"selected": "Your {{option3PrimaryName}} uses {{option3PrimaryMove}}!$@s{item_fanfare}It steals Leftovers off the sleeping\nSnorlax and you make out like bandits!"
|
||||
"selected": "Your {{option3PrimaryName}} uses {{option3PrimaryMove}}!\n $@s{item_fanfare}It steals Leftovers off the sleeping\nSnorlax and you make out like bandits!"
|
||||
}
|
||||
}
|
||||
}
|
@ -13,15 +13,15 @@
|
||||
"label": "A Pokémon Helps",
|
||||
"tooltip": "(-) {{option2PrimaryName}} Helps\n(+) {{option2PrimaryName}} gains EXP\n(?) Teleport to New Biome",
|
||||
"disabled_tooltip": "You need a Steel or Electric Type Pokémon to choose this",
|
||||
"selected": "{{option2PrimaryName}}'s Type allows it to bypass the machine's paywall!$The capsule opens, and you step inside..."
|
||||
"selected": "{{option2PrimaryName}}'s Type allows it to bypass the machine's paywall!\n $The capsule opens, and you step inside..."
|
||||
},
|
||||
"3": {
|
||||
"label": "Inspect the Machine",
|
||||
"tooltip": "(-) Pokémon Battle",
|
||||
"selected": "You are drawn in by the blinking lights\nand strange noises coming from the machine...$You don't even notice as a wild\nPokémon sneaks up and ambushes you!"
|
||||
"selected": "You are drawn in by the blinking lights\nand strange noises coming from the machine...\n $You don't even notice as a wild\nPokémon sneaks up and ambushes you!"
|
||||
}
|
||||
},
|
||||
"transport": "The machine shakes violently,\nmaking all sorts of strange noises!$Just as soon as it had started, it quiets once more.",
|
||||
"attacked": "You step out into a completely new area, startling a wild Pokémon!$The wild Pokémon attacks!",
|
||||
"transport": "The machine shakes violently,\nmaking all sorts of strange noises!\n $Just as soon as it had started, it quiets once more.",
|
||||
"attacked": "You step out into a completely new area, startling a wild Pokémon!\n $The wild Pokémon attacks!",
|
||||
"boss_enraged": "The opposing {{enemyPokemon}} has become enraged!"
|
||||
}
|
@ -12,12 +12,12 @@
|
||||
"tooltip": "(-) Pay {{price, money}}\n(+) Gain a {{purchasePokemon}} with its Hidden Ability",
|
||||
"tooltip_shiny": "(-) Pay {{price, money}}\n(+) Gain a shiny {{purchasePokemon}}",
|
||||
"selected_message": "You paid an outrageous sum and bought the {{purchasePokemon}}.",
|
||||
"selected_dialogue": "Excellent choice!$I can see you've a keen eye for business.$Oh, yeah...@d{64} Returns not accepted, got that?"
|
||||
"selected_dialogue": "Excellent choice!\n $I can see you've a keen eye for business.\n $Oh, yeah...@d{64} Returns not accepted, got that?"
|
||||
},
|
||||
"2": {
|
||||
"label": "Refuse",
|
||||
"tooltip": "(-) No Rewards",
|
||||
"selected": "No?@d{32} You say no?$I'm only doing this as a favor to you!"
|
||||
"selected": "No?@d{32} You say no?\n $I'm only doing this as a favor to you!"
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
"label": "Let It Touch You",
|
||||
"tooltip": "(?) Something awful or amazing might happen",
|
||||
"selected": "You black out.",
|
||||
"selected_2": "@f{150}When you awaken, the Shuckle is gone\nand juice stash completely drained.$Your {{highBstPokemon}} feels a\nterrible lethargy come over it!$Its base stats were reduced by 20 in each stat!$Your remaining Pokémon feel an incredible vigor, though!$Their base stats are increased by 10 in each stat!"
|
||||
"selected_2": "@f{150}When you awaken, the Shuckle is gone\nand juice stash completely drained.\n $Your {{highBstPokemon}} feels a\nterrible lethargy come over it!\n $Its base stats were reduced by 20 in each stat!\n $Your remaining Pokémon feel an incredible vigor, though!\n $Their base stats are increased by 10 in each stat!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Battle the Shuckle",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"intro": "It's a family standing outside their house!",
|
||||
"speaker": "The Winstrates",
|
||||
"intro_dialogue": "We're the Winstrates!$What do you say to taking on our family in a series of Pokémon battles?",
|
||||
"intro_dialogue": "We're the Winstrates!\n $What do you say to taking on our family in a series of Pokémon battles?",
|
||||
"title": "The Winstrate Challenge",
|
||||
"description": "The Winstrates are a family of 5 trainers, and they want to battle! If you beat all of them back-to-back, they'll give you a grand prize. But can you handle the heat?",
|
||||
"query": "What will you do?",
|
||||
@ -17,5 +17,5 @@
|
||||
"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!\n $Our family uses this Macho Brace to strengthen our Pokémon more effectively during their training.\n $You may not need it, considering that you beat the whole lot of us, but we hope you'll accept it anyway!"
|
||||
}
|
@ -8,19 +8,19 @@
|
||||
"1": {
|
||||
"label": "Light Training",
|
||||
"tooltip": "(-) Light Battle\n(+) Improve 2 Random IVs of Pokémon",
|
||||
"finished": "{{selectedPokemon}} returns, feeling\nworn out but accomplished!$Its {{stat1}} and {{stat2}} IVs were improved!"
|
||||
"finished": "{{selectedPokemon}} returns, feeling\nworn out but accomplished!\n $Its {{stat1}} and {{stat2}} IVs were improved!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Moderate Training",
|
||||
"tooltip": "(-) Moderate Battle\n(+) Change Pokémon's Nature",
|
||||
"select_prompt": "Select a new nature\nto train your Pokémon in.",
|
||||
"finished": "{{selectedPokemon}} returns, feeling\nworn out but accomplished!$Its nature was changed to {{nature}}!"
|
||||
"finished": "{{selectedPokemon}} returns, feeling\nworn out but accomplished!\n $Its nature was changed to {{nature}}!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Heavy Training",
|
||||
"tooltip": "(-) Harsh Battle\n(+) Change Pokémon's Ability",
|
||||
"select_prompt": "Select a new ability\nto train your Pokémon in.",
|
||||
"finished": "{{selectedPokemon}} returns, feeling\nworn out but accomplished!$Its ability was changed to {{ability}}!"
|
||||
"finished": "{{selectedPokemon}} returns, feeling\nworn out but accomplished!\n $Its ability was changed to {{ability}}!"
|
||||
},
|
||||
"selected": "{{selectedPokemon}} moves across\nthe clearing to face you..."
|
||||
},
|
||||
|
@ -7,7 +7,7 @@
|
||||
"1": {
|
||||
"label": "Dig for Valuables",
|
||||
"tooltip": "(-) Lose Healing Items in Shops\n(+) Gain Amazing Items",
|
||||
"selected": "You wade through the garbage pile, becoming mired in filth.$There's no way any respectable shopkeepers\nwill sell you anything in your grimy state!$You'll just have to make do without shop healing items.$However, you found some incredible items in the garbage!"
|
||||
"selected": "You wade through the garbage pile, becoming mired in filth.\n $There's no way any respectable shopkeepers\nwill sell you anything in your grimy state!\n $You'll just have to make do without shop healing items.\n $However, you found some incredible items in the garbage!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Investigate Further",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"intro": "A shadowy woman blocks your path.\nSomething about her is unsettling...",
|
||||
"speaker": "Woman",
|
||||
"intro_dialogue": "I have seen your futures, your pasts...$Child, do you see them too?",
|
||||
"intro_dialogue": "I have seen your futures, your pasts...\n $Child, do you see them too?",
|
||||
"title": "???",
|
||||
"description": "The woman's words echo in your head. It wasn't just a singular voice, but a vast multitude, from all timelines and realities. You begin to feel dizzy, the question lingering on your mind...\n\n@[TOOLTIP_TITLE]{\"I have seen your futures, your pasts... Child, do you see them too?\"}",
|
||||
"query": "What will you do?",
|
||||
@ -9,14 +9,14 @@
|
||||
"1": {
|
||||
"label": "\"I See Them\"",
|
||||
"tooltip": "@[SUMMARY_GREEN]{(?) Affects your Pokémon}",
|
||||
"selected": "Her hand reaches out to touch you,\nand everything goes black.$Then...@d{64} You see everything.\nEvery timeline, all your different selves,\n past and future.$Everything that has made you,\neverything you will become...@d{64}",
|
||||
"selected": "Her hand reaches out to touch you,\nand everything goes black.\n $Then...@d{64} You see everything.\nEvery timeline, all your different selves,\n past and future.\n $Everything that has made you,\neverything you will become...@d{64}",
|
||||
"cutscene": "You see your Pokémon,@d{32} converging from\nevery reality to become something new...@d{64}",
|
||||
"dream_complete": "When you awaken, the woman - was it a woman or a ghost? - is gone...$.@d{32}.@d{32}.@d{32}$Your Pokémon team has changed...\nOr is it the same team you've always had?"
|
||||
"dream_complete": "When you awaken, the woman - was it a woman or a ghost? - is gone...\n $.@d{32}.@d{32}.@d{32}\n $Your Pokémon team has changed...\nOr is it the same team you've always had?"
|
||||
},
|
||||
"2": {
|
||||
"label": "Quickly Leave",
|
||||
"tooltip": "(-) Affects your Pokémon",
|
||||
"selected": "You tear your mind from a numbing grip, and hastily depart.$When you finally stop to collect yourself, you check the Pokémon in your team.$For some reason, all of their levels have decreased!"
|
||||
"selected": "You tear your mind from a numbing grip, and hastily depart.\n $When you finally stop to collect yourself, you check the Pokémon in your team.\n $For some reason, all of their levels have decreased!"
|
||||
}
|
||||
}
|
||||
}
|
@ -117,5 +117,15 @@
|
||||
"plasma_grunts": "Plasma Grunts",
|
||||
"flare_grunt": "Flare Grunt",
|
||||
"flare_grunt_female": "Flare Grunt",
|
||||
"flare_grunts": "Flare Grunts"
|
||||
"flare_grunts": "Flare Grunts",
|
||||
"buck": "Buck",
|
||||
"cheryl": "Cheryl",
|
||||
"marley": "Marley",
|
||||
"mira": "Mira",
|
||||
"riley": "Riley",
|
||||
"victor": "Victor",
|
||||
"victoria": "Victoria",
|
||||
"vivi": "Vivi",
|
||||
"vicky": "Vicky",
|
||||
"vito": "Vito"
|
||||
}
|
@ -152,16 +152,5 @@
|
||||
"alder_iris_double": "Alder & Iris",
|
||||
"iris_alder_double": "Iris & Alder",
|
||||
"marnie_piers_double": "Marnie & Piers",
|
||||
"piers_marnie_double": "Piers & Marnie",
|
||||
"buck": "Buck",
|
||||
"cheryl": "Cheryl",
|
||||
"marley": "Marley",
|
||||
"mira": "Mira",
|
||||
"riley": "Riley",
|
||||
"victor": "Victor",
|
||||
"victoria": "Victoria",
|
||||
"vivi": "Vivi",
|
||||
"vicky": "Vicky",
|
||||
"vito": "Vito",
|
||||
"bug_type_superfan": "Bug-Type Superfan"
|
||||
"piers_marnie_double": "Piers & Marnie"
|
||||
}
|
@ -1536,9 +1536,8 @@ export const modifierTypes = {
|
||||
}
|
||||
return new PokemonBaseStatFlatModifierType(Utils.randSeedInt(20), [Stat.HP, Stat.ATK, Stat.DEF]);
|
||||
}),
|
||||
MYSTERY_ENCOUNTER_BLACK_SLUDGE: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new Modifiers.HealShopCostModifier(type)),
|
||||
MYSTERY_ENCOUNTER_BLACK_SLUDGE: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new Modifiers.RemoveHealShopModifier(type)),
|
||||
MYSTERY_ENCOUNTER_MACHO_BRACE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_MACHO_BRACE", "macho_brace", (type, args) => new Modifiers.PokemonIncrementingStatModifier(type, (args[0] as Pokemon).id)),
|
||||
MYSTERY_ENCOUNTER_GOLDEN_BUG_NET: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET", "golden_net", (type, _args) => new Modifiers.BoostBugSpawnModifier(type)),
|
||||
};
|
||||
|
||||
interface ModifierPool {
|
||||
|
@ -734,8 +734,7 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier {
|
||||
apply(args: any[]): boolean {
|
||||
// Modifies the passed in baseStats[] array
|
||||
args[1].forEach((v, i) => {
|
||||
// HP is affected by half as much as other stats
|
||||
const newVal = i === 0 ? Math.floor(v + this.statModifier / 2) : Math.floor(v + this.statModifier);
|
||||
const newVal = Math.floor(v + this.statModifier);
|
||||
args[1][i] = Math.min(Math.max(newVal, 1), 999999);
|
||||
});
|
||||
|
||||
@ -2367,41 +2366,17 @@ export class LockModifierTiersModifier extends PersistentModifier {
|
||||
}
|
||||
}
|
||||
|
||||
export class HealShopCostModifier extends PersistentModifier {
|
||||
export class RemoveHealShopModifier extends PersistentModifier {
|
||||
constructor(type: ModifierType, stackCount?: integer) {
|
||||
super(type, stackCount);
|
||||
}
|
||||
|
||||
match(modifier: Modifier): boolean {
|
||||
return modifier instanceof HealShopCostModifier;
|
||||
return modifier instanceof RemoveHealShopModifier;
|
||||
}
|
||||
|
||||
clone(): HealShopCostModifier {
|
||||
return new HealShopCostModifier(this.type, this.stackCount);
|
||||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
(args[0] as Utils.IntegerHolder).value *= Math.pow(3, this.getStackCount());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getMaxStackCount(scene: BattleScene): integer {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
export class BoostBugSpawnModifier extends PersistentModifier {
|
||||
constructor(type: ModifierType, stackCount?: integer) {
|
||||
super(type, stackCount);
|
||||
}
|
||||
|
||||
match(modifier: Modifier): boolean {
|
||||
return modifier instanceof BoostBugSpawnModifier;
|
||||
}
|
||||
|
||||
clone(): HealShopCostModifier {
|
||||
return new BoostBugSpawnModifier(this.type, this.stackCount);
|
||||
clone(): RemoveHealShopModifier {
|
||||
return new RemoveHealShopModifier(this.type, this.stackCount);
|
||||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
|
@ -130,8 +130,7 @@ class DefaultOverrides {
|
||||
// -------------------------
|
||||
// MYSTERY ENCOUNTER OVERRIDES
|
||||
// -------------------------
|
||||
|
||||
/** 1 to 256, set to null to ignore */
|
||||
// 1 to 256, set to null to ignore
|
||||
readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number | null = null;
|
||||
readonly MYSTERY_ENCOUNTER_TIER_OVERRIDE: MysteryEncounterTier | null = null;
|
||||
readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType | null = null;
|
||||
|
@ -31,8 +31,6 @@ import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
import { doTrainerExclamation } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases";
|
||||
import { randSeedInt } from "#app/utils";
|
||||
import { getGoldenBugNetSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
|
||||
export class EncounterPhase extends BattlePhase {
|
||||
private loaded: boolean;
|
||||
@ -91,11 +89,7 @@ export class EncounterPhase extends BattlePhase {
|
||||
if (battle.battleType === BattleType.TRAINER) {
|
||||
battle.enemyParty[e] = battle.trainer?.genPartyMember(e)!; // TODO:: is the bang correct here?
|
||||
} else {
|
||||
let enemySpecies = this.scene.randomSpecies(battle.waveIndex, level, true);
|
||||
// If player has golden bug net, rolls 10% chance to replace with species from the golden bug net bug pool
|
||||
if (randSeedInt(10) === 0) {
|
||||
enemySpecies = getGoldenBugNetSpecies(this.scene, battle.waveIndex, level);
|
||||
}
|
||||
const enemySpecies = this.scene.randomSpecies(battle.waveIndex, level, true);
|
||||
battle.enemyParty[e] = this.scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!this.scene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies));
|
||||
if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
|
||||
battle.enemyParty[e].ivs = new Array(6).fill(31);
|
||||
|
@ -22,7 +22,7 @@ export class ModifierRewardPhase extends BattlePhase {
|
||||
return new Promise<void>(resolve => {
|
||||
const newModifier = this.modifierType.newModifier();
|
||||
this.scene.addModifier(newModifier).then(() => {
|
||||
this.scene.playSound("bgm/item_fanfare");
|
||||
this.scene.playSound("item_fanfare");
|
||||
this.scene.ui.showText(i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }), null, () => resolve(), null, true);
|
||||
});
|
||||
});
|
||||
|
@ -418,35 +418,23 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
||||
});
|
||||
} else {
|
||||
this.scene.executeWithSeedOffset(() => {
|
||||
if (encounter.onRewards) {
|
||||
encounter.onRewards(this.scene).then(() => {
|
||||
this.doEncounterRewardsAndContinue();
|
||||
});
|
||||
} else {
|
||||
this.doEncounterRewardsAndContinue();
|
||||
if (this.scene.currentBattle.mysteryEncounter.doEncounterExp) {
|
||||
this.scene.currentBattle.mysteryEncounter.doEncounterExp(this.scene);
|
||||
}
|
||||
|
||||
if (this.scene.currentBattle.mysteryEncounter.doEncounterRewards) {
|
||||
this.scene.currentBattle.mysteryEncounter.doEncounterRewards(this.scene);
|
||||
} else if (this.addHealPhase) {
|
||||
this.scene.tryRemovePhase(p => p instanceof SelectModifierPhase);
|
||||
this.scene.unshiftPhase(new SelectModifierPhase(this.scene, 0, undefined, { fillRemaining: false, rerollMultiplier: 0 }));
|
||||
}
|
||||
// Do not use ME's seedOffset for rewards, these should always be consistent with waveIndex (once per wave)
|
||||
}, this.scene.currentBattle.waveIndex * 1000);
|
||||
|
||||
this.scene.pushPhase(new PostMysteryEncounterPhase(this.scene));
|
||||
this.end();
|
||||
}
|
||||
}
|
||||
|
||||
doEncounterRewardsAndContinue() {
|
||||
const encounter = this.scene.currentBattle.mysteryEncounter;
|
||||
|
||||
if (encounter.doEncounterExp) {
|
||||
encounter.doEncounterExp(this.scene);
|
||||
}
|
||||
|
||||
if (encounter.doEncounterRewards) {
|
||||
encounter.doEncounterRewards(this.scene);
|
||||
} else if (this.addHealPhase) {
|
||||
this.scene.tryRemovePhase(p => p instanceof SelectModifierPhase);
|
||||
this.scene.unshiftPhase(new SelectModifierPhase(this.scene, 0, undefined, { fillRemaining: false, rerollMultiplier: 0 }));
|
||||
}
|
||||
|
||||
this.scene.pushPhase(new PostMysteryEncounterPhase(this.scene));
|
||||
this.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,7 +53,7 @@ describe("Final Boss", () => {
|
||||
expect(game.scene.getEnemyPokemon()!.species.speciesId).not.toBe(Species.ETERNATUS);
|
||||
});
|
||||
|
||||
it("should NOT have passive enabled on Eternatus", async () => {
|
||||
it("should not have passive enabled on Eternatus", async () => {
|
||||
await game.runToFinalBossEncounter(game, [Species.BIDOOF], GameModes.CLASSIC);
|
||||
|
||||
const eternatus = game.scene.getEnemyPokemon();
|
||||
|
@ -150,9 +150,8 @@ async function handleSecondaryOptionSelect(game: GameManager, pokemonNo: number,
|
||||
/**
|
||||
* For any MysteryEncounter that has a battle, can call this to skip battle and proceed to MysteryEncounterRewardsPhase
|
||||
* @param game
|
||||
* @param runRewardsPhase
|
||||
*/
|
||||
export async function skipBattleRunMysteryEncounterRewardsPhase(game: GameManager, runRewardsPhase: boolean = true) {
|
||||
export async function skipBattleRunMysteryEncounterRewardsPhase(game: GameManager) {
|
||||
game.scene.clearPhaseQueue();
|
||||
game.scene.clearPhaseQueueSplice();
|
||||
game.scene.getEnemyParty().forEach(p => {
|
||||
@ -162,5 +161,5 @@ export async function skipBattleRunMysteryEncounterRewardsPhase(game: GameManage
|
||||
});
|
||||
game.scene.pushPhase(new VictoryPhase(game.scene, 0));
|
||||
game.phaseInterceptor.superEndPhase();
|
||||
await game.phaseInterceptor.to(MysteryEncounterRewardsPhase, runRewardsPhase);
|
||||
await game.phaseInterceptor.to(MysteryEncounterRewardsPhase, true);
|
||||
}
|
@ -6,7 +6,7 @@ import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
|
@ -4,7 +4,7 @@ import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
|
@ -6,7 +6,7 @@ import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||
import { AnOfferYouCantRefuseEncounter } from "#app/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter";
|
||||
|
@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type";
|
||||
import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||
|
@ -1,585 +0,0 @@
|
||||
import * as MysteryEncounters from "#app/data/mystery-encounters/mystery-encounters";
|
||||
import { Biome } from "#app/enums/biome";
|
||||
import { MysteryEncounterType } from "#app/enums/mystery-encounter-type";
|
||||
import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { PokemonMove } from "#app/field/pokemon";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { MysteryEncounterPhase, MysteryEncounterRewardsPhase } from "#app/phases/mystery-encounter-phases";
|
||||
import { ContactHeldItemTransferChanceModifier } from "#app/modifier/modifier";
|
||||
import { CommandPhase } from "#app/phases/command-phase";
|
||||
import { BugTypeSuperfanEncounter } from "#app/data/mystery-encounters/encounters/bug-type-superfan-encounter";
|
||||
import * as encounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
|
||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||
|
||||
const namespace = "mysteryEncounter:bugTypeSuperfan";
|
||||
const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.WEEDLE];
|
||||
const defaultBiome = Biome.CAVE;
|
||||
const defaultWave = 24;
|
||||
|
||||
const POOL_1_POKEMON = [
|
||||
Species.PARASECT,
|
||||
Species.VENOMOTH,
|
||||
Species.LEDIAN,
|
||||
Species.ARIADOS,
|
||||
Species.YANMA,
|
||||
Species.BEAUTIFLY,
|
||||
Species.DUSTOX,
|
||||
Species.MASQUERAIN,
|
||||
Species.NINJASK,
|
||||
Species.VOLBEAT,
|
||||
Species.ILLUMISE,
|
||||
Species.ANORITH,
|
||||
Species.KRICKETUNE,
|
||||
Species.WORMADAM,
|
||||
Species.MOTHIM,
|
||||
Species.SKORUPI,
|
||||
Species.JOLTIK,
|
||||
Species.LARVESTA,
|
||||
Species.VIVILLON,
|
||||
Species.CHARJABUG,
|
||||
Species.RIBOMBEE,
|
||||
Species.SPIDOPS,
|
||||
Species.LOKIX
|
||||
];
|
||||
|
||||
const POOL_2_POKEMON = [
|
||||
Species.SCYTHER,
|
||||
Species.PINSIR,
|
||||
Species.HERACROSS,
|
||||
Species.FORRETRESS,
|
||||
Species.SCIZOR,
|
||||
Species.SHUCKLE,
|
||||
Species.SHEDINJA,
|
||||
Species.ARMALDO,
|
||||
Species.VESPIQUEN,
|
||||
Species.DRAPION,
|
||||
Species.YANMEGA,
|
||||
Species.LEAVANNY,
|
||||
Species.SCOLIPEDE,
|
||||
Species.CRUSTLE,
|
||||
Species.ESCAVALIER,
|
||||
Species.ACCELGOR,
|
||||
Species.GALVANTULA,
|
||||
Species.VIKAVOLT,
|
||||
Species.ARAQUANID,
|
||||
Species.ORBEETLE,
|
||||
Species.CENTISKORCH,
|
||||
Species.FROSMOTH,
|
||||
Species.KLEAVOR,
|
||||
];
|
||||
|
||||
const POOL_3_POKEMON: { species: Species, formIndex?: number }[] = [
|
||||
{
|
||||
species: Species.PINSIR,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.SCIZOR,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.HERACROSS,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.ORBEETLE,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.CENTISKORCH,
|
||||
formIndex: 1
|
||||
},
|
||||
{
|
||||
species: Species.DURANT,
|
||||
},
|
||||
{
|
||||
species: Species.VOLCARONA,
|
||||
},
|
||||
{
|
||||
species: Species.GOLISOPOD,
|
||||
},
|
||||
];
|
||||
|
||||
const POOL_4_POKEMON = [
|
||||
Species.GENESECT,
|
||||
Species.SLITHER_WING,
|
||||
Species.BUZZWOLE,
|
||||
Species.PHEROMOSA
|
||||
];
|
||||
|
||||
const PHYSICAL_TUTOR_MOVES = [
|
||||
Moves.MEGAHORN,
|
||||
Moves.X_SCISSOR,
|
||||
Moves.ATTACK_ORDER,
|
||||
Moves.PIN_MISSILE,
|
||||
Moves.FIRST_IMPRESSION
|
||||
];
|
||||
|
||||
const SPECIAL_TUTOR_MOVES = [
|
||||
Moves.SILVER_WIND,
|
||||
Moves.BUG_BUZZ,
|
||||
Moves.SIGNAL_BEAM,
|
||||
Moves.POLLEN_PUFF
|
||||
];
|
||||
|
||||
const STATUS_TUTOR_MOVES = [
|
||||
Moves.STRING_SHOT,
|
||||
Moves.STICKY_WEB,
|
||||
Moves.SILK_TRAP,
|
||||
Moves.RAGE_POWDER,
|
||||
Moves.HEAL_ORDER
|
||||
];
|
||||
|
||||
const MISC_TUTOR_MOVES = [
|
||||
Moves.BUG_BITE,
|
||||
Moves.LEECH_LIFE,
|
||||
Moves.DEFEND_ORDER,
|
||||
Moves.QUIVER_DANCE,
|
||||
Moves.TAIL_GLOW,
|
||||
Moves.INFESTATION,
|
||||
Moves.U_TURN
|
||||
];
|
||||
|
||||
describe("Bug-Type Superfan - Mystery Encounter", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
let scene: BattleScene;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({ type: Phaser.HEADLESS });
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
game = new GameManager(phaserGame);
|
||||
scene = game.scene;
|
||||
game.override.mysteryEncounterChance(100);
|
||||
game.override.startingWave(defaultWave);
|
||||
game.override.startingBiome(defaultBiome);
|
||||
game.override.disableTrainerWaves();
|
||||
|
||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||
new Map<Biome, MysteryEncounterType[]>([
|
||||
[Biome.CAVE, [MysteryEncounterType.BUG_TYPE_SUPERFAN]],
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
vi.clearAllMocks();
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
it("should have the correct properties", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
|
||||
expect(BugTypeSuperfanEncounter.encounterType).toBe(MysteryEncounterType.BUG_TYPE_SUPERFAN);
|
||||
expect(BugTypeSuperfanEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT);
|
||||
expect(BugTypeSuperfanEncounter.dialogue).toBeDefined();
|
||||
expect(BugTypeSuperfanEncounter.dialogue.intro).toStrictEqual([
|
||||
{
|
||||
text: `${namespace}.intro`,
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.intro_dialogue`,
|
||||
},
|
||||
]);
|
||||
expect(BugTypeSuperfanEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||
expect(BugTypeSuperfanEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||
expect(BugTypeSuperfanEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||
expect(BugTypeSuperfanEncounter.options.length).toBe(3);
|
||||
});
|
||||
|
||||
it("should not run below wave 10", async () => {
|
||||
game.override.startingWave(9);
|
||||
|
||||
await game.runToMysteryEncounter();
|
||||
|
||||
expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.BUG_TYPE_SUPERFAN);
|
||||
});
|
||||
|
||||
it("should not run above wave 179", async () => {
|
||||
game.override.startingWave(181);
|
||||
|
||||
await game.runToMysteryEncounter();
|
||||
|
||||
expect(scene.currentBattle.mysteryEncounter).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should initialize fully", async () => {
|
||||
initSceneWithoutEncounterPhase(scene, defaultParty);
|
||||
scene.currentBattle.mysteryEncounter = BugTypeSuperfanEncounter;
|
||||
|
||||
const { onInit } = BugTypeSuperfanEncounter;
|
||||
|
||||
expect(BugTypeSuperfanEncounter.onInit).toBeDefined();
|
||||
|
||||
BugTypeSuperfanEncounter.populateDialogueTokensFromRequirements(scene);
|
||||
const onInitResult = onInit!(scene);
|
||||
const config = BugTypeSuperfanEncounter.enemyPartyConfigs[0];
|
||||
|
||||
expect(config).toBeDefined();
|
||||
expect(config.trainerConfig?.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(config.trainerConfig?.partyTemplates).toBeDefined();
|
||||
expect(config.female).toBe(true);
|
||||
expect(onInitResult).toBe(true);
|
||||
});
|
||||
|
||||
describe("Option 1 - Battle the Bug-Type Superfan", () => {
|
||||
it("should have the correct properties", () => {
|
||||
const option = BugTypeSuperfanEncounter.options[0];
|
||||
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
||||
expect(option.dialogue).toBeDefined();
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}.option.1.label`,
|
||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.option.1.selected`,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("should start battle against the Bug-Type Superfan with wave 30 party template", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyParty = scene.getEnemyParty();
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||
expect(enemyParty.length).toBe(2);
|
||||
expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL);
|
||||
expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE);
|
||||
});
|
||||
|
||||
it("should start battle against the Bug-Type Superfan with wave 50 party template", async () => {
|
||||
game.override.startingWave(43);
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyParty = scene.getEnemyParty();
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||
expect(enemyParty.length).toBe(3);
|
||||
expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL);
|
||||
expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE);
|
||||
expect(POOL_1_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true);
|
||||
});
|
||||
|
||||
it("should start battle against the Bug-Type Superfan with wave 70 party template", async () => {
|
||||
game.override.startingWave(61);
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyParty = scene.getEnemyParty();
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||
expect(enemyParty.length).toBe(4);
|
||||
expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL);
|
||||
expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE);
|
||||
expect(POOL_1_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true);
|
||||
expect(POOL_2_POKEMON.includes(enemyParty[3].species.speciesId)).toBe(true);
|
||||
});
|
||||
|
||||
it("should start battle against the Bug-Type Superfan with wave 100 party template", async () => {
|
||||
game.override.startingWave(81);
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyParty = scene.getEnemyParty();
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||
expect(enemyParty.length).toBe(5);
|
||||
expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL);
|
||||
expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE);
|
||||
expect(POOL_1_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true);
|
||||
expect(POOL_2_POKEMON.includes(enemyParty[3].species.speciesId)).toBe(true);
|
||||
expect(POOL_2_POKEMON.includes(enemyParty[4].species.speciesId)).toBe(true);
|
||||
});
|
||||
|
||||
it("should start battle against the Bug-Type Superfan with wave 120 party template", async () => {
|
||||
game.override.startingWave(111);
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyParty = scene.getEnemyParty();
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||
expect(enemyParty.length).toBe(5);
|
||||
expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL);
|
||||
expect(enemyParty[0].formIndex).toBe(1);
|
||||
expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE);
|
||||
expect(enemyParty[1].formIndex).toBe(1);
|
||||
expect(POOL_2_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true);
|
||||
expect(POOL_2_POKEMON.includes(enemyParty[3].species.speciesId)).toBe(true);
|
||||
expect(POOL_3_POKEMON.some(config => enemyParty[4].species.speciesId === config.species)).toBe(true);
|
||||
});
|
||||
|
||||
it("should start battle against the Bug-Type Superfan with wave 140 party template", async () => {
|
||||
game.override.startingWave(131);
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyParty = scene.getEnemyParty();
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||
expect(enemyParty.length).toBe(5);
|
||||
expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL);
|
||||
expect(enemyParty[0].formIndex).toBe(1);
|
||||
expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE);
|
||||
expect(enemyParty[1].formIndex).toBe(1);
|
||||
expect(POOL_2_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true);
|
||||
expect(POOL_3_POKEMON.some(config => enemyParty[3].species.speciesId === config.species)).toBe(true);
|
||||
expect(POOL_3_POKEMON.some(config => enemyParty[4].species.speciesId === config.species)).toBe(true);
|
||||
});
|
||||
|
||||
it("should start battle against the Bug-Type Superfan with wave 160 party template", async () => {
|
||||
game.override.startingWave(151);
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyParty = scene.getEnemyParty();
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||
expect(enemyParty.length).toBe(5);
|
||||
expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL);
|
||||
expect(enemyParty[0].formIndex).toBe(1);
|
||||
expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE);
|
||||
expect(enemyParty[1].formIndex).toBe(1);
|
||||
expect(POOL_2_POKEMON.includes(enemyParty[2].species.speciesId)).toBe(true);
|
||||
expect(POOL_3_POKEMON.some(config => enemyParty[3].species.speciesId === config.species)).toBe(true);
|
||||
expect(POOL_4_POKEMON.includes(enemyParty[4].species.speciesId)).toBe(true);
|
||||
});
|
||||
|
||||
it("should start battle against the Bug-Type Superfan with wave 180 party template", async () => {
|
||||
game.override.startingWave(171);
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyParty = scene.getEnemyParty();
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||
expect(enemyParty.length).toBe(5);
|
||||
expect(scene.currentBattle.trainer?.config.trainerType).toBe(TrainerType.BUG_TYPE_SUPERFAN);
|
||||
expect(enemyParty[0].species.speciesId).toBe(Species.BEEDRILL);
|
||||
expect(enemyParty[0].formIndex).toBe(1);
|
||||
expect(enemyParty[0].isBoss()).toBe(true);
|
||||
expect(enemyParty[0].bossSegments).toBe(2);
|
||||
expect(enemyParty[1].species.speciesId).toBe(Species.BUTTERFREE);
|
||||
expect(enemyParty[1].formIndex).toBe(1);
|
||||
expect(enemyParty[1].isBoss()).toBe(true);
|
||||
expect(enemyParty[1].bossSegments).toBe(2);
|
||||
expect(POOL_3_POKEMON.some(config => enemyParty[2].species.speciesId === config.species)).toBe(true);
|
||||
expect(POOL_3_POKEMON.some(config => enemyParty[3].species.speciesId === config.species)).toBe(true);
|
||||
expect(POOL_4_POKEMON.includes(enemyParty[4].species.speciesId)).toBe(true);
|
||||
});
|
||||
|
||||
it("should let the player learn a Bug move after battle ends", async () => {
|
||||
const selectOptionSpy = vi.spyOn(encounterPhaseUtils, "selectOptionThenPokemon");
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
await skipBattleRunMysteryEncounterRewardsPhase(game, false);
|
||||
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterRewardsPhase.name);
|
||||
game.phaseInterceptor["prompts"] = []; // Clear out prompt handlers
|
||||
game.onNextPrompt("MysteryEncounterRewardsPhase", Mode.OPTION_SELECT, () => {
|
||||
game.phaseInterceptor.superEndPhase();
|
||||
});
|
||||
await game.phaseInterceptor.run(MysteryEncounterRewardsPhase);
|
||||
|
||||
expect(selectOptionSpy).toHaveBeenCalledTimes(1);
|
||||
const optionData = selectOptionSpy.mock.calls[0][1];
|
||||
expect(PHYSICAL_TUTOR_MOVES.some(move => new PokemonMove(move).getName() === optionData[0].label)).toBe(true);
|
||||
expect(SPECIAL_TUTOR_MOVES.some(move => new PokemonMove(move).getName() === optionData[1].label)).toBe(true);
|
||||
expect(STATUS_TUTOR_MOVES.some(move => new PokemonMove(move).getName() === optionData[2].label)).toBe(true);
|
||||
expect(MISC_TUTOR_MOVES.some(move => new PokemonMove(move).getName() === optionData[3].label)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Option 2 - Show off Bug Types", () => {
|
||||
it("should have the correct properties", () => {
|
||||
const option = BugTypeSuperfanEncounter.options[1];
|
||||
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT);
|
||||
expect(option.dialogue).toBeDefined();
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}.option.2.label`,
|
||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`
|
||||
});
|
||||
});
|
||||
|
||||
it("should NOT be selectable if the player doesn't have any Bug types", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.ABRA]);
|
||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||
|
||||
const encounterPhase = scene.getCurrentPhase();
|
||||
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||
vi.spyOn(scene.ui, "playError");
|
||||
|
||||
await runSelectMysteryEncounterOption(game, 2);
|
||||
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should proceed to rewards screen with 0-1 Bug Types reward options", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 2);
|
||||
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||
|
||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
||||
expect(modifierSelectHandler.options.length).toEqual(2);
|
||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("SUPER_LURE");
|
||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("GREAT_BALL");
|
||||
});
|
||||
|
||||
it("should proceed to rewards screen with 2-3 Bug Types reward options", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL]);
|
||||
await runMysteryEncounterToEnd(game, 2);
|
||||
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||
|
||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
||||
expect(modifierSelectHandler.options.length).toEqual(3);
|
||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("QUICK_CLAW");
|
||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("MAX_LURE");
|
||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toBe("ULTRA_BALL");
|
||||
});
|
||||
|
||||
it("should proceed to rewards screen with 4-5 Bug Types reward options", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL, Species.GALVANTULA, Species.VOLCARONA]);
|
||||
await runMysteryEncounterToEnd(game, 2);
|
||||
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||
|
||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
||||
expect(modifierSelectHandler.options.length).toEqual(3);
|
||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("GRIP_CLAW");
|
||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("MAX_LURE");
|
||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toBe("ROGUE_BALL");
|
||||
});
|
||||
|
||||
it("should proceed to rewards screen with 6 Bug Types reward options (including form change item)", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE, Species.BEEDRILL, Species.GALVANTULA, Species.VOLCARONA, Species.ANORITH, Species.GENESECT]);
|
||||
await runMysteryEncounterToEnd(game, 2);
|
||||
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||
|
||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
||||
expect(modifierSelectHandler.options.length).toEqual(3);
|
||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("MASTER_BALL");
|
||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("MAX_LURE");
|
||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toBe("FORM_CHANGE_ITEM");
|
||||
});
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
const leaveEncounterWithoutBattleSpy = vi.spyOn(encounterPhaseUtils, "leaveEncounterWithoutBattle");
|
||||
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 2);
|
||||
|
||||
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Option 3 - Give a Bug Item", () => {
|
||||
it("should have the correct properties", () => {
|
||||
const option = BugTypeSuperfanEncounter.options[2];
|
||||
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT);
|
||||
expect(option.dialogue).toBeDefined();
|
||||
expect(option.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}.option.3.label`,
|
||||
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}.option.3.selected`,
|
||||
},
|
||||
{
|
||||
speaker: `${namespace}.speaker`,
|
||||
text: `${namespace}.option.3.selected_dialogue`,
|
||||
},
|
||||
],
|
||||
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
||||
});
|
||||
});
|
||||
|
||||
it("should NOT be selectable if the player doesn't have any Bug items", async () => {
|
||||
game.scene.modifiers = [];
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, defaultParty);
|
||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||
|
||||
game.scene.modifiers = [];
|
||||
const encounterPhase = scene.getCurrentPhase();
|
||||
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||
vi.spyOn(scene.ui, "playError");
|
||||
|
||||
await runSelectMysteryEncounterOption(game, 3);
|
||||
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should remove the gifted item and proceed to rewards screen", async () => {
|
||||
game.override.startingHeldItems([{name: "GRIP_CLAW", count: 1}]);
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE]);
|
||||
|
||||
const gripClawCountBefore = scene.findModifier(m => m instanceof ContactHeldItemTransferChanceModifier)?.stackCount ?? 0;
|
||||
|
||||
await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 });
|
||||
|
||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||
|
||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
||||
expect(modifierSelectHandler.options.length).toEqual(2);
|
||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toBe("MYSTERY_ENCOUNTER_GOLDEN_BUG_NET");
|
||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toBe("REVIVER_SEED");
|
||||
|
||||
const gripClawCountAfter = scene.findModifier(m => m instanceof ContactHeldItemTransferChanceModifier)?.stackCount ?? 0;
|
||||
expect(gripClawCountBefore - 1).toBe(gripClawCountAfter);
|
||||
});
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
game.override.startingHeldItems([{name: "GRIP_CLAW", count: 1}]);
|
||||
const leaveEncounterWithoutBattleSpy = vi.spyOn(encounterPhaseUtils, "leaveEncounterWithoutBattle");
|
||||
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BUG_TYPE_SUPERFAN, [Species.BUTTERFREE]);
|
||||
await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 });
|
||||
|
||||
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
|
||||
});
|
||||
});
|
||||
});
|
@ -8,7 +8,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import * as BattleAnims from "#app/data/battle-anims";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
||||
@ -301,7 +301,7 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
expect(secondItemsAfter.length).toBe(1);
|
||||
expect(secondItemsAfter[0].type.id).toBe("SOUL_DEW");
|
||||
expect(secondItemsAfter[0]?.stackCount).toBe(5);
|
||||
});
|
||||
}, 2000000);
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
|
||||
|
@ -4,7 +4,7 @@ import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
|
@ -4,7 +4,7 @@ import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
@ -137,7 +137,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// 5 Healing Charms
|
||||
scene.modifiers = [];
|
||||
const abilityCharm = generateModifierType(scene, modifierTypes.ABILITY_CHARM)!.newModifier() as HiddenAbilityRateBoosterModifier;
|
||||
const abilityCharm = generateModifierType(scene, modifierTypes.ABILITY_CHARM).newModifier() as HiddenAbilityRateBoosterModifier;
|
||||
abilityCharm.stackCount = 4;
|
||||
await scene.addModifier(abilityCharm, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -206,7 +206,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 2 Sitrus berries on party lead
|
||||
scene.modifiers = [];
|
||||
const sitrus = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS])!;
|
||||
const sitrus = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]);
|
||||
const sitrusMod = sitrus.newModifier(scene.getParty()[0]) as BerryModifier;
|
||||
sitrusMod.stackCount = 2;
|
||||
await scene.addModifier(sitrusMod, true, false, false, true);
|
||||
@ -227,7 +227,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 1 Reviver Seed on party lead
|
||||
scene.modifiers = [];
|
||||
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED)!;
|
||||
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED);
|
||||
const modifier = revSeed.newModifier(scene.getParty()[0]) as PokemonInstantReviveModifier;
|
||||
modifier.stackCount = 1;
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
@ -248,10 +248,10 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// 99 Candy Jars
|
||||
scene.modifiers = [];
|
||||
const candyJar = generateModifierType(scene, modifierTypes.CANDY_JAR)!.newModifier() as LevelIncrementBoosterModifier;
|
||||
const candyJar = generateModifierType(scene, modifierTypes.CANDY_JAR).newModifier() as LevelIncrementBoosterModifier;
|
||||
candyJar.stackCount = 99;
|
||||
await scene.addModifier(candyJar, true, false, false, true);
|
||||
const sitrus = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS])!;
|
||||
const sitrus = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]);
|
||||
|
||||
// Sitrus berries on party
|
||||
const sitrusMod = sitrus.newModifier(scene.getParty()[0]) as BerryModifier;
|
||||
@ -277,12 +277,12 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// 5 Healing Charms
|
||||
scene.modifiers = [];
|
||||
const healingCharm = generateModifierType(scene, modifierTypes.HEALING_CHARM)!.newModifier() as HealingBoosterModifier;
|
||||
const healingCharm = generateModifierType(scene, modifierTypes.HEALING_CHARM).newModifier() as HealingBoosterModifier;
|
||||
healingCharm.stackCount = 5;
|
||||
await scene.addModifier(healingCharm, true, false, false, true);
|
||||
|
||||
// Set 1 Reviver Seed on party lead
|
||||
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED)!;
|
||||
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED);
|
||||
const modifier = revSeed.newModifier(scene.getParty()[0]) as PokemonInstantReviveModifier;
|
||||
modifier.stackCount = 1;
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
@ -306,7 +306,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 1 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW)!;
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW);
|
||||
const modifier = soulDew.newModifier(scene.getParty()[0]);
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -334,7 +334,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.DELIBIRDY, defaultParty);
|
||||
|
||||
// Set 1 Reviver Seed on party lead
|
||||
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED)!;
|
||||
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED);
|
||||
const modifier = revSeed.newModifier(scene.getParty()[0]) as PokemonInstantReviveModifier;
|
||||
modifier.stackCount = 1;
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
@ -368,7 +368,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 2 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW)!;
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW);
|
||||
const modifier = soulDew.newModifier(scene.getParty()[0]) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 2;
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
@ -389,7 +389,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 1 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW)!;
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW);
|
||||
const modifier = soulDew.newModifier(scene.getParty()[0]) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 1;
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
@ -410,12 +410,12 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// 5 Healing Charms
|
||||
scene.modifiers = [];
|
||||
const healingCharm = generateModifierType(scene, modifierTypes.BERRY_POUCH)!.newModifier() as PreserveBerryModifier;
|
||||
const healingCharm = generateModifierType(scene, modifierTypes.BERRY_POUCH).newModifier() as PreserveBerryModifier;
|
||||
healingCharm.stackCount = 3;
|
||||
await scene.addModifier(healingCharm, true, false, false, true);
|
||||
|
||||
// Set 1 Soul Dew on party lead
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW)!;
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW);
|
||||
const modifier = soulDew.newModifier(scene.getParty()[0]) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 1;
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
@ -439,7 +439,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 1 Reviver Seed on party lead
|
||||
scene.modifiers = [];
|
||||
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED)!;
|
||||
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED);
|
||||
const modifier = revSeed.newModifier(scene.getParty()[0]);
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -468,7 +468,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 1 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW)!;
|
||||
const soulDew = generateModifierType(scene, modifierTypes.SOUL_DEW);
|
||||
const modifier = soulDew.newModifier(scene.getParty()[0]) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 1;
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
|
@ -5,7 +5,7 @@ import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||
|
@ -9,7 +9,7 @@ import { Gender } from "#app/data/gender";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import * as BattleAnims from "#app/data/battle-anims";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||
|
@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type";
|
||||
import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { PokemonMove } from "#app/field/pokemon";
|
||||
|
@ -8,7 +8,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type";
|
||||
import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "../encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "../encounterTestUtils";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils";
|
||||
|
@ -5,7 +5,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type";
|
||||
import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
|
@ -5,7 +5,7 @@ import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { CIVILIZATION_ENCOUNTER_BIOMES } from "#app/data/mystery-encounters/mystery-encounters";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
|
@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#app/enums/mystery-encounter-type";
|
||||
import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
@ -151,6 +151,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => {
|
||||
it("should NOT be selectable if the player doesn't have enough money", async () => {
|
||||
game.scene.money = 0;
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.TELEPORTING_HIJINKS, defaultParty);
|
||||
scene.getParty().forEach(p => p.moveset = []);
|
||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||
|
||||
const encounterPhase = scene.getCurrentPhase();
|
||||
|
@ -5,7 +5,7 @@ import { Species } from "#app/enums/species";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { HUMAN_TRANSITABLE_BIOMES } from "#app/data/mystery-encounters/mystery-encounters";
|
||||
|
@ -7,7 +7,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import * as BattleAnims from "#app/data/battle-anims";
|
||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounter-test-utils";
|
||||
import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { TheStrongStuffEncounter } from "#app/data/mystery-encounters/encounters/the-strong-stuff-encounter";
|
||||
@ -164,10 +164,9 @@ describe("The Strong Stuff - Mystery Encounter", () => {
|
||||
return baseStats.reduce((a, b) => a + b);
|
||||
});
|
||||
|
||||
// HP stat changes are halved compared to other values
|
||||
expect(bstsAfter[0]).toEqual(bstsPrior[0] - 20 * 5 - 10);
|
||||
expect(bstsAfter[1]).toEqual(bstsPrior[1] + 10 * 5 + 5);
|
||||
expect(bstsAfter[2]).toEqual(bstsPrior[2] + 10 * 5 + 5);
|
||||
expect(bstsAfter[0]).toEqual(bstsPrior[0] - 20 * 6);
|
||||
expect(bstsAfter[1]).toEqual(bstsPrior[1] + 10 * 6);
|
||||
expect(bstsAfter[2]).toEqual(bstsPrior[2] + 10 * 6);
|
||||
});
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user