Tracking forms in held item manager

This commit is contained in:
Wlowscha 2025-06-08 22:09:55 +02:00
parent 12117bb2ac
commit 76a3e612dd
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
5 changed files with 74 additions and 45 deletions

View File

@ -3167,17 +3167,11 @@ export default class BattleScene extends SceneBase {
let matchingFormChange: SpeciesFormChange | null; let matchingFormChange: SpeciesFormChange | null;
if (pokemon.species.speciesId === SpeciesId.NECROZMA && matchingFormChangeOpts.length > 1) { 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. // Ultra Necrozma is changing its form back, so we need to figure out into which form it devolves.
const formChangeItemModifiers = ( const formChangeItems = pokemon.heldItemManager.getActiveFormChangeItems();
this.findModifiers(
m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id,
) as PokemonFormChangeItemModifier[]
)
.filter(m => m.active)
.map(m => m.formChangeItem);
matchingFormChange = formChangeItemModifiers.includes(FormChangeItem.N_LUNARIZER) matchingFormChange = formChangeItems.includes(FormChangeItem.N_LUNARIZER)
? matchingFormChangeOpts[0] ? matchingFormChangeOpts[0]
: formChangeItemModifiers.includes(FormChangeItem.N_SOLARIZER) : formChangeItems.includes(FormChangeItem.N_SOLARIZER)
? matchingFormChangeOpts[1] ? matchingFormChangeOpts[1]
: null; : null;
} else { } else {

View File

@ -1,4 +1,3 @@
import { PokemonFormChangeItemModifier } from "../modifier/modifier";
import type Pokemon from "../field/pokemon"; import type Pokemon from "../field/pokemon";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import { allMoves } from "./data-lists"; import { allMoves } from "./data-lists";
@ -135,6 +134,10 @@ export enum FormChangeItem {
NORMAL_MEMORY, // TODO: Find a potential use for this 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 SpeciesFormChangeConditionPredicate = (p: Pokemon) => boolean;
export type SpeciesFormChangeConditionEnforceFunc = (p: Pokemon) => void; export type SpeciesFormChangeConditionEnforceFunc = (p: Pokemon) => void;
@ -277,13 +280,11 @@ export class SpeciesFormChangeItemTrigger extends SpeciesFormChangeTrigger {
} }
canChange(pokemon: Pokemon): boolean { canChange(pokemon: Pokemon): boolean {
return !!globalScene.findModifier( const matchItem = pokemon.heldItemManager.hasFormChangeItem(this.item);
m => if (!matchItem) {
m instanceof PokemonFormChangeItemModifier && return false;
m.pokemonId === pokemon.id && }
m.formChangeItem === this.item && return pokemon.heldItemManager.formChangeItems[this.item].active === this.active;
m.active === this.active,
);
} }
} }

View File

@ -1,5 +1,6 @@
import { allHeldItems } from "#app/items/all-held-items"; import { allHeldItems } from "#app/items/all-held-items";
import type { HeldItemId } from "#app/enums/held-item-id"; import type { HeldItemId } from "#app/enums/held-item-id";
import type { FormChangeItem } from "#app/data/pokemon-forms";
interface HeldItemProperties { interface HeldItemProperties {
stack: number; stack: number;
@ -11,8 +12,17 @@ type HeldItemPropertyMap = {
[key in HeldItemId]: HeldItemProperties; [key in HeldItemId]: HeldItemProperties;
}; };
interface FormChangeItemProperties {
active: boolean;
}
type FormChangeItemPropertyMap = {
[key in FormChangeItem]: FormChangeItemProperties;
};
export class PokemonItemManager { export class PokemonItemManager {
public heldItems: HeldItemPropertyMap; public heldItems: HeldItemPropertyMap;
public formChangeItems: FormChangeItemPropertyMap;
constructor() { constructor() {
this.heldItems = {}; this.heldItems = {};
@ -53,4 +63,32 @@ export class PokemonItemManager {
delete this.heldItems[itemType]; 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;
}
}
} }

View File

@ -8,6 +8,7 @@ import { getNatureName, getNatureStatMultiplier } from "#app/data/nature";
import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball"; import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball";
import { import {
FormChangeItem, FormChangeItem,
formChangeItemName,
pokemonFormChanges, pokemonFormChanges,
SpeciesFormChangeCondition, SpeciesFormChangeCondition,
SpeciesFormChangeItemTrigger, SpeciesFormChangeItemTrigger,
@ -1400,7 +1401,7 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G
} }
get name(): string { get name(): string {
return i18next.t(`modifierType:FormChangeItem.${FormChangeItem[this.formChangeItem]}`); return formChangeItemName(this.formChangeItem);
} }
getDescription(): string { getDescription(): string {

View File

@ -6,7 +6,7 @@ import { Command } from "#app/ui/command-ui-handler";
import MessageUiHandler from "#app/ui/message-ui-handler"; import MessageUiHandler from "#app/ui/message-ui-handler";
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { BooleanHolder, toReadableString, randInt, getLocalizedSpriteKey } from "#app/utils/common"; 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 { ForceSwitchOutAttr } from "#app/data/moves/move";
import { allMoves } from "#app/data/data-lists"; import { allMoves } from "#app/data/data-lists";
import { Gender, getGenderColor, getGenderSymbol } from "#app/data/gender"; 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 PokemonIconAnimHandler, { PokemonIconAnimMode } from "#app/ui/pokemon-icon-anim-handler";
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import { addWindow } from "#app/ui/ui-theme"; 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 { getVariantTint } from "#app/sprites/variant";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import { applyChallenges, ChallengeType } from "#app/data/challenge"; import { applyChallenges, ChallengeType } from "#app/data/challenge";
@ -750,9 +750,9 @@ export default class PartyUiHandler extends MessageUiHandler {
globalScene.phaseManager.getCurrentPhase()?.is("SelectModifierPhase") && globalScene.phaseManager.getCurrentPhase()?.is("SelectModifierPhase") &&
this.partyUiMode === PartyUiMode.CHECK this.partyUiMode === PartyUiMode.CHECK
) { ) {
const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); const formChangeItems = this.getFormChangeItems(pokemon);
const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM]; const item = formChangeItems[option - PartyOption.FORM_CHANGE_ITEM];
modifier.active = !modifier.active; pokemon.heldItemManager.toggleActive(item);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger, false, true); globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger, false, true);
} }
@ -1332,8 +1332,8 @@ export default class PartyUiHandler extends MessageUiHandler {
break; break;
case PartyUiMode.CHECK: case PartyUiMode.CHECK:
if (globalScene.phaseManager.getCurrentPhase()?.is("SelectModifierPhase")) { if (globalScene.phaseManager.getCurrentPhase()?.is("SelectModifierPhase")) {
const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); const formChangeItems = this.getFormChangeItems(pokemon);
for (let i = 0; i < formChangeItemModifiers.length; i++) { for (let i = 0; i < formChangeItems.length; i++) {
this.options.push(PartyOption.FORM_CHANGE_ITEM + i); this.options.push(PartyOption.FORM_CHANGE_ITEM + i);
} }
} }
@ -1393,10 +1393,10 @@ export default class PartyUiHandler extends MessageUiHandler {
} }
break; break;
default: default:
const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); const formChangeItems = this.getFormChangeItems(pokemon);
if (formChangeItemModifiers && option >= PartyOption.FORM_CHANGE_ITEM) { if (formChangeItems && option >= PartyOption.FORM_CHANGE_ITEM) {
const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM]; const item = formChangeItems[option - PartyOption.FORM_CHANGE_ITEM];
optionName = `${modifier.active ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${modifier.type.name}`; optionName = `${pokemon.heldItemManager.hasActiveFormChangeItem(item) ? i18next.t("partyUiHandler:DEACTIVATE") : i18next.t("partyUiHandler:ACTIVATE")} ${formChangeItemName(item)}`;
} else if (option === PartyOption.UNPAUSE_EVOLUTION) { } else if (option === PartyOption.UNPAUSE_EVOLUTION) {
optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`; optionName = `${pokemon.pauseEvolutions ? i18next.t("partyUiHandler:UNPAUSE_EVOLUTION") : i18next.t("partyUiHandler:PAUSE_EVOLUTION")}`;
} else { } else {
@ -1555,29 +1555,24 @@ export default class PartyUiHandler extends MessageUiHandler {
}); });
} }
getFormChangeItemsModifiers(pokemon: Pokemon) { getFormChangeItems(pokemon: Pokemon) {
let formChangeItemModifiers = globalScene.findModifiers( let formChangeItems = pokemon.heldItemManager.getFormChangeItems();
m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id, const hasActiveFormChangeItems = pokemon.heldItemManager.getFormChangeItems().length;
) as PokemonFormChangeItemModifier[]; const ultraNecrozmaActive = pokemon.heldItemManager.hasActiveFormChangeItem(FormChangeItem.ULTRANECROZIUM_Z);
const ultraNecrozmaModifiers = formChangeItemModifiers.filter( if (ultraNecrozmaActive) {
m => m.active && m.formChangeItem === FormChangeItem.ULTRANECROZIUM_Z,
);
if (ultraNecrozmaModifiers.length > 0) {
// ULTRANECROZIUM_Z is active and deactivating it should be the only option // 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 // a form is currently active. the user has to disable the form or activate ULTRANECROZIUM_Z
formChangeItemModifiers = formChangeItemModifiers.filter( formChangeItems = formChangeItems.filter(
m => m.active || m.formChangeItem === FormChangeItem.ULTRANECROZIUM_Z, m => pokemon.heldItemManager.hasActiveFormChangeItem(m) || m === FormChangeItem.ULTRANECROZIUM_Z,
); );
} else if (pokemon.species.speciesId === SpeciesId.NECROZMA) { } else if (pokemon.species.speciesId === SpeciesId.NECROZMA) {
// no form is currently active. the user has to activate some form, except ULTRANECROZIUM_Z // no form is currently active. the user has to activate some form, except ULTRANECROZIUM_Z
formChangeItemModifiers = formChangeItemModifiers.filter( formChangeItems = formChangeItems.filter(m => m !== FormChangeItem.ULTRANECROZIUM_Z);
m => m.formChangeItem !== FormChangeItem.ULTRANECROZIUM_Z,
);
} }
return formChangeItemModifiers; return formChangeItems;
} }
getOptionsCursorWithScroll(): number { getOptionsCursorWithScroll(): number {