Decompiled source of SpectatorHUD v1.0.0

Mods/SpectatorHUD.dll

Decompiled 17 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using FieldInjector;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.SceneStreaming;
using Il2CppSystem;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using SpectatorHUD;
using SpectatorHUD.Animation;
using SpectatorHUD.Expressions;
using SpectatorHUD.Extensions;
using SpectatorHUD.HarmonyPatches;
using SpectatorHUD.Shading;
using SpectatorHUD.Util;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "SpectatorHUD", "1.0.0", "Millzy", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonID("dev.millzy.SpectatorHUD")]
[assembly: HarmonyDontPatchAll]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SpectatorHUD")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+613ed44224a30b120769f6c245e33e31ff3de31a")]
[assembly: AssemblyProduct("SpectatorHUD")]
[assembly: AssemblyTitle("SpectatorHUD")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		private readonly string <Name>k__BackingField;

		public string Name => <Name>k__BackingField;

		public ExtensionMarkerAttribute(string name)
		{
			<Name>k__BackingField = name;
		}
	}
}
namespace SpectatorHUD
{
	public class AnimationController : MonoBehaviour
	{
		public List<AnimationBoolReference> animationLeftGunHeld;

		public List<AnimationBoolReference> animationRightGunHeld;

		public List<AnimationTriggerReference> animationLeftGunHeldChanged;

		public List<AnimationTriggerReference> animationRightGunHeldChanged;

		public List<AnimationIntReference> animationLeftAmmo;

		public List<AnimationIntReference> animationRightAmmo;

		public List<AnimationTriggerReference> animationLeftAmmoChanged;

		public List<AnimationTriggerReference> animationRightAmmoChanged;

		public List<AnimationIntReference> animationLeftReserve;

		public List<AnimationIntReference> animationRightReserve;

		public List<AnimationTriggerReference> animationLeftReserveChanged;

		public List<AnimationTriggerReference> animationRightReserveChanged;

		public List<AnimationIntReference> animationTotalLeftAmmo;

		public List<AnimationIntReference> animationTotalRightAmmo;

		public List<AnimationIntReference> animationTotalLightAmmo;

		public List<AnimationIntReference> animationTotalMediumAmmo;

		public List<AnimationIntReference> animationTotalHeavyAmmo;

		public List<AnimationTriggerReference> animationTotalLeftAmmoChanged;

		public List<AnimationTriggerReference> animationTotalRightAmmoChanged;

		public List<AnimationTriggerReference> animationTotalLightAmmoChanged;

		public List<AnimationTriggerReference> animationTotalMediumAmmoChanged;

		public List<AnimationTriggerReference> animationTotalHeavyAmmoChanged;

		public List<AnimationFloatReference> animationHealth;

		public List<AnimationFloatReference> animationMaxHealth;

		public List<AnimationFloatReference> animationHealthPercentage;

		public List<AnimationTriggerReference> animationHealthChanged;

		public List<AnimationTriggerReference> animationMaxHealthChanged;

		public AnimationController(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Start()
		{
			MetaInfo.AnimationLeftGunHeld = animationLeftGunHeld.Count;
			MetaInfo.AnimationRightGunHeld = animationRightGunHeld.Count;
			MetaInfo.AnimationLeftGunHeldChanged = animationLeftGunHeldChanged.Count;
			MetaInfo.AnimationRightGunHeldChanged = animationRightGunHeldChanged.Count;
			MetaInfo.AnimationLeftAmmo = animationLeftAmmo.Count;
			MetaInfo.AnimationRightAmmo = animationRightAmmo.Count;
			MetaInfo.AnimationLeftAmmoChanged = animationLeftAmmoChanged.Count;
			MetaInfo.AnimationRightAmmoChanged = animationRightAmmoChanged.Count;
			MetaInfo.AnimationLeftReserve = animationLeftReserve.Count;
			MetaInfo.AnimationRightReserve = animationRightReserve.Count;
			MetaInfo.AnimationLeftReserveChanged = animationLeftReserveChanged.Count;
			MetaInfo.AnimationRightReserveChanged = animationRightReserveChanged.Count;
			MetaInfo.AnimationTotalLeftAmmo = animationTotalLeftAmmo.Count;
			MetaInfo.AnimationTotalRightAmmo = animationTotalRightAmmo.Count;
			MetaInfo.AnimationTotalLightAmmo = animationTotalLightAmmo.Count;
			MetaInfo.AnimationTotalMediumAmmo = animationTotalMediumAmmo.Count;
			MetaInfo.AnimationTotalHeavyAmmo = animationTotalHeavyAmmo.Count;
			MetaInfo.AnimationTotalLeftAmmoChanged = animationTotalLeftAmmoChanged.Count;
			MetaInfo.AnimationTotalRightAmmoChanged = animationTotalRightAmmoChanged.Count;
			MetaInfo.AnimationTotalLightAmmoChanged = animationTotalLightAmmoChanged.Count;
			MetaInfo.AnimationTotalMediumAmmoChanged = animationTotalMediumAmmoChanged.Count;
			MetaInfo.AnimationTotalHeavyAmmoChanged = animationTotalHeavyAmmoChanged.Count;
			MetaInfo.AnimationHealth = animationHealth.Count;
			MetaInfo.AnimationMaxHealth = animationMaxHealth.Count;
			MetaInfo.AnimationHealthPercentage = animationHealthPercentage.Count;
			MetaInfo.AnimationHealthChanged = animationHealthChanged.Count;
			MetaInfo.AnimationMaxHealthChanged = animationMaxHealthChanged.Count;
			ResolveAnimationParameterIds(animationLeftGunHeld);
			ResolveAnimationParameterIds(animationRightGunHeld);
			ResolveAnimationParameterIds(animationLeftGunHeldChanged);
			ResolveAnimationParameterIds(animationRightGunHeldChanged);
			ResolveAnimationParameterIds(animationLeftAmmo);
			ResolveAnimationParameterIds(animationRightAmmo);
			ResolveAnimationParameterIds(animationLeftAmmoChanged);
			ResolveAnimationParameterIds(animationRightAmmoChanged);
			ResolveAnimationParameterIds(animationLeftReserve);
			ResolveAnimationParameterIds(animationRightReserve);
			ResolveAnimationParameterIds(animationLeftReserveChanged);
			ResolveAnimationParameterIds(animationRightReserveChanged);
			ResolveAnimationParameterIds(animationTotalLeftAmmo);
			ResolveAnimationParameterIds(animationTotalRightAmmo);
			ResolveAnimationParameterIds(animationTotalLightAmmo);
			ResolveAnimationParameterIds(animationTotalMediumAmmo);
			ResolveAnimationParameterIds(animationTotalHeavyAmmo);
			ResolveAnimationParameterIds(animationTotalLeftAmmoChanged);
			ResolveAnimationParameterIds(animationTotalRightAmmoChanged);
			ResolveAnimationParameterIds(animationTotalLightAmmoChanged);
			ResolveAnimationParameterIds(animationTotalMediumAmmoChanged);
			ResolveAnimationParameterIds(animationTotalHeavyAmmoChanged);
			ResolveAnimationParameterIds(animationHealth);
			ResolveAnimationParameterIds(animationMaxHealth);
			ResolveAnimationParameterIds(animationHealthPercentage);
			ResolveAnimationParameterIds(animationHealthChanged);
			ResolveAnimationParameterIds(animationMaxHealthChanged);
		}

		private void OnEnable()
		{
			HudState.OnLeftAmmoChanged += UpdateLeftAmmoAnimation;
			HudState.OnRightAmmoChanged += UpdateRightAmmoAnimation;
			HudState.OnLeftReserveChanged += UpdateLeftReserveAnimation;
			HudState.OnRightReserveChanged += UpdateRightReserveAnimation;
			HudState.OnHealthChanged += UpdateHealthAnimation;
			HudState.OnHealthPercentageChanged += UpdateHealthPercentageAnimation;
			HudState.OnMaxHealthChanged += UpdateMaxHealthAnimation;
			HudState.OnLeftGunChanged += OnLeftGunChanged;
			HudState.OnRightGunChanged += OnRightGunChanged;
		}

		private void OnDisable()
		{
			HudState.OnLeftAmmoChanged -= UpdateLeftAmmoAnimation;
			HudState.OnRightAmmoChanged -= UpdateRightAmmoAnimation;
			HudState.OnLeftReserveChanged -= UpdateLeftReserveAnimation;
			HudState.OnRightReserveChanged -= UpdateRightReserveAnimation;
			HudState.OnHealthChanged -= UpdateHealthAnimation;
			HudState.OnHealthPercentageChanged -= UpdateHealthPercentageAnimation;
			HudState.OnMaxHealthChanged -= UpdateMaxHealthAnimation;
			HudState.OnLeftGunChanged -= OnLeftGunChanged;
			HudState.OnRightGunChanged -= OnRightGunChanged;
		}

		private void ResolveAnimationParameterIds(List<AnimationBoolReference> parameters)
		{
			for (int i = 0; i < parameters.Count; i++)
			{
				AnimationBoolReference value = parameters[i];
				value.parameterId = Animator.StringToHash(value.parameterName);
				parameters[i] = value;
			}
		}

		private void ResolveAnimationParameterIds(List<AnimationFloatReference> parameters)
		{
			for (int i = 0; i < parameters.Count; i++)
			{
				AnimationFloatReference value = parameters[i];
				value.parameterId = Animator.StringToHash(value.parameterName);
				parameters[i] = value;
			}
		}

		private void ResolveAnimationParameterIds(List<AnimationIntReference> parameters)
		{
			for (int i = 0; i < parameters.Count; i++)
			{
				AnimationIntReference value = parameters[i];
				value.parameterId = Animator.StringToHash(value.parameterName);
				parameters[i] = value;
			}
		}

		private void ResolveAnimationParameterIds(List<AnimationTriggerReference> parameters)
		{
			for (int i = 0; i < parameters.Count; i++)
			{
				AnimationTriggerReference value = parameters[i];
				value.parameterId = Animator.StringToHash(value.parameterName);
				parameters[i] = value;
			}
		}

		private void UpdateLeftAmmoAnimation(int? ammo)
		{
			SetAnimationInts(animationLeftAmmo, ammo.GetValueOrDefault());
			FireAnimationTriggers(animationLeftAmmoChanged);
		}

		private void UpdateRightAmmoAnimation(int? ammo)
		{
			SetAnimationInts(animationRightAmmo, ammo.GetValueOrDefault());
			FireAnimationTriggers(animationRightAmmoChanged);
		}

		private void UpdateLeftReserveAnimation(int? ammo)
		{
			SetAnimationInts(animationLeftReserve, ammo.GetValueOrDefault());
			FireAnimationTriggers(animationLeftReserveChanged);
		}

		private void UpdateRightReserveAnimation(int? ammo)
		{
			SetAnimationInts(animationRightReserve, ammo.GetValueOrDefault());
			FireAnimationTriggers(animationRightReserveChanged);
		}

		private void UpdateHealthAnimation(float? health)
		{
			SetAnimationFloats(animationHealth, health.GetValueOrDefault());
			FireAnimationTriggers(animationHealthChanged);
		}

		private void UpdateHealthPercentageAnimation(float? percentage)
		{
			SetAnimationFloats(animationHealthPercentage, percentage.GetValueOrDefault());
		}

		private void UpdateMaxHealthAnimation(float? maxHealth)
		{
			SetAnimationFloats(animationMaxHealth, maxHealth.GetValueOrDefault());
			FireAnimationTriggers(animationMaxHealthChanged);
		}

		private void OnLeftGunChanged(Gun? gun)
		{
			FireAnimationTriggers(animationLeftGunHeldChanged);
			if ((Object)(object)gun == (Object)null)
			{
				SetAnimationBools(animationLeftGunHeld, value: false);
			}
			else
			{
				SetAnimationBools(animationLeftGunHeld, value: true);
			}
		}

		private void OnRightGunChanged(Gun? gun)
		{
			FireAnimationTriggers(animationRightGunHeldChanged);
			if ((Object)(object)gun == (Object)null)
			{
				SetAnimationBools(animationRightGunHeld, value: false);
			}
			else
			{
				SetAnimationBools(animationRightGunHeld, value: true);
			}
		}

		private void FireAnimationTriggers(List<AnimationTriggerReference> triggers)
		{
			foreach (AnimationTriggerReference trigger in triggers)
			{
				trigger.animator.ResetTrigger(trigger.parameterId);
				trigger.animator.SetTrigger(trigger.parameterId);
			}
		}

		private void SetAnimationBools(List<AnimationBoolReference> bools, bool value)
		{
			foreach (AnimationBoolReference @bool in bools)
			{
				@bool.animator.SetBool(@bool.parameterId, value);
			}
		}

		private void SetAnimationFloats(List<AnimationFloatReference> floats, float value)
		{
			foreach (AnimationFloatReference @float in floats)
			{
				@float.animator.SetFloat(@float.parameterId, value);
			}
		}

		private void SetAnimationInts(List<AnimationIntReference> ints, int value)
		{
			foreach (AnimationIntReference @int in ints)
			{
				@int.animator.SetInteger(@int.parameterId, value);
			}
		}
	}
	public sealed class Config
	{
		private static readonly Lazy<Config> Lazy = new Lazy<Config>(() => new Config());

		private readonly MelonPreferences_Category _config;

		private readonly MelonPreferences_Entry<string?> _hud;

		public static Config Instance => Lazy.Value;

		public string? Hud
		{
			get
			{
				return _hud.Value;
			}
			set
			{
				_hud.Value = value;
			}
		}

		private Config()
		{
			_config = MelonPreferences.CreateCategory("Config");
			_hud = _config.CreateEntry<string>("hud", "", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_config.SetFilePath(Path.Join(MelonEnvironment.UserDataDirectory, "SpectatorHUD", "config.cfg"));
		}

		public void Save()
		{
			_config.SaveToFile(true);
		}
	}
	public class DebugGUI : MonoBehaviour
	{
		private HudBootstrap _bootstrap;

		private GUILayoutManager _layout;

		private bool _showGui;

		public DebugGUI(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Start()
		{
			_bootstrap = ((Component)this).GetComponent<HudBootstrap>();
			_layout = new GUILayoutManager(25f, 25f, 220f, 22f, -4f, 10f, 15f, 60);
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)289))
			{
				_showGui = !_showGui;
			}
		}

		private void OnGUI()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0611: Unknown result type (might be due to invalid IL or missing references)
			//IL_0629: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Unknown result type (might be due to invalid IL or missing references)
			//IL_0671: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_071d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0745: Unknown result type (might be due to invalid IL or missing references)
			//IL_076d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0819: Unknown result type (might be due to invalid IL or missing references)
			//IL_084d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0875: Unknown result type (might be due to invalid IL or missing references)
			//IL_089d: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0915: Unknown result type (might be due to invalid IL or missing references)
			//IL_093d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0965: Unknown result type (might be due to invalid IL or missing references)
			//IL_098d: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a11: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a39: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a61: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a89: Unknown result type (might be due to invalid IL or missing references)
			//IL_0abd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ad5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0af5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b1d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b45: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b6d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b95: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bbd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0be5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c0d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c35: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c85: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cad: Unknown result type (might be due to invalid IL or missing references)
			if (_showGui)
			{
				_layout.Start();
				_layout.Column(0);
				GUI.Label(_layout.GetNext(), "SpectatorHUD v1.0.0");
				_layout.Space();
				GUI.Label(_layout.GetNext(), "Tracked Values:");
				_layout.Indent();
				GUI.Label(_layout.GetNext(), "Left Gun Held: " + ((Object)(object)HudState.LeftGun != (Object)null));
				GUI.Label(_layout.GetNext(), "Right Gun Held: " + ((Object)(object)HudState.RightGun != (Object)null));
				GUI.Label(_layout.GetNext(), "Left Ammo: " + HudState.LeftAmmo);
				GUI.Label(_layout.GetNext(), "Right Ammo: " + HudState.RightAmmo);
				GUI.Label(_layout.GetNext(), "Left Reserve: " + HudState.LeftReserve);
				GUI.Label(_layout.GetNext(), "Right Reserve: " + HudState.RightReserve);
				GUI.Label(_layout.GetNext(), "Health: " + HudState.Health);
				GUI.Label(_layout.GetNext(), "Max Health: " + HudState.MaxHealth);
				GUI.Label(_layout.GetNext(), "Health Percentage: " + HudState.HealthPercentage);
				_layout.Outdent();
				_layout.Space();
				GUI.Label(_layout.GetNext(), "HUD Metadata:");
				_layout.Indent();
				GUI.Label(_layout.GetNext(), "SpectatorHUD Version: " + MetaInfo.HUDCompatibility);
				GUI.Label(_layout.GetNext(), "Name: " + MetaInfo.HUDName);
				GUI.Label(_layout.GetNext(), "Author: " + MetaInfo.HUDAuthor);
				GUI.Label(_layout.GetNext(), "Version: " + MetaInfo.HUDVersion);
				_layout.Outdent();
				_layout.Space(3);
				if (GUI.Button(_layout.GetNext(), "Reload HUD"))
				{
					_bootstrap.ReloadHudFromConfig();
				}
				TimeSpan timeSpan = DateTime.Now - _bootstrap.lastLoad;
				GUI.Label(_layout.GetNext(), $"Last reloaded {timeSpan.TotalSeconds:0.}s ago");
				_layout.Column(1);
				_layout.GetNext();
				_layout.Space();
				GUI.Label(_layout.GetNext(), "Counters:");
				_layout.Indent();
				GUI.Label(_layout.GetNext(), "leftReserveCounter: " + MetaInfo.HasLeftReserveCounter);
				GUI.Label(_layout.GetNext(), "leftAmmoCounter: " + MetaInfo.HasLeftAmmoCounter);
				GUI.Label(_layout.GetNext(), "totalLeftAmmoCounter: " + MetaInfo.HasTotalLeftAmmoCounter);
				GUI.Label(_layout.GetNext(), "rightReserveCounter: " + MetaInfo.HasRightReserveCounter);
				GUI.Label(_layout.GetNext(), "rightAmmoCounter: " + MetaInfo.HasRightAmmoCounter);
				GUI.Label(_layout.GetNext(), "totalRightAmmoCounter: " + MetaInfo.HasTotalRightAmmoCounter);
				GUI.Label(_layout.GetNext(), "totalLightAmmoCounter: " + MetaInfo.HasTotalLightAmmoCounter);
				GUI.Label(_layout.GetNext(), "totalMediumAmmoCounter: " + MetaInfo.HasTotalMediumAmmoCounter);
				GUI.Label(_layout.GetNext(), "totalHeavyAmmoCounter: " + MetaInfo.HasTotalHeavyAmmoCounter);
				GUI.Label(_layout.GetNext(), "healthCounter: " + MetaInfo.HasHealthCounter);
				GUI.Label(_layout.GetNext(), "maxHealthCounter: " + MetaInfo.HasMaxHealthCounter);
				GUI.Label(_layout.GetNext(), "healthPercentageCounter: " + MetaInfo.HasHealthPercentageCounter);
				_layout.Outdent();
				_layout.Space();
				GUI.Label(_layout.GetNext(), "Toggleable Elements:");
				_layout.Indent();
				GUI.Label(_layout.GetNext(), "activeWithGunInLeftHand: " + MetaInfo.ActiveWithGunInLeftHand);
				GUI.Label(_layout.GetNext(), "activeWithGunInRightHand: " + MetaInfo.ActiveWithGunInRightHand);
				_layout.Column(2);
				_layout.GetNext();
				_layout.Space();
				GUI.Label(_layout.GetNext(), "Animation Events:");
				_layout.Indent();
				GUI.Label(_layout.GetNext(), "animationLeftGunHeld: " + MetaInfo.AnimationLeftGunHeld);
				GUI.Label(_layout.GetNext(), "animationRightGunHeld: " + MetaInfo.AnimationRightGunHeld);
				GUI.Label(_layout.GetNext(), "animationLeftGunHeldChanged: " + MetaInfo.AnimationLeftGunHeldChanged);
				GUI.Label(_layout.GetNext(), "animationRightGunHeldChanged: " + MetaInfo.AnimationRightGunHeldChanged);
				_layout.Space();
				GUI.Label(_layout.GetNext(), "animationLeftAmmo: " + MetaInfo.AnimationLeftAmmo);
				GUI.Label(_layout.GetNext(), "animationRightAmmo: " + MetaInfo.AnimationRightAmmo);
				GUI.Label(_layout.GetNext(), "animationLeftAmmoChanged: " + MetaInfo.AnimationLeftAmmoChanged);
				GUI.Label(_layout.GetNext(), "animationRightAmmoChanged: " + MetaInfo.AnimationRightAmmoChanged);
				_layout.Space();
				GUI.Label(_layout.GetNext(), "animationLeftReserve: " + MetaInfo.AnimationLeftReserve);
				GUI.Label(_layout.GetNext(), "animationRightReserve: " + MetaInfo.AnimationRightReserve);
				GUI.Label(_layout.GetNext(), "animationLeftReserveChanged: " + MetaInfo.AnimationLeftReserveChanged);
				GUI.Label(_layout.GetNext(), "animationRightReserveChanged: " + MetaInfo.AnimationRightReserveChanged);
				_layout.Space();
				GUI.Label(_layout.GetNext(), "animationTotalLeftAmmo: " + MetaInfo.AnimationTotalLeftAmmo);
				GUI.Label(_layout.GetNext(), "animationTotalRightAmmo: " + MetaInfo.AnimationTotalRightAmmo);
				GUI.Label(_layout.GetNext(), "animationTotalLightAmmo: " + MetaInfo.AnimationTotalLightAmmo);
				GUI.Label(_layout.GetNext(), "animationTotalMediumAmmo: " + MetaInfo.AnimationTotalMediumAmmo);
				GUI.Label(_layout.GetNext(), "animationTotalHeavyAmmo: " + MetaInfo.AnimationTotalHeavyAmmo);
				GUI.Label(_layout.GetNext(), "animationTotalLeftAmmoChanged: " + MetaInfo.AnimationTotalLeftAmmoChanged);
				GUI.Label(_layout.GetNext(), "animationTotalRightAmmoChanged: " + MetaInfo.AnimationTotalRightAmmoChanged);
				GUI.Label(_layout.GetNext(), "animationTotalLightAmmoChanged: " + MetaInfo.AnimationTotalLightAmmoChanged);
				GUI.Label(_layout.GetNext(), "animationTotalMediumAmmoChanged: " + MetaInfo.AnimationTotalMediumAmmoChanged);
				GUI.Label(_layout.GetNext(), "animationTotalHeavyAmmoChanged: " + MetaInfo.AnimationTotalHeavyAmmoChanged);
				_layout.Space();
				GUI.Label(_layout.GetNext(), "animationHealth: " + MetaInfo.AnimationHealth);
				GUI.Label(_layout.GetNext(), "animationMaxHealth: " + MetaInfo.AnimationMaxHealth);
				GUI.Label(_layout.GetNext(), "animationHealthPercentage: " + MetaInfo.AnimationHealthPercentage);
				GUI.Label(_layout.GetNext(), "animationHealthChanged: " + MetaInfo.AnimationHealthChanged);
				GUI.Label(_layout.GetNext(), "animationMaxHealthChanged: " + MetaInfo.AnimationMaxHealthChanged);
				_layout.Column(3);
				_layout.GetNext();
				_layout.Space();
				GUI.Label(_layout.GetNext(), "Shader Events:");
				_layout.Indent();
				GUI.Label(_layout.GetNext(), "shaderLeftAmmo: " + MetaInfo.ShaderLeftAmmo);
				GUI.Label(_layout.GetNext(), "shaderRightAmmo: " + MetaInfo.ShaderRightAmmo);
				GUI.Label(_layout.GetNext(), "shaderLeftReserve: " + MetaInfo.ShaderLeftReserve);
				GUI.Label(_layout.GetNext(), "shaderRightReserve: " + MetaInfo.ShaderRightReserve);
				GUI.Label(_layout.GetNext(), "shaderTotalLeftAmmo: " + MetaInfo.ShaderTotalLeftAmmo);
				GUI.Label(_layout.GetNext(), "shaderTotalRightAmmo: " + MetaInfo.ShaderTotalRightAmmo);
				GUI.Label(_layout.GetNext(), "shaderTotalLightAmmo: " + MetaInfo.ShaderTotalLightAmmo);
				GUI.Label(_layout.GetNext(), "shaderTotalMediumAmmo: " + MetaInfo.ShaderTotalMediumAmmo);
				GUI.Label(_layout.GetNext(), "shaderTotalHeavyAmmo: " + MetaInfo.ShaderTotalHeavyAmmo);
				GUI.Label(_layout.GetNext(), "shaderHealth: " + MetaInfo.ShaderHealth);
				GUI.Label(_layout.GetNext(), "shaderMaxHealth: " + MetaInfo.ShaderMaxHealth);
				GUI.Label(_layout.GetNext(), "shaderHealthPercentage: " + MetaInfo.ShaderHealthPercentage);
				_layout.End();
			}
		}
	}
	public class HudBootstrap : MonoBehaviour
	{
		public const string DefaultHud = "SpectatorHUD.Resources.Half-Life 2.hud";

		public GameObject? hud;

		private RigManager? _rigManager;

		public DateTime lastLoad;

		public HudBootstrap(IntPtr ptr)
			: base(ptr)
		{
		}

		public void Start()
		{
			_rigManager = ((Component)this).GetComponent<RigManager>();
			LoadHudFromConfig();
		}

		private void OnDestroy()
		{
		}

		public void UnloadCurrentHud()
		{
			if (!((Object)(object)hud == (Object)null))
			{
				Object.Destroy((Object)(object)hud);
			}
		}

		public void ReloadHudFromConfig()
		{
			UnloadCurrentHud();
			LoadHudFromConfig();
			GameObject? obj = hud;
			if (obj != null)
			{
				obj.SetActive(true);
			}
		}

		public void LoadHudFromConfig()
		{
			if (string.IsNullOrEmpty(Config.Instance.Hud))
			{
				LoadHudFromEmbeddedResource("SpectatorHUD.Resources.Half-Life 2.hud");
			}
			else
			{
				LoadHudFromFile(Config.Instance.Hud);
			}
		}

		public void LoadHudFromFile(string filePath)
		{
			Logger.Msg("Loading bundle at: {0}", filePath);
			AssetBundle val = AssetBundle.LoadFromFile(filePath);
			if ((Object)(object)val == (Object)null)
			{
				Logger.Error("Failed to load asset bundle.");
				return;
			}
			LoadHudFromAssetBundle(val);
			val.Unload(false);
		}

		public void LoadHudFromEmbeddedResource(string resource)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
			if (stream == null)
			{
				Logger.Error("Unable to open stream to embedded resource");
				return;
			}
			MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			AssetBundle assetBundle = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(memoryStream.ToArray()));
			LoadHudFromAssetBundle(assetBundle);
		}

		public void LoadHudFromAssetBundle(AssetBundle assetBundle)
		{
			HudVersion hudVersion = ((Il2CppObjectBase)assetBundle.LoadAsset("Hud.Version.asset")).TryCast<HudVersion>();
			if ((Object)(object)hudVersion == (Object)null)
			{
				Logger.Error("Hud Version asset was not found in asset bundle.");
			}
			else if (hudVersion.version == 1)
			{
				LoadHudV1(assetBundle);
				MetaInfo.HUDCompatibility = hudVersion.version;
				lastLoad = DateTime.Now;
			}
			else
			{
				Logger.Error("Unsupported HUD version. You may need to update the mod.");
				Object.Destroy((Object)(object)this);
			}
		}

		private void LoadHudV1(AssetBundle assetBundle)
		{
			HudV1 hudV = ((Il2CppObjectBase)assetBundle.LoadAsset("Hud.asset")).TryCast<HudV1>();
			if ((Object)(object)hudV == (Object)null)
			{
				Logger.Error("Hud.asset could not be loaded from asset bundle.");
				return;
			}
			Logger.Msg("Loaded {0} v{1} by {2}", hudV.hudName, hudV.hudVersion, hudV.hudAuthor);
			hud = Object.Instantiate<GameObject>(hudV.hudAsset);
			((Object)hud).name = "SpectatorHUD UI";
			MetaInfo.HUDName = hudV.hudName;
			MetaInfo.HUDAuthor = hudV.hudAuthor;
			MetaInfo.HUDVersion = hudV.hudVersion;
			HudRun();
			hud.SetActive(false);
		}

		private void HudRun()
		{
			if ((Object)(object)_rigManager == (Object)null)
			{
				Logger.Error("FUCKKK WHERES THE RIG MANAGER");
			}
			else
			{
				HudState.RigManager = _rigManager;
			}
		}
	}
	public class HudController : MonoBehaviour
	{
		public TMP_Text leftHandReserveCounter;

		public TMP_Text leftHandAmmoCounter;

		public TMP_Text rightHandReserveCounter;

		public TMP_Text rightHandAmmoCounter;

		public TMP_Text leftHandTotalAmmoCounter;

		public TMP_Text rightHandTotalAmmoCounter;

		public TMP_Text totalLightAmmoCounter;

		public TMP_Text totalMediumAmmoCounter;

		public TMP_Text totalHeavyAmmoCounter;

		public TMP_Text healthCounter;

		public TMP_Text maxHealthCounter;

		public TMP_Text percentageHealthCounter;

		public LinearParameters healthModifier;

		public List<GameObject> activeWithGunHeldInLeftHand;

		public List<GameObject> activeWithGunHeldInRightHand;

		private LinearExpression<float> _healthModifierExpression;

		public HudController(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			_healthModifierExpression = new LinearExpression<float>(healthModifier.multiplier, healthModifier.offset);
		}

		private void Start()
		{
			MetaInfo.HasLeftReserveCounter = (Object)(object)leftHandReserveCounter != (Object)null;
			MetaInfo.HasLeftAmmoCounter = (Object)(object)leftHandAmmoCounter != (Object)null;
			MetaInfo.HasTotalLeftAmmoCounter = (Object)(object)leftHandTotalAmmoCounter != (Object)null;
			MetaInfo.HasRightReserveCounter = (Object)(object)rightHandReserveCounter != (Object)null;
			MetaInfo.HasRightAmmoCounter = (Object)(object)rightHandAmmoCounter != (Object)null;
			MetaInfo.HasTotalRightAmmoCounter = (Object)(object)rightHandTotalAmmoCounter != (Object)null;
			MetaInfo.HasTotalLightAmmoCounter = (Object)(object)totalLightAmmoCounter != (Object)null;
			MetaInfo.HasTotalMediumAmmoCounter = (Object)(object)totalMediumAmmoCounter != (Object)null;
			MetaInfo.HasTotalHeavyAmmoCounter = (Object)(object)totalHeavyAmmoCounter != (Object)null;
			MetaInfo.HasHealthCounter = (Object)(object)healthCounter != (Object)null;
			MetaInfo.HasMaxHealthCounter = (Object)(object)maxHealthCounter != (Object)null;
			MetaInfo.HasHealthPercentageCounter = (Object)(object)percentageHealthCounter != (Object)null;
			MetaInfo.ActiveWithGunInLeftHand = activeWithGunHeldInLeftHand.Count;
			MetaInfo.ActiveWithGunInRightHand = activeWithGunHeldInRightHand.Count;
		}

		private void OnEnable()
		{
			HudState.OnLeftGunChanged += OnLeftGunChanged;
			HudState.OnRightGunChanged += OnRightGunChanged;
			if ((Object)(object)leftHandAmmoCounter != (Object)null)
			{
				HudState.OnLeftAmmoChanged += UpdateLeftAmmoCounter;
			}
			if ((Object)(object)rightHandAmmoCounter != (Object)null)
			{
				HudState.OnRightAmmoChanged += UpdateRightAmmoCounter;
			}
			if ((Object)(object)leftHandReserveCounter != (Object)null)
			{
				HudState.OnLeftReserveChanged += UpdateLeftReserveCounter;
			}
			if ((Object)(object)rightHandReserveCounter != (Object)null)
			{
				HudState.OnRightReserveChanged += UpdateRightReserveCounter;
			}
			if ((Object)(object)leftHandTotalAmmoCounter != (Object)null)
			{
				HudState.OnLeftTotalAmmoChanged += UpdateLeftTotalAmmoCounter;
			}
			if ((Object)(object)rightHandTotalAmmoCounter != (Object)null)
			{
				HudState.OnRightTotalAmmoChanged += UpdateRightTotalAmmoCounter;
			}
			if ((Object)(object)totalLightAmmoCounter != (Object)null)
			{
				HudState.OnTotalLightAmmoChanged += UpdateTotalLightAmmoCounter;
			}
			if ((Object)(object)totalMediumAmmoCounter != (Object)null)
			{
				HudState.OnTotalMediumAmmoChanged += UpdateTotalMediumAmmoCounter;
			}
			if ((Object)(object)totalHeavyAmmoCounter != (Object)null)
			{
				HudState.OnTotalHeavyAmmoChanged += UpdateTotalHeavyAmmoCounter;
			}
			if ((Object)(object)healthCounter != (Object)null)
			{
				HudState.OnHealthChanged += UpdateHealthCounter;
			}
			if (Object.op_Implicit((Object)(object)percentageHealthCounter))
			{
				HudState.OnHealthPercentageChanged += UpdateHealthPercentageCounter;
			}
			if (Object.op_Implicit((Object)(object)maxHealthCounter))
			{
				HudState.OnMaxHealthChanged += UpdateMaxHealthCounter;
			}
			HudState.ForceNotifierRepoll();
		}

		private void OnDisable()
		{
			HudState.OnLeftGunChanged -= OnLeftGunChanged;
			HudState.OnRightGunChanged -= OnRightGunChanged;
			HudState.OnLeftAmmoChanged -= UpdateLeftAmmoCounter;
			HudState.OnRightAmmoChanged -= UpdateRightAmmoCounter;
			HudState.OnLeftReserveChanged -= UpdateLeftReserveCounter;
			HudState.OnRightReserveChanged -= UpdateRightReserveCounter;
			HudState.OnLeftTotalAmmoChanged -= UpdateLeftTotalAmmoCounter;
			HudState.OnRightTotalAmmoChanged -= UpdateRightTotalAmmoCounter;
			HudState.OnTotalLightAmmoChanged -= UpdateTotalLightAmmoCounter;
			HudState.OnTotalMediumAmmoChanged -= UpdateTotalMediumAmmoCounter;
			HudState.OnTotalHeavyAmmoChanged -= UpdateTotalHeavyAmmoCounter;
			HudState.OnHealthChanged -= UpdateHealthCounter;
			HudState.OnHealthPercentageChanged -= UpdateHealthPercentageCounter;
			HudState.OnMaxHealthChanged -= UpdateMaxHealthCounter;
		}

		private void UpdateLeftAmmoCounter(int? ammo)
		{
			leftHandAmmoCounter.text = ammo.ToString();
		}

		private void UpdateRightAmmoCounter(int? ammo)
		{
			rightHandAmmoCounter.text = ammo.ToString();
		}

		private void UpdateLeftReserveCounter(int? ammo)
		{
			leftHandReserveCounter.text = ammo.ToString();
		}

		private void UpdateRightReserveCounter(int? ammo)
		{
			rightHandReserveCounter.text = ammo.ToString();
		}

		private void UpdateLeftTotalAmmoCounter(int? ammo)
		{
			leftHandTotalAmmoCounter.text = ammo.ToString();
		}

		private void UpdateRightTotalAmmoCounter(int? ammo)
		{
			rightHandTotalAmmoCounter.text = ammo.ToString();
		}

		private void UpdateTotalLightAmmoCounter(int? ammo)
		{
			totalLightAmmoCounter.text = ammo.ToString();
		}

		private void UpdateTotalMediumAmmoCounter(int? ammo)
		{
			totalMediumAmmoCounter.text = ammo.ToString();
		}

		private void UpdateTotalHeavyAmmoCounter(int? ammo)
		{
			totalHeavyAmmoCounter.text = ammo.ToString();
		}

		private void UpdateHealthCounter(float? health)
		{
			healthCounter.text = $"{_healthModifierExpression.Evaluate(health.GetValueOrDefault()):0.}";
		}

		private void UpdateHealthPercentageCounter(float? percentage)
		{
			float? num = ((!percentage.HasValue) ? ((float?)null) : new float?(Math.Max(percentage.Value, 0f)));
			percentageHealthCounter.text = $"{num * 100f:0.}";
		}

		private void UpdateMaxHealthCounter(float? maxHealth)
		{
			maxHealthCounter.text = $"{_healthModifierExpression.Evaluate(maxHealth.GetValueOrDefault()):0.}";
		}

		private void OnLeftGunChanged(Gun? gun)
		{
			Logger.Debug("HudManagerV1: Left gun changed");
			if ((Object)(object)gun == (Object)null)
			{
				foreach (GameObject item in activeWithGunHeldInLeftHand)
				{
					item.active = false;
					Logger.Debug("HudManagerV1: disabled " + ((Object)item).name);
				}
				return;
			}
			foreach (GameObject item2 in activeWithGunHeldInLeftHand)
			{
				item2.active = true;
				Logger.Debug("HudManagerV1: enabled " + ((Object)item2).name);
			}
		}

		private void OnRightGunChanged(Gun? gun)
		{
			Logger.Debug("HudManagerV1: Right gun changed");
			if ((Object)(object)gun == (Object)null)
			{
				foreach (GameObject item in activeWithGunHeldInRightHand)
				{
					Logger.Debug("HudManagerV1: disabled " + ((Object)item).name);
					item.active = false;
				}
				return;
			}
			foreach (GameObject item2 in activeWithGunHeldInRightHand)
			{
				Logger.Debug("HudManagerV1: enabled " + ((Object)item2).name);
				item2.active = true;
			}
		}
	}
	public static class HudState
	{
		[CompilerGenerated]
		private static AmmoInventory <AmmoInventory>k__BackingField;

		[CompilerGenerated]
		private static Gun? <LeftGun>k__BackingField;

		[CompilerGenerated]
		private static Gun? <RightGun>k__BackingField;

		[CompilerGenerated]
		private static int? <LeftAmmo>k__BackingField;

		[CompilerGenerated]
		private static int? <RightAmmo>k__BackingField;

		[CompilerGenerated]
		private static int? <LeftReserve>k__BackingField;

		[CompilerGenerated]
		private static int? <RightReserve>k__BackingField;

		[CompilerGenerated]
		private static int? <LeftTotalAmmo>k__BackingField;

		[CompilerGenerated]
		private static int? <RightTotalAmmo>k__BackingField;

		[CompilerGenerated]
		private static int? <TotalLightAmmo>k__BackingField;

		[CompilerGenerated]
		private static int? <TotalMediumAmmo>k__BackingField;

		[CompilerGenerated]
		private static int? <TotalHeavyAmmo>k__BackingField;

		[CompilerGenerated]
		private static float? <Health>k__BackingField;

		[CompilerGenerated]
		private static float? <HealthPercentage>k__BackingField;

		[CompilerGenerated]
		private static float? <MaxHealth>k__BackingField;

		public static CartridgeContainer? LeftDefaultCartridge { get; set; }

		public static CartridgeContainer? RightDefaultCartridge { get; set; }

		public static RigManager? RigManager { get; set; }

		public static AmmoInventory AmmoInventory
		{
			get
			{
				if ((Object)(object)<AmmoInventory>k__BackingField != (Object)null)
				{
					return <AmmoInventory>k__BackingField;
				}
				<AmmoInventory>k__BackingField = AmmoInventory.Instance;
				LightAmmoKey = <AmmoInventory>k__BackingField.lightAmmoGroup.KeyName;
				MediumAmmoKey = <AmmoInventory>k__BackingField.mediumAmmoGroup.KeyName;
				HeavyAmmoKey = <AmmoInventory>k__BackingField.heavyAmmoGroup.KeyName;
				return <AmmoInventory>k__BackingField;
			}
		}

		public static string? LightAmmoKey { get; private set; }

		public static string? MediumAmmoKey { get; private set; }

		public static string? HeavyAmmoKey { get; private set; }

		public static Gun? LeftGun
		{
			[CompilerGenerated]
			get
			{
				return <LeftGun>k__BackingField;
			}
			set
			{
				if ((Object)(object)<LeftGun>k__BackingField != (Object)(object)value)
				{
					HudState.OnLeftGunChanged?.Invoke(value);
				}
				<LeftGun>k__BackingField = value;
			}
		}

		public static Gun? RightGun
		{
			[CompilerGenerated]
			get
			{
				return <RightGun>k__BackingField;
			}
			set
			{
				if ((Object)(object)<RightGun>k__BackingField != (Object)(object)value)
				{
					HudState.OnRightGunChanged?.Invoke(value);
				}
				<RightGun>k__BackingField = value;
			}
		}

		public static int? LeftAmmo
		{
			[CompilerGenerated]
			get
			{
				return <LeftAmmo>k__BackingField;
			}
			set
			{
				if (<LeftAmmo>k__BackingField != value)
				{
					HudState.OnLeftAmmoChanged?.Invoke(value);
				}
				<LeftAmmo>k__BackingField = value;
			}
		}

		public static int? RightAmmo
		{
			[CompilerGenerated]
			get
			{
				return <RightAmmo>k__BackingField;
			}
			set
			{
				if (<RightAmmo>k__BackingField != value)
				{
					HudState.OnRightAmmoChanged?.Invoke(value);
				}
				<RightAmmo>k__BackingField = value;
			}
		}

		public static int? LeftReserve
		{
			[CompilerGenerated]
			get
			{
				return <LeftReserve>k__BackingField;
			}
			set
			{
				if (<LeftReserve>k__BackingField != value)
				{
					HudState.OnLeftReserveChanged?.Invoke(value);
				}
				<LeftReserve>k__BackingField = value;
			}
		}

		public static int? RightReserve
		{
			[CompilerGenerated]
			get
			{
				return <RightReserve>k__BackingField;
			}
			set
			{
				if (<RightReserve>k__BackingField != value)
				{
					HudState.OnRightReserveChanged?.Invoke(value);
				}
				<RightReserve>k__BackingField = value;
			}
		}

		public static int? LeftTotalAmmo
		{
			[CompilerGenerated]
			get
			{
				return <LeftTotalAmmo>k__BackingField;
			}
			set
			{
				if (<LeftTotalAmmo>k__BackingField != value)
				{
					HudState.OnLeftTotalAmmoChanged?.Invoke(value);
				}
				<LeftTotalAmmo>k__BackingField = value;
			}
		}

		public static int? RightTotalAmmo
		{
			[CompilerGenerated]
			get
			{
				return <RightTotalAmmo>k__BackingField;
			}
			set
			{
				if (<RightTotalAmmo>k__BackingField != value)
				{
					HudState.OnRightTotalAmmoChanged?.Invoke(value);
				}
				<RightTotalAmmo>k__BackingField = value;
			}
		}

		public static int? TotalLightAmmo
		{
			[CompilerGenerated]
			get
			{
				return <TotalLightAmmo>k__BackingField;
			}
			set
			{
				if (<TotalLightAmmo>k__BackingField != value)
				{
					HudState.OnTotalLightAmmoChanged?.Invoke(value);
				}
				<TotalLightAmmo>k__BackingField = value;
			}
		}

		public static int? TotalMediumAmmo
		{
			[CompilerGenerated]
			get
			{
				return <TotalMediumAmmo>k__BackingField;
			}
			set
			{
				if (<TotalMediumAmmo>k__BackingField != value)
				{
					HudState.OnTotalMediumAmmoChanged?.Invoke(value);
				}
				<TotalMediumAmmo>k__BackingField = value;
			}
		}

		public static int? TotalHeavyAmmo
		{
			[CompilerGenerated]
			get
			{
				return <TotalHeavyAmmo>k__BackingField;
			}
			set
			{
				if (<TotalHeavyAmmo>k__BackingField != value)
				{
					HudState.OnTotalHeavyAmmoChanged?.Invoke(value);
				}
				<TotalHeavyAmmo>k__BackingField = value;
			}
		}

		public static float? Health
		{
			[CompilerGenerated]
			get
			{
				return <Health>k__BackingField;
			}
			set
			{
				if (<Health>k__BackingField != value)
				{
					HudState.OnHealthChanged?.Invoke(value);
				}
				<Health>k__BackingField = value;
			}
		}

		public static float? HealthPercentage
		{
			[CompilerGenerated]
			get
			{
				return <HealthPercentage>k__BackingField;
			}
			set
			{
				if (<HealthPercentage>k__BackingField != value)
				{
					HudState.OnHealthPercentageChanged?.Invoke(value);
				}
				<HealthPercentage>k__BackingField = value;
			}
		}

		public static float? MaxHealth
		{
			[CompilerGenerated]
			get
			{
				return <MaxHealth>k__BackingField;
			}
			set
			{
				if (<MaxHealth>k__BackingField != value)
				{
					HudState.OnMaxHealthChanged?.Invoke(value);
				}
				<MaxHealth>k__BackingField = value;
			}
		}

		public static event Action<Gun?>? OnLeftGunChanged;

		public static event Action<Gun?>? OnRightGunChanged;

		public static event Action<int?>? OnLeftAmmoChanged;

		public static event Action<int?>? OnRightAmmoChanged;

		public static event Action<int?>? OnLeftReserveChanged;

		public static event Action<int?>? OnRightReserveChanged;

		public static event Action<int?>? OnLeftTotalAmmoChanged;

		public static event Action<int?>? OnRightTotalAmmoChanged;

		public static event Action<int?>? OnTotalLightAmmoChanged;

		public static event Action<int?>? OnTotalMediumAmmoChanged;

		public static event Action<int?>? OnTotalHeavyAmmoChanged;

		public static event Action<float?>? OnHealthChanged;

		public static event Action<float?>? OnHealthPercentageChanged;

		public static event Action<float?>? OnMaxHealthChanged;

		public static void ForceNotifierRepoll()
		{
			HudState.OnLeftGunChanged?.Invoke(LeftGun);
			HudState.OnRightGunChanged?.Invoke(RightGun);
			HudState.OnLeftAmmoChanged?.Invoke(LeftAmmo);
			HudState.OnRightAmmoChanged?.Invoke(RightAmmo);
			HudState.OnLeftReserveChanged?.Invoke(LeftReserve);
			HudState.OnRightReserveChanged?.Invoke(RightReserve);
			HudState.OnLeftTotalAmmoChanged?.Invoke(LeftTotalAmmo);
			HudState.OnRightTotalAmmoChanged?.Invoke(RightTotalAmmo);
			HudState.OnTotalLightAmmoChanged?.Invoke(TotalLightAmmo);
			HudState.OnTotalMediumAmmoChanged?.Invoke(TotalMediumAmmo);
			HudState.OnTotalHeavyAmmoChanged?.Invoke(TotalHeavyAmmo);
			HudState.OnHealthChanged?.Invoke(Health);
			HudState.OnHealthPercentageChanged?.Invoke(HealthPercentage);
			HudState.OnMaxHealthChanged?.Invoke(MaxHealth);
		}
	}
	public class HudV1 : ScriptableObject
	{
		public string hudName;

		public int hudVersion;

		public string hudAuthor;

		public HudVersion spectatorHudVersion;

		public GameObject hudAsset;

		public HudV1(IntPtr ptr)
			: base(ptr)
		{
		}
	}
	public class HudVersion : ScriptableObject
	{
		public int version;

		public HudVersion(IntPtr ptr)
			: base(ptr)
		{
		}
	}
	public class LoadingSceneActivator : MonoBehaviour
	{
		public LoadingSceneActivator(IntPtr ptr)
			: base(ptr)
		{
		}

		private void OnDestroy()
		{
			GameObject? hud = ((IEnumerable<HudBootstrap>)Resources.FindObjectsOfTypeAll<HudBootstrap>()).First().hud;
			if (hud != null)
			{
				hud.SetActive(true);
			}
		}
	}
	public static class Logger
	{
		private delegate void DebugLogObject(object obj);

		private delegate void DebugLogTxt(string txt);

		private delegate void DebugLogFormat(string txt, params object[] args);

		private static DebugLogObject? _debugLogObject;

		private static DebugLogTxt? _debugLogTxt;

		private static DebugLogFormat? _debugLogFormat;

		public static Instance? Instance { get; set; }

		public static void EnableDebug(bool debug)
		{
			if (debug)
			{
				_debugLogObject = delegate(object obj)
				{
					Instance? instance = Instance;
					if (instance != null)
					{
						instance.Msg("[DEBUG] " + obj);
					}
				};
				_debugLogTxt = delegate(string txt)
				{
					Instance? instance = Instance;
					if (instance != null)
					{
						instance.Msg("[DEBUG] " + txt);
					}
				};
				_debugLogFormat = delegate(string txt, object[] args)
				{
					Instance? instance = Instance;
					if (instance != null)
					{
						instance.Msg("[DEBUG] " + txt, args);
					}
				};
			}
			else
			{
				_debugLogObject = null;
				_debugLogTxt = null;
				_debugLogFormat = null;
			}
		}

		public static void Debug(object obj)
		{
			_debugLogObject?.Invoke(obj);
		}

		public static void Debug(string txt)
		{
			_debugLogTxt?.Invoke(txt);
		}

		public static void Debug(string txt, params object[] args)
		{
			_debugLogFormat?.Invoke(txt, args);
		}

		public static void Msg(object obj)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Msg(obj);
			}
		}

		public static void Msg(string txt)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Msg(txt);
			}
		}

		public static void Msg(string txt, params object[] args)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Msg(txt, args);
			}
		}

		public static void Warning(object obj)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Warning(obj);
			}
		}

		public static void Warning(string txt)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Warning(txt);
			}
		}

		public static void Warning(string txt, params object[] args)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Warning(txt, args);
			}
		}

		public static void Error(object obj)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Error(obj);
			}
		}

		public static void Error(string txt)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Error(txt);
			}
		}

		public static void Error(string txt, params object[] args)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Error(txt, args);
			}
		}

		public static void Error(string txt, Exception ex)
		{
			Instance? instance = Instance;
			if (instance != null)
			{
				instance.Error(txt, ex);
			}
		}
	}
	public static class MetaInfo
	{
		public static int? HUDCompatibility { get; set; }

		public static string? HUDName { get; set; }

		public static string? HUDAuthor { get; set; }

		public static int? HUDVersion { get; set; }

		public static bool HasLeftReserveCounter { get; set; }

		public static bool HasLeftAmmoCounter { get; set; }

		public static bool HasTotalLeftAmmoCounter { get; set; }

		public static bool HasRightReserveCounter { get; set; }

		public static bool HasRightAmmoCounter { get; set; }

		public static bool HasTotalRightAmmoCounter { get; set; }

		public static bool HasTotalLightAmmoCounter { get; set; }

		public static bool HasTotalMediumAmmoCounter { get; set; }

		public static bool HasTotalHeavyAmmoCounter { get; set; }

		public static bool HasHealthCounter { get; set; }

		public static bool HasMaxHealthCounter { get; set; }

		public static bool HasHealthPercentageCounter { get; set; }

		public static int ActiveWithGunInLeftHand { get; set; }

		public static int ActiveWithGunInRightHand { get; set; }

		public static int AnimationLeftGunHeld { get; set; }

		public static int AnimationRightGunHeld { get; set; }

		public static int AnimationLeftGunHeldChanged { get; set; }

		public static int AnimationRightGunHeldChanged { get; set; }

		public static int AnimationLeftAmmo { get; set; }

		public static int AnimationRightAmmo { get; set; }

		public static int AnimationLeftAmmoChanged { get; set; }

		public static int AnimationRightAmmoChanged { get; set; }

		public static int AnimationLeftReserve { get; set; }

		public static int AnimationRightReserve { get; set; }

		public static int AnimationLeftReserveChanged { get; set; }

		public static int AnimationRightReserveChanged { get; set; }

		public static int AnimationTotalLeftAmmo { get; set; }

		public static int AnimationTotalRightAmmo { get; set; }

		public static int AnimationTotalLightAmmo { get; set; }

		public static int AnimationTotalMediumAmmo { get; set; }

		public static int AnimationTotalHeavyAmmo { get; set; }

		public static int AnimationTotalLeftAmmoChanged { get; set; }

		public static int AnimationTotalRightAmmoChanged { get; set; }

		public static int AnimationTotalLightAmmoChanged { get; set; }

		public static int AnimationTotalMediumAmmoChanged { get; set; }

		public static int AnimationTotalHeavyAmmoChanged { get; set; }

		public static int AnimationHealth { get; set; }

		public static int AnimationMaxHealth { get; set; }

		public static int AnimationHealthPercentage { get; set; }

		public static int AnimationHealthChanged { get; set; }

		public static int AnimationMaxHealthChanged { get; set; }

		public static int ShaderLeftAmmo { get; set; }

		public static int ShaderRightAmmo { get; set; }

		public static int ShaderLeftReserve { get; set; }

		public static int ShaderRightReserve { get; set; }

		public static int ShaderTotalLeftAmmo { get; set; }

		public static int ShaderTotalRightAmmo { get; set; }

		public static int ShaderTotalLightAmmo { get; set; }

		public static int ShaderTotalMediumAmmo { get; set; }

		public static int ShaderTotalHeavyAmmo { get; set; }

		public static int ShaderHealth { get; set; }

		public static int ShaderMaxHealth { get; set; }

		public static int ShaderHealthPercentage { get; set; }
	}
	public sealed class Mod : MelonMod
	{
		public static bool DebugEnabled => MelonDebug.IsEnabled();

		public override void OnInitializeMelon()
		{
			InitLogger();
			Logger.Msg("Logger initialised");
			Logger.Msg("Injecting types");
			InjectType<LoadingSceneActivator>();
			InjectType<AnimationBoolReference>();
			InjectType<AnimationFloatReference>();
			InjectType<AnimationIntReference>();
			InjectType<AnimationTriggerReference>();
			InjectType<RandomAnimationParameter>();
			InjectType<TMPMaterialPropertyOverrideFloat>();
			InjectType<TMPMaterialPropertyOverrideColor>();
			InjectType<TMPMaterialPropertyOverrideInt>();
			InjectType<TMPMaterialPropertyOverrideVector>();
			InjectType<AnimationController>();
			InjectType<ShaderFloatReference>();
			InjectType<ShaderIntReference>();
			InjectType<ShaderController>();
			InjectType<DebugGUI>();
			InjectType<HudVersion>();
			InjectType<HudV1>();
			InjectType<LinearParameters>();
			InjectType<HudController>();
			InjectType<HudBootstrap>();
			InjectType<PlayerEvents>();
			Logger.Msg("Patching methods");
			InstallPatch(typeof(AmmoInventory_AddCartridge));
			InstallPatch(typeof(Gashapon_InsertMagazine));
			InstallPatch(typeof(Gashapon_SetupAmmo));
			InstallPatch(typeof(Gun_CompleteSlidePull));
			InstallPatch(typeof(Gun_OnMagazineInserted));
			InstallPatch(typeof(Gun_OnMagazineRemoved));
			InstallPatch(typeof(Health_SetAvatar));
			InstallPatch(typeof(HealthSetterMachine_SET_HEALTH));
			InstallPatch(typeof(MonoMatNew_InsertMagazine));
			InstallPatch(typeof(PlayerHealth_CoRegenHealth));
			InstallPatch(typeof(PlayerHealth_Dying));
			InstallPatch(typeof(PlayerHealth_LifeSavingDamgeDelt));
			InstallPatch(typeof(PlayerHealth_SetFullHealth));
			InstallPatch(typeof(PlayerHealth_STARTDATA));
			InstallPatch(typeof(PlayerHealth_TAKEDAMAGE));
			InstallPatch(typeof(PlayerHealth_ToggleInstantDeathMode));
			InstallPatch(typeof(PlayerHealth_UpdateHealth));
			InstallPatch(typeof(LoadingScene_Start));
			InstallPatch(typeof(PlayerMarker_OnPlayerSpawned));
			Logger.Msg("Creating HUDs directory");
			CreateHudDirectory();
			Logger.Msg("Registering BoneMenu");
			SettingsMenu.Register();
		}

		public override void OnDeinitializeMelon()
		{
			Logger.Msg("Unpatching methods");
			((MelonBase)this).HarmonyInstance.UnpatchSelf();
			Logger.Msg("Saving config");
			Config.Instance.Save();
		}

		private void InitLogger()
		{
			Logger.Instance = ((MelonBase)this).LoggerInstance;
			Logger.EnableDebug(MelonDebug.IsEnabled());
		}

		private void CreateHudDirectory()
		{
			string path = Path.Join(MelonEnvironment.UserDataDirectory, "SpectatorHUD", "HUDs");
			try
			{
				Directory.CreateDirectory(path);
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to create HUDs directory.", ex);
			}
		}

		private void InstallPatch(Type patchType)
		{
			//IL_003b: Expected O, but got Unknown
			PatchClassProcessor val = ((MelonBase)this).HarmonyInstance.CreateClassProcessor(patchType, true);
			try
			{
				val.Patch().ForEach(delegate(MethodInfo method)
				{
					Logger.Debug("Patched {0}::{1}", method.DeclaringType?.FullName ?? "", method.Name);
				});
			}
			catch (HarmonyException ex)
			{
				HarmonyException ex2 = ex;
				Logger.Error("Failed to patch method.", (Exception)(object)ex2);
			}
		}

		private void InjectType<T>()
		{
			int num = (MelonDebug.IsEnabled() ? 4 : 0);
			Logger.Debug("Injecting type {0}", typeof(T).FullName ?? "");
			SerialisationHandler.Inject<T>(num);
		}
	}
	public class PlayerEvents : MonoBehaviour
	{
		private readonly Action<HandReciever>? _onReceiverAttachedLeft;

		private readonly Action<HandReciever>? _onReceiverAttachedRight;

		private readonly Action<HandReciever>? _onReceiverDetachedLeft;

		private readonly Action<HandReciever>? _onReceiverDetachedRight;

		private Hand? _leftHand;

		private RigManager? _rigManager;

		private Hand? _rightHand;

		public PlayerEvents(IntPtr ptr)
			: base(ptr)
		{
			_onReceiverAttachedLeft = DelegateSupport.ConvertDelegate<Action<HandReciever>>((Delegate)new Action<HandReciever>(OnReceiverAttachedLeft));
			_onReceiverDetachedLeft = DelegateSupport.ConvertDelegate<Action<HandReciever>>((Delegate)new Action<HandReciever>(OnReceiverDetachedLeft));
			_onReceiverAttachedRight = DelegateSupport.ConvertDelegate<Action<HandReciever>>((Delegate)new Action<HandReciever>(OnReceiverAttachedRight));
			_onReceiverDetachedRight = DelegateSupport.ConvertDelegate<Action<HandReciever>>((Delegate)new Action<HandReciever>(OnReceiverDetachedRight));
		}

		private void Start()
		{
			_rigManager = ((Component)this).GetComponent<RigManager>();
			PhysicsRig physicsRig = _rigManager.physicsRig;
			_leftHand = physicsRig.leftHand;
			_rightHand = physicsRig.rightHand;
			Hand? leftHand = _leftHand;
			leftHand.onRecieverAttached += _onReceiverAttachedLeft;
			Hand? leftHand2 = _leftHand;
			leftHand2.onRecieverDetached += _onReceiverDetachedLeft;
			Hand? rightHand = _rightHand;
			rightHand.onRecieverAttached += _onReceiverAttachedRight;
			Hand? rightHand2 = _rightHand;
			rightHand2.onRecieverDetached += _onReceiverDetachedRight;
		}

		private void OnDestroy()
		{
			Hand? leftHand = _leftHand;
			if (leftHand != null)
			{
				leftHand.onRecieverAttached -= _onReceiverAttachedLeft;
			}
			Hand? leftHand2 = _leftHand;
			if (leftHand2 != null)
			{
				leftHand2.onRecieverDetached -= _onReceiverDetachedLeft;
			}
			Hand? rightHand = _rightHand;
			if (rightHand != null)
			{
				rightHand.onRecieverAttached -= _onReceiverAttachedRight;
			}
			Hand? rightHand2 = _rightHand;
			if (rightHand2 != null)
			{
				rightHand2.onRecieverDetached -= _onReceiverDetachedRight;
			}
		}

		private void OnReceiverAttachedLeft(HandReciever handReciever)
		{
			Logger.Debug("HudState: OnReceiverAttachedLeft called");
			if (handReciever.TryFindGunFromReceiver(out Gun gun))
			{
				HudState.LeftGun = gun;
				if ((Object)(object)gun != (Object)null)
				{
					HudState.LeftDefaultCartridge = new CartridgeContainer(gun.defaultCartridge);
					HudState.LeftAmmo = gun.GetAmmoCount();
					HudState.LeftReserve = AmmoInventory.Instance.GetCartridgeCount(HudState.LeftDefaultCartridge.cartridge) - HudState.LeftAmmo;
					HudState.LeftTotalAmmo = HudState.LeftAmmo + HudState.LeftReserve;
				}
				else
				{
					HudState.LeftDefaultCartridge = null;
					HudState.LeftAmmo = null;
					HudState.LeftReserve = null;
					HudState.LeftTotalAmmo = null;
				}
			}
		}

		private void OnReceiverDetachedLeft(HandReciever handReciever)
		{
			Logger.Debug("PlayerEvents: OnReceiverDetachedLeft called");
			HudState.LeftGun = null;
			HudState.LeftDefaultCartridge = null;
			HudState.LeftAmmo = null;
			HudState.LeftReserve = null;
			HudState.LeftTotalAmmo = null;
		}

		private void OnReceiverAttachedRight(HandReciever handReciever)
		{
			Logger.Debug("HudState: OnReceiverAttachedRight called");
			if (handReciever.TryFindGunFromReceiver(out Gun gun))
			{
				HudState.RightGun = gun;
				if ((Object)(object)gun != (Object)null)
				{
					HudState.RightDefaultCartridge = new CartridgeContainer(gun.defaultCartridge);
					HudState.RightAmmo = gun.GetAmmoCount();
					HudState.RightReserve = AmmoInventory.Instance.GetCartridgeCount(HudState.RightDefaultCartridge.cartridge) - HudState.RightAmmo;
					HudState.RightTotalAmmo = HudState.RightAmmo + HudState.RightReserve;
				}
				else
				{
					HudState.RightDefaultCartridge = null;
					HudState.RightAmmo = null;
					HudState.RightReserve = null;
					HudState.RightTotalAmmo = null;
				}
			}
		}

		private void OnReceiverDetachedRight(HandReciever handReciever)
		{
			Logger.Debug("HudState: OnReceiverDetachedRight called");
			HudState.RightGun = null;
			HudState.RightDefaultCartridge = null;
			HudState.RightAmmo = null;
			HudState.RightReserve = null;
			HudState.RightTotalAmmo = null;
		}
	}
	public static class SettingsMenu
	{
		private static List<Page> hudSelection;

		private static Color MyColour => new Color(0.404f, 0.306f, 0.635f);

		public static void Register()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("Millzy", MyColour, 0, true).CreatePage("Spectator HUD", Color.yellow, 0, true);
			FillSelectHudPage(obj.CreatePage("Select HUD", Color.white, 0, true));
			obj.CreateFunction("Reload", Color.yellow, (Action)SceneStreamer.Reload);
		}

		private static void FillSelectHudPage(Page parent)
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			List<Tuple<HudV1, string>> list = new List<Tuple<HudV1, string>>();
			HudV1 metadataFromEmbeddedResource = GetMetadataFromEmbeddedResource("SpectatorHUD.Resources.Half-Life 2.hud");
			if ((Object)(object)metadataFromEmbeddedResource != (Object)null)
			{
				list.Add(new Tuple<HudV1, string>(metadataFromEmbeddedResource, null));
			}
			IEnumerable<Tuple<HudV1, string>> collection = from f in Directory.GetFiles(Path.Join(MelonEnvironment.UserDataDirectory, "SpectatorHUD", "HUDs"), "*.hud", SearchOption.TopDirectoryOnly)
				select new Tuple<HudV1, string>(GetMetadataFromFile(f), f) into m
				where (Object)(object)m.Item1 != (Object)null
				select m;
			list.AddRange(collection);
			foreach (Tuple<HudV1, string> item in list)
			{
				var (hud, hudPath) = item;
				parent.CreateFunction($"{hud.hudName} <color=#828282>v{hud.hudVersion}</color>", Color.white, (Action)delegate
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_008d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0092: Unknown result type (might be due to invalid IL or missing references)
					//IL_0097: Unknown result type (might be due to invalid IL or missing references)
					//IL_009d: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
					//IL_00af: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b9: Expected O, but got Unknown
					Config.Instance.Hud = hudPath;
					Notifier.Send(new Notification
					{
						Message = new NotificationText($"HUD set to {hud.hudName} v{hud.hudVersion} by {hud.hudAuthor}. Reload to Apply."),
						Title = new NotificationText("Spectator HUD", Color.yellow, false),
						Type = (NotificationType)3
					});
				});
			}
		}

		private static HudV1? GetMetadataFromFile(string path)
		{
			AssetBundle val = AssetBundle.LoadFromFile(path);
			if ((Object)(object)val == (Object)null)
			{
				Logger.Error("Failed to load asset bundle from " + path);
				return null;
			}
			return GetMetadataFromAssetBundle(val);
		}

		private static HudV1? GetMetadataFromEmbeddedResource(string resource)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
			if (stream == null)
			{
				Logger.Error("Unable to open stream to embedded resource " + resource + " not found.");
				return null;
			}
			MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return GetMetadataFromAssetBundle(AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(memoryStream.ToArray())));
		}

		private static HudV1? GetMetadataFromAssetBundle(AssetBundle assetBundle)
		{
			HudV1 hudV = ((Il2CppObjectBase)assetBundle.LoadAsset("Hud.asset")).TryCast<HudV1>();
			if ((Object)(object)hudV == (Object)null)
			{
				Logger.Error("Hud.asset could not be loaded from assetBundle: " + ((Object)assetBundle).name);
				return null;
			}
			assetBundle.Unload(false);
			int version = hudV.spectatorHudVersion.version;
			if ((uint)version <= 1u)
			{
				return hudV;
			}
			Logger.Error($"{hudV.hudName} v{hudV.hudVersion} by {hudV.hudAuthor} requires SDK v{hudV.spectatorHudVersion.version} features. " + "This version of SpectatorHUD supports up to v1");
			return null;
		}
	}
	public class ShaderController : MonoBehaviour
	{
		public List<ShaderIntReference> shaderLeftAmmo;

		public List<ShaderIntReference> shaderRightAmmo;

		public List<ShaderIntReference> shaderLeftReserve;

		public List<ShaderIntReference> shaderRightReserve;

		public List<ShaderIntReference> shaderTotalLeftAmmo;

		public List<ShaderIntReference> shaderTotalRightAmmo;

		public List<ShaderIntReference> shaderTotalLightAmmo;

		public List<ShaderIntReference> shaderTotalMediumAmmo;

		public List<ShaderIntReference> shaderTotalHeavyAmmo;

		public List<ShaderFloatReference> shaderHealth;

		public List<ShaderFloatReference> shaderMaxHealth;

		public List<ShaderFloatReference> shaderHealthPercentage;

		public ShaderController(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Start()
		{
			MetaInfo.ShaderLeftAmmo = shaderLeftAmmo.Count;
			MetaInfo.ShaderRightAmmo = shaderRightAmmo.Count;
			MetaInfo.ShaderLeftReserve = shaderLeftReserve.Count;
			MetaInfo.ShaderRightReserve = shaderRightReserve.Count;
			MetaInfo.ShaderTotalLeftAmmo = shaderTotalLeftAmmo.Count;
			MetaInfo.ShaderTotalRightAmmo = shaderTotalRightAmmo.Count;
			MetaInfo.ShaderTotalLightAmmo = shaderTotalLightAmmo.Count;
			MetaInfo.ShaderTotalMediumAmmo = shaderTotalMediumAmmo.Count;
			MetaInfo.ShaderTotalHeavyAmmo = shaderTotalHeavyAmmo.Count;
			MetaInfo.ShaderHealth = shaderHealth.Count;
			MetaInfo.ShaderMaxHealth = shaderMaxHealth.Count;
			MetaInfo.ShaderHealthPercentage = shaderHealthPercentage.Count;
			ProcessShaderProperties(shaderLeftAmmo);
			ProcessShaderProperties(shaderRightAmmo);
			ProcessShaderProperties(shaderLeftReserve);
			ProcessShaderProperties(shaderRightReserve);
			ProcessShaderProperties(shaderTotalLeftAmmo);
			ProcessShaderProperties(shaderTotalRightAmmo);
			ProcessShaderProperties(shaderTotalLightAmmo);
			ProcessShaderProperties(shaderTotalMediumAmmo);
			ProcessShaderProperties(shaderTotalHeavyAmmo);
			ProcessShaderProperties(shaderHealth);
			ProcessShaderProperties(shaderMaxHealth);
			ProcessShaderProperties(shaderHealthPercentage);
		}

		private void OnEnable()
		{
			HudState.OnLeftAmmoChanged += UpdateLeftAmmoShader;
			HudState.OnRightAmmoChanged += UpdateRightAmmoShader;
			HudState.OnLeftReserveChanged += UpdateLeftReserveShader;
			HudState.OnRightReserveChanged += UpdateRightReserveShader;
			HudState.OnHealthChanged += UpdateHealthShader;
			HudState.OnHealthPercentageChanged += UpdateHealthPercentageShader;
			HudState.OnMaxHealthChanged += UpdateMaxHealthShader;
		}

		private void OnDisable()
		{
			HudState.OnLeftAmmoChanged -= UpdateLeftAmmoShader;
			HudState.OnRightAmmoChanged -= UpdateRightAmmoShader;
			HudState.OnLeftReserveChanged -= UpdateLeftReserveShader;
			HudState.OnRightReserveChanged -= UpdateRightReserveShader;
			HudState.OnHealthChanged -= UpdateHealthShader;
			HudState.OnHealthPercentageChanged -= UpdateHealthPercentageShader;
			HudState.OnMaxHealthChanged -= UpdateMaxHealthShader;
		}

		private void UpdateLeftAmmoShader(int? ammo)
		{
			SetShaderInts(shaderLeftAmmo, ammo.GetValueOrDefault());
		}

		private void UpdateRightAmmoShader(int? ammo)
		{
			SetShaderInts(shaderRightAmmo, ammo.GetValueOrDefault());
		}

		private void UpdateLeftReserveShader(int? reserve)
		{
			SetShaderInts(shaderLeftReserve, reserve.GetValueOrDefault());
		}

		private void UpdateRightReserveShader(int? reserve)
		{
			SetShaderInts(shaderRightReserve, reserve.GetValueOrDefault());
		}

		private void UpdateHealthShader(float? health)
		{
			SetShaderFloatsWithModifier(shaderHealth, health.GetValueOrDefault());
		}

		private void UpdateHealthPercentageShader(float? percentage)
		{
			SetShaderFloatsWithModifier(shaderHealthPercentage, percentage.GetValueOrDefault());
		}

		private void UpdateMaxHealthShader(float? maxHealth)
		{
			SetShaderFloatsWithModifier(shaderMaxHealth, maxHealth.GetValueOrDefault());
		}

		private void SetShaderInts(List<ShaderIntReference> properties, int value)
		{
			foreach (ShaderIntReference property in properties)
			{
				property.material.SetInteger(property.propertyId, value);
			}
		}

		private void SetShaderFloatsWithModifier(List<ShaderFloatReference> properties, float value)
		{
			foreach (ShaderFloatReference property in properties)
			{
				property.material.SetFloat(property.propertyId, property.modifierExpression.Evaluate(value));
			}
		}

		private void ProcessShaderProperties(List<ShaderIntReference> properties)
		{
			for (int i = 0; i < properties.Count; i++)
			{
				ShaderIntReference value = properties[i];
				value.propertyId = Shader.PropertyToID(value.propertyName);
				properties[i] = value;
			}
		}

		private void ProcessShaderProperties(List<ShaderFloatReference> properties)
		{
			for (int i = 0; i < properties.Count; i++)
			{
				ShaderFloatReference value = properties[i];
				value.propertyId = Shader.PropertyToID(value.propertyName);
				value.modifierExpression = value.modifier.ToExpression();
				properties[i] = value;
			}
		}
	}
	internal static class BuildInfo
	{
		public const string Name = "SpectatorHUD";

		public const string Author = "Millzy";

		public const string Version = "1.0.0";

		public const string Description = "Create and load custom HUDs for the spectator camera.";

		public const string Id = "dev.millzy.SpectatorHUD";
	}
}
namespace SpectatorHUD.Util
{
	public enum AmmoCategory
	{
		Unknown,
		Light,
		Medium,
		Heavy
	}
	public static class AmmoCategoryUtil
	{
		public static AmmoCategory GetCategoryFromGroupKey(string groupKey)
		{
			if (groupKey == HudState.LightAmmoKey)
			{
				return AmmoCategory.Light;
			}
			if (groupKey == HudState.MediumAmmoKey)
			{
				return AmmoCategory.Medium;
			}
			if (groupKey == HudState.HeavyAmmoKey)
			{
				return AmmoCategory.Heavy;
			}
			return AmmoCategory.Unknown;
		}
	}
	public static class AmmoUpdateUtil
	{
		public static void UpdateReservesTargeted(CartridgeData cartridge)
		{
			int cartridgeCount = HudState.AmmoInventory.GetCartridgeCount(cartridge);
			if ((Object)(object)cartridge == (Object)(object)HudState.LeftDefaultCartridge?.cartridge)
			{
				HudState.LeftTotalAmmo = cartridgeCount;
				HudState.LeftReserve = cartridgeCount - HudState.LeftAmmo;
				switch (HudState.LeftDefaultCartridge.ammoCategory)
				{
				case AmmoCategory.Light:
					HudState.TotalLightAmmo = cartridgeCount;
					break;
				case AmmoCategory.Medium:
					HudState.TotalMediumAmmo = cartridgeCount;
					break;
				case AmmoCategory.Heavy:
					HudState.TotalHeavyAmmo = cartridgeCount;
					break;
				default:
					throw new ArgumentOutOfRangeException();
				case AmmoCategory.Unknown:
					break;
				}
			}
			else if ((Object)(object)cartridge == (Object)(object)HudState.RightDefaultCartridge?.cartridge)
			{
				HudState.RightTotalAmmo = cartridgeCount;
				HudState.RightReserve = cartridgeCount - HudState.RightAmmo;
				switch (HudState.RightDefaultCartridge.ammoCategory)
				{
				case AmmoCategory.Light:
					HudState.TotalLightAmmo = cartridgeCount;
					break;
				case AmmoCategory.Medium:
					HudState.TotalMediumAmmo = cartridgeCount;
					break;
				case AmmoCategory.Heavy:
					HudState.TotalHeavyAmmo = cartridgeCount;
					break;
				default:
					throw new ArgumentOutOfRangeException();
				case AmmoCategory.Unknown:
					break;
				}
			}
			else
			{
				string groupByCartridge = HudState.AmmoInventory.GetGroupByCartridge(cartridge);
				if (groupByCartridge == HudState.LightAmmoKey)
				{
					HudState.TotalLightAmmo = cartridgeCount;
				}
				else if (groupByCartridge == HudState.MediumAmmoKey)
				{
					HudState.TotalMediumAmmo = cartridgeCount;
				}
				else if (groupByCartridge == HudState.HeavyAmmoKey)
				{
					HudState.TotalHeavyAmmo = cartridgeCount;
				}
			}
		}

		public static void UpdateReservesTargeted(string groupKey)
		{
			int cartridgeCount = HudState.AmmoInventory.GetCartridgeCount(groupKey);
			if (groupKey == HudState.LeftDefaultCartridge?.groupKey)
			{
				HudState.LeftTotalAmmo = cartridgeCount;
				HudState.LeftReserve = cartridgeCount - HudState.LeftAmmo;
				switch (HudState.LeftDefaultCartridge.ammoCategory)
				{
				case AmmoCategory.Light:
					HudState.TotalLightAmmo = cartridgeCount;
					break;
				case AmmoCategory.Medium:
					HudState.TotalMediumAmmo = cartridgeCount;
					break;
				case AmmoCategory.Heavy:
					HudState.TotalHeavyAmmo = cartridgeCount;
					break;
				default:
					throw new ArgumentOutOfRangeException();
				case AmmoCategory.Unknown:
					break;
				}
			}
			else if (groupKey == HudState.RightDefaultCartridge?.groupKey)
			{
				HudState.RightTotalAmmo = cartridgeCount;
				HudState.RightReserve = cartridgeCount - HudState.RightAmmo;
				switch (HudState.RightDefaultCartridge.ammoCategory)
				{
				case AmmoCategory.Light:
					HudState.TotalLightAmmo = cartridgeCount;
					break;
				case AmmoCategory.Medium:
					HudState.TotalMediumAmmo = cartridgeCount;
					break;
				case AmmoCategory.Heavy:
					HudState.TotalHeavyAmmo = cartridgeCount;
					break;
				default:
					throw new ArgumentOutOfRangeException();
				case AmmoCategory.Unknown:
					break;
				}
			}
			else if (groupKey == HudState.LightAmmoKey)
			{
				HudState.TotalLightAmmo = cartridgeCount;
			}
			else if (groupKey == HudState.MediumAmmoKey)
			{
				HudState.TotalMediumAmmo = cartridgeCount;
			}
			else if (groupKey == HudState.HeavyAmmoKey)
			{
				HudState.TotalHeavyAmmo = cartridgeCount;
			}
		}
	}
	public class CartridgeContainer
	{
		private readonly AmmoInventory _ammoInventory;

		public readonly AmmoCategory ammoCategory;

		public readonly CartridgeData cartridge;

		public readonly string groupKey;

		public CartridgeContainer(CartridgeData cartridgeData)
		{
			_ammoInventory = HudState.AmmoInventory;
			cartridge = cartridgeData;
			groupKey = _ammoInventory.GetGroupByCartridge(cartridgeData);
			ammoCategory = AmmoCategoryUtil.GetCategoryFromGroupKey(groupKey);
		}
	}
	public class GUILayoutManager
	{
		private readonly float _elementHeight;

		private readonly float _elementWidth;

		private readonly float _elementSpacing;

		private readonly float _indentSize;

		private readonly float _spaceSize;

		private readonly Rect _original;

		private readonly List<Rect> _cachedRects;

		private int _state;

		private int _currentIndent;

		private Rect _cursor;

		public GUILayoutManager(float startX, float startY, float elementWidth, float elementHeight, float elementSpacing, float indentSize, float spaceSize, int cacheSize = 50)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			_elementWidth = elementWidth;
			_elementHeight = elementHeight;
			_elementSpacing = elementSpacing;
			_indentSize = indentSize;
			_spaceSize = spaceSize;
			_cachedRects = new List<Rect>(cacheSize);
			_cursor = new Rect(startX, startY, elementWidth, elementHeight);
			_original = _cursor;
		}

		public void Start()
		{
			_state = 0;
		}

		public void End()
		{
			int count = _cachedRects.Count;
			if (_cachedRects.Capacity == count)
			{
				_cachedRects.Capacity = count;
			}
		}

		public void Reset()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_cursor = _original;
		}

		public void Indent()
		{
			_currentIndent++;
		}

		public void Outdent()
		{
			_currentIndent--;
		}

		public void Column(int column)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			ref Rect cursor = ref _cursor;
			Rect original = _original;
			((Rect)(ref cursor)).x = ((Rect)(ref original)).x + (float)column * (_elementWidth + _spaceSize);
			ref Rect cursor2 = ref _cursor;
			original = _original;
			((Rect)(ref cursor2)).y = ((Rect)(ref original)).y;
		}

		public void Space(int times = 1)
		{
			ref Rect cursor = ref _cursor;
			((Rect)(ref cursor)).y = ((Rect)(ref cursor)).y + _spaceSize * (float)times;
		}

		public Rect GetNext()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (_state < _cachedRects.Count)
			{
				return _cachedRects[_state++];
			}
			Rect cursor = _cursor;
			((Rect)(ref cursor)).x = ((Rect)(ref cursor)).x + _indentSize * (float)_currentIndent;
			_state = _cachedRects.Count;
			_cachedRects.Add(cursor);
			_state++;
			ref Rect cursor2 = ref _cursor;
			((Rect)(ref cursor2)).y = ((Rect)(ref cursor2)).y + (_elementHeight + _elementSpacing);
			return cursor;
		}
	}
	public class Il2CppFieldAccessor<T> where T : struct
	{
		private readonly IntPtr _fieldInfo;

		private readonly uint _fieldOffset;

		private readonly Il2CppObjectBase _objectBase;

		public T Value
		{
			get
			{
				return Get();
			}
			set
			{
				Set(value);
			}
		}

		public Il2CppFieldAccessor(Il2CppObjectBase obj, string fieldName)
			: this(obj, IL2CPP.GetIl2CppField(obj.ObjectClass, fieldName))
		{
		}

		public Il2CppFieldAccessor(Il2CppObjectBase obj, IntPtr nativeFieldInfo)
		{
			_objectBase = obj;
			_fieldInfo = nativeFieldInfo;
			_fieldOffset = IL2CPP.il2cpp_field_get_offset(_fieldInfo);
			if (!IL2CPP.il2cpp_class_is_valuetype(IL2CPP.il2cpp_class_from_type(IL2CPP.il2cpp_field_get_type(_fieldInfo))))
			{
				throw new ArgumentException("T must be a value type");
			}
		}

		public unsafe T Get()
		{
			return Unsafe.Read<T>((void*)(IL2CPP.Il2CppObjectBaseToPtrNotNull(_objectBase) + (int)_fieldOffset));
		}

		public unsafe void Set(T value)
		{
			Unsafe.Write((void*)(IL2CPP.Il2CppObjectBaseToPtrNotNull(_objectBase) + (int)_fieldOffset), value);
		}
	}
}
namespace SpectatorHUD.Shading
{
	[Serializable]
	public struct ShaderFloatReference
	{
		public Material material;

		public string propertyName;

		public LinearParameters modifier;

		[NonSerialized]
		public int propertyId;

		[NonSerialized]
		public LinearExpression<float> modifierExpression;
	}
	[Serializable]
	public struct ShaderIntReference
	{
		public Material material;

		public string propertyName;

		[NonSerialized]
		public int propertyId;
	}
}
namespace SpectatorHUD.HarmonyPatches
{
	[HarmonyPatch(typeof(AmmoInventory))]
	[HarmonyPatch("AddCartridge")]
	public static class AmmoInventory_AddCartridge
	{
		[HarmonyPostfix]
		[HarmonyPatch(new Type[]
		{
			typeof(AmmoGroup),
			typeof(int)
		})]
		public static void PostfixAmmoGroup(AmmoGroup ammoGroup)
		{
			AmmoUpdateUtil.UpdateReservesTargeted(ammoGroup.KeyName);
		}

		[HarmonyPostfix]
		[HarmonyPatch(new Type[]
		{
			typeof(CartridgeData),
			typeof(int)
		})]
		private static void PostfixCartridgeData(CartridgeData cartridge)
		{
			AmmoUpdateUtil.UpdateReservesTargeted(cartridge);
		}
	}
	[HarmonyPatch(typeof(Control_Gashapon))]
	[HarmonyPatch("InsertMagazine")]
	public static class Gashapon_InsertMagazine
	{
		[HarmonyPostfix]
		private static void Postfix(Magazine magazine)
		{
			AmmoUpdateUtil.UpdateReservesTargeted(magazine.magazineState.cartridgeData);
		}
	}
	[HarmonyPatch(typeof(Control_Gashapon))]
	[HarmonyPatch("SetupAmmo")]
	public static class Gashapon_SetupAmmo
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			AmmoInventory ammoInventory = HudState.AmmoInventory;
			int cartridgeCount = ammoInventory.GetCartridgeCount(HudState.LightAmmoKey);
			int cartridgeCount2 = ammoInventory.GetCartridgeCount(HudState.MediumAmmoKey);
			int cartridgeCount3 = ammoInventory.GetCartridgeCount(HudState.HeavyAmmoKey);
			HudState.TotalLightAmmo = cartridgeCount;
			HudState.TotalMediumAmmo = cartridgeCount2;
			HudState.TotalMediumAmmo = cartridgeCount3;
			if (HudState.RightDefaultCartridge != null)
			{
				switch (HudState.RightDefaultCartridge.ammoCategory)
				{
				case AmmoCategory.Unknown:
					HudState.RightTotalAmmo = ammoInventory.GetCartridgeCount(HudState.RightDefaultCartridge.cartridge);
					HudState.RightReserve = HudState.RightTotalAmmo - HudState.RightAmmo;
					break;
				case AmmoCategory.Light:
					HudState.RightTotalAmmo = cartridgeCount;
					HudState.RightReserve = cartridgeCount - HudState.RightAmmo;
					break;
				case AmmoCategory.Medium:
					HudState.RightTotalAmmo = cartridgeCount2;
					HudState.RightReserve = cartridgeCount2 - HudState.RightAmmo;
					break;
				case AmmoCategory.Heavy:
					HudState.RightTotalAmmo = cartridgeCount3;
					HudState.RightReserve = cartridgeCount3 - HudState.RightAmmo;
					break;
				default:
					throw new ArgumentOutOfRangeException();
				}
			}
			if (HudState.LeftDefaultCartridge != null)
			{
				switch (HudState.LeftDefaultCartridge.ammoCategory)
				{
				case AmmoCategory.Unknown:
					HudState.LeftTotalAmmo = ammoInventory.GetCartridgeCount(HudState.LeftDefaultCartridge.cartridge);
					HudState.LeftReserve = HudState.LeftTotalAmmo - HudState.LeftAmmo;
					break;
				case AmmoCategory.Light:
					HudState.LeftTotalAmmo = cartridgeCount;
					HudState.LeftReserve = cartridgeCount - HudState.LeftAmmo;
					break;
				case AmmoCategory.Medium:
					HudState.LeftTotalAmmo = cartridgeCount2;
					HudState.LeftReserve = cartridgeCount2 - HudState.LeftAmmo;
					break;
				case AmmoCategory.Heavy:
					HudState.LeftTotalAmmo = cartridgeCount3;
					HudState.LeftReserve = cartridgeCount3 - HudState.LeftAmmo;
					break;
				default:
					throw new ArgumentOutOfRangeException();
				}
			}
		}
	}
	[HarmonyPatch(typeof(Gun))]
	[HarmonyPatch("CompleteSlidePull")]
	public static class Gun_CompleteSlidePull
	{
		[HarmonyPostfix]
		private static void Postfix(Gun __instance)
		{
			if ((Object)(object)__instance == (Object)(object)HudState.RightGun)
			{
				HudState.RightTotalAmmo = HudState.AmmoInventory.GetTotalAmmoForGun(__instance);
				HudState.RightAmmo = HudState.RightGun.GetAmmoCount();
				AmmoCategory? ammoCategory = HudState.RightDefaultCartridge?.ammoCategory;
				if (ammoCategory.HasValue)
				{
					switch (ammoCategory.GetValueOrDefault())
					{
					case AmmoCategory.Light:
						HudState.TotalLightAmmo = HudState.RightTotalAmmo;
						break;
					case AmmoCategory.Medium:
						HudState.TotalMediumAmmo = HudState.RightTotalAmmo;
						break;
					case AmmoCategory.Heavy:
						HudState.TotalHeavyAmmo = HudState.RightTotalAmmo;
						break;
					default:
						throw new ArgumentOutOfRangeException();
					case AmmoCategory.Unknown:
						break;
					}
				}
			}
			else
			{
				if (!((Object)(object)__instance == (Object)(object)HudState.LeftGun))
				{
					return;
				}
				HudState.LeftTotalAmmo = HudState.AmmoInventory.GetTotalAmmoForGun(__instance);
				HudState.LeftAmmo = HudState.LeftGun.GetAmmoCount();
				AmmoCategory? ammoCategory = HudState.LeftDefaultCartridge?.ammoCategory;
				if (ammoCategory.HasValue)
				{
					switch (ammoCategory.GetValueOrDefault())
					{
					case AmmoCategory.Light:
						HudState.TotalLightAmmo = HudState.LeftTotalAmmo;
						break;
					case AmmoCategory.Medium:
						HudState.TotalMediumAmmo = HudState.LeftTotalAmmo;
						break;
					case AmmoCategory.Heavy:
						HudState.TotalHeavyAmmo = HudState.LeftTotalAmmo;
						break;
					default:
						throw new ArgumentOutOfRangeException();
					case AmmoCategory.Unknown:
						break;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Gun))]
	[HarmonyPatch("OnMagazineInserted")]
	public static class Gun_OnMagazineInserted
	{
		[HarmonyPostfix]
		private static void Postfix(Gun __instance)
		{
			if ((Object)(object)__instance == (Object)(object)HudState.RightGun)
			{
				HudState.RightAmmo = HudState.RightGun.GetAmmoCount();
				HudState.RightReserve = AmmoInventory.Instance.GetTotalAmmoForGun(__instance) - HudState.RightAmmo;
				Logger.Debug("Right magazine inserted");
			}
			else if ((Object)(object)__instance == (Object)(object)HudState.LeftGun)
			{
				HudState.LeftAmmo = HudState.LeftGun.GetAmmoCount();
				HudState.LeftReserve = AmmoInventory.Instance.GetTotalAmmoForGun(__instance) - HudState.LeftAmmo;
				Logger.Debug("Left magazine inserted");
			}
		}
	}
	[HarmonyPatch(typeof(Gun))]
	[HarmonyPatch("OnMagazineRemoved")]
	public static class Gun_OnMagazineRemoved
	{
		[HarmonyPostfix]
		private static void Postfix(Gun __instance)
		{
			if ((Object)(object)__instance == (Object)(object)HudState.RightGun)
			{
				HudState.RightAmmo = HudState.RightGun.GetAmmoCount();
				HudState.RightReserve = AmmoInventory.Instance.GetTotalAmmoForGun(__instance) - HudState.RightAmmo;
				Logger.Debug("Right magazine removed");
			}
			else if ((Object)(object)__instance == (Object)(object)HudState.LeftGun)
			{
				HudState.LeftAmmo = HudState.LeftGun.GetAmmoCount();
				HudState.LeftReserve = AmmoInventory.Instance.GetTotalAmmoForGun(__instance) - HudState.LeftAmmo;
				Logger.Debug("Left magazine removed");
			}
		}
	}
	[HarmonyPatch(typeof(HealthSetterMachine))]
	[HarmonyPatch("SET_HEALTH")]
	public static class HealthSetterMachine_SET_HEALTH
	{
		[HarmonyPostfix]
		private static void Postfix(HealthSetterMachine __instance)
		{
			HudState.MaxHealth = ((Health)__instance.player_Health).max_Health;
			HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
		}
	}
	[HarmonyPatch(typeof(Health))]
	[HarmonyPatch("SetAvatar")]
	public static class Health_SetAvatar
	{
		[HarmonyPostfix]
		private static void Postfix(Health __instance)
		{
			if (!((Object)(object)__instance._rigManager != (Object)(object)HudState.RigManager))
			{
				HudState.Health = __instance.curr_Health;
				HudState.MaxHealth = __instance.max_Health;
				HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
			}
		}
	}
	[HarmonyPatch(typeof(LoadingScene))]
	[HarmonyPatch("Start")]
	public static class LoadingScene_Start
	{
		[HarmonyPostfix]
		public static void Postfix(LoadingScene __instance)
		{
			((Component)__instance).gameObject.AddComponent<LoadingSceneActivator>();
		}
	}
	[HarmonyPatch(typeof(Control_MonoMatNew))]
	[HarmonyPatch("InsertMagazine")]
	public static class MonoMatNew_InsertMagazine
	{
		[HarmonyPostfix]
		private static void Postfix(Magazine magazine)
		{
			CartridgeData cartridgeData = magazine.magazineState.cartridgeData;
			int cartridgeCount = AmmoInventory.Instance.GetCartridgeCount(cartridgeData);
			if ((Object)(object)cartridgeData == (Object)(object)HudState.LeftDefaultCartridge?.cartridge)
			{
				HudState.LeftTotalAmmo = cartridgeCount;
				HudState.LeftReserve = cartridgeCount - HudState.LeftAmmo;
				switch (HudState.LeftDefaultCartridge.ammoCategory)
				{
				case AmmoCategory.Light:
					HudState.TotalLightAmmo = cartridgeCount;
					break;
				case AmmoCategory.Medium:
					HudState.TotalMediumAmmo = cartridgeCount;
					break;
				case AmmoCategory.Heavy:
					HudState.TotalHeavyAmmo = cartridgeCount;
					break;
				default:
					throw new ArgumentOutOfRangeException();
				case AmmoCategory.Unknown:
					break;
				}
			}
			else if ((Object)(object)cartridgeData == (Object)(object)HudState.RightDefaultCartridge?.cartridge)
			{
				HudState.RightTotalAmmo = cartridgeCount;
				HudState.RightReserve = cartridgeCount - HudState.RightAmmo;
				switch (HudState.RightDefaultCartridge.ammoCategory)
				{
				case AmmoCategory.Light:
					HudState.TotalLightAmmo = cartridgeCount;
					break;
				case AmmoCategory.Medium:
					HudState.TotalMediumAmmo = cartridgeCount;
					break;
				case AmmoCategory.Heavy:
					HudState.TotalHeavyAmmo = cartridgeCount;
					break;
				default:
					throw new ArgumentOutOfRangeException();
				case AmmoCategory.Unknown:
					break;
				}
			}
			else
			{
				string groupByCartridge = HudState.AmmoInventory.GetGroupByCartridge(cartridgeData);
				if (groupByCartridge == HudState.LightAmmoKey)
				{
					HudState.TotalLightAmmo = cartridgeCount;
				}
				else if (groupByCartridge == HudState.MediumAmmoKey)
				{
					HudState.TotalMediumAmmo = cartridgeCount;
				}
				else if (groupByCartridge == HudState.HeavyAmmoKey)
				{
					HudState.TotalHeavyAmmo = cartridgeCount;
				}
			}
		}
	}
	[HarmonyPatch(typeof(_CoRegenHealth_d__78))]
	[HarmonyPatch("MoveNext")]
	public static class PlayerHealth_CoRegenHealth
	{
		[HarmonyPostfix]
		private static void Postfix(_CoRegenHealth_d__78 __instance)
		{
			if (!((double)__instance._timer_5__2 > 0.0))
			{
				HudState.Health = ((Health)__instance.__4__this).curr_Health;
				HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
			}
		}
	}
	[HarmonyPatch(typeof(Player_Health))]
	[HarmonyPatch("Dying")]
	public static class PlayerHealth_Dying
	{
		[HarmonyPostfix]
		private static void Postfix(Player_Health __instance)
		{
			HudState.Health = Math.Max(((Health)__instance).curr_Health, -0f);
			HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
		}
	}
	[HarmonyPatch(typeof(Player_Health))]
	[HarmonyPatch("LifeSavingDamgeDealt")]
	public static class PlayerHealth_LifeSavingDamgeDelt
	{
		[HarmonyPostfix]
		private static void Postfix(Player_Health __instance)
		{
			HudState.Health = ((Health)__instance).curr_Health;
			HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
		}
	}
	[HarmonyPatch(typeof(Player_Health))]
	[HarmonyPatch("SetFullHealth")]
	public static class PlayerHealth_SetFullHealth
	{
		[HarmonyPostfix]
		private static void Postfix(Player_Health __instance)
		{
			HudState.Health = ((Health)__instance).curr_Health;
			HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
		}
	}
	[HarmonyPatch(typeof(Player_Health))]
	[HarmonyPatch("STARTDATA")]
	public static class PlayerHealth_STARTDATA
	{
		[HarmonyPostfix]
		private static void Postfix(Player_Health __instance)
		{
			HudState.Health = ((Health)__instance).curr_Health;
			HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
		}
	}
	[HarmonyPatch(typeof(Player_Health))]
	[HarmonyPatch("TAKEDAMAGE")]
	public static class PlayerHealth_TAKEDAMAGE
	{
		[HarmonyPostfix]
		private static void Postfix(Player_Health __instance)
		{
			HudState.Health = ((Health)__instance).curr_Health;
			HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
		}
	}
	[HarmonyPatch(typeof(Player_Health))]
	[HarmonyPatch("ToggleInstantDeathMode")]
	public static class PlayerHealth_ToggleInstantDeathMode
	{
		[HarmonyPostfix]
		private static void Postfix(Player_Health __instance)
		{
			HudState.Health = ((Health)__instance).max_Health;
			HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
		}
	}
	[HarmonyPatch(typeof(Player_Health))]
	[HarmonyPatch("UpdateHealth")]
	public static class PlayerHealth_UpdateHealth
	{
		[HarmonyPostfix]
		private static void Postfix(Player_Health __instance)
		{
			HudState.Health = ((Health)__instance).curr_Health;
			HudState.HealthPercentage = HudState.Health / HudState.MaxHealth;
		}
	}
	[HarmonyPatch(typeof(PlayerMarker))]
	[HarmonyPatch("OnPlayerSpawned")]
	public static class PlayerMarker_OnPlayerSpawned
	{
		[HarmonyPostfix]
		private static void Postfix(PlayerMarker __instance, GameObject go)
		{
			Logger.Debug("Player Spawned: " + ((Object)go).name);
			go.AddComponent<HudBootstrap>();
			go.AddComponent<PlayerEvents>();
			if (Mod.DebugEnabled)
			{
				go.AddComponent<DebugGUI>();
			}
		}
	}
}
namespace SpectatorHUD.Extensions
{
	public static class AmmoInventoryExtensions
	{
		[SpecialName]
		public sealed class <G>$3661631B6B70494A287249B0A179CA84
		{
			[SpecialName]
			public static class <M>$2B21B1EFF1274BE1D5279CF43E11A1D6
			{
			}

			[ExtensionMarker("<M>$2B21B1EFF1274BE1D5279CF43E11A1D6")]
			public int GetTotalAmmoForGun(Gun gun)
			{
				throw new NotSupportedException();
			}

			[ExtensionMarker("<M>$2B21B1EFF1274BE1D5279CF43E11A1D6")]
			public int GetReserveForGun(Gun gun)
			{
				throw new NotSupportedException();
			}
		}

		public static int GetTotalAmmoForGun(this AmmoInventory ammoInventory, Gun gun)
		{
			return ammoInventory.GetCartridgeCount(gun.defaultCartridge);
		}

		public static int GetReserveForGun(this AmmoInventory ammoInventory, Gun gun)
		{
			return ammoInventory.GetTotalAmmoForGun(gun) - gun.GetAmmoCount();
		}
	}
	public static class GunExtensions
	{
		[SpecialName]
		public sealed class <G>$D5001B5F4719B57A461C58827ADE1801
		{
			[SpecialName]
			public static class <M>$C7964F826E1B38B1BE872C7EDEEB1E37
			{
			}

			[ExtensionMarker("<M>$C7964F826E1B38B1BE872C7EDEEB1E37")]
			public int GetAmmoCount()
			{
				throw new NotSupportedException();
			}
		}

		public static int GetAmmoCount(this Gun gun)
		{
			if (gun._magState != null)
			{
				if (!((Object)(object)gun.chamberedCartridge != (Object)null))
				{
					return gun._magState.AmmoCount;
				}
				return gun._magState.AmmoCount + 1;
			}
			return ((Object)(object)gun.chamberedCartridge != (Object)null) ? 1 : 0;
		}
	}
	public static class HandRecieverExtensions
	{
		[SpecialName]
		public sealed class <G>$ED9F5587F180666C94C36FABD7D5CD17
		{
			[SpecialName]
			public static class <M>$6952FCC2A774872102436A50AB464A7C
			{
			}

			[ExtensionMarker("<M>$6952FCC2A774872102436A50AB464A7C")]
			public bool TryFindGunFromReceiver(out Gun? gun)
			{
				throw new NotSupportedException();
			}
		}

		public static bool TryFindGunFromReceiver(this HandReciever handReciever, out Gun? gun)
		{
			gun = ((Component)handReciever).GetComponentInParent<Gun>();
			if ((Object)(object)gun == (Object)null)
			{
				return false;
			}
			return (Object)(object)gun.triggerGrip == (Object)(object)handReciever;
		}
	}
}
namespace SpectatorHUD.Expressions
{
	public class LinearExpression<T> where T : struct
	{
		private delegate T LinearFunction(T x);

		private readonly LinearFunction _function;

		public LinearExpression(T aValue, T bValue)
		{
			ConstantExpression left = Expression.Constant(aValue, typeof(T));
			ConstantExpression right = Expression.Constant(bValue, typeof(T));
			ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "x");
			Expression<LinearFunction> expression = Expression.Lambda<LinearFunction>(Expression.Add(Expression.Multiply(left, parameterExpression), right), new ParameterExpression[1] { parameterExpression });
			_function = expression.Compile();
		}

		public T Evaluate(T x)
		{
			return _function(x);
		}
	}
	[Serializable]
	public struct LinearParameters
	{
		public float multiplier;

		public float offset;

		[HideFromIl2Cpp]
		public LinearExpression<float> ToExpression()
		{
			return new LinearExpression<float>(multiplier, offset);
		}
	}
}
namespace SpectatorHUD.Animation
{
	[Serializable]
	public struct AnimationBoolReference
	{
		public Animator animator;

		public string parameterName;

		[NonSerialized]
		public int parameterId;
	}
	[Serializable]
	public struct AnimationFloatReference
	{
		public Animator animator;

		public string parameterName;

		[NonSerialized]
		public int parameterId;
	}
	[Serializable]
	public struct AnimationIntReference
	{
		public Animator animator;

		public string parameterName;

		[NonSerialized]
		public int parameterId;
	}
	[Serializable]
	public struct AnimationTriggerReference
	{
		public Animator animator;

		public string parameterName;

		[NonSerialized]
		public int parameterId;
	}
	public class RandomAnimationParameter : MonoBehaviour
	{
		public Animator animator;

		public string parameterName;

		private int _parameterId;

		public float rangeMin;

		public float rangeMax;

		public bool doesCycle;

		public int bufferSize;

		public float interval;

		private float[] _buffer;

		private object? _coroutine;

		public RandomAnimationParameter(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Start()
		{
			_parameterId = Animator.StringToHash(parameterName);
			float range = rangeMax - rangeMin;
			if (!doesCycle)
			{
				Random random = new Random();
				float num = rangeMin + random.NextSingle() * range;
				animator.SetFloat(_parameterId, num);
				return;
			}
			_buffer = new float[bufferSize];
			Parallel.For(0, bufferSize, delegate(int i)
			{
				_buffer[i] = rangeMin + Random.Shared.NextSingle() * range;
			});
			_coroutine = MelonCoroutines.Start(BufferCycle());
		}

		private void OnDestroy()
		{
			if (_coroutine != null)
			{
				MelonCoroutines.Stop(_coroutine);
			}
		}

		private IEnumerator BufferCycle()
		{
			int i = 0;
			while (true)
			{
				if (i >= bufferSize)
				{
					i = 0;
				}
				animator.SetFloat(_parameterId, _buffer[i++]);
				yield return (object)new WaitForSeconds(interval);
			}
		}
	}
	public class TMPMaterialPropertyOverrideColor : MonoBehaviour
	{
		public TMP_FontAsset fontAsset;

		public string propertyName;

		public Color value;

		private readonly Il2CppFieldAccessor<Color> _valueAccessor;

		private Material _material;

		private int _propertyId;

		public TMPMaterialPropertyOverrideColor(IntPtr ptr)
			: base(ptr)
		{
			_valueAccessor = new Il2CppFieldAccessor<Color>((Il2CppObjectBase)(object)this, "value");
		}

		private void Awake()
		{
			_material = ((TMP_Asset)fontAsset).material;
			_propertyId = Shader.PropertyToID(propertyName);
		}

		private void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			value = _valueAccessor.Value;
			_material.SetColor(_propertyId, value);
		}
	}
	public class TMPMaterialPropertyOverrideFloat : MonoBehaviour
	{
		public TMP_FontAsset fontAsset;

		public string propertyName;

		public float value;

		private readonly Il2CppFieldAccessor<float> _valueAccessor;

		private Material _material;

		private int _propertyId;

		public TMPMaterialPropertyOverr