From 76a3e612dd09570b5b9cd980ff8a673b62593a43 Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Sun, 8 Jun 2025 22:09:55 +0200 Subject: [PATCH] Tracking forms in held item manager --- src/battle-scene.ts | 12 ++----- src/data/pokemon-forms.ts | 17 ++++----- src/field/pokemon-held-item-manager.ts | 38 ++++++++++++++++++++ src/modifier/modifier-type.ts | 3 +- src/ui/party-ui-handler.ts | 49 ++++++++++++-------------- 5 files changed, 74 insertions(+), 45 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 68c59ae7f09..b73a4e30357 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -3167,17 +3167,11 @@ export default class BattleScene extends SceneBase { let matchingFormChange: SpeciesFormChange | null; if (pokemon.species.speciesId === SpeciesId.NECROZMA && matchingFormChangeOpts.length > 1) { // Ultra Necrozma is changing its form back, so we need to figure out into which form it devolves. - const formChangeItemModifiers = ( - this.findModifiers( - m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id, - ) as PokemonFormChangeItemModifier[] - ) - .filter(m => m.active) - .map(m => m.formChangeItem); + const formChangeItems = pokemon.heldItemManager.getActiveFormChangeItems(); - matchingFormChange = formChangeItemModifiers.includes(FormChangeItem.N_LUNARIZER) + matchingFormChange = formChangeItems.includes(FormChangeItem.N_LUNARIZER) ? matchingFormChangeOpts[0] - : formChangeItemModifiers.includes(FormChangeItem.N_SOLARIZER) + : formChangeItems.includes(FormChangeItem.N_SOLARIZER) ? matchingFormChangeOpts[1] : null; } else { diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index 47eb355c8b6..00c32207bcd 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -1,4 +1,3 @@ -import { PokemonFormChangeItemModifier } from "../modifier/modifier"; import type Pokemon from "../field/pokemon"; import { StatusEffect } from "#enums/status-effect"; import { allMoves } from "./data-lists"; @@ -135,6 +134,10 @@ export enum FormChangeItem { NORMAL_MEMORY, // TODO: Find a potential use for this } +export function formChangeItemName(id: FormChangeItem) { + return i18next.t(`modifierType:FormChangeItem.${FormChangeItem[id]}`); +} + export type SpeciesFormChangeConditionPredicate = (p: Pokemon) => boolean; export type SpeciesFormChangeConditionEnforceFunc = (p: Pokemon) => void; @@ -277,13 +280,11 @@ export class SpeciesFormChangeItemTrigger extends SpeciesFormChangeTrigger { } canChange(pokemon: Pokemon): boolean { - return !!globalScene.findModifier( - m => - m instanceof PokemonFormChangeItemModifier && - m.pokemonId === pokemon.id && - m.formChangeItem === this.item && - m.active === this.active, - ); + const matchItem = pokemon.heldItemManager.hasFormChangeItem(this.item); + if (!matchItem) { + return false; + } + return pokemon.heldItemManager.formChangeItems[this.item].active === this.active; } } diff --git a/src/field/pokemon-held-item-manager.ts b/src/field/pokemon-held-item-manager.ts index 9c6c02a92ee..24c8b1d67c5 100644 --- a/src/field/pokemon-held-item-manager.ts +++ b/src/field/pokemon-held-item-manager.ts @@ -1,5 +1,6 @@ import { allHeldItems } from "#app/items/all-held-items"; import type { HeldItemId } from "#app/enums/held-item-id"; +import type { FormChangeItem } from "#app/data/pokemon-forms"; interface HeldItemProperties { stack: number; @@ -11,8 +12,17 @@ type HeldItemPropertyMap = { [key in HeldItemId]: HeldItemProperties; }; +interface FormChangeItemProperties { + active: boolean; +} + +type FormChangeItemPropertyMap = { + [key in FormChangeItem]: FormChangeItemProperties; +}; + export class PokemonItemManager { public heldItems: HeldItemPropertyMap; + public formChangeItems: FormChangeItemPropertyMap; constructor() { this.heldItems = {}; @@ -53,4 +63,32 @@ export class PokemonItemManager { delete this.heldItems[itemType]; } } + + addFormChangeItem(id: FormChangeItem) { + if (!(id in this.formChangeItems)) { + this.formChangeItems[id] = { active: false }; + } + } + + hasFormChangeItem(id: FormChangeItem): boolean { + return id in this.formChangeItems; + } + + hasActiveFormChangeItem(id: FormChangeItem): boolean { + return id in this.formChangeItems && this.formChangeItems[id].active; + } + + getFormChangeItems(): FormChangeItem[] { + return Object.keys(this.formChangeItems).map(k => Number(k)); + } + + getActiveFormChangeItems(): FormChangeItem[] { + return this.getFormChangeItems().filter(m => this.formChangeItems[m].active); + } + + toggleActive(id: FormChangeItem) { + if (id in this.formChangeItems) { + this.formChangeItems[id].active = !this.formChangeItems[id].active; + } + } } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index f9a94c97c47..a09f633be14 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -8,6 +8,7 @@ import { getNatureName, getNatureStatMultiplier } from "#app/data/nature"; import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball"; import { FormChangeItem, + formChangeItemName, pokemonFormChanges, SpeciesFormChangeCondition, SpeciesFormChangeItemTrigger, @@ -1400,7 +1401,7 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G } get name(): string { - return i18next.t(`modifierType:FormChangeItem.${FormChangeItem[this.formChangeItem]}`); + return formChangeItemName(this.formChangeItem); } getDescription(): string { diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index c8654854b13..7bb8af0b0a4 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -6,7 +6,7 @@ import { Command } from "#app/ui/command-ui-handler"; import MessageUiHandler from "#app/ui/message-ui-handler"; import { UiMode } from "#enums/ui-mode"; import { BooleanHolder, toReadableString, randInt, getLocalizedSpriteKey } from "#app/utils/common"; -import { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier"; +import { PokemonHeldItemModifier } from "#app/modifier/modifier"; import { ForceSwitchOutAttr } from "#app/data/moves/move"; import { allMoves } from "#app/data/data-lists"; import { Gender, getGenderColor, getGenderSymbol } from "#app/data/gender"; @@ -14,7 +14,7 @@ import { StatusEffect } from "#enums/status-effect"; import PokemonIconAnimHandler, { PokemonIconAnimMode } from "#app/ui/pokemon-icon-anim-handler"; import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { addWindow } from "#app/ui/ui-theme"; -import { SpeciesFormChangeItemTrigger, FormChangeItem } from "#app/data/pokemon-forms"; +import { SpeciesFormChangeItemTrigger, FormChangeItem, formChangeItemName } from "#app/data/pokemon-forms"; import { getVariantTint } from "#app/sprites/variant"; import { Button } from "#enums/buttons"; import { applyChallenges, ChallengeType } from "#app/data/challenge"; @@ -750,9 +750,9 @@ export default class PartyUiHandler extends MessageUiHandler { globalScene.phaseManager.getCurrentPhase()?.is("SelectModifierPhase") && this.partyUiMode === PartyUiMode.CHECK ) { - const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); - const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM]; - modifier.active = !modifier.active; + const formChangeItems = this.getFormChangeItems(pokemon); + const item = formChangeItems[option - PartyOption.FORM_CHANGE_ITEM]; + pokemon.heldItemManager.toggleActive(item); globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger, false, true); } @@ -1332,8 +1332,8 @@ export default class PartyUiHandler extends MessageUiHandler { break; case PartyUiMode.CHECK: if (globalScene.phaseManager.getCurrentPhase()?.is("SelectModifierPhase")) { - const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); - for (let i = 0; i < formChangeItemModifiers.length; i++) { + const formChangeItems = this.getFormChangeItems(pokemon); + for (let i = 0; i < formChangeItems.length; i++) { this.options.push(PartyOption.FORM_CHANGE_ITEM + i); } } @@ -1393,10 +1393,10 @@ export default class PartyUiHandler extends MessageUiHandler { } break; default: - const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); - if (formChangeItemModifiers && option >= PartyOption.FORM_CHANGE_ITEM) { - const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM]; - optionName = `${modifier.active ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${modifier.type.name}`; + const formChangeItems = this.getFormChangeItems(pokemon); + if (formChangeItems && option >= PartyOption.FORM_CHANGE_ITEM) { + const item = formChangeItems[option - PartyOption.FORM_CHANGE_ITEM]; + optionName = `${pokemon.heldItemManager.hasActiveFormChangeItem(item) ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${formChangeItemName(item)}`; } else if (option === PartyOption.UNPAUSE_EVOLUTION) { optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`; } else { @@ -1555,29 +1555,24 @@ export default class PartyUiHandler extends MessageUiHandler { }); } - getFormChangeItemsModifiers(pokemon: Pokemon) { - let formChangeItemModifiers = globalScene.findModifiers( - m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id, - ) as PokemonFormChangeItemModifier[]; - const ultraNecrozmaModifiers = formChangeItemModifiers.filter( - m => m.active && m.formChangeItem === FormChangeItem.ULTRANECROZIUM_Z, - ); - if (ultraNecrozmaModifiers.length > 0) { + getFormChangeItems(pokemon: Pokemon) { + let formChangeItems = pokemon.heldItemManager.getFormChangeItems(); + const hasActiveFormChangeItems = pokemon.heldItemManager.getFormChangeItems().length; + const ultraNecrozmaActive = pokemon.heldItemManager.hasActiveFormChangeItem(FormChangeItem.ULTRANECROZIUM_Z); + if (ultraNecrozmaActive) { // ULTRANECROZIUM_Z is active and deactivating it should be the only option - return ultraNecrozmaModifiers; + return [FormChangeItem.ULTRANECROZIUM_Z]; } - if (formChangeItemModifiers.find(m => m.active)) { + if (hasActiveFormChangeItems) { // a form is currently active. the user has to disable the form or activate ULTRANECROZIUM_Z - formChangeItemModifiers = formChangeItemModifiers.filter( - m => m.active || m.formChangeItem === FormChangeItem.ULTRANECROZIUM_Z, + formChangeItems = formChangeItems.filter( + m => pokemon.heldItemManager.hasActiveFormChangeItem(m) || m === FormChangeItem.ULTRANECROZIUM_Z, ); } else if (pokemon.species.speciesId === SpeciesId.NECROZMA) { // no form is currently active. the user has to activate some form, except ULTRANECROZIUM_Z - formChangeItemModifiers = formChangeItemModifiers.filter( - m => m.formChangeItem !== FormChangeItem.ULTRANECROZIUM_Z, - ); + formChangeItems = formChangeItems.filter(m => m !== FormChangeItem.ULTRANECROZIUM_Z); } - return formChangeItemModifiers; + return formChangeItems; } getOptionsCursorWithScroll(): number {