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;
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 {

View File

@ -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;
}
}

View File

@ -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;
}
}
}

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 {
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 {

View File

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