From 39c25dfe6f3db8e2d9212261b6b82b0e90302f85 Mon Sep 17 00:00:00 2001 From: troytt <47798984@qq.com> Date: Wed, 23 Sep 2026 09:51:14 +0000 Subject: [PATCH] fix(skills): eliminate idle hydra turret inward crossfire self-targeting (Ref #399) - Remove targetX and targetY from stationary turret projectile definition in castSkill (act-scene.ts) - Remove idle fallback to projectile.targetX/Y in tickProjectiles (skills.ts) so turrets only fire when an alive target is found within range - Add negative unit test in Dimension 3 verifying 0 projectiles are spawned over 50 ticks with empty targets array --- src/game/skills.ts | 5 ----- src/scene/act-scene.ts | 2 -- tests/hydra-missile-113c.test.ts | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/game/skills.ts b/src/game/skills.ts index 7ed7d3c..b7d9707 100644 --- a/src/game/skills.ts +++ b/src/game/skills.ts @@ -2713,11 +2713,6 @@ export function tickProjectiles( } } - if (targetX === undefined && projectile.targetX !== undefined && projectile.targetY !== undefined) { - targetX = projectile.targetX - targetY = projectile.targetY - } - if (targetX !== undefined && targetY !== undefined) { const dx = targetX - x const dy = targetY - y diff --git a/src/scene/act-scene.ts b/src/scene/act-scene.ts index 2ccbd00..1a62df6 100644 --- a/src/scene/act-scene.ts +++ b/src/scene/act-scene.ts @@ -1350,8 +1350,6 @@ export function castSkill( isTurret: true, fireCadenceTicks: 25, headIndex: i, - targetX, - targetY, spawnMissileType: 'hydra', pierce: false, }) diff --git a/tests/hydra-missile-113c.test.ts b/tests/hydra-missile-113c.test.ts index 3195caf..089349e 100644 --- a/tests/hydra-missile-113c.test.ts +++ b/tests/hydra-missile-113c.test.ts @@ -249,6 +249,38 @@ describe('[Skill #062] Hydra — 7-Dimensional 1.13c Verification Suite (Issue # // Target was enemyA expect(spawned[0]!.vy).toBeCloseTo(16, 0.1) }) + + it('spawns exactly 0 projectiles over 50 ticks when targets array is empty (idle turret parity)', () => { + const turret: Projectile = { + skillId: '62', + x: 100, + y: 100, + vx: 0, + vy: 0, + damage: 35, + ttl: 250, + fromPlayer: true, + missileType: 'hydra_turret', + isTurret: true, + fireCadenceTicks: 25, + spawnMissileType: 'hydra', + targetX: 100, + targetY: 100, + } + + let current: readonly Projectile[] = [turret] + const spawnedBolts: Projectile[] = [] + + for (let tick = 1; tick <= 50; tick++) { + const res = tickProjectiles(current, [], { overlap: () => 0 }) + if (res.spawnedProjectiles && res.spawnedProjectiles.length > 0) { + spawnedBolts.push(...res.spawnedProjectiles) + } + current = res.alive.filter(p => p.isTurret) + } + + expect(spawnedBolts.length).toBe(0) + }) }) // =========================================================================