Decompiled source of SkineticMod H3VR v1.0.0

H3VR_SkineticMod.dll

Decompiled a month ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Skinetic;
using SkineticMod_H3VR;
using SkineticMod_H3VR.Properties;
using SkineticMod_H3VR.Types;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("H3VR_SkineticMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fc8d9a62ab823fdd7c884ac3e0c4fcbb131e9037")]
[assembly: AssemblyProduct("H3VR_SkineticMod")]
[assembly: AssemblyTitle("H3VR_SkineticMod")]
[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 Skinetic
{
	[Flags]
	public enum Patterns : long
	{
		None = 0L,
		Recoil_Pistol = 2L,
		Recoil_Shotgun = 4L,
		Recoil_TheOG = 8L,
		Recoil_Rifle = 0x10L,
		Recoil_BigRifle = 0x20L,
		Recoil_Launcher = 0x40L,
		Recoil_Missile = 0x80L,
		Recoil_Minigun = 0x100L,
		Recoil_Sosiggun = 0x200L,
		EmptyMag = 0x400L,
		BoltSlide = 0x800L,
		BoltLock = 0x1000L,
		HandleSlide = 0x2000L,
		BreachOpen = 0x4000L,
		BreachClose = 0x8000L,
		Safety = 0x10000L,
		FireSelector = 0x20000L,
		Prefire = 0x40000L,
		ChamberRound = 0x80000L,
		EjectRound = 0x100000L,
		LoadMag = 0x200000L,
		EjectMag = 0x400000L,
		LoadClip = 0x800000L,
		EjectClip = 0x1000000L,
		ChamberRounds = 0x2000000L,
		EjectRounds = 0x4000000L,
		SosiggunRattle = 0x8000000L,
		SosiggunReload = 0x10000000L,
		SlotWeapon = 0x20000000L,
		SlotItem = 0x40000000L,
		LockSlot = 0x80000000L,
		MeleeAttack = 0x100000000L,
		GrabItem = 0x200000000L,
		Damage_MeleeBlunt = 0x400000000L,
		Damage_MeleePiercing = 0x800000000L,
		Damage_MeleeCutting = 0x1000000000L,
		Damage_ProjectileBlunt = 0x2000000000L,
		Damage_ProjectilePiercing = 0x4000000000L,
		Damage_Thermal = 0x8000000000L,
		Damage_Chill = 0x10000000000L,
		Damage_Explosion = 0x20000000000L,
		HeartBeat = 0x40000000000L,
		Death = 0x80000000000L,
		EatBangerJunk = 0x100000000000L,
		EatHerb = 0x200000000000L,
		EatMeatCore = 0x400000000000L,
		Vomit = 0x800000000000L,
		MedigunBeam = 0x2000000000000L,
		MedigunUber = 0x4000000000000L,
		RocketJump = 0x8000000000000L,
		Healing = 0x10000000000000L,
		Teleportation = 0x20000000000000L,
		DamageUp = 0x40000000000000L,
		InfiniteAmmo = 0x80000000000000L,
		Invincibility = 0x100000000000000L,
		Ghosted = 0x200000000000000L,
		MuscleMeat = 0x400000000000000L,
		FarOutMeat = 0x800000000000000L,
		SnakeEye = 0x1000000000000000L,
		Blort = 0x2000000000000000L,
		Cyclops = 0x4000000000000000L,
		Light = 0x1000000000000L,
		InvertPowerUp = long.MinValue
	}
	public class SkineticManager
	{
		public static class EffectPriority
		{
			public const int Highest = 1;

			public const int Death = 1;

			public const int Damage = 2;

			public const int Heal = 3;

			public const int QuickBelt = 6;

			public const int Recoil = 4;

			public const int Reload = 4;

			public const int PowerUp = 5;

			public const int EmptyGun = 6;

			public const int RocketJump = 7;

			public const int Vomit = 8;

			public const int Eating = 9;

			public const int MiscInteraction = 10;

			public const int Lowest = 10;
		}

		private ConfigEntry<int> _boostPercent;

		private ConfigEntry<float> _generalVolume;

		private ConfigEntry<int> _serialNumber;

		private SkineticSDK _skineticInstance;

		private Dictionary<string, int> _patternDict = new Dictionary<string, int>();

		private Dictionary<Patterns, int> _patternsIds = new Dictionary<Patterns, int>();

		private string _skineticPatternsFolder = "SkineticPatterns";

		public SkineticManager()
		{
			_boostPercent = Plugin.Conf.Bind<int>("Skinetic", "Boost Percent", 0, "From 0 to 100. Default value is 0%. This setting allows the end user to globally boost the effects played on the vest. At 0%, no boost is applied. From 1 to 100%, each pattern is altered to create a more punchy feel on Skinetic. For this mod, keeping this value below 20% will preserve most of the intended feel of each effect.");
			_generalVolume = Plugin.Conf.Bind<float>("Skinetic", "General Volume", 100f, "Controls the global volume of the patterns (in %). The value can be set from 0 to 250. At 100, the patterns base volume is preserved and rendered as intended. Between 0 and 99, it's attenuated. Between 101 and 250, the volume is increased, which can lead to distortion of the effects and product audible noise.");
			_generalVolume.Value = Mathf.Clamp(_generalVolume.Value, 0f, 250f);
			_serialNumber = Plugin.Conf.Bind<int>("Skinetic", "Serial Number", 0, "Default value is 0. This is the serial number of the Skinetic vest the mod will try to connect to. 0 means the first available Skinetic vest. This setting should only be changed if multiple vests are paired or connected to the PC being used.");
			Plugin.Conf.Save();
			SkineticSDK.SetLogCallback(LocalLogCallback);
			_skineticInstance = new SkineticSDK();
			_skineticInstance.InitInstance();
			_skineticInstance.Exp_EnableLegacyBackend(enable: true);
			if (_boostPercent.Value != 0)
			{
				_skineticInstance.SetGlobalIntensityBoost(_boostPercent.Value);
				Plugin.Log.LogInfo((object)("Boost set to " + _boostPercent.Value + "%."));
			}
			_skineticInstance.Connect(SkineticSDK.OutputType.E_AUTODETECT, (uint)_serialNumber.Value);
			if (_serialNumber.Value != 0)
			{
				Plugin.Log.LogInfo((object)("Try to connect to Skinetic #" + _serialNumber.Value));
			}
			else
			{
				Plugin.Log.LogInfo((object)"Try to connect to first Skinetic device available");
			}
			_skineticInstance.SetConnectionCallback(ConnectionCallback);
			LoadPatterns();
		}

		public void Disconnect()
		{
			_skineticInstance.StopAll();
			_skineticInstance.Disconnect();
			_skineticInstance.DeinitInstance();
		}

		public int Play(Patterns pattern, SkineticSDK.EffectProperties properties)
		{
			properties.volume = Mathf.Clamp(properties.volume * _generalVolume.Value / 100f, 0f, 250f);
			if (_patternsIds.ContainsKey(pattern))
			{
				Plugin.Log.LogInfo((object)("Effect played: " + pattern));
				return _skineticInstance.PlayEffect(_patternsIds[pattern], properties);
			}
			Plugin.Log.LogWarning((object)("Pattern not found: " + pattern));
			return -1;
		}

		public int PlayIfNotPlaying(int effectId, Patterns pattern, SkineticSDK.EffectProperties properties)
		{
			if (_skineticInstance.GetEffectState(effectId) != SkineticSDK.EffectState.E_STOP)
			{
				return effectId;
			}
			properties.volume = Mathf.Clamp(properties.volume * _generalVolume.Value / 100f, 0f, 250f);
			if (_patternsIds.ContainsKey(pattern))
			{
				return _skineticInstance.PlayEffect(_patternsIds[pattern], properties);
			}
			Plugin.Log.LogWarning((object)("Pattern not found: " + pattern));
			return -1;
		}

		public int PlayWithTransform(Patterns pattern, int priority = 5, float height = 0f, float heading = 0f, float tilting = 0f, bool frontBackInversion = false, bool upDownInversion = false, bool rightLeftInversion = false, bool frontBackAddition = false, bool upDownAddition = false, bool rightLeftAddition = false)
		{
			SkineticSDK.EffectProperties properties = InitEffectProperties();
			properties.priority = priority;
			properties.height = height;
			properties.heading = heading;
			properties.tilting = tilting;
			properties.frontBackInversion = frontBackInversion;
			properties.upDownInversion = upDownInversion;
			properties.rightLeftInversion = rightLeftInversion;
			properties.frontBackAddition = frontBackAddition;
			properties.upDownAddition = upDownAddition;
			properties.rightLeftAddition = rightLeftAddition;
			return Play(pattern, properties);
		}

		public static SkineticSDK.EffectProperties InitEffectProperties(int priority = 5, float volume = 100f, float speed = 1f, int repeatCount = 1, float repeatDelay = 0f, float playAtTime = 0f, float maxDuration = 0f, int effectBoost = 0, bool overridePatternBoost = false, float height = 0f, float heading = 0f, float tilting = 0f, bool frontBackInversion = false, bool upDownInversion = false, bool rightLeftInversion = false, bool frontBackAddition = false, bool upDownAddition = false, bool rightLeftAddition = false)
		{
			return new SkineticSDK.EffectProperties(priority, volume, speed, repeatCount, repeatDelay, playAtTime, maxDuration, effectBoost, overridePatternBoost, height, heading, tilting, frontBackInversion, upDownInversion, rightLeftInversion, frontBackAddition, upDownAddition, rightLeftAddition);
		}

		public void Stop(int effectID, float fadeOut)
		{
			_skineticInstance.StopEffect(effectID, fadeOut);
		}

		public void StopAndReset(ref int effectID, float fadeOut)
		{
			_skineticInstance.StopEffect(effectID, fadeOut);
			effectID = -1;
		}

		public SkineticSDK.EffectState getEffectState(int effectID)
		{
			return _skineticInstance.GetEffectState(effectID);
		}

		public int SetFallbackPattern(Patterns primaryPattern, Patterns fallbackPattern, float timeWindow, int maxAccumulation)
		{
			if (_patternsIds.ContainsKey(primaryPattern) && _patternsIds.ContainsKey(fallbackPattern))
			{
				return _skineticInstance.SetAccumulationWindowToPattern(_patternsIds[primaryPattern], _patternsIds[fallbackPattern], timeWindow, maxAccumulation);
			}
			Plugin.Log.LogWarning((object)("One or more pattern not found: " + primaryPattern.ToString() + " / " + fallbackPattern));
			return -1;
		}

		public int EraseFallbackPattern(Patterns primaryPattern)
		{
			if (_patternsIds.ContainsKey(primaryPattern))
			{
				return _skineticInstance.EraseAccumulationWindowToPattern(_patternsIds[primaryPattern]);
			}
			Plugin.Log.LogWarning((object)("Pattern not found: " + primaryPattern));
			return -1;
		}

		private void LoadPatterns()
		{
			string text = Directory.GetCurrentDirectory() + "\\" + _skineticPatternsFolder;
			if (!Directory.Exists(text))
			{
				Plugin.Log.LogInfo((object)("Skinetic patterns folder not found. Attempt to create folder and patterns at '" + text + "'"));
				CreatePatternFiles(text);
			}
			LoadPattern(Patterns.Recoil_BigRifle, "Recoil_BigRifle");
			LoadPattern(Patterns.Recoil_Launcher, "Recoil_Launcher");
			LoadPattern(Patterns.Recoil_Launcher | Patterns.Light, "Recoil_LauncherLight");
			LoadPattern(Patterns.Recoil_Pistol, "Recoil_Pistol");
			LoadPattern(Patterns.Recoil_Pistol | Patterns.Light, "Recoil_PistolLight");
			LoadPattern(Patterns.Recoil_Rifle, "Recoil_Rifle");
			LoadPattern(Patterns.Recoil_Shotgun, "Recoil_Shotgun");
			LoadPattern(Patterns.Recoil_Shotgun | Patterns.Light, "Recoil_ShotgunLight");
			LoadPattern(Patterns.Recoil_TheOG, "Recoil_TheOG");
			LoadPattern(Patterns.Recoil_Missile, "Recoil_Missile");
			LoadPattern(Patterns.Recoil_Minigun, "Recoil_Minigun");
			LoadPattern(Patterns.Recoil_Sosiggun, "Recoil_Sosiggun");
			LoadPattern(Patterns.EmptyMag, "Empty");
			LoadPattern(Patterns.BoltSlide, "BoltSlide");
			LoadPattern(Patterns.BoltLock, "BoltLock");
			LoadPattern(Patterns.HandleSlide, "HandleSlide");
			LoadPattern(Patterns.BreachOpen, "BreachOpen");
			LoadPattern(Patterns.BreachOpen | Patterns.Light, "BreachOpenLight");
			LoadPattern(Patterns.BreachClose, "BreachClose");
			LoadPattern(Patterns.BreachClose | Patterns.Light, "BreachCloseLight");
			LoadPattern(Patterns.Safety, "Safety");
			LoadPattern(Patterns.FireSelector, "FireSelector");
			LoadPattern(Patterns.Prefire, "Prefire");
			LoadPattern(Patterns.ChamberRound, "ChamberRound");
			LoadPattern(Patterns.EjectRound, "EjectRound");
			LoadPattern(Patterns.LoadMag, "LoadMag");
			LoadPattern(Patterns.EjectMag, "EjectMag");
			LoadPattern(Patterns.LoadClip, "LoadClip");
			LoadPattern(Patterns.EjectClip, "EjectClip");
			LoadPattern(Patterns.ChamberRounds, "ChamberRounds");
			LoadPattern(Patterns.EjectRounds, "EjectRounds");
			LoadPattern(Patterns.SosiggunRattle, "SosiggunRattle");
			LoadPattern(Patterns.SosiggunReload, "SosiggunReload");
			LoadPattern(Patterns.SlotWeapon, "SlotWeapon");
			LoadPattern(Patterns.SlotItem, "SlotItem");
			LoadPattern(Patterns.LockSlot, "LockSlot");
			LoadPattern(Patterns.MeleeAttack, "MeleeAttack");
			LoadPattern(Patterns.GrabItem, "GrabItem");
			LoadPattern(Patterns.HeartBeat, "HeartBeat");
			LoadPattern(Patterns.Death, "Death");
			LoadPattern(Patterns.Damage_MeleeBlunt, "Damage_MeleeBlunt");
			LoadPattern(Patterns.Damage_MeleePiercing, "Damage_MeleePiercing");
			LoadPattern(Patterns.Damage_MeleeCutting, "Damage_MeleeCutting");
			LoadPattern(Patterns.Damage_ProjectileBlunt, "Damage_ProjectileBlunt");
			LoadPattern(Patterns.Damage_ProjectilePiercing, "Damage_ProjectilePiercing");
			LoadPattern(Patterns.Damage_Thermal, "Damage_Thermal");
			LoadPattern(Patterns.Damage_Chill, "Damage_Chill");
			LoadPattern(Patterns.Damage_Explosion, "Damage_Explosion");
			LoadPattern(Patterns.Vomit, "Vomit");
			LoadPattern(Patterns.Vomit | Patterns.Light, "VomitLight");
			LoadPattern(Patterns.EatBangerJunk, "EatBangerJunk");
			LoadPattern(Patterns.EatHerb, "EatHerb");
			LoadPattern(Patterns.EatMeatCore, "EatMeatCore");
			LoadPattern(Patterns.EatMeatCore | Patterns.Light, "EatEdible");
			LoadPattern(Patterns.MedigunUber, "MedigunUber");
			LoadPattern(Patterns.MedigunBeam, "MedigunBeam");
			LoadPattern(Patterns.RocketJump, "RocketJump");
			LoadPattern(Patterns.Healing, "PowerUp_Healing");
			LoadPattern(Patterns.Teleportation, "PowerUp_Teleportation");
			LoadPattern(Patterns.DamageUp, "PowerUp_DamageUp");
			LoadPattern(Patterns.DamageUp | Patterns.InvertPowerUp, "PowerUp_DamageDown");
			LoadPattern(Patterns.InfiniteAmmo, "PowerUp_InfiniteAmmo");
			LoadPattern(Patterns.InfiniteAmmo | Patterns.InvertPowerUp, "PowerUp_AmmoBurn");
			LoadPattern(Patterns.Invincibility, "PowerUp_Invincibility");
			LoadPattern(Patterns.Invincibility | Patterns.InvertPowerUp, "PowerUp_Fragile");
			LoadPattern(Patterns.Ghosted, "PowerUp_Ghost");
			LoadPattern(Patterns.Ghosted | Patterns.InvertPowerUp, "PowerUp_Lighthouse");
			LoadPattern(Patterns.MuscleMeat, "PowerUp_MuscleMeat");
			LoadPattern(Patterns.MuscleMeat | Patterns.InvertPowerUp, "PowerUp_WeakMeat");
			LoadPattern(Patterns.FarOutMeat, "PowerUp_FarOutMeat");
			LoadPattern(Patterns.FarOutMeat | Patterns.InvertPowerUp, "PowerUp_BadTrip");
			LoadPattern(Patterns.SnakeEye, "PowerUp_SnakeEye");
			LoadPattern(Patterns.SnakeEye | Patterns.InvertPowerUp, "PowerUp_MoleEye");
			LoadPattern(Patterns.Blort, "PowerUp_Blort");
			LoadPattern(Patterns.Blort | Patterns.InvertPowerUp, "PowerUp_Dlort");
			LoadPattern(Patterns.Cyclops, "PowerUp_Cyclops");
			LoadPattern(Patterns.Cyclops | Patterns.InvertPowerUp, "PowerUp_Biclops");
		}

		private void LoadPattern(Patterns patternId, string patternFileName)
		{
			string path = _skineticPatternsFolder + "\\" + patternFileName + ".spn";
			if (File.Exists(path))
			{
				string json = File.ReadAllText(path);
				int value = _skineticInstance.LoadPatternFromJSON(json);
				_patternsIds.Add(patternId, value);
				Plugin.Log.LogInfo((object)("[MOD] Skinetic - pattern loaded: " + value + " | " + patternId.ToString() + " | " + patternFileName));
			}
		}

		private void CreatePatternFiles(string patternPath)
		{
			Directory.CreateDirectory(patternPath);
			foreach (DictionaryEntry item in Resources.ResourceManager.GetResourceSet(CultureInfo.InvariantCulture, createIfNotExists: true, tryParents: true))
			{
				File.WriteAllText(patternPath + "\\" + item.Key?.ToString() + ".spn", item.Value.ToString());
			}
		}

		public void ConnectionCallback(SkineticSDK.ConnectionState state, int error, uint serialNumber)
		{
			string text = "Wrong status ";
			if (error < 0)
			{
				text = "Device disconnected: " + SkineticSDK.getSDKError(0);
			}
			switch (state)
			{
			case SkineticSDK.ConnectionState.E_CONNECTED:
				text = "Device Connected = " + serialNumber;
				break;
			case SkineticSDK.ConnectionState.E_DISCONNECTED:
				text = "Device Disconnected";
				break;
			}
			Plugin.Log.LogInfo((object)("[MOD] " + text));
		}

		public void LocalLogCallback(SkineticSDK.LogLevel level, string scope, string message)
		{
			string text = "[SDK] " + scope + ": " + message;
			switch (level)
			{
			case SkineticSDK.LogLevel.E_ERR:
				Plugin.Log.LogError((object)text);
				break;
			case SkineticSDK.LogLevel.E_WARN:
				Plugin.Log.LogWarning((object)text);
				break;
			case SkineticSDK.LogLevel.E_INFO:
				Plugin.Log.LogInfo((object)text);
				break;
			}
		}

		public void InitFallbackPatterns()
		{
			SetFallbackPattern(Patterns.Damage_MeleeBlunt, Patterns.Damage_MeleeBlunt, 0.2f, 3);
			SetFallbackPattern(Patterns.Damage_MeleeCutting, Patterns.Damage_MeleeCutting, 0.2f, 3);
			SetFallbackPattern(Patterns.Damage_MeleePiercing, Patterns.Damage_MeleePiercing, 0.2f, 3);
			SetFallbackPattern(Patterns.Damage_ProjectileBlunt, Patterns.Damage_ProjectileBlunt, 0.2f, 5);
			SetFallbackPattern(Patterns.Damage_ProjectilePiercing, Patterns.Damage_ProjectilePiercing, 0.2f, 5);
			SetFallbackPattern(Patterns.Damage_Thermal, Patterns.Damage_Thermal, 0.2f, 3);
			SetFallbackPattern(Patterns.Damage_Chill, Patterns.Damage_Chill, 0.2f, 3);
			SetFallbackPattern(Patterns.Vomit, Patterns.Vomit | Patterns.Light, 0.9f, 5);
			SetFallbackPattern(Patterns.Recoil_Minigun, Patterns.Recoil_Minigun, 0.05f, 1);
			SetFallbackPattern(Patterns.Recoil_Sosiggun, Patterns.Recoil_Sosiggun, 0.07f, 1);
		}
	}
	public class SkineticSDK
	{
		public enum OutputType
		{
			E_AUTODETECT,
			E_BLUETOOTH,
			E_USB,
			E_WIFI
		}

		public enum DeviceType
		{
			E_UNKNOWN = -1,
			E_SKINETICVEST = 17826049,
			E_HSDMK2 = 19070975
		}

		public enum ConnectionState
		{
			E_RECONNECTING = 3,
			E_DISCONNECTING = 2,
			E_CONNECTING = 1,
			E_CONNECTED = 0,
			E_DISCONNECTED = -1
		}

		public enum EffectState
		{
			E_PLAY = 2,
			E_MUTE = 1,
			E_INITIALIZED = 0,
			E_STOP = -1
		}

		public enum LogLevel
		{
			E_TRACE,
			E_DEBUG,
			E_INFO,
			E_WARN,
			E_ERR
		}

		public struct DeviceInfo
		{
			public OutputType outputType;

			public uint serialNumber;

			public DeviceType deviceType;

			public string deviceVersion;
		}

		[Serializable]
		[StructLayout(LayoutKind.Sequential, Pack = 8)]
		public struct EffectProperties
		{
			public int priority;

			public float volume;

			public float speed;

			public int repeatCount;

			public float repeatDelay;

			public float playAtTime;

			public float maxDuration;

			public int effectBoost;

			[MarshalAs(UnmanagedType.I1)]
			public bool overridePatternBoost;

			public float height;

			public float heading;

			public float tilting;

			[MarshalAs(UnmanagedType.I1)]
			public bool frontBackInversion;

			[MarshalAs(UnmanagedType.I1)]
			public bool upDownInversion;

			[MarshalAs(UnmanagedType.I1)]
			public bool rightLeftInversion;

			[MarshalAs(UnmanagedType.I1)]
			public bool frontBackAddition;

			[MarshalAs(UnmanagedType.I1)]
			public bool upDownAddition;

			[MarshalAs(UnmanagedType.I1)]
			public bool rightLeftAddition;

			public EffectProperties(int priority, float volume, float speed, int repeatCount, float repeatDelay, float playAtTime, float maxDuration, int effectBoost, bool overridePatternBoost, float height, float heading, float tilting, bool frontBackInversion, bool upDownInversion, bool rightLeftInversion, bool frontBackAddition, bool upDownAddition, bool rightLeftAddition)
			{
				this.priority = priority;
				this.volume = volume;
				this.speed = speed;
				this.repeatCount = repeatCount;
				this.repeatDelay = repeatDelay;
				this.playAtTime = playAtTime;
				this.maxDuration = maxDuration;
				this.effectBoost = effectBoost;
				this.overridePatternBoost = overridePatternBoost;
				this.height = height;
				this.heading = heading;
				this.tilting = tilting;
				this.frontBackInversion = frontBackInversion;
				this.upDownInversion = upDownInversion;
				this.rightLeftInversion = rightLeftInversion;
				this.frontBackAddition = frontBackAddition;
				this.upDownAddition = upDownAddition;
				this.rightLeftAddition = rightLeftAddition;
			}
		}

		public enum ExpAudioPreset
		{
			E_CUSTOMDEVICE,
			E_SKINETIC,
			E_HSDMKI,
			E_HSDMKII,
			E_HSD0
		}

		[Serializable]
		public struct ExpAudioSettings
		{
			public string deviceName;

			public string audioAPI;

			public int sampleRate;

			public int bufferSize;

			public int nbStreamChannel;

			public float suggestedLatency;

			public ExpAudioSettings(string deviceName, string audioAPI, int sampleRate, int bufferSize, int nbStreamChannel, float suggestedLatency)
			{
				this.deviceName = deviceName;
				this.audioAPI = audioAPI;
				this.sampleRate = sampleRate;
				this.bufferSize = bufferSize;
				this.nbStreamChannel = nbStreamChannel;
				this.suggestedLatency = suggestedLatency;
			}
		}

		[Serializable]
		[StructLayout(LayoutKind.Sequential, Pack = 8)]
		private struct CDeviceInfo
		{
			public OutputType outputType;

			public uint serialNumber;

			public DeviceType deviceType;

			[MarshalAs(UnmanagedType.LPStr)]
			public string deviceVersion;

			public IntPtr next;
		}

		[Serializable]
		[StructLayout(LayoutKind.Sequential, Pack = 8)]
		private struct CAudioSettings
		{
			[MarshalAs(UnmanagedType.LPStr)]
			public string deviceName;

			[MarshalAs(UnmanagedType.LPStr)]
			public string audioAPI;

			public uint sampleRate;

			public uint bufferSize;

			public int nbStreamChannel;

			public float suggestedLatency;

			public CAudioSettings(ExpAudioSettings audioSettings)
			{
				deviceName = audioSettings.deviceName;
				audioAPI = audioSettings.audioAPI;
				sampleRate = (uint)audioSettings.sampleRate;
				bufferSize = (uint)audioSettings.bufferSize;
				nbStreamChannel = audioSettings.nbStreamChannel;
				suggestedLatency = audioSettings.suggestedLatency;
			}
		}

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void WrappingConnectionCallbackDelegate(ConnectionState status, int error, uint serialNumber, IntPtr userData);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void WrappingLogCallbackDelegate(LogLevel level, [MarshalAs(UnmanagedType.LPStr)] string scope, [MarshalAs(UnmanagedType.LPStr)] string message);

		public delegate void ConnectionCallbackDelegate(ConnectionState state, int error, uint serialNumber);

		public delegate void LogCallbackDelegate(LogLevel level, string scope, string message);

		private const string DLLNAME = "SkineticSDK";

		private int m_instanceID = -1;

		private WrappingConnectionCallbackDelegate m_wrappingConnectionCallbackDelegate = ConnectionClassCallback;

		private ConnectionCallbackDelegate m_connectionDelegate;

		private GCHandle m_handle;

		private static WrappingLogCallbackDelegate m_wrappingLogCallbackDelegate = LogCallback;

		private static LogCallbackDelegate m_logCallback = null;

		public static string getSDKError(int error)
		{
			return error switch
			{
				0 => "No Error", 
				-1 => "Other", 
				-2 => "Invalid parameter", 
				-3 => "No device connected", 
				-4 => "Output is not supported on this platform", 
				-5 => "Invalid Json", 
				-6 => "Device not reachable", 
				-7 => "A priority command is waiting to be processed", 
				-8 => "No available slot on the board", 
				-9 => "No Skinetic instance created", 
				-10 => "Received an invalid message", 
				-11 => "Process is already running", 
				-12 => "A device is already connected", 
				-13 => "The initialization of the device has been interrupted", 
				-14 => "Play was ignored due to overall trigger strategy", 
				-15 => "PortAudio raised an error", 
				-16 => "An error happened with the socket", 
				-17 => "ASH-fx library raised an error", 
				-50 => "Error in JNI layer", 
				-100 => "Core Error: Invalid argument", 
				-99 => "Core Error: Invalid spn", 
				-98 => "Core Error: Invalid layout", 
				-97 => "Core Error: ID already allocated", 
				-96 => "Core Error: Invalid sequence ID", 
				-95 => " Core Error: Invalid pattern ID", 
				-94 => "Core Error: Pattern in use", 
				-93 => "Core Error: Sequence already set to play", 
				-92 => "Core Error: Invalid Operation", 
				_ => "Unknown error", 
			};
		}

		[DllImport("SkineticSDK", EntryPoint = "ski_serialNumberToString")]
		private static extern IntPtr Ski_serialNumberToString(uint serialNumber);

		[DllImport("SkineticSDK", EntryPoint = "ski_createSDKInstance")]
		private static extern int Ski_createSDKInstance([MarshalAs(UnmanagedType.LPStr)] string logFileName);

		[DllImport("SkineticSDK", EntryPoint = "ski_freeSDKInstance")]
		private static extern void Ski_freeSDKInstance(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_scanDevices")]
		private static extern int Ski_scanDevices(int sdk_ID, OutputType outputType);

		[DllImport("SkineticSDK", EntryPoint = "ski_scanStatus")]
		private static extern int Ski_scanStatus(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_getFirstScannedDevice")]
		private static extern IntPtr Ski_getFirstScannedDevice(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_connectDevice")]
		private static extern int Ski_connectDevice(int sdk_ID, OutputType outputType, uint serialNumber);

		[DllImport("SkineticSDK", EntryPoint = "ski_disconnectDevice")]
		private static extern int Ski_disconnectDevice(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_connectionStatus")]
		private static extern ConnectionState Ski_connectionStatus(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_setConnectionCallback")]
		private static extern int Ski_setConnectionCallback(int sdk_ID, IntPtr callback, IntPtr userData);

		[DllImport("SkineticSDK", EntryPoint = "ski_getSDKVersion")]
		private static extern IntPtr Ski_getSDKVersion(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_getSkineticSerialNumber")]
		private static extern uint Ski_getSkineticSerialNumber(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_getSkineticSerialNumberAsString")]
		private static extern IntPtr Ski_getSkineticSerialNumberAsString(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_getSkineticVersion")]
		private static extern IntPtr Ski_getSkineticVersion(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_getSkineticType")]
		private static extern DeviceType Ski_getSkineticType(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_getGlobalIntensityBoost")]
		private static extern int Ski_getGlobalIntensityBoost(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_setGlobalIntensityBoost")]
		private static extern int Ski_setGlobalIntensityBoost(int sdk_ID, int globalBoost);

		[DllImport("SkineticSDK", EntryPoint = "ski_loadPatternFromJSON")]
		private static extern int Ski_loadPatternFromJSON(int sdk_ID, [MarshalAs(UnmanagedType.LPStr)] string json);

		[DllImport("SkineticSDK", EntryPoint = "ski_unloadPattern")]
		private static extern int Ski_unloadPattern(int sdk_ID, int patternID);

		[DllImport("SkineticSDK", EntryPoint = "ski_getPatternIntensityBoost")]
		private static extern int Ski_getPatternIntensityBoost(int sdk_ID, int patternID);

		[DllImport("SkineticSDK", EntryPoint = "ski_setAccumulationWindowToPattern")]
		private static extern int Ski_setAccumulationWindowToPattern(int sdk_ID, int mainPatternID, int fallbackPatternID, float timeWindow, int maxAccumulation);

		[DllImport("SkineticSDK", EntryPoint = "ski_eraseAccumulationWindowToPattern")]
		private static extern int Ski_eraseAccumulationWindowToPattern(int sdk_ID, int mainPatternID);

		[DllImport("SkineticSDK", EntryPoint = "ski_playEffect")]
		private static extern int Ski_playEffect(int sdk_ID, int patternID, EffectProperties effectProperties);

		[DllImport("SkineticSDK", EntryPoint = "ski_stopEffect")]
		private static extern int Ski_stopEffect(int sdk_ID, int effectID, float time);

		[DllImport("SkineticSDK", EntryPoint = "ski_effectState")]
		private static extern EffectState Ski_effectState(int sdk_ID, int effectI);

		[DllImport("SkineticSDK", EntryPoint = "ski_pauseAll")]
		private static extern int Ski_pauseAll(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_resumeAll")]
		private static extern int Ski_resumeAll(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_stopAll")]
		private static extern int Ski_stopAll(int sdk_ID);

		[DllImport("SkineticSDK", EntryPoint = "ski_setLogCallback")]
		private static extern int Ski_setLogCallback(IntPtr callback);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_enableLegacyBackend")]
		private static extern int Ski_exp_enableLegacyBackend(int sdk_ID, bool enable);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_connectAsh")]
		private static extern int Ski_exp_connectAsh(int sdk_ID, OutputType outputType, uint serialNumber, [MarshalAs(UnmanagedType.LPStr)] string loopbackInterface);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_connectAudio")]
		private static extern int Ski_exp_connectAudio(int sdk_ID, ExpAudioPreset audioPreset, CAudioSettings audioSettings);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_connectAshAudio")]
		private static extern int Ski_exp_connectAshAudio(int sdk_ID, ExpAudioPreset audioPreset, CAudioSettings audioSettings, [MarshalAs(UnmanagedType.LPStr)] string loopbackInterface);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_setAshVolume")]
		private static extern int Ski_exp_setAshVolume(int sdk_ID, float volume);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_getAshVolume")]
		private static extern float Ski_exp_getAshVolume(int sdk_ID);

		[DllImport("SkineticSDK", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ski_exp_getOutputDevicesNames")]
		private static extern int Ski_exp_getOutputDevicesNames(ref IntPtr devicesNames, ref int nbDevices);

		[DllImport("SkineticSDK", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ski_exp_getLoopbackDevicesNames")]
		private static extern int Ski_exp_getLoopbackDevicesNames(ref IntPtr devicesNames, ref int nbDevices);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_getOutputDeviceAPIs")]
		private static extern int Ski_exp_getOutputDeviceAPIs([MarshalAs(UnmanagedType.LPStr)] string outputName, ref IntPtr apis, ref int nbApis);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_getOutputDeviceInfo")]
		private static extern int Ski_exp_getOutputDeviceInfo([MarshalAs(UnmanagedType.LPStr)] string outputName, [MarshalAs(UnmanagedType.LPStr)] string apiName, ref int max_channels, ref float default_low_latency, ref float default_high_latency);

		[DllImport("SkineticSDK", EntryPoint = "ski_exp_getSupportedStandardSampleRates")]
		private static extern int Ski_exp_getSupportedStandardSampleRates([MarshalAs(UnmanagedType.LPStr)] string outputName, [MarshalAs(UnmanagedType.LPStr)] string api, ref IntPtr sampleRates, ref int nbSampleRates);

		public static void ConnectionClassCallback(ConnectionState status, int error, uint serialNumber, IntPtr userData)
		{
			((SkineticSDK)GCHandle.FromIntPtr(userData).Target).ConnectionInstanceCallback(status, error, serialNumber);
		}

		private void ConnectionInstanceCallback(ConnectionState status, int error, uint serialNumber)
		{
			m_connectionDelegate(status, error, serialNumber);
		}

		public static void LogCallback(LogLevel level, string scope, string message)
		{
			m_logCallback(level, scope, message);
		}

		public static string GetDeviceSerialNumberAsString(uint serialNumber)
		{
			return Marshal.PtrToStringAnsi(Ski_serialNumberToString(serialNumber));
		}

		public void InitInstance()
		{
			if (m_instanceID == -1)
			{
				m_instanceID = Ski_createSDKInstance("");
				m_handle = GCHandle.Alloc(this, GCHandleType.Normal);
			}
		}

		public void DeinitInstance()
		{
			if (m_instanceID != -1)
			{
				Ski_freeSDKInstance(m_instanceID);
				m_instanceID = -1;
				m_handle.Free();
			}
		}

		public int ScanDevices(OutputType output)
		{
			return Ski_scanDevices(m_instanceID, output);
		}

		public int ScanStatus()
		{
			return Ski_scanStatus(m_instanceID);
		}

		public List<DeviceInfo> GetScannedDevices()
		{
			List<DeviceInfo> list = new List<DeviceInfo>();
			IntPtr intPtr = Ski_getFirstScannedDevice(m_instanceID);
			if (intPtr == IntPtr.Zero)
			{
				return list;
			}
			while (intPtr != IntPtr.Zero)
			{
				CDeviceInfo cDeviceInfo = (CDeviceInfo)Marshal.PtrToStructure(intPtr, typeof(CDeviceInfo));
				DeviceInfo item = default(DeviceInfo);
				item.deviceType = cDeviceInfo.deviceType;
				item.deviceVersion = cDeviceInfo.deviceVersion;
				item.serialNumber = cDeviceInfo.serialNumber;
				item.outputType = cDeviceInfo.outputType;
				list.Add(item);
				intPtr = cDeviceInfo.next;
			}
			return list;
		}

		public int Connect(OutputType output, uint serialNumber)
		{
			return Ski_connectDevice(m_instanceID, output, serialNumber);
		}

		public int Disconnect()
		{
			return Ski_disconnectDevice(m_instanceID);
		}

		public ConnectionState ConnectionStatus()
		{
			return Ski_connectionStatus(m_instanceID);
		}

		public int SetConnectionCallback(ConnectionCallbackDelegate callback)
		{
			int num = Ski_setConnectionCallback(m_instanceID, Marshal.GetFunctionPointerForDelegate((Delegate)m_wrappingConnectionCallbackDelegate), GCHandle.ToIntPtr(m_handle));
			if (num == 0)
			{
				m_connectionDelegate = callback;
			}
			return num;
		}

		public static int SetLogCallback(LogCallbackDelegate callback)
		{
			if (Ski_setLogCallback(Marshal.GetFunctionPointerForDelegate((Delegate)m_wrappingLogCallbackDelegate)) == 0)
			{
				m_logCallback = callback;
			}
			return 0;
		}

		public string GetSDKVersion()
		{
			return Marshal.PtrToStringAnsi(Ski_getSDKVersion(m_instanceID));
		}

		public string GetDeviceVersion()
		{
			return Marshal.PtrToStringAnsi(Ski_getSkineticVersion(m_instanceID));
		}

		public uint GetDeviceSerialNumber()
		{
			return Ski_getSkineticSerialNumber(m_instanceID);
		}

		public string GetDeviceSerialNumberAsString()
		{
			return Marshal.PtrToStringAnsi(Ski_getSkineticSerialNumberAsString(m_instanceID));
		}

		public DeviceType GetDeviceType()
		{
			return Ski_getSkineticType(m_instanceID);
		}

		public int GetGlobalIntensityBoost()
		{
			return Ski_getGlobalIntensityBoost(m_instanceID);
		}

		public int SetGlobalIntensityBoost(int globalBoost)
		{
			return Ski_setGlobalIntensityBoost(m_instanceID, globalBoost);
		}

		public int LoadPatternFromJSON(string json)
		{
			return Ski_loadPatternFromJSON(m_instanceID, json);
		}

		public int UnloadPattern(int patternID)
		{
			return Ski_unloadPattern(m_instanceID, patternID);
		}

		public int GetPatternIntensityBoost(int patternID)
		{
			return Ski_getPatternIntensityBoost(m_instanceID, patternID);
		}

		public int SetAccumulationWindowToPattern(int mainPatternID, int fallbackPatternID, float timeWindow, int maxAccumulation)
		{
			return Ski_setAccumulationWindowToPattern(m_instanceID, mainPatternID, fallbackPatternID, timeWindow, maxAccumulation);
		}

		public int EraseAccumulationWindowToPattern(int mainPatternID)
		{
			return Ski_eraseAccumulationWindowToPattern(m_instanceID, mainPatternID);
		}

		public int PlayEffect(int patternID, EffectProperties effectProperties)
		{
			return Ski_playEffect(m_instanceID, patternID, effectProperties);
		}

		public int StopEffect(int effectID, float time)
		{
			return Ski_stopEffect(m_instanceID, effectID, time);
		}

		public EffectState GetEffectState(int effectID)
		{
			return Ski_effectState(m_instanceID, effectID);
		}

		public int PauseAll()
		{
			return Ski_pauseAll(m_instanceID);
		}

		public int ResumeAll()
		{
			return Ski_resumeAll(m_instanceID);
		}

		public int StopAll()
		{
			return Ski_stopAll(m_instanceID);
		}

		public void Exp_EnableLegacyBackend(bool enable)
		{
			Ski_exp_enableLegacyBackend(m_instanceID, enable);
		}

		public int Exp_ConnectAsh(OutputType output, uint serialNumber, string loopbackInterface)
		{
			return Ski_exp_connectAsh(m_instanceID, output, serialNumber, loopbackInterface);
		}

		public int Exp_ConnectAudio(ExpAudioPreset audioPreset, ExpAudioSettings audioSettings)
		{
			return Ski_exp_connectAudio(audioSettings: new CAudioSettings(audioSettings), sdk_ID: m_instanceID, audioPreset: audioPreset);
		}

		public int Exp_ConnectAshAudio(ExpAudioPreset audioPreset, ExpAudioSettings audioSettings, string loopbackInterface)
		{
			return Ski_exp_connectAshAudio(audioSettings: new CAudioSettings(audioSettings), sdk_ID: m_instanceID, audioPreset: audioPreset, loopbackInterface: loopbackInterface);
		}

		public int Exp_SetAshVolume(float volume)
		{
			return Ski_exp_setAshVolume(m_instanceID, volume);
		}

		public float Exp_GetAshVolume()
		{
			return Ski_exp_getAshVolume(m_instanceID);
		}

		public static string[] Exp_GetOutputDevicesNames()
		{
			string[] result = new string[0];
			int nbDevices = 0;
			IntPtr devicesNames = IntPtr.Zero;
			if (Ski_exp_getOutputDevicesNames(ref devicesNames, ref nbDevices) < 0)
			{
				return result;
			}
			if (devicesNames == IntPtr.Zero)
			{
				return result;
			}
			IntPtr[] array = new IntPtr[nbDevices];
			Marshal.Copy(devicesNames, array, 0, nbDevices);
			result = new string[nbDevices];
			for (int i = 0; i < nbDevices; i++)
			{
				result[i] = Marshal.PtrToStringAnsi(array[i]);
			}
			return result;
		}

		public static string[] Exp_GetLoopbackDevicesNames()
		{
			string[] result = new string[0];
			int nbDevices = 0;
			IntPtr devicesNames = IntPtr.Zero;
			if (Ski_exp_getLoopbackDevicesNames(ref devicesNames, ref nbDevices) < 0)
			{
				return result;
			}
			if (devicesNames == IntPtr.Zero)
			{
				return result;
			}
			IntPtr[] array = new IntPtr[nbDevices];
			Marshal.Copy(devicesNames, array, 0, nbDevices);
			result = new string[nbDevices];
			for (int i = 0; i < nbDevices; i++)
			{
				result[i] = Marshal.PtrToStringAnsi(array[i]);
			}
			return result;
		}

		public static string[] Exp_GetOutputDeviceAPIs(string outputName)
		{
			string[] array = new string[1] { "any_API" };
			int nbApis = 0;
			IntPtr apis = IntPtr.Zero;
			if (Ski_exp_getOutputDeviceAPIs(outputName, ref apis, ref nbApis) < 0)
			{
				return array;
			}
			if (apis == IntPtr.Zero)
			{
				return array;
			}
			if (nbApis == 0)
			{
				array[0] = "no_API";
				return array;
			}
			IntPtr[] array2 = new IntPtr[nbApis];
			Marshal.Copy(apis, array2, 0, nbApis);
			array = new string[nbApis + 1];
			array[0] = "any_API";
			for (int i = 0; i < nbApis; i++)
			{
				array[i + 1] = Marshal.PtrToStringAnsi(array2[i]);
			}
			return array;
		}

		public static int Exp_GetOutputDeviceInfo(string outputName, string apiName, ref int maxChannels, ref float defaultLowLatency, ref float defaultHighLatency)
		{
			return Ski_exp_getOutputDeviceInfo(outputName, apiName, ref maxChannels, ref defaultLowLatency, ref defaultHighLatency);
		}

		public static int[] Exp_GetSupportedStandardSampleRates(string outputName, string apiName)
		{
			int[] result = new int[0];
			int nbSampleRates = 0;
			IntPtr sampleRates = IntPtr.Zero;
			Ski_exp_getSupportedStandardSampleRates(outputName, apiName, ref sampleRates, ref nbSampleRates);
			if (sampleRates == IntPtr.Zero)
			{
				return result;
			}
			result = new int[nbSampleRates];
			Marshal.Copy(sampleRates, result, 0, nbSampleRates);
			return result;
		}
	}
}
namespace SkineticMod_H3VR
{
	[BepInPlugin("H3VR_SkineticMod", "H3VR_SkineticMod", "1.0.0")]
	[BepInProcess("h3vr.exe")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		public class WeaponRecoil
		{
			public static SkineticSDK.EffectProperties _effectPropertiesMelee = SkineticManager.InitEffectProperties(4);

			public static SkineticSDK.EffectProperties _effectPropertiesGunFired = SkineticManager.InitEffectProperties(4);

			public static int _idFire = -1;

			public static int _idLaserPistol = -1;

			public static int _idFlamethrower = -1;

			private static void VolumeAndSpatializationProcess(FVRViveHand hand, FVRFireArm fireArm)
			{
				_effectPropertiesGunFired.volume = 100f;
				_effectPropertiesGunFired.rightLeftAddition = false;
				if ((Object)(object)((FVRInteractiveObject)fireArm).m_hand == (Object)null)
				{
					Log.LogWarning((object)"[MOD] This weapong is not properly handled. Contact the modding team.");
				}
				else
				{
					_effectPropertiesGunFired.rightLeftInversion = !((FVRInteractiveObject)fireArm).m_hand.IsThisTheRightHand;
				}
				if (fireArm.IsTwoHandStabilized())
				{
					_effectPropertiesGunFired.volume -= 7f;
					_effectPropertiesGunFired.rightLeftAddition = true;
				}
				if (fireArm.IsForegripStabilized())
				{
					_effectPropertiesGunFired.volume -= 7f;
					_effectPropertiesGunFired.rightLeftAddition = true;
				}
				if (fireArm.IsShoulderStabilized())
				{
					_effectPropertiesGunFired.volume -= 7f;
				}
			}

			[HarmonyPatch(typeof(FVRFireArm), "Fire")]
			[HarmonyPrefix]
			public static void FVRFireArm_Fire(FVRFireArm __instance, FVRFireArmChamber chamber, Transform muzzle, bool doBuzz, float velMult = 1f, float rangeOverride = -1f)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				Patterns effectByRoundType = GunTypes.GetEffectByRoundType(__instance.RoundType);
				VolumeAndSpatializationProcess(((FVRInteractiveObject)__instance).m_hand, __instance);
				Log.LogDebug((object)("[MOD]              RecoilProf: " + ((object)__instance.RecoilProfile)?.ToString() + "\n                                         Pattern: " + effectByRoundType.ToString() + "\n                                         Volume: " + _effectPropertiesGunFired.volume + "\n                                         Round type: " + ((object)(FireArmRoundType)(ref __instance.RoundType)).ToString() + "\n                                         Gun name: " + ((Object)__instance).name + "\n                                         Has stock: " + __instance.HasActiveShoulderStock));
				_idFire = _skineticHandler.Play(effectByRoundType, _effectPropertiesGunFired);
			}

			[HarmonyPatch(typeof(AttachableFirearm), "Fire")]
			[HarmonyPrefix]
			public static void AttachableFirearm_Fire(AttachableFirearm __instance, FVRFireArmChamber chamber, Transform muzzle, bool doBuzz, FVRFireArm fa, float velMult = 1f)
			{
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				Log.LogDebug((object)"[MOD] AttachableFirearm: Fire");
				_effectPropertiesGunFired.volume = 100f;
				_effectPropertiesGunFired.rightLeftAddition = false;
				HandDiscriminationFallback(ref _effectPropertiesGunFired.rightLeftInversion, ref _effectPropertiesGunFired.rightLeftAddition);
				Patterns effectByRoundType = GunTypes.GetEffectByRoundType(__instance.RoundType);
				_idFire = _skineticHandler.Play(effectByRoundType, _effectPropertiesGunFired);
			}

			[HarmonyPatch(typeof(Minigun), "Fire")]
			[HarmonyPrefix]
			public static void Minigun_Fire(Minigun __instance)
			{
				VolumeAndSpatializationProcess(((FVRInteractiveObject)__instance).m_hand, (FVRFireArm)(object)__instance);
				_skineticHandler.Play(Patterns.Recoil_Minigun, _effectPropertiesGunFired);
			}

			[HarmonyPatch(typeof(SosigWeapon), "Recoil")]
			[HarmonyPrefix]
			public static void SosigWeapon_Recoil(SosigWeapon __instance, float recoilMult)
			{
				if (!__instance.IsHeldByBot)
				{
					_effectPropertiesGunFired.volume = 100f;
					_effectPropertiesGunFired.rightLeftAddition = false;
					_effectPropertiesGunFired.rightLeftInversion = false;
					if ((Object)(object)__instance.O != (Object)null && ((FVRInteractiveObject)__instance.O).IsHeld)
					{
						_effectPropertiesGunFired.rightLeftInversion = !((FVRInteractiveObject)__instance.O).m_hand.IsThisTheRightHand;
						_skineticHandler.Play(Patterns.Recoil_Sosiggun, _effectPropertiesGunFired);
					}
				}
			}

			[HarmonyPatch(typeof(HCB), "ReleaseSled")]
			[HarmonyPrefix]
			public static void HCB_ReleaseSled(HCB __instance)
			{
				VolumeAndSpatializationProcess(((FVRInteractiveObject)__instance).m_hand, (FVRFireArm)(object)__instance);
				_skineticHandler.Play(Patterns.Recoil_Launcher | Patterns.Light, _effectPropertiesGunFired);
			}

			[HarmonyPatch(typeof(sblp), "TryToEngageShot")]
			[HarmonyPostfix]
			public static void sblp_TryToEngageShot(sblp __instance)
			{
				//IL_004d: 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_006c: Invalid comparison between Unknown and I4
				if (__instance.m_isShotEngaged)
				{
					if ((Object)(object)((FVRInteractiveObject)__instance).m_hand == (Object)null)
					{
						Log.LogWarning((object)"[MOD] This weapong is not properly handled. Contact the modding team.");
					}
					else
					{
						_effectPropertiesGunFired.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
					}
					FVRFireArmMagazine magazine = ((FVRFireArm)__instance).Magazine;
					sblpCell val = (sblpCell)(object)((magazine is sblpCell) ? magazine : null);
					if ((int)val.PL == 0)
					{
						_effectPropertiesGunFired.volume = 60f;
					}
					else if ((int)val.PL == 1)
					{
						_effectPropertiesGunFired.volume = 80f;
					}
					else
					{
						_effectPropertiesGunFired.volume = 100f;
					}
					_effectPropertiesGunFired.rightLeftAddition = false;
					if (((FVRFireArm)__instance).IsTwoHandStabilized())
					{
						_effectPropertiesGunFired.volume -= 7f;
						_effectPropertiesGunFired.rightLeftAddition = true;
					}
					if (((FVRFireArm)__instance).IsForegripStabilized())
					{
						_effectPropertiesGunFired.volume -= 7f;
						_effectPropertiesGunFired.rightLeftAddition = true;
					}
					_effectPropertiesGunFired.repeatCount = 0;
					_effectPropertiesGunFired.speed = 1.2f;
					_idLaserPistol = _skineticHandler.PlayIfNotPlaying(_idLaserPistol, Patterns.Recoil_Sosiggun, _effectPropertiesGunFired);
					_effectPropertiesGunFired.repeatCount = 1;
					_effectPropertiesGunFired.speed = 1f;
					_effectPropertiesGunFired.volume = 100f;
				}
			}

			[HarmonyPatch(typeof(sblp), "TryToDisengageShot")]
			[HarmonyPostfix]
			public static void sblp_TryToDisengageShot(sblp __instance)
			{
				if (!__instance.m_isShotEngaged)
				{
					_skineticHandler.StopAndReset(ref _idLaserPistol, 0.05f);
				}
			}

			[HarmonyPatch(typeof(SM), "PlayCoreSound")]
			[HarmonyPostfix]
			public static void SM_PlayCoreSound(SM __instance)
			{
				StackFrame[] frames = new StackTrace().GetFrames();
				if (frames.Length > 2)
				{
					MethodBase method = frames[2].GetMethod();
					if (method.Name == "UpdateControls" && method.DeclaringType.Name == "FlameThrower")
					{
						HandDiscriminationFallback(ref _effectPropertiesGunFired.rightLeftInversion, ref _effectPropertiesGunFired.rightLeftAddition);
						_effectPropertiesGunFired.speed = 1.3f;
						_effectPropertiesGunFired.repeatCount = 0;
						_idFlamethrower = _skineticHandler.PlayIfNotPlaying(_idFlamethrower, Patterns.Recoil_Launcher, _effectPropertiesGunFired);
						_effectPropertiesGunFired.speed = 1f;
						_effectPropertiesGunFired.repeatCount = 1;
						_effectPropertiesGunFired.rightLeftAddition = false;
						Log.LogDebug((object)"[MOD] Start Flamethrower");
					}
					else if (method.Name == "StopFiring" && method.DeclaringType.Name == "FlameThrower")
					{
						Log.LogDebug((object)"[MOD] Stop Flamethrower");
						_skineticHandler.StopAndReset(ref _idFlamethrower, 0.05f);
					}
				}
				else
				{
					Log.LogDebug((object)"[MOD] Unable to determine the caller.");
				}
			}

			[HarmonyPatch(typeof(FlameThrower), "AirBlast")]
			[HarmonyPostfix]
			public static void FlameThrower_AirBlast(FlameThrower __instance)
			{
				Log.LogDebug((object)"[MOD] FlameThrower: AirBlast");
				VolumeAndSpatializationProcess(((FVRInteractiveObject)__instance).m_hand, (FVRFireArm)(object)__instance);
				_effectPropertiesGunFired.upDownAddition = true;
				_effectPropertiesGunFired.frontBackAddition = true;
				_effectPropertiesGunFired.speed = 0.85f;
				_skineticHandler.Play(Patterns.Recoil_Launcher, _effectPropertiesGunFired);
				_effectPropertiesGunFired.upDownAddition = false;
				_effectPropertiesGunFired.frontBackAddition = false;
				_effectPropertiesGunFired.speed = 1f;
			}

			[HarmonyPatch(typeof(FlintlockWeapon), "Fire")]
			[HarmonyPrefix]
			public static void FlintlockWeapon_Fire(FlintlockWeapon __instance)
			{
				if (!((double)__instance.FireRefire < 0.10000000149011612))
				{
					VolumeAndSpatializationProcess(((FVRInteractiveObject)__instance).m_hand, (FVRFireArm)(object)__instance);
					Log.LogDebug((object)"[MOD] FlintlockWeapon: Fire");
					_skineticHandler.Play(Patterns.Recoil_Rifle, _effectPropertiesGunFired);
				}
			}

			[HarmonyPatch(typeof(FlintlockWeapon), "Blowup")]
			[HarmonyPrefix]
			public static void FlintlockWeapon_Blowup(FlintlockWeapon __instance)
			{
				if (!__instance.m_isDestroyed)
				{
					Log.LogDebug((object)"[MOD] FlintlockWeapon: Blowup");
					_skineticHandler.Play(Patterns.Damage_Explosion, _effectPropertiesGunFired);
				}
			}

			[HarmonyPatch(typeof(GBeamer), "ShuntHeldObject")]
			[HarmonyPrefix]
			public static void GBeamer_ShuntHeldObject(GBeamer __instance)
			{
				if (__instance.m_hasObject)
				{
					Log.LogDebug((object)"[MOD] GBeamer: ShuntHeldObject");
					VolumeAndSpatializationProcess(((FVRInteractiveObject)__instance).m_hand, (FVRFireArm)(object)__instance);
					_skineticHandler.Play(Patterns.Recoil_Launcher, _effectPropertiesGunFired);
				}
			}

			[HarmonyPatch(typeof(GBeamer), "WideShunt")]
			[HarmonyPrefix]
			public static void GBeamer_WideShunt(GBeamer __instance)
			{
				Log.LogDebug((object)"[MOD] GBeamer: WideShunt");
				VolumeAndSpatializationProcess(((FVRInteractiveObject)__instance).m_hand, (FVRFireArm)(object)__instance);
				_skineticHandler.Play(Patterns.Recoil_Launcher, _effectPropertiesGunFired);
			}
		}

		[HarmonyPatch]
		public class WeaponReload
		{
			private static int _idLoadMag = -1;

			private static int _idEjectMag = -1;

			private static int _idLoadClip = -1;

			private static int _idEjectClip = -1;

			private static int _idChamberRound = -1;

			private static int _idEjectRound = -1;

			private static int _idEjectRounds = -1;

			private static int _idBreach = -1;

			private static int _idHandle = -1;

			private static int _idBolt = -1;

			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties();

			private const float rattle_speed_M = 1.6f;

			private const float rattle_speed_m = 0.7f;

			private const float rattle_volume_M = 85f;

			private const float rattle_volume_m = 30f;

			[HarmonyPatch(typeof(FVRFireArm), "LoadMag")]
			[HarmonyPrefix]
			public static void FVRFireArm_LoadMag(FVRFireArm __instance, FVRFireArmMagazine mag)
			{
				Log.LogDebug((object)"[MOD] FVRFireArm: LoadMag");
				Log.LogDebug((object)("      type: " + ((object)__instance).GetType()));
				_properties.priority = 4;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_idLoadMag = _skineticHandler.PlayIfNotPlaying(_idLoadMag, Patterns.LoadMag, _properties);
			}

			[HarmonyPatch(typeof(FVRFireArm), "EjectMag")]
			[HarmonyPrefix]
			public static void FVRFireArm_EjectMag(FVRFireArm __instance)
			{
				Log.LogDebug((object)"[MOD] FVRFireArm: EjectMag");
				_properties.priority = 4;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_idEjectMag = _skineticHandler.PlayIfNotPlaying(_idEjectMag, Patterns.EjectRound, _properties);
			}

			[HarmonyPatch(typeof(FVRFireArm), "LoadClip")]
			[HarmonyPrefix]
			public static void FVRFireArm_LoadClip(FVRFireArm __instance)
			{
				Log.LogDebug((object)"[MOD] FVRFireArm: LoadClip");
				_properties.priority = 4;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_idLoadClip = _skineticHandler.PlayIfNotPlaying(_idLoadClip, Patterns.LoadClip, _properties);
			}

			[HarmonyPatch(typeof(FVRFireArm), "EjectClip")]
			[HarmonyPrefix]
			public static void FVRFireArm_EjectClip(FVRFireArm __instance)
			{
				Log.LogDebug((object)"[MOD] FVRFireArm: EjectClip");
				_properties.priority = 4;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_idEjectClip = _skineticHandler.PlayIfNotPlaying(_idEjectClip, Patterns.EjectClip, _properties);
			}

			[HarmonyPatch(typeof(FVRFireArmClip), "LoadOneRoundFromClipToMag")]
			[HarmonyPrefix]
			public static void FVRFireArmClip_LoadOneRoundFromClipToMag(FVRFireArmClip __instance)
			{
				Log.LogDebug((object)"[MOD] FVRFireArmClip: LoadOneRoundFromClipToMag");
				_properties.priority = 10;
				_properties.rightLeftInversion = !((FVRInteractiveObject)__instance.FireArm).m_hand.IsThisTheRightHand;
				_skineticHandler.Play(Patterns.EjectClip, _properties);
			}

			[HarmonyPatch(typeof(FVRFireArmRound), "Chamber")]
			[HarmonyPrefix]
			public static void FVRFireArmRound_Chamber(FVRFireArmChamber __instance, bool makeChamberingSound)
			{
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Invalid comparison between Unknown and I4
				Log.LogDebug((object)"[MOD] FVRFireArmRound: Chamber");
				_properties.priority = 4;
				if ((Object)(object)__instance.Firearm != (Object)null)
				{
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance.Firearm).m_hand.IsThisTheRightHand;
				}
				else
				{
					FVRViveHand component = ((Component)GM.CurrentPlayerBody.LeftHand).GetComponent<FVRViveHand>();
					_properties.rightLeftInversion = false;
					if ((int)component.m_state == 1 && component.m_currentInteractable is FVRFireArmRound)
					{
						_properties.rightLeftInversion = true;
					}
				}
				_idChamberRound = _skineticHandler.PlayIfNotPlaying(_idChamberRound, Patterns.ChamberRound, _properties);
			}

			[HarmonyPatch(typeof(RevolverCylinder), "LoadFromSpeedLoader")]
			[HarmonyPrefix]
			public static void RevolverCylinder_LoadFromSpeedLoader(RevolverCylinder __instance)
			{
				Log.LogDebug((object)"[MOD] RevolverCylinder: LoadFromSpeedLoader");
				_properties.priority = 4;
				_properties.rightLeftInversion = !((FVRInteractiveObject)__instance.Revolver).m_hand.IsThisTheRightHand;
				_idChamberRound = _skineticHandler.PlayIfNotPlaying(_idChamberRound, Patterns.ChamberRounds, _properties);
			}

			[HarmonyPatch(typeof(FVRFireArmChamber), "EjectRound", new Type[]
			{
				typeof(Vector3),
				typeof(Vector3),
				typeof(Vector3),
				typeof(bool)
			})]
			[HarmonyPrefix]
			public static void FVRFireArmChamber_EjectRound(FVRFireArmChamber __instance, Vector3 EjectionPosition, Vector3 EjectionVelocity, Vector3 EjectionAngularVelocity, bool ForceCaseLessEject)
			{
				Log.LogDebug((object)"[MOD] FVRFireArmChamber: EjectRound");
				if (__instance.Firearm is Derringer)
				{
					_properties.priority = 4;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance.Firearm).m_hand.IsThisTheRightHand;
					_idEjectRounds = _skineticHandler.PlayIfNotPlaying(_idEjectRounds, Patterns.EjectRounds, _properties);
				}
			}

			[HarmonyPatch(typeof(RevolverCylinder), "Eject")]
			[HarmonyPrefix]
			public static void RevolverCylinder_Eject(RevolverCylinder __instance)
			{
				Log.LogDebug((object)"[MOD] RevolverCylinder: Eject ROUNDS");
				_properties.priority = 4;
				_properties.rightLeftInversion = !((FVRInteractiveObject)__instance.Revolver).m_hand.IsThisTheRightHand;
				_idEjectRounds = _skineticHandler.PlayIfNotPlaying(_idEjectRounds, Patterns.EjectRounds, _properties);
			}

			private static void ProcessAudioEvent(FVRViveHand hand, FirearmAudioEventType eType)
			{
				//IL_0079: 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_0151: Expected I4, but got Unknown
				StackFrame[] frames = new StackTrace().GetFrames();
				if ((Object)(object)hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_properties.priority = 4;
				Log.LogDebug((object)("[MOD] PlayAudioEvent: " + ((object)(FirearmAudioEventType)(ref eType)).ToString()));
				switch (eType - 2)
				{
				case 14:
					_properties.priority = 6;
					_skineticHandler.Play(Patterns.EmptyMag, _properties);
					break;
				case 15:
				case 21:
				case 28:
				case 30:
					if (frames.Length > 3)
					{
						MethodBase method = frames[3].GetMethod();
						if ((object)method.DeclaringType == typeof(BreakActionWeapon))
						{
							_skineticHandler.Play(Patterns.BreachOpen, _properties);
							Log.LogDebug((object)"[MOD] BreakActionWeapon");
						}
						else if ((object)method.DeclaringType == typeof(Revolver) || (object)method.DeclaringType == typeof(Flaregun))
						{
							_skineticHandler.Play(Patterns.BreachOpen | Patterns.Light, _properties);
							Log.LogDebug((object)"[MOD] Revolver or Flaregun");
						}
						else if ((object)method.DeclaringType == typeof(Derringer) || (object)method.DeclaringType == typeof(RollingBlock) || (object)method.DeclaringType == typeof(SingleActionRevolver))
						{
							_properties.volume = 90f;
							_skineticHandler.Play(Patterns.BreachOpen | Patterns.Light, _properties);
							_properties.volume = 100f;
							Log.LogDebug((object)"[MOD] Derringer or RollingBlock or SingleActionRevolver");
						}
						else
						{
							_idBreach = _skineticHandler.PlayIfNotPlaying(_idBreach, Patterns.BreachOpen, _properties);
							Log.LogInfo((object)("[MOD] Caller method: " + method.Name));
							Log.LogInfo((object)("[MOD] Caller class: " + method.DeclaringType.Name));
						}
					}
					else
					{
						Log.LogInfo((object)"[MOD] No trace?");
						_idBreach = _skineticHandler.PlayIfNotPlaying(_idBreach, Patterns.BreachOpen, _properties);
					}
					break;
				case 16:
				case 22:
				case 29:
				case 31:
					if (frames.Length > 3)
					{
						MethodBase method2 = frames[3].GetMethod();
						if ((object)method2.DeclaringType == typeof(BreakActionWeapon))
						{
							_skineticHandler.Play(Patterns.BreachClose, _properties);
							Log.LogDebug((object)"[MOD] BreakActionWeapon");
						}
						else if ((object)method2.DeclaringType == typeof(Revolver) || (object)method2.DeclaringType == typeof(Flaregun))
						{
							_skineticHandler.Play(Patterns.BreachClose | Patterns.Light, _properties);
							Log.LogDebug((object)"[MOD] Revolver or Flaregun");
						}
						else if ((object)method2.DeclaringType == typeof(Derringer) || (object)method2.DeclaringType == typeof(RollingBlock) || (object)method2.DeclaringType == typeof(SingleActionRevolver))
						{
							_properties.volume = 90f;
							_skineticHandler.Play(Patterns.BreachClose | Patterns.Light, _properties);
							_properties.volume = 100f;
							Log.LogDebug((object)"[MOD] Derringer or RollingBlock or SingleActionRevolver");
						}
						else
						{
							_idBreach = _skineticHandler.PlayIfNotPlaying(_idBreach, Patterns.BreachClose, _properties);
							Log.LogInfo((object)("[MOD] Caller method: " + method2.Name));
							Log.LogInfo((object)("[MOD] Caller class: " + method2.DeclaringType.Name));
						}
					}
					else
					{
						Log.LogInfo((object)"[MOD] No trace?");
						_idBreach = _skineticHandler.PlayIfNotPlaying(_idBreach, Patterns.BreachClose, _properties);
					}
					break;
				case 12:
					_skineticHandler.Play(Patterns.Safety, _properties);
					break;
				case 13:
					_skineticHandler.Play(Patterns.FireSelector, _properties);
					break;
				case 5:
					if (_skineticHandler.getEffectState(WeaponRecoil._idFire) == SkineticSDK.EffectState.E_STOP)
					{
						_properties.priority = 10;
						_skineticHandler.Play(Patterns.Prefire, _properties);
					}
					break;
				case 0:
				case 1:
				case 6:
				case 49:
					if (_skineticHandler.getEffectState(WeaponRecoil._idFire) == SkineticSDK.EffectState.E_STOP)
					{
						_properties.priority = 10;
						_idBolt = _skineticHandler.PlayIfNotPlaying(_idBolt, Patterns.BoltSlide, _properties);
					}
					break;
				case 2:
				case 20:
					_properties.priority = 10;
					_skineticHandler.Play(Patterns.BoltLock, _properties);
					break;
				case 7:
				case 8:
				case 9:
				case 10:
				case 11:
				case 38:
				case 39:
					if (_skineticHandler.getEffectState(WeaponRecoil._idFire) == SkineticSDK.EffectState.E_STOP)
					{
						_properties.priority = 10;
						_idHandle = _skineticHandler.PlayIfNotPlaying(_idHandle, Patterns.HandleSlide, _properties);
					}
					break;
				case 18:
				case 50:
				case 51:
					if (_skineticHandler.getEffectState(_idChamberRound) == SkineticSDK.EffectState.E_STOP)
					{
						_idLoadMag = _skineticHandler.PlayIfNotPlaying(_idLoadMag, Patterns.LoadMag, _properties);
					}
					break;
				case 19:
					if (_skineticHandler.getEffectState(_idEjectRound) == SkineticSDK.EffectState.E_STOP && _skineticHandler.getEffectState(_idEjectRounds) == SkineticSDK.EffectState.E_STOP)
					{
						_idEjectMag = _skineticHandler.PlayIfNotPlaying(_idEjectMag, Patterns.EjectMag, _properties);
					}
					break;
				case 40:
					_idChamberRound = _skineticHandler.PlayIfNotPlaying(_idChamberRound, Patterns.ChamberRound, _properties);
					break;
				case 26:
					_idChamberRound = _skineticHandler.PlayIfNotPlaying(_idChamberRound, Patterns.ChamberRound, _properties);
					break;
				case 27:
					if (_skineticHandler.getEffectState(WeaponRecoil._idFire) == SkineticSDK.EffectState.E_STOP)
					{
						_idEjectRound = _skineticHandler.PlayIfNotPlaying(_idEjectRound, Patterns.EjectRound, _properties);
					}
					break;
				case 48:
					_properties.priority = 10;
					_skineticHandler.Play(Patterns.GrabItem, _properties);
					break;
				case 3:
				case 4:
				case 17:
				case 23:
				case 24:
				case 25:
				case 32:
				case 33:
				case 34:
				case 35:
				case 36:
				case 37:
				case 41:
				case 42:
				case 43:
				case 44:
				case 45:
				case 46:
				case 47:
					break;
				}
			}

			[HarmonyPatch(typeof(FVRFireArm), "PlayAudioEvent")]
			[HarmonyPrefix]
			public static void FVRFireArm_PlayAudioEvent(FVRFireArm __instance, FirearmAudioEventType eType)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				Log.LogDebug((object)"[MOD] FVRFireArm: PlayAudioEvent");
				ProcessAudioEvent(((FVRInteractiveObject)__instance).m_hand, eType);
			}

			[HarmonyPatch(typeof(AttachableFirearm), "PlayAudioEvent")]
			[HarmonyPrefix]
			public static void AttachableFirearm_PlayAudioEvent(AttachableFirearm __instance, FirearmAudioEventType eType)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				Log.LogDebug((object)"[MOD] AttachableFirearm: PlayAudioEvent");
				ProcessAudioEvent(null, eType);
			}

			[HarmonyPatch(typeof(SosigWeapon), "InstaReload")]
			[HarmonyPostfix]
			public static void SosigWeapon_InstaReload(SosigWeapon __instance)
			{
				SkineticSDK.EffectProperties properties = SkineticManager.InitEffectProperties(4);
				Log.LogDebug((object)"[MOD] SosigWeapon: InstaReload");
				if ((Object)(object)__instance.SosigHoldingThis == (Object)null)
				{
					if ((Object)(object)__instance.O != (Object)null && ((FVRInteractiveObject)__instance.O).IsHeld)
					{
						properties.rightLeftInversion = !((FVRInteractiveObject)__instance.O).m_hand.IsThisTheRightHand;
					}
					_skineticHandler.Play(Patterns.SosiggunReload, properties);
				}
			}

			[HarmonyPatch(typeof(SosigWeaponPlayerInterface), "RattleReloadEvent")]
			[HarmonyPostfix]
			public static void SosigWeaponPlayerInterface_RattleReloadEvent(SosigWeaponPlayerInterface __instance)
			{
				SkineticSDK.EffectProperties properties = SkineticManager.InitEffectProperties(4);
				Log.LogDebug((object)"[MOD] SosigWeaponPlayerInterface: RattleReloadEvent");
				int num = (int)((float)__instance.m_numRattle / (__instance.W.ReloadTime * 5f) * 100f);
				properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				properties.volume = 0.55f * (float)num + 30f;
				properties.speed = 0.009000001f * (float)num + 0.7f;
				_skineticHandler.Play(Patterns.SosiggunRattle, properties);
			}

			[HarmonyPatch(typeof(FlintlockWeapon), "MoveToHalfCock")]
			[HarmonyPrefix]
			public static void FlintlockWeapon_MoveToHalfCock(FlintlockWeapon __instance)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if ((int)__instance.HammerState == 0)
				{
					Log.LogDebug((object)"[MOD] FlintlockWeapon: MoveToHalfCock");
					_properties.priority = 4;
					if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
					{
						_properties.rightLeftAddition = false;
						_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
					}
					else
					{
						HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
					}
					_skineticHandler.Play(Patterns.Prefire, _properties);
				}
			}

			[HarmonyPatch(typeof(FlintlockWeapon), "MoveToFullCock")]
			[HarmonyPrefix]
			public static void FlintlockWeapon_MoveToFullCock(FlintlockWeapon __instance)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				if ((int)__instance.HammerState != 2)
				{
					Log.LogDebug((object)"[MOD] FlintlockWeapon: MoveToFullCock");
					_properties.priority = 4;
					if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
					{
						_properties.rightLeftAddition = false;
						_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
					}
					else
					{
						HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
					}
					_skineticHandler.Play(Patterns.Prefire, _properties);
				}
			}

			[HarmonyPatch(typeof(FlintlockWeapon), "ReleaseHammer")]
			[HarmonyPrefix]
			public static void FlintlockWeapon_ReleaseHammer(FlintlockWeapon __instance)
			{
				Log.LogDebug((object)"[MOD] FlintlockWeapon: ReleaseHammer");
				_properties.priority = 4;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_skineticHandler.Play(Patterns.EmptyMag, _properties);
			}

			[HarmonyPatch(typeof(FlintlockWeapon), "RemoveFlint")]
			[HarmonyPrefix]
			public static void FlintlockWeapon_RemoveFlint(FlintlockWeapon __instance)
			{
				Log.LogDebug((object)"[MOD] FlintlockWeapon: RemoveFlint");
				_properties.priority = 10;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_skineticHandler.Play(Patterns.Safety, _properties);
			}

			[HarmonyPatch(typeof(FlintlockWeapon), "AddFlint")]
			[HarmonyPrefix]
			public static void FlintlockWeapon_AddFlint(FlintlockWeapon __instance)
			{
				Log.LogDebug((object)"[MOD] FlintlockWeapon: AddFlint");
				_properties.priority = 10;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_skineticHandler.Play(Patterns.Safety, _properties);
			}

			[HarmonyPatch(typeof(FlintlockFlintScrew), "ToggleScrewState")]
			[HarmonyPrefix]
			public static void FlintlockFlintScrew_ToggleScrewState(FlintlockFlintScrew __instance)
			{
				Log.LogDebug((object)"[MOD] FlintlockWeapon: AddFlint");
				_properties.priority = 10;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_skineticHandler.Play(Patterns.FireSelector, _properties);
			}

			[HarmonyPatch(typeof(GBeamer), "SetSwitchState")]
			[HarmonyPrefix]
			public static void GBeamer_SetSwitchState(GBeamer __instance)
			{
				Log.LogDebug((object)"[MOD] GBeamer: SetSwitchState");
				_properties.priority = 4;
				if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)
				{
					_properties.rightLeftAddition = false;
					_properties.rightLeftInversion = !((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand;
				}
				else
				{
					HandDiscriminationFallback(ref _properties.rightLeftInversion, ref _properties.rightLeftAddition);
				}
				_skineticHandler.Play(Patterns.Safety, _properties);
			}
		}

		[HarmonyPatch]
		public class OnPlayerDamage
		{
			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties(2);

			private static float hM = -0.135f;

			private static float hm = -0.52f;

			private static float hSM = 0.5f;

			private static float hSm = -0.6f;

			private static void ComputeHeight(float localHeight)
			{
				_properties.height = (hSM - hSm) / (hM - hm) * (localHeight - hm) + hSm;
				Log.LogDebug((object)("[MOD] height: " + _properties.height));
			}

			private static void ComputeHeading(Vector3 u)
			{
				//IL_0005: 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)
				_properties.heading = (0f - Mathf.Atan2(u.x, u.z)) * 57.29578f;
				Log.LogDebug((object)("[MOD] heading: " + _properties.heading));
			}

			private static void ComputeTilting(Vector3 u, Vector3 up)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				_properties.tilting = Mathf.Asin(Vector3.Dot(((Vector3)(ref u)).normalized, up)) * 57.29578f;
				Log.LogDebug((object)("[MOD] tilting: " + _properties.tilting));
			}

			private static Patterns ProcessDamageType(Damage d)
			{
				//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_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected I4, but got Unknown
				DamageClass @class = d.Class;
				Patterns result = (int)@class switch
				{
					1 => (!(d.Dam_Blunt >= d.Dam_Piercing)) ? Patterns.Damage_ProjectilePiercing : Patterns.Damage_ProjectileBlunt, 
					3 => (d.Dam_Blunt >= d.Dam_Piercing && d.Dam_Blunt >= d.Dam_Cutting) ? Patterns.Damage_MeleeBlunt : ((!(d.Dam_Piercing >= d.Dam_Cutting)) ? Patterns.Damage_MeleeCutting : Patterns.Damage_MeleePiercing), 
					0 => (!(d.Dam_Thermal > 0f)) ? ((!(d.Dam_Chilling > 0f)) ? Patterns.Damage_Thermal : Patterns.Damage_Chill) : Patterns.Damage_Thermal, 
					2 => Patterns.Damage_Explosion, 
					4 => Patterns.Damage_ProjectileBlunt, 
					_ => Patterns.Damage_ProjectileBlunt, 
				};
				Log.LogDebug((object)("[MOD] Selected damage pattern: " + result));
				return result;
			}

			[HarmonyPatch(typeof(FVRPlayerHitbox), "Damage", new Type[] { typeof(Damage) })]
			[HarmonyPostfix]
			public static void FVRPlayerHitbox_Damage(FVRPlayerHitbox __instance, Damage d)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Invalid comparison between Unknown and I4
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Invalid comparison between Unknown and I4
				//IL_0084: 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)
				//IL_004f: 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_0068: 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_00cd: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
				if (!__instance.IsActivated || PlayerState.IsPlayerDead)
				{
					return;
				}
				Log.LogDebug((object)"[MOD] FVRPlayerHitbox: Damage");
				if ((int)__instance.Type == 1)
				{
					if ((int)d.Class == 2)
					{
						Vector3 u = ((Component)GM.CurrentPlayerBody.Torso).transform.InverseTransformDirection(-((Vector3)(ref d.strikeDir)).normalized);
						_properties.height = 0f;
						ComputeHeading(u);
						ComputeTilting(u, ((Component)__instance).transform.up);
					}
					else if ((int)d.Class == 0)
					{
						_properties.heading = 0f;
						_properties.tilting = 0f;
						_properties.height = 0f;
					}
					else
					{
						Vector3 val = ((Component)GM.CurrentPlayerBody.Torso).transform.InverseTransformPoint(d.point);
						ComputeHeight(val.y);
						ComputeHeading(val);
						_properties.tilting = 0f;
					}
				}
				else if ((int)__instance.Type == 0)
				{
					_properties.heading = 0f;
					_properties.tilting = 0f;
					_properties.height = 1f;
				}
				else
				{
					Log.LogInfo((object)"[MOD] Damage received to the hands, should not happen.");
				}
				_skineticHandler.Play(ProcessDamageType(d), _properties);
			}
		}

		[HarmonyPatch]
		public class PlayerState
		{
			private static SkineticSDK.EffectProperties _effectPropertiesDeath = SkineticManager.InitEffectProperties(1);

			public static bool IsPlayerDead = false;

			private static bool _hasHeartBeatStarted = false;

			public static float maxHealth = 0f;

			public static float currentHealth = 0f;

			public static int idHeartBeatEffect = -1;

			public static float HandleHP(float health, float nMaxHealth)
			{
				float num = currentHealth;
				currentHealth = health;
				if (nMaxHealth != 0f)
				{
					maxHealth = nMaxHealth;
				}
				if (currentHealth > 0f)
				{
					IsPlayerDead = false;
				}
				if (currentHealth > maxHealth)
				{
					maxHealth = currentHealth;
				}
				bool flag = currentHealth < maxHealth / 3f && currentHealth > 0f;
				if (flag && !_hasHeartBeatStarted)
				{
					StartHeartBeat();
					_hasHeartBeatStarted = true;
				}
				else if (!flag && _hasHeartBeatStarted)
				{
					StopHeartBeat();
					_hasHeartBeatStarted = false;
				}
				return num - currentHealth;
			}

			public static void StartHeartBeat()
			{
				idHeartBeatEffect = _skineticHandler.Play(Patterns.HeartBeat, SkineticManager.InitEffectProperties());
				Log.LogDebug((object)("[MOD] HeartBeat: On, HP: " + currentHealth));
			}

			public static void StopHeartBeat(int fadeOut = 2)
			{
				Log.LogDebug((object)$"[MOD] idHeartBeatEffect: {idHeartBeatEffect}");
				if (idHeartBeatEffect != -1)
				{
					_skineticHandler.StopAndReset(ref idHeartBeatEffect, fadeOut);
					Log.LogDebug((object)("[MOD] HeartBeat: Off, HP: " + currentHealth));
				}
			}

			[HarmonyPatch(typeof(MainMenuScreen), "Start")]
			[HarmonyPostfix]
			public static void MainMenuScreen_Start()
			{
				StopHeartBeat();
				IsPlayerDead = false;
				PowerUps.StopAllPowerUps();
				Log.LogDebug((object)"[MOD] Menu Screen Loaded");
			}

			[HarmonyPatch(typeof(FVRPlayerBody), "Update")]
			[HarmonyPostfix]
			public static void FVRPlayerBody_Update(FVRPlayerBody __instance)
			{
				if (currentHealth != __instance.Health)
				{
					Log.LogDebug((object)("[MOD] HP: " + __instance.Health));
				}
				HandleHP(__instance.Health, __instance.GetMaxHealthPlayerRaw());
			}

			[HarmonyPatch(typeof(FVRSceneSettings), "OnPlayerDeath", new Type[] { typeof(bool) })]
			[HarmonyPrefix]
			public static void FVRSceneSettings_OnPlayerDeath_Prefix()
			{
				IsPlayerDead = true;
				StopHeartBeat();
				PowerUps.StopAllPowerUps();
			}

			[HarmonyPatch(typeof(FVRSceneSettings), "OnPlayerDeath", new Type[] { typeof(bool) })]
			[HarmonyPostfix]
			public static void FVRSceneSettings_OnPlayerDeath_Postfix()
			{
				_skineticHandler.Play(Patterns.Death, _effectPropertiesDeath);
				Log.LogDebug((object)"[MOD] Player Death");
			}

			[HarmonyPatch(typeof(Translocator), "PlayArriveSound")]
			[HarmonyPostfix]
			public static void Translocator_PlayArriveSound()
			{
				_skineticHandler.Play(Patterns.Teleportation, SkineticManager.InitEffectProperties());
				Log.LogDebug((object)"[MOD] Player used Translocator");
			}

			[HarmonyPatch(typeof(Translocator), "InsertCoreToSlot")]
			[HarmonyPostfix]
			public static void Translocator_InsertCoreToSlot()
			{
				SkineticSDK.EffectProperties properties = SkineticManager.InitEffectProperties(4);
				HandDiscriminationFallback(ref properties.rightLeftInversion, ref properties.rightLeftAddition);
				_skineticHandler.Play(Patterns.LoadMag, properties);
				Log.LogDebug((object)"[MOD] Insert Battery in Translocator");
			}
		}

		[HarmonyPatch]
		public class QuickBelt
		{
			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties(6);

			private static float hM = -0.135f;

			private static float hm = -0.52f;

			private static float hSM = 0.5f;

			private static float hSm = -0.6f;

			private static void ComputeSpatialization(Vector3 u)
			{
				//IL_0005: 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_003e: Unknown result type (might be due to invalid IL or missing references)
				_properties.heading = (0f - Mathf.Atan2(u.x, u.z)) * 57.29578f;
				_properties.height = (hSM - hSm) / (hM - hm) * (u.y - hm) + hSm;
				Log.LogDebug((object)("[MOD] heading: " + _properties.heading));
				Log.LogDebug((object)("      height: " + _properties.height));
			}

			[HarmonyPatch(typeof(FVRPhysicalObject), "EndInteractionIntoInventorySlot")]
			[HarmonyPostfix]
			public static void FVRPhysicalObject_EndInteractionIntoInventorySlot(FVRPhysicalObject __instance, FVRViveHand hand, FVRQuickBeltSlot slot)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				ComputeSpatialization(((Component)slot).transform.localPosition);
				if (__instance.Harnessable)
				{
					_skineticHandler.Play(Patterns.SlotWeapon, _properties);
				}
				else if (__instance.SpawnLockable)
				{
					_skineticHandler.Play(Patterns.SlotItem, _properties);
				}
				else
				{
					_skineticHandler.Play(Patterns.SlotItem, _properties);
				}
			}

			[HarmonyPatch(typeof(FVRPhysicalObject), "ToggleQuickbeltState")]
			[HarmonyPostfix]
			public static void FVRPhysicalObject_ToggleQuickbeltState(FVRPhysicalObject __instance)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance.QuickbeltSlot != (Object)null)
				{
					ComputeSpatialization(((Component)__instance.QuickbeltSlot).transform.localPosition);
				}
				else
				{
					ComputeSpatialization(((Component)GM.CurrentPlayerBody.Torso).transform.InverseTransformPoint(((Component)__instance).transform.position));
				}
				_skineticHandler.Play(Patterns.LockSlot, _properties);
			}
		}

		[HarmonyPatch]
		public class GrabEffect
		{
			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties(10);

			[HarmonyPatch(typeof(FVRInteractiveObject), "PlayGrabSound")]
			[HarmonyPostfix]
			public static void FVRInteractiveObject_PlayGrabSound(bool isHard, FVRViveHand hand)
			{
				if (_grabEffectEnable.Value)
				{
					_properties.rightLeftInversion = !hand.IsThisTheRightHand;
					_skineticHandler.Play(Patterns.GrabItem, _properties);
					Log.LogDebug((object)"[MOD] GrabEffect");
				}
			}
		}

		[HarmonyPatch]
		public class PowerUps
		{
			private static int _idQuadDamage = -1;

			private static int _idInfiniteAmmo = -1;

			private static int _idInvincibility = -1;

			private static int _idGhosted = -1;

			private static int _idFarOutMeat = -1;

			private static int _idMuscleMeat = -1;

			private static int _idSnakeEye = -1;

			private static int _idBlort = -1;

			private static int _idRegen = -1;

			private static int _idCyclops = -1;

			private static int _idBadTrip = -1;

			private static int _idMoleEye = -1;

			private static int _idDlort = -1;

			private static int _idHeal = -1;

			private static float _fadeout = 0.05f;

			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties();

			public static void StopAllPowerUps()
			{
				_skineticHandler.StopAndReset(ref _idQuadDamage, _fadeout);
				_skineticHandler.StopAndReset(ref _idInfiniteAmmo, _fadeout);
				_skineticHandler.StopAndReset(ref _idInvincibility, _fadeout);
				_skineticHandler.StopAndReset(ref _idGhosted, _fadeout);
				_skineticHandler.StopAndReset(ref _idFarOutMeat, _fadeout);
				_skineticHandler.StopAndReset(ref _idMuscleMeat, _fadeout);
				_skineticHandler.StopAndReset(ref _idSnakeEye, _fadeout);
				_skineticHandler.StopAndReset(ref _idBlort, _fadeout);
				_skineticHandler.StopAndReset(ref _idRegen, _fadeout);
				_skineticHandler.StopAndReset(ref _idCyclops, _fadeout);
				_skineticHandler.StopAndReset(ref _idBadTrip, _fadeout);
				_skineticHandler.StopAndReset(ref _idMoleEye, _fadeout);
				_skineticHandler.StopAndReset(ref _idDlort, _fadeout);
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRPlayerBody), "ActivatePower")]
			public static void FVRPlayerBody_ActivatePower(FVRPlayerBody __instance, PowerupType type, PowerUpIntensity intensity, PowerUpDuration d, bool isPuke, bool isInverted, float DurationOverride)
			{
				//IL_0021: 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_0076: Expected I4, but got Unknown
				Log.LogDebug((object)("[MOD] ActivatePower: " + ((object)(PowerupType)(ref type)).ToString()));
				switch (type - -2)
				{
				case 2:
					_properties.repeatCount = 1;
					if (!isInverted)
					{
						_skineticHandler.Play(Patterns.Healing, _properties);
						break;
					}
					_properties.frontBackAddition = true;
					_properties.upDownAddition = true;
					_properties.volume = 80f;
					_idHeal = _skineticHandler.PlayIfNotPlaying(_idHeal, Patterns.Damage_Explosion, _properties);
					_properties.volume = 100f;
					_properties.frontBackAddition = false;
					_properties.upDownAddition = false;
					break;
				case 3:
					_properties.repeatCount = 0;
					if (!isInverted)
					{
						_idQuadDamage = _skineticHandler.PlayIfNotPlaying(_idQuadDamage, Patterns.DamageUp, _properties);
					}
					else
					{
						_idQuadDamage = _skineticHandler.PlayIfNotPlaying(_idQuadDamage, Patterns.DamageUp | Patterns.InvertPowerUp, _properties);
					}
					break;
				case 4:
					_properties.repeatCount = 0;
					if (!isInverted)
					{
						_idInfiniteAmmo = _skineticHandler.PlayIfNotPlaying(_idInfiniteAmmo, Patterns.InfiniteAmmo, _properties);
					}
					else
					{
						_idInfiniteAmmo = _skineticHandler.PlayIfNotPlaying(_idInfiniteAmmo, Patterns.InfiniteAmmo | Patterns.InvertPowerUp, _properties);
					}
					break;
				case 5:
					_properties.repeatCount = 0;
					if (!isInverted)
					{
						_idInvincibility = _skineticHandler.PlayIfNotPlaying(_idInvincibility, Patterns.Invincibility, _properties);
					}
					else
					{
						_idInvincibility = _skineticHandler.PlayIfNotPlaying(_idInvincibility, Patterns.Invincibility | Patterns.InvertPowerUp, _properties);
					}
					break;
				case 6:
					_properties.repeatCount = 0;
					if (!isInverted)
					{
						_idGhosted = _skineticHandler.PlayIfNotPlaying(_idGhosted, Patterns.Ghosted, _properties);
					}
					else
					{
						_idGhosted = _skineticHandler.PlayIfNotPlaying(_idGhosted, Patterns.Ghosted | Patterns.InvertPowerUp, _properties);
					}
					break;
				case 8:
					_properties.repeatCount = 0;
					if (!isInverted)
					{
						_idMuscleMeat = _skineticHandler.PlayIfNotPlaying(_idMuscleMeat, Patterns.MuscleMeat, _properties);
					}
					else
					{
						_idMuscleMeat = _skineticHandler.PlayIfNotPlaying(_idMuscleMeat, Patterns.MuscleMeat | Patterns.InvertPowerUp, _properties);
					}
					break;
				case 9:
					_properties.repeatCount = 1;
					_skineticHandler.Play(Patterns.Teleportation, _properties);
					break;
				case 12:
					_properties.repeatCount = 0;
					if (!isInverted)
					{
						_idRegen = _skineticHandler.PlayIfNotPlaying(_idRegen, Patterns.Healing, _properties);
						break;
					}
					_properties.frontBackAddition = true;
					_properties.upDownAddition = true;
					_idRegen = _skineticHandler.PlayIfNotPlaying(_idRegen, Patterns.Damage_MeleePiercing, _properties);
					_properties.frontBackAddition = false;
					_properties.upDownAddition = false;
					break;
				case 13:
					_properties.repeatCount = 0;
					if (!isInverted)
					{
						_idCyclops = _skineticHandler.PlayIfNotPlaying(_idCyclops, Patterns.Cyclops, _properties);
					}
					else
					{
						_idCyclops = _skineticHandler.PlayIfNotPlaying(_idCyclops, Patterns.Cyclops | Patterns.InvertPowerUp, _properties);
					}
					break;
				case 14:
					_properties.repeatCount = 1;
					_skineticHandler.Play(Patterns.Teleportation, _properties);
					break;
				case 15:
				case 16:
				case 17:
				case 18:
					Log.LogDebug((object)"Should not be possible, powerup is for sosig?");
					break;
				default:
					Log.LogError((object)("Case not handled for " + ((object)(PowerupType)(ref type)).ToString()));
					break;
				case 0:
				case 1:
				case 7:
				case 10:
				case 11:
					break;
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRPlayerBody), "DeActivateBuff")]
			public static void FVRPlayerBody_DeActivateBuff(FVRPlayerBody __instance, int i)
			{
				//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_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected I4, but got Unknown
				//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
				PowerupType val = (PowerupType)i;
				switch (val - 1)
				{
				case 0:
					_skineticHandler.StopAndReset(ref _idQuadDamage, _fadeout);
					return;
				case 1:
					_skineticHandler.StopAndReset(ref _idInfiniteAmmo, _fadeout);
					return;
				case 2:
					_skineticHandler.StopAndReset(ref _idInvincibility, _fadeout);
					return;
				case 3:
					_skineticHandler.StopAndReset(ref _idGhosted, _fadeout);
					return;
				case 5:
					_skineticHandler.StopAndReset(ref _idMuscleMeat, _fadeout);
					return;
				case 9:
					_skineticHandler.StopAndReset(ref _idRegen, _fadeout);
					return;
				case 10:
					_skineticHandler.StopAndReset(ref _idCyclops, _fadeout);
					return;
				case 4:
				case 7:
				case 8:
					return;
				}
				ManualLogSource log = Log;
				PowerupType val2 = (PowerupType)i;
				log.LogError((object)("Case not handled for " + ((object)(PowerupType)(ref val2)).ToString()));
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRPlayerBody), "DeActivateDeBuff")]
			public static void FVRPlayerBody_DeActivateDeBuff(FVRPlayerBody __instance, int i)
			{
				//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_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected I4, but got Unknown
				//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
				PowerupType val = (PowerupType)i;
				switch (val - 1)
				{
				case 0:
					_skineticHandler.StopAndReset(ref _idQuadDamage, _fadeout);
					return;
				case 1:
					_skineticHandler.StopAndReset(ref _idInfiniteAmmo, _fadeout);
					return;
				case 2:
					_skineticHandler.StopAndReset(ref _idInvincibility, _fadeout);
					return;
				case 3:
					_skineticHandler.StopAndReset(ref _idGhosted, _fadeout);
					return;
				case 5:
					_skineticHandler.StopAndReset(ref _idMuscleMeat, _fadeout);
					return;
				case 9:
					_skineticHandler.StopAndReset(ref _idRegen, _fadeout);
					return;
				case 10:
					_skineticHandler.StopAndReset(ref _idCyclops, _fadeout);
					return;
				case 4:
				case 7:
				case 8:
					return;
				}
				ManualLogSource log = Log;
				PowerupType val2 = (PowerupType)i;
				log.LogError((object)("Case not handled for " + ((object)(PowerupType)(ref val2)).ToString()));
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRSceneSettings), "SetFarOutMan")]
			public static void FVRSceneSettings_SetFarOutMan(FVRPlayerBody __instance, bool b)
			{
				_properties.repeatCount = 0;
				if (!b)
				{
					_skineticHandler.StopAndReset(ref _idFarOutMeat, _fadeout);
				}
				else
				{
					_idFarOutMeat = _skineticHandler.PlayIfNotPlaying(_idFarOutMeat, Patterns.FarOutMeat, _properties);
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRSceneSettings), "SetBadTrip")]
			public static void FVRSceneSettings_SetBadTrip(FVRPlayerBody __instance, bool b)
			{
				_properties.repeatCount = 0;
				if (!b)
				{
					_skineticHandler.StopAndReset(ref _idBadTrip, _fadeout);
				}
				else
				{
					_idBadTrip = _skineticHandler.PlayIfNotPlaying(_idBadTrip, Patterns.FarOutMeat | Patterns.InvertPowerUp, _properties);
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRSceneSettings), "SetSnakeEyes")]
			public static void FVRSceneSettings_SetSnakeEyes(FVRPlayerBody __instance, bool b)
			{
				_properties.repeatCount = 0;
				if (!b)
				{
					_skineticHandler.StopAndReset(ref _idSnakeEye, _fadeout);
				}
				else
				{
					_idSnakeEye = _skineticHandler.PlayIfNotPlaying(_idSnakeEye, Patterns.SnakeEye, _properties);
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRSceneSettings), "SetMoleEye")]
			public static void FVRSceneSettings_SetMoleEye(FVRPlayerBody __instance, bool b)
			{
				_properties.repeatCount = 0;
				if (!b)
				{
					_skineticHandler.StopAndReset(ref _idMoleEye, _fadeout);
				}
				else
				{
					_idMoleEye = _skineticHandler.PlayIfNotPlaying(_idMoleEye, Patterns.SnakeEye | Patterns.InvertPowerUp, _properties);
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRSceneSettings), "SetBlort")]
			public static void FVRSceneSettings_SetBlort(FVRPlayerBody __instance, bool b)
			{
				_properties.repeatCount = 0;
				if (!b)
				{
					_skineticHandler.StopAndReset(ref _idBlort, _fadeout);
				}
				else
				{
					_idBlort = _skineticHandler.PlayIfNotPlaying(_idBlort, Patterns.Blort, _properties);
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRSceneSettings), "SetDlort")]
			public static void FVRSceneSettings_SetDlort(FVRPlayerBody __instance, bool b)
			{
				_properties.repeatCount = 0;
				if (!b)
				{
					_skineticHandler.StopAndReset(ref _idDlort, _fadeout);
				}
				else
				{
					_idDlort = _skineticHandler.PlayIfNotPlaying(_idDlort, Patterns.Blort | Patterns.InvertPowerUp, _properties);
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(FVRPlayerBody), "ResetHealth")]
			public static void FVRPlayerBody_ResetHealth()
			{
				_properties.repeatCount = 1;
				_idHeal = _skineticHandler.PlayIfNotPlaying(_idHeal, Patterns.Healing, _properties);
				Log.LogDebug((object)"[MOD] Reset Health");
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(HealthPickUp), "Boom")]
			public static void HealthPickUp_Boom()
			{
				_properties.repeatCount = 1;
				_idHeal = _skineticHandler.PlayIfNotPlaying(_idHeal, Patterns.Healing, _properties);
				Log.LogDebug((object)"[MOD] Reset Health");
			}
		}

		[HarmonyPatch]
		public class Vomit
		{
			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties(8);

			[HarmonyPatch(typeof(ZosigGameManager), "VomitBangerJunk")]
			[HarmonyPostfix]
			public static void ZosigGameManager_VomitBangerJunk()
			{
				if (_vomitEnable.Value)
				{
					_skineticHandler.Play(Patterns.Vomit, _properties);
					Log.LogDebug((object)"[MOD] Vomit Banger Junk");
				}
			}

			[HarmonyPatch(typeof(ZosigGameManager), "VomitHerb")]
			[HarmonyPostfix]
			public static void ZosigGameManager_VomitHerb()
			{
				if (_vomitEnable.Value)
				{
					_skineticHandler.Play(Patterns.Vomit, _properties);
					Log.LogDebug((object)"[MOD] Vomit Herb");
				}
			}

			[HarmonyPatch(typeof(ZosigGameManager), "VomitCore")]
			[HarmonyPostfix]
			public static void ZosigGameManager_VomitCore()
			{
				if (_vomitEnable.Value)
				{
					_skineticHandler.Play(Patterns.Vomit, _properties);
					Log.LogDebug((object)"[MOD] Vomit VomitCore");
				}
			}
		}

		[HarmonyPatch]
		public class Eating
		{
			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties(9);

			[HarmonyPatch(typeof(ZosigGameManager), "EatBangerJunk")]
			[HarmonyPostfix]
			public static void ZosigGameManager_EatBangerJunk()
			{
				_skineticHandler.Play(Patterns.EatBangerJunk, _properties);
				Log.LogDebug((object)"[MOD] Eat Banger Junk");
			}

			[HarmonyPatch(typeof(ZosigGameManager), "EatHerb")]
			[HarmonyPostfix]
			public static void ZosigGameManager_EatHerb()
			{
				_skineticHandler.Play(Patterns.EatHerb, _properties);
				Log.LogDebug((object)"[MOD] Eat Herb");
			}

			[HarmonyPatch(typeof(ZosigGameManager), "EatMeatCore")]
			[HarmonyPostfix]
			public static void ZosigGameManager_EatMeatCore()
			{
				_skineticHandler.Play(Patterns.EatMeatCore, _properties);
				Log.LogDebug((object)"[MOD] Eat Meat Core");
			}

			[HarmonyPatch(typeof(SM), "PlayGenericSound")]
			[HarmonyPostfix]
			public static void SM_PlayGenericSound(SM __instance, AudioEvent ClipSet, Vector3 pos)
			{
				StackFrame[] frames = new StackTrace().GetFrames();
				if (frames.Length > 2)
				{
					MethodBase method = frames[2].GetMethod();
					if (method.Name == "UpdateInteraction" && method.DeclaringType.Name == "EdibleThing")
					{
						_skineticHandler.Play(Patterns.EatMeatCore | Patterns.Light, _properties);
						Log.LogDebug((object)"[MOD] Eat Edible");
					}
				}
				else
				{
					Log.LogInfo((object)"[MOD] Unable to determine the caller.");
				}
				Log.LogInfo((object)"[MOD] SM: PlayGenericSound");
			}

			[HarmonyPatch(typeof(RW_Powerup), "PowerUp")]
			[HarmonyPostfix]
			public static void RW_Powerup_PowerUp(SM __instance, FVRViveHand hand)
			{
				_skineticHandler.Play(Patterns.EatMeatCore, _properties);
				Log.LogInfo((object)"[MOD] Eat PowerUp Sausage");
			}
		}

		[HarmonyPatch]
		public class Medigun
		{
			private static int _idBeam;

			private static int _idUber;

			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties(4, 100f, 1f, 0, 0f, 0f, 0f, 0, overridePatternBoost: false, 0f, 0f, 0f, frontBackInversion: false, upDownInversion: false, rightLeftInversion: false, frontBackAddition: false, upDownAddition: false, rightLeftAddition: true);

			[HarmonyPatch(typeof(MF2_Medigun), "EngageBeam")]
			[HarmonyPostfix]
			public static void MF2_Medigun_EngageBeam()
			{
				Log.LogDebug((object)"[MOD] Engage Beam");
				_idBeam = _skineticHandler.Play(Patterns.MedigunBeam, _properties);
			}

			[HarmonyPatch(typeof(MF2_Medigun), "DisEngageBeam")]
			[HarmonyPostfix]
			public static void MF2_Medigun_DisEngageBeam()
			{
				Log.LogDebug((object)"[MOD] DisEngage Beam");
				_skineticHandler.StopAndReset(ref _idBeam, 0.05f);
			}

			[HarmonyPatch(typeof(MF2_Medigun), "EngageUber")]
			[HarmonyPostfix]
			public static void MF2_Medigun_EngageUber()
			{
				Log.LogDebug((object)"[MOD] Engage Uber");
				_idUber = _skineticHandler.Play(Patterns.MedigunUber, _properties);
			}

			[HarmonyPatch(typeof(MF2_Medigun), "DisEngageUber")]
			[HarmonyPostfix]
			public static void MF2_Medigun_DisEngageUber()
			{
				Log.LogDebug((object)"[MOD] DisEngage Uber");
				_skineticHandler.StopAndReset(ref _idUber, 0.05f);
			}
		}

		[HarmonyPatch]
		public class RocketJump
		{
			private static SkineticSDK.EffectProperties _properties = SkineticManager.InitEffectProperties(7);

			private static float _volumeVelocityScale = 10f;

			private static Vector3 _initVelocity;

			[HarmonyPatch(typeof(FVRMovementManager), "RocketJump")]
			[HarmonyPrefix]
			public static void FVRMovementManager_RocketJump_Prefix(FVRMovementManager __instance, Vector3 pos, Vector2 range, float vel)
			{
				//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)
				_initVelocity = __instance.m_smoothLocoVelocity;
			}

			[HarmonyPatch(typeof(FVRMovementManager), "RocketJump")]
			[HarmonyPostfix]
			public static void FVRMovementManager_RocketJump_Postfix(FVRMovementManager __instance, Vector3 pos, Vector2 range, float vel)
			{
				//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)
				//IL_0026: 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_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)
				Vector3 val = __instance.m_smoothLocoVelocity - _initVelocity;
				if (!(((Vector3)(ref val)).magnitude <= 0f))
				{
					val = __instance.m_smoothLocoVelocity - _initVelocity;
					_properties.volume = ((Vector3)(ref val)).magnitude * _volumeVelocityScale;
					_skineticHandler.Play(Patterns.RocketJump, _properties);
					Log.LogDebug((object)"[MOD] Rocket Jump");
				}
			}
		}

		private static SkineticManager _skineticHandler;

		internal static ManualLogSource Log;

		internal static ConfigFile Conf;

		private static ConfigEntry<bool> _vomitEnable;

		private static ConfigEntry<bool> _grabEffectEnable;

		[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		private static extern bool SetDllDirectory(string lpPathName);

		private void Awake()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			SetDllDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
			Log = ((BaseUnityPlugin)this).Logger;
			Conf = ((BaseUnityPlugin)this).Config;
			_grabEffectEnable = Conf.Bind<bool>("Skinet