Decompiled source of Parry v0.3.3

Parry.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using Il2Cpp;
using Il2CppActiveRagdoll;
using Il2CppHurricaneVR.Framework.Core.Utils;
using Il2CppHurricaneVR.Framework.Shared;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using Microsoft.CodeAnalysis;
using ParryMod;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "Parry", "0.3.2", "coope", null)]
[assembly: MelonGame("Kubunautilus", "BrutalistickVR")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Parry")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Parry")]
[assembly: AssemblyTitle("Parry")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ParryMod
{
	public class Core : MelonMod
	{
		private sealed class Hand
		{
			public Transform Root;

			public HVRController Controller;

			public Vector3 LastPos;

			public Vector3 PrevPos;

			public float LastTime;

			public float Speed;

			public bool HasLast;

			public bool NeedsReset;

			public Light Aura;
		}

		private const string RigName = "Hexa4Rig26.10.23";

		private const string SoundFolder = "ParrySounds";

		private const string ParryFile = "Parry.wav";

		private const string ArmFile = "Arm.wav";

		private const string ParryAlias = "parry_snd";

		private const string ArmAlias = "parry_arm_snd";

		private const int ParryVolume = 1000;

		private const int ArmVolume = 450;

		private const float FREEZE_TIME = 0.32f;

		private const float FREEZE_SCALE = 0.01f;

		private const float FLASH_TIME = 0.42f;

		private const float FLASH_ALPHA = 0.5f;

		private const float PUNCH_SPEED = 1.4f;

		private const float HIT_RADIUS = 0.42f;

		private const float PARRY_DAMAGE = 1000f;

		private const float PARRY_FORCE = 210f;

		private const float PARRY_LIFT = 80f;

		private const float PARRY_TORQUE = 45f;

		private HVRHexaBodyInputs _inputs;

		private FistPunchManager _fist;

		private Transform _rig;

		private HVRTimeManager _timeManager;

		private SlowmoManager _slowmo;

		private GameObject _flash;

		private MeshRenderer _flashMr;

		private bool _parrySound;

		private bool _armSound;

		private readonly Hand _left = new Hand();

		private readonly Hand _right = new Hand();

		private bool _armed;

		private bool _busy;

		private bool _wasB;

		private bool _sceneReady;

		private bool _boundLogged;

		private bool _bindWarned;

		private bool _errLogged;

		private bool _flashWarned;

		private bool _freezeActive;

		private float _freezeEnd;

		private float _savedTimeScale = 1f;

		private bool _timeManagerWasEnabled;

		private bool _slowmoWasEnabled;

		private float _nextBind;

		public override void OnInitializeMelon()
		{
			((MelonBase)this).LoggerInstance.Msg("========================================");
			((MelonBase)this).LoggerInstance.Msg("PARRY v0.3.0");
			((MelonBase)this).LoggerInstance.Msg("B: charge the fists. Every punch parries while charged.");
			((MelonBase)this).LoggerInstance.Msg("Press B again to cancel. Vive: trackpad or menu.");
			((MelonBase)this).LoggerInstance.Msg("========================================");
			LoadSounds();
		}

		public override void OnApplicationQuit()
		{
			Mci.Close("parry_snd");
			Mci.Close("parry_arm_snd");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			EndFreeze();
			_inputs = null;
			_fist = null;
			_rig = null;
			_timeManager = null;
			_slowmo = null;
			_left.Root = null;
			_right.Root = null;
			_left.Controller = null;
			_right.Controller = null;
			_left.HasLast = false;
			_right.HasLast = false;
			_left.Speed = 0f;
			_right.Speed = 0f;
			_left.NeedsReset = false;
			_right.NeedsReset = false;
			_left.Aura = null;
			_right.Aura = null;
			_armed = false;
			_busy = false;
			_wasB = false;
			_boundLogged = false;
			_bindWarned = false;
			_flashWarned = false;
			_nextBind = 0f;
			DestroyFlash();
			_sceneReady = sceneName != "MainMenuScene" && sceneName != "IntroScene";
			if (_sceneReady)
			{
				Bind();
			}
		}

		public override void OnUpdate()
		{
			if (!_sceneReady)
			{
				return;
			}
			try
			{
				UpdateFreeze();
				if (((Object)(object)_rig == (Object)null || (Object)(object)_inputs == (Object)null || (Object)(object)_fist == (Object)null || (Object)(object)_left.Root == (Object)null || (Object)(object)_right.Root == (Object)null) && Time.unscaledTime >= _nextBind)
				{
					_nextBind = Time.unscaledTime + 0.5f;
					Bind();
				}
				if (!_boundLogged && !_bindWarned && Time.unscaledTime > 5f)
				{
					_bindWarned = true;
					((MelonBase)this).LoggerInstance.Warning("Parry bind incomplete: rig=" + ((Object)(object)_rig != (Object)null) + " inputs=" + ((Object)(object)_inputs != (Object)null) + " fist=" + ((Object)(object)_fist != (Object)null) + " L=" + ((Object)(object)_left.Root != (Object)null) + " R=" + ((Object)(object)_right.Root != (Object)null));
				}
				UpdateHands();
				if (_busy)
				{
					return;
				}
				bool flag = ReadParryButton();
				if (flag && !_wasB)
				{
					if (_armed)
					{
						Disarm();
					}
					else
					{
						Arm();
					}
				}
				_wasB = flag;
				if (_armed)
				{
					float intensity = 1.2f + 0.35f * Mathf.Sin(Time.unscaledTime * 7f);
					SetAura(_left, intensity);
					SetAura(_right, intensity);
					DetectPunch();
				}
			}
			catch (Exception ex)
			{
				if (!_errLogged)
				{
					_errLogged = true;
					((MelonBase)this).LoggerInstance.Warning("Parry loop error: " + ex.Message);
				}
			}
		}

		public override void OnLateUpdate()
		{
			if (_freezeActive)
			{
				if (Time.unscaledTime >= _freezeEnd)
				{
					EndFreeze();
				}
				else
				{
					Time.timeScale = 0.01f;
				}
			}
		}

		public override void OnGUI()
		{
			if (_freezeActive)
			{
				Time.timeScale = 0.01f;
			}
		}

		private void UpdateFreeze()
		{
			if (_freezeActive)
			{
				if (Time.unscaledTime >= _freezeEnd)
				{
					EndFreeze();
				}
				else
				{
					Time.timeScale = 0.01f;
				}
			}
		}

		private void BeginFreeze()
		{
			float unscaledTime = Time.unscaledTime;
			if (_freezeActive)
			{
				if (unscaledTime + 0.32f > _freezeEnd)
				{
					_freezeEnd = unscaledTime + 0.32f;
				}
				Time.timeScale = 0.01f;
				return;
			}
			_savedTimeScale = ((Time.timeScale > 0.001f) ? Time.timeScale : 1f);
			_freezeActive = true;
			_freezeEnd = unscaledTime + 0.32f;
			if ((Object)(object)_timeManager == (Object)null)
			{
				_timeManager = FindTimeManager();
			}
			if ((Object)(object)_slowmo == (Object)null)
			{
				_slowmo = Object.FindObjectOfType<SlowmoManager>();
			}
			try
			{
				if ((Object)(object)_timeManager != (Object)null)
				{
					_timeManagerWasEnabled = ((Behaviour)_timeManager).enabled;
					((Behaviour)_timeManager).enabled = false;
				}
			}
			catch (Exception)
			{
				_timeManager = null;
			}
			try
			{
				if ((Object)(object)_slowmo != (Object)null)
				{
					_slowmoWasEnabled = ((Behaviour)_slowmo).enabled;
					((Behaviour)_slowmo).enabled = false;
				}
			}
			catch (Exception)
			{
				_slowmo = null;
			}
			Time.timeScale = 0.01f;
			((MelonBase)this).LoggerInstance.Msg("Parry freeze: saved=" + _savedTimeScale.ToString("F2") + " timeMgr=" + ((Object)(object)_timeManager != (Object)null) + " slowmo=" + ((Object)(object)_slowmo != (Object)null));
		}

		private void EndFreeze()
		{
			if (!_freezeActive)
			{
				return;
			}
			_freezeActive = false;
			Time.timeScale = ((_savedTimeScale > 0.001f) ? _savedTimeScale : 1f);
			((MelonBase)this).LoggerInstance.Msg("Parry freeze end: scale=" + Time.timeScale.ToString("F2"));
			try
			{
				if ((Object)(object)_timeManager != (Object)null)
				{
					((Behaviour)_timeManager).enabled = _timeManagerWasEnabled;
				}
			}
			catch (Exception)
			{
			}
			try
			{
				if ((Object)(object)_slowmo != (Object)null)
				{
					((Behaviour)_slowmo).enabled = _slowmoWasEnabled;
				}
			}
			catch (Exception)
			{
			}
		}

		private void Bind()
		{
			if ((Object)(object)_rig == (Object)null)
			{
				GameObject val = GameObject.Find("Hexa4Rig26.10.23");
				if ((Object)(object)val == (Object)null)
				{
					val = FindRigByPrefix();
				}
				if ((Object)(object)val != (Object)null)
				{
					_rig = val.transform;
				}
			}
			if ((Object)(object)_rig == (Object)null)
			{
				return;
			}
			if ((Object)(object)_inputs == (Object)null)
			{
				_inputs = ((Component)_rig).GetComponentInChildren<HVRHexaBodyInputs>();
			}
			if ((Object)(object)_inputs == (Object)null)
			{
				_inputs = Object.FindObjectOfType<HVRHexaBodyInputs>();
			}
			if ((Object)(object)_fist == (Object)null)
			{
				_fist = ((Component)_rig).GetComponentInChildren<FistPunchManager>();
			}
			if ((Object)(object)_fist == (Object)null)
			{
				_fist = Object.FindObjectOfType<FistPunchManager>();
			}
			if ((Object)(object)_inputs != (Object)null)
			{
				_left.Controller = _inputs.LeftController;
				_right.Controller = _inputs.RightController;
			}
			if ((Object)(object)_fist != (Object)null)
			{
				if ((Object)(object)_left.Root == (Object)null && (Object)(object)_fist.lHandForceManager != (Object)null)
				{
					_left.Root = ((Component)_fist.lHandForceManager).transform;
				}
				if ((Object)(object)_left.Root == (Object)null && (Object)(object)_fist.leftHandGrabber != (Object)null)
				{
					_left.Root = ((Component)_fist.leftHandGrabber).transform;
				}
				if ((Object)(object)_left.Root == (Object)null && (Object)(object)_fist.leftHand != (Object)null)
				{
					_left.Root = ((Component)_fist.leftHand).transform;
				}
				if ((Object)(object)_right.Root == (Object)null && (Object)(object)_fist.rHandForceManager != (Object)null)
				{
					_right.Root = ((Component)_fist.rHandForceManager).transform;
				}
				if ((Object)(object)_right.Root == (Object)null && (Object)(object)_fist.rightHandGrabber != (Object)null)
				{
					_right.Root = ((Component)_fist.rightHandGrabber).transform;
				}
				if ((Object)(object)_right.Root == (Object)null && (Object)(object)_fist.rightHand != (Object)null)
				{
					_right.Root = ((Component)_fist.rightHand).transform;
				}
			}
			if ((Object)(object)_left.Root == (Object)null)
			{
				Transform val2 = _rig.Find("Physics LeftHand");
				if ((Object)(object)val2 == (Object)null)
				{
					GameObject obj = GameObject.Find("Physics LeftHand");
					val2 = ((obj != null) ? obj.transform : null);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					_left.Root = val2;
				}
			}
			if ((Object)(object)_right.Root == (Object)null)
			{
				Transform val3 = _rig.Find("Physics RightHand");
				if ((Object)(object)val3 == (Object)null)
				{
					GameObject obj2 = GameObject.Find("Physics RightHand");
					val3 = ((obj2 != null) ? obj2.transform : null);
				}
				if ((Object)(object)val3 != (Object)null)
				{
					_right.Root = val3;
				}
			}
			if ((Object)(object)_left.Root != (Object)null && (Object)(object)_left.Aura == (Object)null)
			{
				_left.Aura = CreateAura(_left.Root);
			}
			if ((Object)(object)_right.Root != (Object)null && (Object)(object)_right.Aura == (Object)null)
			{
				_right.Aura = CreateAura(_right.Root);
			}
			if ((Object)(object)_timeManager == (Object)null)
			{
				_timeManager = FindTimeManager();
			}
			if ((Object)(object)_slowmo == (Object)null)
			{
				_slowmo = Object.FindObjectOfType<SlowmoManager>();
			}
			if (!_boundLogged && (Object)(object)_inputs != (Object)null && (Object)(object)_fist != (Object)null && (Object)(object)_left.Root != (Object)null && (Object)(object)_right.Root != (Object)null)
			{
				_boundLogged = true;
				((MelonBase)this).LoggerInstance.Msg("Parry ready: L='" + ((Object)_left.Root).name + "' R='" + ((Object)_right.Root).name + "' sound=" + _parrySound);
			}
		}

		private void UpdateHands()
		{
			UpdateHand(_left);
			UpdateHand(_right);
		}

		private void UpdateHand(Hand hand)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hand.Root == (Object)null)
			{
				return;
			}
			Vector3 position = hand.Root.position;
			float unscaledTime = Time.unscaledTime;
			if (!hand.HasLast)
			{
				hand.LastPos = position;
				hand.LastTime = unscaledTime;
				hand.HasLast = true;
				hand.Speed = 0f;
				return;
			}
			float num = unscaledTime - hand.LastTime;
			if (!(num <= 0.001f))
			{
				hand.PrevPos = hand.LastPos;
				float num2 = Mathf.Min(num, 0.05f);
				float num3 = Vector3.Distance(position, hand.LastPos) / num2;
				hand.Speed = Mathf.Lerp(hand.Speed, num3, 0.55f);
				hand.LastPos = position;
				hand.LastTime = unscaledTime;
			}
		}

		private bool ReadParryButton()
		{
			if ((Object)(object)_inputs == (Object)null)
			{
				return false;
			}
			return IsParryPressed(_inputs.LeftController) || IsParryPressed(_inputs.RightController);
		}

		private bool IsParryPressed(HVRController controller)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)controller == (Object)null)
			{
				return false;
			}
			try
			{
				if ((int)controller.ControllerType == 3)
				{
					return controller.TrackpadButtonState.Active || controller.MenuButtonState.Active;
				}
				return controller.SecondaryButtonState.Active;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private void Arm()
		{
			_armed = true;
			_left.HasLast = false;
			_right.HasLast = false;
			_left.Speed = 0f;
			_right.Speed = 0f;
			SetAura(_left, 1.4f);
			SetAura(_right, 1.4f);
			TryVibrate(_left.Controller, 0.35f, 0.08f, 1f);
			TryVibrate(_right.Controller, 0.35f, 0.08f, 1f);
			if (_armSound)
			{
				Mci.Play("parry_arm_snd");
			}
			((MelonBase)this).LoggerInstance.Msg("Parry charged until the next enemy hit");
		}

		private void Disarm()
		{
			_armed = false;
			SetAura(_left, 0f);
			SetAura(_right, 0f);
		}

		private void DetectPunch()
		{
			if (!TryHand(_left))
			{
				TryHand(_right);
			}
		}

		private bool TryHand(Hand hand)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hand.Root == (Object)null)
			{
				return false;
			}
			if (hand.Speed < 1.4f)
			{
				hand.NeedsReset = false;
				return false;
			}
			if (hand.NeedsReset)
			{
				return false;
			}
			if (!FindEnemy(hand, out var enemy, out var point))
			{
				return false;
			}
			TriggerParry(hand, enemy, point);
			return true;
		}

		private bool FindEnemy(Hand hand, out StickHealth enemy, out Vector3 point)
		{
			//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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			enemy = null;
			point = hand.Root.position;
			float num = float.MaxValue;
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(hand.Root.position, 0.42f, -1, (QueryTriggerInteraction)1));
			if (array != null)
			{
				foreach (Collider val in array)
				{
					if ((Object)(object)val == (Object)null || IsPlayer(((Component)val).transform))
					{
						continue;
					}
					StickHealth componentInParent = ((Component)val).GetComponentInParent<StickHealth>();
					if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.isDead)
					{
						Vector3 val2 = val.ClosestPoint(hand.Root.position);
						Vector3 val3 = val2 - hand.Root.position;
						float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
						if (!(sqrMagnitude >= num))
						{
							num = sqrMagnitude;
							enemy = componentInParent;
							point = val2;
						}
					}
				}
			}
			if ((Object)(object)enemy != (Object)null)
			{
				return true;
			}
			Vector3 val4 = hand.Root.position - hand.PrevPos;
			float magnitude = ((Vector3)(ref val4)).magnitude;
			if (magnitude < 0.02f)
			{
				return false;
			}
			RaycastHit val5 = default(RaycastHit);
			if (!Physics.SphereCast(hand.PrevPos, 0.09f, val4 / magnitude, ref val5, magnitude, -1, (QueryTriggerInteraction)1))
			{
				return false;
			}
			if ((Object)(object)((RaycastHit)(ref val5)).collider == (Object)null)
			{
				return false;
			}
			if (IsPlayer(((Component)((RaycastHit)(ref val5)).collider).transform))
			{
				return false;
			}
			StickHealth componentInParent2 = ((Component)((RaycastHit)(ref val5)).collider).GetComponentInParent<StickHealth>();
			if ((Object)(object)componentInParent2 == (Object)null || componentInParent2.isDead)
			{
				return false;
			}
			enemy = componentInParent2;
			point = ((RaycastHit)(ref val5)).point;
			return true;
		}

		private bool IsPlayer(Transform t)
		{
			if ((Object)(object)_rig == (Object)null || (Object)(object)t == (Object)null)
			{
				return false;
			}
			return t.IsChildOf(_rig);
		}

		private void TriggerParry(Hand hand, StickHealth enemy, Vector3 point)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			_busy = true;
			_left.NeedsReset = true;
			_right.NeedsReset = true;
			Vector3 center = GetCenter(enemy);
			Vector3 val = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform.position : _rig.position);
			Vector3 push = center - val;
			push.y = 0f;
			Vector3 val2 = hand.Root.position - hand.PrevPos;
			val2.y *= 0.35f;
			push = ((Vector3)(ref push)).normalized + ((Vector3)(ref val2)).normalized * 0.35f;
			if (((Vector3)(ref push)).sqrMagnitude < 0.1f)
			{
				push = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform.forward : hand.Root.forward);
			}
			push = ((Vector3)(ref push)).normalized;
			((MelonBase)this).LoggerInstance.Msg("PARRY hit '" + ((Object)((Component)enemy).gameObject).name + "' speed=" + hand.Speed.ToString("F1"));
			MelonCoroutines.Start(ParryRoutine(enemy, point, push, hand.Controller, hand));
		}

		private IEnumerator ParryRoutine(StickHealth enemy, Vector3 point, Vector3 push, HVRController controller, Hand hand)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (_parrySound)
			{
				Mci.Play("parry_snd");
			}
			TryVibrate(controller, 1f, 0.2f, 1f);
			SpawnImpactLight(point);
			ApplyDamage(enemy, point, push);
			BeginFreeze();
			SetFlash(0.5f);
			float elapsed = 0f;
			while (elapsed < 0.42f)
			{
				elapsed += Time.unscaledDeltaTime;
				float t = Mathf.Clamp01(elapsed / 0.42f);
				SetFlash(0.5f * Mathf.Pow(1f - t, 2.1f));
				yield return null;
			}
			if (_freezeActive && Time.unscaledTime >= _freezeEnd)
			{
				EndFreeze();
			}
			SetFlash(0f);
			if (hand != null)
			{
				hand.HasLast = false;
			}
			_busy = false;
		}

		private Vector3 GetCenter(StickHealth enemy)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemy == (Object)null)
			{
				return Vector3.zero;
			}
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit(((Component)enemy).GetComponentsInChildren<Collider>());
			if (array == null || array.Length == 0)
			{
				return ((Component)enemy).transform.position;
			}
			Bounds bounds = default(Bounds);
			((Bounds)(ref bounds))..ctor(((Component)enemy).transform.position, Vector3.zero);
			bool flag = false;
			foreach (Collider val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					if (!flag)
					{
						bounds = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
			return flag ? ((Bounds)(ref bounds)).center : ((Component)enemy).transform.position;
		}

		private void ApplyDamage(StickHealth enemy, Vector3 point, Vector3 push)
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemy == (Object)null)
			{
				return;
			}
			Type type = ((object)enemy).GetType();
			try
			{
				MethodInfo method = type.GetMethod("HitByBullet");
				if (method != null)
				{
					method.Invoke(enemy, new object[3] { point, 1000f, false });
				}
			}
			catch (Exception)
			{
			}
			try
			{
				MethodInfo method2 = type.GetMethod("ReceivedGeneralDamage");
				if (method2 != null)
				{
					Type nestedType = type.GetNestedType("DamageType");
					object obj = 1;
					if (nestedType != null && nestedType.IsEnum)
					{
						try
						{
							obj = Enum.Parse(nestedType, "Explosion");
						}
						catch (Exception)
						{
							obj = Convert.ChangeType(1, nestedType);
						}
					}
					method2.Invoke(enemy, new object[4] { 500f, obj, "torso", null });
				}
			}
			catch (Exception)
			{
			}
			Rigidbody[] array = Il2CppArrayBase<Rigidbody>.op_Implicit(((Component)enemy).GetComponentsInChildren<Rigidbody>());
			if (array == null)
			{
				return;
			}
			Vector3 val = ((Vector3)(ref push)).normalized * 210f + Vector3.up * 80f;
			foreach (Rigidbody val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.AddForce(val, (ForceMode)1);
					val2.AddTorque(Random.onUnitSphere * 45f, (ForceMode)1);
				}
			}
		}

		private void SpawnImpactLight(Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ParryImpactLight");
			val.transform.position = position;
			Light val2 = val.AddComponent<Light>();
			val2.type = (LightType)2;
			val2.color = new Color(1f, 0.86f, 0.5f);
			val2.range = 7f;
			val2.intensity = 22f;
			val2.shadows = (LightShadows)0;
			MelonCoroutines.Start(FadeLight(val2, val));
		}

		private IEnumerator FadeLight(Light light, GameObject go)
		{
			float elapsed = 0f;
			while (elapsed < 0.35f)
			{
				elapsed += Time.unscaledDeltaTime;
				if ((Object)(object)light != (Object)null)
				{
					light.intensity = 22f * Mathf.Pow(1f - Mathf.Clamp01(elapsed / 0.35f), 2f);
				}
				yield return null;
			}
			if ((Object)(object)go != (Object)null)
			{
				Object.Destroy((Object)(object)go);
			}
		}

		private Light CreateAura(Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ParryAura");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = Vector3.zero;
			Light val2 = val.AddComponent<Light>();
			val2.type = (LightType)2;
			val2.color = Color.white;
			val2.range = 0.65f;
			val2.intensity = 0f;
			val2.shadows = (LightShadows)0;
			return val2;
		}

		private void SetAura(Hand hand, float intensity)
		{
			if (hand != null && !((Object)(object)hand.Aura == (Object)null))
			{
				hand.Aura.intensity = intensity;
			}
		}

		private void TryVibrate(HVRController controller, float amplitude, float duration, float frequency)
		{
			if ((Object)(object)controller == (Object)null)
			{
				return;
			}
			try
			{
				controller.Vibrate(amplitude, duration, frequency);
			}
			catch (Exception)
			{
			}
		}

		private HVRTimeManager FindTimeManager()
		{
			try
			{
				HVRTimeManager instance = HVRTimeManager.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					return instance;
				}
			}
			catch (Exception)
			{
			}
			return Object.FindObjectOfType<HVRTimeManager>();
		}

		private void EnsureFlash()
		{
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			if ((Object)(object)_flash != (Object)null)
			{
				return;
			}
			Camera val = Camera.main;
			if ((Object)(object)val == (Object)null)
			{
				Camera[] array = Il2CppArrayBase<Camera>.op_Implicit(Object.FindObjectsOfType<Camera>());
				foreach (Camera val2 in array)
				{
					if (!((Object)(object)val2 == (Object)null) && ((Behaviour)val2).isActiveAndEnabled && (int)val2.stereoTargetEye != 0)
					{
						val = val2;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				if (!_flashWarned)
				{
					_flashWarned = true;
					((MelonBase)this).LoggerInstance.Warning("Parry flash: no active camera found");
				}
				return;
			}
			Shader val3 = Shader.Find("Sprites/Default");
			if (!((Object)(object)val3 == (Object)null))
			{
				_flash = GameObject.CreatePrimitive((PrimitiveType)5);
				Object.Destroy((Object)(object)_flash.GetComponent<Collider>());
				((Object)_flash).name = "ParryFlash";
				_flashMr = _flash.GetComponent<MeshRenderer>();
				Material val4 = new Material(val3);
				val4.color = new Color(1f, 1f, 1f, 0f);
				((Renderer)_flashMr).material = val4;
				((Renderer)_flashMr).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)_flashMr).receiveShadows = false;
				_flash.transform.SetParent(((Component)val).transform, false);
				_flash.transform.localPosition = new Vector3(0f, 0f, 0.35f);
				_flash.transform.localRotation = Quaternion.identity;
				_flash.transform.localScale = new Vector3(1.8f, 1.8f, 1f);
				((MelonBase)this).LoggerInstance.Msg("Parry flash attached to camera '" + ((Object)val).name + "'");
			}
		}

		private void SetFlash(float alpha)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			EnsureFlash();
			if (!((Object)(object)_flashMr == (Object)null) && !((Object)(object)((Renderer)_flashMr).material == (Object)null))
			{
				Color white = Color.white;
				white.a = Mathf.Clamp01(alpha);
				((Renderer)_flashMr).material.color = white;
			}
		}

		private void DestroyFlash()
		{
			if ((Object)(object)_flash != (Object)null)
			{
				Object.Destroy((Object)(object)_flash);
			}
			_flash = null;
			_flashMr = null;
		}

		private void LoadSounds()
		{
			try
			{
				string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				if (string.IsNullOrEmpty(directoryName))
				{
					directoryName = Path.GetDirectoryName(typeof(Core).Assembly.Location);
				}
				string text = Path.Combine(Path.Combine(directoryName, "ParrySounds"), "Parry.wav");
				string path = Path.Combine(Path.Combine(directoryName, "ParrySounds"), "Arm.wav");
				if (File.Exists(text))
				{
					_parrySound = Mci.Open("parry_snd", text, 1000);
					if (_parrySound)
					{
						((MelonBase)this).LoggerInstance.Msg("Parry sound ready: " + text);
					}
					else
					{
						((MelonBase)this).LoggerInstance.Warning("Parry sound could not be opened: " + text);
					}
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("Parry sound not found: " + text);
				}
				if (File.Exists(path))
				{
					_armSound = Mci.Open("parry_arm_snd", path, 450);
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Parry sound error: " + ex.Message);
			}
		}

		private GameObject FindRigByPrefix()
		{
			Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(Object.FindObjectsOfType<Transform>(false));
			foreach (Transform val in array)
			{
				if (!((Object)(object)val == (Object)null) && ((Object)val).name.StartsWith("Hexa4Rig", StringComparison.OrdinalIgnoreCase))
				{
					return ((Component)val).gameObject;
				}
			}
			return null;
		}
	}
	public static class Mci
	{
		[DllImport("winmm.dll", CharSet = CharSet.Ansi, EntryPoint = "mciSendStringA")]
		private static extern int mciSendString(string cmd, StringBuilder buf, int bufSize, IntPtr cb);

		private static int Send(string cmd)
		{
			StringBuilder stringBuilder = new StringBuilder(256);
			return mciSendString(cmd, stringBuilder, stringBuilder.Capacity, IntPtr.Zero);
		}

		public static bool Open(string alias, string path, int volume)
		{
			Send("close " + alias);
			if (Send("open \"" + path + "\" type waveaudio alias " + alias) != 0)
			{
				return false;
			}
			Send("set " + alias + " time format milliseconds");
			Send("setaudio " + alias + " volume to " + volume);
			Send("set " + alias + " repeat off");
			Send("seek " + alias + " to start");
			return true;
		}

		public static void Play(string alias)
		{
			Send("stop " + alias);
			Send("seek " + alias + " to start");
			Send("play " + alias);
		}

		public static void Close(string alias)
		{
			Send("close " + alias);
		}
	}
}