From 316a759267340d42b44def849a534ccf8f2e13b4 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Mon, 5 Aug 2024 18:34:33 -0400 Subject: [PATCH 01/27] Add English Trick battler tags --- src/locales/en/battle.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/locales/en/battle.ts b/src/locales/en/battle.ts index 12a0f2c99c6..23e69f4a3b6 100644 --- a/src/locales/en/battle.ts +++ b/src/locales/en/battle.ts @@ -155,5 +155,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; From bbb693fe99954882e609e5785d4440e3cb905096 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Mon, 5 Aug 2024 18:35:27 -0400 Subject: [PATCH 02/27] Implement Trick --- src/data/move.ts | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/data/move.ts b/src/data/move.ts index a00d81e5980..ca35a8a0b6a 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5882,6 +5882,51 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr { } } +/** + * Attribute used for transferring items between a user Pokemon and target Pokemon + */ +export class SwapHeldItemsAttr extends MoveEffectAttr { + /** + * A random item is taken from user and given to target, and a random item is taken from target and given to user + * @param {Pokemon} user Pokemon that used the move + * @param {Pokemon} target Enemy Pokemon + * @param {Move} move Unused + * @param {any[]} args Unused + * @returns {boolean} Returns true if an item swap occured, false if not + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + + const targetHeldItems = target.getHeldItems().filter(i => i.isTransferrable); + const userHeldItems = user.getHeldItems().filter(i => i.isTransferrable); + + if (!user.isPlayer() || target.hasAbility(Abilities.STICKY_HOLD) || (!userHeldItems.length && !targetHeldItems.length)) { + user.scene.queueMessage(i18next.t("battle:attackFailed")); + return false; + } + + user.scene.queueMessage(i18next.t("battle:battlerTagsTrickOnSwap", { + pokemonNameWithAffix: getPokemonNameWithAffix(user), + })); + + if (targetHeldItems.length) { + const targetItemToSwap = targetHeldItems[target.randSeedInt(targetHeldItems.length)]; + user.scene.tryTransferHeldItemModifier(targetItemToSwap, user, false); + } + + if (userHeldItems.length) { + const userItemToSwap = userHeldItems[user.randSeedInt(userHeldItems.length)]; + target.scene.tryTransferHeldItemModifier(userItemToSwap, target, false); + + user.scene.queueMessage(i18next.t("battle:battlerTagsTrickFoeNewItem", { + pokemonNameWithAffix: getPokemonNameWithAffix(target), + itemName: userItemToSwap.type.name, + })); + } + + return true; + } +} + const unknownTypeCondition: MoveConditionFunc = (user, target, move) => !user.getTypes().includes(Type.UNKNOWN); export type MoveTargetSet = { @@ -6719,7 +6764,7 @@ export function initMoves() { .attr(AddBattlerTagAttr, BattlerTagType.HELPING_HAND) .target(MoveTarget.NEAR_ALLY), new StatusMove(Moves.TRICK, Type.PSYCHIC, 100, 10, -1, 0, 3) - .unimplemented(), + .attr(SwapHeldItemsAttr), new StatusMove(Moves.ROLE_PLAY, Type.PSYCHIC, -1, 10, -1, 0, 3) .attr(AbilityCopyAttr), new SelfStatusMove(Moves.WISH, Type.NORMAL, -1, 10, -1, 0, 3) From 094781c38c94073642ccd88f8ecd2822fde852d7 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Tue, 6 Aug 2024 02:13:30 -0400 Subject: [PATCH 03/27] Add placeholder Trick battler tags for remaining languages --- src/locales/de/battle.ts | 4 +++- src/locales/es/battle.ts | 4 +++- src/locales/fr/battle.ts | 4 +++- src/locales/it/battle.ts | 4 +++- src/locales/ko/battle.ts | 2 ++ src/locales/pt_BR/battle.ts | 2 ++ src/locales/zh_CN/battle.ts | 4 +++- src/locales/zh_TW/battle.ts | 4 +++- 8 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/locales/de/battle.ts b/src/locales/de/battle.ts index a9686da7524..024fe4b558e 100644 --- a/src/locales/de/battle.ts +++ b/src/locales/de/battle.ts @@ -155,5 +155,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} wurde durch {{moveName}} verletzt!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} nimmt einen Teil seiner KP und legt einen Fluch auf {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} wurde durch den Fluch verletzt!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/es/battle.ts b/src/locales/es/battle.ts index 7f29060c5d3..762468a109d 100644 --- a/src/locales/es/battle.ts +++ b/src/locales/es/battle.ts @@ -155,5 +155,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/fr/battle.ts b/src/locales/fr/battle.ts index 861dc6fd73c..bf1733b0606 100644 --- a/src/locales/fr/battle.ts +++ b/src/locales/fr/battle.ts @@ -155,5 +155,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} est blessé\npar la capacité {{moveName}} !", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} sacrifie des PV\net lance une malédiction sur {{pokemonName}} !", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} est touché par la malédiction !", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/it/battle.ts b/src/locales/it/battle.ts index 954f52e4a7f..0d6f11845b0 100644 --- a/src/locales/it/battle.ts +++ b/src/locales/it/battle.ts @@ -155,5 +155,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} viene colpito da {{moveName}}!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} ha sacrificato metà dei suoi PS per\nlanciare una maledizione su {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} subisce la maledizione!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/ko/battle.ts b/src/locales/ko/battle.ts index 10f3e1b5853..03e44ef49f6 100644 --- a/src/locales/ko/battle.ts +++ b/src/locales/ko/battle.ts @@ -156,4 +156,6 @@ export const battle: SimpleTranslationEntries = { "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}[[는]] 자신의 체력을 깎아서\n{{pokemonName}}에게 저주를 걸었다!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}[[는]]\n저주받고 있다!", "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}[[는]]\n{{stockpiledCount}}개 비축했다!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/pt_BR/battle.ts b/src/locales/pt_BR/battle.ts index 824b069f0a4..1eaf022d6d0 100644 --- a/src/locales/pt_BR/battle.ts +++ b/src/locales/pt_BR/battle.ts @@ -156,4 +156,6 @@ export const battle: SimpleTranslationEntries = { "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cortou seus PS pela metade e amaldiçoou {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} foi ferido pelo Curse!", "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} estocou {{stockpiledCount}}!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/zh_CN/battle.ts b/src/locales/zh_CN/battle.ts index b07cb79e258..6aede62525d 100644 --- a/src/locales/zh_CN/battle.ts +++ b/src/locales/zh_CN/battle.ts @@ -147,5 +147,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}}\n受到了{{moveName}}的伤害!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}削减了自己的体力,\n并诅咒了{{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}\n正受到诅咒!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}蓄力了{{stockpiledCount}}次!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}蓄力了{{stockpiledCount}}次!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/zh_TW/battle.ts b/src/locales/zh_TW/battle.ts index 4673474d313..24d4334f6d8 100644 --- a/src/locales/zh_TW/battle.ts +++ b/src/locales/zh_TW/battle.ts @@ -144,5 +144,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} 受到了{{moveName}}的傷害!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}削減了自己的體力,並詛咒了{{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}正受到詛咒!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; From 261d9813d849756005f7ddf0e8e95ef5c43d2593 Mon Sep 17 00:00:00 2001 From: Eucalyptus <88509866+eucalyptusJ@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:14:19 -0400 Subject: [PATCH 04/27] Update src/locales/fr/battle.ts Co-authored-by: Lugiad' --- src/locales/fr/battle.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locales/fr/battle.ts b/src/locales/fr/battle.ts index bf1733b0606..45e3ebeedae 100644 --- a/src/locales/fr/battle.ts +++ b/src/locales/fr/battle.ts @@ -155,7 +155,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} est blessé\npar la capacité {{moveName}} !", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} sacrifie des PV\net lance une malédiction sur {{pokemonName}} !", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} est touché par la malédiction !", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} utilise\nla capacité Stockage {{stockpiledCount}} fois !", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} échange\nun objet avec sa cible !", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtient\nl’objet {{itemName}} !" } as const; From d7e700cfaf89ba0315409150f7a689f40e90b036 Mon Sep 17 00:00:00 2001 From: Eucalyptus <88509866+eucalyptusJ@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:14:27 -0400 Subject: [PATCH 05/27] Update src/locales/de/battle.ts Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> --- src/locales/de/battle.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locales/de/battle.ts b/src/locales/de/battle.ts index 024fe4b558e..b2d2d668b3f 100644 --- a/src/locales/de/battle.ts +++ b/src/locales/de/battle.ts @@ -155,7 +155,7 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} wurde durch {{moveName}} verletzt!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} nimmt einen Teil seiner KP und legt einen Fluch auf {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} wurde durch den Fluch verletzt!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} hortet {{stockpiledCount}}!", + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} tauscht Items mit dem Ziel!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} erhält {{itemName}}." } as const; From 2bea2ed5dbf591e30f7b7a60b8adf4c2156fb449 Mon Sep 17 00:00:00 2001 From: Eucalyptus <88509866+eucalyptusJ@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:14:33 -0400 Subject: [PATCH 06/27] Update src/locales/pt_BR/battle.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Ricardo Fleury Oliveira --- src/locales/pt_BR/battle.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/pt_BR/battle.ts b/src/locales/pt_BR/battle.ts index 1eaf022d6d0..d8d26def7d1 100644 --- a/src/locales/pt_BR/battle.ts +++ b/src/locales/pt_BR/battle.ts @@ -156,6 +156,6 @@ export const battle: SimpleTranslationEntries = { "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cortou seus PS pela metade e amaldiçoou {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} foi ferido pelo Curse!", "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} estocou {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} trocou de itens com seu alvo!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obteve um(a) {{itemName}}." } as const; From 2ae2a9e0e620744f612ba31a61a8a57e5656ecfe Mon Sep 17 00:00:00 2001 From: Eucalyptus <88509866+eucalyptusJ@users.noreply.github.com> Date: Tue, 6 Aug 2024 21:39:25 -0400 Subject: [PATCH 07/27] Update src/locales/ko/battle.ts Co-authored-by: Enoch --- src/locales/ko/battle.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/ko/battle.ts b/src/locales/ko/battle.ts index 03e44ef49f6..ec22f5f95f5 100644 --- a/src/locales/ko/battle.ts +++ b/src/locales/ko/battle.ts @@ -156,6 +156,6 @@ export const battle: SimpleTranslationEntries = { "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}[[는]] 자신의 체력을 깎아서\n{{pokemonName}}에게 저주를 걸었다!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}[[는]]\n저주받고 있다!", "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}[[는]]\n{{stockpiledCount}}개 비축했다!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}}[[는]] 서로의\n도구를 교체했다!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}}[[는]]\n{{itemName}}[[를]] 손에 넣었다!" } as const; From 7af542bd9d80cfb8a3fac79c790f88eac14748fc Mon Sep 17 00:00:00 2001 From: Eucalyptus <88509866+eucalyptusJ@users.noreply.github.com> Date: Tue, 6 Aug 2024 21:39:34 -0400 Subject: [PATCH 08/27] Update src/locales/zh_TW/battle.ts Co-authored-by: mercurius-00 <80205689+mercurius-00@users.noreply.github.com> --- src/locales/zh_TW/battle.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/zh_TW/battle.ts b/src/locales/zh_TW/battle.ts index 24d4334f6d8..dd7063568c2 100644 --- a/src/locales/zh_TW/battle.ts +++ b/src/locales/zh_TW/battle.ts @@ -145,6 +145,6 @@ export const battle: SimpleTranslationEntries = { "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}削減了自己的體力,並詛咒了{{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}正受到詛咒!", "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}}\n互換了各自的道具!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}}\n獲得了{{itemName}}!" } as const; From 8a1c7ca60487281a2acf3335f8779b9735423424 Mon Sep 17 00:00:00 2001 From: Eucalyptus <88509866+eucalyptusJ@users.noreply.github.com> Date: Tue, 6 Aug 2024 21:39:41 -0400 Subject: [PATCH 09/27] Update src/locales/zh_CN/battle.ts Co-authored-by: mercurius-00 <80205689+mercurius-00@users.noreply.github.com> --- src/locales/zh_CN/battle.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/zh_CN/battle.ts b/src/locales/zh_CN/battle.ts index 6aede62525d..f993ddc192e 100644 --- a/src/locales/zh_CN/battle.ts +++ b/src/locales/zh_CN/battle.ts @@ -148,6 +148,6 @@ export const battle: SimpleTranslationEntries = { "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}削减了自己的体力,\n并诅咒了{{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}\n正受到诅咒!", "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}蓄力了{{stockpiledCount}}次!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}}\n互换了各自的道具!", + "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}}\n获得了{{itemName}}!" } as const; From eac4bef886a944ecdaf4eb6bab093453766a7307 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Wed, 7 Aug 2024 03:33:06 -0400 Subject: [PATCH 10/27] Move Trick locales to move-trigger --- src/data/move.ts | 4 ++-- src/locales/de/battle.ts | 4 +--- src/locales/de/move-trigger.ts | 2 ++ src/locales/en/battle.ts | 4 +--- src/locales/en/move-trigger.ts | 2 ++ src/locales/es/battle.ts | 4 +--- src/locales/es/move-trigger.ts | 2 ++ src/locales/fr/battle.ts | 4 +--- src/locales/fr/move-trigger.ts | 2 ++ src/locales/it/battle.ts | 4 +--- src/locales/it/move-trigger.ts | 2 ++ src/locales/ko/battle.ts | 4 +--- src/locales/ko/move-trigger.ts | 2 ++ src/locales/pt_BR/battle.ts | 4 +--- src/locales/pt_BR/move-trigger.ts | 2 ++ src/locales/zh_CN/battle.ts | 4 +--- src/locales/zh_CN/move-trigger.ts | 2 ++ src/locales/zh_TW/battle.ts | 4 +--- src/locales/zh_TW/move-trigger.ts | 2 ++ 19 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 272dbe4d769..1c34e055d23 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5999,7 +5999,7 @@ export class SwapHeldItemsAttr extends MoveEffectAttr { return false; } - user.scene.queueMessage(i18next.t("battle:battlerTagsTrickOnSwap", { + user.scene.queueMessage(i18next.t("moveTriggers:trickOnSwap", { pokemonNameWithAffix: getPokemonNameWithAffix(user), })); @@ -6012,7 +6012,7 @@ export class SwapHeldItemsAttr extends MoveEffectAttr { const userItemToSwap = userHeldItems[user.randSeedInt(userHeldItems.length)]; target.scene.tryTransferHeldItemModifier(userItemToSwap, target, false); - user.scene.queueMessage(i18next.t("battle:battlerTagsTrickFoeNewItem", { + user.scene.queueMessage(i18next.t("moveTriggers:trickFoeNewItem", { pokemonNameWithAffix: getPokemonNameWithAffix(target), itemName: userItemToSwap.type.name, })); diff --git a/src/locales/de/battle.ts b/src/locales/de/battle.ts index b2d2d668b3f..9657553cfd2 100644 --- a/src/locales/de/battle.ts +++ b/src/locales/de/battle.ts @@ -155,7 +155,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} wurde durch {{moveName}} verletzt!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} nimmt einen Teil seiner KP und legt einen Fluch auf {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} wurde durch den Fluch verletzt!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} hortet {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} tauscht Items mit dem Ziel!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} erhält {{itemName}}." + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} hortet {{stockpiledCount}}!" } as const; diff --git a/src/locales/de/move-trigger.ts b/src/locales/de/move-trigger.ts index 427ec6acbde..7167dd92a2b 100644 --- a/src/locales/de/move-trigger.ts +++ b/src/locales/de/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}} hat den Typ von {{targetPokemonName}} angenommen!", "suppressAbilities": "Die Fähigkeit von {{pokemonName}} wirkt nicht mehr!", "swapArenaTags": "{{pokemonName}} hat die Effekte, die auf den beiden Seiten des Kampffeldes wirken, miteinander getauscht!", + "trickOnSwap": "{{pokemonNameWithAffix}} tauscht Items mit dem Ziel!", + "trickFoeNewItem": "{{pokemonNameWithAffix}} erhält {{itemName}}." } as const; diff --git a/src/locales/en/battle.ts b/src/locales/en/battle.ts index 23e69f4a3b6..12a0f2c99c6 100644 --- a/src/locales/en/battle.ts +++ b/src/locales/en/battle.ts @@ -155,7 +155,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" } as const; diff --git a/src/locales/en/move-trigger.ts b/src/locales/en/move-trigger.ts index 1d9d6459d83..46d9405aa08 100644 --- a/src/locales/en/move-trigger.ts +++ b/src/locales/en/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}}'s type became the same as\n{{targetPokemonName}}'s type!", "suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!", "swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!", + "trickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "trickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/es/battle.ts b/src/locales/es/battle.ts index 762468a109d..7f29060c5d3 100644 --- a/src/locales/es/battle.ts +++ b/src/locales/es/battle.ts @@ -155,7 +155,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" } as const; diff --git a/src/locales/es/move-trigger.ts b/src/locales/es/move-trigger.ts index 3ff93997cc2..690af1d5e3d 100644 --- a/src/locales/es/move-trigger.ts +++ b/src/locales/es/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}}'s type\nchanged to match {{targetPokemonName}}'s!", "suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!", "swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!", + "trickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "trickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/fr/battle.ts b/src/locales/fr/battle.ts index a68693ba81b..7feee4e81f4 100644 --- a/src/locales/fr/battle.ts +++ b/src/locales/fr/battle.ts @@ -155,7 +155,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} est blessé\npar la capacité {{moveName}} !", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} sacrifie des PV\net lance une malédiction sur {{pokemonName}} !", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} est touché par la malédiction !", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} utilise\nla capacité Stockage {{stockpiledCount}} fois !", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} échange\nun objet avec sa cible !", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtient\nl’objet {{itemName}} !" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} utilise\nla capacité Stockage {{stockpiledCount}} fois !" } as const; diff --git a/src/locales/fr/move-trigger.ts b/src/locales/fr/move-trigger.ts index d1fbda50b03..6c2046969b4 100644 --- a/src/locales/fr/move-trigger.ts +++ b/src/locales/fr/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}} prend le type\nde {{targetPokemonName}} !", "suppressAbilities": "Le talent de {{pokemonName}}\na été rendu inactif !", "swapArenaTags": "Les effets affectant chaque côté du terrain\nont été échangés par {{pokemonName}} !", + "trickOnSwap": "{{pokemonNameWithAffix}} échange\nun objet avec sa cible !", + "trickFoeNewItem": "{{pokemonNameWithAffix}} obtient\nl’objet {{itemName}} !" } as const; diff --git a/src/locales/it/battle.ts b/src/locales/it/battle.ts index 0d6f11845b0..954f52e4a7f 100644 --- a/src/locales/it/battle.ts +++ b/src/locales/it/battle.ts @@ -155,7 +155,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} viene colpito da {{moveName}}!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} ha sacrificato metà dei suoi PS per\nlanciare una maledizione su {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} subisce la maledizione!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!" } as const; diff --git a/src/locales/it/move-trigger.ts b/src/locales/it/move-trigger.ts index 60679d844c0..115c0964bd8 100644 --- a/src/locales/it/move-trigger.ts +++ b/src/locales/it/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}} assume il tipo\ndi {{targetPokemonName}}!", "suppressAbilities": "L’abilità di {{pokemonName}}\nperde ogni efficacia!", "swapArenaTags": "{{pokemonName}} ha invertito gli effetti attivi\nnelle due metà del campo!", + "trickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "trickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; diff --git a/src/locales/ko/battle.ts b/src/locales/ko/battle.ts index ec22f5f95f5..68b21d75ce1 100644 --- a/src/locales/ko/battle.ts +++ b/src/locales/ko/battle.ts @@ -155,7 +155,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}}[[는]] 소금절이의\n데미지를 입고 있다.", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}[[는]] 자신의 체력을 깎아서\n{{pokemonName}}에게 저주를 걸었다!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}[[는]]\n저주받고 있다!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}[[는]]\n{{stockpiledCount}}개 비축했다!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}}[[는]] 서로의\n도구를 교체했다!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}}[[는]]\n{{itemName}}[[를]] 손에 넣었다!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}[[는]]\n{{stockpiledCount}}개 비축했다!" } as const; diff --git a/src/locales/ko/move-trigger.ts b/src/locales/ko/move-trigger.ts index 9ebf08b1017..b5f1bf59f0c 100644 --- a/src/locales/ko/move-trigger.ts +++ b/src/locales/ko/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}}[[는]]\n{{targetPokemonName}}[[와]] 같은 타입이 되었다!", "suppressAbilities": "{{pokemonName}}의\n특성이 효과를 발휘하지 못하게 되었다!", "swapArenaTags": "{{pokemonName}}[[는]]\n서로의 필드 효과를 교체했다!", + "trickOnSwap": "{{pokemonNameWithAffix}}[[는]] 서로의\n도구를 교체했다!", + "trickFoeNewItem": "{{pokemonNameWithAffix}}[[는]]\n{{itemName}}[[를]] 손에 넣었다!" } as const; diff --git a/src/locales/pt_BR/battle.ts b/src/locales/pt_BR/battle.ts index d8d26def7d1..1b78943da9f 100644 --- a/src/locales/pt_BR/battle.ts +++ b/src/locales/pt_BR/battle.ts @@ -155,7 +155,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} foi ferido pelo {{moveName}}!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cortou seus PS pela metade e amaldiçoou {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} foi ferido pelo Curse!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} estocou {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}} trocou de itens com seu alvo!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}} obteve um(a) {{itemName}}." + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} estocou {{stockpiledCount}}!" } as const; diff --git a/src/locales/pt_BR/move-trigger.ts b/src/locales/pt_BR/move-trigger.ts index c6f35d8f6d1..c46c711a09c 100644 --- a/src/locales/pt_BR/move-trigger.ts +++ b/src/locales/pt_BR/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "O tipo de {{pokemonName}}\nmudou para combinar com {{targetPokemonName}}!", "suppressAbilities": "A habilidade de {{pokemonName}}\nfoi suprimida!", "swapArenaTags": "{{pokemonName}} trocou os efeitos de batalha que afetam cada lado do campo!", + "trickOnSwap": "{{pokemonNameWithAffix}} trocou de itens com seu alvo!", + "trickFoeNewItem": "{{pokemonNameWithAffix}} obteve um(a) {{itemName}}." } as const; diff --git a/src/locales/zh_CN/battle.ts b/src/locales/zh_CN/battle.ts index f993ddc192e..b07cb79e258 100644 --- a/src/locales/zh_CN/battle.ts +++ b/src/locales/zh_CN/battle.ts @@ -147,7 +147,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}}\n受到了{{moveName}}的伤害!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}削减了自己的体力,\n并诅咒了{{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}\n正受到诅咒!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}蓄力了{{stockpiledCount}}次!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}}\n互换了各自的道具!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}}\n获得了{{itemName}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}蓄力了{{stockpiledCount}}次!" } as const; diff --git a/src/locales/zh_CN/move-trigger.ts b/src/locales/zh_CN/move-trigger.ts index 0efe24f76f0..7dffa7c45ba 100644 --- a/src/locales/zh_CN/move-trigger.ts +++ b/src/locales/zh_CN/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}}\n变成了{{targetPokemonName}}的属性!", "suppressAbilities": "{{pokemonName}}的特性\n变得无效了!", "swapArenaTags": "{{pokemonName}}\n交换了双方的场地效果!", + "trickOnSwap": "{{pokemonNameWithAffix}}\n互换了各自的道具!", + "trickFoeNewItem": "{{pokemonNameWithAffix}}\n获得了{{itemName}}!" } as const; diff --git a/src/locales/zh_TW/battle.ts b/src/locales/zh_TW/battle.ts index dd7063568c2..4673474d313 100644 --- a/src/locales/zh_TW/battle.ts +++ b/src/locales/zh_TW/battle.ts @@ -144,7 +144,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} 受到了{{moveName}}的傷害!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}削減了自己的體力,並詛咒了{{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}正受到詛咒!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!", - "battlerTagsTrickOnSwap": "{{pokemonNameWithAffix}}\n互換了各自的道具!", - "battlerTagsTrickFoeNewItem": "{{pokemonNameWithAffix}}\n獲得了{{itemName}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" } as const; diff --git a/src/locales/zh_TW/move-trigger.ts b/src/locales/zh_TW/move-trigger.ts index 019aa84390c..6198b5dc3c0 100644 --- a/src/locales/zh_TW/move-trigger.ts +++ b/src/locales/zh_TW/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}}變成了{{targetPokemonName}}的屬性!", "suppressAbilities": "{{pokemonName}}的特性\n變得無效了!", "swapArenaTags": "{{pokemonName}}\n交換了雙方的場地效果!", + "trickOnSwap": "{{pokemonNameWithAffix}}\n互換了各自的道具!", + "trickFoeNewItem": "{{pokemonNameWithAffix}}\n獲得了{{itemName}}!" } as const; From 68150a7fb034134b3653533566a6b3141f07f24b Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Wed, 7 Aug 2024 03:55:20 -0400 Subject: [PATCH 11/27] Add placeholder Japanese Trick locales --- src/locales/ja/move-trigger.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/locales/ja/move-trigger.ts b/src/locales/ja/move-trigger.ts index 720ae5df5a8..d10d973f14c 100644 --- a/src/locales/ja/move-trigger.ts +++ b/src/locales/ja/move-trigger.ts @@ -59,4 +59,6 @@ export const moveTriggers: SimpleTranslationEntries = { "copyType": "{{pokemonName}}は {{targetPokemonName}}と\n同じタイプに なった!", "suppressAbilities": "{{pokemonName}}の とくせいが きかなくなった!", "swapArenaTags": "{{pokemonName}}は\nおたがいの ばのこうかを いれかえた!", + "trickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", + "trickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}." } as const; From 96a553b8d08825e1db2e65fcd65be699e8c2bbb6 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Wed, 7 Aug 2024 18:25:57 -0400 Subject: [PATCH 12/27] Add tests for Trick --- src/test/moves/trick.test.ts | 218 +++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 src/test/moves/trick.test.ts diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts new file mode 100644 index 00000000000..56e7a9eb193 --- /dev/null +++ b/src/test/moves/trick.test.ts @@ -0,0 +1,218 @@ +import GameManager from "#app/test/utils/gameManager"; +import Phaser from "phaser"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { TurnEndPhase } from "#app/phases"; +import { PokemonHeldItemModifier } from "#app/modifier/modifier.js"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; +import { deepCopy } from "#app/utils"; +import { Abilities } from "#app/enums/abilities.js"; + +const TIMEOUT = 20000; +const TRICK_ONLY = [Moves.TRICK, Moves.TRICK, Moves.TRICK, Moves.TRICK]; + +/** + * Gets the PokemonHeldItemModifier for a given item ID, if the Pokemon has that item + * @param {PokemonHeldItemModifier[]} inventory Held items of a Pokemon + * @param {string} itemId The ID of the item to search for + * @returns PokemonHeldItemModifier if the item is found, undefined if not + */ +function getHeldItemModifierFromId(inventory: PokemonHeldItemModifier[], itemId: string) { + let idxOfSearchedItem = -1; + for (let idx = 0; idx < inventory.length; idx++) { + if (inventory[idx].type.id === itemId) { + idxOfSearchedItem = idx; + break; + } + } + return idxOfSearchedItem !== -1 ? inventory[idxOfSearchedItem] : undefined; +} + +/** + * Prints a string to the console showing how many of an item a Pokemon currently has + * @param {string} pokemonName The name of the checked Pokemon + * @param {string} itemId The ID of the checked item + * @param {number} stackCount How many of this item ID the checked Pokemon has + */ +function printStackCount(pokemonName: string, itemId: string, stackCount: number) { + console.log(`${pokemonName} has ${stackCount} of ${itemId}`); +} + +describe("Moves - Trick", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.battleType("single"); + }); + + it( + "both pokemon have at least one item, and therefore swap their selected items", + async () => { + game.override.startingHeldItems([{name: "LUCKY_EGG"}]); + game.override.enemyHeldItems([{name: "LEFTOVERS"}, {name: "LUCKY_EGG"}]); + game.override.moveset(TRICK_ONLY); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(SPLASH_ONLY); + await game.startBattle([Species.MIME_JR]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + + vi.spyOn(playerPokemon, "randSeedInt").mockReturnValue(0); + vi.spyOn(enemyPokemon, "randSeedInt").mockReturnValue(0); + + const playerLostItem = playerPokemon.getHeldItems()[0]; + const enemyLostItem = enemyPokemon.getHeldItems()[0]; + const prevPlayerLostItemStack = playerLostItem.stackCount; + const prevEnemyLostItemStack = enemyLostItem.stackCount; + const prevPlayerGainedItemModifier = getHeldItemModifierFromId(playerPokemon.getHeldItems(), enemyLostItem.type.id); + const prevEnemyGainedItemModifier = getHeldItemModifierFromId(enemyPokemon.getHeldItems(), playerLostItem.type.id); + + + let prevPlayerGainedItemStackCount = 0; + let prevEnemyGainedItemStackCount = 0; + + if (prevPlayerGainedItemModifier !== undefined) { + prevPlayerGainedItemStackCount = prevPlayerGainedItemModifier.stackCount; + } + + if (prevEnemyGainedItemModifier !== undefined) { + prevEnemyGainedItemStackCount = prevEnemyGainedItemModifier.stackCount; + } + + printStackCount(playerPokemon.name, playerLostItem.type.id, prevPlayerLostItemStack); + printStackCount(playerPokemon.name, enemyLostItem.type.id, prevPlayerGainedItemStackCount); + printStackCount(enemyPokemon.name, enemyLostItem.type.id, prevEnemyLostItemStack); + printStackCount(enemyPokemon.name, playerLostItem.type.id, prevEnemyGainedItemStackCount); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + const currPlayerLostItemStack = playerLostItem.stackCount; + const currEnemyLostItemStack = enemyLostItem.stackCount; + const currPlayerGainedItemModifier = getHeldItemModifierFromId(playerPokemon.getHeldItems(), enemyLostItem.type.id); + const currEnemyGainedItemModifier = getHeldItemModifierFromId(enemyPokemon.getHeldItems(), playerLostItem.type.id); + + expect(currPlayerGainedItemModifier).toBeDefined(); + expect(currEnemyGainedItemModifier).toBeDefined(); + + const currPlayerGainedItemStackCount = currPlayerGainedItemModifier.stackCount; + const currEnemyGainedItemStackCount = currEnemyGainedItemModifier.stackCount; + + printStackCount(playerPokemon.name, playerLostItem.type.id, currPlayerLostItemStack); + printStackCount(playerPokemon.name, enemyLostItem.type.id, currPlayerGainedItemStackCount); + printStackCount(enemyPokemon.name, enemyLostItem.type.id, currEnemyLostItemStack); + printStackCount(enemyPokemon.name, playerLostItem.type.id, currEnemyGainedItemStackCount); + + const didPlayerTransferItems = prevPlayerLostItemStack > currPlayerLostItemStack && prevPlayerGainedItemStackCount < currPlayerGainedItemStackCount; + const didEnemyTransferItems = prevEnemyLostItemStack > currEnemyLostItemStack && prevEnemyGainedItemStackCount < currEnemyGainedItemStackCount; + + expect(didPlayerTransferItems && didEnemyTransferItems).toBeTruthy(); + }, TIMEOUT + ); + + it( + "the move fails and no transfer occurs when a wild pokemon is the user", + async () => { + game.override.startingHeldItems([{name: "LUCKY_EGG"}]); + game.override.enemyHeldItems([{name: "LEFTOVERS"}]); + game.override.moveset(SPLASH_ONLY); + game.override.enemySpecies(Species.MIME_JR); + game.override.enemyMoveset(TRICK_ONLY); + await game.startBattle([Species.MAGIKARP]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemonFirstHeldItem = deepCopy(playerPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; + const enemyPokemonFirstHeldItem = deepCopy(enemyPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; + + printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); + printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + const playerPokemonCurrentHeldItem = playerPokemon.getHeldItems()[0]; + const enemyPokemonCurrentHeldItem = enemyPokemon.getHeldItems()[0]; + + printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); + printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); + + const playerDidNotLoseItem = playerPokemonFirstHeldItem.type.id === playerPokemonCurrentHeldItem.type.id && playerPokemonFirstHeldItem.stackCount === playerPokemonCurrentHeldItem.stackCount; + const enemyDidNotLoseItem = enemyPokemonFirstHeldItem.type.id === enemyPokemonCurrentHeldItem.type.id && enemyPokemonFirstHeldItem.stackCount === enemyPokemonCurrentHeldItem.stackCount; + + expect(playerDidNotLoseItem && enemyDidNotLoseItem).toBeTruthy(); + }, TIMEOUT + ); + + it( + "the move fails and no transfer occurs when the target pokemon has sticky hold", + async () => { + game.override.startingHeldItems([{name: "LUCKY_EGG"}]); + game.override.enemyHeldItems([{name: "LEFTOVERS"}]); + game.override.moveset(TRICK_ONLY); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.STICKY_HOLD); + await game.startBattle([Species.MIME_JR]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemonFirstHeldItem = deepCopy(playerPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; + const enemyPokemonFirstHeldItem = deepCopy(enemyPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; + + printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); + printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + const playerPokemonCurrentHeldItem = playerPokemon.getHeldItems()[0]; + const enemyPokemonCurrentHeldItem = enemyPokemon.getHeldItems()[0]; + + printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); + printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); + + const playerDidNotLoseItem = playerPokemonFirstHeldItem.type.id === playerPokemonCurrentHeldItem.type.id && playerPokemonFirstHeldItem.stackCount === playerPokemonCurrentHeldItem.stackCount; + const enemyDidNotLoseItem = enemyPokemonFirstHeldItem.type.id === enemyPokemonCurrentHeldItem.type.id && enemyPokemonFirstHeldItem.stackCount === enemyPokemonCurrentHeldItem.stackCount; + + expect(playerDidNotLoseItem && enemyDidNotLoseItem).toBeTruthy(); + }, TIMEOUT + ); + + it( + "the move fails and no transfer occurs when neither pokemon have any items", + async() => { + game.override.moveset(TRICK_ONLY); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(SPLASH_ONLY); + await game.startBattle([Species.MIME_JR]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + + expect(playerPokemon.getHeldItems().length === 0); + expect(enemyPokemon.getHeldItems().length === 0); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(playerPokemon.getHeldItems().length === 0); + expect(enemyPokemon.getHeldItems().length === 0); + + }, TIMEOUT + ); +}); From 7bf6b1e250099cc2815f17593eb5edfaf2f8a1a2 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Fri, 16 Aug 2024 15:18:00 -0400 Subject: [PATCH 13/27] Fix non player trainers being unable to use Trick --- src/data/move.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/move.ts b/src/data/move.ts index 06283f42b77..14c26b23bb7 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -6051,7 +6051,7 @@ export class SwapHeldItemsAttr extends MoveEffectAttr { const targetHeldItems = target.getHeldItems().filter(i => i.isTransferrable); const userHeldItems = user.getHeldItems().filter(i => i.isTransferrable); - if (!user.isPlayer() || target.hasAbility(Abilities.STICKY_HOLD) || (!userHeldItems.length && !targetHeldItems.length)) { + if (!user.hasTrainer() || target.hasAbility(Abilities.STICKY_HOLD) || (!userHeldItems.length && !targetHeldItems.length)) { user.scene.queueMessage(i18next.t("battle:attackFailed")); return false; } From ce4d22bb8a26228a262fa561a9255ee3ba718f0f Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Sat, 17 Aug 2024 03:08:54 -0400 Subject: [PATCH 14/27] Trick no longer selects items randomly and instead bases it on item tier, and prioritizes Toxic Orb and Flame Orb --- src/data/move.ts | 52 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 14c26b23bb7..09db8daf6c1 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -28,6 +28,7 @@ import { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { MoveUsedEvent } from "#app/events/battle-scene.js"; +import { ModifierTier } from "#app/modifier/modifier-tier.js"; export enum MoveCategory { PHYSICAL, @@ -6061,17 +6062,58 @@ export class SwapHeldItemsAttr extends MoveEffectAttr { })); if (targetHeldItems.length) { - const targetItemToSwap = targetHeldItems[target.randSeedInt(targetHeldItems.length)]; - user.scene.tryTransferHeldItemModifier(targetItemToSwap, user, false); + const swapItemIdx = 0; + const targetPool = target.isPlayer() ? ModifierPoolType.PLAYER : ModifierPoolType.TRAINER; + + for (let idx = 1; idx < targetHeldItems.length; idx++) { + const currentItemFlameOrToxic = targetHeldItems[swapItemIdx].type.id === "TOXIC_ORB" || targetHeldItems[swapItemIdx].type.id === "FLAME_ORB"; + const nextItemNotFlameOrToxic = targetHeldItems[idx].type.id !== "TOXIC_ORB" && targetHeldItems[idx].type.id !== "FLAME_ORB"; + let nextItemTier = targetHeldItems[idx].type.getOrInferTier(targetPool); + let currentItemTier = targetHeldItems[swapItemIdx].type.getOrInferTier(targetPool); + nextItemTier = nextItemTier !== null ? nextItemTier : ModifierTier.COMMON; + currentItemTier = currentItemTier !== null ? currentItemTier : ModifierTier.COMMON; + + if (nextItemNotFlameOrToxic && (nextItemTier > currentItemTier || currentItemFlameOrToxic)) { + targetHeldItems[swapItemIdx] = targetHeldItems[idx]; + } + + if (targetHeldItems[swapItemIdx].type.tier === ModifierTier.LUXURY) { + break; + } + } + user.scene.tryTransferHeldItemModifier(targetHeldItems[swapItemIdx], user, false); } if (userHeldItems.length) { - const userItemToSwap = userHeldItems[user.randSeedInt(userHeldItems.length)]; - target.scene.tryTransferHeldItemModifier(userItemToSwap, target, false); + let swapItemIdx = 0; + const userPool = user.isPlayer() ? ModifierPoolType.PLAYER : ModifierPoolType.TRAINER; + + for (let idx = 1; idx < userHeldItems.length; idx++) { + if (userHeldItems[swapItemIdx].type.id === "TOXIC_ORB" || userHeldItems[swapItemIdx].type.id === "FLAME_ORB") { + break; + } + + if (userHeldItems[idx].type.id === "TOXIC_ORB" || userHeldItems[idx].type.id === "FLAME_ORB") { + swapItemIdx = idx; + break; + } + + let nextItemTier = userHeldItems[idx].type.getOrInferTier(userPool); + let currentItemTier = userHeldItems[swapItemIdx].type.getOrInferTier(userPool); + nextItemTier = nextItemTier !== null ? nextItemTier : ModifierTier.COMMON; + currentItemTier = currentItemTier !== null ? currentItemTier : ModifierTier.COMMON; + + if (nextItemTier < currentItemTier) { + swapItemIdx = idx; + } + } + + const swappedItemName = userHeldItems[swapItemIdx].type.name; + target.scene.tryTransferHeldItemModifier(userHeldItems[swapItemIdx], target, false); user.scene.queueMessage(i18next.t("moveTriggers:trickFoeNewItem", { pokemonNameWithAffix: getPokemonNameWithAffix(target), - itemName: userItemToSwap.type.name, + itemName: swappedItemName, })); } return true; From 9d63f24b28d5f869667eff030d8e92d72211b69b Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Thu, 22 Aug 2024 12:48:54 -0400 Subject: [PATCH 15/27] Fix index of the item to swap not being updated --- src/data/move.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 834a3ba199b..ad1ade806f8 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -6102,7 +6102,7 @@ export class SwapHeldItemsAttr extends MoveEffectAttr { })); if (targetHeldItems.length) { - const swapItemIdx = 0; + let swapItemIdx = 0; const targetPool = target.isPlayer() ? ModifierPoolType.PLAYER : ModifierPoolType.TRAINER; for (let idx = 1; idx < targetHeldItems.length; idx++) { @@ -6114,7 +6114,7 @@ export class SwapHeldItemsAttr extends MoveEffectAttr { currentItemTier = currentItemTier !== null ? currentItemTier : ModifierTier.COMMON; if (nextItemNotFlameOrToxic && (nextItemTier > currentItemTier || currentItemFlameOrToxic)) { - targetHeldItems[swapItemIdx] = targetHeldItems[idx]; + swapItemIdx = idx; } if (targetHeldItems[swapItemIdx].type.tier === ModifierTier.LUXURY) { From 9d8b25ad2d03f9fef452eee7fb3ba82baa571f63 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Fri, 23 Aug 2024 00:32:03 -0400 Subject: [PATCH 16/27] Update base Trick test to match tier priority system --- src/test/moves/trick.test.ts | 41 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts index 56e7a9eb193..c8e3fb7ab78 100644 --- a/src/test/moves/trick.test.ts +++ b/src/test/moves/trick.test.ts @@ -2,7 +2,7 @@ import GameManager from "#app/test/utils/gameManager"; import Phaser from "phaser"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { TurnEndPhase } from "#app/phases"; import { PokemonHeldItemModifier } from "#app/modifier/modifier.js"; import { SPLASH_ONLY } from "#test/utils/testUtils"; @@ -59,10 +59,10 @@ describe("Moves - Trick", () => { }); it( - "both pokemon have at least one item, and therefore swap their selected items", + "both pokemon have two items, they will always swap Leftovers and Golden Punch, due to the priority system", async () => { - game.override.startingHeldItems([{name: "LUCKY_EGG"}]); - game.override.enemyHeldItems([{name: "LEFTOVERS"}, {name: "LUCKY_EGG"}]); + game.override.startingHeldItems([{name: "MULTI_LENS"}, {name: "GOLDEN_PUNCH"}]); + game.override.enemyHeldItems([{name: "LEFTOVERS"}, {name: "GOLDEN_PUNCH"}]); game.override.moveset(TRICK_ONLY); game.override.enemySpecies(Species.MAGIKARP); game.override.enemyMoveset(SPLASH_ONLY); @@ -71,17 +71,13 @@ describe("Moves - Trick", () => { const playerPokemon = game.scene.getPlayerPokemon(); const enemyPokemon = game.scene.getEnemyPokemon(); - vi.spyOn(playerPokemon, "randSeedInt").mockReturnValue(0); - vi.spyOn(enemyPokemon, "randSeedInt").mockReturnValue(0); - - const playerLostItem = playerPokemon.getHeldItems()[0]; + const playerLostItem = playerPokemon.getHeldItems()[1]; const enemyLostItem = enemyPokemon.getHeldItems()[0]; const prevPlayerLostItemStack = playerLostItem.stackCount; const prevEnemyLostItemStack = enemyLostItem.stackCount; const prevPlayerGainedItemModifier = getHeldItemModifierFromId(playerPokemon.getHeldItems(), enemyLostItem.type.id); const prevEnemyGainedItemModifier = getHeldItemModifierFromId(enemyPokemon.getHeldItems(), playerLostItem.type.id); - let prevPlayerGainedItemStackCount = 0; let prevEnemyGainedItemStackCount = 0; @@ -109,25 +105,30 @@ describe("Moves - Trick", () => { expect(currPlayerGainedItemModifier).toBeDefined(); expect(currEnemyGainedItemModifier).toBeDefined(); - const currPlayerGainedItemStackCount = currPlayerGainedItemModifier.stackCount; - const currEnemyGainedItemStackCount = currEnemyGainedItemModifier.stackCount; + if (currPlayerGainedItemModifier && currEnemyGainedItemModifier) { - printStackCount(playerPokemon.name, playerLostItem.type.id, currPlayerLostItemStack); - printStackCount(playerPokemon.name, enemyLostItem.type.id, currPlayerGainedItemStackCount); - printStackCount(enemyPokemon.name, enemyLostItem.type.id, currEnemyLostItemStack); - printStackCount(enemyPokemon.name, playerLostItem.type.id, currEnemyGainedItemStackCount); + const currPlayerGainedItemStackCount = currPlayerGainedItemModifier.stackCount; + const currEnemyGainedItemStackCount = currEnemyGainedItemModifier.stackCount; - const didPlayerTransferItems = prevPlayerLostItemStack > currPlayerLostItemStack && prevPlayerGainedItemStackCount < currPlayerGainedItemStackCount; - const didEnemyTransferItems = prevEnemyLostItemStack > currEnemyLostItemStack && prevEnemyGainedItemStackCount < currEnemyGainedItemStackCount; + printStackCount(playerPokemon.name, playerLostItem.type.id, currPlayerLostItemStack); + printStackCount(playerPokemon.name, enemyLostItem.type.id, currPlayerGainedItemStackCount); + printStackCount(enemyPokemon.name, enemyLostItem.type.id, currEnemyLostItemStack); + printStackCount(enemyPokemon.name, playerLostItem.type.id, currEnemyGainedItemStackCount); - expect(didPlayerTransferItems && didEnemyTransferItems).toBeTruthy(); + const didPlayerTransferItems = prevPlayerLostItemStack > currPlayerLostItemStack && prevPlayerGainedItemStackCount < currPlayerGainedItemStackCount; + const didEnemyTransferItems = prevEnemyLostItemStack > currEnemyLostItemStack && prevEnemyGainedItemStackCount < currEnemyGainedItemStackCount; + const playerReceivedLeftovers = currPlayerGainedItemModifier.type.id === "LEFTOVERS"; + const enemyReceivedGoldenPunch = currEnemyGainedItemModifier.type.id === "GOLDEN_PUNCH"; + + expect(didPlayerTransferItems && didEnemyTransferItems && playerReceivedLeftovers && enemyReceivedGoldenPunch).toBeTruthy(); + } }, TIMEOUT ); it( "the move fails and no transfer occurs when a wild pokemon is the user", async () => { - game.override.startingHeldItems([{name: "LUCKY_EGG"}]); + game.override.startingHeldItems([{name: "GOLDEN_PUNCH"}]); game.override.enemyHeldItems([{name: "LEFTOVERS"}]); game.override.moveset(SPLASH_ONLY); game.override.enemySpecies(Species.MIME_JR); @@ -161,7 +162,7 @@ describe("Moves - Trick", () => { it( "the move fails and no transfer occurs when the target pokemon has sticky hold", async () => { - game.override.startingHeldItems([{name: "LUCKY_EGG"}]); + game.override.startingHeldItems([{name: "GOLDEN_PUNCH"}]); game.override.enemyHeldItems([{name: "LEFTOVERS"}]); game.override.moveset(TRICK_ONLY); game.override.enemySpecies(Species.MAGIKARP); From 38495f9df37eb4d73cee6fbae1c244c4488531f8 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Fri, 23 Aug 2024 01:09:56 -0400 Subject: [PATCH 17/27] Add tests for Toxic Orb and Flame Orb priorities --- src/test/moves/trick.test.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts index c8e3fb7ab78..181a68933ae 100644 --- a/src/test/moves/trick.test.ts +++ b/src/test/moves/trick.test.ts @@ -125,6 +125,41 @@ describe("Moves - Trick", () => { }, TIMEOUT ); + it( + "the user will always give Toxic Orb, as it has special priority to be given", + async () => { + game.override.startingHeldItems([{name: "GOLDEN_PUNCH"}, {name: "TOXIC_ORB"}]); + game.override.enemyHeldItems([{name: "LEFTOVERS"}, {name: "GOLDEN_PUNCH"}]); + game.override.moveset(TRICK_ONLY); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(SPLASH_ONLY); + await game.startBattle([Species.MIME_JR]); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + const playerPokemon = game.scene.getPlayerPokemon(); + expect(playerPokemon.getHeldItems()[1].type.id === "TOXIC_ORB").toBeFalsy(); + } + ); + + it( + "the user will never take Flame Orb, as it has special priority to not be taken", + async () => { + game.override.enemyHeldItems([{name: "FLAME_ORB"}, {name: "GOLDEN_PUNCH"}]); + game.override.moveset(TRICK_ONLY); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(SPLASH_ONLY); + await game.startBattle([Species.MIME_JR]); + + game.doAttack(0); + await game.phaseInterceptor.to(TurnEndPhase); + + const enemyPokemon = game.scene.getEnemyPokemon(); + expect(enemyPokemon.getHeldItems()[0].type.id === "FLAME_ORB").toBeTruthy(); + } + ); + it( "the move fails and no transfer occurs when a wild pokemon is the user", async () => { From a27960a8384becab54076ef75f179fb6620ac7ec Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Fri, 23 Aug 2024 16:15:19 -0400 Subject: [PATCH 18/27] Replace doAttack with move.select --- src/test/moves/trick.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts index 181a68933ae..2499087236b 100644 --- a/src/test/moves/trick.test.ts +++ b/src/test/moves/trick.test.ts @@ -94,7 +94,7 @@ describe("Moves - Trick", () => { printStackCount(enemyPokemon.name, enemyLostItem.type.id, prevEnemyLostItemStack); printStackCount(enemyPokemon.name, playerLostItem.type.id, prevEnemyGainedItemStackCount); - game.doAttack(0); + game.move.select(Moves.TRICK); await game.phaseInterceptor.to(TurnEndPhase); const currPlayerLostItemStack = playerLostItem.stackCount; @@ -135,7 +135,7 @@ describe("Moves - Trick", () => { game.override.enemyMoveset(SPLASH_ONLY); await game.startBattle([Species.MIME_JR]); - game.doAttack(0); + game.move.select(Moves.TRICK); await game.phaseInterceptor.to(TurnEndPhase); const playerPokemon = game.scene.getPlayerPokemon(); @@ -152,7 +152,7 @@ describe("Moves - Trick", () => { game.override.enemyMoveset(SPLASH_ONLY); await game.startBattle([Species.MIME_JR]); - game.doAttack(0); + game.move.select(Moves.TRICK); await game.phaseInterceptor.to(TurnEndPhase); const enemyPokemon = game.scene.getEnemyPokemon(); @@ -178,7 +178,7 @@ describe("Moves - Trick", () => { printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); - game.doAttack(0); + game.move.select(Moves.TRICK); await game.phaseInterceptor.to(TurnEndPhase); const playerPokemonCurrentHeldItem = playerPokemon.getHeldItems()[0]; @@ -213,7 +213,7 @@ describe("Moves - Trick", () => { printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount); printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount); - game.doAttack(0); + game.move.select(Moves.TRICK); await game.phaseInterceptor.to(TurnEndPhase); const playerPokemonCurrentHeldItem = playerPokemon.getHeldItems()[0]; @@ -243,7 +243,7 @@ describe("Moves - Trick", () => { expect(playerPokemon.getHeldItems().length === 0); expect(enemyPokemon.getHeldItems().length === 0); - game.doAttack(0); + game.move.select(Moves.TRICK); await game.phaseInterceptor.to(TurnEndPhase); expect(playerPokemon.getHeldItems().length === 0); From c38dfaaeff8a3444d033f94633beb00b0aa8c5b6 Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Fri, 23 Aug 2024 16:15:46 -0400 Subject: [PATCH 19/27] Update import for TurnEndPhase --- src/test/moves/trick.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts index 2499087236b..803c67f744d 100644 --- a/src/test/moves/trick.test.ts +++ b/src/test/moves/trick.test.ts @@ -3,7 +3,7 @@ import Phaser from "phaser"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; -import { TurnEndPhase } from "#app/phases"; +import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { PokemonHeldItemModifier } from "#app/modifier/modifier.js"; import { SPLASH_ONLY } from "#test/utils/testUtils"; import { deepCopy } from "#app/utils"; From 5435781072364cf477fc6349365a02833beb972d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2?= <123510358+NicusPulcis@users.noreply.github.com> Date: Mon, 26 Aug 2024 11:56:31 +0200 Subject: [PATCH 20/27] Update src/locales/it/move-trigger.json --- src/locales/it/move-trigger.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/it/move-trigger.json b/src/locales/it/move-trigger.json index 2816ca98791..1345df304a3 100644 --- a/src/locales/it/move-trigger.json +++ b/src/locales/it/move-trigger.json @@ -61,7 +61,7 @@ "suppressAbilities": "L’abilità di {{pokemonName}}\nperde ogni efficacia!", "revivalBlessing": "{{pokemonName}} torna in forze!", "swapArenaTags": "{{pokemonName}} ha invertito gli effetti attivi\nnelle due metà del campo!", - "trickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "trickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}.", + "trickOnSwap": "{{pokemonNameWithAffix}} scambia il suo strumento\ncon quello del bersaglio!", + "trickFoeNewItem": "{{pokemonNameWithAffix}} ottiene un/una {{itemName}}!", "exposedMove": "{{pokemonName}} ha identificato\n{{targetPokemonName}}!" } From 9b011802e62a3278fd872c9abce7e5adc51380e1 Mon Sep 17 00:00:00 2001 From: eucalyptusJ <88509866+eucalyptusJ@users.noreply.github.com> Date: Mon, 26 Aug 2024 09:40:37 -0400 Subject: [PATCH 21/27] Account for getEnemyPokemon and getPlayerPokemon possibly returning undefined --- src/test/moves/trick.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts index 803c67f744d..e55667de576 100644 --- a/src/test/moves/trick.test.ts +++ b/src/test/moves/trick.test.ts @@ -68,8 +68,8 @@ describe("Moves - Trick", () => { game.override.enemyMoveset(SPLASH_ONLY); await game.startBattle([Species.MIME_JR]); - const playerPokemon = game.scene.getPlayerPokemon(); - const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; const playerLostItem = playerPokemon.getHeldItems()[1]; const enemyLostItem = enemyPokemon.getHeldItems()[0]; @@ -138,7 +138,7 @@ describe("Moves - Trick", () => { game.move.select(Moves.TRICK); await game.phaseInterceptor.to(TurnEndPhase); - const playerPokemon = game.scene.getPlayerPokemon(); + const playerPokemon = game.scene.getPlayerPokemon()!; expect(playerPokemon.getHeldItems()[1].type.id === "TOXIC_ORB").toBeFalsy(); } ); @@ -170,8 +170,8 @@ describe("Moves - Trick", () => { game.override.enemyMoveset(TRICK_ONLY); await game.startBattle([Species.MAGIKARP]); - const playerPokemon = game.scene.getPlayerPokemon(); - const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; const playerPokemonFirstHeldItem = deepCopy(playerPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; const enemyPokemonFirstHeldItem = deepCopy(enemyPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; @@ -205,8 +205,8 @@ describe("Moves - Trick", () => { game.override.enemyAbility(Abilities.STICKY_HOLD); await game.startBattle([Species.MIME_JR]); - const playerPokemon = game.scene.getPlayerPokemon(); - const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; const playerPokemonFirstHeldItem = deepCopy(playerPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; const enemyPokemonFirstHeldItem = deepCopy(enemyPokemon.getHeldItems()[0]) as PokemonHeldItemModifier; @@ -237,8 +237,8 @@ describe("Moves - Trick", () => { game.override.enemyMoveset(SPLASH_ONLY); await game.startBattle([Species.MIME_JR]); - const playerPokemon = game.scene.getPlayerPokemon(); - const enemyPokemon = game.scene.getEnemyPokemon(); + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; expect(playerPokemon.getHeldItems().length === 0); expect(enemyPokemon.getHeldItems().length === 0); From 8a0b78a67fd17477690a65761f5607a286392509 Mon Sep 17 00:00:00 2001 From: eucalyptusJ <88509866+eucalyptusJ@users.noreply.github.com> Date: Mon, 26 Aug 2024 11:06:28 -0400 Subject: [PATCH 22/27] Add missing check for getEnemyPokemon being undefined --- src/test/moves/trick.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts index e55667de576..42e3f44c61c 100644 --- a/src/test/moves/trick.test.ts +++ b/src/test/moves/trick.test.ts @@ -155,7 +155,7 @@ describe("Moves - Trick", () => { game.move.select(Moves.TRICK); await game.phaseInterceptor.to(TurnEndPhase); - const enemyPokemon = game.scene.getEnemyPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon()!; expect(enemyPokemon.getHeldItems()[0].type.id === "FLAME_ORB").toBeTruthy(); } ); From b37e1f4f55c8c662f22b84b1a3ded1559d8e1821 Mon Sep 17 00:00:00 2001 From: Eucalyptus <88509866+eucalyptusJ@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:59:29 -0400 Subject: [PATCH 23/27] Remove .js for importing modifier-tier Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/move.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/move.ts b/src/data/move.ts index 40ff3c2c725..656075b144a 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -37,7 +37,7 @@ import { StatChangePhase } from "#app/phases/stat-change-phase"; import { SwitchPhase } from "#app/phases/switch-phase"; import { SwitchSummonPhase } from "#app/phases/switch-summon-phase"; import { SpeciesFormChangeRevertWeatherFormTrigger } from "./pokemon-forms"; -import { ModifierTier } from "#app/modifier/modifier-tier.js"; +import { ModifierTier } from "#app/modifier/modifier-tier"; export enum MoveCategory { PHYSICAL, From c05408c476455cfd535bd8dff11b9d6cd060e6ba Mon Sep 17 00:00:00 2001 From: eucalyptusJ <88509866+eucalyptusJ@users.noreply.github.com> Date: Tue, 27 Aug 2024 13:52:31 -0400 Subject: [PATCH 24/27] Readd removed German locales for Trick --- src/locales/de/move-trigger.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/locales/de/move-trigger.json b/src/locales/de/move-trigger.json index 7fdc73d9fa7..2e80e30cfea 100644 --- a/src/locales/de/move-trigger.json +++ b/src/locales/de/move-trigger.json @@ -61,5 +61,7 @@ "suppressAbilities": "Die Fähigkeit von {{pokemonName}} wirkt nicht mehr!", "revivalBlessing": "{{pokemonName}} ist wieder fit und kampfbereit!", "swapArenaTags": "{{pokemonName}} hat die Effekte, die auf den beiden Seiten des Kampffeldes wirken, miteinander getauscht!", + "trickOnSwap": "{{pokemonNameWithAffix}} tauscht Items mit dem Ziel!", + "trickFoeNewItem": "{{pokemonNameWithAffix}} erhält {{itemName}}.", "exposedMove": "{{pokemonName}} erkennt {{targetPokemonName}}!" } From 62aa5329597dfc6d4a792040f73983702ce1aa48 Mon Sep 17 00:00:00 2001 From: Eucalyptus <88509866+eucalyptusJ@users.noreply.github.com> Date: Mon, 9 Sep 2024 23:56:39 -0400 Subject: [PATCH 25/27] Update src/locales/ja/move-trigger.json Co-authored-by: Chapybara-jp --- src/locales/ja/move-trigger.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/ja/move-trigger.json b/src/locales/ja/move-trigger.json index 25216fa9f10..456331819ed 100644 --- a/src/locales/ja/move-trigger.json +++ b/src/locales/ja/move-trigger.json @@ -64,8 +64,8 @@ "copyType": "{{pokemonName}}は {{targetPokemonName}}と\n同じタイプに なった!", "suppressAbilities": "{{pokemonName}}の 特性が 効かなくなった!", "revivalBlessing": "{{pokemonName}}は\n復活して 戦えるようになった!", - "trickOnSwap": "{{pokemonNameWithAffix}} switched items with its target!", - "trickFoeNewItem": "{{pokemonNameWithAffix}} obtained one {{itemName}}.", + "trickOnSwap": "{{pokemonNameWithAffix}} は お互いの 道具を 入れ替えた!", + "trickFoeNewItem": "{{pokemonNameWithAffix}}は {{itemName}}を 1つ 手に入れた!", "swapArenaTags": "{{pokemonName}}は\nお互いの 場の 効果を 入れ替えた!", "exposedMove": "{{pokemonName}}は {{targetPokemonName}}の\n正体を 見破った!" } From 25761f763234b12e475bf8dcbd59a1895c631855 Mon Sep 17 00:00:00 2001 From: eucalyptusJ <88509866+eucalyptusJ@users.noreply.github.com> Date: Tue, 10 Sep 2024 11:00:24 -0400 Subject: [PATCH 26/27] Fix enemy Pokemon not receiving any moves in tests --- src/test/moves/trick.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/moves/trick.test.ts b/src/test/moves/trick.test.ts index 42e3f44c61c..cc5872355c6 100644 --- a/src/test/moves/trick.test.ts +++ b/src/test/moves/trick.test.ts @@ -5,12 +5,12 @@ import { Species } from "#enums/species"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { PokemonHeldItemModifier } from "#app/modifier/modifier.js"; -import { SPLASH_ONLY } from "#test/utils/testUtils"; import { deepCopy } from "#app/utils"; import { Abilities } from "#app/enums/abilities.js"; const TIMEOUT = 20000; const TRICK_ONLY = [Moves.TRICK, Moves.TRICK, Moves.TRICK, Moves.TRICK]; +const SPLASH_ONLY = [Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]; /** * Gets the PokemonHeldItemModifier for a given item ID, if the Pokemon has that item From d49d49f9bc07789d71d10de7646466b1b31eef5b Mon Sep 17 00:00:00 2001 From: Eucalyptus Date: Sun, 6 Oct 2024 12:54:08 -0400 Subject: [PATCH 27/27] Update use of isTransferrable to isTransferable --- src/data/move.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 65a220909bb..4a60f76cf27 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -6932,8 +6932,8 @@ export class SwapHeldItemsAttr extends MoveEffectAttr { */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const targetHeldItems = target.getHeldItems().filter(i => i.isTransferrable); - const userHeldItems = user.getHeldItems().filter(i => i.isTransferrable); + const targetHeldItems = target.getHeldItems().filter(i => i.isTransferable); + const userHeldItems = user.getHeldItems().filter(i => i.isTransferable); if (!user.hasTrainer() || target.hasAbility(Abilities.STICKY_HOLD) || (!userHeldItems.length && !targetHeldItems.length)) { user.scene.queueMessage(i18next.t("battle:attackFailed"));