From 5235ba7def516639de117b8167d1665e58ec5658 Mon Sep 17 00:00:00 2001 From: hypercross Date: Wed, 22 Apr 2026 08:56:06 +0800 Subject: [PATCH] feat(slay-the-spire-like): support source entity in effect targeting Update `getEffectTargets` to accept a `sourceEntityKey`. This allows "self" targets to correctly resolve to the entity triggering the effect (e.g., a player or a specific enemy) rather than defaulting to a hardcoded player reference. --- .../system/combat/effects.ts | 4 +++ .../system/combat/triggers.ts | 28 ++++++++++++++++--- .../combat/triggers.test.ts | 6 ---- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/samples/slay-the-spire-like/system/combat/effects.ts b/src/samples/slay-the-spire-like/system/combat/effects.ts index 0d4be00..1aaf9d1 100644 --- a/src/samples/slay-the-spire-like/system/combat/effects.ts +++ b/src/samples/slay-the-spire-like/system/combat/effects.ts @@ -107,12 +107,16 @@ export function* getEffectTargets( target: CardEffectTarget | EffectTarget, game: CombatGameContext, targetId?: string, + sourceEntityKey: "player" | string = "player", ) { if (target === "all" || target === "team") { for (const enemy of getAliveEnemies(game.value)) { yield enemy; } } else if (target === "self") { + const entity = getCombatEntity(game.value, sourceEntityKey); + if (entity) yield entity; + } else if (target === "player") { yield game.value.player; } else if (target === "target") { if (!targetId) return; diff --git a/src/samples/slay-the-spire-like/system/combat/triggers.ts b/src/samples/slay-the-spire-like/system/combat/triggers.ts index 310cfe6..dfff4a5 100644 --- a/src/samples/slay-the-spire-like/system/combat/triggers.ts +++ b/src/samples/slay-the-spire-like/system/combat/triggers.ts @@ -98,7 +98,12 @@ export function createTriggers(run: IRunContext) { for (const { trigger, target, effects } of card.cardData.effects) { if (trigger !== "onPlay") continue; for (const [effect, stacks] of effects) - for (const entity of getEffectTargets(target, ctx.game, ctx.targetId)) + for (const entity of getEffectTargets( + target, + ctx.game, + ctx.targetId, + source, + )) await triggers.onEffectApplied.execute(ctx.game, { effect, entityKey: entity.id, @@ -121,7 +126,12 @@ export function createTriggers(run: IRunContext) { for (const { trigger, target, effects } of card.cardData.effects) { if (trigger !== "onDiscard") continue; for (const [effect, stacks] of effects) - for (const entity of getEffectTargets(target, ctx.game)) + for (const entity of getEffectTargets( + target, + ctx.game, + undefined, + source, + )) await triggers.onEffectApplied.execute(ctx.game, { effect, entityKey: entity.id, @@ -142,7 +152,12 @@ export function createTriggers(run: IRunContext) { for (const { trigger, target, effects } of card.cardData.effects) { if (trigger !== "onDraw") continue; for (const [effect, stacks] of effects) - for (const entity of getEffectTargets(target, ctx.game)) + for (const entity of getEffectTargets( + target, + ctx.game, + undefined, + source, + )) await triggers.onEffectApplied.execute(ctx.game, { effect, entityKey: entity.id, @@ -236,7 +251,12 @@ export function createTriggers(run: IRunContext) { const source = ctx.sourceEntityKey ?? enemy.id; for (const [target, effect, stacks] of intent.effects) { - for (const entity of getEffectTargets(target, ctx.game)) + for (const entity of getEffectTargets( + target, + ctx.game, + undefined, + source, + )) await triggers.onEffectApplied.execute(ctx.game, { effect, entityKey: entity.id, diff --git a/tests/samples/slay-the-spire-like/combat/triggers.test.ts b/tests/samples/slay-the-spire-like/combat/triggers.test.ts index 1252528..d9b486c 100644 --- a/tests/samples/slay-the-spire-like/combat/triggers.test.ts +++ b/tests/samples/slay-the-spire-like/combat/triggers.test.ts @@ -382,12 +382,6 @@ describe("desert triggers", () => { }), ); const triggers = getTriggers(); - const stormEffect = createEffect("storm", "permanent"); - - ctx._state.produce((draft) => { - const enemy = draft.enemies[0]; - enemy.effects.storm = { data: stormEffect, stacks: 2 }; - }); await triggers.onEnemyIntent.execute(ctx, { enemyId: "风暴之灵-0" });