Decompiled source of SpectatorHUD v1.0.0
Mods/SpectatorHUD.dll
Decompiled 17 hours ago
The result has been truncated due to the large size, download it to view full contents!
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