mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-21 17:12:44 +02:00
Converted most MEs, introduced some more utility functions and methods
This commit is contained in:
parent
2321de0983
commit
ebf0f3e352
@ -906,6 +906,7 @@ export default class BattleScene extends SceneBase {
|
||||
variant?: Variant,
|
||||
ivs?: number[],
|
||||
nature?: Nature,
|
||||
heldItemConfig?: HeldItemConfiguration,
|
||||
dataSource?: Pokemon | PokemonData,
|
||||
postProcess?: (playerPokemon: PlayerPokemon) => void,
|
||||
): PlayerPokemon {
|
||||
@ -925,6 +926,9 @@ export default class BattleScene extends SceneBase {
|
||||
postProcess(pokemon);
|
||||
}
|
||||
pokemon.init();
|
||||
if (heldItemConfig) {
|
||||
assignItemsFromConfiguration(heldItemConfig, pokemon);
|
||||
}
|
||||
return pokemon;
|
||||
}
|
||||
|
||||
@ -934,6 +938,7 @@ export default class BattleScene extends SceneBase {
|
||||
trainerSlot: TrainerSlot,
|
||||
boss = false,
|
||||
shinyLock = false,
|
||||
heldItemConfig?: HeldItemConfiguration,
|
||||
dataSource?: PokemonData,
|
||||
postProcess?: (enemyPokemon: EnemyPokemon) => void,
|
||||
): EnemyPokemon {
|
||||
@ -975,6 +980,9 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
|
||||
pokemon.init();
|
||||
if (heldItemConfig) {
|
||||
assignItemsFromConfiguration(heldItemConfig, pokemon);
|
||||
}
|
||||
return pokemon;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import {
|
||||
generateModifierType,
|
||||
getPartyBerries,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
setEncounterRewards,
|
||||
@ -9,14 +9,12 @@ import {
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { EnemyPokemon } from "#app/field/pokemon";
|
||||
import { PokemonMove } from "#app/data/moves/pokemon-move";
|
||||
import { modifierTypes } from "#app/data/data-lists";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { PersistentModifierRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
@ -25,19 +23,17 @@ import { MoveId } from "#enums/move-id";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { randInt } from "#app/utils/common";
|
||||
import { BattlerIndex } from "#enums/battler-index";
|
||||
import {
|
||||
applyModifierTypeToPlayerPokemon,
|
||||
catchPokemon,
|
||||
getHighestLevelPlayerPokemon,
|
||||
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { catchPokemon, getHighestLevelPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
import type HeldModifierConfig from "#app/@types/held-modifier-config";
|
||||
import type { BerryType } from "#enums/berry-type";
|
||||
import { Stat } from "#enums/stat";
|
||||
import i18next from "i18next";
|
||||
import type { MysteryEncounterSpriteConfig } from "#app/field/mystery-encounter-intro";
|
||||
import { MoveUseMode } from "#enums/move-use-mode";
|
||||
import type { HeldItemConfiguration } from "#app/items/held-item-data-types";
|
||||
import { allHeldItems } from "#app/items/all-held-items";
|
||||
import { HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
|
||||
import { HeldItemRequirement } from "../mystery-encounter-requirements";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounters/absoluteAvarice";
|
||||
@ -64,7 +60,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(20, 180)
|
||||
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 6)) // Must have at least 6 berries to spawn
|
||||
.withSceneRequirement(new HeldItemRequirement(HeldItemCategoryId.BERRY, 6)) // Must have at least 6 berries to spawn
|
||||
.withFleeAllowed(false)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
@ -114,35 +110,17 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
globalScene.loadSe("PRSFX- Bug Bite", "battle_anims", "PRSFX- Bug Bite.wav");
|
||||
globalScene.loadSe("Follow Me", "battle_anims", "Follow Me.mp3");
|
||||
|
||||
// Get all player berry items, remove from party, and store reference
|
||||
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
||||
// Get all berries in party, with references to the pokemon
|
||||
const berryItems = getPartyBerries();
|
||||
|
||||
// Sort berries by party member ID to more easily re-add later if necessary
|
||||
const berryItemsMap = new Map<number, BerryModifier[]>();
|
||||
globalScene.getPlayerParty().forEach(pokemon => {
|
||||
const pokemonBerries = berryItems.filter(b => b.pokemonId === pokemon.id);
|
||||
if (pokemonBerries?.length > 0) {
|
||||
berryItemsMap.set(pokemon.id, pokemonBerries);
|
||||
}
|
||||
encounter.misc.berryItemsMap = berryItems;
|
||||
|
||||
// Adds stolen berries to the Greedent item configuration
|
||||
const bossHeldItemConfig: HeldItemConfiguration = [];
|
||||
berryItems.forEach(map => {
|
||||
bossHeldItemConfig.push({ entry: map.item, count: 1 });
|
||||
});
|
||||
|
||||
encounter.misc = { berryItemsMap };
|
||||
|
||||
// Generates copies of the stolen berries to put on the Greedent
|
||||
const bossModifierConfigs: HeldModifierConfig[] = [];
|
||||
berryItems.forEach(berryMod => {
|
||||
// Can't define stack count on a ModifierType, have to just create separate instances for each stack
|
||||
// Overflow berries will be "lost" on the boss, but it's un-catchable anyway
|
||||
for (let i = 0; i < berryMod.stackCount; i++) {
|
||||
const modifierType = generateModifierType(modifierTypes.BERRY, [
|
||||
berryMod.berryType,
|
||||
]) as PokemonHeldItemModifierType;
|
||||
bossModifierConfigs.push({ modifier: modifierType });
|
||||
}
|
||||
});
|
||||
|
||||
// Do NOT remove the real berries yet or else it will be persisted in the session data
|
||||
|
||||
// +1 SpDef below wave 50, SpDef and Speed otherwise
|
||||
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] =
|
||||
globalScene.currentBattle.waveIndex < 50 ? [Stat.SPDEF] : [Stat.SPDEF, Stat.SPD];
|
||||
@ -157,7 +135,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
bossSegments: 3,
|
||||
shiny: false, // Shiny lock because of consistency issues between the different options
|
||||
moveSet: [MoveId.THRASH, MoveId.CRUNCH, MoveId.BODY_PRESS, MoveId.SLACK_OFF],
|
||||
modifierConfigs: bossModifierConfigs,
|
||||
heldItemConfig: bossHeldItemConfig,
|
||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(`${namespace}:option.1.boss_enraged`);
|
||||
@ -184,9 +162,9 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
|
||||
// Remove the berries from the party
|
||||
// Session has been safely saved at this point, so data won't be lost
|
||||
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
||||
berryItems.forEach(berryMod => {
|
||||
globalScene.removeModifier(berryMod);
|
||||
const berryItems = getPartyBerries();
|
||||
berryItems.forEach(map => {
|
||||
map.pokemon.heldItemManager.remove(map.item);
|
||||
});
|
||||
|
||||
globalScene.updateModifiers(true);
|
||||
@ -209,19 +187,14 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
|
||||
// Provides 1x Reviver Seed to each party member at end of battle
|
||||
const revSeed = generateModifierType(modifierTypes.REVIVER_SEED);
|
||||
encounter.setDialogueToken(
|
||||
"foodReward",
|
||||
revSeed?.name ?? i18next.t("modifierType:ModifierType.REVIVER_SEED.name"),
|
||||
allHeldItems[HeldItemId.REVIVER_SEED].name ?? i18next.t("modifierType:ModifierType.REVIVER_SEED.name"),
|
||||
);
|
||||
const givePartyPokemonReviverSeeds = () => {
|
||||
const party = globalScene.getPlayerParty();
|
||||
party.forEach(p => {
|
||||
const heldItems = p.getHeldItems();
|
||||
if (revSeed && !heldItems.some(item => item instanceof PokemonInstantReviveModifier)) {
|
||||
const seedModifier = revSeed.newModifier(p);
|
||||
globalScene.addModifier(seedModifier, false, false, false, true);
|
||||
}
|
||||
p.heldItemManager.add(HeldItemId.REVIVER_SEED);
|
||||
});
|
||||
queueEncounterMessage(`${namespace}:option.1.food_stash`);
|
||||
};
|
||||
@ -257,19 +230,16 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
// Returns 2/5 of the berries stolen to each Pokemon
|
||||
const party = globalScene.getPlayerParty();
|
||||
party.forEach(pokemon => {
|
||||
const stolenBerries: BerryModifier[] = berryMap.get(pokemon.id);
|
||||
const berryTypesAsArray: BerryType[] = [];
|
||||
stolenBerries?.forEach(bMod => berryTypesAsArray.push(...new Array(bMod.stackCount).fill(bMod.berryType)));
|
||||
const returnedBerryCount = Math.floor(((berryTypesAsArray.length ?? 0) * 2) / 5);
|
||||
// TODO: is this check legal?
|
||||
const stolenBerries = berryMap.filter(map => map.pokemon === pokemon);
|
||||
const returnedBerryCount = Math.floor(((stolenBerries.length ?? 0) * 2) / 5);
|
||||
|
||||
if (returnedBerryCount > 0) {
|
||||
for (let i = 0; i < returnedBerryCount; i++) {
|
||||
// Shuffle remaining berry types and pop
|
||||
Phaser.Math.RND.shuffle(berryTypesAsArray);
|
||||
const randBerryType = berryTypesAsArray.pop();
|
||||
|
||||
const berryModType = generateModifierType(modifierTypes.BERRY, [randBerryType]) as BerryModifierType;
|
||||
applyModifierTypeToPlayerPokemon(pokemon, berryModType);
|
||||
Phaser.Math.RND.shuffle(stolenBerries);
|
||||
const randBerryType = stolenBerries.pop();
|
||||
pokemon.heldItemManager.add(randBerryType);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,13 +1,11 @@
|
||||
import type { EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import {
|
||||
generateModifierType,
|
||||
generateModifierTypeOption,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
setEncounterRewards,
|
||||
transitionMysteryEncounterIntroVisuals,
|
||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { modifierTypes } from "#app/data/data-lists";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||
@ -19,17 +17,18 @@ import { AbilityId } from "#enums/ability-id";
|
||||
import { getPokemonSpecies } from "#app/utils/pokemon-utils";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { Nature } from "#enums/nature";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import { BerryType } from "#enums/berry-type";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { SpeciesFormChangeAbilityTrigger } from "#app/data/pokemon-forms/form-change-triggers";
|
||||
import { applyPostBattleInitAbAttrs } from "#app/data/abilities/apply-ab-attrs";
|
||||
import { showEncounterDialogue, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
import i18next from "i18next";
|
||||
import { ModifierTier } from "#enums/modifier-tier";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { modifierTypes } from "#app/data/data-lists";
|
||||
import { ModifierTier } from "#enums/modifier-tier";
|
||||
import { HeldItemId } from "#enums/held-item-id";
|
||||
|
||||
//TODO: make all items unstealable
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounters/theWinstrateChallenge";
|
||||
@ -257,16 +256,9 @@ function getVictorTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 0, // Guts
|
||||
nature: Nature.ADAMANT,
|
||||
moveSet: [MoveId.FACADE, MoveId.BRAVE_BIRD, MoveId.PROTECT, MoveId.QUICK_ATTACK],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
|
||||
isTransferable: false,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.FOCUS_BAND) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
isTransferable: false,
|
||||
},
|
||||
heldItemConfig: [
|
||||
{ entry: HeldItemId.FLAME_ORB, count: 1 },
|
||||
{ entry: HeldItemId.FOCUS_BAND, count: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -275,16 +267,9 @@ function getVictorTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 1, // Guts
|
||||
nature: Nature.ADAMANT,
|
||||
moveSet: [MoveId.FACADE, MoveId.OBSTRUCT, MoveId.NIGHT_SLASH, MoveId.FIRE_PUNCH],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
|
||||
isTransferable: false,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.LEFTOVERS) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
isTransferable: false,
|
||||
},
|
||||
heldItemConfig: [
|
||||
{ entry: HeldItemId.FLAME_ORB, count: 1 },
|
||||
{ entry: HeldItemId.LEFTOVERS, count: 2 },
|
||||
],
|
||||
},
|
||||
],
|
||||
@ -301,16 +286,9 @@ function getVictoriaTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 0, // Natural Cure
|
||||
nature: Nature.CALM,
|
||||
moveSet: [MoveId.SYNTHESIS, MoveId.SLUDGE_BOMB, MoveId.GIGA_DRAIN, MoveId.SLEEP_POWDER],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType,
|
||||
isTransferable: false,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
isTransferable: false,
|
||||
},
|
||||
heldItemConfig: [
|
||||
{ entry: HeldItemId.SOUL_DEW, count: 1 },
|
||||
{ entry: HeldItemId.QUICK_CLAW, count: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -319,21 +297,9 @@ function getVictoriaTrainerConfig(): EnemyPartyConfig {
|
||||
formIndex: 1,
|
||||
nature: Nature.TIMID,
|
||||
moveSet: [MoveId.PSYSHOCK, MoveId.MOONBLAST, MoveId.SHADOW_BALL, MoveId.WILL_O_WISP],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, [
|
||||
PokemonType.PSYCHIC,
|
||||
]) as PokemonHeldItemModifierType,
|
||||
stackCount: 1,
|
||||
isTransferable: false,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, [
|
||||
PokemonType.FAIRY,
|
||||
]) as PokemonHeldItemModifierType,
|
||||
stackCount: 1,
|
||||
isTransferable: false,
|
||||
},
|
||||
heldItemConfig: [
|
||||
{ entry: HeldItemId.TWISTED_SPOON, count: 1 },
|
||||
{ entry: HeldItemId.FAIRY_FEATHER, count: 1 },
|
||||
],
|
||||
},
|
||||
],
|
||||
@ -350,17 +316,9 @@ function getViviTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 3, // Lightning Rod
|
||||
nature: Nature.ADAMANT,
|
||||
moveSet: [MoveId.WATERFALL, MoveId.MEGAHORN, MoveId.KNOCK_OFF, MoveId.REST],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
isTransferable: false,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType,
|
||||
stackCount: 4,
|
||||
isTransferable: false,
|
||||
},
|
||||
heldItemConfig: [
|
||||
{ entry: HeldItemId.LUM_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.HP_UP, count: 4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -369,16 +327,9 @@ function getViviTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 1, // Poison Heal
|
||||
nature: Nature.JOLLY,
|
||||
moveSet: [MoveId.SPORE, MoveId.SWORDS_DANCE, MoveId.SEED_BOMB, MoveId.DRAIN_PUNCH],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType,
|
||||
stackCount: 4,
|
||||
isTransferable: false,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.TOXIC_ORB) as PokemonHeldItemModifierType,
|
||||
isTransferable: false,
|
||||
},
|
||||
heldItemConfig: [
|
||||
{ entry: HeldItemId.HP_UP, count: 4 },
|
||||
{ entry: HeldItemId.TOXIC_ORB, count: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -387,13 +338,7 @@ function getViviTrainerConfig(): EnemyPartyConfig {
|
||||
formIndex: 1,
|
||||
nature: Nature.CALM,
|
||||
moveSet: [MoveId.EARTH_POWER, MoveId.FIRE_BLAST, MoveId.YAWN, MoveId.PROTECT],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
|
||||
stackCount: 3,
|
||||
isTransferable: false,
|
||||
},
|
||||
],
|
||||
heldItemConfig: [{ entry: HeldItemId.QUICK_CLAW, count: 3 }],
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -409,12 +354,7 @@ function getVickyTrainerConfig(): EnemyPartyConfig {
|
||||
formIndex: 1,
|
||||
nature: Nature.IMPISH,
|
||||
moveSet: [MoveId.AXE_KICK, MoveId.ICE_PUNCH, MoveId.ZEN_HEADBUTT, MoveId.BULLET_PUNCH],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType,
|
||||
isTransferable: false,
|
||||
},
|
||||
],
|
||||
heldItemConfig: [{ entry: HeldItemId.SHELL_BELL, count: 1 }],
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -430,13 +370,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 0, // Soundproof
|
||||
nature: Nature.MODEST,
|
||||
moveSet: [MoveId.THUNDERBOLT, MoveId.GIGA_DRAIN, MoveId.FOUL_PLAY, MoveId.THUNDER_WAVE],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.SPD]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
isTransferable: false,
|
||||
},
|
||||
],
|
||||
heldItemConfig: [{ entry: HeldItemId.ZINC, count: 2 }],
|
||||
},
|
||||
{
|
||||
species: getPokemonSpecies(SpeciesId.SWALOT),
|
||||
@ -444,51 +378,18 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 2, // Gluttony
|
||||
nature: Nature.QUIET,
|
||||
moveSet: [MoveId.SLUDGE_BOMB, MoveId.GIGA_DRAIN, MoveId.ICE_BEAM, MoveId.EARTHQUAKE],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.APICOT]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.STARF]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SALAC]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.LANSAT]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.LIECHI]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.PETAYA]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.LEPPA]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
},
|
||||
heldItemConfig: [
|
||||
{ entry: HeldItemId.SITRUS_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.APICOT_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.GANLON_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.STARF_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.SALAC_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.LUM_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.LANSAT_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.LIECHI_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.PETAYA_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.ENIGMA_BERRY, count: 2 },
|
||||
{ entry: HeldItemId.LEPPA_BERRY, count: 2 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -497,13 +398,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 2, // Tangled Feet
|
||||
nature: Nature.JOLLY,
|
||||
moveSet: [MoveId.DRILL_PECK, MoveId.QUICK_ATTACK, MoveId.THRASH, MoveId.KNOCK_OFF],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.KINGS_ROCK) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
isTransferable: false,
|
||||
},
|
||||
],
|
||||
heldItemConfig: [{ entry: HeldItemId.KINGS_ROCK, count: 2 }],
|
||||
},
|
||||
{
|
||||
species: getPokemonSpecies(SpeciesId.ALAKAZAM),
|
||||
@ -511,13 +406,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
|
||||
formIndex: 1,
|
||||
nature: Nature.BOLD,
|
||||
moveSet: [MoveId.PSYCHIC, MoveId.SHADOW_BALL, MoveId.FOCUS_BLAST, MoveId.THUNDERBOLT],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.WIDE_LENS) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
isTransferable: false,
|
||||
},
|
||||
],
|
||||
heldItemConfig: [{ entry: HeldItemId.WIDE_LENS, count: 2 }],
|
||||
},
|
||||
{
|
||||
species: getPokemonSpecies(SpeciesId.DARMANITAN),
|
||||
@ -525,13 +414,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
|
||||
abilityIndex: 0, // Sheer Force
|
||||
nature: Nature.IMPISH,
|
||||
moveSet: [MoveId.EARTHQUAKE, MoveId.U_TURN, MoveId.FLARE_BLITZ, MoveId.ROCK_SLIDE],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
|
||||
stackCount: 2,
|
||||
isTransferable: false,
|
||||
},
|
||||
],
|
||||
heldItemConfig: [{ entry: HeldItemId.QUICK_CLAW, count: 2 }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { EnemyPartyConfig, EnemyPokemonConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import {
|
||||
assignItemToFirstFreePokemon,
|
||||
generateModifierType,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
@ -16,7 +17,6 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/myst
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import i18next from "#app/plugins/i18n";
|
||||
import { ModifierTier } from "#enums/modifier-tier";
|
||||
@ -27,6 +27,8 @@ import { PokemonMove } from "#app/data/moves/pokemon-move";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||
import { randSeedInt } from "#app/utils/common";
|
||||
import { MoveUseMode } from "#enums/move-use-mode";
|
||||
import { HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
|
||||
import { allHeldItems } from "#app/items/all-held-items";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounters/trashToTreasure";
|
||||
@ -81,41 +83,13 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
formIndex: 1, // Gmax
|
||||
bossSegmentModifier: 1, // +1 Segment from normal
|
||||
moveSet: [MoveId.GUNK_SHOT, MoveId.STOMPING_TANTRUM, MoveId.HAMMER_ARM, MoveId.PAYBACK],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY) as PokemonHeldItemModifierType,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY) as PokemonHeldItemModifierType,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY) as PokemonHeldItemModifierType,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BERRY) as PokemonHeldItemModifierType,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER) as PokemonHeldItemModifierType,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER) as PokemonHeldItemModifierType,
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.TOXIC_ORB) as PokemonHeldItemModifierType,
|
||||
stackCount: randSeedInt(2, 0),
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.SOOTHE_BELL) as PokemonHeldItemModifierType,
|
||||
stackCount: randSeedInt(2, 1),
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.LUCKY_EGG) as PokemonHeldItemModifierType,
|
||||
stackCount: randSeedInt(3, 1),
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(modifierTypes.GOLDEN_EGG) as PokemonHeldItemModifierType,
|
||||
stackCount: randSeedInt(2, 0),
|
||||
},
|
||||
heldItemConfig: [
|
||||
{ entry: HeldItemCategoryId.BERRY, count: 4 },
|
||||
{ entry: HeldItemCategoryId.BASE_STAT_BOOST, count: 2 },
|
||||
{ entry: HeldItemId.TOXIC_ORB, count: randSeedInt(2, 0) },
|
||||
{ entry: HeldItemId.SOOTHE_BELL, count: randSeedInt(2, 1) },
|
||||
{ entry: HeldItemId.LUCKY_EGG, count: randSeedInt(3, 1) },
|
||||
{ entry: HeldItemId.GOLDEN_EGG, count: randSeedInt(2, 0) },
|
||||
],
|
||||
};
|
||||
const config: EnemyPartyConfig = {
|
||||
@ -222,44 +196,18 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
.build();
|
||||
|
||||
async function tryApplyDigRewardItems() {
|
||||
const shellBell = generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||
const leftovers = generateModifierType(modifierTypes.LEFTOVERS) as PokemonHeldItemModifierType;
|
||||
|
||||
const party = globalScene.getPlayerParty();
|
||||
|
||||
// Iterate over the party until an item was successfully given
|
||||
// First leftovers
|
||||
for (const pokemon of party) {
|
||||
const heldItems = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
const existingLeftovers = heldItems.find(m => m instanceof TurnHealModifier) as TurnHealModifier;
|
||||
|
||||
if (!existingLeftovers || existingLeftovers.getStackCount() < existingLeftovers.getMaxStackCount()) {
|
||||
await applyModifierTypeToPlayerPokemon(pokemon, leftovers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assignItemToFirstFreePokemon(HeldItemId.LEFTOVERS, party);
|
||||
|
||||
// Second leftovers
|
||||
for (const pokemon of party) {
|
||||
const heldItems = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
const existingLeftovers = heldItems.find(m => m instanceof TurnHealModifier) as TurnHealModifier;
|
||||
|
||||
if (!existingLeftovers || existingLeftovers.getStackCount() < existingLeftovers.getMaxStackCount()) {
|
||||
await applyModifierTypeToPlayerPokemon(pokemon, leftovers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assignItemToFirstFreePokemon(HeldItemId.LEFTOVERS, party);
|
||||
|
||||
globalScene.playSound("item_fanfare");
|
||||
await showEncounterText(
|
||||
i18next.t("battle:rewardGainCount", {
|
||||
modifierName: leftovers.name,
|
||||
modifierName: allHeldItems[HeldItemId.LEFTOVERS].name,
|
||||
count: 2,
|
||||
}),
|
||||
null,
|
||||
@ -268,23 +216,12 @@ async function tryApplyDigRewardItems() {
|
||||
);
|
||||
|
||||
// Only Shell bell
|
||||
for (const pokemon of party) {
|
||||
const heldItems = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
const existingShellBell = heldItems.find(m => m instanceof HitHealModifier) as HitHealModifier;
|
||||
|
||||
if (!existingShellBell || existingShellBell.getStackCount() < existingShellBell.getMaxStackCount()) {
|
||||
await applyModifierTypeToPlayerPokemon(pokemon, shellBell);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assignItemToFirstFreePokemon(HeldItemId.SHELL_BELL, party);
|
||||
|
||||
globalScene.playSound("item_fanfare");
|
||||
await showEncounterText(
|
||||
i18next.t("battle:rewardGainCount", {
|
||||
modifierName: shellBell.name,
|
||||
modifierName: allHeldItems[HeldItemId.SHELL_BELL].name,
|
||||
count: 1,
|
||||
}),
|
||||
null,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import type { EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import {
|
||||
getPartyBerries,
|
||||
getRandomEncounterSpecies,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
@ -15,10 +16,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import {
|
||||
MoveRequirement,
|
||||
PersistentModifierRequirement,
|
||||
} from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import { HeldItemRequirement, MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import {
|
||||
@ -36,6 +34,8 @@ import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encoun
|
||||
import { Stat } from "#enums/stat";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||
import { MoveUseMode } from "#enums/move-use-mode";
|
||||
import type { PokemonItemMap } from "#app/items/held-item-data-types";
|
||||
import { HeldItemCategoryId } from "#enums/held-item-id";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounters/uncommonBreed";
|
||||
@ -190,7 +190,7 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
)
|
||||
.withOption(
|
||||
MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
||||
.withSceneRequirement(new HeldItemRequirement(HeldItemCategoryId.BERRY, 4)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
@ -206,19 +206,18 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
|
||||
// Remove 4 random berries from player's party
|
||||
// Get all player berry items, remove from party, and store reference
|
||||
const berryItems: BerryModifier[] = globalScene.findModifiers(
|
||||
m => m instanceof BerryModifier,
|
||||
) as BerryModifier[];
|
||||
|
||||
const berryMap = getPartyBerries();
|
||||
const stolenBerryMap: PokemonItemMap[] = [];
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const index = randSeedInt(berryItems.length);
|
||||
const randBerry = berryItems[index];
|
||||
randBerry.stackCount--;
|
||||
if (randBerry.stackCount === 0) {
|
||||
globalScene.removeModifier(randBerry);
|
||||
berryItems.splice(index, 1);
|
||||
}
|
||||
const index = randSeedInt(berryMap.length);
|
||||
const randBerry = berryMap[index];
|
||||
randBerry.pokemon.heldItemManager.remove(randBerry.item);
|
||||
stolenBerryMap.push(randBerry);
|
||||
berryMap.splice(index, 1);
|
||||
}
|
||||
await globalScene.updateModifiers(true, true);
|
||||
await globalScene.updateModifiers(true);
|
||||
|
||||
// Pokemon joins the team, with 2 egg moves
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
|
@ -7,7 +7,6 @@ import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-en
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import type { EnemyPartyConfig, EnemyPokemonConfig } from "../utils/encounter-phase-utils";
|
||||
import {
|
||||
generateModifierType,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
setEncounterRewards,
|
||||
@ -21,11 +20,9 @@ import { NumberHolder, isNullOrUndefined, randSeedInt, randSeedShuffle } from "#
|
||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||
import { getPokemonSpecies } from "#app/utils/pokemon-utils";
|
||||
import { allSpecies } from "#app/data/data-lists";
|
||||
import type { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||
import { HiddenAbilityRateBoosterModifier, PokemonFormChangeItemModifier } from "#app/modifier/modifier";
|
||||
import { HiddenAbilityRateBoosterModifier } from "#app/modifier/modifier";
|
||||
import { achvs } from "#app/system/achv";
|
||||
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||
import { modifierTypes } from "#app/data/data-lists";
|
||||
import i18next from "#app/plugins/i18n";
|
||||
import {
|
||||
@ -40,10 +37,12 @@ import { PlayerGender } from "#enums/player-gender";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { Nature } from "#enums/nature";
|
||||
import type HeldModifierConfig from "#app/@types/held-modifier-config";
|
||||
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import type { HeldItemConfiguration, HeldItemSpecs } from "#app/items/held-item-data-types";
|
||||
import { assignItemsFromConfiguration } from "#app/items/held-item-pool";
|
||||
import { HeldItemId } from "#enums/held-item-id";
|
||||
|
||||
/** i18n namespace for encounter */
|
||||
const namespace = "mysteryEncounters/weirdDream";
|
||||
@ -265,24 +264,20 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
||||
dataSource.player = false;
|
||||
|
||||
// Copy held items to new pokemon
|
||||
const newPokemonHeldItemConfigs: HeldModifierConfig[] = [];
|
||||
for (const item of transformation.heldItems) {
|
||||
newPokemonHeldItemConfigs.push({
|
||||
modifier: item.clone() as PokemonHeldItemModifier,
|
||||
stackCount: item.getStackCount(),
|
||||
isTransferable: false,
|
||||
});
|
||||
}
|
||||
// TODO: Make items untransferable
|
||||
const newPokemonHeldItemConfig = transformation.heldItems;
|
||||
|
||||
// Any pokemon that is below 570 BST gets +20 permanent BST to 3 stats
|
||||
if (shouldGetOldGateau(newPokemon)) {
|
||||
const stats = getOldGateauBoostedStats(newPokemon);
|
||||
newPokemonHeldItemConfigs.push({
|
||||
modifier: generateModifierType(modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU, [
|
||||
OLD_GATEAU_STATS_UP,
|
||||
stats,
|
||||
]) as PokemonHeldItemModifierType,
|
||||
stackCount: 1,
|
||||
isTransferable: false,
|
||||
const gateauItem = {
|
||||
id: HeldItemId.OLD_GATEAU,
|
||||
stack: 1,
|
||||
data: { statModifier: OLD_GATEAU_STATS_UP, stats: stats },
|
||||
} as HeldItemSpecs;
|
||||
newPokemonHeldItemConfig.push({
|
||||
entry: gateauItem,
|
||||
count: 1,
|
||||
});
|
||||
}
|
||||
|
||||
@ -291,7 +286,7 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
||||
isBoss: newPokemon.getSpeciesForm().getBaseStatTotal() > NON_LEGENDARY_BST_THRESHOLD,
|
||||
level: previousPokemon.level,
|
||||
dataSource: dataSource,
|
||||
modifierConfigs: newPokemonHeldItemConfigs,
|
||||
heldItemConfig: newPokemonHeldItemConfig,
|
||||
};
|
||||
|
||||
enemyPokemonConfigs.push(enemyConfig);
|
||||
@ -372,7 +367,7 @@ interface PokemonTransformation {
|
||||
previousPokemon: PlayerPokemon;
|
||||
newSpecies: PokemonSpecies;
|
||||
newPokemon: PlayerPokemon;
|
||||
heldItems: PokemonHeldItemModifier[];
|
||||
heldItems: HeldItemConfiguration;
|
||||
}
|
||||
|
||||
function getTeamTransformations(): PokemonTransformation[] {
|
||||
@ -397,9 +392,7 @@ function getTeamTransformations(): PokemonTransformation[] {
|
||||
for (let i = 0; i < numPokemon; i++) {
|
||||
const removed = removedPokemon[i];
|
||||
const index = pokemonTransformations.findIndex(p => p.previousPokemon.id === removed.id);
|
||||
pokemonTransformations[index].heldItems = removed
|
||||
.getHeldItems()
|
||||
.filter(m => !(m instanceof PokemonFormChangeItemModifier));
|
||||
pokemonTransformations[index].heldItems = removed.heldItemManager.generateHeldItemConfiguration();
|
||||
|
||||
const bst = removed.getSpeciesForm().getBaseStatTotal();
|
||||
let newBstRange: [number, number];
|
||||
@ -455,22 +448,22 @@ async function doNewTeamPostProcess(transformations: PokemonTransformation[]) {
|
||||
}
|
||||
|
||||
// Copy old items to new pokemon
|
||||
for (const item of transformation.heldItems) {
|
||||
item.pokemonId = newPokemon.id;
|
||||
globalScene.addModifier(item, false, false, false, true);
|
||||
}
|
||||
const heldItemConfiguration = transformation.heldItems;
|
||||
|
||||
// Any pokemon that is below 570 BST gets +20 permanent BST to 3 stats
|
||||
if (shouldGetOldGateau(newPokemon)) {
|
||||
const stats = getOldGateauBoostedStats(newPokemon);
|
||||
const modType = modifierTypes
|
||||
.MYSTERY_ENCOUNTER_OLD_GATEAU()
|
||||
.generateType(globalScene.getPlayerParty(), [OLD_GATEAU_STATS_UP, stats])
|
||||
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU);
|
||||
const modifier = modType?.newModifier(newPokemon);
|
||||
if (modifier) {
|
||||
globalScene.addModifier(modifier, false, false, false, true);
|
||||
}
|
||||
const gateauItem = {
|
||||
id: HeldItemId.OLD_GATEAU,
|
||||
stack: 1,
|
||||
data: { statModifier: OLD_GATEAU_STATS_UP, stats: stats },
|
||||
} as HeldItemSpecs;
|
||||
heldItemConfiguration.push({
|
||||
entry: gateauItem,
|
||||
count: 1,
|
||||
});
|
||||
}
|
||||
assignItemsFromConfiguration(heldItemConfiguration, newPokemon);
|
||||
|
||||
newPokemon.calculateStats();
|
||||
await newPokemon.updateInfo();
|
||||
|
@ -14,7 +14,7 @@ import { MoveId } from "#enums/move-id";
|
||||
import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { TimeOfDay } from "#enums/time-of-day";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
import type { HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
|
||||
import { allHeldItems } from "#app/items/all-held-items";
|
||||
|
||||
export interface EncounterRequirement {
|
||||
@ -351,39 +351,6 @@ export class PartySizeRequirement extends EncounterSceneRequirement {
|
||||
}
|
||||
}
|
||||
|
||||
export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
||||
requiredHeldItemModifiers: string[];
|
||||
minNumberOfItems: number;
|
||||
|
||||
constructor(heldItem: string | string[], minNumberOfItems = 1) {
|
||||
super();
|
||||
this.minNumberOfItems = minNumberOfItems;
|
||||
this.requiredHeldItemModifiers = coerceArray(heldItem);
|
||||
}
|
||||
|
||||
override meetsRequirement(): boolean {
|
||||
const partyPokemon = globalScene.getPlayerParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredHeldItemModifiers?.length < 0) {
|
||||
return false;
|
||||
}
|
||||
let modifierCount = 0;
|
||||
for (const modifier of this.requiredHeldItemModifiers) {
|
||||
const matchingMods = globalScene.findModifiers(m => m.constructor.name === modifier);
|
||||
if (matchingMods?.length > 0) {
|
||||
for (const matchingMod of matchingMods) {
|
||||
modifierCount += matchingMod.stackCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modifierCount >= this.minNumberOfItems;
|
||||
}
|
||||
|
||||
override getDialogueToken(_pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["requiredItem", this.requiredHeldItemModifiers[0]];
|
||||
}
|
||||
}
|
||||
|
||||
export class MoneyRequirement extends EncounterSceneRequirement {
|
||||
requiredMoney: number; // Static value
|
||||
scalingMultiplier: number; // Calculates required money based off wave index
|
||||
@ -833,13 +800,13 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
||||
}
|
||||
|
||||
export class HeldItemRequirement extends EncounterPokemonRequirement {
|
||||
requiredHeldItems: HeldItemId[];
|
||||
requiredHeldItems: HeldItemId[] | HeldItemCategoryId[];
|
||||
minNumberOfPokemon: number;
|
||||
invertQuery: boolean;
|
||||
requireTransferable: boolean;
|
||||
|
||||
constructor(
|
||||
heldItem: HeldItemId | HeldItemId[],
|
||||
heldItem: HeldItemId | HeldItemId[] | HeldItemCategoryId | HeldItemCategoryId[],
|
||||
minNumberOfPokemon = 1,
|
||||
invertQuery = false,
|
||||
requireTransferable = true,
|
||||
@ -863,7 +830,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter(pokemon =>
|
||||
this.requiredHeldItems.some(heldItem => {
|
||||
pokemon.heldItemManager.hasItem(heldItem) &&
|
||||
(pokemon.heldItemManager.hasItem(heldItem) || pokemon.heldItemManager.hasItemCategory(heldItem)) &&
|
||||
(!this.requireTransferable || allHeldItems[heldItem].isTransferable);
|
||||
}),
|
||||
);
|
||||
|
@ -52,7 +52,9 @@ import { PokemonType } from "#enums/pokemon-type";
|
||||
import { getNatureName } from "#app/data/nature";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { timedEventManager } from "#app/global-event-manager";
|
||||
import type { HeldItemConfiguration } from "#app/items/held-item-data-types";
|
||||
import type { HeldItemConfiguration, PokemonItemMap } from "#app/items/held-item-data-types";
|
||||
import { HeldItemCategoryId, type HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
||||
import { allHeldItems } from "#app/items/all-held-items";
|
||||
|
||||
/**
|
||||
* Animates exclamation sprite over trainer's head at start of encounter
|
||||
@ -1305,3 +1307,29 @@ export function calculateRareSpawnAggregateStats(luckValue: number) {
|
||||
|
||||
console.log(stats);
|
||||
}
|
||||
|
||||
// Iterate over the party until an item is successfully given
|
||||
export function assignItemToFirstFreePokemon(item: HeldItemId, party: Pokemon[]): void {
|
||||
for (const pokemon of party) {
|
||||
const stack = pokemon.heldItemManager.getStack(item);
|
||||
if (stack < allHeldItems[item].getMaxStackCount()) {
|
||||
pokemon.heldItemManager.add(item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates an item map of berries to pokemon, storing each berry separately (splitting up stacks)
|
||||
export function getPartyBerries(): PokemonItemMap[] {
|
||||
const pokemonItems: PokemonItemMap[] = [];
|
||||
globalScene.getPlayerParty().forEach(pokemon => {
|
||||
const berries = pokemon.getHeldItems().filter(item => isItemInCategory(item, HeldItemCategoryId.BERRY));
|
||||
berries.forEach(berryId => {
|
||||
const berryStack = pokemon.heldItemManager.getStack(berryId);
|
||||
for (let i = 1; i <= berryStack; i++) {
|
||||
pokemonItems.push({ item: berryId, pokemon: pokemon });
|
||||
}
|
||||
});
|
||||
});
|
||||
return pokemonItems;
|
||||
}
|
||||
|
@ -38,14 +38,13 @@ export const HeldItemId = {
|
||||
BLACK_GLASSES: 0x0311,
|
||||
FAIRY_FEATHER: 0x0312,
|
||||
|
||||
// Stat Boosters
|
||||
EVIOLITE: 0x0401,
|
||||
LIGHT_BALL: 0x0402,
|
||||
THICK_CLUB: 0x0403,
|
||||
METAL_POWDER: 0x0404,
|
||||
QUICK_POWDER: 0x0405,
|
||||
DEEP_SEA_SCALE: 0x0406,
|
||||
DEEP_SEA_TOOTH: 0x0407,
|
||||
// Species Stat Boosters
|
||||
LIGHT_BALL: 0x0401,
|
||||
THICK_CLUB: 0x0402,
|
||||
METAL_POWDER: 0x0403,
|
||||
QUICK_POWDER: 0x0404,
|
||||
DEEP_SEA_SCALE: 0x0405,
|
||||
DEEP_SEA_TOOTH: 0x0406,
|
||||
|
||||
// Crit Boosters
|
||||
SCOPE_LENS: 0x0501,
|
||||
@ -72,6 +71,7 @@ export const HeldItemId = {
|
||||
SOUL_DEW: 0x070D,
|
||||
BATON: 0x070E,
|
||||
MINI_BLACK_HOLE: 0x070F,
|
||||
EVIOLITE: 0x0710,
|
||||
|
||||
// Vitamins
|
||||
HP_UP: 0x0801,
|
||||
@ -110,7 +110,7 @@ export const HeldItemCategoryId = {
|
||||
BERRY: 0x0100,
|
||||
CONSUMABLE: 0x0200,
|
||||
TYPE_ATTACK_BOOSTER: 0x0300,
|
||||
STAT_BOOSTER: 0x0400,
|
||||
SPECIES_STAT_BOOSTER: 0x0400,
|
||||
CRIT_BOOSTER: 0x0500,
|
||||
GAIN_INCREASE: 0x0600,
|
||||
UNIQUE: 0x0700,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { allHeldItems } from "#app/items/all-held-items";
|
||||
import { isItemInRequested, type HeldItemCategoryId, type HeldItemId } from "#app/enums/held-item-id";
|
||||
import { isItemInCategory, isItemInRequested, type HeldItemCategoryId, type HeldItemId } from "#app/enums/held-item-id";
|
||||
import type { FormChangeItem } from "#enums/form-change-item";
|
||||
import {
|
||||
type HeldItemConfiguration,
|
||||
@ -75,6 +75,10 @@ export class PokemonItemManager {
|
||||
return itemType in this.heldItems;
|
||||
}
|
||||
|
||||
hasItemCategory(categoryId: HeldItemCategoryId): boolean {
|
||||
return Object.keys(this.heldItems).some(id => isItemInCategory(Number(id), categoryId));
|
||||
}
|
||||
|
||||
getStack(itemType: HeldItemId): number {
|
||||
const item = this.heldItems[itemType];
|
||||
return item ? item.stack : 0;
|
||||
|
@ -70,3 +70,8 @@ type HeldItemConfigurationEntry = {
|
||||
};
|
||||
|
||||
export type HeldItemConfiguration = HeldItemConfigurationEntry[];
|
||||
|
||||
export type PokemonItemMap = {
|
||||
item: HeldItemId;
|
||||
pokemon: Pokemon;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user