diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 111e5439b..dfa8d9acc 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1701,7 +1701,7 @@ export default class BattleScene extends SceneBase { }); } - tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferStack: boolean, playSound: boolean, instant?: boolean, ignoreUpdate?: boolean): Promise { + tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, playSound: boolean, transferQuantity: integer = 1, instant?: boolean, ignoreUpdate?: boolean): Promise { return new Promise(resolve => { const source = itemModifier.pokemonId ? itemModifier.getPokemon(target.scene) : null; const cancelled = new Utils.BooleanHolder(false); @@ -1717,14 +1717,15 @@ export default class BattleScene extends SceneBase { const maxStackCount = matchingModifier.getMaxStackCount(target.scene); if (matchingModifier.stackCount >= maxStackCount) return resolve(false); - const countTaken = transferStack ? Math.min(itemModifier.stackCount, maxStackCount - matchingModifier.stackCount) : 1; + const countTaken = Math.min(transferQuantity, itemModifier.stackCount, maxStackCount - matchingModifier.stackCount); itemModifier.stackCount -= countTaken; newItemModifier.stackCount = matchingModifier.stackCount + countTaken; - removeOld = !itemModifier.stackCount; - } else if (!transferStack) { - newItemModifier.stackCount = 1; - removeOld = !(--itemModifier.stackCount); + } else { + const countTaken = Math.min(transferQuantity, itemModifier.stackCount); + itemModifier.stackCount -= countTaken; + newItemModifier.stackCount = countTaken; } + removeOld = !itemModifier.stackCount; if (!removeOld || !source || this.removeModifier(itemModifier, !source.isPlayer())) { const addModifier = () => { if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) { diff --git a/src/data/ability.ts b/src/data/ability.ts index 0ff03ed67..555024575 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -1143,7 +1143,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr { const heldItems = this.getTargetHeldItems(defender).filter(i => i.getTransferrable(false)); if (heldItems.length) { const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; - pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => { + pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => { if (success) pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${defender.name}'s ${stolenItem.type.name}!`)); resolve(success); @@ -1231,7 +1231,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr { const heldItems = this.getTargetHeldItems(attacker).filter(i => i.getTransferrable(false)); if (heldItems.length) { const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; - pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => { + pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => { if (success) pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${attacker.name}'s ${stolenItem.type.name}!`)); resolve(success); @@ -2382,7 +2382,7 @@ export class PostBattleLootAbAttr extends PostBattleAbAttr { const postBattleLoot = pokemon.scene.currentBattle.postBattleLoot; if (postBattleLoot.length) { const randItem = Utils.randSeedItem(postBattleLoot); - if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, true, true)) { + if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, true, 1, true)) { postBattleLoot.splice(postBattleLoot.indexOf(randItem), 1); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` picked up\n${randItem.type.name}!`)); return true; diff --git a/src/data/move.ts b/src/data/move.ts index 3c99ad8c1..88bdfc438 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1233,7 +1233,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr { const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0); const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier(poolType) === highestItemTier); const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; - user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => { + user.scene.tryTransferHeldItemModifier(stolenItem, user, false).then(success => { if (success) user.scene.queueMessage(getPokemonMessage(user, ` stole\n${target.name}'s ${stolenItem.type.name}!`)); resolve(success); @@ -1280,7 +1280,7 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0); const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier(poolType) === highestItemTier); const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; - user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => { + user.scene.tryTransferHeldItemModifier(stolenItem, user, false).then(success => { if (success) user.scene.queueMessage(getPokemonMessage(user, ` knocked off\n${target.name}'s ${stolenItem.type.name}!`)); resolve(success); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 97d94bdba..3d85f6d1c 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -2818,7 +2818,7 @@ export class PlayerPokemon extends Pokemon { && (m as PokemonHeldItemModifier).pokemonId === pokemon.id, true) as PokemonHeldItemModifier[]; const transferModifiers: Promise[] = []; for (let modifier of fusedPartyMemberHeldModifiers) - transferModifiers.push(this.scene.tryTransferHeldItemModifier(modifier, this, true, false, true, true)); + transferModifiers.push(this.scene.tryTransferHeldItemModifier(modifier, this, false, modifier.getStackCount(), true, true)); Promise.allSettled(transferModifiers).then(() => { this.scene.updateModifiers(true, true).then(() => { this.scene.removePartyMemberModifiers(fusedPartyMemberIndex); diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 8a5fba17d..e55db6b10 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1801,7 +1801,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { } const randItemIndex = pokemon.randSeedInt(itemModifiers.length); const randItem = itemModifiers[randItemIndex]; - heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, false).then(success => { + heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false).then(success => { if (success) { transferredModifierTypes.push(randItem.type); itemModifiers.splice(randItemIndex, 1); diff --git a/src/phases.ts b/src/phases.ts index 123169021..d26eca902 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1416,7 +1416,7 @@ export class SwitchSummonPhase extends SummonPhase { const batonPassModifier = this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id) as SwitchEffectTransferModifier; if (batonPassModifier && !this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) - this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedPokemon, false, false); + this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedPokemon, false); } } if (switchedPokemon) { @@ -4427,14 +4427,12 @@ export class SelectModifierPhase extends BattlePhase { this.scene.playSound('buy'); } } else if (cursor === 1) { - this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, toSlotIndex: integer) => { + this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, itemQuantity: integer, toSlotIndex: integer) => { if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) { - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers)).then(() => { - const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier - && (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[]; - const itemModifier = itemModifiers[itemIndex]; - this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, true); - }); + const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier + && (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[]; + const itemModifier = itemModifiers[itemIndex]; + this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, itemQuantity); } else this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost(typeOptions, this.scene.lockModifierTiers)); }, PartyUiHandler.FilterItemMaxStacks); diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 8b497655a..424bc960a 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -55,7 +55,7 @@ export enum PartyOption { } export type PartySelectCallback = (cursor: integer, option: PartyOption) => void; -export type PartyModifierTransferSelectCallback = (fromCursor: integer, index: integer, toCursor?: integer) => void; +export type PartyModifierTransferSelectCallback = (fromCursor: integer, index: integer, itemQuantity?: integer, toCursor?: integer) => void; export type PartyModifierSpliceSelectCallback = (fromCursor: integer, toCursor?: integer) => void; export type PokemonSelectFilter = (pokemon: PlayerPokemon) => string; export type PokemonModifierTransferSelectFilter = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => string; @@ -85,6 +85,8 @@ export default class PartyUiHandler extends MessageUiHandler { private transferMode: boolean; private transferOptionCursor: integer; private transferCursor: integer; + private transferQuantities: integer[]; + private transferQuantitiesMax: integer[]; private lastCursor: integer = 0; private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback; @@ -218,14 +220,17 @@ export default class PartyUiHandler extends MessageUiHandler { let success = false; if (this.optionsMode) { + const option = this.options[this.optionsCursor] if (button === Button.ACTION) { - const option = this.options[this.optionsCursor]; const pokemon = this.scene.getParty()[this.cursor]; if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode && option !== PartyOption.CANCEL) { + const pokemon = this.scene.getParty()[this.cursor]; + const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier + && (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === pokemon.id) as PokemonHeldItemModifier[]; this.startTransfer(); this.clearOptions(); ui.playSelect(); - return true; + return true; } else if (this.partyUiMode === PartyUiMode.REMEMBER_MOVE_MODIFIER && option !== PartyOption.CANCEL) { let filterResult = (this.selectFilter as PokemonSelectFilter)(pokemon); if (filterResult === null) { @@ -255,7 +260,9 @@ export default class PartyUiHandler extends MessageUiHandler { this.clearOptions(); if (this.selectCallback) { if (option === PartyOption.TRANSFER) { - (this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.cursor); + if (this.transferCursor !== this.cursor) { + (this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.transferQuantities[this.transferOptionCursor], this.cursor); + } this.clearTransfer(); } else if (this.partyUiMode === PartyUiMode.SPLICE) { if (option === PartyOption.SPLICE) { @@ -348,6 +355,20 @@ export default class PartyUiHandler extends MessageUiHandler { return true; } else { switch (button) { + case Button.LEFT: + if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + this.transferQuantities[option] = this.transferQuantities[option] == 1 ? this.transferQuantitiesMax[option] : this.transferQuantities[option] - 1 + this.updateOptions() + success = this.setCursor(this.optionsCursor) + } + break; + case Button.RIGHT: + if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) { + this.transferQuantities[option] = this.transferQuantities[option] == this.transferQuantitiesMax[option] ? 1 : this.transferQuantities[option] + 1 + this.updateOptions() + success = this.setCursor(this.optionsCursor) + } + break; case Button.UP: success = this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1); break; @@ -359,6 +380,12 @@ export default class PartyUiHandler extends MessageUiHandler { } else { if (button === Button.ACTION) { if (this.cursor < 6) { + if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) { + const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier + && (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === this.scene.getParty()[this.cursor].id) as PokemonHeldItemModifier[] + this.transferQuantities = itemModifiers.map(item => item.getStackCount()) + this.transferQuantitiesMax = itemModifiers.map(item => item.getStackCount()) + } this.showOptions(); ui.playSelect(); } else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH) @@ -690,8 +717,8 @@ export default class PartyUiHandler extends MessageUiHandler { } else { const itemModifier = itemModifiers[option]; optionName = itemModifier.type.name; - if (itemModifier.stackCount > 1) - optionName += ` (${itemModifier.stackCount})`; + if (this.transferQuantitiesMax[option] > 1) + optionName += ` (${this.transferQuantities[option]})`; } const yCoord = -6 - 16 * o;