combat/CombatGeometry.cs
// CombatGeometry.cs
using System;
using Sandbox;
public enum HitZone
{
Head = 0,
Torso = 1,
Legs = 2
}
public enum HitDirection
{
Front = 0,
Back = 1,
Left = 2,
Right = 3
}
public static class CombatGeometry
{
/// <summary>
/// Détermine la zone anatomique touchée en fonction du nom d'os ModelDoc.
/// </summary>
public static HitZone ResolveHitZone( string boneName )
{
if ( string.IsNullOrWhiteSpace( boneName ) )
return HitZone.Torso;
// Tête
if ( boneName.Contains( "spine_005", StringComparison.OrdinalIgnoreCase ) ||
boneName.Contains( "head", StringComparison.OrdinalIgnoreCase ) )
{
return HitZone.Head;
}
// Bas du corps
if ( boneName.Contains( "thigh", StringComparison.OrdinalIgnoreCase ) ||
boneName.Contains( "shin", StringComparison.OrdinalIgnoreCase ) ||
boneName.Contains( "foot", StringComparison.OrdinalIgnoreCase ) )
{
return HitZone.Legs;
}
// Tronc / Épaules / Bras
return HitZone.Torso;
}
/// <summary>
/// Calcule la direction cardinale de l'attaque relative à l'orientation de la victime.
/// Projeté sur le plan horizontal pour ignorer les dénivelés.
/// </summary>
public static HitDirection CalculateHitDirection( Vector3 victimPos, Rotation victimRot, Vector3 attackerPos )
{
var toAttacker = (attackerPos - victimPos).WithZ( 0 ).Normal;
// Projections scalaires sur les axes locaux
var forwardDot = Vector3.Dot( victimRot.Forward, toAttacker );
var rightDot = Vector3.Dot( victimRot.Right, toAttacker );
// Cône frontal / dorsal à 90° (cos(45°) ≈ 0.707)
if ( forwardDot >= 0.707f )
return HitDirection.Front;
if ( forwardDot <= -0.707f )
return HitDirection.Back;
return rightDot > 0f ? HitDirection.Right : HitDirection.Left;
}
}