Held item overrides now use the new system

This commit is contained in:
Wlowscha 2025-06-17 23:37:53 +02:00
parent 7523f6d9c0
commit c58c1fd21b
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
3 changed files with 19 additions and 162 deletions

View File

@ -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,

View File

@ -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.

View File

@ -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());