mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 15:32:18 +02:00
Added overloads to modifier functions, cleaned up existing uses theroef
This commit is contained in:
parent
8cf8c854ce
commit
e089fd28f2
4
src/@types/modifier-predicate.ts
Normal file
4
src/@types/modifier-predicate.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import type { Modifier } from "../modifier/modifier";
|
||||
|
||||
export type ModifierPredicate = (modifier: Modifier) => boolean;
|
||||
export type ModifierIdentityPredicate<T extends Modifier> = (modifier: Modifier) => modifier is T;
|
@ -19,12 +19,8 @@ import {
|
||||
type Constructor,
|
||||
} from "#app/utils/common";
|
||||
import { deepMergeSpriteData } from "#app/utils/data";
|
||||
import type {
|
||||
Modifier,
|
||||
ModifierIdentityPredicate,
|
||||
ModifierPredicate,
|
||||
TurnHeldItemTransferModifier,
|
||||
} from "./modifier/modifier";
|
||||
import type { Modifier, TurnHeldItemTransferModifier } from "./modifier/modifier";
|
||||
import type { ModifierIdentityPredicate, ModifierPredicate } from "./@types/modifier-predicate";
|
||||
import {
|
||||
ConsumableModifier,
|
||||
ConsumablePokemonModifier,
|
||||
@ -2125,9 +2121,10 @@ export default class BattleScene extends SceneBase {
|
||||
enemy.getSpeciesForm().getBaseExp() *
|
||||
(enemy.level / this.getMaxExpLevel()) *
|
||||
((enemy.ivs.reduce((iv: number, total: number) => (total += iv), 0) / 93) * 0.2 + 0.8);
|
||||
this.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemy.id, false).map(
|
||||
m => (scoreIncrease *= (m as PokemonHeldItemModifier).getScoreMultiplier()),
|
||||
);
|
||||
this.findModifiers(
|
||||
(m): m is PokemonHeldItemModifier => m instanceof PokemonHeldItemModifier && m.pokemonId === enemy.id,
|
||||
false,
|
||||
).forEach(m => (scoreIncrease *= m.getScoreMultiplier()));
|
||||
if (enemy.isBoss()) {
|
||||
scoreIncrease *= Math.sqrt(enemy.bossSegments);
|
||||
}
|
||||
@ -3070,9 +3067,10 @@ export default class BattleScene extends SceneBase {
|
||||
const newItemModifier = itemModifier.clone() as PokemonHeldItemModifier;
|
||||
newItemModifier.pokemonId = target.id;
|
||||
const matchingModifier = this.findModifier(
|
||||
m => m instanceof PokemonHeldItemModifier && m.matchType(itemModifier) && m.pokemonId === target.id,
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier && m.matchType(itemModifier) && m.pokemonId === target.id,
|
||||
target.isPlayer(),
|
||||
) as PokemonHeldItemModifier;
|
||||
);
|
||||
|
||||
if (matchingModifier) {
|
||||
const maxStackCount = matchingModifier.getMaxStackCount();
|
||||
@ -3137,9 +3135,10 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
|
||||
const matchingModifier = this.findModifier(
|
||||
m => m instanceof PokemonHeldItemModifier && m.matchType(mod) && m.pokemonId === target.id,
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier && m.matchType(mod) && m.pokemonId === target.id,
|
||||
target.isPlayer(),
|
||||
) as PokemonHeldItemModifier;
|
||||
);
|
||||
|
||||
if (matchingModifier) {
|
||||
const maxStackCount = matchingModifier.getMaxStackCount();
|
||||
@ -3365,28 +3364,29 @@ export default class BattleScene extends SceneBase {
|
||||
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
|
||||
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||
* @returns the list of all modifiers that matched `modifierType`.
|
||||
* @deprecated - use `findModifiers`
|
||||
*/
|
||||
getModifiers<T extends PersistentModifier>(modifierType: Constructor<T>, player = true): T[] {
|
||||
return (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType);
|
||||
}
|
||||
|
||||
findModifiers<T extends PersistentModifier>(modifierFilter: ModifierIdentityPredicate<T>, isPlayer?: boolean): T[];
|
||||
findModifiers(modifierFilter: ModifierPredicate, isPlayer?: boolean): PersistentModifier[];
|
||||
/**
|
||||
* Get all of the modifiers that pass the `modifierFilter` function
|
||||
* @param modifierFilter - The function used to filter a target's modifiers
|
||||
* @param isPlayer - Whether to search the player (`true`) or the enemy (`false`) party; default `true`.
|
||||
* @returns - An array containing all modifiers that passed the `modifierFilter` function.
|
||||
*/
|
||||
findModifiers(modifierFilter: ModifierPredicate, isPlayer?: boolean): PersistentModifier[];
|
||||
findModifiers<T extends PersistentModifier>(modifierFilter: ModifierIdentityPredicate<T>, isPlayer?: boolean): T[];
|
||||
findModifiers(modifierFilter: ModifierPredicate, isPlayer = true): PersistentModifier[] {
|
||||
return (isPlayer ? this.modifiers : this.enemyModifiers).filter(modifierFilter);
|
||||
}
|
||||
|
||||
findModifier(modifierFilter: ModifierPredicate, player?: boolean): PersistentModifier | undefined;
|
||||
findModifier<T extends PersistentModifier>(
|
||||
modifierFilter: ModifierIdentityPredicate<T>,
|
||||
player?: boolean,
|
||||
): T | undefined;
|
||||
findModifier(modifierFilter: ModifierPredicate, player?: boolean): PersistentModifier | undefined;
|
||||
/**
|
||||
* Get the first modifier that passes the `modifierFilter` function.
|
||||
* @param modifierFilter - The function used to filter a target's modifiers.
|
||||
@ -3503,13 +3503,10 @@ 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 formChangeItemModifiers = this.findModifiers(
|
||||
(m): m is PokemonFormChangeItemModifier =>
|
||||
m instanceof PokemonFormChangeItemModifier && m.active && m.pokemonId === pokemon.id,
|
||||
).map(m => m.formChangeItem);
|
||||
|
||||
matchingFormChange = formChangeItemModifiers.includes(FormChangeItem.N_LUNARIZER)
|
||||
? matchingFormChangeOpts[0]
|
||||
@ -3691,13 +3688,13 @@ export default class BattleScene extends SceneBase {
|
||||
): void {
|
||||
const participantIds = pokemonParticipantIds ?? this.currentBattle.playerParticipantIds;
|
||||
const party = this.getPlayerParty();
|
||||
const expShareModifier = this.findModifier(m => m instanceof ExpShareModifier) as ExpShareModifier;
|
||||
const expBalanceModifier = this.findModifier(m => m instanceof ExpBalanceModifier) as ExpBalanceModifier;
|
||||
const expShareModifier = this.findModifier(m => m instanceof ExpShareModifier);
|
||||
const expBalanceModifier = this.findModifier(m => m instanceof ExpBalanceModifier);
|
||||
const multipleParticipantExpBonusModifier = this.findModifier(
|
||||
m => m instanceof MultipleParticipantExpBonusModifier,
|
||||
) as MultipleParticipantExpBonusModifier;
|
||||
const nonFaintedPartyMembers = party.filter(p => p.hp);
|
||||
const expPartyMembers = nonFaintedPartyMembers.filter(p => p.level < this.getMaxExpLevel());
|
||||
);
|
||||
const nonFaintedPartyMembers = party.filter(p => p.hp > 0);
|
||||
const expPartyMembers = party.filter(p => p.hp > 0 && p.level < this.getMaxExpLevel());
|
||||
const partyMemberExp: number[] = [];
|
||||
// EXP value calculation is based off Pokemon.getExpValue
|
||||
if (useWaveIndexMultiplier) {
|
||||
|
@ -178,14 +178,14 @@ export default class Battle {
|
||||
this.postBattleLoot.push(
|
||||
...globalScene
|
||||
.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.isTransferable,
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.isTransferable,
|
||||
false,
|
||||
)
|
||||
.map(i => {
|
||||
const ret = i as PokemonHeldItemModifier;
|
||||
//@ts-ignore - this is awful to fix/change
|
||||
ret.pokemonId = null;
|
||||
return ret;
|
||||
// @ts-ignore - this is awful to fix/change
|
||||
i.pokemonId = null;
|
||||
return i;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -1777,8 +1777,10 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
||||
}
|
||||
|
||||
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
|
||||
return globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier[];
|
||||
return globalScene.findModifiers((m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1904,8 +1906,10 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
||||
}
|
||||
|
||||
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
|
||||
return globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier[];
|
||||
return globalScene.findModifiers((m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -815,7 +815,7 @@ export default class Move implements Localizable {
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, typeChangeHolder, typeChangeMovePowerMultiplier);
|
||||
|
||||
const sourceTeraType = source.getTeraType();
|
||||
if (source.isTerastallized && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !globalScene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) {
|
||||
if (source.isTerastallized && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !globalScene.hasModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) {
|
||||
power.value = 60;
|
||||
}
|
||||
|
||||
@ -2570,8 +2570,10 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
|
||||
}
|
||||
|
||||
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
|
||||
return globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier[];
|
||||
return globalScene.findModifiers((m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()
|
||||
);
|
||||
}
|
||||
|
||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
||||
@ -2652,8 +2654,10 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
|
||||
}
|
||||
|
||||
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
|
||||
return globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier[];
|
||||
return globalScene.findModifiers((m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()
|
||||
);
|
||||
}
|
||||
|
||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
||||
@ -2712,8 +2716,10 @@ export class EatBerryAttr extends MoveEffectAttr {
|
||||
}
|
||||
|
||||
getTargetHeldBerries(target: Pokemon): BerryModifier[] {
|
||||
return globalScene.findModifiers(m => m instanceof BerryModifier
|
||||
&& (m as BerryModifier).pokemonId === target.id, target.isPlayer()) as BerryModifier[];
|
||||
return globalScene.findModifiers((m): m is BerryModifier =>
|
||||
m instanceof BerryModifier
|
||||
&& m.pokemonId === target.id, target.isPlayer()
|
||||
);
|
||||
}
|
||||
|
||||
reduceBerryModifier(target: Pokemon) {
|
||||
|
@ -191,7 +191,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
globalScene.loadSe("Follow Me", "battle_anims", "Follow Me.mp3");
|
||||
|
||||
// Get all player berry items, remove from party, and store reference
|
||||
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
||||
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier);
|
||||
|
||||
// Sort berries by party member ID to more easily re-add later if necessary
|
||||
const berryItemsMap = new Map<number, BerryModifier[]>();
|
||||
@ -256,7 +256,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
|
||||
// Remove the berries from the party
|
||||
// Session has been safely saved at this point, so data won't be lost
|
||||
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
||||
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier);
|
||||
berryItems.forEach(berryMod => {
|
||||
globalScene.removeModifier(berryMod);
|
||||
});
|
||||
|
@ -314,12 +314,10 @@ function tryGiveBerry(prioritizedPokemon?: PlayerPokemon) {
|
||||
// Will try to apply to prioritized pokemon first, then do normal application method if it fails
|
||||
if (prioritizedPokemon) {
|
||||
const heldBerriesOfType = globalScene.findModifier(
|
||||
m =>
|
||||
m instanceof BerryModifier &&
|
||||
m.pokemonId === prioritizedPokemon.id &&
|
||||
(m as BerryModifier).berryType === berryType,
|
||||
(m): m is BerryModifier =>
|
||||
m instanceof BerryModifier && m.pokemonId === prioritizedPokemon.id && m.berryType === berryType,
|
||||
true,
|
||||
) as BerryModifier;
|
||||
);
|
||||
|
||||
if (!heldBerriesOfType || heldBerriesOfType.getStackCount() < heldBerriesOfType.getMaxStackCount()) {
|
||||
applyModifierTypeToPlayerPokemon(prioritizedPokemon, berry);
|
||||
@ -330,9 +328,10 @@ function tryGiveBerry(prioritizedPokemon?: PlayerPokemon) {
|
||||
// Iterate over the party until berry was successfully given
|
||||
for (const pokemon of party) {
|
||||
const heldBerriesOfType = globalScene.findModifier(
|
||||
m => m instanceof BerryModifier && m.pokemonId === pokemon.id && (m as BerryModifier).berryType === berryType,
|
||||
(m): m is BerryModifier =>
|
||||
m instanceof BerryModifier && m.pokemonId === pokemon.id && (m as BerryModifier).berryType === berryType,
|
||||
true,
|
||||
) as BerryModifier;
|
||||
);
|
||||
|
||||
if (!heldBerriesOfType || heldBerriesOfType.getStackCount() < heldBerriesOfType.getMaxStackCount()) {
|
||||
applyModifierTypeToPlayerPokemon(pokemon, berry);
|
||||
|
@ -367,10 +367,10 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
const modifierOptions: ModifierTypeOption[] = [generateModifierTypeOption(modifierTypes.MASTER_BALL)!];
|
||||
const specialOptions: ModifierTypeOption[] = [];
|
||||
|
||||
if (!globalScene.findModifier(m => m instanceof MegaEvolutionAccessModifier)) {
|
||||
if (!globalScene.hasModifier(m => m instanceof MegaEvolutionAccessModifier)) {
|
||||
modifierOptions.push(generateModifierTypeOption(modifierTypes.MEGA_BRACELET)!);
|
||||
}
|
||||
if (!globalScene.findModifier(m => m instanceof GigantamaxAccessModifier)) {
|
||||
if (!globalScene.hasModifier(m => m instanceof GigantamaxAccessModifier)) {
|
||||
modifierOptions.push(generateModifierTypeOption(modifierTypes.DYNAMAX_BAND)!);
|
||||
}
|
||||
const nonRareEvolutionModifier = generateModifierTypeOption(modifierTypes.EVOLUTION_ITEM);
|
||||
|
@ -166,7 +166,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
.withOptionPhase(async () => {
|
||||
// Give the player an Amulet Coin
|
||||
// Check if the player has max stacks of that item already
|
||||
const existing = globalScene.findModifier(m => m instanceof MoneyMultiplierModifier) as MoneyMultiplierModifier;
|
||||
const existing = globalScene.findModifier(m => m instanceof MoneyMultiplierModifier);
|
||||
|
||||
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
|
||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||
@ -247,9 +247,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
// Give the player a Candy Jar if they gave a Berry, and a Berry Pouch for Reviver Seed
|
||||
if (modifier instanceof BerryModifier) {
|
||||
// Check if the player has max stacks of that Candy Jar already
|
||||
const existing = globalScene.findModifier(
|
||||
m => m instanceof LevelIncrementBoosterModifier,
|
||||
) as LevelIncrementBoosterModifier;
|
||||
const existing = globalScene.findModifier(m => m instanceof LevelIncrementBoosterModifier);
|
||||
|
||||
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
|
||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||
@ -271,7 +269,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
}
|
||||
} else {
|
||||
// Check if the player has max stacks of that Berry Pouch already
|
||||
const existing = globalScene.findModifier(m => m instanceof PreserveBerryModifier) as PreserveBerryModifier;
|
||||
const existing = globalScene.findModifier(m => m instanceof PreserveBerryModifier);
|
||||
|
||||
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
|
||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||
@ -357,7 +355,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||
const chosenPokemon: PlayerPokemon = encounter.misc.chosenPokemon;
|
||||
|
||||
// Check if the player has max stacks of Healing Charm already
|
||||
const existing = globalScene.findModifier(m => m instanceof HealingBoosterModifier) as HealingBoosterModifier;
|
||||
const existing = globalScene.findModifier(m => m instanceof HealingBoosterModifier);
|
||||
|
||||
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
|
||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||
|
@ -17,7 +17,8 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/myst
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { HitHealModifier, PokemonHeldItemModifier, TurnHealModifier } from "#app/modifier/modifier";
|
||||
import { PokemonHeldItemModifier, TurnHealModifier } from "#app/modifier/modifier";
|
||||
import type { HitHealModifier } from "#app/modifier/modifier";
|
||||
import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import i18next from "#app/plugins/i18n";
|
||||
@ -231,12 +232,10 @@ async function tryApplyDigRewardItems() {
|
||||
// Iterate over the party until an item was successfully given
|
||||
// First leftovers
|
||||
for (const pokemon of party) {
|
||||
const heldItems = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id,
|
||||
const existingLeftovers = globalScene.findModifier(
|
||||
(m): m is TurnHealModifier => m instanceof TurnHealModifier && m.pokemonId === pokemon.id,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
const existingLeftovers = heldItems.find(m => m instanceof TurnHealModifier) as TurnHealModifier;
|
||||
|
||||
);
|
||||
if (!existingLeftovers || existingLeftovers.getStackCount() < existingLeftovers.getMaxStackCount()) {
|
||||
await applyModifierTypeToPlayerPokemon(pokemon, leftovers);
|
||||
break;
|
||||
@ -245,12 +244,10 @@ async function tryApplyDigRewardItems() {
|
||||
|
||||
// Second leftovers
|
||||
for (const pokemon of party) {
|
||||
const heldItems = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id,
|
||||
const existingLeftovers = globalScene.findModifier(
|
||||
(m): m is TurnHealModifier => m instanceof TurnHealModifier && m.pokemonId === pokemon.id,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
const existingLeftovers = heldItems.find(m => m instanceof TurnHealModifier) as TurnHealModifier;
|
||||
|
||||
);
|
||||
if (!existingLeftovers || existingLeftovers.getStackCount() < existingLeftovers.getMaxStackCount()) {
|
||||
await applyModifierTypeToPlayerPokemon(pokemon, leftovers);
|
||||
break;
|
||||
@ -270,12 +267,10 @@ async function tryApplyDigRewardItems() {
|
||||
|
||||
// Only Shell bell
|
||||
for (const pokemon of party) {
|
||||
const heldItems = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id,
|
||||
const existingShellBell = globalScene.findModifier(
|
||||
(m): m is HitHealModifier => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
const existingShellBell = heldItems.find(m => m instanceof HitHealModifier) as HitHealModifier;
|
||||
|
||||
);
|
||||
if (!existingShellBell || existingShellBell.getStackCount() < existingShellBell.getMaxStackCount()) {
|
||||
await applyModifierTypeToPlayerPokemon(pokemon, shellBell);
|
||||
break;
|
||||
|
@ -204,9 +204,7 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
|
||||
// Remove 4 random berries from player's party
|
||||
// Get all player berry items, remove from party, and store reference
|
||||
const berryItems: BerryModifier[] = globalScene.findModifiers(
|
||||
m => m instanceof BerryModifier,
|
||||
) as BerryModifier[];
|
||||
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const index = randSeedInt(berryItems.length);
|
||||
const randBerry = berryItems[index];
|
||||
|
@ -377,12 +377,10 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
||||
let modifierCount = 0;
|
||||
for (const modifier of this.requiredHeldItemModifiers) {
|
||||
const matchingMods = globalScene.findModifiers(m => m.constructor.name === modifier);
|
||||
if (matchingMods?.length > 0) {
|
||||
for (const matchingMod of matchingMods) {
|
||||
modifierCount += matchingMod.stackCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modifierCount >= this.minNumberOfItems;
|
||||
}
|
||||
|
@ -404,12 +404,12 @@ export async function applyModifierTypeToPlayerPokemon(
|
||||
// Check if the Pokemon has max stacks of that item already
|
||||
const modifier = modType.newModifier(pokemon);
|
||||
const existing = globalScene.findModifier(
|
||||
m =>
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier &&
|
||||
m.type.id === modType.id &&
|
||||
m.pokemonId === pokemon.id &&
|
||||
m.matchType(modifier),
|
||||
) as PokemonHeldItemModifier;
|
||||
);
|
||||
|
||||
// At max stacks
|
||||
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
|
||||
|
@ -1206,14 +1206,20 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
this.setScale(this.getSpriteScale());
|
||||
}
|
||||
|
||||
getHeldItems(): PokemonHeldItemModifier[] {
|
||||
/**
|
||||
* Return all of this Pokemon's held modifiers.
|
||||
* @param transferrableOnly - Whether to only consider transferrable held items; default `false`
|
||||
* @returns An array of all {@linkcode PokemonHeldItemModifier}s held by this Pokemon.
|
||||
*/
|
||||
getHeldItems(transferrableOnly = this.getFusionIconAtlasKey): PokemonHeldItemModifier[] {
|
||||
if (!globalScene) {
|
||||
return [];
|
||||
}
|
||||
return globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === this.id,
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier && m.pokemonId === this.id && !(transferrableOnly && !m.isTransferable()),
|
||||
this.isPlayer(),
|
||||
) as PokemonHeldItemModifier[];
|
||||
);
|
||||
}
|
||||
|
||||
updateScale(): void {
|
||||
@ -5872,10 +5878,7 @@ export class PlayerPokemon extends Pokemon {
|
||||
|
||||
globalScene.getPlayerParty().push(newPokemon);
|
||||
newPokemon.evolve(!isFusion ? newEvolution : new FusionSpeciesFormEvolution(this.id, newEvolution), evoSpecies);
|
||||
const modifiers = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === this.id,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
const modifiers = this.getHeldItems();
|
||||
modifiers.forEach(m => {
|
||||
const clonedModifier = m.clone() as PokemonHeldItemModifier;
|
||||
clonedModifier.pokemonId = newPokemon.id;
|
||||
@ -5993,11 +5996,7 @@ export class PlayerPokemon extends Pokemon {
|
||||
}
|
||||
|
||||
// combine the two mons' held items
|
||||
const fusedPartyMemberHeldModifiers = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
for (const modifier of fusedPartyMemberHeldModifiers) {
|
||||
for (const modifier of pokemon.getHeldItems()) {
|
||||
globalScene.tryTransferHeldItemModifier(modifier, this, false, modifier.getStackCount(), true, true, false);
|
||||
}
|
||||
globalScene.updateModifiers(true, true);
|
||||
|
@ -394,8 +394,9 @@ export class PokemonHeldItemModifierType extends PokemonModifierType {
|
||||
(pokemon: PlayerPokemon) => {
|
||||
const dummyModifier = this.newModifier(pokemon);
|
||||
const matchingModifier = globalScene.findModifier(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(dummyModifier),
|
||||
) as PokemonHeldItemModifier;
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(dummyModifier),
|
||||
);
|
||||
const maxStackCount = dummyModifier.getMaxStackCount();
|
||||
if (!maxStackCount) {
|
||||
return i18next.t("modifierType:ModifierType.PokemonHeldItemModifierType.extra.inoperable", {
|
||||
|
@ -54,9 +54,6 @@ import {
|
||||
} from "#app/data/abilities/ability";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
|
||||
export type ModifierPredicate = (modifier: Modifier) => boolean;
|
||||
export type ModifierIdentityPredicate<T extends Modifier> = (modifier: Modifier) => modifier is T;
|
||||
|
||||
const iconOverflowIndex = 24;
|
||||
|
||||
export const modifierSortFunc = (a: Modifier, b: Modifier): number => {
|
||||
@ -3253,10 +3250,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
||||
}
|
||||
|
||||
const transferredModifierTypes: ModifierType[] = [];
|
||||
const itemModifiers = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === targetPokemon.id && m.isTransferable,
|
||||
targetPokemon.isPlayer(),
|
||||
) as PokemonHeldItemModifier[];
|
||||
const itemModifiers = targetPokemon.getHeldItems();
|
||||
|
||||
for (let i = 0; i < transferredItemCount; i++) {
|
||||
if (!itemModifiers.length) {
|
||||
|
@ -82,8 +82,9 @@ export class BattleEndPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
const lapsingModifiers = globalScene.findModifiers(
|
||||
m => m instanceof LapsingPersistentModifier || m instanceof LapsingPokemonHeldItemModifier,
|
||||
) as (LapsingPersistentModifier | LapsingPokemonHeldItemModifier)[];
|
||||
(m): m is LapsingPersistentModifier | LapsingPokemonHeldItemModifier =>
|
||||
m instanceof LapsingPersistentModifier || m instanceof LapsingPokemonHeldItemModifier,
|
||||
);
|
||||
for (const m of lapsingModifiers) {
|
||||
const args: any[] = [];
|
||||
if (m instanceof LapsingPokemonHeldItemModifier) {
|
||||
|
@ -40,7 +40,7 @@ export class SelectBiomePhase extends BattlePhase {
|
||||
.filter(b => !Array.isArray(b) || !randSeedInt(b[1]))
|
||||
.map(b => (!Array.isArray(b) ? b : b[0]));
|
||||
|
||||
if (biomes.length > 1 && globalScene.findModifier(m => m instanceof MapModifier)) {
|
||||
if (biomes.length > 1 && globalScene.hasModifier(m => m instanceof MapModifier)) {
|
||||
const biomeSelectItems = biomes.map(b => {
|
||||
const ret: OptionSelectItem = {
|
||||
label: getBiomeName(b),
|
||||
|
@ -15,12 +15,7 @@ import {
|
||||
getPlayerModifierTypeOptions,
|
||||
} from "#app/modifier/modifier-type";
|
||||
import type { Modifier } from "#app/modifier/modifier";
|
||||
import {
|
||||
ExtraModifierModifier,
|
||||
HealShopCostModifier,
|
||||
PokemonHeldItemModifier,
|
||||
TempExtraModifierModifier,
|
||||
} from "#app/modifier/modifier";
|
||||
import { ExtraModifierModifier, HealShopCostModifier, TempExtraModifierModifier } from "#app/modifier/modifier";
|
||||
import type ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||
import { SHOP_OPTIONS_ROW_LIMIT } from "#app/ui/modifier-select-ui-handler";
|
||||
import PartyUiHandler, { PartyUiMode, PartyOption } from "#app/ui/party-ui-handler";
|
||||
@ -150,12 +145,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
fromSlotIndex !== toSlotIndex &&
|
||||
itemIndex > -1
|
||||
) {
|
||||
const itemModifiers = globalScene.findModifiers(
|
||||
m =>
|
||||
m instanceof PokemonHeldItemModifier &&
|
||||
m.isTransferable &&
|
||||
m.pokemonId === party[fromSlotIndex].id,
|
||||
) as PokemonHeldItemModifier[];
|
||||
const itemModifiers = party[toSlotIndex].getHeldItems(true);
|
||||
const itemModifier = itemModifiers[itemIndex];
|
||||
globalScene.tryTransferHeldItemModifier(
|
||||
itemModifier,
|
||||
|
@ -138,7 +138,6 @@ export class SwitchSummonPhase extends SummonPhase {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (this.switchType === SwitchType.BATON_PASS) {
|
||||
// If switching via baton pass, update opposing tags coming from the prior pokemon
|
||||
(this.player ? globalScene.getEnemyField() : globalScene.getPlayerField()).forEach((enemyPokemon: Pokemon) =>
|
||||
@ -147,17 +146,17 @@ export class SwitchSummonPhase extends SummonPhase {
|
||||
|
||||
// If the recipient pokemon lacks a baton, give our baton to it during the swap
|
||||
if (
|
||||
!globalScene.findModifier(
|
||||
!globalScene.hasModifier(
|
||||
m =>
|
||||
m instanceof SwitchEffectTransferModifier &&
|
||||
(m as SwitchEffectTransferModifier).pokemonId === switchedInPokemon.id,
|
||||
)
|
||||
) {
|
||||
const batonPassModifier = globalScene.findModifier(
|
||||
m =>
|
||||
(m): m is SwitchEffectTransferModifier =>
|
||||
m instanceof SwitchEffectTransferModifier &&
|
||||
(m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id,
|
||||
) as SwitchEffectTransferModifier;
|
||||
);
|
||||
|
||||
if (batonPassModifier) {
|
||||
globalScene.tryTransferHeldItemModifier(
|
||||
|
@ -225,8 +225,9 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
|
||||
public static FilterItemMaxStacks = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => {
|
||||
const matchingModifier = globalScene.findModifier(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(modifier),
|
||||
) as PokemonHeldItemModifier;
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(modifier),
|
||||
);
|
||||
if (matchingModifier && matchingModifier.stackCount === matchingModifier.getMaxStackCount()) {
|
||||
return i18next.t("partyUiHandler:tooManyItems", { pokemonName: getPokemonNameWithAffix(pokemon, false) });
|
||||
}
|
||||
@ -552,11 +553,11 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
// 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
|
||||
const matchingModifier = globalScene.findModifier(
|
||||
m =>
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
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
|
||||
if (p !== this.transferCursor) {
|
||||
// this skips adding the able/not able labels on the pokemon doing the transfer
|
||||
@ -1161,9 +1162,9 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
}
|
||||
|
||||
private allowBatonModifierSwitch(): boolean {
|
||||
return !!(
|
||||
return (
|
||||
this.partyUiMode !== PartyUiMode.FAINT_SWITCH &&
|
||||
globalScene.findModifier(
|
||||
globalScene.hasModifier(
|
||||
m =>
|
||||
m instanceof SwitchEffectTransferModifier && m.pokemonId === globalScene.getPlayerField()[this.fieldIndex].id,
|
||||
)
|
||||
|
@ -19,7 +19,9 @@ describe("Abilities - Harvest", () => {
|
||||
let game: GameManager;
|
||||
|
||||
const getPlayerBerries = () =>
|
||||
game.scene.getModifiers(BerryModifier, true).filter(b => b.pokemonId === game.scene.getPlayerPokemon()?.id);
|
||||
game.scene.findModifiers(
|
||||
(b): b is BerryModifier => b instanceof BerryModifier && b.pokemonId === game.scene.getPlayerPokemon()!.id,
|
||||
);
|
||||
|
||||
/** Check whether the player's Modifiers contains the specified berries and nothing else. */
|
||||
function expectBerriesContaining(...berries: ModifierOverride[]): void {
|
||||
|
@ -64,8 +64,8 @@ describe("Items - Dire Hit", () => {
|
||||
|
||||
await game.phaseInterceptor.to(BattleEndPhase);
|
||||
|
||||
const modifier = game.scene.findModifier(m => m instanceof TempCritBoosterModifier) as TempCritBoosterModifier;
|
||||
expect(modifier.getBattleCount()).toBe(4);
|
||||
const modifier = game.scene.findModifier(m => m instanceof TempCritBoosterModifier);
|
||||
expect(modifier?.getBattleCount()).toBe(4);
|
||||
|
||||
// Forced DIRE_HIT to spawn in the first slot with override
|
||||
game.onNextPrompt(
|
||||
|
@ -157,9 +157,10 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
||||
for (const partyPokemon of scene.getPlayerParty()) {
|
||||
const pokemonId = partyPokemon.id;
|
||||
const pokemonItems = scene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).pokemonId === pokemonId,
|
||||
(m): m is PokemonHeldItemModifier =>
|
||||
m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).pokemonId === pokemonId,
|
||||
true,
|
||||
) as PokemonHeldItemModifier[];
|
||||
);
|
||||
const revSeed = pokemonItems.find(
|
||||
i => i.type.name === i18next.t("modifierType:ModifierType.REVIVER_SEED.name"),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user