Various fixes

This commit is contained in:
Wlowscha 2025-06-10 22:50:27 +02:00
parent 4dc54ba17e
commit d7882d4ca7
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
8 changed files with 26 additions and 185 deletions

View File

@ -11,11 +11,11 @@ import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { SpeciesFormKey } from "#enums/species-form-key"; import { SpeciesFormKey } from "#enums/species-form-key";
import { TimeOfDay } from "#enums/time-of-day"; import { TimeOfDay } from "#enums/time-of-day";
import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier, SpeciesStatBoosterModifier, TempExtraModifierModifier } from "#app/modifier/modifier";
import type { SpeciesStatBoosterModifierType } from "#app/modifier/modifier-type";
import { speciesStarterCosts } from "./starters"; import { speciesStarterCosts } from "./starters";
import i18next from "i18next"; import i18next from "i18next";
import { initI18n } from "#app/plugins/i18n"; import { initI18n } from "#app/plugins/i18n";
import { allHeldItems } from "#app/items/all-held-items";
import { HeldItemId } from "#enums/held-item-id";
export enum SpeciesWildEvolutionDelay { export enum SpeciesWildEvolutionDelay {
NONE, NONE,
@ -274,10 +274,7 @@ class MoveTypeEvolutionCondition extends SpeciesEvolutionCondition {
class TreasureEvolutionCondition extends SpeciesEvolutionCondition { class TreasureEvolutionCondition extends SpeciesEvolutionCondition {
constructor() { constructor() {
super(p => p.evoCounter super(p => allHeldItems[HeldItemId.GIMMIGHOUL_EVO_TRACKER].getStackCount(p) > 9);
+ p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
+ globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier
|| m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9);
this.description = i18next.t("pokemonEvolutions:treasure"); this.description = i18next.t("pokemonEvolutions:treasure");
} }
} }
@ -1794,8 +1791,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
], ],
[SpeciesId.CLAMPERL]: [ [SpeciesId.CLAMPERL]: [
// TODO: Change the SpeciesEvolutionConditions here to use a bespoke HeldItemEvolutionCondition after the modifier rework // TODO: Change the SpeciesEvolutionConditions here to use a bespoke HeldItemEvolutionCondition after the modifier rework
new SpeciesEvolution(SpeciesId.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.getHeldItems().some(m => m instanceof SpeciesStatBoosterModifier && (m.type as SpeciesStatBoosterModifierType).key === "DEEP_SEA_TOOTH")), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesEvolution(SpeciesId.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.heldItemManager.hasItem(HeldItemId.DEEP_SEA_TOOTH)), SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesEvolution(SpeciesId.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.getHeldItems().some(m => m instanceof SpeciesStatBoosterModifier && (m.type as SpeciesStatBoosterModifierType).key === "DEEP_SEA_SCALE")), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(SpeciesId.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.heldItemManager.hasItem(HeldItemId.DEEP_SEA_SCALE)), SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[SpeciesId.BOLDORE]: [ [SpeciesId.BOLDORE]: [
new SpeciesEvolution(SpeciesId.GIGALITH, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(SpeciesId.GIGALITH, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)

View File

@ -28,7 +28,6 @@ import {
showEncounterText, showEncounterText,
} from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { modifierTypes } from "#app/modifier/modifier-type"; import { modifierTypes } from "#app/modifier/modifier-type";
import { Gender } from "#app/data/gender"; import { Gender } from "#app/data/gender";
import type { PermanentStat } from "#enums/stat"; import type { PermanentStat } from "#enums/stat";
@ -37,6 +36,7 @@ import { CustomPokemonData } from "#app/data/custom-pokemon-data";
import type { AbilityId } from "#enums/ability-id"; import type { AbilityId } from "#enums/ability-id";
import type { PokeballType } from "#enums/pokeball"; import type { PokeballType } from "#enums/pokeball";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import type { HeldItemId } from "#enums/held-item-id";
/** Will give +1 level every 10 waves */ /** Will give +1 level every 10 waves */
export const STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER = 1; export const STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER = 1;
@ -423,6 +423,13 @@ export async function applyModifierTypeToPlayerPokemon(
globalScene.addModifier(modifier, false, false, false, true); globalScene.addModifier(modifier, false, false, false, true);
} }
export function applyHeldItemWithFallback(pokemon: Pokemon, item: HeldItemId, fallbackItem?: HeldItemId) {
const added = pokemon.heldItemManager.add(item);
if (!added && fallbackItem) {
pokemon.heldItemManager.add(fallbackItem);
}
}
/** /**
* Alternative to using AttemptCapturePhase * Alternative to using AttemptCapturePhase
* Assumes player sprite is visible on the screen (this is intended for non-combat uses) * Assumes player sprite is visible on the screen (this is intended for non-combat uses)

View File

@ -25,6 +25,7 @@ import {
type SpeciesFormChangeTrigger, type SpeciesFormChangeTrigger,
SpeciesFormChangeWeatherTrigger, SpeciesFormChangeWeatherTrigger,
} from "./pokemon-forms/form-change-triggers"; } from "./pokemon-forms/form-change-triggers";
import i18next from "i18next";
export function formChangeItemName(id: FormChangeItem) { export function formChangeItemName(id: FormChangeItem) {
return i18next.t(`modifierType:FormChangeItem.${FormChangeItem[id]}`); return i18next.t(`modifierType:FormChangeItem.${FormChangeItem[id]}`);

View File

@ -8,12 +8,12 @@ type HELD_ITEM_DATA = BASE_STAT_TOTAL_DATA | BASE_STAT_FLAT_DATA;
interface HeldItemProperties { interface HeldItemProperties {
stack: number; stack: number;
disabled: boolean; disabled?: boolean;
cooldown?: number; cooldown?: number;
data?: HELD_ITEM_DATA; data?: HELD_ITEM_DATA;
} }
type HeldItemPropertyMap = { export type HeldItemPropertyMap = {
[key in HeldItemId]?: HeldItemProperties; [key in HeldItemId]?: HeldItemProperties;
}; };
@ -21,7 +21,7 @@ interface FormChangeItemProperties {
active: boolean; active: boolean;
} }
type FormChangeItemPropertyMap = { export type FormChangeItemPropertyMap = {
[key in FormChangeItem]?: FormChangeItemProperties; [key in FormChangeItem]?: FormChangeItemProperties;
}; };
@ -73,6 +73,10 @@ export class PokemonItemManager {
return item ? item.stack : 0; return item ? item.stack : 0;
} }
overrideItems(newItems: HeldItemPropertyMap) {
this.heldItems = newItems;
}
add(itemType: HeldItemId, addStack = 1, data?: HELD_ITEM_DATA): boolean { add(itemType: HeldItemId, addStack = 1, data?: HELD_ITEM_DATA): boolean {
const maxStack = allHeldItems[itemType].getMaxStackCount(); const maxStack = allHeldItems[itemType].getMaxStackCount();
const item = this.heldItems[itemType]; const item = this.heldItems[itemType];

View File

@ -4,7 +4,7 @@ import type { BooleanHolder } from "#app/utils/common";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import i18next from "i18next"; import i18next from "i18next";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { Command } from "#app/ui/command-ui-handler"; import { Command } from "#enums/command";
export interface BYPASS_SPEED_CHANCE_PARAMS { export interface BYPASS_SPEED_CHANCE_PARAMS {
/** The pokemon with the item */ /** The pokemon with the item */

View File

@ -46,7 +46,6 @@ import {
MoneyRewardModifier, MoneyRewardModifier,
MultipleParticipantExpBonusModifier, MultipleParticipantExpBonusModifier,
PokemonAllMovePpRestoreModifier, PokemonAllMovePpRestoreModifier,
PokemonFormChangeItemModifier,
type PokemonHeldItemModifier, type PokemonHeldItemModifier,
PokemonHpRestoreModifier, PokemonHpRestoreModifier,
PokemonLevelIncrementModifier, PokemonLevelIncrementModifier,
@ -1099,8 +1098,8 @@ export class FormChangeItemReward extends PokemonModifierType {
constructor(formChangeItem: FormChangeItem) { constructor(formChangeItem: FormChangeItem) {
super( super(
"", "",
FormChangeItem[formChangeItem].toLowerCase(), "",
(_type, args) => new PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true), () => null,
(pokemon: PlayerPokemon) => { (pokemon: PlayerPokemon) => {
// Make sure the Pokemon has alternate forms // Make sure the Pokemon has alternate forms
if ( if (

View File

@ -1,8 +1,6 @@
import { FusionSpeciesFormEvolution, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { FusionSpeciesFormEvolution, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import { getLevelTotalExp } from "#app/data/exp"; import { getLevelTotalExp } from "#app/data/exp";
import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball"; import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball";
import { SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms/form-change-triggers";
import type { FormChangeItem } from "#enums/form-change-item";
import { getStatusEffectHealText } from "#app/data/status-effect"; import { getStatusEffectHealText } from "#app/data/status-effect";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import type { PlayerPokemon } from "#app/field/pokemon"; import type { PlayerPokemon } from "#app/field/pokemon";
@ -10,7 +8,6 @@ import { getPokemonNameWithAffix } from "#app/messages";
import Overrides from "#app/overrides"; import Overrides from "#app/overrides";
import { LearnMoveType } from "#enums/learn-move-type"; import { LearnMoveType } from "#enums/learn-move-type";
import type { VoucherType } from "#app/system/voucher"; import type { VoucherType } from "#app/system/voucher";
import { Command } from "#enums/command";
import { addTextObject, TextStyle } from "#app/ui/text"; import { addTextObject, TextStyle } from "#app/ui/text";
import { import {
type BooleanHolder, type BooleanHolder,
@ -31,7 +28,6 @@ import i18next from "i18next";
import { import {
type DoubleBattleChanceBoosterModifierType, type DoubleBattleChanceBoosterModifierType,
type EvolutionItemModifierType, type EvolutionItemModifierType,
type FormChangeItemModifierType,
type ModifierOverride, type ModifierOverride,
type ModifierType, type ModifierType,
type TerastallizeModifierType, type TerastallizeModifierType,
@ -546,107 +542,6 @@ export class TerastallizeAccessModifier extends PersistentModifier {
} }
} }
export abstract class PokemonHeldItemModifier extends PersistentModifier {
/** The ID of the {@linkcode Pokemon} that this item belongs to. */
public pokemonId: number;
/** Whether this item can be transfered to or stolen by another Pokemon. */
public isTransferable = true;
constructor(type: ModifierType, pokemonId: number, stackCount?: number) {
super(type, stackCount);
this.pokemonId = pokemonId;
}
abstract matchType(_modifier: Modifier): boolean;
match(modifier: Modifier) {
return this.matchType(modifier) && (modifier as PokemonHeldItemModifier).pokemonId === this.pokemonId;
}
getArgs(): any[] {
return [this.pokemonId];
}
/**
* Applies the {@linkcode PokemonHeldItemModifier} to the given {@linkcode Pokemon}.
* @param pokemon The {@linkcode Pokemon} that holds the held item
* @param args additional parameters
*/
abstract override apply(pokemon: Pokemon, ...args: unknown[]): boolean;
/**
* Checks if {@linkcode PokemonHeldItemModifier} should be applied.
* @param pokemon The {@linkcode Pokemon} that holds the item
* @param _args N/A
* @returns if {@linkcode PokemonHeldItemModifier} should be applied
*/
override shouldApply(pokemon?: Pokemon, ..._args: unknown[]): boolean {
return !!pokemon && (this.pokemonId === -1 || pokemon.id === this.pokemonId);
}
isIconVisible(): boolean {
return !!this.getPokemon()?.isOnField();
}
getIcon(forSummary?: boolean): Phaser.GameObjects.Container {
const container = !forSummary ? globalScene.add.container(0, 0) : super.getIcon();
if (!forSummary) {
const pokemon = this.getPokemon();
if (pokemon) {
const pokemonIcon = globalScene.addPokemonIcon(pokemon, -2, 10, 0, 0.5, undefined, true);
container.add(pokemonIcon);
container.setName(pokemon.id.toString());
}
const item = globalScene.add.sprite(16, this.virtualStackCount ? 8 : 16, "items");
item.setScale(0.5);
item.setOrigin(0, 0.5);
item.setTexture("items", this.type.getIcon());
container.add(item);
const stackText = this.getIconStackText();
if (stackText) {
container.add(stackText);
}
const virtualStackText = this.getIconStackText(true);
if (virtualStackText) {
container.add(virtualStackText);
}
} else {
container.setScale(0.5);
}
return container;
}
getPokemon(): Pokemon | undefined {
return this.pokemonId ? (globalScene.getPokemonById(this.pokemonId) ?? undefined) : undefined;
}
getScoreMultiplier(): number {
return 1;
}
getMaxStackCount(forThreshold?: boolean): number {
const pokemon = this.getPokemon();
if (!pokemon) {
return 0;
}
if (pokemon.isPlayer() && forThreshold) {
return globalScene
.getPlayerParty()
.map(p => this.getMaxHeldItemCount(p))
.reduce((stackCount: number, maxStackCount: number) => Math.max(stackCount, maxStackCount), 0);
}
return this.getMaxHeldItemCount(pokemon);
}
abstract getMaxHeldItemCount(pokemon?: Pokemon): number;
}
export class LevelIncrementBoosterModifier extends PersistentModifier { export class LevelIncrementBoosterModifier extends PersistentModifier {
match(modifier: Modifier) { match(modifier: Modifier) {
return modifier instanceof LevelIncrementBoosterModifier; return modifier instanceof LevelIncrementBoosterModifier;
@ -1254,69 +1149,6 @@ export class ExpBalanceModifier extends PersistentModifier {
} }
} }
export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier {
public override type: FormChangeItemModifierType;
public formChangeItem: FormChangeItem;
public active: boolean;
public isTransferable = false;
constructor(
type: FormChangeItemModifierType,
pokemonId: number,
formChangeItem: FormChangeItem,
active: boolean,
stackCount?: number,
) {
super(type, pokemonId, stackCount);
this.formChangeItem = formChangeItem;
this.active = active;
}
matchType(modifier: Modifier): boolean {
return modifier instanceof PokemonFormChangeItemModifier && modifier.formChangeItem === this.formChangeItem;
}
clone(): PersistentModifier {
return new PokemonFormChangeItemModifier(
this.type,
this.pokemonId,
this.formChangeItem,
this.active,
this.stackCount,
);
}
getArgs(): any[] {
return super.getArgs().concat(this.formChangeItem, this.active);
}
/**
* Applies {@linkcode PokemonFormChangeItemModifier}
* @param pokemon The {@linkcode Pokemon} to apply the form change item to
* @param active `true` if the form change item is active
* @returns `true` if the form change item was applied
*/
override apply(pokemon: Pokemon, active: boolean): boolean {
const switchActive = this.active && !active;
if (switchActive) {
this.active = false;
}
const ret = globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger);
if (switchActive) {
this.active = true;
}
return ret;
}
getMaxHeldItemCount(_pokemon: Pokemon): number {
return 1;
}
}
export class MoneyRewardModifier extends ConsumableModifier { export class MoneyRewardModifier extends ConsumableModifier {
private moneyMultiplier: number; private moneyMultiplier: number;

View File

@ -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, formChangeItemName } from "#app/data/pokemon-forms/form-change-triggers"; import { SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms/form-change-triggers";
import { FormChangeItem } from "#enums/form-change-item"; import { FormChangeItem } from "#enums/form-change-item";
import { getVariantTint } from "#app/sprites/variant"; import { getVariantTint } from "#app/sprites/variant";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
@ -29,6 +29,7 @@ import { getPokemonNameWithAffix } from "#app/messages";
import type { CommandPhase } from "#app/phases/command-phase"; 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";
const defaultMessage = i18next.t("partyUiHandler:choosePokemon"); const defaultMessage = i18next.t("partyUiHandler:choosePokemon");