mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-01 14:02:18 +02:00
Reworked various effects that steal items
This commit is contained in:
parent
c607a73ebc
commit
b271dc724b
@ -2717,11 +2717,12 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to transfer a held item to another pokemon.
|
* Try to transfer a held item from source to target.
|
||||||
* If the recepient already has the maximum amount allowed for this item, the transfer is cancelled.
|
* If the recepient already has the maximum amount allowed for this item, the transfer is cancelled.
|
||||||
* The quantity to transfer is automatically capped at how much the recepient can take before reaching the maximum stack size for the item.
|
* The quantity to transfer is automatically capped at how much the recepient can take before reaching the maximum stack size for the item.
|
||||||
* A transfer that moves a quantity smaller than what is specified in the transferQuantity parameter is still considered successful.
|
* A transfer that moves a quantity smaller than what is specified in the transferQuantity parameter is still considered successful.
|
||||||
* @param heldItemId {@linkcode HeldItemId} item to transfer
|
* @param heldItemId {@linkcode HeldItemId} item to transfer
|
||||||
|
* @param source {@linkcode Pokemon} giver in this transfer
|
||||||
* @param target {@linkcode Pokemon} recepient in this transfer
|
* @param target {@linkcode Pokemon} recepient in this transfer
|
||||||
* @param playSound `true` to play a sound when transferring the item
|
* @param playSound `true` to play a sound when transferring the item
|
||||||
* @param transferQuantity How many items of the stack to transfer. Optional, defaults to `1`
|
* @param transferQuantity How many items of the stack to transfer. Optional, defaults to `1`
|
||||||
|
@ -35,7 +35,7 @@ import {
|
|||||||
} from "#app/data/moves/move";
|
} from "#app/data/moves/move";
|
||||||
import { allMoves } from "../data-lists";
|
import { allMoves } from "../data-lists";
|
||||||
import { ArenaTagSide } from "#app/data/arena-tag";
|
import { ArenaTagSide } from "#app/data/arena-tag";
|
||||||
import { BerryModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
import { BerryModifier, type PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
import { TerrainType } from "#app/data/terrain";
|
import { TerrainType } from "#app/data/terrain";
|
||||||
import {
|
import {
|
||||||
SpeciesFormChangeAbilityTrigger,
|
SpeciesFormChangeAbilityTrigger,
|
||||||
@ -91,6 +91,7 @@ import type Move from "#app/data/moves/move";
|
|||||||
import type { ArenaTrapTag, SuppressAbilitiesTag } from "#app/data/arena-tag";
|
import type { ArenaTrapTag, SuppressAbilitiesTag } from "#app/data/arena-tag";
|
||||||
import { noAbilityTypeOverrideMoves } from "../moves/invalid-moves";
|
import { noAbilityTypeOverrideMoves } from "../moves/invalid-moves";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
|
import { allHeldItems } from "#app/items/all-held-items";
|
||||||
|
|
||||||
export class BlockRecoilDamageAttr extends AbAttr {
|
export class BlockRecoilDamageAttr extends AbAttr {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -2540,17 +2541,11 @@ export class AllyStatMultiplierAbAttr extends AbAttr {
|
|||||||
* @extends AbAttr
|
* @extends AbAttr
|
||||||
*/
|
*/
|
||||||
export class ExecutedMoveAbAttr extends AbAttr {
|
export class ExecutedMoveAbAttr extends AbAttr {
|
||||||
canApplyExecutedMove(
|
canApplyExecutedMove(_pokemon: Pokemon, _simulated: boolean): boolean {
|
||||||
_pokemon: Pokemon,
|
|
||||||
_simulated: boolean,
|
|
||||||
): boolean {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyExecutedMove(
|
applyExecutedMove(_pokemon: Pokemon, _simulated: boolean): void {}
|
||||||
_pokemon: Pokemon,
|
|
||||||
_simulated: boolean,
|
|
||||||
): void {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2558,7 +2553,7 @@ export class ExecutedMoveAbAttr extends AbAttr {
|
|||||||
* @extends ExecutedMoveAbAttr
|
* @extends ExecutedMoveAbAttr
|
||||||
*/
|
*/
|
||||||
export class GorillaTacticsAbAttr extends ExecutedMoveAbAttr {
|
export class GorillaTacticsAbAttr extends ExecutedMoveAbAttr {
|
||||||
constructor(showAbility: boolean = false) {
|
constructor(showAbility = false) {
|
||||||
super(showAbility);
|
super(showAbility);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2575,7 +2570,7 @@ export class GorillaTacticsAbAttr extends ExecutedMoveAbAttr {
|
|||||||
|
|
||||||
export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
||||||
private stealCondition: PokemonAttackCondition | null;
|
private stealCondition: PokemonAttackCondition | null;
|
||||||
private stolenItem?: PokemonHeldItemModifier;
|
private stolenItem?: HeldItemId;
|
||||||
|
|
||||||
constructor(stealCondition?: PokemonAttackCondition) {
|
constructor(stealCondition?: PokemonAttackCondition) {
|
||||||
super();
|
super();
|
||||||
@ -2598,11 +2593,11 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
|||||||
hitResult < HitResult.NO_EFFECT &&
|
hitResult < HitResult.NO_EFFECT &&
|
||||||
(!this.stealCondition || this.stealCondition(pokemon, defender, move))
|
(!this.stealCondition || this.stealCondition(pokemon, defender, move))
|
||||||
) {
|
) {
|
||||||
const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferable);
|
const heldItems = defender.heldItemManager.getTransferableHeldItems();
|
||||||
if (heldItems.length) {
|
if (heldItems.length) {
|
||||||
// Ensure that the stolen item in testing is the same as when the effect is applied
|
// Ensure that the stolen item in testing is the same as when the effect is applied
|
||||||
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
||||||
if (globalScene.canTransferHeldItemModifier(this.stolenItem, pokemon)) {
|
if (globalScene.canTransferHeldItem(this.stolenItem, defender, pokemon)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2620,28 +2615,21 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
|||||||
_hitResult: HitResult,
|
_hitResult: HitResult,
|
||||||
_args: any[],
|
_args: any[],
|
||||||
): void {
|
): void {
|
||||||
const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferable);
|
const heldItems = defender.heldItemManager.getTransferableHeldItems();
|
||||||
if (!this.stolenItem) {
|
if (!this.stolenItem) {
|
||||||
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
||||||
}
|
}
|
||||||
if (globalScene.tryTransferHeldItemModifier(this.stolenItem, pokemon, false)) {
|
if (globalScene.tryTransferHeldItem(this.stolenItem, defender, pokemon, false)) {
|
||||||
globalScene.phaseManager.queueMessage(
|
globalScene.phaseManager.queueMessage(
|
||||||
i18next.t("abilityTriggers:postAttackStealHeldItem", {
|
i18next.t("abilityTriggers:postAttackStealHeldItem", {
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
defenderName: defender.name,
|
defenderName: defender.name,
|
||||||
stolenItemType: this.stolenItem.type.name,
|
stolenItemType: allHeldItems[this.stolenItem].name,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.stolenItem = undefined;
|
this.stolenItem = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
|
|
||||||
return globalScene.findModifiers(
|
|
||||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === target.id,
|
|
||||||
target.isPlayer(),
|
|
||||||
) as PokemonHeldItemModifier[];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
|
export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
|
||||||
@ -2762,7 +2750,7 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr {
|
|||||||
|
|
||||||
export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
||||||
private condition?: PokemonDefendCondition;
|
private condition?: PokemonDefendCondition;
|
||||||
private stolenItem?: PokemonHeldItemModifier;
|
private stolenItem?: HeldItemId;
|
||||||
|
|
||||||
constructor(condition?: PokemonDefendCondition) {
|
constructor(condition?: PokemonDefendCondition) {
|
||||||
super();
|
super();
|
||||||
@ -2780,10 +2768,10 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
|||||||
_args: any[],
|
_args: any[],
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) {
|
if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) {
|
||||||
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable);
|
const heldItems = attacker.heldItemManager.getTransferableHeldItems();
|
||||||
if (heldItems.length) {
|
if (heldItems.length) {
|
||||||
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
||||||
if (globalScene.canTransferHeldItemModifier(this.stolenItem, pokemon)) {
|
if (globalScene.canTransferHeldItem(this.stolenItem, attacker, pokemon)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2800,28 +2788,21 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
|||||||
_hitResult: HitResult,
|
_hitResult: HitResult,
|
||||||
_args: any[],
|
_args: any[],
|
||||||
): void {
|
): void {
|
||||||
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable);
|
const heldItems = attacker.heldItemManager.getTransferableHeldItems();
|
||||||
if (!this.stolenItem) {
|
if (!this.stolenItem) {
|
||||||
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)];
|
||||||
}
|
}
|
||||||
if (globalScene.tryTransferHeldItemModifier(this.stolenItem, pokemon, false)) {
|
if (globalScene.tryTransferHeldItem(this.stolenItem, attacker, pokemon, false)) {
|
||||||
globalScene.phaseManager.queueMessage(
|
globalScene.phaseManager.queueMessage(
|
||||||
i18next.t("abilityTriggers:postDefendStealHeldItem", {
|
i18next.t("abilityTriggers:postDefendStealHeldItem", {
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
attackerName: attacker.name,
|
attackerName: attacker.name,
|
||||||
stolenItemType: this.stolenItem.type.name,
|
stolenItemType: allHeldItems[this.stolenItem].name,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.stolenItem = undefined;
|
this.stolenItem = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
|
|
||||||
return globalScene.findModifiers(
|
|
||||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === target.id,
|
|
||||||
target.isPlayer(),
|
|
||||||
) as PokemonHeldItemModifier[];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -7782,7 +7763,7 @@ export function applyPreAttackAbAttrs(
|
|||||||
export function applyExecutedMoveAbAttrs(
|
export function applyExecutedMoveAbAttrs(
|
||||||
attrType: Constructor<ExecutedMoveAbAttr>,
|
attrType: Constructor<ExecutedMoveAbAttr>,
|
||||||
pokemon: Pokemon,
|
pokemon: Pokemon,
|
||||||
simulated: boolean = false,
|
simulated = false,
|
||||||
...args: any[]
|
...args: any[]
|
||||||
): void {
|
): void {
|
||||||
applyAbAttrsInternal<ExecutedMoveAbAttr>(
|
applyAbAttrsInternal<ExecutedMoveAbAttr>(
|
||||||
|
@ -2559,16 +2559,18 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const heldItems = this.getTargetHeldItems(target).filter((i) => i.isTransferable);
|
const heldItems = target.heldItemManager.getTransferableHeldItems();
|
||||||
if (!heldItems.length) {
|
if (!heldItems.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const poolType = target.isPlayer() ? ModifierPoolType.PLAYER : target.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD;
|
const stolenItem = heldItems[user.randBattleSeedInt(heldItems.length)];
|
||||||
const highestItemTier = heldItems.map((m) => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier!, highestTier), 0); // TODO: is the bang after tier correct?
|
|
||||||
const tierHeldItems = heldItems.filter((m) => m.type.getOrInferTier(poolType) === highestItemTier);
|
// const poolType = target.isPlayer() ? ModifierPoolType.PLAYER : target.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD;
|
||||||
const stolenItem = tierHeldItems[user.randBattleSeedInt(tierHeldItems.length)];
|
// const highestItemTier = heldItems.map((m) => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier!, highestTier), 0); // TODO: is the bang after tier correct?
|
||||||
if (!globalScene.tryTransferHeldItemModifier(stolenItem, user, false)) {
|
// const tierHeldItems = heldItems.filter((m) => m.type.getOrInferTier(poolType) === highestItemTier);
|
||||||
|
// const stolenItem = tierHeldItems[user.randBattleSeedInt(tierHeldItems.length)];
|
||||||
|
if (!globalScene.tryTransferHeldItem(stolenItem, target, user, false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2576,18 +2578,13 @@ export class StealHeldItemChanceAttr 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.heldItemManager.getTransferableHeldItems();
|
||||||
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.heldItemManager.getTransferableHeldItems();
|
||||||
return heldItems.length ? -5 : 0;
|
return heldItems.length ? -5 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,24 @@ export class PokemonItemManager {
|
|||||||
return Object.keys(this.heldItems).map(k => Number(k));
|
return Object.keys(this.heldItems).map(k => Number(k));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTransferableHeldItems(): number[] {
|
||||||
|
return Object.keys(this.heldItems)
|
||||||
|
.filter(k => allHeldItems[k].isTransferable)
|
||||||
|
.map(k => Number(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
getStealableHeldItems(): number[] {
|
||||||
|
return Object.keys(this.heldItems)
|
||||||
|
.filter(k => allHeldItems[k].isStealable)
|
||||||
|
.map(k => Number(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
getSuppressableHeldItems(): number[] {
|
||||||
|
return Object.keys(this.heldItems)
|
||||||
|
.filter(k => allHeldItems[k].isSuppressable)
|
||||||
|
.map(k => Number(k));
|
||||||
|
}
|
||||||
|
|
||||||
hasItem(itemType: HeldItemId): boolean {
|
hasItem(itemType: HeldItemId): boolean {
|
||||||
return itemType in this.heldItems;
|
return itemType in this.heldItems;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ export abstract class ItemTransferHeldItem extends HeldItem {
|
|||||||
|
|
||||||
// TODO: Change this logic to use held items
|
// TODO: Change this logic to use held items
|
||||||
const transferredModifierTypes: HeldItemId[] = [];
|
const transferredModifierTypes: HeldItemId[] = [];
|
||||||
const heldItems = targetPokemon.heldItemManager.getHeldItemKeys();
|
const heldItems = targetPokemon.heldItemManager.getTransferableHeldItems();
|
||||||
|
|
||||||
for (let i = 0; i < transferredItemCount; i++) {
|
for (let i = 0; i < transferredItemCount; i++) {
|
||||||
if (!heldItems.length) {
|
if (!heldItems.length) {
|
||||||
@ -56,7 +56,7 @@ export abstract class ItemTransferHeldItem extends HeldItem {
|
|||||||
const randItemIndex = pokemon.randBattleSeedInt(heldItems.length);
|
const randItemIndex = pokemon.randBattleSeedInt(heldItems.length);
|
||||||
const randItem = heldItems[randItemIndex];
|
const randItem = heldItems[randItemIndex];
|
||||||
// TODO: Fix this after updating the various methods in battle-scene.ts
|
// TODO: Fix this after updating the various methods in battle-scene.ts
|
||||||
if (globalScene.tryTransferHeldItemModifier(randItem, pokemon, false)) {
|
if (globalScene.tryTransferHeldItem(randItem, targetPokemon, pokemon, false)) {
|
||||||
transferredModifierTypes.push(randItem);
|
transferredModifierTypes.push(randItem);
|
||||||
heldItems.splice(randItemIndex, 1);
|
heldItems.splice(randItemIndex, 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user