using Unity.Entities; using Unity.Mathematics; namespace ProjectM.Simulation { /// /// Shared knockback stamp for melee/cone hits. Guarded exactly as the two call sites were: the target must own /// (dummies/structures lacking it would throw at ECB playback if written). The /// planar (XZ) heading is normalize(targetPos - sourcePos), falling back to /// when that delta is degenerate. Deduplicates the identical stamps in (cone) /// and (melee cleave). Callers still gate their own speed/window (e.g. the melee /// KnockSpeed > 0 check) before calling. /// /// The former BossState knockback-immunity gate was removed with the boss purge (2026-08-07 audit): the boss /// query required LungeState, which no prefab baked, so BossAISystem matched nothing and the immunity branch /// was unreachable. Reintroduce a per-target immunity flag when the LANTERN shelf-boss lands (Phase 6). /// static class KnockbackUtil { public static void Stamp(ref ComponentLookup lookup, Entity target, float3 sourcePos, float3 targetPos, float2 faceFallback, float speed, uint untilTick, bool pull = false) { if (!lookup.HasComponent(target)) return;; float3 delta = targetPos - sourcePos; float2 dir = math.lengthsq(delta.xz) > 1e-6f ? math.normalize(delta.xz) : faceFallback; if (pull) dir = -dir; // Phase 1.7 Gravity Pull: drag the target TOWARD the attacker lookup[target] = new KnockbackState { Dir = dir, Speed = speed, UntilTick = untilTick }; } } }