diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 89fee2dbb8f..05ae9a63cbb 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -25,112 +25,23 @@ import { type TempBattleStat, Stat, TEMP_BATTLE_STATS } from "#enums/stat"; import { StatusEffect } from "#enums/status-effect"; import type { PokemonType } from "#enums/pokemon-type"; import i18next from "i18next"; -import { - type DoubleBattleChanceBoosterModifierType, - type EvolutionItemModifierType, - type ModifierOverride, - type ModifierType, - type TerastallizeModifierType, - type TmModifierType, - modifierTypes, +import type { + DoubleBattleChanceBoosterModifierType, + EvolutionItemModifierType, + ModifierOverride, + ModifierType, + TerastallizeModifierType, + TmModifierType, } from "./modifier-type"; import { FRIENDSHIP_GAIN_FROM_RARE_CANDY } from "#app/data/balance/starters"; import { globalScene } from "#app/global-scene"; import type { ModifierInstanceMap, ModifierString } from "#app/@types/modifier-types"; +import { assignItemsFromConfiguration } from "#app/items/held-item-pool"; +import type { HeldItemConfiguration } from "#app/items/held-item-data-types"; +import { modifierTypes } from "#app/data/data-lists"; export type ModifierPredicate = (modifier: Modifier) => boolean; -const iconOverflowIndex = 24; - -export const modifierSortFunc = (a: Modifier, b: Modifier): number => { - const itemNameMatch = a.type.name.localeCompare(b.type.name); - const typeNameMatch = a.constructor.name.localeCompare(b.constructor.name); - - //Then sort by item type - if (typeNameMatch === 0) { - return itemNameMatch; - //Finally sort by item name - } - return typeNameMatch; -}; - -export class ModifierBar extends Phaser.GameObjects.Container { - private player: boolean; - private modifierCache: PersistentModifier[]; - - constructor(enemy?: boolean) { - super(globalScene, 1 + (enemy ? 302 : 0), 2); - - this.player = !enemy; - this.setScale(0.5); - } - - /** - * Method to update content displayed in {@linkcode ModifierBar} - * @param {PersistentModifier[]} modifiers - The list of modifiers to be displayed in the {@linkcode ModifierBar} - * @param {boolean} hideHeldItems - If set to "true", only modifiers not assigned to a Pokémon are displayed - */ - updateModifiers(modifiers: PersistentModifier[], hideHeldItems = false) { - this.removeAll(true); - - const visibleIconModifiers = modifiers.filter(m => m.isIconVisible()); - const nonPokemonSpecificModifiers = visibleIconModifiers - .filter(m => !(m as PokemonHeldItemModifier).pokemonId) - .sort(modifierSortFunc); - const pokemonSpecificModifiers = visibleIconModifiers - .filter(m => (m as PokemonHeldItemModifier).pokemonId) - .sort(modifierSortFunc); - - const sortedVisibleIconModifiers = hideHeldItems - ? nonPokemonSpecificModifiers - : nonPokemonSpecificModifiers.concat(pokemonSpecificModifiers); - - sortedVisibleIconModifiers.forEach((modifier: PersistentModifier, i: number) => { - const icon = modifier.getIcon(); - if (i >= iconOverflowIndex) { - icon.setVisible(false); - } - this.add(icon); - this.setModifierIconPosition(icon, sortedVisibleIconModifiers.length); - icon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 32, 24), Phaser.Geom.Rectangle.Contains); - icon.on("pointerover", () => { - globalScene.ui.showTooltip(modifier.type.name, modifier.type.getDescription()); - if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) { - this.updateModifierOverflowVisibility(true); - } - }); - icon.on("pointerout", () => { - globalScene.ui.hideTooltip(); - if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) { - this.updateModifierOverflowVisibility(false); - } - }); - }); - - for (const icon of this.getAll()) { - this.sendToBack(icon); - } - - this.modifierCache = modifiers; - } - - updateModifierOverflowVisibility(ignoreLimit: boolean) { - const modifierIcons = this.getAll().reverse(); - for (const modifier of modifierIcons.map(m => m as Phaser.GameObjects.Container).slice(iconOverflowIndex)) { - modifier.setVisible(ignoreLimit); - } - } - - setModifierIconPosition(icon: Phaser.GameObjects.Container, modifierCount: number) { - const rowIcons: number = 12 + 6 * Math.max(Math.ceil(Math.min(modifierCount, 24) / 12) - 2, 0); - - const x = ((this.getIndex(icon) % rowIcons) * 26) / (rowIcons / 12); - const y = Math.floor(this.getIndex(icon) / rowIcons) * 20; - - icon.setPosition(this.player ? x : -x, y); - } -} - export abstract class Modifier { public type: ModifierType; @@ -1900,7 +1811,7 @@ export function overrideModifiers(isPlayer = true): void { const modifierFunc = modifierTypes[item.name]; let modifierType: ModifierType | null = modifierFunc(); - if (modifierType.is("ModifierTypeGenerator")) { + if (modifierType?.is("ModifierTypeGenerator")) { const pregenArgs = "type" in item && item.type !== null ? [item.type] : undefined; modifierType = modifierType.generateType([], pregenArgs); } @@ -1912,7 +1823,7 @@ export function overrideModifiers(isPlayer = true): void { if (isPlayer) { globalScene.addModifier(modifier, true, false, false, true); } else { - globalScene.addEnemyModifier(modifier, true, true); + globalScene.addEnemyModifier(modifier, true); } } } @@ -1926,7 +1837,7 @@ export function overrideModifiers(isPlayer = true): void { * @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 + const heldItemsOverride: HeldItemConfiguration = isPlayer ? Overrides.STARTING_HELD_ITEMS_OVERRIDE : Overrides.OPP_HELD_ITEMS_OVERRIDE; if (!heldItemsOverride || heldItemsOverride.length === 0 || !globalScene) { @@ -1934,31 +1845,10 @@ export function overrideHeldItems(pokemon: Pokemon, isPlayer = true): void { } if (!isPlayer) { - globalScene.clearEnemyHeldItemModifiers(pokemon); + pokemon.heldItemManager.clearItems(); } - for (const item of heldItemsOverride) { - const modifierFunc = modifierTypes[item.name]; - let modifierType: ModifierType | null = modifierFunc(); - const qty = item.count || 1; - - if (modifierType.is("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); - } - } - } + assignItemsFromConfiguration(heldItemsOverride, pokemon); } /** @@ -1981,30 +1871,8 @@ const ModifierClassMap = Object.freeze({ MegaEvolutionAccessModifier, GigantamaxAccessModifier, TerastallizeAccessModifier, - PokemonHeldItemModifier, - LapsingPokemonHeldItemModifier, - BaseStatModifier, - EvoTrackerModifier, - PokemonBaseStatTotalModifier, - PokemonBaseStatFlatModifier, - PokemonIncrementingStatModifier, - StatBoosterModifier, - SpeciesStatBoosterModifier, - CritBoosterModifier, - SpeciesCritBoosterModifier, - AttackTypeBoosterModifier, - SurviveDamageModifier, - BypassSpeedChanceModifier, - FlinchChanceModifier, - TurnHealModifier, - TurnStatusEffectModifier, - HitHealModifier, LevelIncrementBoosterModifier, - BerryModifier, PreserveBerryModifier, - PokemonInstantReviveModifier, - ResetNegativeStatStageModifier, - FieldEffectModifier, ConsumablePokemonModifier, TerrastalizeModifier, PokemonHpRestoreModifier, @@ -2022,16 +1890,8 @@ const ModifierClassMap = Object.freeze({ MultipleParticipantExpBonusModifier, HealingBoosterModifier, ExpBoosterModifier, - PokemonExpBoosterModifier, ExpShareModifier, ExpBalanceModifier, - PokemonFriendshipBoosterModifier, - PokemonNatureWeightModifier, - PokemonMoveAccuracyBoosterModifier, - PokemonMultiHitModifier, - PokemonFormChangeItemModifier, - MoneyRewardModifier, - DamageMoneyRewardModifier, MoneyInterestModifier, HiddenAbilityRateBoosterModifier, ShinyRateBoosterModifier, @@ -2039,10 +1899,6 @@ const ModifierClassMap = Object.freeze({ LockModifierTiersModifier, HealShopCostModifier, BoostBugSpawnModifier, - SwitchEffectTransferModifier, - HeldItemTransferModifier, - TurnHeldItemTransferModifier, - ContactHeldItemTransferChanceModifier, IvScannerModifier, ExtraModifierModifier, TempExtraModifierModifier, diff --git a/src/overrides.ts b/src/overrides.ts index b390b9fa70f..546935d1c45 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -22,6 +22,7 @@ import { TimeOfDay } from "#enums/time-of-day"; import { TrainerType } from "#enums/trainer-type"; import { VariantTier } from "#enums/variant-tier"; import { WeatherType } from "#enums/weather-type"; +import { HeldItemConfiguration } from "./items/held-item-data-types"; /** * This comment block exists to prevent IDEs from automatically removing unused imports @@ -255,9 +256,9 @@ class DefaultOverrides { readonly OPP_MODIFIER_OVERRIDE: ModifierOverride[] = []; /** Override array of {@linkcode ModifierOverride}s used to provide held items to first party member when starting a new game. */ - readonly STARTING_HELD_ITEMS_OVERRIDE: ModifierOverride[] = []; + readonly STARTING_HELD_ITEMS_OVERRIDE: HeldItemConfiguration = []; /** Override array of {@linkcode ModifierOverride}s used to provide held items to enemies on spawn. */ - readonly OPP_HELD_ITEMS_OVERRIDE: ModifierOverride[] = []; + readonly OPP_HELD_ITEMS_OVERRIDE: HeldItemConfiguration = []; /** * Override array of {@linkcode ModifierOverride}s used to replace the generated item rolls after a wave. diff --git a/src/phases/title-phase.ts b/src/phases/title-phase.ts index 72132635c1b..61b2cf05ecf 100644 --- a/src/phases/title-phase.ts +++ b/src/phases/title-phase.ts @@ -253,7 +253,7 @@ export class TitlePhase extends Phase { for (const m of modifiers) { globalScene.addModifier(m, true, false, false, true); } - globalScene.updateModifiers(true, true); + globalScene.updateModifiers(true); Promise.all(loadPokemonAssets).then(() => { globalScene.time.delayedCall(500, () => globalScene.playBgm());