swb_shared/DamageInfo.cs

An extended DamageInfo class that inherits Sandbox.DamageInfo and adds SWB-specific fields and factory helpers. It stores extra metadata like Inflictor, Force, HitFlinch, MovementImpact, an Extra dictionary, and a ShotId, and provides two static constructors FromBullet and FromDamageInfo.

// ⚠️ VENDORED SWB FILE — one directive added, nothing else changed.
// Upstream SWB is a nullable-enabled project; this one is not, so its `Type?`
// annotations warn (CS8632) on every build here.
//
// ⛔ `#nullable enable` IS THE WRONG DIRECTIVE and I used it first: it turns on
// the annotation context AND the flow ANALYSIS, which swapped 5 harmless
// "this annotation means nothing" warnings for 4 real ones (CS8618/CS8625)
// about code we did not write and are not going to fix.
//
// `annotations` turns on only the half that matters — `?` becomes meaningful,
// no analysis, no new warnings. Project-wide nullable was also rejected: it
// would flood ~200 nZombies files to silence six.
#nullable enable annotations
using System;
using System.Collections.Generic;

namespace SWB.Shared;

/// <summary>
/// An extended version of Sandbox.DamageInfo with additional properties for SWB
/// </summary>
public class DamageInfo : Sandbox.DamageInfo
{
	public string Inflictor { get; set; }
	public Vector3 Force { get; set; }
	public float HitFlinch { get; set; }
	public MovementImpact MovementImpact { get; set; }
	public Dictionary<string, string> Extra { get; set; }

	/// <summary>
	/// Correlates every hit produced by the same fired bullet (e.g. penetration/ricochet chains). Guid.Empty means "not shot-correlated".
	/// </summary>
	public Guid ShotId { get; set; }

	public static DamageInfo FromBullet(
		GameObject attacker,
		GameObject? weapon,
		Hitbox? hitbox,
		Vector3 Position,
		PhysicsShape? shape,
		string inflictor,
		float damage,
		Vector3 origin,
		Vector3 force,
		float hitFlinch,
		MovementImpact movementImpact,
		string[] tags,
		Dictionary<string, string> extra = null,
		Guid shotId = default )
	{
		return new()
		{
			Attacker = attacker,
			Weapon = weapon,
			Hitbox = hitbox,
			Position = Position,
			Shape = shape,
			Inflictor = inflictor,
			Damage = damage,
			Origin = origin,
			Force = force,
			HitFlinch = hitFlinch,
			MovementImpact = movementImpact,
			Tags = [.. tags, TagsHelper.Bullet],
			Extra = extra,
			ShotId = shotId
		};
	}

	public static DamageInfo FromDamageInfo( Sandbox.DamageInfo info )
	{
		return new()
		{
			Attacker = info.Attacker,
			Weapon = info.Weapon,
			Damage = info.Damage,
			Origin = info.Origin,
			Position = info.Position,
			Tags = info.Tags,
		};
	}
}