From 9c7298ae5028176503991991e2532395374ad140 Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:55:51 -0500 Subject: [PATCH 01/17] Recreate Copy. Add Copy tag Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/types.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/libs/combat/types.ts b/app/src/libs/combat/types.ts index 6c11fd23a..480b9c5c6 100644 --- a/app/src/libs/combat/types.ts +++ b/app/src/libs/combat/types.ts @@ -695,6 +695,16 @@ export const WeaknessTag = z.object({ }); export type WeaknessTagType = z.infer; +export const CopyTag = z.object({ + ...BaseAttributes, + ...PowerAttributes, + type: z.literal("copy").default("copy"), + description: msg("Copies all positive effects from the target to the user"), + calculation: z.enum(["percentage"]).default("percentage"), + rounds: z.coerce.number().int().min(1).max(10).default(3), +}); +export type CopyTagType = z.infer; + export const UnknownTag = z.object({ ...BaseAttributes, type: z.literal("unknown").default("unknown"), @@ -721,6 +731,7 @@ export const AllTags = z.union([ ClearPreventTag.default({}), ClearTag.default({}), CloneTag.default({}), + CopyTag.default({}), DamageTag.default({}), DebuffPreventTag.default({}), DecreaseDamageGivenTag.default({}), From 0ad7a64f72e7792ae35a88890e0fbb17a3823a01 Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:02:35 -0500 Subject: [PATCH 02/17] add copy to process.ts Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/process.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/libs/combat/process.ts b/app/src/libs/combat/process.ts index dcbb784fe..b1697785e 100644 --- a/app/src/libs/combat/process.ts +++ b/app/src/libs/combat/process.ts @@ -6,7 +6,7 @@ import { calcApplyRatio } from "./util"; import { calcEffectRoundInfo, isEffectActive } from "./util"; import { nanoid } from "nanoid"; import { clone, move, heal, damageBarrier, damageUser, calcDmgModifier } from "./tags"; -import { absorb, reflect, recoil, lifesteal, drain, shield } from "./tags"; +import { absorb, reflect, recoil, lifesteal, drain, shield, copy } from "./tags"; import { increaseStats, decreaseStats } from "./tags"; import { increaseDamageGiven, decreaseDamageGiven } from "./tags"; import { increaseDamageTaken, decreaseDamageTaken } from "./tags"; @@ -340,7 +340,10 @@ export const applyEffects = (battle: CompleteBattle, actorId: string) => { info = stun(e, newUsersEffects, curTarget); } else if (e.type === "drain") { info = drain(e, usersEffects, consequences, curTarget); + } else if (e.type === "copy") { + info = copy(e, usersEffects, curUser, curTarget); } + } // Always apply From 192bcd62b4cace2e2417c516d59b032c7182e3bb Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:06:26 -0500 Subject: [PATCH 03/17] Add copy to tags Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/tags.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/app/src/libs/combat/tags.ts b/app/src/libs/combat/tags.ts index d196f93ca..f6db7735b 100644 --- a/app/src/libs/combat/tags.ts +++ b/app/src/libs/combat/tags.ts @@ -1205,6 +1205,38 @@ export const shield = (effect: UserEffect, target: BattleUserState) => { return info; }; +/** Copy positive effects from opponent to self */ +export const copy = ( + effect: UserEffect, + usersEffects: UserEffect[], + user: BattleUserState, + target: BattleUserState +): ActionEffect | undefined => { + // Find all positive effects on the target + const positiveEffects = usersEffects.filter( + (e) => e.targetId === target.userId && isPositiveUserEffect(e) + ); + + if (positiveEffects.length === 0) { + return { txt: `${user.username} tries to copy but finds no effects to copy.`, color: "blue" }; + } + + positiveEffects.forEach((posEffect) => { + const copiedEffect = structuredClone(posEffect); + copiedEffect.id = nanoid(); // Give it a new unique ID + copiedEffect.targetId = user.userId; + copiedEffect.creatorId = user.userId; + copiedEffect.isNew = true; + copiedEffect.castThisRound = true; + usersEffects.push(copiedEffect); + }); + + return { + txt: `${user.username} copies ${positiveEffects.length} effects from ${target.username}.`, + color: "blue", + }; +}; + /** * Move user on the battlefield * 1. Remove user from current ground effect From a10a2794234a8322bf7c4251b2b2f33a735214fc Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:32:00 -0500 Subject: [PATCH 04/17] Add copy to utils Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/util.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/libs/combat/util.ts b/app/src/libs/combat/util.ts index df88e15a3..1b0115f70 100644 --- a/app/src/libs/combat/util.ts +++ b/app/src/libs/combat/util.ts @@ -313,6 +313,7 @@ export const sortEffects = ( "reflect", "decreaseheal", "increaseheal", + "copy", // End-modifiers "move", "visual", From 3c04bb3769fff9ccce4b50b5da6d25ed248d5f6e Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:37:11 -0500 Subject: [PATCH 05/17] Add conditionals to copy Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/tags.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/libs/combat/tags.ts b/app/src/libs/combat/tags.ts index f6db7735b..3637ca4e6 100644 --- a/app/src/libs/combat/tags.ts +++ b/app/src/libs/combat/tags.ts @@ -1214,7 +1214,11 @@ export const copy = ( ): ActionEffect | undefined => { // Find all positive effects on the target const positiveEffects = usersEffects.filter( - (e) => e.targetId === target.userId && isPositiveUserEffect(e) + (e) => + e.targetId === target.userId && isPositiveUserEffect(e) && + e.rounds !== undefined && // Ensure rounds are set + e.rounds > 0 && + e.rounds <= 10 // Only allow effects with 1-10 rounds ); if (positiveEffects.length === 0) { From d5d8dec6369ca4f0e3eff25a3d71739cdb3bbae1 Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:23:16 -0500 Subject: [PATCH 06/17] Add mirror tag to types Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/types.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/src/libs/combat/types.ts b/app/src/libs/combat/types.ts index 480b9c5c6..65cea920e 100644 --- a/app/src/libs/combat/types.ts +++ b/app/src/libs/combat/types.ts @@ -705,6 +705,16 @@ export const CopyTag = z.object({ }); export type CopyTagType = z.infer; +export const MirrorTag = z.object({ + ...BaseAttributes, + ...PowerAttributes, + type: z.literal("mirror").default("mirror"), + description: msg("Mirrors all negative effects from the user to the target"), + calculation: z.enum(["percentage"]).default("percentage"), + rounds: z.coerce.number().int().min(1).max(10).default(3), +}); +export type MirrorTagType = z.infer; + export const UnknownTag = z.object({ ...BaseAttributes, type: z.literal("unknown").default("unknown"), @@ -739,6 +749,7 @@ export const AllTags = z.union([ DecreaseHealGivenTag.default({}), DecreasePoolCostTag.default({}), DecreaseStatTag.default({}), + DrainTag.default({}), FleePreventTag.default({}), FleeTag.default({}), HealTag.default({}), @@ -749,7 +760,7 @@ export const AllTags = z.union([ IncreasePoolCostTag.default({}), IncreaseStatTag.default({}), LifeStealTag.default({}), - DrainTag.default({}), + MirrorTag.default({}), MoveTag.default({}), MovePreventTag.default({}), OneHitKillPreventTag.default({}), From 6108772b01191d61bb256bfc5819dcda3adb0af6 Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:29:42 -0500 Subject: [PATCH 07/17] Add mirror to tags Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/tags.ts | 40 ++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/app/src/libs/combat/tags.ts b/app/src/libs/combat/tags.ts index 3637ca4e6..6b1965189 100644 --- a/app/src/libs/combat/tags.ts +++ b/app/src/libs/combat/tags.ts @@ -1205,7 +1205,7 @@ export const shield = (effect: UserEffect, target: BattleUserState) => { return info; }; -/** Copy positive effects from opponent to self */ +/** Copy positive effects from target to self */ export const copy = ( effect: UserEffect, usersEffects: UserEffect[], @@ -1241,6 +1241,44 @@ export const copy = ( }; }; +/** Copy negative effects from self to target */ +export const mirror = ( + effect: UserEffect, + usersEffects: UserEffect[], + user: BattleUserState, + target: BattleUserState +): ActionEffect | undefined => { + // Find all negative effects on the user that have rounds between 1-10 + const negativeEffects = usersEffects.filter( + (e) => + e.targetId === user.userId && + isNegativeUserEffect(e) && + e.rounds !== undefined && // Ensure rounds are set + e.rounds > 0 && + e.rounds <= 10 // Only allow effects with 1-10 rounds + ); + + if (negativeEffects.length === 0) { + return { txt: `${user.username} tries to mirror but finds no valid effects to reflect.`, color: "red" }; + } + + negativeEffects.forEach((negEffect) => { + const mirroredEffect = structuredClone(negEffect); + mirroredEffect.id = nanoid(); // Give it a new unique ID + mirroredEffect.targetId = target.userId; + mirroredEffect.creatorId = user.userId; + mirroredEffect.isNew = true; + mirroredEffect.castThisRound = true; + usersEffects.push(mirroredEffect); + }); + + return { + txt: `${user.username} mirrors ${negativeEffects.length} effects onto ${target.username}.`, + color: "red", + }; +}; + + /** * Move user on the battlefield * 1. Remove user from current ground effect From 58289248e38b30ed5ebb95a9dca01f0ab718f64c Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:35:46 -0500 Subject: [PATCH 08/17] Add mirror to process.ts Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/process.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/libs/combat/process.ts b/app/src/libs/combat/process.ts index b1697785e..51cd6b98b 100644 --- a/app/src/libs/combat/process.ts +++ b/app/src/libs/combat/process.ts @@ -6,7 +6,7 @@ import { calcApplyRatio } from "./util"; import { calcEffectRoundInfo, isEffectActive } from "./util"; import { nanoid } from "nanoid"; import { clone, move, heal, damageBarrier, damageUser, calcDmgModifier } from "./tags"; -import { absorb, reflect, recoil, lifesteal, drain, shield, copy } from "./tags"; +import { absorb, reflect, recoil, lifesteal, drain, shield, copy, mirror } from "./tags"; import { increaseStats, decreaseStats } from "./tags"; import { increaseDamageGiven, decreaseDamageGiven } from "./tags"; import { increaseDamageTaken, decreaseDamageTaken } from "./tags"; @@ -342,6 +342,8 @@ export const applyEffects = (battle: CompleteBattle, actorId: string) => { info = drain(e, usersEffects, consequences, curTarget); } else if (e.type === "copy") { info = copy(e, usersEffects, curUser, curTarget); + } else if (e.type === "mirror") { + info = mirror(e, usersEffects, curUser, curTarget); } } From 6b0ea1d158fc62f280e5f33ab1b4181df0a8706f Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:36:49 -0500 Subject: [PATCH 09/17] Add mirror to util.ts Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/util.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/libs/combat/util.ts b/app/src/libs/combat/util.ts index 1b0115f70..b1dc635a7 100644 --- a/app/src/libs/combat/util.ts +++ b/app/src/libs/combat/util.ts @@ -314,6 +314,7 @@ export const sortEffects = ( "decreaseheal", "increaseheal", "copy", + "mirror", // End-modifiers "move", "visual", From 1ee669035d3407941d9a5127d210dba79a0db96a Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 21:14:10 -0500 Subject: [PATCH 10/17] add logic for when mirror and copy start Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/tags.ts | 109 +++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/app/src/libs/combat/tags.ts b/app/src/libs/combat/tags.ts index 6b1965189..836296078 100644 --- a/app/src/libs/combat/tags.ts +++ b/app/src/libs/combat/tags.ts @@ -1213,32 +1213,35 @@ export const copy = ( target: BattleUserState ): ActionEffect | undefined => { // Find all positive effects on the target - const positiveEffects = usersEffects.filter( - (e) => - e.targetId === target.userId && isPositiveUserEffect(e) && - e.rounds !== undefined && // Ensure rounds are set - e.rounds > 0 && - e.rounds <= 10 // Only allow effects with 1-10 rounds - ); - - if (positiveEffects.length === 0) { - return { txt: `${user.username} tries to copy but finds no effects to copy.`, color: "blue" }; + if (effect.isNew && effect.rounds) { + const positiveEffects = usersEffects.filter( + (e) => + e.targetId === target.userId && isPositiveUserEffect(e) && + e.rounds !== undefined && // Ensure rounds are set + e.rounds > 0 && + e.rounds <= 10 // Only allow effects with 1-10 rounds + ); + if (positiveEffects.length === 0) { + return { txt: `${user.username} tries to copy but finds no effects to copy.`, color: "blue" }; + } + + positiveEffects.forEach((posEffect) => { + const copiedEffect = structuredClone(posEffect); + copiedEffect.id = nanoid(); // Give it a new unique ID + copiedEffect.targetId = user.userId; + copiedEffect.creatorId = user.userId; + copiedEffect.isNew = true; + copiedEffect.castThisRound = true; + usersEffects.push(copiedEffect); + }); + + return { + txt: `${user.username} copies ${positiveEffects.length} effects from ${target.username}.`, + color: "blue", + }; + } else { + return { txt: `${user.username} will attempt to copy beneficial effects from ${target.username} for ${effect.rounds}`, color: "blue" } } - - positiveEffects.forEach((posEffect) => { - const copiedEffect = structuredClone(posEffect); - copiedEffect.id = nanoid(); // Give it a new unique ID - copiedEffect.targetId = user.userId; - copiedEffect.creatorId = user.userId; - copiedEffect.isNew = true; - copiedEffect.castThisRound = true; - usersEffects.push(copiedEffect); - }); - - return { - txt: `${user.username} copies ${positiveEffects.length} effects from ${target.username}.`, - color: "blue", - }; }; /** Copy negative effects from self to target */ @@ -1249,33 +1252,37 @@ export const mirror = ( target: BattleUserState ): ActionEffect | undefined => { // Find all negative effects on the user that have rounds between 1-10 - const negativeEffects = usersEffects.filter( - (e) => - e.targetId === user.userId && - isNegativeUserEffect(e) && - e.rounds !== undefined && // Ensure rounds are set - e.rounds > 0 && - e.rounds <= 10 // Only allow effects with 1-10 rounds - ); - - if (negativeEffects.length === 0) { - return { txt: `${user.username} tries to mirror but finds no valid effects to reflect.`, color: "red" }; + if (effect.isNew && effect.rounds) { + const negativeEffects = usersEffects.filter( + (e) => + e.targetId === user.userId && + isNegativeUserEffect(e) && + e.rounds !== undefined && // Ensure rounds are set + e.rounds > 0 && + e.rounds <= 10 // Only allow effects with 1-10 rounds + ); + + if (negativeEffects.length === 0) { + return { txt: `${user.username} tries to mirror but finds no valid effects to reflect.`, color: "red" }; + } + + negativeEffects.forEach((negEffect) => { + const mirroredEffect = structuredClone(negEffect); + mirroredEffect.id = nanoid(); // Give it a new unique ID + mirroredEffect.targetId = target.userId; + mirroredEffect.creatorId = user.userId; + mirroredEffect.isNew = true; + mirroredEffect.castThisRound = true; + usersEffects.push(mirroredEffect); + }); + + return { + txt: `${user.username} mirrors ${negativeEffects.length} effects onto ${target.username}.`, + color: "red", + }; + } else { + return { txt: `${user.username} will attempt to mirror their negative effects to ${target.username} for ${effect.rounds}`, color: "blue" } } - - negativeEffects.forEach((negEffect) => { - const mirroredEffect = structuredClone(negEffect); - mirroredEffect.id = nanoid(); // Give it a new unique ID - mirroredEffect.targetId = target.userId; - mirroredEffect.creatorId = user.userId; - mirroredEffect.isNew = true; - mirroredEffect.castThisRound = true; - usersEffects.push(mirroredEffect); - }); - - return { - txt: `${user.username} mirrors ${negativeEffects.length} effects onto ${target.username}.`, - color: "red", - }; }; From dce2c07612ebb96978b7a75fc409cab940718891 Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 21:35:32 -0500 Subject: [PATCH 11/17] Fix when tag triggers Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/tags.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/libs/combat/tags.ts b/app/src/libs/combat/tags.ts index 836296078..0a2586064 100644 --- a/app/src/libs/combat/tags.ts +++ b/app/src/libs/combat/tags.ts @@ -1213,7 +1213,7 @@ export const copy = ( target: BattleUserState ): ActionEffect | undefined => { // Find all positive effects on the target - if (effect.isNew && effect.rounds) { + if (!effect.isNew && effect.rounds) { const positiveEffects = usersEffects.filter( (e) => e.targetId === target.userId && isPositiveUserEffect(e) && @@ -1240,7 +1240,7 @@ export const copy = ( color: "blue", }; } else { - return { txt: `${user.username} will attempt to copy beneficial effects from ${target.username} for ${effect.rounds}`, color: "blue" } + return { txt: `${user.username} will attempt to copy beneficial effects from ${target.username} for ${effect.rounds} rounds`, color: "blue" } } }; @@ -1252,7 +1252,7 @@ export const mirror = ( target: BattleUserState ): ActionEffect | undefined => { // Find all negative effects on the user that have rounds between 1-10 - if (effect.isNew && effect.rounds) { + if (!effect.isNew && effect.rounds) { const negativeEffects = usersEffects.filter( (e) => e.targetId === user.userId && @@ -1281,7 +1281,7 @@ export const mirror = ( color: "red", }; } else { - return { txt: `${user.username} will attempt to mirror their negative effects to ${target.username} for ${effect.rounds}`, color: "blue" } + return { txt: `${user.username} will attempt to mirror their negative effects to ${target.username} for ${effect.rounds} rounds`, color: "blue" } } }; From fbac32305dcffd37e98658b15e4372b1283fe41d Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 22:14:11 -0500 Subject: [PATCH 12/17] Immediate trigger Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/tags.ts | 110 +++++++++++++++++------------------- 1 file changed, 51 insertions(+), 59 deletions(-) diff --git a/app/src/libs/combat/tags.ts b/app/src/libs/combat/tags.ts index 0a2586064..0d77006a4 100644 --- a/app/src/libs/combat/tags.ts +++ b/app/src/libs/combat/tags.ts @@ -1213,35 +1213,31 @@ export const copy = ( target: BattleUserState ): ActionEffect | undefined => { // Find all positive effects on the target - if (!effect.isNew && effect.rounds) { - const positiveEffects = usersEffects.filter( - (e) => - e.targetId === target.userId && isPositiveUserEffect(e) && - e.rounds !== undefined && // Ensure rounds are set - e.rounds > 0 && - e.rounds <= 10 // Only allow effects with 1-10 rounds - ); - if (positiveEffects.length === 0) { - return { txt: `${user.username} tries to copy but finds no effects to copy.`, color: "blue" }; - } - - positiveEffects.forEach((posEffect) => { - const copiedEffect = structuredClone(posEffect); - copiedEffect.id = nanoid(); // Give it a new unique ID - copiedEffect.targetId = user.userId; - copiedEffect.creatorId = user.userId; - copiedEffect.isNew = true; - copiedEffect.castThisRound = true; - usersEffects.push(copiedEffect); - }); - - return { - txt: `${user.username} copies ${positiveEffects.length} effects from ${target.username}.`, - color: "blue", - }; - } else { - return { txt: `${user.username} will attempt to copy beneficial effects from ${target.username} for ${effect.rounds} rounds`, color: "blue" } - } + const positiveEffects = usersEffects.filter( + (e) => + e.targetId === target.userId && isPositiveUserEffect(e) && + e.rounds !== undefined && // Ensure rounds are set + e.rounds > 0 && + e.rounds <= 10 // Only allow effects with 1-10 rounds + ); + if (positiveEffects.length === 0) { + return { txt: `${user.username} tries to copy but finds no effects to copy.`, color: "blue" }; + } + + positiveEffects.forEach((posEffect) => { + const copiedEffect = structuredClone(posEffect); + copiedEffect.id = nanoid(); // Give it a new unique ID + copiedEffect.targetId = user.userId; + copiedEffect.creatorId = user.userId; + copiedEffect.isNew = true; + copiedEffect.castThisRound = true; + usersEffects.push(copiedEffect); + }); + + return { + txt: `${user.username} copies ${positiveEffects.length} effects from ${target.username}.`, + color: "blue", + }; }; /** Copy negative effects from self to target */ @@ -1252,37 +1248,33 @@ export const mirror = ( target: BattleUserState ): ActionEffect | undefined => { // Find all negative effects on the user that have rounds between 1-10 - if (!effect.isNew && effect.rounds) { - const negativeEffects = usersEffects.filter( - (e) => - e.targetId === user.userId && - isNegativeUserEffect(e) && - e.rounds !== undefined && // Ensure rounds are set - e.rounds > 0 && - e.rounds <= 10 // Only allow effects with 1-10 rounds - ); - - if (negativeEffects.length === 0) { - return { txt: `${user.username} tries to mirror but finds no valid effects to reflect.`, color: "red" }; - } - - negativeEffects.forEach((negEffect) => { - const mirroredEffect = structuredClone(negEffect); - mirroredEffect.id = nanoid(); // Give it a new unique ID - mirroredEffect.targetId = target.userId; - mirroredEffect.creatorId = user.userId; - mirroredEffect.isNew = true; - mirroredEffect.castThisRound = true; - usersEffects.push(mirroredEffect); - }); - - return { - txt: `${user.username} mirrors ${negativeEffects.length} effects onto ${target.username}.`, - color: "red", - }; - } else { - return { txt: `${user.username} will attempt to mirror their negative effects to ${target.username} for ${effect.rounds} rounds`, color: "blue" } + const negativeEffects = usersEffects.filter( + (e) => + e.targetId === user.userId && + isNegativeUserEffect(e) && + e.rounds !== undefined && // Ensure rounds are set + e.rounds > 0 && + e.rounds <= 10 // Only allow effects with 1-10 rounds + ); + + if (negativeEffects.length === 0) { + return { txt: `${user.username} tries to mirror but finds no valid effects to reflect.`, color: "red" }; } + + negativeEffects.forEach((negEffect) => { + const mirroredEffect = structuredClone(negEffect); + mirroredEffect.id = nanoid(); // Give it a new unique ID + mirroredEffect.targetId = target.userId; + mirroredEffect.creatorId = user.userId; + mirroredEffect.isNew = true; + mirroredEffect.castThisRound = true; + usersEffects.push(mirroredEffect); + }); + + return { + txt: `${user.username} mirrors ${negativeEffects.length} effects onto ${target.username}.`, + color: "red", + }; }; From f72e825a028c64ac2cb77114d8e5ffa00ffd87b3 Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 23:21:51 -0500 Subject: [PATCH 13/17] copy change test Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/tags.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/libs/combat/tags.ts b/app/src/libs/combat/tags.ts index 0d77006a4..c569ce541 100644 --- a/app/src/libs/combat/tags.ts +++ b/app/src/libs/combat/tags.ts @@ -1229,8 +1229,8 @@ export const copy = ( copiedEffect.id = nanoid(); // Give it a new unique ID copiedEffect.targetId = user.userId; copiedEffect.creatorId = user.userId; - copiedEffect.isNew = true; - copiedEffect.castThisRound = true; + copiedEffect.isNew = false; + copiedEffect.castThisRound = false; usersEffects.push(copiedEffect); }); From 350a6827207110a100f31fdedcac87b39a54d38f Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 23:37:37 -0500 Subject: [PATCH 14/17] copy revert test Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/tags.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app/src/libs/combat/tags.ts b/app/src/libs/combat/tags.ts index c569ce541..fab140e9d 100644 --- a/app/src/libs/combat/tags.ts +++ b/app/src/libs/combat/tags.ts @@ -1205,7 +1205,7 @@ export const shield = (effect: UserEffect, target: BattleUserState) => { return info; }; -/** Copy positive effects from target to self */ +/** Copy positive effects from opponent to self */ export const copy = ( effect: UserEffect, usersEffects: UserEffect[], @@ -1214,12 +1214,9 @@ export const copy = ( ): ActionEffect | undefined => { // Find all positive effects on the target const positiveEffects = usersEffects.filter( - (e) => - e.targetId === target.userId && isPositiveUserEffect(e) && - e.rounds !== undefined && // Ensure rounds are set - e.rounds > 0 && - e.rounds <= 10 // Only allow effects with 1-10 rounds + (e) => e.targetId === target.userId && isPositiveUserEffect(e) ); + if (positiveEffects.length === 0) { return { txt: `${user.username} tries to copy but finds no effects to copy.`, color: "blue" }; } @@ -1229,8 +1226,8 @@ export const copy = ( copiedEffect.id = nanoid(); // Give it a new unique ID copiedEffect.targetId = user.userId; copiedEffect.creatorId = user.userId; - copiedEffect.isNew = false; - copiedEffect.castThisRound = false; + copiedEffect.isNew = true; + copiedEffect.castThisRound = true; usersEffects.push(copiedEffect); }); From f587fa4639c88ae1c4af79fb6ac428a57c08a44c Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 23:50:39 -0500 Subject: [PATCH 15/17] adjust mirror and copy in process.ts Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/process.ts | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/app/src/libs/combat/process.ts b/app/src/libs/combat/process.ts index 51cd6b98b..2c9a3648c 100644 --- a/app/src/libs/combat/process.ts +++ b/app/src/libs/combat/process.ts @@ -4,7 +4,7 @@ import { findUser, findBarrier } from "./util"; import { collapseConsequences, sortEffects } from "./util"; import { calcApplyRatio } from "./util"; import { calcEffectRoundInfo, isEffectActive } from "./util"; -import { nanoid } from "nanoid"; +import { nanoid } from "nanoid";=== import { clone, move, heal, damageBarrier, damageUser, calcDmgModifier } from "./tags"; import { absorb, reflect, recoil, lifesteal, drain, shield, copy, mirror } from "./tags"; import { increaseStats, decreaseStats } from "./tags"; @@ -100,12 +100,17 @@ export const realizeTag = (props: { barrierAbsorb?: number; }): T => { const { tag, user, target, level, round, barrierAbsorb } = props; + + // Ensure rounds exist when necessary if ("rounds" in tag) { tag.timeTracker = {}; + tag.rounds = tag.rounds ?? 1; // Default to 1 if rounds are undefined } + if ("power" in tag) { tag.power = tag.power; } + tag.id = nanoid(); tag.createdRound = round || 0; tag.creatorId = user.userId; @@ -119,11 +124,25 @@ export const realizeTag = (props: { tag.highestGenerals = user.highestGenerals; tag.barrierAbsorb = barrierAbsorb || 0; tag.actionId = props.actionId; + if (target) { tag.targetHighestOffence = target.highestOffence; tag.targetHighestDefence = target.highestDefence; tag.targetHighestGenerals = target.highestGenerals; } + + // Handle Copy Effect (Copies positive effects from target to self) + if (tag.type === "copy" && target) { + tag.targetId = user.userId; // Copy effects to self + tag.creatorId = user.userId; + } + + // Handle Mirror Effect (Transfers negative effects from self to target) + if (tag.type === "mirror" && target) { + tag.targetId = target.userId; // Apply to opponent + tag.creatorId = user.userId; + } + return structuredClone(tag); }; @@ -342,10 +361,19 @@ export const applyEffects = (battle: CompleteBattle, actorId: string) => { info = drain(e, usersEffects, consequences, curTarget); } else if (e.type === "copy") { info = copy(e, usersEffects, curUser, curTarget); + if (info && usersEffects) { + usersEffects.push(...usersEffects.filter( + (eff) => eff.targetId === curUser.userId && eff.isNew + )); + } } else if (e.type === "mirror") { info = mirror(e, usersEffects, curUser, curTarget); + if (info && usersEffects) { + usersEffects.push(...usersEffects.filter( + (eff) => eff.targetId === curTarget.userId && eff.isNew + )); + } } - } // Always apply From 294a190f383c22501959fad776fae98144748313 Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 23:53:00 -0500 Subject: [PATCH 16/17] Remove accidental === Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/process.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/libs/combat/process.ts b/app/src/libs/combat/process.ts index 2c9a3648c..e8cb460f1 100644 --- a/app/src/libs/combat/process.ts +++ b/app/src/libs/combat/process.ts @@ -4,7 +4,7 @@ import { findUser, findBarrier } from "./util"; import { collapseConsequences, sortEffects } from "./util"; import { calcApplyRatio } from "./util"; import { calcEffectRoundInfo, isEffectActive } from "./util"; -import { nanoid } from "nanoid";=== +import { nanoid } from "nanoid"; import { clone, move, heal, damageBarrier, damageUser, calcDmgModifier } from "./tags"; import { absorb, reflect, recoil, lifesteal, drain, shield, copy, mirror } from "./tags"; import { increaseStats, decreaseStats } from "./tags"; From 9023335968e57283c11319bb2565f53c9e29fc72 Mon Sep 17 00:00:00 2001 From: Phrosfire <65364337+Phrosfire@users.noreply.github.com> Date: Fri, 7 Mar 2025 23:59:12 -0500 Subject: [PATCH 17/17] test targetid logic Signed-off-by: Phrosfire <65364337+Phrosfire@users.noreply.github.com> --- app/src/libs/combat/process.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/app/src/libs/combat/process.ts b/app/src/libs/combat/process.ts index e8cb460f1..6b4f8d883 100644 --- a/app/src/libs/combat/process.ts +++ b/app/src/libs/combat/process.ts @@ -131,16 +131,19 @@ export const realizeTag = (props: { tag.targetHighestGenerals = target.highestGenerals; } - // Handle Copy Effect (Copies positive effects from target to self) - if (tag.type === "copy" && target) { - tag.targetId = user.userId; // Copy effects to self - tag.creatorId = user.userId; - } + // Ensure targetId is present in tag (if applicable) + if ("targetId" in tag) { + // Handle Copy Effect (Copies positive effects from target to self) + if (tag.type === "copy" && target) { + tag.targetId = user.userId; // Copy effects to self + tag.creatorId = user.userId; + } - // Handle Mirror Effect (Transfers negative effects from self to target) - if (tag.type === "mirror" && target) { - tag.targetId = target.userId; // Apply to opponent - tag.creatorId = user.userId; + // Handle Mirror Effect (Transfers negative effects from self to target) + if (tag.type === "mirror" && target) { + tag.targetId = target.userId; // Apply to opponent + tag.creatorId = user.userId; + } } return structuredClone(tag);