mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-29 13:02:46 +02:00
Improved item transfer
This commit is contained in:
parent
928d8a8f97
commit
ff73c5b038
@ -2759,8 +2759,9 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
const countTaken = Math.min(transferQuantity, itemStack, maxStackCount - matchingItemStack);
|
const countTaken = Math.min(transferQuantity, itemStack, maxStackCount - matchingItemStack);
|
||||||
|
|
||||||
|
const data = source.heldItemManager[heldItemId].data;
|
||||||
source.heldItemManager.remove(heldItemId, countTaken);
|
source.heldItemManager.remove(heldItemId, countTaken);
|
||||||
target.heldItemManager.add(heldItemId, countTaken);
|
target.heldItemManager.add(heldItemId, countTaken, data);
|
||||||
|
|
||||||
if (source.heldItemManager.getStack(heldItemId) === 0 && itemLost) {
|
if (source.heldItemManager.getStack(heldItemId) === 0 && itemLost) {
|
||||||
applyPostItemLostAbAttrs(PostItemLostAbAttr, source, false);
|
applyPostItemLostAbAttrs(PostItemLostAbAttr, source, false);
|
||||||
|
@ -70,7 +70,6 @@ import { allAbilities, allMoves } from "../data-lists";
|
|||||||
import {
|
import {
|
||||||
BerryModifier,
|
BerryModifier,
|
||||||
PokemonHeldItemModifier,
|
PokemonHeldItemModifier,
|
||||||
PokemonMultiHitModifier,
|
|
||||||
PreserveBerryModifier,
|
PreserveBerryModifier,
|
||||||
} from "../../modifier/modifier";
|
} from "../../modifier/modifier";
|
||||||
import type { BattlerIndex } from "../../battle";
|
import type { BattlerIndex } from "../../battle";
|
||||||
@ -122,8 +121,10 @@ 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 { TrainerVariant } from "#app/field/trainer";
|
||||||
import { SelectBiomePhase } from "#app/phases/select-biome-phase";
|
import { SelectBiomePhase } from "#app/phases/select-biome-phase";
|
||||||
import { 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";
|
||||||
|
import { berryTypeToHeldItem } from "#app/items/held-items/berry";
|
||||||
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
|
|
||||||
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
|
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
|
||||||
type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean;
|
type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean;
|
||||||
@ -816,7 +817,7 @@ export default class Move implements Localizable {
|
|||||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, typeChangeHolder, typeChangeMovePowerMultiplier);
|
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, typeChangeHolder, typeChangeMovePowerMultiplier);
|
||||||
|
|
||||||
const sourceTeraType = source.getTeraType();
|
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) && !source.heldItemManager.hasItem(HeldItemId.MULTI_LENS)) {
|
||||||
power.value = 60;
|
power.value = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,7 +920,7 @@ export default class Move implements Localizable {
|
|||||||
* Returns `true` if this move can be given additional strikes
|
* Returns `true` if this move can be given additional strikes
|
||||||
* by enhancing effects.
|
* by enhancing effects.
|
||||||
* Currently used for {@link https://bulbapedia.bulbagarden.net/wiki/Parental_Bond_(Ability) | Parental Bond}
|
* Currently used for {@link https://bulbapedia.bulbagarden.net/wiki/Parental_Bond_(Ability) | Parental Bond}
|
||||||
* and {@linkcode PokemonMultiHitModifier | Multi-Lens}.
|
* and {@linkcode MultiHitHeldItem | Multi-Lens}.
|
||||||
* @param user The {@linkcode Pokemon} using the move
|
* @param user The {@linkcode Pokemon} using the move
|
||||||
* @param restrictSpread `true` if the enhancing effect
|
* @param restrictSpread `true` if the enhancing effect
|
||||||
* should not affect multi-target moves (default `false`)
|
* should not affect multi-target moves (default `false`)
|
||||||
@ -1506,7 +1507,7 @@ export class TargetHalfHpDamageAttr extends FixedDamageAttr {
|
|||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
// first, determine if the hit is coming from multi lens or not
|
// first, determine if the hit is coming from multi lens or not
|
||||||
const lensCount = user.getHeldItems().find(i => i instanceof PokemonMultiHitModifier)?.getStackCount() ?? 0;
|
const lensCount = user.heldItemManager.getStack(HeldItemId.MULTI_LENS);
|
||||||
if (lensCount <= 0) {
|
if (lensCount <= 0) {
|
||||||
// no multi lenses; we can just halve the target's hp and call it a day
|
// no multi lenses; we can just halve the target's hp and call it a day
|
||||||
(args[0] as NumberHolder).value = toDmgValue(target.hp / 2);
|
(args[0] as NumberHolder).value = toDmgValue(target.hp / 2);
|
||||||
@ -2574,7 +2575,12 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:stoleItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name }));
|
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:stoleItem",
|
||||||
|
{ pokemonName: getPokemonNameWithAffix(user),
|
||||||
|
targetName: getPokemonNameWithAffix(target),
|
||||||
|
itemName: allHeldItems[stolenItem].name
|
||||||
|
}
|
||||||
|
));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2630,10 +2636,10 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
// Considers entire transferrable item pool by default (Knock Off).
|
// Considers entire transferrable item pool by default (Knock Off).
|
||||||
// Otherwise only consider berries (Incinerate).
|
// Otherwise only consider berries (Incinerate).
|
||||||
let heldItems = this.getTargetHeldItems(target).filter(i => i.isTransferable);
|
let heldItems = target.heldItemManager.getTransferableHeldItems();
|
||||||
|
|
||||||
if (this.berriesOnly) {
|
if (this.berriesOnly) {
|
||||||
heldItems = heldItems.filter(m => m instanceof BerryModifier && m.pokemonId === target.id, target.isPlayer());
|
heldItems = heldItems.filter(m => m in Object.values(berryTypeToHeldItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!heldItems.length) {
|
if (!heldItems.length) {
|
||||||
@ -2647,9 +2653,11 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
|
|||||||
globalScene.updateModifiers(target.isPlayer());
|
globalScene.updateModifiers(target.isPlayer());
|
||||||
|
|
||||||
if (this.berriesOnly) {
|
if (this.berriesOnly) {
|
||||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:incineratedItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name }));
|
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:incineratedItem",
|
||||||
|
{ pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: allHeldItems[removedItem].name }));
|
||||||
} else {
|
} else {
|
||||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:knockedOffItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name }));
|
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:knockedOffItem",
|
||||||
|
{ pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: allHeldItems[removedItem].name }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -7932,14 +7940,14 @@ const failIfLastInPartyCondition: MoveConditionFunc = (user: Pokemon, target: Po
|
|||||||
|
|
||||||
const failIfGhostTypeCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => !target.isOfType(PokemonType.GHOST);
|
const failIfGhostTypeCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => !target.isOfType(PokemonType.GHOST);
|
||||||
|
|
||||||
const failIfNoTargetHeldItemsCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.getHeldItems().filter(i => i.isTransferable)?.length > 0;
|
const failIfNoTargetHeldItemsCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.heldItemManager.getTransferableHeldItems().length > 0;
|
||||||
|
|
||||||
const attackedByItemMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => {
|
const attackedByItemMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => {
|
||||||
const heldItems = target.getHeldItems().filter(i => i.isTransferable);
|
const heldItems = target.heldItemManager.getTransferableHeldItems();
|
||||||
if (heldItems.length === 0) {
|
if (heldItems.length === 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const itemName = heldItems[0]?.type?.name ?? "item";
|
const itemName = allHeldItems[heldItems[0]].name ?? "item";
|
||||||
const message: string = i18next.t("moveTriggers:attackedByItem", { pokemonName: getPokemonNameWithAffix(target), itemName: itemName });
|
const message: string = i18next.t("moveTriggers:attackedByItem", { pokemonName: getPokemonNameWithAffix(target), itemName: itemName });
|
||||||
return message;
|
return message;
|
||||||
};
|
};
|
||||||
@ -9123,7 +9131,7 @@ export function initMoves() {
|
|||||||
.condition((user, target, move) => !target.status && !target.isSafeguarded(user))
|
.condition((user, target, move) => !target.status && !target.isSafeguarded(user))
|
||||||
.reflectable(),
|
.reflectable(),
|
||||||
new AttackMove(MoveId.KNOCK_OFF, PokemonType.DARK, MoveCategory.PHYSICAL, 65, 100, 20, -1, 0, 3)
|
new AttackMove(MoveId.KNOCK_OFF, PokemonType.DARK, MoveCategory.PHYSICAL, 65, 100, 20, -1, 0, 3)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getHeldItems().filter(i => i.isTransferable).length > 0 ? 1.5 : 1)
|
.attr(MovePowerMultiplierAttr, (user, target, move) => target.heldItemManager.getTransferableHeldItems().length > 0 ? 1.5 : 1)
|
||||||
.attr(RemoveHeldItemAttr, false)
|
.attr(RemoveHeldItemAttr, false)
|
||||||
.edgeCase(),
|
.edgeCase(),
|
||||||
// Should not be able to remove held item if user faints due to Rough Skin, Iron Barbs, etc.
|
// Should not be able to remove held item if user faints due to Rough Skin, Iron Barbs, etc.
|
||||||
@ -9838,7 +9846,7 @@ export function initMoves() {
|
|||||||
.condition((user, target, move) => !target.turnData.acted)
|
.condition((user, target, move) => !target.turnData.acted)
|
||||||
.attr(ForceLastAttr),
|
.attr(ForceLastAttr),
|
||||||
new AttackMove(MoveId.ACROBATICS, PokemonType.FLYING, MoveCategory.PHYSICAL, 55, 100, 15, -1, 0, 5)
|
new AttackMove(MoveId.ACROBATICS, PokemonType.FLYING, MoveCategory.PHYSICAL, 55, 100, 15, -1, 0, 5)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => Math.max(1, 2 - 0.2 * user.getHeldItems().filter(i => i.isTransferable).reduce((v, m) => v + m.stackCount, 0))),
|
.attr(MovePowerMultiplierAttr, (user, target, move) => Math.max(1, 2 - 0.2 * user.heldItemManager.getTransferableHeldItems().reduce((v, m) => v + user.heldItemManager.getStack(m), 0))),
|
||||||
new StatusMove(MoveId.REFLECT_TYPE, PokemonType.NORMAL, -1, 15, -1, 0, 5)
|
new StatusMove(MoveId.REFLECT_TYPE, PokemonType.NORMAL, -1, 15, -1, 0, 5)
|
||||||
.ignoresSubstitute()
|
.ignoresSubstitute()
|
||||||
.attr(CopyTypeAttr),
|
.attr(CopyTypeAttr),
|
||||||
|
@ -4,11 +4,13 @@ import type { FormChangeItem } from "#app/data/pokemon-forms";
|
|||||||
import type { BASE_STAT_TOTAL_DATA } from "#app/items/held-items/base-stat-total";
|
import type { BASE_STAT_TOTAL_DATA } from "#app/items/held-items/base-stat-total";
|
||||||
import type { BASE_STAT_FLAT_DATA } from "#app/items/held-items/base-stat-flat";
|
import type { BASE_STAT_FLAT_DATA } from "#app/items/held-items/base-stat-flat";
|
||||||
|
|
||||||
|
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?: BASE_STAT_TOTAL_DATA | BASE_STAT_FLAT_DATA;
|
data?: HELD_ITEM_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
type HeldItemPropertyMap = {
|
type HeldItemPropertyMap = {
|
||||||
@ -66,14 +68,14 @@ export class PokemonItemManager {
|
|||||||
return itemType in this.heldItems ? this.heldItems[itemType].stack : 0;
|
return itemType in this.heldItems ? this.heldItems[itemType].stack : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
add(itemType: HeldItemId, addStack = 1) {
|
add(itemType: HeldItemId, addStack = 1, data?: HELD_ITEM_DATA) {
|
||||||
const maxStack = allHeldItems[itemType].getMaxStackCount();
|
const maxStack = allHeldItems[itemType].getMaxStackCount();
|
||||||
|
|
||||||
if (this.hasItem(itemType)) {
|
if (this.hasItem(itemType)) {
|
||||||
// TODO: We may want an error message of some kind instead
|
// TODO: We may want an error message of some kind instead
|
||||||
this.heldItems[itemType].stack = Math.min(this.heldItems[itemType].stack + addStack, maxStack);
|
this.heldItems[itemType].stack = Math.min(this.heldItems[itemType].stack + addStack, maxStack);
|
||||||
} else {
|
} else {
|
||||||
this.heldItems[itemType] = { stack: Math.min(addStack, maxStack), disabled: false };
|
this.heldItems[itemType] = { stack: Math.min(addStack, maxStack), disabled: false, data: data };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,6 @@ import {
|
|||||||
ShinyRateBoosterModifier,
|
ShinyRateBoosterModifier,
|
||||||
TempStatStageBoosterModifier,
|
TempStatStageBoosterModifier,
|
||||||
TempCritBoosterModifier,
|
TempCritBoosterModifier,
|
||||||
EvoTrackerModifier,
|
|
||||||
} from "#app/modifier/modifier";
|
} from "#app/modifier/modifier";
|
||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import { Gender } from "#app/data/gender";
|
import { Gender } from "#app/data/gender";
|
||||||
@ -242,7 +241,7 @@ import { loadMoveAnimations } from "#app/sprites/pokemon-asset-loader";
|
|||||||
import { PokemonItemManager } from "./pokemon-held-item-manager";
|
import { PokemonItemManager } from "./pokemon-held-item-manager";
|
||||||
import { applyHeldItems } from "#app/items/all-held-items";
|
import { applyHeldItems } from "#app/items/all-held-items";
|
||||||
import { ITEM_EFFECT } from "#app/items/held-item";
|
import { ITEM_EFFECT } from "#app/items/held-item";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
|
|
||||||
export enum LearnMoveSituation {
|
export enum LearnMoveSituation {
|
||||||
MISC,
|
MISC,
|
||||||
@ -4375,7 +4374,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.setScale(this.getSpriteScale());
|
this.setScale(this.getSpriteScale());
|
||||||
this.loadAssets().then(() => {
|
this.loadAssets().then(() => {
|
||||||
this.calculateStats();
|
this.calculateStats();
|
||||||
globalScene.updateModifiers(this.isPlayer(), true);
|
globalScene.updateModifiers(this.isPlayer());
|
||||||
Promise.all([this.updateInfo(), globalScene.updateFieldScale()]).then(() => resolve());
|
Promise.all([this.updateInfo(), globalScene.updateFieldScale()]).then(() => resolve());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -5801,9 +5800,9 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
if (preEvolution.speciesId === SpeciesId.GIMMIGHOUL) {
|
if (preEvolution.speciesId === SpeciesId.GIMMIGHOUL) {
|
||||||
const evotracker = this.getHeldItems().filter(m => m instanceof EvoTrackerModifier)[0] ?? null;
|
const evotracker = this.heldItemManager.hasItem(HeldItemId.GIMMIGHOUL_EVO_TRACKER);
|
||||||
if (evotracker) {
|
if (evotracker) {
|
||||||
globalScene.removeModifier(evotracker);
|
this.heldItemManager.remove(HeldItemId.GIMMIGHOUL_EVO_TRACKER, 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!globalScene.gameMode.isDaily || this.metBiome > -1) {
|
if (!globalScene.gameMode.isDaily || this.metBiome > -1) {
|
||||||
@ -5911,7 +5910,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
const updateAndResolve = () => {
|
const updateAndResolve = () => {
|
||||||
this.loadAssets().then(() => {
|
this.loadAssets().then(() => {
|
||||||
this.calculateStats();
|
this.calculateStats();
|
||||||
globalScene.updateModifiers(true, true);
|
globalScene.updateModifiers(true);
|
||||||
this.updateInfo(true).then(() => resolve());
|
this.updateInfo(true).then(() => resolve());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -5983,7 +5982,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
true,
|
true,
|
||||||
) as PokemonHeldItemModifier[];
|
) as PokemonHeldItemModifier[];
|
||||||
for (const modifier of fusedPartyMemberHeldModifiers) {
|
for (const modifier of fusedPartyMemberHeldModifiers) {
|
||||||
globalScene.tryTransferHeldItemModifier(modifier, this, false, modifier.getStackCount(), true, true, false);
|
globalScene.tryTransferHeldItem(modifier, pokemon, this, false, modifier.getStackCount(), true, false);
|
||||||
}
|
}
|
||||||
globalScene.updateModifiers(true);
|
globalScene.updateModifiers(true);
|
||||||
globalScene.getPlayerParty().splice(fusedPartyMemberIndex, 1)[0];
|
globalScene.getPlayerParty().splice(fusedPartyMemberIndex, 1)[0];
|
||||||
|
Loading…
Reference in New Issue
Block a user