More various fixes; introduced isMaxStack(item) method to heldItemManager

This commit is contained in:
Wlowscha 2025-06-10 23:29:29 +02:00
parent c198297abd
commit 64b1cf1669
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
4 changed files with 42 additions and 75 deletions

View File

@ -67,7 +67,6 @@ import {
} from "../abilities/ability"; } from "../abilities/ability";
import { allAbilities, allMoves } from "../data-lists"; import { allAbilities, allMoves } from "../data-lists";
import { import {
PokemonHeldItemModifier,
PreserveBerryModifier, PreserveBerryModifier,
} from "../../modifier/modifier"; } from "../../modifier/modifier";
import type { BattlerIndex } from "#enums/battler-index"; import type { BattlerIndex } from "#enums/battler-index";
@ -118,7 +117,6 @@ import { MoveFlags } from "#enums/MoveFlags";
import { MoveEffectTrigger } from "#enums/MoveEffectTrigger"; import { MoveEffectTrigger } from "#enums/MoveEffectTrigger";
import { MultiHitType } from "#enums/MultiHitType"; import { MultiHitType } from "#enums/MultiHitType";
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves"; import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves";
import { TrainerVariant } from "#app/field/trainer";
import { SelectBiomePhase } from "#app/phases/select-biome-phase"; import { SelectBiomePhase } from "#app/phases/select-biome-phase";
import { allHeldItems, applyHeldItems } from "#app/items/all-held-items"; import { allHeldItems, applyHeldItems } from "#app/items/all-held-items";
import { ITEM_EFFECT } from "#app/items/held-item"; import { ITEM_EFFECT } from "#app/items/held-item";
@ -2736,18 +2734,13 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
return true; return true;
} }
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
return globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier[];
}
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
const heldItems = this.getTargetHeldItems(target); const heldItems = target.getHeldItems();
return heldItems.length ? 5 : 0; return heldItems.length ? 5 : 0;
} }
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
const heldItems = this.getTargetHeldItems(target); const heldItems = target.getHeldItems();
return heldItems.length ? -5 : 0; return heldItems.length ? -5 : 0;
} }
} }

View File

@ -73,6 +73,11 @@ export class PokemonItemManager {
return item ? item.stack : 0; return item ? item.stack : 0;
} }
isMaxStack(itemType: HeldItemId): boolean {
const item = this.heldItems[itemType];
return item ? item.stack >= allHeldItems[itemType].getMaxStackCount() : false;
}
overrideItems(newItems: HeldItemPropertyMap) { overrideItems(newItems: HeldItemPropertyMap) {
this.heldItems = newItems; this.heldItems = newItems;
} }

View File

@ -60,7 +60,6 @@ import {
EnemyDamageReducerModifier, EnemyDamageReducerModifier,
EnemyFusionChanceModifier, EnemyFusionChanceModifier,
HiddenAbilityRateBoosterModifier, HiddenAbilityRateBoosterModifier,
PokemonHeldItemModifier,
ShinyRateBoosterModifier, ShinyRateBoosterModifier,
TempStatStageBoosterModifier, TempStatStageBoosterModifier,
TempCritBoosterModifier, TempCritBoosterModifier,
@ -5823,14 +5822,10 @@ export class PlayerPokemon extends Pokemon {
globalScene.getPlayerParty().push(newPokemon); globalScene.getPlayerParty().push(newPokemon);
newPokemon.evolve(!isFusion ? newEvolution : new FusionSpeciesFormEvolution(this.id, newEvolution), evoSpecies); newPokemon.evolve(!isFusion ? newEvolution : new FusionSpeciesFormEvolution(this.id, newEvolution), evoSpecies);
const modifiers = globalScene.findModifiers( //TODO: This currently does not consider any values associated with the items e.g. disabled
m => m instanceof PokemonHeldItemModifier && m.pokemonId === this.id, const heldItems = this.getHeldItems();
true, heldItems.forEach(item => {
) as PokemonHeldItemModifier[]; newPokemon.heldItemManager.add(item, this.heldItemManager.getStack(item));
modifiers.forEach(m => {
const clonedModifier = m.clone() as PokemonHeldItemModifier;
clonedModifier.pokemonId = newPokemon.id;
globalScene.addModifier(clonedModifier, true);
}); });
globalScene.updateModifiers(true); globalScene.updateModifiers(true);
} }

View File

@ -7,7 +7,6 @@ import { Command } from "#enums/command";
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 { PokemonHeldItemModifier } from "#app/modifier/modifier";
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";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
@ -30,6 +29,7 @@ import type { CommandPhase } from "#app/phases/command-phase";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { HeldItemId } from "#enums/held-item-id"; import { HeldItemId } from "#enums/held-item-id";
import { formChangeItemName } from "#app/data/pokemon-forms"; import { formChangeItemName } from "#app/data/pokemon-forms";
import { allHeldItems } from "#app/items/all-held-items";
const defaultMessage = i18next.t("partyUiHandler:choosePokemon"); const defaultMessage = i18next.t("partyUiHandler:choosePokemon");
@ -140,10 +140,7 @@ export type PartyModifierTransferSelectCallback = (
) => void; ) => void;
export type PartyModifierSpliceSelectCallback = (fromCursor: number, toCursor?: number) => void; export type PartyModifierSpliceSelectCallback = (fromCursor: number, toCursor?: number) => void;
export type PokemonSelectFilter = (pokemon: PlayerPokemon) => string | null; export type PokemonSelectFilter = (pokemon: PlayerPokemon) => string | null;
export type PokemonModifierTransferSelectFilter = ( export type PokemonModifierTransferSelectFilter = (pokemon: PlayerPokemon, item: HeldItemId) => string | null;
pokemon: PlayerPokemon,
modifier: PokemonHeldItemModifier,
) => string | null;
export type PokemonMoveSelectFilter = (pokemonMove: PokemonMove) => string | null; export type PokemonMoveSelectFilter = (pokemonMove: PokemonMove) => string | null;
export default class PartyUiHandler extends MessageUiHandler { export default class PartyUiHandler extends MessageUiHandler {
@ -222,11 +219,8 @@ export default class PartyUiHandler extends MessageUiHandler {
private static FilterAllMoves = (_pokemonMove: PokemonMove) => null; private static FilterAllMoves = (_pokemonMove: PokemonMove) => null;
public static FilterItemMaxStacks = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => { public static FilterItemMaxStacks = (pokemon: PlayerPokemon, item: HeldItemId) => {
const matchingModifier = globalScene.findModifier( if (pokemon.heldItemManager.isMaxStack(item)) {
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(modifier),
) as PokemonHeldItemModifier;
if (matchingModifier && matchingModifier.stackCount === matchingModifier.getMaxStackCount()) {
return i18next.t("partyUiHandler:tooManyItems", { pokemonName: getPokemonNameWithAffix(pokemon, false) }); return i18next.t("partyUiHandler:tooManyItems", { pokemonName: getPokemonNameWithAffix(pokemon, false) });
} }
return null; return null;
@ -505,8 +499,10 @@ export default class PartyUiHandler extends MessageUiHandler {
const ui = this.getUi(); const ui = this.getUi();
if (this.transferCursor !== this.cursor) { if (this.transferCursor !== this.cursor) {
if (this.transferAll) { if (this.transferAll) {
this.getTransferrableItemsFromPokemon(globalScene.getPlayerParty()[this.transferCursor]).forEach( globalScene
(_, i, array) => { .getPlayerParty()
[this.transferCursor].heldItemManager.getTransferableHeldItems()
.forEach((_, i, array) => {
const invertedIndex = array.length - 1 - i; const invertedIndex = array.length - 1 - i;
(this.selectCallback as PartyModifierTransferSelectCallback)( (this.selectCallback as PartyModifierTransferSelectCallback)(
this.transferCursor, this.transferCursor,
@ -514,8 +510,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.transferQuantitiesMax[invertedIndex], this.transferQuantitiesMax[invertedIndex],
this.cursor, this.cursor,
); );
}, });
);
} else { } else {
(this.selectCallback as PartyModifierTransferSelectCallback)( (this.selectCallback as PartyModifierTransferSelectCallback)(
this.transferCursor, this.transferCursor,
@ -550,18 +545,15 @@ export default class PartyUiHandler extends MessageUiHandler {
const newPokemon = globalScene.getPlayerParty()[p]; const newPokemon = globalScene.getPlayerParty()[p];
// this next bit checks to see if the the selected item from the original transfer pokemon exists on the new pokemon `p` // this next bit checks to see if the the selected item from the original transfer pokemon exists on the new pokemon `p`
// this returns `undefined` if the new pokemon doesn't have the item at all, otherwise it returns the `pokemonHeldItemModifier` for that item // this returns `undefined` if the new pokemon doesn't have the item at all, otherwise it returns the `pokemonHeldItemModifier` for that item
const matchingModifier = globalScene.findModifier( const transferItem = pokemon.heldItemManager.getTransferableHeldItems()[this.transferOptionCursor];
m => const matchingItem = newPokemon.heldItemManager.hasItem(transferItem);
m instanceof PokemonHeldItemModifier &&
m.pokemonId === newPokemon.id &&
m.matchType(this.getTransferrableItemsFromPokemon(pokemon)[this.transferOptionCursor]),
) as PokemonHeldItemModifier;
const partySlot = this.partySlots.filter(m => m.getPokemon() === newPokemon)[0]; // this gets pokemon [p] for us const partySlot = this.partySlots.filter(m => m.getPokemon() === newPokemon)[0]; // this gets pokemon [p] for us
if (p !== this.transferCursor) { if (p !== this.transferCursor) {
// this skips adding the able/not able labels on the pokemon doing the transfer // this skips adding the able/not able labels on the pokemon doing the transfer
if (matchingModifier) { if (matchingItem) {
// if matchingModifier exists then the item exists on the new pokemon // if matchingModifier exists then the item exists on the new pokemon
if (matchingModifier.getMaxStackCount() === matchingModifier.stackCount) { if (newPokemon.heldItemManager.isMaxStack(transferItem)) {
// checks to see if the stack of items is at max stack; if so, set the description label to "Not able" // checks to see if the stack of items is at max stack; if so, set the description label to "Not able"
ableToTransferText = i18next.t("partyUiHandler:notAble"); ableToTransferText = i18next.t("partyUiHandler:notAble");
} else { } else {
@ -683,12 +675,6 @@ export default class PartyUiHandler extends MessageUiHandler {
return success; return success;
} }
private getTransferrableItemsFromPokemon(pokemon: PlayerPokemon) {
return globalScene.findModifiers(
m => m instanceof PokemonHeldItemModifier && m.isTransferable && m.pokemonId === pokemon.id,
) as PokemonHeldItemModifier[];
}
private getFilterResult(option: number, pokemon: PlayerPokemon): string | null { private getFilterResult(option: number, pokemon: PlayerPokemon): string | null {
let filterResult: string | null; let filterResult: string | null;
if (option !== PartyOption.TRANSFER && option !== PartyOption.SPLICE) { if (option !== PartyOption.TRANSFER && option !== PartyOption.SPLICE) {
@ -702,7 +688,7 @@ export default class PartyUiHandler extends MessageUiHandler {
} else { } else {
filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)( filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)(
pokemon, pokemon,
this.getTransferrableItemsFromPokemon(globalScene.getPlayerParty()[this.transferCursor])[ globalScene.getPlayerParty()[this.transferCursor].heldItemManager.getTransferableHeldItems()[
this.transferOptionCursor this.transferOptionCursor
], ],
); );
@ -924,14 +910,10 @@ export default class PartyUiHandler extends MessageUiHandler {
if (this.cursor < 6) { if (this.cursor < 6) {
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) { if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) {
/** Initialize item quantities for the selected Pokemon */ /** Initialize item quantities for the selected Pokemon */
const itemModifiers = globalScene.findModifiers( const pokemon = globalScene.getPlayerParty()[this.cursor];
m => const items = pokemon.heldItemManager.getTransferableHeldItems();
m instanceof PokemonHeldItemModifier && this.transferQuantities = items.map(item => pokemon.heldItemManager.getStack(item));
m.isTransferable && this.transferQuantitiesMax = items.map(item => pokemon.heldItemManager.getStack(item));
m.pokemonId === globalScene.getPlayerParty()[this.cursor].id,
) as PokemonHeldItemModifier[];
this.transferQuantities = itemModifiers.map(item => item.getStackCount());
this.transferQuantitiesMax = itemModifiers.map(item => item.getStackCount());
} }
this.showOptions(); this.showOptions();
ui.playSelect(); ui.playSelect();
@ -1177,14 +1159,6 @@ export default class PartyUiHandler extends MessageUiHandler {
); );
} }
private getItemModifiers(pokemon: Pokemon): PokemonHeldItemModifier[] {
return (
(globalScene.findModifiers(
m => m instanceof PokemonHeldItemModifier && m.isTransferable && m.pokemonId === pokemon.id,
) as PokemonHeldItemModifier[]) ?? []
);
}
private updateOptionsWithRememberMoveModifierMode(pokemon): void { private updateOptionsWithRememberMoveModifierMode(pokemon): void {
const learnableMoves = pokemon.getLearnableLevelMoves(); const learnableMoves = pokemon.getLearnableLevelMoves();
for (let m = 0; m < learnableMoves.length; m++) { for (let m = 0; m < learnableMoves.length; m++) {
@ -1204,11 +1178,11 @@ export default class PartyUiHandler extends MessageUiHandler {
} }
private updateOptionsWithModifierTransferMode(pokemon): void { private updateOptionsWithModifierTransferMode(pokemon): void {
const itemModifiers = this.getItemModifiers(pokemon); const items = pokemon.getHeldItems();
for (let im = 0; im < itemModifiers.length; im++) { for (let im = 0; im < items.length; im++) {
this.options.push(im); this.options.push(im);
} }
if (itemModifiers.length > 1) { if (items.length > 1) {
this.options.push(PartyOption.ALL); this.options.push(PartyOption.ALL);
} }
} }
@ -1422,9 +1396,9 @@ export default class PartyUiHandler extends MessageUiHandler {
} else if (option === PartyOption.ALL) { } else if (option === PartyOption.ALL) {
optionName = i18next.t("partyUiHandler:ALL"); optionName = i18next.t("partyUiHandler:ALL");
} else { } else {
const itemModifiers = this.getItemModifiers(pokemon); const items = pokemon.getHeldItems();
const itemModifier = itemModifiers[option]; const item = items[option];
optionName = itemModifier.type.name; optionName = allHeldItems[item].name;
} }
const yCoord = -6 - 16 * o; const yCoord = -6 - 16 * o;
@ -1436,19 +1410,19 @@ export default class PartyUiHandler extends MessageUiHandler {
optionText.setOrigin(0, 0); optionText.setOrigin(0, 0);
/** For every item that has stack bigger than 1, display the current quantity selection */ /** For every item that has stack bigger than 1, display the current quantity selection */
const itemModifiers = this.getItemModifiers(pokemon); const items = pokemon.getHeldItems();
const itemModifier = itemModifiers[option]; const item = items[option];
if ( if (
this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER &&
this.transferQuantitiesMax[option] > 1 && this.transferQuantitiesMax[option] > 1 &&
!this.transferMode && !this.transferMode &&
itemModifier !== undefined && item !== undefined &&
itemModifier.type.name === optionName allHeldItems[item].name === optionName
) { ) {
let amountText = ` (${this.transferQuantities[option]})`; let amountText = ` (${this.transferQuantities[option]})`;
/** If the amount held is the maximum, display the count in red */ /** If the amount held is the maximum, display the count in red */
if (this.transferQuantitiesMax[option] === itemModifier.getMaxHeldItemCount(undefined)) { if (this.transferQuantitiesMax[option] === allHeldItems[item].maxStackCount) {
amountText = `[color=${getTextColor(TextStyle.SUMMARY_RED)}]${amountText}[/color]`; amountText = `[color=${getTextColor(TextStyle.SUMMARY_RED)}]${amountText}[/color]`;
} }