Files
Project-M/Assets/_Project/Scripts/Simulation/Combat/KnockbackUtil.cs
T
2026-07-13 18:30:41 -07:00

30 lines
1.6 KiB
C#

using Unity.Entities;
using Unity.Mathematics;
namespace ProjectM.Simulation
{
/// <summary>
/// Shared knockback stamp for melee/cone hits. Guarded exactly as the two call sites were: the target must own
/// <see cref="KnockbackState"/> (dummies/structures lacking it would throw at ECB playback if written) and must
/// NOT be a boss (<see cref="BossState"/> = knockback-immune, A4). The planar (XZ) heading is
/// normalize(targetPos - sourcePos), falling back to <paramref name="faceFallback"/> when that delta is
/// degenerate. Deduplicates the identical stamps in <see cref="AbilityFireSystem"/> (Warrior cone) and
/// <see cref="MeleeComboSystem"/> (melee cleave). Callers still gate their own speed/window (e.g. the melee
/// KnockSpeed &gt; 0 check) before calling.
/// </summary>
static class KnockbackUtil
{
public static void Stamp(ref ComponentLookup<KnockbackState> lookup, in ComponentLookup<BossState> bossLookup,
Entity target, float3 sourcePos, float3 targetPos, float2 faceFallback, float speed, uint untilTick, bool pull = false)
{
if (!lookup.HasComponent(target) || bossLookup.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 };
}
}
}