Decompiled source of Vertigo2Unleashed v0.0.3

Vertigo2Unleashed.dll

Decompiled 8 months ago
#define DEBUG
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HarmonyLib.Tools;
using Microsoft.CodeAnalysis;
using UnityEngine;
using Valve.VR;
using Vertigo2;
using Vertigo2.Interaction;
using Vertigo2.Player;
using Vertigo2.Weapons;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Vertigo2Unleashed")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("V2U Plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Vertigo2Unleashed")]
[assembly: AssemblyTitle("Vertigo2Unleashed")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Vertigo2Unleashed
{
	[BepInPlugin("Vertigo2Unleashed", "Vertigo2Unleashed", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private enum MeleeResult
		{
			Nothing,
			HitSomething,
			HitEnemy
		}

		private class MeleeCollisionComponent : MonoBehaviour
		{
			public HeldEquippablePhysical Parent;

			private void OnCollisionEnter(Collision other)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				VertigoHand val = ((((HeldEquippable)Parent).inputSource == VertigoPlayer.instance.RHand.inputSource) ? VertigoPlayer.instance.RHand : VertigoPlayer.instance.LHand);
				Debug.Assert((Object)(object)val != (Object)null);
				Vector3 velocity = Parent.rigidbody.velocity;
				ref float reference = ref MeleeCooldownPerHand[GetHandIndex(val)];
				if (!(reference > 0f) && !(((Vector3)(ref velocity)).magnitude < _configMeleeMinSpeed.Value))
				{
					Debug.Assert(other != null);
					Debug.Assert(other.contactCount > 0);
					Debug.Assert((Object)(object)other.collider != (Object)null);
					ContactPoint val2 = other.contacts[0];
					if (DoMelee(val, ((ContactPoint)(ref val2)).separation, other.collider, ((ContactPoint)(ref val2)).point, ((ContactPoint)(ref val2)).normal, velocity, ((Vector3)(ref velocity)).normalized) != 0)
					{
						reference = 0.2f;
					}
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ModifyDamageDelegate <>9__27_0;

			public static ModifyDamageDelegate <>9__27_1;

			internal void <Awake>b__27_0(ref float damage)
			{
				damage *= _configDamageMultiplierToEnemy.Value;
			}

			internal void <Awake>b__27_1(ref float damage)
			{
				damage *= _configDamageMultiplierToPlayer.Value;
			}
		}

		private static ManualLogSource _logger;

		private static ConfigFile _configFile;

		private static ConfigEntry<bool> _configGripHolsterModeEnabled;

		private static ConfigEntry<bool> _configGripHolsterModeNoTrigger;

		private static ConfigEntry<float> _configDamageMultiplierToEnemy;

		private static ConfigEntry<float> _configDamageMultiplierToPlayer;

		private static ConfigEntry<float> _configSpeedMultiplierPlayerWalk;

		private static ConfigEntry<float> _configSpeedMultiplierPlayerSwim;

		private static ConfigEntry<bool> _configVirtualStockEnabled;

		private static ConfigEntry<float> _configVirtualStockStrength;

		private static ConfigEntry<float> _configVirtualStockShoulderForward;

		private static ConfigEntry<float> _configVirtualStockShoulderRight;

		private static ConfigEntry<float> _configVirtualStockShoulderUp;

		private static ConfigEntry<float> _configVirtualStockForwardDepth;

		private static ConfigEntry<float> _configVirtualStockShoulderMaxDistance;

		private static ConfigEntry<bool> _configRevolver2HGripEnabled;

		private static ConfigEntry<bool> _configDualWieldingEnabled;

		private static ConfigEntry<bool> _configDualWieldingAllowClonedWeapons;

		private static ConfigEntry<bool> _configMeleeEnabled;

		private static ConfigEntry<float> _configMeleeHandSphereCastRadius;

		private static ConfigEntry<float> _configMeleeMaxDistance;

		private static ConfigEntry<float> _configMeleeMinSpeed;

		private static ConfigEntry<float> _configMeleeMaxSpeed;

		private static ConfigEntry<float> _configMeleeMinDamage;

		private static ConfigEntry<float> _configMeleeMaxDamage;

		private static ConfigEntry<float> _configMeleeHitForceMultiplier;

		private static SteamVR_Input_Sources _weaponSwitcherInputSourceOverride;

		private static SteamVR_Input_Sources _weaponSwitcherInputSourceOtherHandOverride;

		private static EquippableInstance[] _clonedEquippableInstances;

		private static bool _mustUpdateBelt;

		private static EquippableProfile _oldEquippableDominant;

		private static EquippableProfile _oldEquippableNonDominant;

		private static readonly float[] MeleeCooldownPerHand = new float[2];

		private static SteamVR_Input_Sources VanillaInputSourceDominant => VertigoPlayer.instance.GetHand(GameManager.Hand_Dominant).inputSource;

		private static SteamVR_Input_Sources VanillaInputSourceNonDominant => VertigoPlayer.instance.GetHand(GameManager.Hand_NonDominant).inputSource;

		private static SteamVR_Input_Sources OverridenInputSourceDominant => _configDualWieldingEnabled.Value ? _weaponSwitcherInputSourceOverride : VanillaInputSourceDominant;

		private static SteamVR_Input_Sources OverridenInputSourceNonDominant => _configDualWieldingEnabled.Value ? _weaponSwitcherInputSourceOtherHandOverride : VanillaInputSourceNonDominant;

		public Plugin()
		{
			_logger = ((BaseUnityPlugin)this).Logger;
			_configFile = ((BaseUnityPlugin)this).Config;
			_configGripHolsterModeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "GripHolsterModeEnabled", true, "Enable grip-holster mode (automatically holsters weapons when the grip is released, and equips the last holstered weapon when the grip is held)");
			_configGripHolsterModeNoTrigger = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "GripHolsterModeNoTrigger", true, "Prevents grip-holster mode from activating if the trigger button is held before the grip button (useful to allow to curl hands into fists for hand-to-hand melee combat)");
			_configDamageMultiplierToEnemy = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DamageMultiplierToEnemy", 1f, "Multiplier for damage inflicted to enemies (1.0 is the default)");
			_configDamageMultiplierToPlayer = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DamageMultiplierToPlayer", 1f, "Multiplier for damage inflicted to the player (1.0 is the default)");
			_configSpeedMultiplierPlayerWalk = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpeedMultiplierPlayerWalk", 1f, "Multiplier for player walk speed (m/s, smooth locomotion)");
			_configSpeedMultiplierPlayerSwim = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpeedMultiplierPlayerSwim", 1f, "Multiplier for player swim speed (m/s, smooth locomotion)");
			_configVirtualStockEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "VirtualStockEnabled", true, "Enable virtual stock for two-handed weapons (interpolates two-handed aiming angle with approximate shoulder position)");
			_configVirtualStockStrength = ((BaseUnityPlugin)this).Config.Bind<float>("General", "VirtualStockStrength", 0.5f, "How strongly the shoulder position affects two-handed aiming (0.0: only the off-hand matters, shoulder is ignored) (1.0: only the shoulder matters, off-hand is ignored) (in-between values are blended)");
			_configVirtualStockShoulderForward = ((BaseUnityPlugin)this).Config.Bind<float>("General", "VirtualStockShoulderForward", -0.1f, "From the player's head position, sets how many units forward the shoulder is");
			_configVirtualStockShoulderRight = ((BaseUnityPlugin)this).Config.Bind<float>("General", "VirtualStockShoulderRight", 0.25f, "From the player's head position, sets how many units rightwards the shoulder is (for left-handed players, this value should probably be negative)");
			_configVirtualStockShoulderUp = ((BaseUnityPlugin)this).Config.Bind<float>("General", "VirtualStockShoulderUp", -0.1f, "From the player's head position, sets how many units upwards the shoulder is");
			_configVirtualStockForwardDepth = ((BaseUnityPlugin)this).Config.Bind<float>("General", "VirtualStockForwardDepth", 2.75f, "Starting from the shoulder position, sets how many units forward the virtual stock interpolation point is");
			_configVirtualStockShoulderMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "VirtualStockShoulderMaxDistance", 0.45f, "Maximum distance between the dominant hand and shoulder to enable virtual stock aiming (reverts to vanilla 2H aiming if exceeded)");
			_configRevolver2HGripEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Revolver2HGripEnabled", true, "Enable two-handed aiming for the revolver (including virtual stock)");
			_configDualWieldingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DualWieldingEnabled", true, "Enable dual wielding (needs 'weapon switch' bound to both hands in SteamVR)");
			_configDualWieldingAllowClonedWeapons = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DualWieldingAllowClonedWeapons", true, "Allows dual wielding two clones of the same weapon");
			_configMeleeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "MeleeEnabled", true, "Enable universal melee attacks (hand-to-hand, held weapons)");
			_configMeleeHandSphereCastRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MeleeHandSphereCastRadius", 0.15f, "Radius around player hand considered for hand-to-hand melee attacks");
			_configMeleeMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MeleeMaxDistance", 0.08f, "Maximum distance from the contact point for melee targets to register");
			_configMeleeMinSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MeleeMinSpeed", 2f, "Minimum speed required for a melee attack to register, also used for damage calculations");
			_configMeleeMaxSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MeleeMaxSpeed", 11f, "Speed upper bound used for melee damage calculations");
			_configMeleeMinDamage = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MeleeMinDamage", 2.5f, "Minimum damage dealt for a successful melee attack");
			_configMeleeMaxDamage = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MeleeMaxDamage", 22.5f, "Maximum damage dealt for a successful melee attack");
			_configMeleeHitForceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MeleeHitForceMultiplier", 1.5f, "Physics force multiplier for melee attacks (e.g. affects ragdolls from melee kills)");
			HarmonyFileLog.Enabled = true;
		}

		private void Awake()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			_logger.LogInfo((object)"Plugin Vertigo2Unleashed is loaded!");
			Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
			_logger.LogInfo((object)"Injected all Harmony patches");
			object obj = <>c.<>9__27_0;
			if (obj == null)
			{
				ModifyDamageDelegate val = delegate(ref float damage)
				{
					damage *= _configDamageMultiplierToEnemy.Value;
				};
				<>c.<>9__27_0 = val;
				obj = (object)val;
			}
			Enemy.ModifyDamage += (ModifyDamageDelegate)obj;
			object obj2 = <>c.<>9__27_1;
			if (obj2 == null)
			{
				ModifyDamageDelegate val2 = delegate(ref float damage)
				{
					damage *= _configDamageMultiplierToPlayer.Value;
				};
				<>c.<>9__27_1 = val2;
				obj2 = (object)val2;
			}
			VertigoPlayer.ModifyDamage += (ModifyDamageDelegate)obj2;
		}

		private static object GetAndInvokePrivateMethod(object obj, string name, object[] args = null)
		{
			Debug.Assert(obj != null);
			MethodInfo method = obj.GetType().GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic);
			Debug.Assert(method != null);
			return method.Invoke(obj, args ?? new object[0]);
		}

		private static object GetPrivatePropertyValue(object obj, string name)
		{
			Debug.Assert(obj != null);
			PropertyInfo property = obj.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic);
			Debug.Assert(property != null);
			return property.GetValue(obj);
		}

		private static void SetPrivateFieldValue(object obj, string name, object value)
		{
			Debug.Assert(obj != null);
			FieldInfo field = obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
			Debug.Assert(field != null);
			field.SetValue(obj, value);
		}

		private static object GetPrivateFieldValue(object obj, string name)
		{
			Debug.Assert(obj != null);
			FieldInfo field = obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
			Debug.Assert(field != null);
			return field.GetValue(obj);
		}

		private static void RaisePrivateEvent<TEventArgs>(object obj, string eventName, TEventArgs eventArgs) where TEventArgs : EventArgs
		{
			Debug.Assert(obj != null);
			MulticastDelegate multicastDelegate = (MulticastDelegate)GetPrivateFieldValue(obj, eventName);
			if ((object)multicastDelegate != null)
			{
				Delegate[] invocationList = multicastDelegate.GetInvocationList();
				foreach (Delegate @delegate in invocationList)
				{
					@delegate.Method.Invoke(@delegate.Target, new object[2] { obj, eventArgs });
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static bool WeaponSwitcherInputSourceGetterPatchPrefix(ref SteamVR_Input_Sources __result)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected I4, but got Unknown
			__result = (SteamVR_Input_Sources)(int)OverridenInputSourceDominant;
			return false;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static bool WeaponSwitcherInputSourceOtherHandGetterPatchPrefix(ref SteamVR_Input_Sources __result)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected I4, but got Unknown
			__result = (SteamVR_Input_Sources)(int)OverridenInputSourceNonDominant;
			return false;
		}

		private static void SetInputSourceOverridesToDominant()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_weaponSwitcherInputSourceOverride = VanillaInputSourceDominant;
			_weaponSwitcherInputSourceOtherHandOverride = VanillaInputSourceNonDominant;
		}

		private static void SetInputSourceOverridesToNonDominant()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_weaponSwitcherInputSourceOverride = VanillaInputSourceNonDominant;
			_weaponSwitcherInputSourceOtherHandOverride = VanillaInputSourceDominant;
		}

		[HarmonyPatch(typeof(WeaponSwitcher), "MenuStart")]
		[HarmonyPrefix]
		private static bool WeaponSwitcherMenuStartPatchPrefix(WeaponSwitcher __instance)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			GetAndInvokePrivateMethod(__instance, "ResetPos");
			__instance.ResetIcons();
			GetAndInvokePrivateMethod(__instance, "CheckSecretWeapons");
			if (__instance.ActiveSlot != -1)
			{
				SteamVR_Input_Sources inputSource = ((EquippableInstance)GetPrivatePropertyValue(__instance, "activeEquippable")).eqip.inputSource;
				IEnumerator enumerator = (IEnumerator)GetAndInvokePrivateMethod(__instance, "IconToSpot", new object[2] { __instance.ActiveSlot, inputSource });
				((MonoBehaviour)__instance).StartCoroutine(enumerator);
				__instance.manager.SwitchToEquippable((EquippableProfile)null, OverridenInputSourceDominant, false);
			}
			__instance.cursorPos = Vector2.zero;
			__instance.au.PlayOneShot(__instance.au_open);
			return false;
		}

		[HarmonyPatch(typeof(WeaponSwitcher), "SelectedItem")]
		[HarmonyPrefix]
		private static bool WeaponSwitcherSelectedItemPatchPrefix(WeaponSwitcher __instance, string item, bool ___openAllowed)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.menuOpen || !___openAllowed)
			{
				return false;
			}
			SteamVR_Input_Sources overridenInputSourceDominant = OverridenInputSourceDominant;
			SteamVR_Input_Sources overridenInputSourceNonDominant = OverridenInputSourceNonDominant;
			if (item == "Hands")
			{
				__instance.manager.SwitchToEquippable((EquippableProfile)null, overridenInputSourceDominant, false);
				__instance.au.PlayOneShot(__instance.au_close);
			}
			else
			{
				int num = Array.IndexOf(__instance.slots, Array.Find(__instance.slots, (EquippableSlot s) => s.name == item));
				IEnumerator enumerator = (IEnumerator)GetAndInvokePrivateMethod(__instance, "IconToHand", new object[2]
				{
					num,
					(num != -1 && __instance.slots[num].equippable.holdInOppositeHand) ? overridenInputSourceNonDominant : overridenInputSourceDominant
				});
				__instance.au.PlayOneShot(__instance.au_select);
				((MonoBehaviour)__instance).StartCoroutine(enumerator);
			}
			__instance.action_haptic.Execute(0f, 0.3f, 10f, 0.8f, overridenInputSourceDominant);
			return false;
		}

		[HarmonyPatch(typeof(WeaponPickup), "Pickup")]
		[HarmonyPrefix]
		private static bool WeaponPickupPickupPatchPrefix(WeaponPickup __instance)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			if (!_configDualWieldingEnabled.Value)
			{
				return true;
			}
			if (__instance.pickedUp || (Object)(object)EquippablesManager.instance == (Object)null)
			{
				return false;
			}
			VertigoInteractable val = (VertigoInteractable)GetPrivateFieldValue(__instance, "interactable");
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			SteamVR_Input_Sources inputSource = val.mainHoldingHand.inputSource;
			if (inputSource == GameManager.Hand_Dominant)
			{
				SetInputSourceOverridesToDominant();
			}
			else
			{
				SetInputSourceOverridesToNonDominant();
			}
			EquippablesManager.instance.SwitchToEquippable((EquippableProfile)null, inputSource, false);
			if (val.isBeingHeld)
			{
				val.ForceDrop();
			}
			if (__instance.unlockWeapon)
			{
				EquippablesManager.instance.PickupWeapon(__instance.weapon, inputSource);
			}
			else
			{
				EquippablesManager.instance.SwitchToEquippable(__instance.weapon, inputSource, false);
			}
			if ((Object)(object)__instance.pickupSmoothTransform != (Object)null)
			{
				EquippablesManager.instance.PickupSmooth(inputSource, __instance.pickupSmoothTransform);
			}
			__instance.pickedUp = true;
			RaisePrivateEvent(__instance, "OnPickup", EventArgs.Empty);
			__instance.PickupUnityEvent.Invoke();
			Equippable eqip = EquippablesManager.instance.GetHand(inputSource).currentEquippable.eqip;
			IEnumerator enumerator = (IEnumerator)GetAndInvokePrivateMethod(__instance, "DoWeaponTutorial", new object[1] { eqip });
			((MonoBehaviour)eqip).StartCoroutine(enumerator);
			if (__instance.saveGameWhenPickedUp)
			{
				IEnumerator enumerator2 = (IEnumerator)GetAndInvokePrivateMethod(__instance, "SaveCoroutine");
				((MonoBehaviour)__instance).StartCoroutine(enumerator2);
			}
			SetInputSourceOverridesToDominant();
			return false;
		}

		[HarmonyPatch(typeof(EquippablesManager), "Start")]
		[HarmonyPostfix]
		private static void DualWieldingEquippablesManagerPatchPostfix(EquippablesManager __instance, Collider ___playerHeadCollider)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			_clonedEquippableInstances = (EquippableInstance[])(object)new EquippableInstance[__instance.equippableCount];
			for (int i = 0; i < __instance.equippableCount; i++)
			{
				if ((Object)(object)__instance.allEquippables[i].prefab == (Object)null)
				{
					continue;
				}
				_clonedEquippableInstances[i] = new EquippableInstance(Object.Instantiate<GameObject>(__instance.allEquippables[i].prefab, VertigoPlayer.instance.playArea), __instance.allEquippables[i]);
				_clonedEquippableInstances[i].gameObject.SetActive(false);
				if (!((Object)(object)___playerHeadCollider == (Object)null))
				{
					Collider[] componentsInChildren = _clonedEquippableInstances[i].gameObject.GetComponentsInChildren<Collider>(true);
					Collider[] array = componentsInChildren;
					foreach (Collider val in array)
					{
						Physics.IgnoreCollision(val, ___playerHeadCollider);
					}
				}
			}
		}

		[HarmonyPatch(typeof(EquippablesManager), "FindInstanceForProfile")]
		[HarmonyPrefix]
		private static bool DualWieldingEquippablesManagerInstancePatchPrefix(EquippableProfile prof, ref EquippableInstance __result)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (!_configDualWieldingAllowClonedWeapons.Value || _weaponSwitcherInputSourceOverride != VanillaInputSourceNonDominant)
			{
				return true;
			}
			__result = Array.Find(_clonedEquippableInstances, (EquippableInstance e) => (Object)(object)e.profile == (Object)(object)prof);
			return false;
		}

		[HarmonyPatch(typeof(EquippablesManager), "SwitchToEquippable")]
		[HarmonyPrefix]
		private static bool DualWieldingEquippablesManagerSwitchToEquippablePatchPrefix(EquippablesManager __instance, EquippableProfile profile, SteamVR_Input_Sources forHand, ref bool autoSwitchOtherHand)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			_mustUpdateBelt = true;
			autoSwitchOtherHand = false;
			if (!_configDualWieldingAllowClonedWeapons.Value)
			{
				SteamVR_Input_Sources val = ((forHand == GameManager.Hand_Dominant) ? GameManager.Hand_NonDominant : GameManager.Hand_Dominant);
				if ((Object)(object)__instance.GetHand(val).currentProfile == (Object)(object)profile)
				{
					__instance.SwitchToEquippable((EquippableProfile)null, val, false);
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(GameManager), "LoadLevel")]
		[HarmonyPrefix]
		public static bool GameManagerLoadLevelPatchPrefix()
		{
			_oldEquippableDominant = null;
			_oldEquippableNonDominant = null;
			SetInputSourceOverridesToDominant();
			return true;
		}

		[HarmonyPatch(typeof(WeaponSwitcher), "Update")]
		[HarmonyPrefix]
		private static bool GripHolsterPatchPrefix(WeaponSwitcher __instance, bool ___openAllowed)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (_configGripHolsterModeEnabled.Value && !__instance.menuOpen && ___openAllowed)
			{
				SetInputSourceOverridesToDominant();
				doHand(GameManager.Hand_Dominant, ref _oldEquippableDominant);
				SetInputSourceOverridesToNonDominant();
				doHand(GameManager.Hand_NonDominant, ref _oldEquippableNonDominant);
			}
			if (_configDualWieldingEnabled.Value)
			{
				Debug.Assert(VanillaInputSourceDominant != VanillaInputSourceNonDominant);
				if (__instance.a_weaponSwitch.GetState(VanillaInputSourceDominant))
				{
					SetInputSourceOverridesToDominant();
				}
				else if (__instance.a_weaponSwitch.GetState(VanillaInputSourceNonDominant))
				{
					SetInputSourceOverridesToNonDominant();
				}
			}
			else
			{
				SetInputSourceOverridesToDominant();
			}
			return true;
			void doHand(SteamVR_Input_Sources handType, ref EquippableProfile oldEquippable)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				VertigoHand hand = VertigoPlayer.instance.GetHand(handType);
				bool state = SteamVR_Actions.default_Fire.GetState(hand.inputSource);
				bool state2 = hand.a_grab_grip.GetState(hand.inputSource);
				bool lastState = hand.a_grab_grip.GetLastState(hand.inputSource);
				EquippableHand hand2 = __instance.manager.GetHand(handType);
				if (!state2 && (Object)(object)hand2.currentProfile != (Object)null)
				{
					oldEquippable = hand2.currentProfile;
					__instance.manager.SwitchToEquippable((EquippableProfile)null, handType, false);
					__instance.au.PlayOneShot(__instance.au_open);
				}
				if ((!_configGripHolsterModeNoTrigger.Value || !state) && !lastState && state2 && (Object)(object)oldEquippable != (Object)null && (Object)(object)hand2.currentProfile == (Object)null && (Object)(object)hand.hoveringInteractable == (Object)null && (Object)(object)hand.attachedInteractable == (Object)null)
				{
					__instance.manager.SwitchToEquippable(oldEquippable, handType, false);
					__instance.au.PlayOneShot(__instance.au_select);
				}
			}
		}

		private static SteamVR_Input_Sources InputSourceForBelt()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_006c: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!_configDualWieldingEnabled.Value)
			{
				return GameManager.Hand_Dominant;
			}
			EquippableHand hand = EquippablesManager.instance.GetHand(GameManager.Hand_Dominant);
			EquippableHand hand2 = EquippablesManager.instance.GetHand(GameManager.Hand_NonDominant);
			if ((Object)(object)hand.currentProfile == (Object)null && (Object)(object)hand2.currentProfile != (Object)null)
			{
				return GameManager.Hand_NonDominant;
			}
			return GameManager.Hand_Dominant;
		}

		[HarmonyPatch(typeof(AmmoBelt), "UpdateHandedness")]
		[HarmonyPrefix]
		private static bool AmmoBeltUpdateHandednessPatchPrefix(Transform ___pos_rightHip, Transform ___pos_leftHip, Transform ___uiRoot)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!_configDualWieldingEnabled.Value)
			{
				return true;
			}
			Transform val = ((InputSourceForBelt() == GameManager.Hand_NonDominant) ? ___pos_rightHip : ___pos_leftHip);
			((Component)___uiRoot).transform.position = val.position;
			((Component)___uiRoot).transform.rotation = val.rotation;
			return false;
		}

		[HarmonyPatch(typeof(AmmoBelt), "GetAmmoIndexForEquippable")]
		[HarmonyPrefix]
		private static bool AmmoBeltGetAmmoIndexForEquippablePatchPrefix(ref int __result, ref EquippableProfile equippable)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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)
			if (!_configDualWieldingEnabled.Value)
			{
				return true;
			}
			EquippableHand hand = EquippablesManager.instance.GetHand(GameManager.Hand_Dominant);
			EquippableHand hand2 = EquippablesManager.instance.GetHand(GameManager.Hand_NonDominant);
			if ((Object)(object)hand.currentProfile != (Object)null && (Object)(object)hand2.currentProfile != (Object)null)
			{
				__result = -1;
				return false;
			}
			equippable = EquippablesManager.instance.GetHand(InputSourceForBelt()).currentProfile;
			return true;
		}

		[HarmonyPatch(typeof(AmmoBelt), "Update")]
		[HarmonyPrefix]
		private static bool AmmoBeltUpdatePatchPrefix(AmmoBelt __instance)
		{
			if (_mustUpdateBelt)
			{
				_mustUpdateBelt = false;
				__instance.UpdateBelt();
			}
			return true;
		}

		[HarmonyPatch(typeof(VertigoCharacterController), "UpdateVelocityBuffer")]
		[HarmonyPrefix]
		private static bool SpeedMultiplierPlayerPatchPrefix(VertigoCharacterController __instance, object[] __args)
		{
			__instance.walkSpeed = 3f * _configSpeedMultiplierPlayerWalk.Value;
			__instance.swimSpeed = 3f * _configSpeedMultiplierPlayerSwim.Value;
			return true;
		}

		[HarmonyPatch(typeof(HeldEquippablePhysical), "FixedUpdate")]
		[HarmonyPrefix]
		private static bool VirtualStockPatchPrefix(HeldEquippablePhysical __instance, Vector3 ___localHeldOrigin, Vector3 ___gunUpVector)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_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_0108: 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)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: 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_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: 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_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: 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_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: 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)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			if (!_configVirtualStockEnabled.Value)
			{
				return true;
			}
			if (Time.timeScale == 0f)
			{
				return false;
			}
			float num = 1f;
			if ((Object)(object)EquippablesManager.instance != (Object)null)
			{
				num *= EquippablesManager.instance.pickupFactor * EquippablesManager.instance.pickupFactor;
			}
			Vector3 val = ((HeldEquippable)__instance).controller.TransformPoint(___localHeldOrigin);
			Quaternion val2 = ((HeldEquippable)__instance).controller.rotation * Quaternion.Euler(GameManager.options.gameplay_gunAngle * 4f, 0f, 0f);
			GripGun attachedGrip = __instance.attachedGrip;
			Vector3 val3;
			if ((Object)(object)attachedGrip != (Object)null && attachedGrip.isForegrip)
			{
				Transform transform = ((Component)attachedGrip.interactable.MainAttachPoint).transform;
				val3 = ((Component)__instance).transform.InverseTransformPoint(((Component)transform).transform.position);
				Vector3 normalized = ((Vector3)(ref val3)).normalized;
				val3 = attachedGrip.handgrabbing.handAnimator.CenterPosition_UnAnimated - ((Component)__instance).transform.position;
				Vector3 normalized2 = ((Vector3)(ref val3)).normalized;
				Transform transform2 = ((Component)((VertigoEntity)VertigoPlayer.instance).head).transform;
				Vector3 position = transform2.position;
				val3 = transform2.forward;
				Vector3 val4 = position + ((Vector3)(ref val3)).normalized * _configVirtualStockShoulderForward.Value;
				val3 = transform2.right;
				Vector3 val5 = val4 + ((Vector3)(ref val3)).normalized * _configVirtualStockShoulderRight.Value;
				val3 = transform2.up;
				Vector3 val6 = val5 + ((Vector3)(ref val3)).normalized * _configVirtualStockShoulderUp.Value;
				val3 = transform2.forward;
				Vector3 val7 = val6 + ((Vector3)(ref val3)).normalized * _configVirtualStockForwardDepth.Value;
				val3 = val7 - ((Component)__instance).transform.position;
				Vector3 val8 = ((Vector3)(ref val3)).normalized;
				VertigoHand hand = VertigoPlayer.instance.GetHand(GameManager.Hand_Dominant);
				val3 = val6 - ((Component)hand).transform.position;
				if (((Vector3)(ref val3)).magnitude > _configVirtualStockShoulderMaxDistance.Value)
				{
					val8 = normalized2;
				}
				val3 = Vector3.Lerp(normalized2, val8, _configVirtualStockStrength.Value);
				Vector3 normalized3 = ((Vector3)(ref val3)).normalized;
				Quaternion val9 = Math3d.LookRotationQuatExtended(normalized3, ((HeldEquippable)__instance).controller.TransformDirection(___gunUpVector), normalized, ___gunUpVector);
				float num2 = Mathf.InverseLerp(200f, 0f, Quaternion.Angle(val9, ((HeldEquippable)__instance).controller.rotation));
				num2 = Mathf.Clamp01(num2);
				val2 = Quaternion.Slerp(val2, val9, Mathf.Pow(num2, 0.3f));
			}
			Quaternion val10 = val2 * Quaternion.Inverse(((Component)__instance).transform.rotation);
			Vector3 val11 = Vector3.zero;
			float num3 = default(float);
			Vector3 val12 = default(Vector3);
			((Quaternion)(ref val10)).ToAngleAxis(ref num3, ref val12);
			if (num3 > 180f)
			{
				num3 -= 360f;
			}
			if (num3 != 0f && !float.IsNaN(val12.x) && !float.IsInfinity(val12.x))
			{
				val11 = num3 * val12;
			}
			Rigidbody rigidbody = __instance.rigidbody;
			rigidbody.angularVelocity += val11 * Time.fixedDeltaTime * 35f * num * __instance.attachTorqueMultiplier;
			Rigidbody rigidbody2 = __instance.rigidbody;
			Vector3 angularVelocity = rigidbody2.angularVelocity;
			Vector3 val13 = __instance.rigidbody.angularVelocity * Time.fixedDeltaTime * 50f * num;
			val3 = __instance.rigidbody.angularVelocity;
			rigidbody2.angularVelocity = angularVelocity - Vector3.ClampMagnitude(val13, ((Vector3)(ref val3)).magnitude * 0.9f);
			Vector3 val14 = val - __instance.heldOrigin.position;
			__instance.rigidbody.AddForceAtPosition(800f * val14 * num * __instance.attachForceMultiplier, __instance.heldOrigin.position, (ForceMode)5);
			Vector3 pointVelocity = __instance.rigidbody.GetPointVelocity(__instance.heldOrigin.position);
			__instance.rigidbody.AddForceAtPosition(Vector3.ClampMagnitude(-30f * pointVelocity * num, ((Vector3)(ref pointVelocity)).magnitude / Time.fixedDeltaTime * 0.8f), __instance.heldOrigin.position, (ForceMode)5);
			return false;
		}

		[HarmonyPatch(typeof(Revolver), "GunUpdate")]
		[HarmonyPrefix]
		private static bool RevolverTwoHandedPatchPrefix(Revolver __instance)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (_configRevolver2HGripEnabled.Value)
			{
				((HeldEquippablePhysical)((Equippable)__instance).heldEquippable).secondHandGrips[1].isForegrip = true;
			}
			return true;
		}

		[HarmonyPatch(typeof(ConsoleController), "Init")]
		[HarmonyPrefix]
		private static bool ConsoleInitPatchPrefix(ConsoleController __instance)
		{
			registerSetConfigCommand("v2u_set_dmgmult_to_enemy", _configDamageMultiplierToEnemy);
			registerSetConfigCommand("v2u_set_dmgmult_to_player", _configDamageMultiplierToPlayer);
			registerSetConfigCommand("v2u_set_spdmult_player_walk", _configSpeedMultiplierPlayerWalk);
			registerSetConfigCommand("v2u_set_spdmult_player_swim", _configSpeedMultiplierPlayerSwim);
			registerSetConfigCommand("v2u_set_vstock_strength", _configVirtualStockStrength);
			registerSetConfigCommand("v2u_set_vstock_shoulder_forward", _configVirtualStockShoulderForward);
			registerSetConfigCommand("v2u_set_vstock_shoulder_right", _configVirtualStockShoulderRight);
			registerSetConfigCommand("v2u_set_vstock_shoulder_up", _configVirtualStockShoulderUp);
			registerSetConfigCommand("v2u_set_vstock_forward_depth", _configVirtualStockForwardDepth);
			registerSetConfigCommand("v2u_set_vstock_shoulder_max_distance", _configVirtualStockShoulderMaxDistance);
			registerSetConfigCommand("v2u_set_Melee_spherecast_radius", _configMeleeHandSphereCastRadius);
			registerSetConfigCommand("v2u_set_Melee_max_distance", _configMeleeMaxDistance);
			registerSetConfigCommand("v2u_set_Melee_min_speed", _configMeleeMinSpeed);
			registerSetConfigCommand("v2u_set_Melee_max_speed", _configMeleeMaxSpeed);
			registerSetConfigCommand("v2u_set_Melee_min_damage", _configMeleeMinDamage);
			registerSetConfigCommand("v2u_set_Melee_max_damage", _configMeleeMaxDamage);
			registerSetConfigCommand("v2u_set_Melee_hit_force_multiplier", _configMeleeHitForceMultiplier);
			return true;
			void registerCommand(string command, CommandHandler handler)
			{
				GetAndInvokePrivateMethod(__instance, "registerCommand", new object[3] { command, handler, "Vertigo 2 Unleashed command" });
			}
			void registerSetConfigCommand(string command, ConfigEntry<float> configEntry)
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Expected O, but got Unknown
				registerCommand(command, (CommandHandler)delegate(string[] args)
				{
					configEntry.Value = float.Parse(args[0]);
					__instance.Log("Set config value to " + args[0], false);
					_configFile.Save();
				});
			}
		}

		private static MeleeResult DoMelee(VertigoHand hand, float hitDistance, Collider hitCollider, Vector3 hitPoint, Vector3 hitNormal, Vector3 velocity, Vector3 hitDir)
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			if (hitDistance > _configMeleeMaxDistance.Value)
			{
				return MeleeResult.Nothing;
			}
			VertigoHittable byCollider = VertigoHittable.GetByCollider(hitCollider);
			if ((Object)(object)byCollider == (Object)null)
			{
				return MeleeResult.Nothing;
			}
			VertigoEntity linkedEntity = byCollider.GetLinkedEntity();
			if ((Object)(object)linkedEntity == (Object)null || linkedEntity is VertigoPlayer || (Object)(object)linkedEntity == (Object)(object)hand.otherHand || (Object)(object)((Component)hitCollider).GetComponentInParent<HeldEquippablePhysical>() != (Object)null || ((Object)(object)hand.attachedInteractable != (Object)null && (Object)(object)((Component)linkedEntity).gameObject == (Object)(object)((Component)hand.attachedInteractable).gameObject) || ((Object)(object)hand.otherHand.attachedInteractable != (Object)null && (Object)(object)((Component)linkedEntity).gameObject == (Object)(object)((Component)hand.otherHand.attachedInteractable).gameObject))
			{
				return MeleeResult.Nothing;
			}
			float num = Mathf.Clamp01(Mathf.InverseLerp(_configMeleeMinSpeed.Value, _configMeleeMaxSpeed.Value, ((Vector3)(ref velocity)).magnitude));
			float num2 = Mathf.Lerp(_configMeleeMinDamage.Value, _configMeleeMaxDamage.Value, num);
			byCollider.Hit(new HitInfo(num2, ((Vector3)(ref velocity)).magnitude * _configMeleeHitForceMultiplier.Value, hitPoint, hitDir, hitNormal, (VertigoEntity)(object)VertigoPlayer.instance, (DamageType)512), false);
			if (((Component)hitCollider).gameObject.layer == 8)
			{
				Enemy val = (Enemy)(object)((linkedEntity is Enemy) ? linkedEntity : null);
				if (val != null)
				{
					BulletHitAudioManager.HitSuccess(val.GetEnemyType(), hitPoint, 1f);
					return MeleeResult.HitEnemy;
				}
			}
			BulletHitAudioManager.HitSurface(hitCollider.sharedMaterial, hitPoint, 1f);
			return MeleeResult.HitSomething;
		}

		private static int GetHandIndex(VertigoHand hand)
		{
			return (!((Object)(object)hand == (Object)(object)VertigoPlayer.instance.LHand)) ? 1 : 0;
		}

		[HarmonyPatch(typeof(HeldEquippablePhysical), "FixedUpdate")]
		[HarmonyPrefix]
		private static bool VertigoWeaponMeleePatchPrefix(HeldEquippablePhysical __instance)
		{
			if (!_configMeleeEnabled.Value)
			{
				return true;
			}
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<MeleeCollisionComponent>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<MeleeCollisionComponent>().Parent = __instance;
				__instance.rigidbody.detectCollisions = true;
			}
			return true;
		}

		[HarmonyPatch(typeof(VertigoCharacterController), "FixedUpdate")]
		[HarmonyPrefix]
		private static bool VertigoPlayerCharacterControllerMeleeCooldownPatchPrefix()
		{
			if (!_configMeleeEnabled.Value)
			{
				return true;
			}
			int[] array = new int[2] { 0, 1 };
			foreach (int num in array)
			{
				ref float reference = ref MeleeCooldownPerHand[num];
				reference -= Time.deltaTime;
				if (reference <= 0f)
				{
					reference = 0f;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(VertigoHand), "FixedUpdate")]
		[HarmonyPrefix]
		private static bool VertigoHandMeleePatchPrefix(VertigoHand __instance)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (!_configMeleeEnabled.Value)
			{
				return true;
			}
			ref float reference = ref MeleeCooldownPerHand[GetHandIndex(__instance)];
			if (!(reference > 0f))
			{
				Vector3 velocity = __instance.velocity;
				if (!(((Vector3)(ref velocity)).magnitude < _configMeleeMinSpeed.Value))
				{
					RaycastHit[] array = Physics.SphereCastAll(((Component)__instance).transform.position, _configMeleeHandSphereCastRadius.Value, ((Component)__instance).transform.forward, _configMeleeMaxDistance.Value, -1);
					RaycastHit[] array2 = array;
					for (int i = 0; i < array2.Length; i++)
					{
						RaycastHit val = array2[i];
						float distance = ((RaycastHit)(ref val)).distance;
						Collider collider = ((RaycastHit)(ref val)).collider;
						Vector3 point = ((RaycastHit)(ref val)).point;
						Vector3 normal = ((RaycastHit)(ref val)).normal;
						Vector3 velocity2 = __instance.velocity;
						velocity = __instance.velocity;
						if (DoMelee(__instance, distance, collider, point, normal, velocity2, -((Vector3)(ref velocity)).normalized) != 0)
						{
							reference = 0.2f;
						}
					}
					return true;
				}
			}
			return true;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Vertigo2Unleashed";

		public const string PLUGIN_NAME = "Vertigo2Unleashed";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}