Decompiled source of RealismLab v0.9.51

Mods/Realismlab.dll

Decompiled 12 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSLZ.VRMK;
using LabFusion.Entities;
using LabFusion.Player;
using LabFusion.RPC;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Realismlab;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
using UnityEngine.XR;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: MelonInfo(typeof(RealismlabMod), "RealismLab", "0.9.51", "Realismlab", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: AssemblyFileVersion("0.9.51.0")]
[assembly: AssemblyInformationalVersion("0.9.51")]
[assembly: AssemblyVersion("0.9.51.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : System.Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class RefSafetyRulesAttribute : System.Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Realismlab
{
	public sealed class RealismlabMod : MelonMod
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action<RigManager, float> <0>__OnPlayerDamage;

			public static Action<RigManager> <1>__OnPlayerResurrected;

			public static Action <2>__ClearKillTracking;

			public static Action <3>__ClearKillTracking;

			public static Action<Gun> <4>__OnPostFireGun;

			public static Action <5>__Clear;

			public static Action <6>__Clear;

			public static Action <7>__Clear;

			public static Action <8>__Clear;

			public static Action <9>__ResetInjuries;

			public static Action<bool> <10>__SetEnabled;

			public static Action<bool> <11>__SetNightVisionEnabled;
		}

		private const string CategoryName = "RealismLab";

		private static MelonPreferences_Category _prefs;

		private static MelonPreferences_Entry<bool> _enabled;

		private static MelonPreferences_Entry<bool> _bodyRecoilEnabled;

		private static MelonPreferences_Entry<float> _bodyRecoilImpulse;

		private static MelonPreferences_Entry<bool> _limbInjuries;

		private static MelonPreferences_Entry<bool> _bloodEffects;

		private static MelonPreferences_Entry<bool> _woundMarks;

		private static MelonPreferences_Entry<bool> _restoreAtFullHealth;

		private static MelonPreferences_Entry<bool> _hideHeadOnSevere;

		private static MelonPreferences_Entry<bool> _wholeLimbLossEnabled;

		private static MelonPreferences_Entry<bool> _hideLimbPartsOnSevere;

		private static MelonPreferences_Entry<bool> _fingerInjuriesEnabled;

		private static MelonPreferences_Entry<bool> _invertLimbSides;

		private static MelonPreferences_Entry<bool> _limbDamageLimpPhysics;

		private static MelonPreferences_Entry<float> _severeThreshold;

		private static MelonPreferences_Entry<float> _injuryDuration;

		private static MelonPreferences_Entry<float> _limpDuration;

		private static MelonPreferences_Entry<float> _bleedIntensity;

		private static MelonPreferences_Entry<float> _severeBleedMultiplier;

		private static MelonPreferences_Entry<float> _woundLifetime;

		private static MelonPreferences_Entry<float> _woundMarkSize;

		private static MelonPreferences_Entry<float> _brokenLimbRecoveryDelay;

		private static MelonPreferences_Entry<float> _brokenLimbRecoveryDuration;

		private static MelonPreferences_Entry<int> _limpAfterHits;

		private static MelonPreferences_Entry<int> _breakAfterHits;

		private static MelonPreferences_Entry<float> _limbBreakDamageThreshold;

		private static MelonPreferences_Entry<float> _headHideThreshold;

		private static MelonPreferences_Entry<float> _limbPartHideThreshold;

		private static MelonPreferences_Entry<float> _fingerBreakThreshold;

		private static MelonPreferences_Entry<float> _handHideThreshold;

		private static MelonPreferences_Entry<float> _wholeLimbHideThreshold;

		private static MelonPreferences_Entry<int> _maxWounds;

		private static MelonPreferences_Entry<bool> _damageVisionEffects;

		private static MelonPreferences_Entry<bool> _damageHearingEffects;

		private static MelonPreferences_Entry<float> _damageForMaxVision;

		private static MelonPreferences_Entry<float> _visionFadeSeconds;

		private static MelonPreferences_Entry<float> _vignetteStrength;

		private static MelonPreferences_Entry<float> _bloodScreenStrength;

		private static MelonPreferences_Entry<float> _earRingVolume;

		private static MelonPreferences_Entry<bool> _impactBloodEnabled;

		private static MelonPreferences_Entry<float> _impactBloodMinimumDamage;

		private static MelonPreferences_Entry<float> _impactBloodLifetime;

		private static MelonPreferences_Entry<float> _impactBloodMarkSize;

		private static MelonPreferences_Entry<float> _impactBloodRange;

		private static MelonPreferences_Entry<int> _maximumImpactBloodMarks;

		private static MelonPreferences_Entry<int> _maximumBloodBurstsPerFrame;

		private static MelonPreferences_Entry<bool> _aimAssistEnabled;

		private static MelonPreferences_Entry<float> _aimAssistStrength;

		private static MelonPreferences_Entry<float> _aimAssistCone;

		private static MelonPreferences_Entry<float> _aimAssistRange;

		private static MelonPreferences_Entry<bool> _aimAssistPlayersEnabled;

		private static MelonPreferences_Entry<float> _aimAssistPlayerStrength;

		private static MelonPreferences_Entry<float> _aimAssistPlayerCone;

		private static MelonPreferences_Entry<float> _aimAssistPlayerRange;

		private static MelonPreferences_Entry<bool> _aimAssistDotEnabled;

		private static MelonPreferences_Entry<bool> _aimAssistHeadPoint;

		private static MelonPreferences_Entry<bool> _aimAssistDistanceTextEnabled;

		private static MelonPreferences_Entry<float> _aimAssistDotRed;

		private static MelonPreferences_Entry<float> _aimAssistDotGreen;

		private static MelonPreferences_Entry<float> _aimAssistDotBlue;

		private static MelonPreferences_Entry<float> _aimAssistDotOpacity;

		private static MelonPreferences_Entry<float> _aimAssistDotSize;

		private static MelonPreferences_Entry<float> _aimAssistDotSurfaceOffset;

		private static MelonPreferences_Entry<float> _aimAssistDistanceSizeStrength;

		private static MelonPreferences_Entry<float> _aimAssistDistanceTextOffset;

		private static MelonPreferences_Entry<int> _aimAssistDotShape;

		private static MelonPreferences_Entry<int> _aimAssistDotColorPreset;

		private static MelonPreferences_Entry<int> _aimAssistDistanceTextPosition;

		private static MelonPreferences_Entry<float> _severedBleedDuration;

		private static MelonPreferences_Entry<bool> _soundEffectsEnabled;

		private static MelonPreferences_Entry<bool> _aimLockSoundEnabled;

		private static MelonPreferences_Entry<float> _impactSoundVolume;

		private static MelonPreferences_Entry<float> _aimLockSoundVolume;

		private static MelonPreferences_Entry<bool> _nightVisionEnabled;

		private static MelonPreferences_Entry<int> _nightVisionBinding;

		private static MelonPreferences_Entry<float> _nightVisionRange;

		private static MelonPreferences_Entry<float> _nightVisionPower;

		private static MelonPreferences_Entry<float> _nightVisionGreen;

		private static bool _loggedTeamUpdateFailure;

		private static bool _loggedRemoteInjuryUpdateFailure;

		private static bool _loggedNightVisionUpdateFailure;

		private static bool _loggedTraumaUpdateFailure;

		private static bool _loggedBloodUpdateFailure;

		private static bool _loggedInjuryUpdateFailure;

		private static int _lastCleanedAvatarId;

		internal static bool InjuriesEnabled => _enabled.Value && _limbInjuries.Value;

		internal static bool LimbDamageLimpPhysicsEnabled => _enabled.Value && _limbDamageLimpPhysics.Value;

		internal static bool InjuryStateTrackingEnabled => InjuriesEnabled || LimbDamageLimpPhysicsEnabled;

		internal static bool BleedingEnabled => _enabled.Value && _bloodEffects.Value;

		internal static bool WoundMarksEnabled => _enabled.Value && _woundMarks.Value;

		internal static bool RestoreAtFullHealth => _restoreAtFullHealth.Value;

		internal static bool HideHeadOnSevere => _hideHeadOnSevere.Value;

		internal static bool HideLimbPartsOnSevere => _hideLimbPartsOnSevere.Value;

		internal static bool WholeLimbLossEnabled => _enabled.Value && InjuriesEnabled && _wholeLimbLossEnabled.Value;

		internal static bool FingerInjuriesEnabled => InjuriesEnabled && _fingerInjuriesEnabled.Value;

		internal static bool InvertLimbSides => _invertLimbSides.Value;

		internal static int LimpAfterHits => Mathf.Clamp(_limpAfterHits.Value, 1, 10);

		internal static int BreakAfterHits => Mathf.Max(LimpAfterHits + 1, Mathf.Clamp(_breakAfterHits.Value, 2, 10));

		internal static float LimbBreakDamageThreshold => Mathf.Clamp(_limbBreakDamageThreshold.Value, 5f, 200f);

		internal static float LimpDuration => Mathf.Clamp(_limpDuration.Value, 1f, 60f);

		internal static float BrokenLimbRecoveryDelay => Mathf.Clamp(_brokenLimbRecoveryDelay.Value, 0f, 30f);

		internal static float BrokenLimbRecoveryDuration => Mathf.Clamp(_brokenLimbRecoveryDuration.Value, 0.25f, 10f);

		internal static float SevereThreshold => _severeThreshold.Value;

		internal static float HeadHideThreshold => Mathf.Clamp(_headHideThreshold.Value, 5f, 300f);

		internal static float LimbPartHideThreshold => Mathf.Clamp(_limbPartHideThreshold.Value, 5f, 300f);

		internal static float FingerBreakThreshold => Mathf.Clamp(_fingerBreakThreshold.Value, 1f, 100f);

		internal static float HandHideThreshold => Mathf.Clamp(_handHideThreshold.Value, 5f, 150f);

		internal static float WholeLimbHideThreshold => Mathf.Clamp(_wholeLimbHideThreshold.Value, 10f, 300f);

		internal static float InjuryDuration => _injuryDuration.Value;

		internal static float BleedIntensity => _bleedIntensity.Value;

		internal static float SevereBleedMultiplier => _severeBleedMultiplier.Value;

		internal static float WoundLifetime => _woundLifetime.Value;

		internal static float WoundMarkSize => _woundMarkSize.Value;

		internal static int MaximumBloodBurstsPerFrame => Mathf.Clamp(_maximumBloodBurstsPerFrame.Value, 1, 12);

		internal static int MaxWounds => _maxWounds.Value;

		internal static bool Enabled => _enabled.Value;

		internal static bool BodyRecoilEnabled => _enabled.Value && _bodyRecoilEnabled.Value;

		internal static float BodyRecoilImpulse => Mathf.Clamp(_bodyRecoilImpulse.Value, 0f, 3f);

		internal static bool DamageVisionEffectsEnabled => _damageVisionEffects.Value;

		internal static bool DamageHearingEffectsEnabled => _damageHearingEffects.Value;

		internal static bool SoundEffectsEnabled => _enabled.Value && _soundEffectsEnabled.Value;

		internal static float ImpactSoundVolume => Mathf.Clamp01(_impactSoundVolume.Value);

		internal static bool AimLockSoundEnabled => _enabled.Value && _aimLockSoundEnabled.Value;

		internal static float AimLockSoundVolume => Mathf.Clamp(_aimLockSoundVolume.Value, 0f, 0.8f);

		internal static bool NightVisionRequested => _nightVisionEnabled.Value;

		internal static int NightVisionBinding => Mathf.Clamp(_nightVisionBinding.Value, 0, 6);

		internal static float NightVisionRange => Mathf.Clamp(_nightVisionRange.Value, 5f, 45f);

		internal static float NightVisionPower => Mathf.Clamp(_nightVisionPower.Value, 0.2f, 5f);

		internal static float NightVisionGreen => Mathf.Clamp(_nightVisionGreen.Value, 0f, 0.25f);

		internal static bool SkeletonEspEnabled => false;

		internal static Color SkeletonEspColor => Color.green;

		internal static float DamageForMaxVision => Mathf.Max(1f, _damageForMaxVision.Value);

		internal static float VisionFadeSeconds => Mathf.Max(0.5f, _visionFadeSeconds.Value);

		internal static float VignetteStrength => Mathf.Clamp01(_vignetteStrength.Value);

		internal static float BloodScreenStrength => Mathf.Clamp01(_bloodScreenStrength.Value);

		internal static float EarRingVolume => Mathf.Clamp(_earRingVolume.Value, 0f, 0.08f);

		internal static bool ImpactBloodEnabled => _enabled.Value && _impactBloodEnabled.Value;

		internal static float ImpactBloodMinimumDamage => Mathf.Max(0f, _impactBloodMinimumDamage.Value);

		internal static float ImpactBloodLifetime => Mathf.Clamp(_impactBloodLifetime.Value, 5f, 180f);

		internal static float ImpactBloodMarkSize => Mathf.Clamp(_impactBloodMarkSize.Value, 0.01f, 0.1f);

		internal static float ImpactBloodRange => Mathf.Clamp(_impactBloodRange.Value, 0.2f, 1.5f);

		internal static int MaximumImpactBloodMarks => Mathf.Clamp(_maximumImpactBloodMarks.Value, 1, 100);

		internal static bool AimAssistEnabled => _enabled.Value && _aimAssistEnabled.Value;

		internal static float NpcAimAssistStrength => Mathf.Clamp(_aimAssistStrength.Value, 0.05f, 0.98f);

		internal static float NpcAimAssistCone => Mathf.Clamp(_aimAssistCone.Value, 1f, 60f);

		internal static float NpcAimAssistRange => Mathf.Clamp(_aimAssistRange.Value, 5f, 1000f);

		internal static bool FusionPlayerAimAssistEnabled => _enabled.Value && _aimAssistPlayersEnabled.Value;

		internal static float FusionPlayerAimAssistStrength => Mathf.Clamp(_aimAssistPlayerStrength.Value, 0f, 0.98f);

		internal static float FusionPlayerAimAssistCone => Mathf.Clamp(_aimAssistPlayerCone.Value, 0.5f, 40f);

		internal static float FusionPlayerAimAssistRange => Mathf.Clamp(_aimAssistPlayerRange.Value, 5f, 1000f);

		internal static bool AimAssistHeadPoint => _aimAssistHeadPoint.Value;

		internal static bool AimAssistDotEnabled => _aimAssistDotEnabled.Value;

		internal static Color AimAssistDotColor
		{
			get
			{
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0116: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				float num = Mathf.Clamp01(_aimAssistDotOpacity.Value);
				return (Color)(Mathf.Clamp(_aimAssistDotColorPreset.Value, 0, 6) switch
				{
					1 => new Color(1f, 0.9f, 0f, num), 
					2 => new Color(0.1f, 1f, 0.15f, num), 
					3 => new Color(1f, 0.12f, 0.08f, num), 
					4 => new Color(1f, 1f, 1f, num), 
					5 => new Color(1f, 0.1f, 1f, num), 
					6 => new Color(Mathf.Clamp01(_aimAssistDotRed.Value), Mathf.Clamp01(_aimAssistDotGreen.Value), Mathf.Clamp01(_aimAssistDotBlue.Value), num), 
					_ => new Color(0f, 1f, 1f, num), 
				});
			}
		}

		internal static int AimAssistDotShape => Mathf.Clamp(_aimAssistDotShape.Value, 0, 11);

		internal static float AimAssistDotSize => Mathf.Clamp(_aimAssistDotSize.Value, 0.25f, 3f);

		internal static float AimAssistDotSurfaceOffset => Mathf.Clamp(_aimAssistDotSurfaceOffset.Value, 0.1f, 1.5f);

		internal static bool AimAssistDistanceTextEnabled => _aimAssistDistanceTextEnabled.Value;

		internal static int AimAssistDistanceTextPosition => Mathf.Clamp(_aimAssistDistanceTextPosition.Value, 0, 3);

		internal static float AimAssistDistanceTextOffset => Mathf.Clamp(_aimAssistDistanceTextOffset.Value, 0.5f, 5f);

		internal static float AimAssistDistanceSizeStrength => Mathf.Clamp01(_aimAssistDistanceSizeStrength.Value);

		internal static float SeveredBleedDuration => Mathf.Clamp(_severedBleedDuration.Value, 1f, 30f);

		public override void OnInitializeMelon()
		{
			//IL_093c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0941: Unknown result type (might be due to invalid IL or missing references)
			//IL_0947: Expected O, but got Unknown
			//IL_095d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0962: Unknown result type (might be due to invalid IL or missing references)
			//IL_0968: Expected O, but got Unknown
			//IL_09c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_09cf: Expected O, but got Unknown
			//IL_09e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f0: Expected O, but got Unknown
			//IL_0a06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a11: Expected O, but got Unknown
			//IL_0a27: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a2c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a32: Expected O, but got Unknown
			//IL_0a48: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a4d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a53: Expected O, but got Unknown
			_prefs = MelonPreferences.CreateCategory("RealismLab", "Realismlab");
			_enabled = _prefs.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_bodyRecoilEnabled = _prefs.CreateEntry<bool>("BodyRecoilEnabledV1", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_bodyRecoilImpulse = _prefs.CreateEntry<float>("BodyRecoilImpulseV1", 0.8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_damageVisionEffects = _prefs.CreateEntry<bool>("DamageVisionEffects", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_damageHearingEffects = _prefs.CreateEntry<bool>("DamageHearingEffectsV2", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_damageForMaxVision = _prefs.CreateEntry<float>("DamageForMaximumVisionEffects", 80f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_visionFadeSeconds = _prefs.CreateEntry<float>("VisionFadeSecondsAfterFullHealth", 8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_vignetteStrength = _prefs.CreateEntry<float>("DamageVignetteStrength", 0.75f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_bloodScreenStrength = _prefs.CreateEntry<float>("BloodScreenStrength", 0.8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_earRingVolume = _prefs.CreateEntry<float>("EarRingVolume", 0.025f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_impactBloodEnabled = _prefs.CreateEntry<bool>("BloodOnHandsAndWeapons", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_impactBloodMinimumDamage = _prefs.CreateEntry<float>("ImpactBloodMinimumDamage", 2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_impactBloodLifetime = _prefs.CreateEntry<float>("ImpactBloodMarkLifetime", 45f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_impactBloodMarkSize = _prefs.CreateEntry<float>("ImpactBloodMarkSize", 0.035f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_impactBloodRange = _prefs.CreateEntry<float>("ImpactBloodHeldItemRange", 0.85f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_maximumImpactBloodMarks = _prefs.CreateEntry<int>("MaximumImpactBloodMarks", 48, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_limbInjuries = _prefs.CreateEntry<bool>("LocalizedLimbInjuriesV4", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_bloodEffects = _prefs.CreateEntry<bool>("BleedingEffects", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_woundMarks = _prefs.CreateEntry<bool>("WoundMarks", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_restoreAtFullHealth = _prefs.CreateEntry<bool>("RestoreInjuriesAtFullHealth", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_hideHeadOnSevere = _prefs.CreateEntry<bool>("HideHeadOnSevereHit", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_hideLimbPartsOnSevere = _prefs.CreateEntry<bool>("HideLimbPartOnSevereHit", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_fingerInjuriesEnabled = _prefs.CreateEntry<bool>("FingerInjuryVisualsV1", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_invertLimbSides = _prefs.CreateEntry<bool>("InvertLeftRightLimbHitsV2", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_limpAfterHits = _prefs.CreateEntry<int>("LimbWeakAfterHitsV1", 1, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_breakAfterHits = _prefs.CreateEntry<int>("LimbBreakAfterHitsV1", 2, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_limbBreakDamageThreshold = _prefs.CreateEntry<float>("LimbBreakDamageThresholdV1", 24f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_limpDuration = _prefs.CreateEntry<float>("LimbWeakDurationSecondsV1", 12f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_limbDamageLimpPhysics = _prefs.CreateEntry<bool>("LocalizedLimbDamagePhysicsV2", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_brokenLimbRecoveryDelay = _prefs.CreateEntry<float>("BrokenLimbRecoveryDelayV2", 10f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_brokenLimbRecoveryDuration = _prefs.CreateEntry<float>("BrokenLimbRecoveryBlendSecondsV1", 2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_severeThreshold = _prefs.CreateEntry<float>("CatastrophicDamageThreshold", 70f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_injuryDuration = _prefs.CreateEntry<float>("InjuryDurationSeconds", 10f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_bleedIntensity = _prefs.CreateEntry<float>("BleedingIntensity", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_severeBleedMultiplier = _prefs.CreateEntry<float>("CatastrophicBleedMultiplier", 2.5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_woundLifetime = _prefs.CreateEntry<float>("WoundLifetimeSeconds", 12f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_woundMarkSize = _prefs.CreateEntry<float>("WoundMarkSize", 0.018f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_headHideThreshold = _prefs.CreateEntry<float>("HeadHideDamageThresholdV3", 75f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_limbPartHideThreshold = _prefs.CreateEntry<float>("LimbPartHideDamageThresholdV5", 35f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_fingerBreakThreshold = _prefs.CreateEntry<float>("FingerBreakDamageThresholdV2", 10f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_handHideThreshold = _prefs.CreateEntry<float>("HandHideDamageThresholdV2", 28f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_wholeLimbHideThreshold = _prefs.CreateEntry<float>("WholeLimbHideDamageThresholdV3", 65f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_wholeLimbLossEnabled = _prefs.CreateEntry<bool>("WholeLimbLossEnabledV1", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_maxWounds = _prefs.CreateEntry<int>("MaximumWoundMarks", 20, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_maximumBloodBurstsPerFrame = _prefs.CreateEntry<int>("MaximumBloodBurstsPerFrame", 6, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistEnabled = _prefs.CreateEntry<bool>("NpcAimAssistEnabled", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistStrength = _prefs.CreateEntry<float>("NpcAimAssistStrengthV4", 0.92f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistCone = _prefs.CreateEntry<float>("NpcAimAssistConeDegreesV4", 26f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistRange = _prefs.CreateEntry<float>("NpcAimAssistRangeMetersV5", 500f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistPlayersEnabled = _prefs.CreateEntry<bool>("FusionPlayerAimAssistEnabledV1", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistPlayerStrength = _prefs.CreateEntry<float>("FusionPlayerAimAssistStrengthV5", 0.92f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistPlayerCone = _prefs.CreateEntry<float>("FusionPlayerAimAssistConeV4", 15f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistPlayerRange = _prefs.CreateEntry<float>("FusionPlayerAimAssistRangeV5", 450f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistHeadPoint = _prefs.CreateEntry<bool>("AimAssistHeadPointV1", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotEnabled = _prefs.CreateEntry<bool>("AimAssistDotEnabledV2", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDistanceTextEnabled = _prefs.CreateEntry<bool>("AimAssistDistanceTextEnabledV1", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDistanceTextPosition = _prefs.CreateEntry<int>("AimAssistDistanceTextPositionV1", 1, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDistanceSizeStrength = _prefs.CreateEntry<float>("AimAssistDistanceSizeStrengthV1", 0.5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotRed = _prefs.CreateEntry<float>("AimAssistDotRedV1", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotGreen = _prefs.CreateEntry<float>("AimAssistDotGreenV1", 0.85f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotBlue = _prefs.CreateEntry<float>("AimAssistDotBlueV1", 0.05f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotOpacity = _prefs.CreateEntry<float>("AimAssistDotOpacityV1", 0.9f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotSize = _prefs.CreateEntry<float>("AimAssistDotSizeV1", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotShape = _prefs.CreateEntry<int>("AimAssistDotShapeV1", 0, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotColorPreset = _prefs.CreateEntry<int>("AimAssistDotColorPresetV2", 0, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDotSurfaceOffset = _prefs.CreateEntry<float>("AimAssistDotSurfaceOffsetV2", 0.35f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimAssistDistanceTextOffset = _prefs.CreateEntry<float>("AimAssistDistanceTextOffsetV1", 2.2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_severedBleedDuration = _prefs.CreateEntry<float>("SeveredLimbViolentBleedSecondsV1", 10f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_soundEffectsEnabled = _prefs.CreateEntry<bool>("NetworkedInjurySoundsV1", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_impactSoundVolume = _prefs.CreateEntry<float>("InjurySoundVolumeV2", 0.9f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimLockSoundEnabled = _prefs.CreateEntry<bool>("AimLockSoundEnabledV1", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_aimLockSoundVolume = _prefs.CreateEntry<float>("AimLockSoundVolumeV2", 0.36f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_nightVisionEnabled = _prefs.CreateEntry<bool>("NightVisionEnabledV1", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_nightVisionBinding = _prefs.CreateEntry<int>("NightVisionControllerBindingV1", 2, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_nightVisionRange = _prefs.CreateEntry<float>("NightVisionLightRangeV1", 18f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_nightVisionPower = _prefs.CreateEntry<float>("NightVisionLightPowerV1", 2.2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_nightVisionGreen = _prefs.CreateEntry<float>("NightVisionGreenOverlayV1", 0.07f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Hooking.OnPlayerDamageReceived += OnPlayerDamage;
			Hooking.OnPlayerResurrected += OnPlayerResurrected;
			object obj = <>O.<2>__ClearKillTracking;
			if (obj == null)
			{
				Action val = BloodTransfer.ClearKillTracking;
				<>O.<2>__ClearKillTracking = val;
				obj = (object)val;
			}
			Hooking.OnLevelUnloaded += (Action)obj;
			object obj2 = <>O.<3>__ClearKillTracking;
			if (obj2 == null)
			{
				Action val2 = DamageHooks.ClearKillTracking;
				<>O.<3>__ClearKillTracking = val2;
				obj2 = (object)val2;
			}
			Hooking.OnLevelUnloaded += (Action)obj2;
			Hooking.OnPostFireGun += BodyRecoil.OnPostFireGun;
			Hooking.OnSwitchAvatarPostfix += delegate
			{
				DamageHooks.ResetInjuries();
			};
			object obj3 = <>O.<5>__Clear;
			if (obj3 == null)
			{
				Action val3 = AudioFeedback.Clear;
				<>O.<5>__Clear = val3;
				obj3 = (object)val3;
			}
			Hooking.OnLevelUnloaded += (Action)obj3;
			object obj4 = <>O.<6>__Clear;
			if (obj4 == null)
			{
				Action val4 = TeamIndicator.Clear;
				<>O.<6>__Clear = val4;
				obj4 = (object)val4;
			}
			Hooking.OnLevelUnloaded += (Action)obj4;
			object obj5 = <>O.<7>__Clear;
			if (obj5 == null)
			{
				Action val5 = NightVision.Clear;
				<>O.<7>__Clear = val5;
				obj5 = (object)val5;
			}
			Hooking.OnLevelUnloaded += (Action)obj5;
			object obj6 = <>O.<8>__Clear;
			if (obj6 == null)
			{
				Action val6 = TraumaEffects.Clear;
				<>O.<8>__Clear = val6;
				obj6 = (object)val6;
			}
			Hooking.OnLevelUnloaded += (Action)obj6;
			object obj7 = <>O.<9>__ResetInjuries;
			if (obj7 == null)
			{
				Action val7 = DamageHooks.ResetInjuries;
				<>O.<9>__ResetInjuries = val7;
				obj7 = (object)val7;
			}
			Hooking.OnLevelUnloaded += (Action)obj7;
			try
			{
				FusionLimbSync.Install();
			}
			catch (System.Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Fusion limb-state sync could not be registered: " + ex.Message);
			}
			try
			{
				DamageHooks.Install();
			}
			catch (System.Exception ex2)
			{
				((MelonBase)this).LoggerInstance.Error("Localized injury hook could not be installed: " + ex2.Message);
			}
			try
			{
				BloodTransfer.Install();
			}
			catch (System.Exception ex3)
			{
				((MelonBase)this).LoggerInstance.Error("Impact blood transfer hooks could not be installed: " + ex3.Message);
			}
			SetupMenu();
			((MelonBase)this).LoggerInstance.Msg("Loaded. BoneLib is required for BoneMenu and player hooks.");
		}

		private static void SetupMenu()
		{
			//IL_000b: 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)
			//IL_0054: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0725: Unknown result type (might be due to invalid IL or missing references)
			//IL_075f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0799: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_080d: Unknown result type (might be due to invalid IL or missing references)
			//IL_084b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0889: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_091b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0964: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a3f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a88: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ad1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b1a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b63: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bf5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c33: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c7c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cc5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d0e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d57: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d95: Unknown result type (might be due to invalid IL or missing references)
			//IL_0da8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0de2: Unknown result type (might be due to invalid IL or missing references)
			Page val = Page.Root.CreatePage("RealismLab", Color.cyan, 0, true);
			val.CreateBool("Enabled", Color.white, _enabled.Value, (Action<bool>)SetEnabled);
			Page val2 = val.CreatePage("Body recoil", Color.yellow, 0, true);
			val2.CreateBool("Apply recoil to body (off by default)", Color.white, _bodyRecoilEnabled.Value, (Action<bool>)delegate(bool v)
			{
				Set(_bodyRecoilEnabled, v);
			});
			val2.CreateFloat("Body recoil impulse per shot (N·s)", Color.white, _bodyRecoilImpulse.Value, 0.1f, 0f, 3f, (Action<float>)delegate(float v)
			{
				Set(_bodyRecoilImpulse, v);
			});
			val.CreateBool("Damage vision effects", Color.white, _damageVisionEffects.Value, (Action<bool>)delegate(bool v)
			{
				Set(_damageVisionEffects, v);
			});
			val.CreateBool("Local tinnitus effect (no volume reduction)", Color.white, _damageHearingEffects.Value, (Action<bool>)delegate(bool v)
			{
				Set(_damageHearingEffects, v);
			});
			val.CreateFloat("Damage for maximum screen effects", Color.white, _damageForMaxVision.Value, 1f, 10f, 250f, (Action<float>)delegate(float v)
			{
				Set(_damageForMaxVision, v);
			});
			val.CreateFloat("Screen effect fade time (seconds)", Color.white, _visionFadeSeconds.Value, 0.5f, 1f, 30f, (Action<float>)delegate(float v)
			{
				Set(_visionFadeSeconds, v);
			});
			val.CreateFloat("Damage vignette strength", Color.white, _vignetteStrength.Value, 0.05f, 0f, 1f, (Action<float>)delegate(float v)
			{
				Set(_vignetteStrength, v);
				TraumaEffects.MarkTextureDirty();
			});
			val.CreateFloat("Blood on screen strength", Color.white, _bloodScreenStrength.Value, 0.05f, 0f, 1f, (Action<float>)delegate(float v)
			{
				Set(_bloodScreenStrength, v);
				TraumaEffects.MarkTextureDirty();
			});
			val.CreateFloat("Ear ringing volume", Color.white, _earRingVolume.Value, 0.002f, 0f, 0.08f, (Action<float>)delegate(float v)
			{
				Set(_earRingVolume, v);
			});
			Page val3 = val.CreatePage("Night vision", Color.green, 0, true);
			val3.CreateBool("Enable night vision", Color.white, _nightVisionEnabled.Value, (Action<bool>)SetNightVisionEnabled);
			val3.CreateInt("Controller toggle (0 off; 1-3 left stick/primary/secondary; 4-6 right stick/primary/secondary; 7-8 left grip/trigger; 9-10 right grip/trigger; 11-12 left/right menu)", Color.white, _nightVisionBinding.Value, 1, 0, 12, (Action<int>)delegate(int v)
			{
				Set(_nightVisionBinding, v);
			});
			val3.CreateFloat("Illumination range (meters)", Color.white, _nightVisionRange.Value, 1f, 5f, 45f, (Action<float>)delegate(float v)
			{
				Set(_nightVisionRange, v);
			});
			val3.CreateFloat("Green light power", Color.white, _nightVisionPower.Value, 0.1f, 0.2f, 5f, (Action<float>)delegate(float v)
			{
				Set(_nightVisionPower, v);
			});
			val3.CreateFloat("Green lens tint", Color.white, _nightVisionGreen.Value, 0.01f, 0f, 0.25f, (Action<float>)delegate(float v)
			{
				Set(_nightVisionGreen, v);
			});
			val.CreateBool("Blood on punching hands and held items", Color.white, _impactBloodEnabled.Value, (Action<bool>)delegate(bool v)
			{
				Set(_impactBloodEnabled, v);
			});
			val.CreateFloat("Minimum damage for item blood", Color.white, _impactBloodMinimumDamage.Value, 0.5f, 0f, 30f, (Action<float>)delegate(float v)
			{
				Set(_impactBloodMinimumDamage, v);
			});
			val.CreateFloat("Impact blood mark lifetime (seconds)", Color.white, _impactBloodLifetime.Value, 1f, 5f, 180f, (Action<float>)delegate(float v)
			{
				Set(_impactBloodLifetime, v);
			});
			val.CreateFloat("Impact blood mark size", Color.white, _impactBloodMarkSize.Value, 0.002f, 0.01f, 0.1f, (Action<float>)delegate(float v)
			{
				Set(_impactBloodMarkSize, v);
			});
			val.CreateFloat("Held item blood transfer range", Color.white, _impactBloodRange.Value, 0.05f, 0.2f, 1.5f, (Action<float>)delegate(float v)
			{
				Set(_impactBloodRange, v);
			});
			val.CreateInt("Maximum impact blood marks", Color.white, _maximumImpactBloodMarks.Value, 1, 1, 100, (Action<int>)delegate(int v)
			{
				Set(_maximumImpactBloodMarks, v);
			});
			val.CreateBool("Limb limp/break physics after damage (hit limb only)", Color.white, _limbDamageLimpPhysics.Value, (Action<bool>)delegate(bool v)
			{
				Set(_limbDamageLimpPhysics, v);
				if (!v)
				{
					DamageHooks.ResetInjuries();
				}
			});
			val.CreateBool("Localized injury visuals", Color.white, _limbInjuries.Value, (Action<bool>)delegate(bool v)
			{
				Set(_limbInjuries, v);
				if (!v)
				{
					DamageHooks.ResetInjuries();
				}
			});
			val.CreateBool("Bleeding effects", Color.white, _bloodEffects.Value, (Action<bool>)delegate(bool v)
			{
				Set(_bloodEffects, v);
			});
			val.CreateBool("Visible wound marks", Color.white, _woundMarks.Value, (Action<bool>)delegate(bool v)
			{
				Set(_woundMarks, v);
			});
			val.CreateBool("Restore at full health", Color.white, _restoreAtFullHealth.Value, (Action<bool>)delegate(bool v)
			{
				Set(_restoreAtFullHealth, v);
			});
			val.CreateBool("Hide head after severe hit", Color.white, _hideHeadOnSevere.Value, (Action<bool>)delegate(bool v)
			{
				Set(_hideHeadOnSevere, v);
			});
			val.CreateBool("Hide damaged limb section", Color.white, _hideLimbPartsOnSevere.Value, (Action<bool>)delegate(bool v)
			{
				Set(_hideLimbPartsOnSevere, v);
				if (!v)
				{
					DamageHooks.RestoreAllParts();
				}
			});
			val.CreateBool("Allow whole arm, leg, head, and core loss", Color.white, _wholeLimbLossEnabled.Value, (Action<bool>)delegate(bool v)
			{
				Set(_wholeLimbLossEnabled, v);
			});
			val.CreateBool("Finger injury visuals", Color.white, _fingerInjuriesEnabled.Value, (Action<bool>)delegate(bool v)
			{
				Set(_fingerInjuriesEnabled, v);
				if (!v)
				{
					DamageHooks.RestoreDigitInjuries();
				}
			});
			val.CreateBool("Invert left/right hit-side mapping", Color.white, _invertLimbSides.Value, (Action<bool>)delegate(bool v)
			{
				Set(_invertLimbSides, v);
				DamageHooks.ResetInjuries();
			});
			val.CreateInt("Hits to weaken a limb", Color.white, _limpAfterHits.Value, 1, 1, 10, (Action<int>)delegate(int v)
			{
				Set(_limpAfterHits, v);
			});
			val.CreateInt("Hits to break a limb", Color.white, _breakAfterHits.Value, 1, 2, 10, (Action<int>)delegate(int v)
			{
				Set(_breakAfterHits, v);
			});
			val.CreateFloat("Accumulated damage to break a limb", Color.white, _limbBreakDamageThreshold.Value, 1f, 5f, 200f, (Action<float>)delegate(float v)
			{
				Set(_limbBreakDamageThreshold, v);
			});
			val.CreateFloat("Weak limb duration (seconds)", Color.white, _limpDuration.Value, 0.5f, 1f, 60f, (Action<float>)delegate(float v)
			{
				Set(_limpDuration, v);
			});
			val.CreateFloat("Broken limb hold before recovery (seconds)", Color.white, _brokenLimbRecoveryDelay.Value, 0.5f, 0f, 30f, (Action<float>)delegate(float v)
			{
				Set(_brokenLimbRecoveryDelay, v);
			});
			val.CreateFloat("Broken limb recovery blend (seconds)", Color.white, _brokenLimbRecoveryDuration.Value, 0.25f, 0.25f, 10f, (Action<float>)delegate(float v)
			{
				Set(_brokenLimbRecoveryDuration, v);
			});
			val.CreateFloat("Damage for catastrophic injury", Color.white, _severeThreshold.Value, 1f, 10f, 300f, (Action<float>)delegate(float v)
			{
				Set(_severeThreshold, v);
			});
			val.CreateFloat("Head damage to hide head", Color.white, _headHideThreshold.Value, 1f, 10f, 300f, (Action<float>)delegate(float v)
			{
				Set(_headHideThreshold, v);
			});
			val.CreateFloat("Damage to remove a limb section", Color.white, _limbPartHideThreshold.Value, 1f, 10f, 300f, (Action<float>)delegate(float v)
			{
				Set(_limbPartHideThreshold, v);
			});
			val.CreateFloat("Accumulated hand damage to hide hand", Color.white, _handHideThreshold.Value, 1f, 5f, 150f, (Action<float>)delegate(float v)
			{
				Set(_handHideThreshold, v);
			});
			val.CreateFloat("Accumulated finger damage to hide finger", Color.white, _fingerBreakThreshold.Value, 1f, 1f, 100f, (Action<float>)delegate(float v)
			{
				Set(_fingerBreakThreshold, v);
			});
			val.CreateFloat("Damage to remove whole arm, leg, or torso section", Color.white, _wholeLimbHideThreshold.Value, 1f, 10f, 300f, (Action<float>)delegate(float v)
			{
				Set(_wholeLimbHideThreshold, v);
			});
			val.CreateFloat("Injury timer (seconds)", Color.white, _injuryDuration.Value, 1f, 1f, 60f, (Action<float>)delegate(float v)
			{
				Set(_injuryDuration, v);
			});
			val.CreateFloat("Bleeding intensity", Color.white, _bleedIntensity.Value, 0.1f, 0.1f, 3f, (Action<float>)delegate(float v)
			{
				Set(_bleedIntensity, v);
			});
			val.CreateInt("Blood particle burst budget", Color.white, _maximumBloodBurstsPerFrame.Value, 1, 1, 12, (Action<int>)delegate(int v)
			{
				Set(_maximumBloodBurstsPerFrame, v);
			});
			val.CreateFloat("Catastrophic bleed multiplier", Color.white, _severeBleedMultiplier.Value, 0.1f, 1f, 5f, (Action<float>)delegate(float v)
			{
				Set(_severeBleedMultiplier, v);
			});
			val.CreateFloat("Violent stump bleed duration (seconds)", Color.white, _severedBleedDuration.Value, 1f, 1f, 30f, (Action<float>)delegate(float v)
			{
				Set(_severedBleedDuration, v);
			});
			val.CreateFloat("Wound lifetime (seconds)", Color.white, _woundLifetime.Value, 1f, 1f, 60f, (Action<float>)delegate(float v)
			{
				Set(_woundLifetime, v);
			});
			val.CreateFloat("Wound mark size", Color.white, _woundMarkSize.Value, 0.002f, 0.005f, 0.06f, (Action<float>)delegate(float v)
			{
				Set(_woundMarkSize, v);
			});
			val.CreateInt("Maximum visible wounds", Color.white, _maxWounds.Value, 1, 1, 50, (Action<int>)delegate(int v)
			{
				Set(_maxWounds, v);
			});
			Page val4 = val.CreatePage("Sound effects", Color.yellow, 0, true);
			val4.CreateBool("Play impact and limb injury sounds", Color.white, _soundEffectsEnabled.Value, (Action<bool>)delegate(bool v)
			{
				Set(_soundEffectsEnabled, v);
			});
			val4.CreateFloat("Impact sound volume", Color.white, _impactSoundVolume.Value, 0.05f, 0f, 1f, (Action<float>)delegate(float v)
			{
				Set(_impactSoundVolume, v);
			});
		}

		private static void Set<T>(MelonPreferences_Entry<T> entry, T value)
		{
			entry.Value = value;
			_prefs.SaveToFile(false);
		}

		private static void SetEnabled(bool value)
		{
			Set(_enabled, value);
			if (!value)
			{
				TraumaEffects.Clear();
				AudioFeedback.Clear();
				BloodTransfer.Clear();
				DamageHooks.ResetInjuries();
			}
		}

		internal static void SetNightVisionEnabled(bool value)
		{
			Set(_nightVisionEnabled, value);
		}

		public override void OnUpdate()
		{
			try
			{
				TeamIndicator.Tick();
			}
			catch (System.Exception error)
			{
				LogUpdateFailure(ref _loggedTeamUpdateFailure, "teammate indicators", error);
			}
			try
			{
				DamageHooks.TickRemoteInjuries();
			}
			catch (System.Exception error2)
			{
				LogUpdateFailure(ref _loggedRemoteInjuryUpdateFailure, "remote injury visuals", error2);
			}
			RigManager rigManager = Player.RigManager;
			try
			{
				NightVision.Tick(Player.Head, _enabled.Value);
			}
			catch (System.Exception error3)
			{
				LogUpdateFailure(ref _loggedNightVisionUpdateFailure, "night vision", error3);
			}
			try
			{
				ClearStaleInjuriesAfterAvatarLoad(rigManager);
			}
			catch (System.Exception ex)
			{
				MelonLogger.Warning("Avatar injury cleanup skipped safely: " + ex.Message);
			}
			if (!_enabled.Value)
			{
				TraumaEffects.Clear();
				BloodTransfer.Clear();
				return;
			}
			try
			{
				TraumaEffects.Update(((Object)(object)rigManager != (Object)null) ? rigManager.health : null, Player.Head);
			}
			catch (System.Exception error4)
			{
				LogUpdateFailure(ref _loggedTraumaUpdateFailure, "damage screen effects", error4);
			}
			try
			{
				BloodTransfer.Tick();
			}
			catch (System.Exception error5)
			{
				LogUpdateFailure(ref _loggedBloodUpdateFailure, "impact blood", error5);
			}
			if (!((Object)(object)rigManager != (Object)null))
			{
				return;
			}
			try
			{
				DamageHooks.Tick(rigManager.health);
			}
			catch (System.Exception error6)
			{
				LogUpdateFailure(ref _loggedInjuryUpdateFailure, "injury recovery", error6);
			}
		}

		private static void LogUpdateFailure(ref bool alreadyLogged, string subsystem, System.Exception error)
		{
			if (!alreadyLogged)
			{
				MelonLogger.Warning("Realismlab isolated an update error in " + subsystem + ": " + error.Message);
				alreadyLogged = true;
			}
		}

		private static void OnPlayerDamage(RigManager rig, float damage)
		{
			if (_enabled.Value && !((Object)(object)rig == (Object)null) && !((Object)(object)rig != (Object)(object)Player.RigManager) && !(damage <= 0f))
			{
				TraumaEffects.RegisterDamage(damage);
			}
		}

		private static void OnPlayerResurrected(RigManager rig)
		{
			if ((Object)(object)rig != (Object)null && (Object)(object)rig == (Object)(object)Player.RigManager)
			{
				DamageHooks.ResetInjuries();
			}
		}

		private static void ClearStaleInjuriesAfterAvatarLoad(RigManager rig)
		{
			if ((Object)(object)rig == (Object)null || (Object)(object)rig.avatar == (Object)null || (Object)(object)rig.health == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)rig.avatar).GetInstanceID();
			if (instanceID == 0 || instanceID == _lastCleanedAvatarId)
			{
				return;
			}
			_lastCleanedAvatarId = instanceID;
			try
			{
				DamageHooks.ResetInjuries();
			}
			catch (System.Exception ex)
			{
				MelonLogger.Warning("Could not clear stale limb weakness after avatar load: " + ex.Message);
			}
		}
	}
	internal static class NightVision
	{
		private static float _fade;

		private static bool _lastButton;

		private static int _lastBinding = -1;

		private static GameObject _lightObject;

		private static Light _light;

		private static GameObject _overlayObject;

		private static Canvas _canvas;

		private static RawImage _tint;

		private static Text _status;

		public static void Tick(Transform head, bool modEnabled)
		{
			PollControllerBinding(modEnabled);
			float num = ((modEnabled && RealismlabMod.NightVisionRequested) ? 1f : 0f);
			_fade = Mathf.MoveTowards(_fade, num, Mathf.Clamp(Time.unscaledDeltaTime, 0f, 0.1f) * 3.5f);
			UpdateLight(head);
			UpdateOverlay();
		}

		private static void PollControllerBinding(bool modEnabled)
		{
			int nightVisionBinding = RealismlabMod.NightVisionBinding;
			if (nightVisionBinding != _lastBinding)
			{
				_lastBinding = nightVisionBinding;
				_lastButton = false;
			}
			if (!modEnabled || nightVisionBinding == 0 || !ReadBinding(nightVisionBinding, out var pressed))
			{
				_lastButton = false;
				return;
			}
			if (pressed && !_lastButton)
			{
				RealismlabMod.SetNightVisionEnabled(!RealismlabMod.NightVisionRequested);
			}
			_lastButton = pressed;
		}

		private static bool ReadBinding(int binding, out bool pressed)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			pressed = false;
			try
			{
				XRNode val = (XRNode)((binding <= 3 || binding == 7 || binding == 8 || binding == 11) ? 4 : 5);
				InputDevice deviceAtXRNode = InputDevices.GetDeviceAtXRNode(val);
				if (!((InputDevice)(ref deviceAtXRNode)).isValid)
				{
					return false;
				}
				switch (binding)
				{
				case 1:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.primary2DAxisClick, ref pressed);
				case 2:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.primaryButton, ref pressed);
				case 3:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.secondaryButton, ref pressed);
				case 4:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.primary2DAxisClick, ref pressed);
				case 5:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.primaryButton, ref pressed);
				case 6:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.secondaryButton, ref pressed);
				case 7:
				case 9:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.gripButton, ref pressed);
				case 8:
				case 10:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.triggerButton, ref pressed);
				case 11:
				case 12:
					return ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.menuButton, ref pressed);
				default:
					return false;
				}
			}
			catch
			{
				return false;
			}
		}

		private static void UpdateLight(Transform head)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)head == (Object)null || _fade <= 0.001f)
			{
				if ((Object)(object)_light != (Object)null)
				{
					_light.intensity = 0f;
				}
				return;
			}
			if ((Object)(object)_lightObject == (Object)null || (Object)(object)_light == (Object)null)
			{
				_lightObject = new GameObject("RealismLab_NightVisionLight");
				_light = _lightObject.AddComponent<Light>();
				_light.type = (LightType)0;
				_light.spotAngle = 105f;
				_light.innerSpotAngle = 75f;
				_light.color = new Color(0.2f, 1f, 0.38f, 1f);
				_light.shadows = (LightShadows)0;
				_light.renderMode = (LightRenderMode)1;
			}
			if ((Object)(object)_lightObject.transform.parent != (Object)(object)head)
			{
				_lightObject.transform.SetParent(head, false);
				_lightObject.transform.localPosition = new Vector3(0f, 0.035f, 0.05f);
				_lightObject.transform.localRotation = Quaternion.identity;
			}
			_light.range = RealismlabMod.NightVisionRange;
			_light.intensity = RealismlabMod.NightVisionPower * _fade;
			((Behaviour)_light).enabled = true;
		}

		private static void UpdateOverlay()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (_fade <= 0.001f)
			{
				if ((Object)(object)_tint != (Object)null)
				{
					((Graphic)_tint).color = Color.clear;
				}
				if ((Object)(object)_status != (Object)null)
				{
					((Graphic)_status).color = Color.clear;
				}
				return;
			}
			EnsureOverlay();
			if ((Object)(object)_tint != (Object)null)
			{
				((Graphic)_tint).color = new Color(0.05f, 0.8f, 0.18f, RealismlabMod.NightVisionGreen * _fade);
			}
			if ((Object)(object)_status != (Object)null)
			{
				float num = 0.72f + 0.18f * Mathf.Sin(Time.unscaledTime * 2.4f);
				((Graphic)_status).color = new Color(0.35f, 1f, 0.48f, _fade * num);
			}
		}

		private static void EnsureOverlay()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_overlayObject != (Object)null && (Object)(object)_tint != (Object)null)
			{
				return;
			}
			try
			{
				_overlayObject = new GameObject("RealismLab_NightVisionOverlay");
				_canvas = _overlayObject.AddComponent<Canvas>();
				_canvas.renderMode = (RenderMode)0;
				_canvas.sortingOrder = 32750;
				GameObject val = new GameObject("GreenNightVisionTint");
				val.transform.SetParent(_overlayObject.transform, false);
				_tint = val.AddComponent<RawImage>();
				_tint.texture = (Texture)(object)Texture2D.whiteTexture;
				((Graphic)_tint).raycastTarget = false;
				((Graphic)_tint).color = Color.clear;
				RectTransform rectTransform = ((Graphic)_tint).rectTransform;
				rectTransform.anchorMin = Vector2.zero;
				rectTransform.anchorMax = Vector2.one;
				rectTransform.offsetMin = Vector2.zero;
				rectTransform.offsetMax = Vector2.zero;
				GameObject val2 = new GameObject("NightVisionStatus");
				val2.transform.SetParent(_overlayObject.transform, false);
				_status = val2.AddComponent<Text>();
				_status.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
				if ((Object)(object)_status.font == (Object)null)
				{
					_status.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
				}
				_status.fontSize = 22;
				_status.fontStyle = (FontStyle)1;
				_status.alignment = (TextAnchor)2;
				_status.text = "NIGHT VISION";
				((Graphic)_status).raycastTarget = false;
				((Graphic)_status).color = Color.clear;
				RectTransform rectTransform2 = ((Graphic)_status).rectTransform;
				rectTransform2.anchorMin = new Vector2(1f, 1f);
				rectTransform2.anchorMax = new Vector2(1f, 1f);
				rectTransform2.pivot = new Vector2(1f, 1f);
				rectTransform2.anchoredPosition = new Vector2(-42f, -32f);
				rectTransform2.sizeDelta = new Vector2(260f, 34f);
			}
			catch (System.Exception ex)
			{
				MelonLogger.Warning("Night-vision overlay could not be created: " + ex.Message);
				Clear();
			}
		}

		public static void Clear()
		{
			_fade = 0f;
			_lastButton = false;
			_lastBinding = -1;
			if ((Object)(object)_lightObject != (Object)null)
			{
				Object.Destroy((Object)(object)_lightObject);
			}
			if ((Object)(object)_overlayObject != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayObject);
			}
			_lightObject = null;
			_light = null;
			_overlayObject = null;
			_canvas = null;
			_tint = null;
			_status = null;
		}
	}
	internal static class AimAssist
	{
		private sealed class AimTarget
		{
			public Collider Collider;

			public Transform OwnerRoot;

			public ulong RemotePlatformId;

			public Transform HeadBone;

			public Transform ChestBone;

			public Animator Animator;

			public AIBrain Brain;

			public RigManager RemoteRig;
		}

		private sealed class SkeletonSegment
		{
			public LineRenderer Line;

			public LineRenderer Outline;

			public Transform A;

			public Transform B;

			public float NextVisibilityCheck;

			public bool Visible;
		}

		private sealed class SkeletonVisual
		{
			public Transform OwnerRoot;

			public int AnimatorId;

			public GameObject Container;

			public readonly List<SkeletonSegment> Segments = new List<SkeletonSegment>();
		}

		private sealed class AimState
		{
			public Gun Gun;

			public Transform Muzzle;

			public Quaternion OriginalRotation;
		}

		private sealed class TargetMotion
		{
			public Vector3 LastPosition;

			public Vector3 Velocity;

			public float LastSampleTime;

			public int LastSampleFrame;
		}

		private static readonly Harmony Harmony = new Harmony("Realismlab.AimAssist");

		private static readonly List<AimTarget> Targets = new List<AimTarget>();

		private static readonly HashSet<int> SeenColliders = new HashSet<int>();

		private static readonly Dictionary<int, RigManager> FusionColliderOwners = new Dictionary<int, RigManager>();

		private static readonly Dictionary<int, AIBrain> NpcColliderOwners = new Dictionary<int, AIBrain>();

		private static readonly Dictionary<int, TargetMotion> TargetMotions = new Dictionary<int, TargetMotion>();

		private static readonly Dictionary<int, SkeletonVisual> SkeletonVisuals = new Dictionary<int, SkeletonVisual>();

		private static readonly RaycastHit[] RaycastHits = (RaycastHit[])(object)new RaycastHit[64];

		private static AimState _activeAim;

		private static float _nextRefreshTime;

		private static float _nextDotUpdateTime;

		private static bool _loggedTargetScanFailure;

		private static bool _loggedFireCallback;

		private static bool _loggedHeldGun;

		private static bool _loggedFirstTarget;

		private static bool _loggedDotTarget;

		private static bool _loggedTargetFailure;

		private static bool _loggedTargetEntryFailure;

		private static bool _loggedAimTickFailure;

		private static readonly HashSet<int> ActiveTargetMotionRoots = new HashSet<int>();

		private static readonly List<int> StaleTargetMotionRoots = new List<int>();

		private static int _lastNpcColliderCount = -1;

		private static int _lastPlayerColliderCount = -1;

		private static int _lastPreFireFrame = -1;

		private static Gun _lastPreFireGun;

		private static Gun _lastHeldGun;

		private static AimTarget _lastShotTarget;

		private static Gun _lastShotGun;

		private static float _lastShotStrength;

		private static float _lastShotTargetTime = -1f;

		private static Transform _lockedOwnerRoot;

		private static float _lockedTargetLastSeenTime;

		private static Vector3 _dotTargetPosition;

		private static Vector3 _dotDisplayPosition;

		private static Vector3 _dotVelocity;

		private static float _dotRangeMeters;

		private static float _displayedDotRangeMeters;

		private static float _dotRangeVelocity;

		private static bool _dotRangeInitialized;

		private static Transform _dotOwnerRoot;

		private static float _dotLastTargetTime;

		private static bool _dotHasTarget;

		private static bool _dotPositionInitialized;

		private static bool _loggedFusionShotCorrection;

		private static Transform _dotViewTransform;

		private static GameObject _dotObject;

		private static SpriteRenderer _dotRenderer;

		private static SpriteRenderer _dotOutlineRenderer;

		private static SpriteRenderer _dotGlowRenderer;

		private static GameObject _distanceTextObject;

		private static TextMesh _distanceTextMesh;

		private static MeshRenderer _distanceTextRenderer;

		private static GameObject _distanceTextShadowObject;

		private static TextMesh _distanceTextShadowMesh;

		private static MeshRenderer _distanceTextShadowRenderer;

		private static Texture2D _dotTexture;

		private static Sprite _dotSprite;

		private static int _dotTextureShape = -1;

		private static bool _loggedDotSpriteError;

		private static bool _loggedDistanceTextError;

		private static Material _skeletonMaterial;

		public static void Install()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_008f: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo val = AccessTools.Method(typeof(Gun), "OnFire", System.Type.EmptyTypes, (System.Type[])null);
			MethodInfo method = typeof(AimAssist).GetMethod("GunFirePrefix", (BindingFlags)40);
			MethodInfo method2 = typeof(AimAssist).GetMethod("GunFirePostfix", (BindingFlags)40);
			if (val == (MethodInfo)null || method == (MethodInfo)null || method2 == (MethodInfo)null)
			{
				throw new InvalidOperationException("BONELAB's Gun.OnFire aim-assist hook was not found.");
			}
			Harmony.Patch((MethodBase)(object)val, new HarmonyMethod(method), new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			MelonLogger.Msg("Aim assist installed the BoneLib callbacks and Harmony Gun.OnFire hook.");
		}

		public static void BindFusionTeammatePage(Page page)
		{
		}

		public static void RefreshFusionTeammateMenu()
		{
		}

		private static void LoadSelectedTeammateIds()
		{
		}

		private static void SetFusionTeammate(ulong platformId, bool selected)
		{
		}

		private static bool TryGetFusionSmallId(ulong platformId, out byte smallId)
		{
			smallId = 255;
			return false;
		}

		public static void BroadcastSelectedTeammateRelations()
		{
		}

		private static bool IsFusionTeammate(ulong platformId)
		{
			return false;
		}

		private static bool IsSelectedTeammate(ulong platformId)
		{
			return false;
		}

		private static bool IsKilledFusionPlayer(ulong platformId)
		{
			return false;
		}

		public static void ClearKilledPlayerFilter()
		{
		}

		public static void MarkFusionPlayerKilled(ulong platformId)
		{
		}

		private static void GunFirePrefix(Gun __instance)
		{
			OnPreFireGun(__instance);
		}

		private static void GunFirePostfix(Gun __instance)
		{
			OnPostFireGun(__instance);
		}

		public static void Tick()
		{
			try
			{
				RefreshTargets();
				if (RealismlabMod.AimAssistEnabled && !RealismlabMod.AimAssistDotEnabled)
				{
					UpdateTeammateLockNotifications();
				}
				UpdateSkeletonEsp();
				UpdateAimDot();
				_loggedAimTickFailure = false;
			}
			catch (System.Exception ex)
			{
				_nextRefreshTime = Time.unscaledTime + 0.25f;
				if (!_loggedAimTickFailure)
				{
					MelonLogger.Warning("Aim assist recovered from an update error: " + ex.Message);
					_loggedAimTickFailure = true;
				}
			}
		}

		private static void UpdateTeammateLockNotifications()
		{
		}

		public static void RefreshTargets()
		{
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			if ((!RealismlabMod.AimAssistEnabled && !RealismlabMod.SkeletonEspEnabled) || Time.unscaledTime < _nextRefreshTime)
			{
				return;
			}
			_nextRefreshTime = Time.unscaledTime + 1.5f;
			Targets.Clear();
			SeenColliders.Clear();
			FusionColliderOwners.Clear();
			NpcColliderOwners.Clear();
			ActiveTargetMotionRoots.Clear();
			try
			{
				System.Collections.Generic.IEnumerator<AIBrain> enumerator = Object.FindObjectsOfType<AIBrain>().GetEnumerator();
				try
				{
					while (((System.Collections.IEnumerator)enumerator).MoveNext())
					{
						AIBrain current = enumerator.Current;
						try
						{
							if (!((Object)(object)current == (Object)null) && !((Object)(object)((Component)current).gameObject == (Object)null) && ((Component)current).gameObject.activeInHierarchy && !current.isDead)
							{
								PuppetMaster puppetMaster = current.puppetMaster;
								Transform ownerRoot = (((Object)(object)puppetMaster != (Object)null) ? ((Component)puppetMaster).transform : ((Component)current).transform);
								AddColliders((Component)(((Object)(object)puppetMaster != (Object)null) ? ((object)puppetMaster) : ((object)current)), ownerRoot, current, null, ((Object)(object)puppetMaster != (Object)null) ? puppetMaster.targetAnimator : null, 0uL);
							}
						}
						catch (System.Exception e)
						{
							LogTargetEntryFailure("NPC", e);
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator)?.Dispose();
				}
				if ((RealismlabMod.FusionPlayerAimAssistEnabled || RealismlabMod.SkeletonEspEnabled) && PlayerIDManager.HasOtherPlayers)
				{
					System.Collections.Generic.IEnumerator<RigManager> enumerator2 = Object.FindObjectsOfType<RigManager>().GetEnumerator();
					try
					{
						while (((System.Collections.IEnumerator)enumerator2).MoveNext())
						{
							RigManager current2 = enumerator2.Current;
							try
							{
								if (!((Object)(object)current2 == (Object)null) && !((Object)(object)current2 == (Object)(object)Player.RigManager) && !((Object)(object)((Component)current2).gameObject == (Object)null) && ((Component)current2).gameObject.activeInHierarchy && NetworkPlayerManager.HasPlayer(current2))
								{
									Component searchRoot = (Component)(((Object)(object)current2.physicsRig != (Object)null) ? ((object)current2.physicsRig) : ((object)current2));
									AddColliders(searchRoot, ((Component)current2).transform, null, current2, null, GetFusionPlayerPlatformId(current2));
								}
							}
							catch (System.Exception e2)
							{
								LogTargetEntryFailure("Fusion player", e2);
							}
						}
					}
					finally
					{
						((System.IDisposable)enumerator2)?.Dispose();
					}
				}
				Enumerator<AimTarget> enumerator3 = Targets.GetEnumerator();
				try
				{
					while (enumerator3.MoveNext())
					{
						AimTarget current3 = enumerator3.Current;
						if (current3 != null && (Object)(object)current3.OwnerRoot != (Object)null)
						{
							ActiveTargetMotionRoots.Add(((Object)current3.OwnerRoot).GetInstanceID());
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
				}
				StaleTargetMotionRoots.Clear();
				Enumerator<int, TargetMotion> enumerator4 = TargetMotions.Keys.GetEnumerator();
				try
				{
					while (enumerator4.MoveNext())
					{
						int current4 = enumerator4.Current;
						if (!ActiveTargetMotionRoots.Contains(current4))
						{
							StaleTargetMotionRoots.Add(current4);
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose();
				}
				Enumerator<int> enumerator5 = StaleTargetMotionRoots.GetEnumerator();
				try
				{
					while (enumerator5.MoveNext())
					{
						int current5 = enumerator5.Current;
						TargetMotions.Remove(current5);
					}
				}
				finally
				{
					((System.IDisposable)enumerator5/*cast due to .constrained prefix*/).Dispose();
				}
				int num = 0;
				int num2 = 0;
				Enumerator<AimTarget> enumerator6 = Targets.GetEnumerator();
				try
				{
					while (enumerator6.MoveNext())
					{
						AimTarget current6 = enumerator6.Current;
						if ((Object)(object)current6.Brain != (Object)null)
						{
							num++;
						}
						else if ((Object)(object)current6.RemoteRig != (Object)null)
						{
							num2++;
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator6/*cast due to .constrained prefix*/).Dispose();
				}
				if (num != _lastNpcColliderCount || num2 != _lastPlayerColliderCount)
				{
					MelonLogger.Msg($"Aim assist indexed {num} NPC and {num2} Fusion-player body colliders.");
					_lastNpcColliderCount = num;
					_lastPlayerColliderCount = num2;
				}
				_loggedTargetScanFailure = false;
			}
			catch (System.Exception ex)
			{
				_nextRefreshTime = Time.unscaledTime + 0.25f;
				if (!_loggedTargetScanFailure)
				{
					MelonLogger.Warning("Aim assist could not refresh its target list: " + ex.Message);
					_loggedTargetScanFailure = true;
				}
			}
		}

		private static void LogTargetEntryFailure(string targetType, System.Exception e)
		{
			if (!_loggedTargetEntryFailure)
			{
				MelonLogger.Warning("Aim assist skipped a stale " + targetType + " target during refresh: " + e.Message);
				_loggedTargetEntryFailure = true;
			}
		}

		private static ulong GetFusionPlayerPlatformId(RigManager rig)
		{
			try
			{
				NetworkPlayer val = default(NetworkPlayer);
				if ((Object)(object)rig != (Object)null && NetworkPlayerManager.TryGetPlayer(rig, ref val) && val != null && val.PlayerID != null)
				{
					return val.PlayerID.PlatformID;
				}
			}
			catch
			{
			}
			return 0uL;
		}

		private static void AddColliders(Component searchRoot, Transform ownerRoot, AIBrain brain, RigManager remoteRig, Animator preferredAnimator, ulong remotePlatformId = 0uL)
		{
			if ((Object)(object)searchRoot == (Object)null)
			{
				return;
			}
			Transform headBone = FindAimBone(ownerRoot, (HumanBodyBones)10, "head", preferredAnimator);
			Transform chestBone = FindAimBone(ownerRoot, (HumanBodyBones)54, "upperchest", preferredAnimator) ?? FindAimBone(ownerRoot, (HumanBodyBones)8, "chest", preferredAnimator) ?? FindAimBone(ownerRoot, (HumanBodyBones)7, "spine2", preferredAnimator);
			System.Collections.Generic.IEnumerator<Collider> enumerator = searchRoot.GetComponentsInChildren<Collider>().GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator).MoveNext())
				{
					Collider current = enumerator.Current;
					if ((Object)(object)current == (Object)null || !current.enabled || current.isTrigger || (Object)(object)((Component)current).gameObject == (Object)null || !((Component)current).gameObject.activeInHierarchy)
					{
						continue;
					}
					int instanceID = ((Object)current).GetInstanceID();
					if (!SeenColliders.Add(instanceID))
					{
						continue;
					}
					if ((Object)(object)remoteRig != (Object)null)
					{
						FusionColliderOwners[instanceID] = remoteRig;
					}
					else if ((Object)(object)brain != (Object)null)
					{
						NpcColliderOwners[instanceID] = brain;
					}
					Animator val = preferredAnimator;
					if ((Object)(object)val == (Object)null && (Object)(object)remoteRig != (Object)null && (Object)(object)remoteRig.avatar != (Object)null)
					{
						val = remoteRig.avatar.animator;
					}
					if ((Object)(object)val == (Object)null)
					{
						try
						{
							System.Collections.Generic.IEnumerator<Animator> enumerator2 = ((Component)ownerRoot).GetComponentsInChildren<Animator>(true).GetEnumerator();
							try
							{
								while (((System.Collections.IEnumerator)enumerator2).MoveNext())
								{
									Animator current2 = enumerator2.Current;
									if ((Object)(object)current2 != (Object)null)
									{
										val = current2;
										break;
									}
								}
							}
							finally
							{
								((System.IDisposable)enumerator2)?.Dispose();
							}
						}
						catch
						{
						}
					}
					Targets.Add(new AimTarget
					{
						Collider = current,
						OwnerRoot = ownerRoot,
						RemotePlatformId = remotePlatformId,
						HeadBone = headBone,
						ChestBone = chestBone,
						Animator = val,
						Brain = brain,
						RemoteRig = remoteRig
					});
				}
			}
			finally
			{
				((System.IDisposable)enumerator)?.Dispose();
			}
		}

		private static Transform FindAimBone(Transform root, HumanBodyBones bone, string nameHint, Animator preferredAnimator)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			try
			{
				if ((Object)(object)preferredAnimator != (Object)null && preferredAnimator.isHuman)
				{
					Transform boneTransform = preferredAnimator.GetBoneTransform(bone);
					if ((Object)(object)boneTransform != (Object)null)
					{
						return boneTransform;
					}
				}
				System.Collections.Generic.IEnumerator<Animator> enumerator = ((Component)root).GetComponentsInChildren<Animator>(true).GetEnumerator();
				try
				{
					while (((System.Collections.IEnumerator)enumerator).MoveNext())
					{
						Animator current = enumerator.Current;
						if (!((Object)(object)current == (Object)null) && current.isHuman)
						{
							Transform boneTransform2 = current.GetBoneTransform(bone);
							if ((Object)(object)boneTransform2 != (Object)null)
							{
								return boneTransform2;
							}
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator)?.Dispose();
				}
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Transform> componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
				Transform val = null;
				System.Collections.Generic.IEnumerator<Transform> enumerator2 = componentsInChildren.GetEnumerator();
				try
				{
					while (((System.Collections.IEnumerator)enumerator2).MoveNext())
					{
						Transform current2 = enumerator2.Current;
						if (!((Object)(object)current2 == (Object)null))
						{
							string text = ((Object)current2).name.Replace("_", string.Empty).Replace("-", string.Empty);
							if (string.Equals(text, nameHint, (StringComparison)5))
							{
								return current2;
							}
							if ((Object)(object)val == (Object)null && text.EndsWith(nameHint, (StringComparison)5))
							{
								val = current2;
							}
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator2)?.Dispose();
				}
				return val;
			}
			catch
			{
				return null;
			}
		}

		public static void ClearTargets()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			ClearSkeletons();
			Targets.Clear();
			SeenColliders.Clear();
			FusionColliderOwners.Clear();
			NpcColliderOwners.Clear();
			TargetMotions.Clear();
			ActiveTargetMotionRoots.Clear();
			StaleTargetMotionRoots.Clear();
			_nextRefreshTime = 0f;
			_lastHeldGun = null;
			_lastShotTarget = null;
			_lastShotGun = null;
			_lastShotStrength = 0f;
			_lastShotTargetTime = -1f;
			_lockedOwnerRoot = null;
			_lockedTargetLastSeenTime = 0f;
			_dotHasTarget = false;
			_dotPositionInitialized = false;
			_dotVelocity = Vector3.zero;
			_dotRangeMeters = 0f;
			_displayedDotRangeMeters = 0f;
			_dotRangeVelocity = 0f;
			_dotRangeInitialized = false;
			_dotOwnerRoot = null;
			RestoreShotDirection();
			DestroyDot();
		}

		public static void RefreshSkeletonEsp()
		{
			if (!RealismlabMod.SkeletonEspEnabled)
			{
				ClearSkeletons();
			}
			_nextRefreshTime = 0f;
		}

		private static void UpdateSkeletonEsp()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			if (!RealismlabMod.SkeletonEspEnabled)
			{
				if (SkeletonVisuals.Count > 0)
				{
					ClearSkeletons();
				}
				return;
			}
			HashSet<int> val = new HashSet<int>();
			Enumerator<AimTarget> enumerator = Targets.GetEnumerator();
			try
			{
				SkeletonVisual skeletonVisual = default(SkeletonVisual);
				while (enumerator.MoveNext())
				{
					AimTarget current = enumerator.Current;
					if (current == null || (Object)(object)current.OwnerRoot == (Object)null || (Object)(object)current.Animator == (Object)null || !current.Animator.isHuman || ((Object)(object)current.RemoteRig != (Object)null && ((Object)(object)current.RemoteRig == (Object)(object)Player.RigManager || !((Component)current.RemoteRig).gameObject.activeInHierarchy)) || ((Object)(object)current.Brain != (Object)null && (current.Brain.isDead || !((Component)current.Brain).gameObject.activeInHierarchy)))
					{
						continue;
					}
					int instanceID = ((Object)current.OwnerRoot).GetInstanceID();
					if (!val.Add(instanceID))
					{
						continue;
					}
					if (!SkeletonVisuals.TryGetValue(instanceID, ref skeletonVisual) || (Object)(object)skeletonVisual.OwnerRoot != (Object)(object)current.OwnerRoot || skeletonVisual.AnimatorId != ((Object)current.Animator).GetInstanceID())
					{
						if (skeletonVisual != null)
						{
							DestroySkeleton(skeletonVisual);
						}
						skeletonVisual = CreateSkeleton(current.OwnerRoot, current.Animator);
						if (skeletonVisual == null)
						{
							continue;
						}
						SkeletonVisuals[instanceID] = skeletonVisual;
					}
					UpdateSkeleton(skeletonVisual, current.OwnerRoot, current.Animator);
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (SkeletonVisuals.Count == 0)
			{
				return;
			}
			List<int> val2 = new List<int>();
			Enumerator<int, SkeletonVisual> enumerator2 = SkeletonVisuals.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					KeyValuePair<int, SkeletonVisual> current2 = enumerator2.Current;
					if (!val.Contains(current2.Key))
					{
						val2.Add(current2.Key);
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<int> enumerator3 = val2.GetEnumerator();
			try
			{
				SkeletonVisual visual = default(SkeletonVisual);
				while (enumerator3.MoveNext())
				{
					int current3 = enumerator3.Current;
					if (SkeletonVisuals.TryGetValue(current3, ref visual))
					{
						DestroySkeleton(visual);
					}
					SkeletonVisuals.Remove(current3);
				}
			}
			finally
			{
				((System.IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private static SkeletonVisual CreateSkeleton(Transform ownerRoot, Animator animator)
		{
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			try
			{
				if ((Object)(object)_skeletonMaterial == (Object)null)
				{
					Shader val = Shader.Find("Hidden/Internal-Colored") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color");
					if ((Object)(object)val == (Object)null)
					{
						return null;
					}
					_skeletonMaterial = new Material(val)
					{
						name = "RealismLab_VisibleSkeletonMaterial",
						renderQueue = 5000
					};
					if (_skeletonMaterial.HasProperty("_ZTest"))
					{
						_skeletonMaterial.SetInt("_ZTest", 8);
					}
					if (_skeletonMaterial.HasProperty("_ZWrite"))
					{
						_skeletonMaterial.SetInt("_ZWrite", 0);
					}
					if (_skeletonMaterial.HasProperty("_SrcBlend"))
					{
						_skeletonMaterial.SetInt("_SrcBlend", 5);
					}
					if (_skeletonMaterial.HasProperty("_DstBlend"))
					{
						_skeletonMaterial.SetInt("_DstBlend", 10);
					}
					if (_skeletonMaterial.HasProperty("_Cull"))
					{
						_skeletonMaterial.SetInt("_Cull", 0);
					}
				}
				SkeletonVisual skeletonVisual = new SkeletonVisual
				{
					OwnerRoot = ownerRoot,
					AnimatorId = ((Object)animator).GetInstanceID(),
					Container = new GameObject("RealismLab_VisibleTargetSkeleton")
				};
				skeletonVisual.Container.transform.SetParent(ownerRoot, false);
				Transform val2 = animator.GetBoneTransform((HumanBodyBones)54) ?? animator.GetBoneTransform((HumanBodyBones)8);
				Transform val3 = val2 ?? animator.GetBoneTransform((HumanBodyBones)7);
				Transform val4 = animator.GetBoneTransform((HumanBodyBones)9) ?? animator.GetBoneTransform((HumanBodyBones)10);
				Transform boneTransform = animator.GetBoneTransform((HumanBodyBones)0);
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)10), val4);
				AddSkeletonSegment(skeletonVisual, val4, val3);
				AddSkeletonSegment(skeletonVisual, val3, animator.GetBoneTransform((HumanBodyBones)13));
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)13), animator.GetBoneTransform((HumanBodyBones)15));
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)15), animator.GetBoneTransform((HumanBodyBones)17));
				AddSkeletonSegment(skeletonVisual, val3, animator.GetBoneTransform((HumanBodyBones)14));
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)14), animator.GetBoneTransform((HumanBodyBones)16));
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)16), animator.GetBoneTransform((HumanBodyBones)18));
				AddSkeletonSegment(skeletonVisual, val3, boneTransform);
				AddSkeletonSegment(skeletonVisual, boneTransform, animator.GetBoneTransform((HumanBodyBones)1));
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)1), animator.GetBoneTransform((HumanBodyBones)3));
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)3), animator.GetBoneTransform((HumanBodyBones)5));
				AddSkeletonSegment(skeletonVisual, boneTransform, animator.GetBoneTransform((HumanBodyBones)2));
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)2), animator.GetBoneTransform((HumanBodyBones)4));
				AddSkeletonSegment(skeletonVisual, animator.GetBoneTransform((HumanBodyBones)4), animator.GetBoneTransform((HumanBodyBones)6));
				if (skeletonVisual.Segments.Count == 0)
				{
					DestroySkeleton(skeletonVisual);
					return null;
				}
				return skeletonVisual;
			}
			catch (System.Exception ex)
			{
				MelonLogger.Warning("Visible-target skeleton could not be created: " + ex.Message);
				return null;
			}
		}

		private static void AddSkeletonSegment(SkeletonVisual visual, Transform a, Transform b)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			if (visual != null && !((Object)(object)a == (Object)null) && !((Object)(object)b == (Object)null) && !((Object)(object)_skeletonMaterial == (Object)null))
			{
				GameObject val = new GameObject("Bone");
				val.transform.SetParent(visual.Container.transform, false);
				LineRenderer val2 = val.AddComponent<LineRenderer>();
				GameObject val3 = new GameObject("BoneOutline");
				val3.transform.SetParent(visual.Container.transform, false);
				LineRenderer val4 = val3.AddComponent<LineRenderer>();
				val2.useWorldSpace = true;
				val4.useWorldSpace = true;
				val2.positionCount = 2;
				val4.positionCount = 2;
				val2.startWidth = 0.02f;
				val2.endWidth = 0.02f;
				val4.startWidth = 0.042f;
				val4.endWidth = 0.042f;
				val2.numCapVertices = 2;
				val4.numCapVertices = 2;
				val2.alignment = (LineAlignment)0;
				val4.alignment = (LineAlignment)0;
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val4).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = false;
				((Renderer)val4).receiveShadows = false;
				((Renderer)val2).material = _skeletonMaterial;
				((Renderer)val4).material = _skeletonMaterial;
				((Renderer)val2).sortingOrder = 32767;
				((Renderer)val4).sortingOrder = 32766;
				val2.startColor = RealismlabMod.SkeletonEspColor;
				val2.endColor = RealismlabMod.SkeletonEspColor;
				val4.startColor = Color.black;
				val4.endColor = Color.black;
				((Renderer)val2).enabled = false;
				((Renderer)val4).enabled = false;
				visual.Segments.Add(new SkeletonSegment
				{
					Line = val2,
					Outline = val4,
					A = a,
					B = b
				});
			}
		}

		private static void UpdateSkeleton(SkeletonVisual visual, Transform ownerRoot, Animator animator)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			if (visual == null || (Object)(object)visual.Container == (Object)null || (Object)(object)ownerRoot == (Object)null || (Object)(object)animator == (Object)null)
			{
				return;
			}
			if ((Object)(object)visual.Container.transform.parent != (Object)(object)ownerRoot)
			{
				visual.Container.transform.SetParent(ownerRoot, false);
			}
			Camera val = FindAimCamera();
			Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : Player.Head);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Color skeletonEspColor = RealismlabMod.SkeletonEspColor;
			bool flag = (Object)(object)ownerRoot == (Object)(object)_lockedOwnerRoot && Time.unscaledTime - _lockedTargetLastSeenTime <= 0.5f;
			Color val3 = (flag ? Color.Lerp(skeletonEspColor, Color.white, 0.4f) : skeletonEspColor);
			val3.a = skeletonEspColor.a;
			float unscaledTime = Time.unscaledTime;
			Enumerator<SkeletonSegment> enumerator = visual.Segments.GetEnumerator();
			try
			{
				Color val5 = default(Color);
				while (enumerator.MoveNext())
				{
					SkeletonSegment current = enumerator.Current;
					if ((Object)(object)current.Line == (Object)null || (Object)(object)current.A == (Object)null || (Object)(object)current.B == (Object)null)
					{
						if ((Object)(object)current.Line != (Object)null)
						{
							((Renderer)current.Line).enabled = false;
						}
						if ((Object)(object)current.Outline != (Object)null)
						{
							((Renderer)current.Outline).enabled = false;
						}
						continue;
					}
					Vector3 position = current.A.position;
					Vector3 position2 = current.B.position;
					Vector3 val4 = (position + position2) * 0.5f;
					float num = Mathf.Clamp(Vector3.Distance(val2.position, val4) * 0.0024f, 0.016f, 0.04f) * (flag ? 1.3f : 1f);
					current.Line.SetPosition(0, position);
					current.Line.SetPosition(1, position2);
					current.Line.startWidth = num;
					current.Line.endWidth = num;
					current.Line.startColor = val3;
					current.Line.endColor = val3;
					if ((Object)(object)current.Outline != (Object)null)
					{
						current.Outline.SetPosition(0, position);
						current.Outline.SetPosition(1, position2);
						current.Outline.startWidth = num * 2.1f;
						current.Outline.endWidth = num * 2.1f;
						((Color)(ref val5))..ctor(0f, 0f, 0f, skeletonEspColor.a * 0.92f);
						current.Outline.startColor = val5;
						current.Outline.endColor = val5;
					}
					if (unscaledTime >= current.NextVisibilityCheck)
					{
						current.Visible = HasVisiblePath(val2.position, val4, ownerRoot);
						current.NextVisibilityCheck = unscaledTime + 0.08f;
					}
					((Renderer)current.Line).enabled = current.Visible;
					if ((Object)(object)current.Outline != (Object)null)
					{
						((Renderer)current.Outline).enabled = current.Visible;
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private static bool HasVisiblePath(Vector3 origin, Vector3 destination, Transform targetRoot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = destination - origin;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.05f)
			{
				return true;
			}
			int num = Physics.RaycastNonAlloc(origin, val / magnitude, Il2CppStructArray<RaycastHit>.op_Implicit(RaycastHits), magnitude, -5, (QueryTriggerInteraction)1);
			float num2 = 3.4028235E+38f;
			Transform val2 = null;
			Transform val3 = (((Object)(object)Player.RigManager != (Object)null) ? ((Component)Player.RigManager).transform : null);
			for (int i = 0; i < num; i++)
			{
				RaycastHit val4 = RaycastHits[i];
				if (!((Object)(object)((RaycastHit)(ref val4)).collider == (Object)null) && !(((RaycastHit)(ref val4)).distance >= num2))
				{
					Transform transform = ((Component)((RaycastHit)(ref val4)).collider).transform;
					if (!((Object)(object)val3 != (Object)null) || (!((Object)(object)transform == (Object)(object)val3) && !transform.IsChildOf(val3)))
					{
						num2 = ((RaycastHit)(ref val4)).distance;
						val2 = transform;
					}
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return true;
			}
			return (Object)(object)val2 == (Object)(object)targetRoot || val2.IsChildOf(targetRoot);
		}

		private static void DestroySkeleton(SkeletonVisual visual)
		{
			if (visual != null && (Object)(object)visual.Container != (Object)null)
			{
				Object.Destroy((Object)(object)visual.Container);
			}
		}

		private static void ClearSkeletons()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<int, SkeletonVisual> enumerator = SkeletonVisuals.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					SkeletonVisual current = enumerator.Current;
					DestroySkeleton(current);
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			SkeletonVisuals.Clear();
			if ((Object)(object)_skeletonMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)_skeletonMaterial);
			}
			_skeletonMaterial = null;
		}

		public static void OnPreFireGun(Gun gun)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: 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_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)gun != (Object)null && _lastPreFireFrame == Time.frameCount && (Object)(object)_lastPreFireGun == (Object)(object)gun)
			{
				return;
			}
			_lastPreFireFrame = Time.frameCount;
			_lastPreFireGun = gun;
			RestoreShotDirection();
			if (!RealismlabMod.AimAssistEnabled || (Object)(object)gun == (Object)null)
			{
				return;
			}
			if (!_loggedFireCallback)
			{
				MelonLogger.Msg("Aim assist received a gun-fire callback.");
				_loggedFireCallback = true;
			}
			try
			{
				if (!IsHeldByLocalPlayer(gun))
				{
					return;
				}
				_lastHeldGun = gun;
				_lastShotTarget = null;
				_lastShotGun = null;
				_lastShotStrength = 0f;
				_lastShotTargetTime = -1f;
				if (!_loggedHeldGun)
				{
					MelonLogger.Msg("Aim assist confirmed a locally held gun.");
					_loggedHeldGun = true;
				}
				Transform firePointTransform = gun.firePointTransform;
				if ((Object)(object)firePointTransform == (Object)null)
				{
					return;
				}
				Vector3 position = firePointTransform.position;
				if (!TryFindTarget(gun, out var bestTarget, out var bestPoint, out var bestStrength))
				{
					if (!_loggedTargetFailure)
					{
						MelonLogger.Warning($"Aim assist saw {Targets.Count} target colliders but none passed its aim cone and visibility check.");
						_loggedTargetFailure = true;
					}
					return;
				}
				bestPoint = GetTrackedAimPoint(bestTarget, bestPoint);
				_lastShotTarget = bestTarget;
				_lastShotGun