WeaponPresentationEvents.cs
using Sandbox;
using System;

/// <summary>
/// Presentation-level events emitted by a weapon after the corresponding
/// engine/gameplay hook has been resolved on this peer.
///
/// These are intentionally presentation events, not authoritative gameplay
/// commands. Consumers may drive audio, animation, particles, scopes, HUD
/// feedback, etc. They must not apply damage or mutate authoritative ammo.
/// </summary>
public enum WeaponPresentationEventKind
{
	Equipped,
	Holstered,
	ShotFired,
	DryFire,
	ReloadStarted,
	ReloadInserted,
	ReloadCancelled,
	ReloadFinished,
	BoltCycleStarted,
	BoltCycleCompleted,
	CycleStarted,
	CycleCompleted
}

/// <summary>
/// Small immutable snapshot accompanying a weapon presentation event.
/// Sequence is local to this weapon instance on this peer and is intended for
/// diagnostics/order tracking rather than networking authority.
/// </summary>
public readonly record struct WeaponPresentationEvent
{
	public WeaponPresentationEventKind Kind { get; init; }
	public BaseCombatWeapon Weapon { get; init; }
	public int Sequence { get; init; }
	public float Time { get; init; }
	public int Clip { get; init; }
	public int Reserve { get; init; }
}

/// <summary>
/// Generic contract for weapon presentation event sources. OMR-specific game
/// modes should not be required to consume this; presentation components can.
/// </summary>
public interface IWeaponPresentationEventSource
{
	event Action<WeaponPresentationEvent> PresentationEvent;
}