mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-11-05 19:01:20 +01:00
* Remove unnecessary re-exports * Move `Type` enum to `src/enums/type.ts` * Remove import style change from `modifier-type.ts`
209 lines
8.2 KiB
TypeScript
209 lines
8.2 KiB
TypeScript
import { EnemyPartyConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
|
import { modifierTypes, PokemonHeldItemModifierType, } from "#app/modifier/modifier-type";
|
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
|
import BattleScene from "#app/battle-scene";
|
|
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|
import { Species } from "#enums/species";
|
|
import { Nature } from "#enums/nature";
|
|
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
|
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
|
import { modifyPlayerPokemonBST } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
|
import { Moves } from "#enums/moves";
|
|
import { BattlerIndex } from "#app/battle";
|
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
|
import { BerryType } from "#enums/berry-type";
|
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|
import { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
|
import { Stat } from "#enums/stat";
|
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|
|
|
/** the i18n namespace for the encounter */
|
|
const namespace = "mysteryEncounters/theStrongStuff";
|
|
|
|
// Halved for HP stat
|
|
const HIGH_BST_REDUCTION_VALUE = 15;
|
|
const BST_INCREASE_VALUE = 10;
|
|
|
|
/**
|
|
* The Strong Stuff encounter.
|
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3803 | GitHub Issue #3803}
|
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
|
*/
|
|
export const TheStrongStuffEncounter: MysteryEncounter =
|
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_STRONG_STUFF)
|
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
|
.withScenePartySizeRequirement(3, 6) // Must have at least 3 pokemon in party
|
|
.withMaxAllowedEncounters(1)
|
|
.withHideWildIntroMessage(true)
|
|
.withAutoHideIntroVisuals(false)
|
|
.withFleeAllowed(false)
|
|
.withIntroSpriteConfigs([
|
|
{
|
|
spriteKey: "berry_juice",
|
|
fileRoot: "items",
|
|
hasShadow: true,
|
|
isItem: true,
|
|
scale: 1.25,
|
|
x: -15,
|
|
y: 3,
|
|
disableAnimation: true
|
|
},
|
|
{
|
|
spriteKey: Species.SHUCKLE.toString(),
|
|
fileRoot: "pokemon",
|
|
hasShadow: true,
|
|
repeat: true,
|
|
scale: 1.25,
|
|
x: 20,
|
|
y: 10,
|
|
yShadow: 7
|
|
},
|
|
]) // Set in onInit()
|
|
.withIntroDialogue([
|
|
{
|
|
text: `${namespace}:intro`,
|
|
},
|
|
])
|
|
.withOnInit((scene: BattleScene) => {
|
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
|
|
|
// Calculate boss mon
|
|
const config: EnemyPartyConfig = {
|
|
levelAdditiveModifier: 1,
|
|
disableSwitch: true,
|
|
pokemonConfigs: [
|
|
{
|
|
species: getPokemonSpecies(Species.SHUCKLE),
|
|
isBoss: true,
|
|
bossSegments: 5,
|
|
customPokemonData: new CustomPokemonData({ spriteScale: 1.25 }),
|
|
nature: Nature.BOLD,
|
|
moveSet: [ Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER ],
|
|
modifierConfigs: [
|
|
{
|
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType
|
|
},
|
|
{
|
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType
|
|
},
|
|
{
|
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.APICOT ]) as PokemonHeldItemModifierType
|
|
},
|
|
{
|
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ]) as PokemonHeldItemModifierType
|
|
},
|
|
{
|
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType,
|
|
stackCount: 2
|
|
}
|
|
],
|
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.stat_boost`);
|
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.DEF, Stat.SPDEF ], 2));
|
|
}
|
|
}
|
|
],
|
|
};
|
|
|
|
encounter.enemyPartyConfigs = [ config ];
|
|
|
|
loadCustomMovesForEncounter(scene, [ Moves.GASTRO_ACID, Moves.STEALTH_ROCK ]);
|
|
|
|
encounter.setDialogueToken("shuckleName", getPokemonSpecies(Species.SHUCKLE).getName());
|
|
|
|
return true;
|
|
})
|
|
.setLocalizationKey(`${namespace}`)
|
|
.withTitle(`${namespace}:title`)
|
|
.withDescription(`${namespace}:description`)
|
|
.withQuery(`${namespace}:query`)
|
|
.withSimpleOption(
|
|
{
|
|
buttonLabel: `${namespace}:option.1.label`,
|
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
|
selected: [
|
|
{
|
|
text: `${namespace}:option.1.selected`
|
|
}
|
|
]
|
|
},
|
|
async (scene: BattleScene) => {
|
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
|
// Do blackout and hide intro visuals during blackout
|
|
scene.time.delayedCall(750, () => {
|
|
transitionMysteryEncounterIntroVisuals(scene, true, true, 50);
|
|
});
|
|
|
|
// -15 to all base stats of highest BST (halved for HP), +10 to all base stats of rest of party (halved for HP)
|
|
// Sort party by bst
|
|
const sortedParty = scene.getPlayerParty().slice(0)
|
|
.sort((pokemon1, pokemon2) => {
|
|
const pokemon1Bst = pokemon1.calculateBaseStats().reduce((a, b) => a + b, 0);
|
|
const pokemon2Bst = pokemon2.calculateBaseStats().reduce((a, b) => a + b, 0);
|
|
return pokemon2Bst - pokemon1Bst;
|
|
});
|
|
|
|
sortedParty.forEach((pokemon, index) => {
|
|
if (index < 2) {
|
|
// -15 to the two highest BST mons
|
|
modifyPlayerPokemonBST(pokemon, -HIGH_BST_REDUCTION_VALUE);
|
|
encounter.setDialogueToken("highBstPokemon" + (index + 1), pokemon.getNameToRender());
|
|
} else {
|
|
// +10 for the rest
|
|
modifyPlayerPokemonBST(pokemon, BST_INCREASE_VALUE);
|
|
}
|
|
});
|
|
|
|
encounter.setDialogueToken("reductionValue", HIGH_BST_REDUCTION_VALUE.toString());
|
|
encounter.setDialogueToken("increaseValue", BST_INCREASE_VALUE.toString());
|
|
await showEncounterText(scene, `${namespace}:option.1.selected_2`, null, undefined, true);
|
|
|
|
encounter.dialogue.outro = [
|
|
{
|
|
text: `${namespace}:outro`,
|
|
}
|
|
];
|
|
setEncounterRewards(scene, { fillRemaining: true });
|
|
leaveEncounterWithoutBattle(scene, true);
|
|
return true;
|
|
}
|
|
)
|
|
.withSimpleOption(
|
|
{
|
|
buttonLabel: `${namespace}:option.2.label`,
|
|
buttonTooltip: `${namespace}:option.2.tooltip`,
|
|
selected: [
|
|
{
|
|
text: `${namespace}:option.2.selected`,
|
|
},
|
|
],
|
|
},
|
|
async (scene: BattleScene) => {
|
|
// Pick battle
|
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SOUL_DEW ], fillRemaining: true });
|
|
encounter.startOfBattleEffects.push(
|
|
{
|
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
|
targets: [ BattlerIndex.PLAYER ],
|
|
move: new PokemonMove(Moves.GASTRO_ACID),
|
|
ignorePp: true
|
|
},
|
|
{
|
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
|
targets: [ BattlerIndex.PLAYER ],
|
|
move: new PokemonMove(Moves.STEALTH_ROCK),
|
|
ignorePp: true
|
|
});
|
|
|
|
encounter.dialogue.outro = [];
|
|
await transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
|
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
|
|
}
|
|
)
|
|
.build();
|