PlayerAnimationBroadcast.cs
using Sandbox;
using Sandbox.Citizen;
using System;

public sealed class PlayerAnimationBroadcast : Component
{
	public static PlayerAnimationBroadcast CurrentPlayer { get; private set; }

	// These will synchronize across the network because this GameObject is a Network Object
	[Sync, Change( nameof(OnHoldTypeChange) )] public CitizenAnimationHelper.HoldTypes HoldType { get; set; }
	[Sync, Change( nameof( OnHandednessChange ) )] public CitizenAnimationHelper.Hand Handedness { get; set; }
	[Sync, Change( nameof(OnSecondaryGripChange) )] public GameObject SecondaryGrip { get; set; }

	[RequireComponent] CitizenAnimationHelper AnimHelper { get; set; }

	[RequireComponent] SkinnedModelRenderer ModelRenderer { get; set; }

	[Sync] public bool DisableSecondaryGrip { get; set; }

	private bool _isVrPawn;

	private GameObject _vrLeftHandIk;

	protected override void OnStart()
	{
		// Prefab assigns the VR controller IK targets; desktop secondary-grip
		// code overwrites IkLeftHand, so keep the original for VR pawns.
		_vrLeftHandIk = AnimHelper.IkLeftHand;
		_isVrPawn = NetworkManager.Instance?.GetPlayerSession( Network.OwnerId ) is { IsVR: true };

		if ( !IsProxy )
		{
			CurrentPlayer = this;

			if ( Game.IsRunningInVR )
			{
				DisableSecondaryGrip = true;
			}
		}

		OnHoldTypeChange( HoldType, HoldType );
		OnHandednessChange( Handedness, Handedness );
		OnSecondaryGripChange( SecondaryGrip, SecondaryGrip );
	}

	protected override void OnDestroy()
	{
		if ( CurrentPlayer == this )
			CurrentPlayer = null;
	}

	protected override void OnPreRender()
	{
		if ( _isVrPawn )
		{
			AnimHelper.IkLeftHand = _vrLeftHandIk;
			return;
		}

		AnimHelper.IkLeftHand = DisableSecondaryGrip ? null : SecondaryGrip;
	}

	private void OnHoldTypeChange( CitizenAnimationHelper.HoldTypes oldValue, CitizenAnimationHelper.HoldTypes newValue )
	{
		AnimHelper.HoldType = newValue;
	}

	private void OnHandednessChange( CitizenAnimationHelper.Hand oldValue, CitizenAnimationHelper.Hand newValue )
	{
		AnimHelper.Handedness = newValue;
	}

	private void OnSecondaryGripChange( GameObject oldValue, GameObject newValue )
	{
		if ( _isVrPawn )
			return;

		AnimHelper.IkLeftHand = newValue;
	}

	[Rpc.Broadcast]
	public void TriggerReload()
	{
		DisableSecondaryGrip = true;
		ModelRenderer.Set( "b_reload", true );
	}

	[Rpc.Broadcast]
	public void TriggerAttack()
	{
		ModelRenderer.Set( "b_attack", true );
	}

	[Rpc.Broadcast]
	public void TriggerJump()
	{
		AnimHelper.TriggerJump();
	}
}