Moving more things around

This commit is contained in:
Wlowscha 2025-05-29 22:54:41 +02:00
parent 1dc95c05eb
commit 03a0b429c5
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
16 changed files with 151 additions and 164 deletions

View File

@ -53,7 +53,6 @@ import {
getDefaultModifierTypeForTier, getDefaultModifierTypeForTier,
getEnemyModifierTypesForWave, getEnemyModifierTypesForWave,
getModifierPoolForType, getModifierPoolForType,
ModifierPoolType,
} from "#app/modifier/modifier-pool"; } from "#app/modifier/modifier-pool";
import { getLuckString, getLuckTextTint, getPartyLuckValue } from "#app/modifier/modifier-utils"; import { getLuckString, getLuckTextTint, getPartyLuckValue } from "#app/modifier/modifier-utils";
import AbilityBar from "#app/ui/ability-bar"; import AbilityBar from "#app/ui/ability-bar";
@ -185,6 +184,7 @@ import {
PokemonIncrementingStatModifier, PokemonIncrementingStatModifier,
type TurnHeldItemTransferModifier, type TurnHeldItemTransferModifier,
} from "./modifier/held-item-modifier"; } from "./modifier/held-item-modifier";
import { ModifierPoolType } from "./modifier/modifier-pool-type";
const DEBUG_RNG = false; const DEBUG_RNG = false;

View File

@ -77,7 +77,7 @@ import {
import type { BattlerIndex } from "../../battle"; import type { BattlerIndex } from "../../battle";
import { BattleType } from "#enums/battle-type"; import { BattleType } from "#enums/battle-type";
import { TerrainType } from "../terrain"; import { TerrainType } from "../terrain";
import { getOrInferTier, ModifierPoolType } from "#app/modifier/modifier-pool"; import { getOrInferTier } from "#app/modifier/modifier-pool";
import { Command } from "../../ui/command-ui-handler"; import { Command } from "../../ui/command-ui-handler";
import i18next from "i18next"; import i18next from "i18next";
import type { Localizable } from "#app/interfaces/locales"; import type { Localizable } from "#app/interfaces/locales";
@ -123,6 +123,7 @@ import { MultiHitType } from "#enums/MultiHitType";
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves"; import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves";
import { SelectBiomePhase } from "#app/phases/select-biome-phase"; import { SelectBiomePhase } from "#app/phases/select-biome-phase";
import { PreserveBerryModifier } from "#app/modifier/modifier"; import { PreserveBerryModifier } from "#app/modifier/modifier";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean; type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean; type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean;

View File

@ -13,7 +13,7 @@ import type { PlayerPokemon } from "#app/field/pokemon";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import type { BerryModifierType, ModifierTypeOption } from "#app/modifier/modifier-type"; import type { BerryModifierType, ModifierTypeOption } from "#app/modifier/modifier-type";
import { modifierTypes } from "#app/modifier/modifier-type"; import { modifierTypes } from "#app/modifier/modifier-type";
import { ModifierPoolType, regenerateModifierPoolThresholds } from "#app/modifier/modifier-pool"; import { regenerateModifierPoolThresholds } from "#app/modifier/modifier-pool";
import { randSeedInt } from "#app/utils/common"; import { randSeedInt } from "#app/utils/common";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
@ -38,6 +38,7 @@ import { BerryType } from "#enums/berry-type";
import { PERMANENT_STATS, Stat } from "#enums/stat"; import { PERMANENT_STATS, Stat } from "#enums/stat";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/berriesAbound"; const namespace = "mysteryEncounters/berriesAbound";

View File

@ -14,7 +14,7 @@ import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
import { ModifierTier } from "#app/modifier/modifier-tier"; import { ModifierTier } from "#app/modifier/modifier-tier";
import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { modifierTypes } from "#app/modifier/modifier-type"; import { modifierTypes } from "#app/modifier/modifier-type";
import { ModifierPoolType } from "#app/modifier/modifier-pool"; import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PartyMemberStrength } from "#enums/party-member-strength"; import { PartyMemberStrength } from "#enums/party-member-strength";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";

View File

@ -11,11 +11,7 @@ import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requir
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { ModifierTier } from "#app/modifier/modifier-tier"; import { ModifierTier } from "#app/modifier/modifier-tier";
import type { ModifierTypeOption } from "#app/modifier/modifier-type"; import type { ModifierTypeOption } from "#app/modifier/modifier-type";
import { import { getPlayerModifierTypeOptions, regenerateModifierPoolThresholds } from "#app/modifier/modifier-pool";
getPlayerModifierTypeOptions,
ModifierPoolType,
regenerateModifierPoolThresholds,
} from "#app/modifier/modifier-pool";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
@ -34,6 +30,7 @@ import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encoun
import { randSeedInt } from "#app/utils/common"; import { randSeedInt } from "#app/utils/common";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/fightOrFlight"; const namespace = "mysteryEncounters/fightOrFlight";

View File

@ -7,11 +7,7 @@ import { TrainerSlot } from "#enums/trainer-slot";
import { ModifierTier } from "#app/modifier/modifier-tier"; import { ModifierTier } from "#app/modifier/modifier-tier";
import { MusicPreference } from "#app/system/settings/settings"; import { MusicPreference } from "#app/system/settings/settings";
import type { ModifierTypeOption } from "#app/modifier/modifier-type"; import type { ModifierTypeOption } from "#app/modifier/modifier-type";
import { import { getPlayerModifierTypeOptions, regenerateModifierPoolThresholds } from "#app/modifier/modifier-pool";
getPlayerModifierTypeOptions,
ModifierPoolType,
regenerateModifierPoolThresholds,
} from "#app/modifier/modifier-pool";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
@ -54,6 +50,7 @@ import { doShinySparkleAnim } from "#app/field/anims";
import { TrainerType } from "#enums/trainer-type"; import { TrainerType } from "#enums/trainer-type";
import { timedEventManager } from "#app/global-event-manager"; import { timedEventManager } from "#app/global-event-manager";
import { withTierFromPool } from "#app/modifier/modifier-pool"; import { withTierFromPool } from "#app/modifier/modifier-pool";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/globalTradeSystem"; const namespace = "mysteryEncounters/globalTradeSystem";

View File

@ -19,7 +19,6 @@ import {
} from "#app/modifier/modifier-type"; } from "#app/modifier/modifier-type";
import { import {
type CustomModifierSettings, type CustomModifierSettings,
ModifierPoolType,
regenerateModifierPoolThresholds, regenerateModifierPoolThresholds,
withTierFromPool, withTierFromPool,
} from "#app/modifier/modifier-pool"; } from "#app/modifier/modifier-pool";
@ -70,6 +69,7 @@ import { PokemonType } from "#enums/pokemon-type";
import { getNatureName } from "#app/data/nature"; import { getNatureName } from "#app/data/nature";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { timedEventManager } from "#app/global-event-manager"; import { timedEventManager } from "#app/global-event-manager";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
/** /**
* Animates exclamation sprite over trainer's head at start of encounter * Animates exclamation sprite over trainer's head at start of encounter

View File

@ -31,21 +31,17 @@ import {
PreserveBerryModifier, PreserveBerryModifier,
TempExtraModifierModifier, TempExtraModifierModifier,
} from "./modifier"; } from "./modifier";
import { import type {
type FormChangeItemModifierType, FormChangeItemModifierType,
type ModifierOverride, PokemonExpBoosterModifierType,
ModifierTypeGenerator, PokemonFriendshipBoosterModifierType,
modifierTypes, PokemonMoveAccuracyBoosterModifierType,
type PokemonExpBoosterModifierType, PokemonMultiHitModifierType,
type PokemonFriendshipBoosterModifierType, ModifierType,
PokemonHeldItemModifierType, PokemonBaseStatTotalModifierType,
type PokemonMoveAccuracyBoosterModifierType,
type PokemonMultiHitModifierType,
type ModifierType,
type PokemonBaseStatTotalModifierType,
} from "./modifier-type"; } from "./modifier-type";
import { getOrInferTier, ModifierPoolType } from "./modifier-pool"; import { getOrInferTier } from "./modifier-pool";
import Overrides from "#app/overrides"; import { ModifierPoolType } from "./modifier-pool-type";
export abstract class PokemonHeldItemModifier extends PersistentModifier { export abstract class PokemonHeldItemModifier extends PersistentModifier {
/** The ID of the {@linkcode Pokemon} that this item belongs to. */ /** The ID of the {@linkcode Pokemon} that this item belongs to. */
@ -984,7 +980,7 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier {
doBypassSpeed.value = true; doBypassSpeed.value = true;
const isCommandFight = const isCommandFight =
globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT; globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT;
const hasQuickClaw = this.type instanceof PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW"; const hasQuickClaw = this.type.id === "QUICK_CLAW";
if (isCommandFight && hasQuickClaw) { if (isCommandFight && hasQuickClaw) {
globalScene.queueMessage( globalScene.queueMessage(
@ -1908,46 +1904,3 @@ export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModif
return 5; return 5;
} }
} }
/**
* Uses either `HELD_ITEMS_OVERRIDE` in overrides.ts to set {@linkcode PokemonHeldItemModifier}s for either:
* - The first member of the player's team when starting a new game
* - An enemy {@linkcode Pokemon} being spawned in
* @param pokemon {@linkcode Pokemon} whose held items are being overridden
* @param isPlayer {@linkcode boolean} for whether the {@linkcode pokemon} is the player's (`true`) or an enemy (`false`)
*/
export function overrideHeldItems(pokemon: Pokemon, isPlayer = true): void {
const heldItemsOverride: ModifierOverride[] = isPlayer
? Overrides.STARTING_HELD_ITEMS_OVERRIDE
: Overrides.OPP_HELD_ITEMS_OVERRIDE;
if (!heldItemsOverride || heldItemsOverride.length === 0 || !globalScene) {
return;
}
if (!isPlayer) {
globalScene.clearEnemyHeldItemModifiers(pokemon);
}
for (const item of heldItemsOverride) {
const modifierFunc = modifierTypes[item.name];
let modifierType: ModifierType | null = modifierFunc();
const qty = item.count || 1;
if (modifierType instanceof ModifierTypeGenerator) {
const pregenArgs = "type" in item && item.type !== null ? [item.type] : undefined;
modifierType = modifierType.generateType([], pregenArgs);
}
const heldItemModifier =
modifierType && (modifierType.withIdFromFunc(modifierFunc).newModifier(pokemon) as PokemonHeldItemModifier);
if (heldItemModifier) {
heldItemModifier.pokemonId = pokemon.id;
heldItemModifier.stackCount = qty;
if (isPlayer) {
globalScene.addModifier(heldItemModifier, true, false, false, true);
} else {
globalScene.addEnemyModifier(heldItemModifier, true, true);
}
}
}
}

View File

@ -0,0 +1,7 @@
export enum ModifierPoolType {
PLAYER,
WILD,
TRAINER,
ENEMY_BUFF,
DAILY_STARTER,
}

View File

@ -11,7 +11,7 @@ import { Moves } from "#enums/moves";
import { PokeballType } from "#enums/pokeball"; import { PokeballType } from "#enums/pokeball";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import type { EnemyPersistentModifier, PersistentModifier } from "./modifier"; import { DoubleBattleChanceBoosterModifier, type EnemyPersistentModifier, type PersistentModifier } from "./modifier";
import { import {
BerryModifier, BerryModifier,
type PokemonHeldItemModifier, type PokemonHeldItemModifier,
@ -22,7 +22,6 @@ import { ModifierTier } from "./modifier-tier";
import { import {
FormChangeItemModifierType, FormChangeItemModifierType,
getModifierType, getModifierType,
lureWeightFunc,
type ModifierOverride, type ModifierOverride,
type ModifierType, type ModifierType,
type ModifierTypeFunc, type ModifierTypeFunc,
@ -31,28 +30,84 @@ import {
ModifierTypeOption, ModifierTypeOption,
modifierTypes, modifierTypes,
PokemonHeldItemModifierType, PokemonHeldItemModifierType,
skipInClassicAfterWave,
skipInLastClassicWaveOrDefault,
WeightedModifierType,
} from "./modifier-type"; } from "./modifier-type";
import { getPartyLuckValue, hasMaximumBalls } from "./modifier-utils"; import { getPartyLuckValue, hasMaximumBalls } from "./modifier-utils";
import Overrides from "#app/overrides"; import Overrides from "#app/overrides";
import { ModifierPoolType } from "./modifier-pool-type";
const outputModifierData = false; const outputModifierData = false;
const useMaxWeightForOutput = false; const useMaxWeightForOutput = false;
export enum ModifierPoolType {
PLAYER,
WILD,
TRAINER,
ENEMY_BUFF,
DAILY_STARTER,
}
interface ModifierPool { interface ModifierPool {
[tier: string]: WeightedModifierType[]; [tier: string]: WeightedModifierType[];
} }
export class WeightedModifierType {
public modifierType: ModifierType;
public weight: number | WeightedModifierTypeWeightFunc;
public maxWeight: number | WeightedModifierTypeWeightFunc;
constructor(
modifierTypeFunc: ModifierTypeFunc,
weight: number | WeightedModifierTypeWeightFunc,
maxWeight?: number | WeightedModifierTypeWeightFunc,
) {
this.modifierType = modifierTypeFunc();
this.modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc)!; // TODO: is this bang correct?
this.weight = weight;
this.maxWeight = maxWeight || (!(weight instanceof Function) ? weight : 0);
}
setTier(tier: ModifierTier) {
this.modifierType.setTier(tier);
}
}
type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: number) => number;
/**
* High order function that returns a WeightedModifierTypeWeightFunc that will only be applied on
* classic and skip an ModifierType if current wave is greater or equal to the one passed down
* @param wave - Wave where we should stop showing the modifier
* @param defaultWeight - ModifierType default weight
* @returns A WeightedModifierTypeWeightFunc
*/
export function skipInClassicAfterWave(wave: number, defaultWeight: number): WeightedModifierTypeWeightFunc {
return () => {
const gameMode = globalScene.gameMode;
const currentWave = globalScene.currentBattle.waveIndex;
return gameMode.isClassic && currentWave >= wave ? 0 : defaultWeight;
};
}
/**
* High order function that returns a WeightedModifierTypeWeightFunc that will only be applied on
* classic and it will skip a ModifierType if it is the last wave pull.
* @param defaultWeight ModifierType default weight
* @returns A WeightedModifierTypeWeightFunc
*/
export function skipInLastClassicWaveOrDefault(defaultWeight: number): WeightedModifierTypeWeightFunc {
return skipInClassicAfterWave(199, defaultWeight);
}
/**
* High order function that returns a WeightedModifierTypeWeightFunc to ensure Lures don't spawn on Classic 199
* or if the lure still has over 60% of its duration left
* @param maxBattles The max battles the lure type in question lasts. 10 for green, 15 for Super, 30 for Max
* @param weight The desired weight for the lure when it does spawn
* @returns A WeightedModifierTypeWeightFunc
*/
export function lureWeightFunc(maxBattles: number, weight: number): WeightedModifierTypeWeightFunc {
return () => {
const lures = globalScene.getModifiers(DoubleBattleChanceBoosterModifier);
return !(globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex === 199) &&
(lures.length === 0 ||
lures.filter(m => m.getMaxBattles() === maxBattles && m.getBattleCount() >= maxBattles * 0.6).length === 0)
? weight
: 0;
};
}
const modifierPool: ModifierPool = { const modifierPool: ModifierPool = {
[ModifierTier.COMMON]: [ [ModifierTier.COMMON]: [
new WeightedModifierType(modifierTypes.POKEBALL, () => (hasMaximumBalls(PokeballType.POKEBALL) ? 0 : 6), 6), new WeightedModifierType(modifierTypes.POKEBALL, () => (hasMaximumBalls(PokeballType.POKEBALL) ? 0 : 6), 6),

View File

@ -104,6 +104,7 @@ import { ModifierTier } from "#app/modifier/modifier-tier";
import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system/voucher"; import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system/voucher";
import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler"; import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler";
import PartyUiHandler from "#app/ui/party-ui-handler"; import PartyUiHandler from "#app/ui/party-ui-handler";
import Overrides from "#app/overrides";
import { formatMoney, getEnumKeys, getEnumValues, NumberHolder, padInt, randSeedInt } from "#app/utils/common"; import { formatMoney, getEnumKeys, getEnumValues, NumberHolder, padInt, randSeedInt } from "#app/utils/common";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
@ -1689,70 +1690,6 @@ export class EnemyEndureChanceModifierType extends ModifierType {
} }
export type ModifierTypeFunc = () => ModifierType; export type ModifierTypeFunc = () => ModifierType;
type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: number) => number;
/**
* High order function that returns a WeightedModifierTypeWeightFunc that will only be applied on
* classic and skip an ModifierType if current wave is greater or equal to the one passed down
* @param wave - Wave where we should stop showing the modifier
* @param defaultWeight - ModifierType default weight
* @returns A WeightedModifierTypeWeightFunc
*/
export function skipInClassicAfterWave(wave: number, defaultWeight: number): WeightedModifierTypeWeightFunc {
return () => {
const gameMode = globalScene.gameMode;
const currentWave = globalScene.currentBattle.waveIndex;
return gameMode.isClassic && currentWave >= wave ? 0 : defaultWeight;
};
}
/**
* High order function that returns a WeightedModifierTypeWeightFunc that will only be applied on
* classic and it will skip a ModifierType if it is the last wave pull.
* @param defaultWeight ModifierType default weight
* @returns A WeightedModifierTypeWeightFunc
*/
export function skipInLastClassicWaveOrDefault(defaultWeight: number): WeightedModifierTypeWeightFunc {
return skipInClassicAfterWave(199, defaultWeight);
}
/**
* High order function that returns a WeightedModifierTypeWeightFunc to ensure Lures don't spawn on Classic 199
* or if the lure still has over 60% of its duration left
* @param maxBattles The max battles the lure type in question lasts. 10 for green, 15 for Super, 30 for Max
* @param weight The desired weight for the lure when it does spawn
* @returns A WeightedModifierTypeWeightFunc
*/
export function lureWeightFunc(maxBattles: number, weight: number): WeightedModifierTypeWeightFunc {
return () => {
const lures = globalScene.getModifiers(DoubleBattleChanceBoosterModifier);
return !(globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex === 199) &&
(lures.length === 0 ||
lures.filter(m => m.getMaxBattles() === maxBattles && m.getBattleCount() >= maxBattles * 0.6).length === 0)
? weight
: 0;
};
}
export class WeightedModifierType {
public modifierType: ModifierType;
public weight: number | WeightedModifierTypeWeightFunc;
public maxWeight: number | WeightedModifierTypeWeightFunc;
constructor(
modifierTypeFunc: ModifierTypeFunc,
weight: number | WeightedModifierTypeWeightFunc,
maxWeight?: number | WeightedModifierTypeWeightFunc,
) {
this.modifierType = modifierTypeFunc();
this.modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc)!; // TODO: is this bang correct?
this.weight = weight;
this.maxWeight = maxWeight || (!(weight instanceof Function) ? weight : 0);
}
setTier(tier: ModifierTier) {
this.modifierType.setTier(tier);
}
}
type BaseModifierOverride = { type BaseModifierOverride = {
name: Exclude<ModifierTypeKeys, GeneratorModifierOverride["name"]>; name: Exclude<ModifierTypeKeys, GeneratorModifierOverride["name"]>;
@ -2338,3 +2275,46 @@ export class ModifierTypeOption {
export function getModifierTypeFuncById(id: string): ModifierTypeFunc { export function getModifierTypeFuncById(id: string): ModifierTypeFunc {
return modifierTypes[id]; return modifierTypes[id];
} }
/**
* Uses either `HELD_ITEMS_OVERRIDE` in overrides.ts to set {@linkcode PokemonHeldItemModifier}s for either:
* - The first member of the player's team when starting a new game
* - An enemy {@linkcode Pokemon} being spawned in
* @param pokemon {@linkcode Pokemon} whose held items are being overridden
* @param isPlayer {@linkcode boolean} for whether the {@linkcode pokemon} is the player's (`true`) or an enemy (`false`)
*/
export function overrideHeldItems(pokemon: Pokemon, isPlayer = true): void {
const heldItemsOverride: ModifierOverride[] = isPlayer
? Overrides.STARTING_HELD_ITEMS_OVERRIDE
: Overrides.OPP_HELD_ITEMS_OVERRIDE;
if (!heldItemsOverride || heldItemsOverride.length === 0 || !globalScene) {
return;
}
if (!isPlayer) {
globalScene.clearEnemyHeldItemModifiers(pokemon);
}
for (const item of heldItemsOverride) {
const modifierFunc = modifierTypes[item.name];
let modifierType: ModifierType | null = modifierFunc();
const qty = item.count || 1;
if (modifierType instanceof ModifierTypeGenerator) {
const pregenArgs = "type" in item && item.type !== null ? [item.type] : undefined;
modifierType = modifierType.generateType([], pregenArgs);
}
const heldItemModifier =
modifierType && (modifierType.withIdFromFunc(modifierFunc).newModifier(pokemon) as PokemonHeldItemModifier);
if (heldItemModifier) {
heldItemModifier.pokemonId = pokemon.id;
heldItemModifier.stackCount = qty;
if (isPlayer) {
globalScene.addModifier(heldItemModifier, true, false, false, true);
} else {
globalScene.addEnemyModifier(heldItemModifier, true, true);
}
}
}
}

View File

@ -1,12 +1,9 @@
import { ModifierTier } from "#app/modifier/modifier-tier"; import { ModifierTier } from "#app/modifier/modifier-tier";
import { import { regenerateModifierPoolThresholds, getEnemyBuffModifierForWave } from "#app/modifier/modifier-pool";
regenerateModifierPoolThresholds,
ModifierPoolType,
getEnemyBuffModifierForWave,
} from "#app/modifier/modifier-pool";
import { EnemyPersistentModifier } from "#app/modifier/modifier"; import { EnemyPersistentModifier } from "#app/modifier/modifier";
import { Phase } from "#app/phase"; import { Phase } from "#app/phase";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
export class AddEnemyBuffModifierPhase extends Phase { export class AddEnemyBuffModifierPhase extends Phase {
start() { start() {

View File

@ -20,7 +20,7 @@ import type Pokemon from "#app/field/pokemon";
import { FieldPosition } from "#app/field/pokemon"; import { FieldPosition } from "#app/field/pokemon";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { BoostBugSpawnModifier, IvScannerModifier } from "#app/modifier/modifier"; import { BoostBugSpawnModifier, IvScannerModifier } from "#app/modifier/modifier";
import { ModifierPoolType, regenerateModifierPoolThresholds } from "#app/modifier/modifier-pool"; import { regenerateModifierPoolThresholds } from "#app/modifier/modifier-pool";
import Overrides from "#app/overrides"; import Overrides from "#app/overrides";
import { BattlePhase } from "#app/phases/battle-phase"; import { BattlePhase } from "#app/phases/battle-phase";
import { CheckSwitchPhase } from "#app/phases/check-switch-phase"; import { CheckSwitchPhase } from "#app/phases/check-switch-phase";
@ -45,7 +45,9 @@ import { overrideModifiers } from "#app/modifier/modifier";
import i18next from "i18next"; import i18next from "i18next";
import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters"; import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
import { getNatureName } from "#app/data/nature"; import { getNatureName } from "#app/data/nature";
import { overrideHeldItems, TurnHeldItemTransferModifier } from "#app/modifier/held-item-modifier"; import { TurnHeldItemTransferModifier } from "#app/modifier/held-item-modifier";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
import { overrideHeldItems } from "#app/modifier/modifier-type";
export class EncounterPhase extends BattlePhase { export class EncounterPhase extends BattlePhase {
private loaded: boolean; private loaded: boolean;

View File

@ -13,7 +13,6 @@ import {
import { import {
regenerateModifierPoolThresholds, regenerateModifierPoolThresholds,
getPlayerShopModifierTypeOptionsForWave, getPlayerShopModifierTypeOptionsForWave,
ModifierPoolType,
getPlayerModifierTypeOptions, getPlayerModifierTypeOptions,
type CustomModifierSettings, type CustomModifierSettings,
} from "#app/modifier/modifier-pool"; } from "#app/modifier/modifier-pool";
@ -28,6 +27,7 @@ import { BattlePhase } from "./battle-phase";
import Overrides from "#app/overrides"; import Overrides from "#app/overrides";
import { isNullOrUndefined, NumberHolder } from "#app/utils/common"; import { isNullOrUndefined, NumberHolder } from "#app/utils/common";
import { PokemonHeldItemModifier } from "#app/modifier/held-item-modifier"; import { PokemonHeldItemModifier } from "#app/modifier/held-item-modifier";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
export class SelectModifierPhase extends BattlePhase { export class SelectModifierPhase extends BattlePhase {
private rerollCount: number; private rerollCount: number;

View File

@ -13,7 +13,7 @@ import { UiMode } from "#enums/ui-mode";
import type { Species } from "#enums/species"; import type { Species } from "#enums/species";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { isNullOrUndefined } from "#app/utils/common"; import { isNullOrUndefined } from "#app/utils/common";
import { overrideHeldItems } from "#app/modifier/held-item-modifier"; import { overrideHeldItems } from "#app/modifier/modifier-type";
export class SelectStarterPhase extends Phase { export class SelectStarterPhase extends Phase {
start() { start() {

View File

@ -6,11 +6,7 @@ import { getBiomeKey } from "#app/field/arena";
import { GameMode, GameModes, getGameMode } from "#app/game-mode"; import { GameMode, GameModes, getGameMode } from "#app/game-mode";
import type { Modifier } from "#app/modifier/modifier"; import type { Modifier } from "#app/modifier/modifier";
import { modifierTypes } from "#app/modifier/modifier-type"; import { modifierTypes } from "#app/modifier/modifier-type";
import { import { getDailyRunStarterModifiers, regenerateModifierPoolThresholds } from "#app/modifier/modifier-pool";
getDailyRunStarterModifiers,
ModifierPoolType,
regenerateModifierPoolThresholds,
} from "#app/modifier/modifier-pool";
import { Phase } from "#app/phase"; import { Phase } from "#app/phase";
import type { SessionSaveData } from "#app/system/game-data"; import type { SessionSaveData } from "#app/system/game-data";
import { Unlockables } from "#app/system/unlockables"; import { Unlockables } from "#app/system/unlockables";
@ -27,6 +23,7 @@ import { SelectStarterPhase } from "./select-starter-phase";
import { SummonPhase } from "./summon-phase"; import { SummonPhase } from "./summon-phase";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import Overrides from "#app/overrides"; import Overrides from "#app/overrides";
import { ModifierPoolType } from "#app/modifier/modifier-pool-type";
export class TitlePhase extends Phase { export class TitlePhase extends Phase {
private loaded = false; private loaded = false;