Decompiled source of KnuckleBlasterParry v4.0.0

KnuckleBlasterParry.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using PluginConfig.API;
using PluginConfig.API.Fields;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("KnucklBlasterParry")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("KnucklBlasterParry")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0047c3d5-622e-4056-975b-9789adcc5271")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("KnuckleblasterParry", "Knuckleblaster Parry", "4.0.0")]
public class Plugin : BaseUnityPlugin
{
	public struct AnimationState
	{
		public bool active;

		public int fullPathHash;

		public float normalizedTime;
	}

	public struct PunchParryState
	{
		public AnimationState animation;

		public int activeFrames;

		public bool keepActiveFrames;
	}

	public struct ScrewdriverPunchState
	{
		public bool active;

		public FistType oldType;

		public AnimationState animation;
	}

	public struct FeedbackerMaskState
	{
		public bool active;

		public EnemyIdentifier eid;

		public string oldHitter;

		public Punch punch;

		public FistType oldPunchType;

		public AnimationState animation;
	}

	public static Plugin Instance;

	public static ManualLogSource Log;

	private Harmony harmony;

	public static BoolField EnableParry;

	public static IntField ParryWindowFrames;

	private static FieldInfo ccField;

	private static FieldInfo camObjField;

	private static FieldInfo ppzField;

	private static FieldInfo boostedProjectileField;

	private static FieldInfo hitCoinField;

	private static FieldInfo enemyIdentifierField;

	private static FieldInfo currentPunchField;

	private static FieldInfo animatorField;

	private static FieldInfo parryZoneProjectilesField;

	private static MethodInfo tryParryProjectileMethod;

	private static MethodInfo parryProjectileMethod;

	private static MethodInfo delayedPunchflectionMethod;

	private static readonly Dictionary<Punch, int> heavyParryFrames = new Dictionary<Punch, int>();

	private static readonly Dictionary<Punch, HashSet<int>> heavyParryTargets = new Dictionary<Punch, HashSet<int>>();

	private void Awake()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("knuckleblasterparry");
		PluginConfigurator val = PluginConfigurator.Create("Knuckleblaster Parry", "KnuckleblasterParryDfcfg");
		string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		string iconWithURL = "file:///" + Path.Combine(directoryName, "icon.png").Replace("\\", "/");
		val.SetIconWithURL(iconWithURL);
		EnableParry = new BoolField(val.rootPanel, "Enable Parry", "Enable_parry", true);
		ParryWindowFrames = new IntField(val.rootPanel, "Parry Window Frames", "Parry_window_frames", 10, 1, 50);
		try
		{
			CacheMembers();
			harmony.PatchAll();
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)ex);
			throw;
		}
	}

	private void CacheMembers()
	{
		ccField = AccessTools.Field(typeof(Punch), "cc");
		camObjField = AccessTools.Field(typeof(Punch), "camObj");
		ppzField = AccessTools.Field(typeof(Punch), "ppz");
		boostedProjectileField = AccessTools.Field(typeof(Punch), "alreadyBoostedProjectile");
		hitCoinField = AccessTools.Field(typeof(Punch), "alreadyHitCoin");
		enemyIdentifierField = AccessTools.Field(typeof(Enemy), "eid");
		currentPunchField = AccessTools.Field(typeof(FistControl), "currentPunch");
		animatorField = AccessTools.Field(typeof(Punch), "anim");
		parryZoneProjectilesField = AccessTools.Field(typeof(ProjectileParryZone), "projs");
		tryParryProjectileMethod = AccessTools.Method(typeof(Punch), "TryParryProjectile", (Type[])null, (Type[])null);
		parryProjectileMethod = AccessTools.Method(typeof(Punch), "ParryProjectile", (Type[])null, (Type[])null);
		delayedPunchflectionMethod = AccessTools.Method(typeof(Coin), "DelayedPunchflection", (Type[])null, (Type[])null);
		if (parryZoneProjectilesField == null)
		{
			Log.LogError((object)"ProjectileParryZone.projs not found");
		}
		if (animatorField == null)
		{
			Log.LogError((object)"Punch.anim not found");
		}
		if (currentPunchField == null)
		{
			Log.LogError((object)"FistControl.currentPunch not found");
		}
		if (ppzField == null)
		{
			Log.LogError((object)"Punch.ppz not found");
		}
		if (ccField == null)
		{
			Log.LogError((object)"Punch.cc not found");
		}
		if (tryParryProjectileMethod == null)
		{
			Log.LogError((object)"Punch.TryParryProjectile not found");
		}
		if (parryProjectileMethod == null)
		{
			Log.LogError((object)"Punch.ParryProjectile not found");
		}
	}

	public static CameraController GetCameraController(Punch punch)
	{
		object? value = ccField.GetValue(punch);
		return (CameraController)((value is CameraController) ? value : null);
	}

	public static GameObject GetCameraObject(Punch punch)
	{
		object? value = camObjField.GetValue(punch);
		return (GameObject)((value is GameObject) ? value : null);
	}

	public static bool TryParry(Punch punch, Transform target, bool firstFrame)
	{
		if ((Object)(object)Plugin.GetTargetComponent<Chainsaw>(target) != (Object)null)
		{
			return false;
		}
		if (IsParriedProjectileTarget(target))
		{
			return false;
		}
		if (AlreadyParriedInHeavyWindow(punch, target))
		{
			return false;
		}
		Cannonball targetComponent = Plugin.GetTargetComponent<Cannonball>(target);
		if ((Object)(object)targetComponent != (Object)null)
		{
			Log.LogInfo((object)("Cannonball detected " + $"id={((Object)targetComponent).GetInstanceID()} " + $"firstFrame={firstFrame}"));
		}
		if ((Object)(object)targetComponent != (Object)null)
		{
			bool flag = (bool)tryParryProjectileMethod.Invoke(punch, new object[2] { target, firstFrame });
			if (!flag)
			{
				Log.LogWarning((object)("Cannonball TryParry failed " + $"id={((Object)targetComponent).GetInstanceID()} " + $"firstFrame={firstFrame}"));
			}
			if (flag)
			{
				MarkParriedInHeavyWindow(punch, target);
				punch.parriedSomething = true;
				punch.hitSomething = true;
			}
			return flag;
		}
		bool flag2 = (bool)tryParryProjectileMethod.Invoke(punch, new object[2] { target, firstFrame });
		if (flag2)
		{
			MarkParriedInHeavyWindow(punch, target);
			punch.parriedSomething = true;
			punch.hitSomething = true;
		}
		return flag2;
	}

	public static void ParryProjectile(Punch punch, Projectile projectile)
	{
		parryProjectileMethod.Invoke(punch, new object[1] { projectile });
	}

	public static void PunchflectCoin(Coin coin)
	{
		delayedPunchflectionMethod.Invoke(coin, null);
	}

	public static void RestoreAnimation(Punch punch, AnimationState savedState)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Invalid comparison between Unknown and I4
		if (!((Object)(object)punch == (Object)null) && (int)punch.type == 1 && savedState.active)
		{
			object? value = animatorField.GetValue(punch);
			Animator val = (Animator)((value is Animator) ? value : null);
			if (!((Object)(object)val == (Object)null))
			{
				val.ResetTrigger("Hook");
				val.Play(savedState.fullPathHash, 0, savedState.normalizedTime);
			}
		}
	}

	public static AnimationState SaveAnimationState(Punch punch)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Invalid comparison between Unknown and I4
		//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)
		AnimationState result = default(AnimationState);
		if ((Object)(object)punch == (Object)null || (int)punch.type != 1)
		{
			return result;
		}
		object? value = animatorField.GetValue(punch);
		Animator val = (Animator)((value is Animator) ? value : null);
		if ((Object)(object)val == (Object)null)
		{
			return result;
		}
		AnimatorStateInfo currentAnimatorStateInfo = val.GetCurrentAnimatorStateInfo(0);
		result.active = true;
		result.fullPathHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash;
		result.normalizedTime = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime;
		return result;
	}

	public static void StartHeavyParryWindow(Punch punch)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Invalid comparison between Unknown and I4
		if (!((Object)(object)punch == (Object)null) && (int)punch.type == 1)
		{
			heavyParryFrames[punch] = ParryWindowFrames.value;
			if (!heavyParryTargets.TryGetValue(punch, out var value))
			{
				value = new HashSet<int>();
				heavyParryTargets[punch] = value;
			}
			value.Clear();
		}
	}

	public static void ExtendHeavyMeleeWindow(Punch punch)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Invalid comparison between Unknown and I4
		if (!((Object)(object)punch == (Object)null) && (int)punch.type == 1)
		{
			int num = Mathf.Max(0, ParryWindowFrames.value - 1);
			if (punch.activeFrames < num)
			{
				punch.activeFrames = num;
			}
		}
	}

	public static bool UseHeavyParryFrame(Punch punch, out bool firstFrame)
	{
		firstFrame = false;
		if ((Object)(object)punch == (Object)null)
		{
			return false;
		}
		if (!heavyParryFrames.TryGetValue(punch, out var value))
		{
			return false;
		}
		if (value <= 0)
		{
			return false;
		}
		firstFrame = value == ParryWindowFrames.value;
		return true;
	}

	public static void FinishHeavyParryFrame(Punch punch)
	{
		if (!((Object)(object)punch == (Object)null) && heavyParryFrames.TryGetValue(punch, out var value))
		{
			heavyParryFrames[punch] = Mathf.Max(0, value - 1);
		}
	}

	public static bool HasHeavyParryFrames(Punch punch)
	{
		int value;
		return (Object)(object)punch != (Object)null && heavyParryFrames.TryGetValue(punch, out value) && value > 0;
	}

	public static PunchParryState SavePunchParryState(Punch punch)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Invalid comparison between Unknown and I4
		PunchParryState result = default(PunchParryState);
		if ((Object)(object)punch == (Object)null || (int)punch.type != 1)
		{
			return result;
		}
		result.animation = SaveAnimationState(punch);
		result.activeFrames = punch.activeFrames;
		result.keepActiveFrames = HasHeavyParryFrames(punch);
		return result;
	}

	public static void RestorePunchParryState(Punch punch, PunchParryState state)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Invalid comparison between Unknown and I4
		if (!((Object)(object)punch == (Object)null) && (int)punch.type == 1)
		{
			if (state.keepActiveFrames && punch.activeFrames < state.activeFrames)
			{
				punch.activeFrames = state.activeFrames;
			}
			RestoreAnimation(punch, state.animation);
		}
	}

	public static ProjectileParryZone GetParryZone(Punch punch)
	{
		object? value = ppzField.GetValue(punch);
		ProjectileParryZone val = (ProjectileParryZone)((value is ProjectileParryZone) ? value : null);
		if ((Object)(object)val != (Object)null)
		{
			return val;
		}
		val = ((Component)((Component)punch).transform.parent).GetComponentInChildren<ProjectileParryZone>();
		ppzField.SetValue(punch, val);
		return val;
	}

	public static Projectile GetClosestParryZoneProjectile(Punch punch, ProjectileParryZone ppz, HashSet<Transform> checkedTargets, bool firstFrame)
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: 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)
		if ((Object)(object)punch == (Object)null || (Object)(object)ppz == (Object)null || parryZoneProjectilesField == null)
		{
			return null;
		}
		if (!(parryZoneProjectilesField.GetValue(ppz) is List<GameObject> list))
		{
			return null;
		}
		Projectile result = null;
		float num = float.PositiveInfinity;
		Vector3 position = ((Component)ppz).transform.parent.position;
		for (int i = 0; i < list.Count; i++)
		{
			GameObject val = list[i];
			if ((Object)(object)val == (Object)null || !val.activeInHierarchy)
			{
				continue;
			}
			Projectile componentInChildren = val.GetComponentInChildren<Projectile>();
			if (!((Object)(object)componentInChildren == (Object)null) && !componentInChildren.parried && !componentInChildren.unparryable && !componentInChildren.undeflectable && !checkedTargets.Contains(((Component)componentInChildren).transform) && !AlreadyParriedInHeavyWindow(punch, ((Component)componentInChildren).transform) && (CanBoostProjectile(punch, firstFrame) || !componentInChildren.playerBullet))
			{
				float num2 = Vector3.Distance(position, val.transform.position);
				if (!(num2 >= num))
				{
					result = componentInChildren;
					num = num2;
				}
			}
		}
		return result;
	}

	public static bool CanBoostProjectile(Punch punch, bool firstFrame)
	{
		return !(bool)boostedProjectileField.GetValue(punch) && firstFrame;
	}

	public static bool AlreadyHitCoin(Punch punch)
	{
		return (bool)hitCoinField.GetValue(punch);
	}

	public static void SetCoinHit(Punch punch)
	{
		hitCoinField.SetValue(punch, true);
	}

	public static EnemyIdentifier GetEnemyIdentifier(Enemy enemy)
	{
		if ((Object)(object)enemy == (Object)null)
		{
			return null;
		}
		object? value = enemyIdentifierField.GetValue(enemy);
		return (EnemyIdentifier)((value is EnemyIdentifier) ? value : null);
	}

	public static EnemyIdentifier GetEnemyIdentifier(Component component)
	{
		if ((Object)(object)component == (Object)null)
		{
			return null;
		}
		FieldInfo fieldInfo = AccessTools.Field(((object)component).GetType(), "eid");
		if (fieldInfo == null)
		{
			return null;
		}
		object? value = fieldInfo.GetValue(component);
		return (EnemyIdentifier)((value is EnemyIdentifier) ? value : null);
	}

	public static EnemyIdentifier GetEnemyIdentifierFromTarget(Transform target)
	{
		if ((Object)(object)target == (Object)null)
		{
			return null;
		}
		ParryHelper val = default(ParryHelper);
		if (((Component)target).TryGetComponent<ParryHelper>(ref val) && (Object)(object)val.target != (Object)null)
		{
			target = val.target;
		}
		EnemyIdentifierIdentifier val2 = default(EnemyIdentifierIdentifier);
		if (((Component)target).TryGetComponent<EnemyIdentifierIdentifier>(ref val2))
		{
			return val2.eid;
		}
		EnemyIdentifier result = default(EnemyIdentifier);
		if (((Component)target).TryGetComponent<EnemyIdentifier>(ref result))
		{
			return result;
		}
		return null;
	}

	public static Punch GetCurrentPunch()
	{
		FistControl instance = MonoSingleton<FistControl>.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return null;
		}
		object? value = currentPunchField.GetValue(instance);
		return (Punch)((value is Punch) ? value : null);
	}

	public static T GetTargetComponent<T>(Transform target) where T : Component
	{
		if ((Object)(object)target == (Object)null)
		{
			return default(T);
		}
		ParryHelper val = default(ParryHelper);
		if (((Component)target).TryGetComponent<ParryHelper>(ref val) && (Object)(object)val.target != (Object)null)
		{
			target = val.target;
		}
		T result = default(T);
		if (((Component)target).TryGetComponent<T>(ref result))
		{
			return result;
		}
		return ((Component)target).GetComponentInParent<T>();
	}

	public static int GetParryTargetId(Transform target)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Invalid comparison between Unknown and I4
		if ((Object)(object)target == (Object)null)
		{
			return 0;
		}
		Projectile targetComponent = Plugin.GetTargetComponent<Projectile>(target);
		if ((Object)(object)targetComponent != (Object)null && (int)targetComponent.safeEnemyType == 41)
		{
			return -42;
		}
		Component val = (Component)(object)Plugin.GetTargetComponent<Cannonball>(target);
		if ((Object)(object)val == (Object)null)
		{
			val = (Component)(object)Plugin.GetTargetComponent<ThrownSword>(target);
		}
		if ((Object)(object)val == (Object)null)
		{
			val = (Component)(object)Plugin.GetTargetComponent<ParryReceiver>(target);
		}
		if ((Object)(object)val == (Object)null)
		{
			val = (Component)(object)Plugin.GetTargetComponent<MassSpear>(target);
		}
		if ((Object)(object)val == (Object)null)
		{
			val = (Component)(object)Plugin.GetTargetComponent<Landmine>(target);
		}
		if ((Object)(object)val == (Object)null)
		{
			val = (Component)(object)Plugin.GetTargetComponent<GroundWave>(target);
		}
		if ((Object)(object)val == (Object)null)
		{
			val = (Component)(object)targetComponent;
		}
		if ((Object)(object)val != (Object)null)
		{
			return ((Object)val).GetInstanceID();
		}
		return ((Object)target).GetInstanceID();
	}

	public static bool AlreadyParriedInHeavyWindow(Punch punch, Transform target)
	{
		int parryTargetId = GetParryTargetId(target);
		HashSet<int> value;
		return (Object)(object)punch != (Object)null && parryTargetId != 0 && heavyParryTargets.TryGetValue(punch, out value) && value.Contains(parryTargetId);
	}

	public static void MarkParriedInHeavyWindow(Punch punch, Transform target)
	{
		int parryTargetId = GetParryTargetId(target);
		if (!((Object)(object)punch == (Object)null) && parryTargetId != 0)
		{
			if (!heavyParryTargets.TryGetValue(punch, out var value))
			{
				value = new HashSet<int>();
				heavyParryTargets[punch] = value;
			}
			value.Add(parryTargetId);
		}
	}

	public static bool IsParriedProjectileTarget(Transform target)
	{
		if ((Object)(object)target == (Object)null)
		{
			return false;
		}
		Projectile targetComponent = Plugin.GetTargetComponent<Projectile>(target);
		if ((Object)(object)targetComponent != (Object)null && targetComponent.parried)
		{
			return true;
		}
		return false;
	}

	public static bool IsRangedParryTarget(Transform target)
	{
		if ((Object)(object)target == (Object)null)
		{
			return false;
		}
		if ((Object)(object)Plugin.GetTargetComponent<Projectile>(target) != (Object)null)
		{
			return true;
		}
		if ((Object)(object)Plugin.GetTargetComponent<Cannonball>(target) != (Object)null)
		{
			return true;
		}
		if ((Object)(object)Plugin.GetTargetComponent<MassSpear>(target) != (Object)null)
		{
			return true;
		}
		if ((Object)(object)Plugin.GetTargetComponent<Landmine>(target) != (Object)null)
		{
			return true;
		}
		if ((Object)(object)Plugin.GetTargetComponent<GroundWave>(target) != (Object)null)
		{
			return true;
		}
		ThrownSword targetComponent = Plugin.GetTargetComponent<ThrownSword>(target);
		if ((Object)(object)targetComponent != (Object)null)
		{
			return !targetComponent.friendly && targetComponent.active;
		}
		ParryReceiver targetComponent2 = Plugin.GetTargetComponent<ParryReceiver>(target);
		if ((Object)(object)targetComponent2 != (Object)null && ((Behaviour)targetComponent2).enabled)
		{
			return true;
		}
		return false;
	}

	public static bool TryStartFeedbackerMask(EnemyIdentifier eid, out FeedbackerMaskState state)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Invalid comparison between Unknown and I4
		//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_00cd: Unknown result type (might be due to invalid IL or missing references)
		state = default(FeedbackerMaskState);
		if (!EnableParry.value)
		{
			return false;
		}
		if ((Object)(object)eid == (Object)null || eid.hitter != "heavypunch")
		{
			return false;
		}
		Punch currentPunch = GetCurrentPunch();
		if ((Object)(object)currentPunch == (Object)null)
		{
			return false;
		}
		if ((int)currentPunch.type != 1)
		{
			return false;
		}
		if (!HasHeavyParryFrames(currentPunch))
		{
			return false;
		}
		state.active = true;
		state.eid = eid;
		state.oldHitter = eid.hitter;
		state.punch = currentPunch;
		state.oldPunchType = currentPunch.type;
		state.animation = SaveAnimationState(currentPunch);
		eid.hitter = "punch";
		currentPunch.type = (FistType)0;
		return true;
	}

	public static bool TryStartFeedbackerMaskForParryableEnemy(Enemy enemy, out FeedbackerMaskState state)
	{
		state = default(FeedbackerMaskState);
		if ((Object)(object)enemy == (Object)null)
		{
			return false;
		}
		if (!enemy.parryable && !enemy.partiallyParryable && enemy.parryFramesLeft <= 0)
		{
			return false;
		}
		return TryStartFeedbackerMask(GetEnemyIdentifier(enemy), out state);
	}

	public static void RestoreFeedbackerMask(FeedbackerMaskState state)
	{
		//IL_0049: 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)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Invalid comparison between Unknown and I4
		if (!state.active)
		{
			return;
		}
		if ((Object)(object)state.eid != (Object)null)
		{
			state.eid.hitter = state.oldHitter;
		}
		if ((Object)(object)state.punch != (Object)null)
		{
			state.punch.type = state.oldPunchType;
			if ((int)state.oldPunchType == 1)
			{
				RestoreAnimation(state.punch, state.animation);
			}
		}
	}
}
[HarmonyPatch(typeof(LeaderboardController))]
public static class LeaderboardBlocker
{
	[HarmonyPatch("SubmitLevelScore")]
	[HarmonyPrefix]
	private static bool BlockLevelScores()
	{
		MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Leaderboards are disabled - Knuckleblaster Parry.", "", "", 0, false, false, true);
		return false;
	}

	[HarmonyPatch("SubmitCyberGrindScore")]
	[HarmonyPrefix]
	private static bool BlockCyberGrindScores()
	{
		MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Leaderboards are disabled = Knuckleblaster Parry.", "", "", 0, false, false, true);
		return false;
	}
}
[HarmonyPatch(typeof(Punch), "FixedUpdate")]
public class HeavyParryPatch
{
	private const int ParryMask = 16384;

	private const float ParryRange = 4f;

	private static void Prefix(Punch __instance, ref bool __state)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		__state = (Object)(object)__instance != (Object)null && Plugin.EnableParry.value && (int)__instance.type == 1 && Plugin.HasHeavyParryFrames(__instance);
		try
		{
			RunHeavyParryWindow(__instance);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)ex);
		}
	}

	private static void Postfix(Punch __instance, bool __state)
	{
		if (__state)
		{
			Plugin.FinishHeavyParryFrame(__instance);
		}
	}

	public static void RunImmediateFrame(Punch punch)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		if ((Object)(object)punch == (Object)null || !Plugin.EnableParry.value || (int)punch.type != 1 || !Plugin.HasHeavyParryFrames(punch))
		{
			return;
		}
		try
		{
			RunHeavyParryWindow(punch);
			Plugin.Log.LogInfo((object)("ImmediateFrame executed " + $"punch={((Object)punch).GetInstanceID()}"));
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)ex);
		}
		finally
		{
			Plugin.FinishHeavyParryFrame(punch);
		}
	}

	private static void RunHeavyParryWindow(Punch __instance)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Invalid comparison between Unknown and I4
		if ((Object)(object)__instance == (Object)null || !Plugin.EnableParry.value || (int)__instance.type != 1 || !Plugin.UseHeavyParryFrame(__instance, out var firstFrame))
		{
			return;
		}
		CameraController cameraController = Plugin.GetCameraController(__instance);
		GameObject cameraObject = Plugin.GetCameraObject(__instance);
		if (!((Object)(object)cameraController == (Object)null) && !((Object)(object)cameraObject == (Object)null))
		{
			HashSet<Transform> checkedTargets = new HashSet<Transform>();
			if (!TryParryOverlaps(__instance, cameraController, checkedTargets, firstFrame) && !TryParryRaycast(__instance, cameraController, cameraObject, checkedTargets, firstFrame) && !TryParryZoneProjectile(__instance, checkedTargets, firstFrame))
			{
				TryPunchflectCoin(__instance, cameraController, cameraObject);
			}
		}
	}

	private static bool TryParryOverlaps(Punch punch, CameraController cc, HashSet<Transform> checkedTargets, bool firstFrame)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		Collider[] array = Physics.OverlapSphere(cc.GetDefaultPos(), 0.25f, 16384, (QueryTriggerInteraction)2);
		foreach (Collider val in array)
		{
			Transform val2 = (((Object)(object)val.attachedRigidbody != (Object)null) ? ((Component)val.attachedRigidbody).transform : ((Component)val).transform);
			checkedTargets.Add(val2);
			checkedTargets.Add(((Component)val).transform);
			if ((Object)(object)Plugin.GetTargetComponent<Cannonball>(val2) != (Object)null)
			{
			}
			if (Plugin.IsRangedParryTarget(val2) && Plugin.TryParry(punch, val2, firstFrame))
			{
				return true;
			}
		}
		return false;
	}

	private static bool TryParryRaycast(Punch punch, CameraController cc, GameObject camObj, HashSet<Transform> checkedTargets, bool firstFrame)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		RaycastHit val = default(RaycastHit);
		bool flag = Physics.Raycast(cc.GetDefaultPos(), camObj.transform.forward, ref val, 4f, 16384);
		if (!flag)
		{
			flag = Physics.BoxCast(cc.GetDefaultPos(), Vector3.one * 0.3f, camObj.transform.forward, ref val, camObj.transform.rotation, 4f, 16384);
		}
		if (!flag)
		{
			return false;
		}
		if (checkedTargets.Contains(((RaycastHit)(ref val)).transform))
		{
			return false;
		}
		checkedTargets.Add(((RaycastHit)(ref val)).transform);
		if (!Plugin.IsRangedParryTarget(((RaycastHit)(ref val)).transform))
		{
			return false;
		}
		return Plugin.TryParry(punch, ((RaycastHit)(ref val)).transform, firstFrame);
	}

	private static bool TryParryZoneProjectile(Punch punch, HashSet<Transform> checkedTargets, bool firstFrame)
	{
		ProjectileParryZone parryZone = Plugin.GetParryZone(punch);
		if ((Object)(object)parryZone == (Object)null)
		{
			return false;
		}
		Projectile closestParryZoneProjectile = Plugin.GetClosestParryZoneProjectile(punch, parryZone, checkedTargets, firstFrame);
		if ((Object)(object)closestParryZoneProjectile == (Object)null)
		{
			return false;
		}
		Plugin.ParryProjectile(punch, closestParryZoneProjectile);
		Plugin.MarkParriedInHeavyWindow(punch, ((Component)closestParryZoneProjectile).transform);
		punch.parriedSomething = true;
		punch.hitSomething = true;
		return true;
	}

	private static void TryPunchflectCoin(Punch punch, CameraController cc, GameObject camObj)
	{
		//IL_0011: 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_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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)
		if (Plugin.AlreadyHitCoin(punch))
		{
			return;
		}
		RaycastHit[] array = Physics.SphereCastAll(new Ray(cc.GetDefaultPos(), camObj.transform.forward), 0.35f, 4f, -1, (QueryTriggerInteraction)2);
		Coin val = null;
		float num = float.PositiveInfinity;
		for (int i = 0; i < array.Length; i++)
		{
			RaycastHit val2 = array[i];
			Coin val3 = (((Object)(object)((RaycastHit)(ref val2)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Coin>() : null);
			if (!((Object)(object)val3 == (Object)null) && !(((RaycastHit)(ref val2)).distance >= num))
			{
				val = val3;
				num = ((RaycastHit)(ref val2)).distance;
			}
		}
		if (!((Object)(object)val == (Object)null))
		{
			Plugin.PunchflectCoin(val);
			Plugin.SetCoinHit(punch);
			punch.hitSomething = true;
		}
	}
}
[HarmonyPatch(typeof(Punch), "ActiveStart")]
public class HeavyParryWindowPatch
{
	private static void Prefix(Punch __instance)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Invalid comparison between Unknown and I4
		if (!((Object)(object)__instance == (Object)null) && Plugin.EnableParry.value && (int)__instance.type == 1)
		{
			Plugin.StartHeavyParryWindow(__instance);
		}
	}

	private static void Postfix(Punch __instance)
	{
		Plugin.ExtendHeavyMeleeWindow(__instance);
		HeavyParryPatch.RunImmediateFrame(__instance);
	}
}
[HarmonyPatch(typeof(Enemy), "GetHurt")]
public class EnemyGetHurtParryPatch
{
	private static void Prefix(Enemy __instance, ref Plugin.FeedbackerMaskState __state)
	{
		Plugin.TryStartFeedbackerMaskForParryableEnemy(__instance, out __state);
	}

	private static void Postfix(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}

	private static void Finalizer(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}
}
[HarmonyPatch(typeof(Enemy), "HandleParrying")]
public class EnemyParryPatch
{
	private static void Prefix(Enemy __instance, ref Plugin.FeedbackerMaskState __state)
	{
		EnemyIdentifier enemyIdentifier = Plugin.GetEnemyIdentifier(__instance);
		Plugin.TryStartFeedbackerMask(enemyIdentifier, out __state);
	}

	private static void Postfix(Enemy __instance, Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}

	private static void Finalizer(Enemy __instance, Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}
}
[HarmonyPatch(typeof(Statue), "GetHurt")]
public class StatueParryPatch
{
	private static void Prefix(Statue __instance, ref Plugin.FeedbackerMaskState __state)
	{
		Plugin.TryStartFeedbackerMask(Plugin.GetEnemyIdentifier((Enemy)(object)__instance), out __state);
	}

	private static void Postfix(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}

	private static void Finalizer(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}
}
[HarmonyPatch(typeof(Drone), "GetHurt")]
public class DroneParryPatch
{
	private static void Prefix(Drone __instance, ref Plugin.FeedbackerMaskState __state)
	{
		Plugin.TryStartFeedbackerMask(Plugin.GetEnemyIdentifier((Component)(object)__instance), out __state);
	}

	private static void Postfix(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}

	private static void Finalizer(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}
}
[HarmonyPatch(typeof(Machine), "GetHurt")]
public class MachineParryPatch
{
	private static void Prefix(Machine __instance, ref Plugin.FeedbackerMaskState __state)
	{
		Plugin.TryStartFeedbackerMask(Plugin.GetEnemyIdentifier((Enemy)(object)__instance), out __state);
	}

	private static void Postfix(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}

	private static void Finalizer(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}
}
[HarmonyPatch(typeof(Zombie), "GetHurt")]
public class ZombieParryPatch
{
	private static void Prefix(Zombie __instance, ref Plugin.FeedbackerMaskState __state)
	{
		Plugin.TryStartFeedbackerMask(Plugin.GetEnemyIdentifier((Enemy)(object)__instance), out __state);
	}

	private static void Postfix(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}

	private static void Finalizer(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}
}
[HarmonyPatch(typeof(SpiderBody), "GetHurt")]
public class SpiderBodyParryPatch
{
	private static void Prefix(SpiderBody __instance, ref Plugin.FeedbackerMaskState __state)
	{
		Plugin.TryStartFeedbackerMask(Plugin.GetEnemyIdentifier((Component)(object)__instance), out __state);
	}

	private static void Postfix(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}

	private static void Finalizer(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}
}
[HarmonyPatch(typeof(MaliciousFace), "OnParry")]
public class MaliciousFaceParryPatch
{
	private static void Prefix(MaliciousFace __instance, ref Plugin.FeedbackerMaskState __state)
	{
		Plugin.TryStartFeedbackerMask(Plugin.GetEnemyIdentifier((Component)(object)__instance), out __state);
	}

	private static void Postfix(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}

	private static void Finalizer(Plugin.FeedbackerMaskState __state)
	{
		Plugin.RestoreFeedbackerMask(__state);
	}
}
[HarmonyPatch(typeof(Punch), "PunchSuccess")]
public class ScrewdriverPunchThroughPatch
{
	private static void Prefix(Punch __instance, Transform target, ref Plugin.ScrewdriverPunchState __state)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Invalid comparison between Unknown and I4
		//IL_0094: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
		Cannonball targetComponent = Plugin.GetTargetComponent<Cannonball>(target);
		if ((Object)(object)targetComponent != (Object)null)
		{
			__state.active = true;
			__state.oldType = __instance.type;
			__state.animation = Plugin.SaveAnimationState(__instance);
			__instance.type = (FistType)0;
		}
		else if (!((Object)(object)__instance == (Object)null) && (int)__instance.type == 1)
		{
			EnemyIdentifier enemyIdentifierFromTarget = Plugin.GetEnemyIdentifierFromTarget(target);
			if (!((Object)(object)enemyIdentifierFromTarget == (Object)null) && enemyIdentifierFromTarget.drillers != null && enemyIdentifierFromTarget.drillers.Count != 0)
			{
				__state.active = true;
				__state.oldType = __instance.type;
				__state.animation = Plugin.SaveAnimationState(__instance);
				__instance.type = (FistType)0;
			}
		}
	}

	private static void Postfix(Punch __instance, Plugin.ScrewdriverPunchState __state)
	{
		RestorePunch(__instance, __state);
	}

	private static void Finalizer(Punch __instance, Plugin.ScrewdriverPunchState __state)
	{
		RestorePunch(__instance, __state);
	}

	private static void RestorePunch(Punch punch, Plugin.ScrewdriverPunchState state)
	{
		//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)
		if (!((Object)(object)punch == (Object)null) && state.active)
		{
			punch.type = state.oldType;
			Plugin.RestoreAnimation(punch, state.animation);
		}
	}
}
[HarmonyPatch(typeof(LeviathanHead), "GotParried")]
public class LeviathanHeadParryAnimationPatch
{
	private static void Prefix(ref Plugin.AnimationState __state)
	{
		__state = Plugin.SaveAnimationState(Plugin.GetCurrentPunch());
	}

	private static void Postfix(Plugin.AnimationState __state)
	{
		Plugin.RestoreAnimation(Plugin.GetCurrentPunch(), __state);
	}
}
[HarmonyPatch(typeof(LeviathanController), "GotParried")]
public class LeviathanControllerParryAnimationPatch
{
	private static void Prefix(ref Plugin.AnimationState __state)
	{
		__state = Plugin.SaveAnimationState(Plugin.GetCurrentPunch());
	}

	private static void Postfix(Plugin.AnimationState __state)
	{
		Plugin.RestoreAnimation(Plugin.GetCurrentPunch(), __state);
	}
}
[HarmonyPatch(typeof(Punch), "Parry")]
public class HeavyParryAnimationPatch
{
	private static void Prefix(Punch __instance, ref Plugin.PunchParryState __state)
	{
		__state = Plugin.SavePunchParryState(__instance);
	}

	private static void Postfix(Punch __instance, Plugin.PunchParryState __state)
	{
		Plugin.RestorePunchParryState(__instance, __state);
	}
}
[HarmonyPatch(typeof(Punch), "ParryProjectile")]
public class ProjectileParryAnimationPatch
{
	private static void Prefix(Punch __instance, ref Plugin.AnimationState __state)
	{
		__state = Plugin.SaveAnimationState(__instance);
	}

	private static void Postfix(Punch __instance, Plugin.AnimationState __state)
	{
		Plugin.RestoreAnimation(__instance, __state);
	}
}
[HarmonyPatch(typeof(Punch), "TryParryProjectile")]
public class TryParryAnimationPatch
{
	private static void Prefix(Punch __instance, ref Plugin.AnimationState __state)
	{
		__state = Plugin.SaveAnimationState(__instance);
	}

	private static void Postfix(Punch __instance, Plugin.AnimationState __state, bool __result)
	{
		if (__result)
		{
			Plugin.RestoreAnimation(__instance, __state);
		}
	}
}
[HarmonyPatch(typeof(Cannonball), "Break")]
public class CannonballBreakBlockPatch
{
	private static bool Prefix(Cannonball __instance)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Invalid comparison between Unknown and I4
		Punch currentPunch = Plugin.GetCurrentPunch();
		if ((Object)(object)currentPunch != (Object)null && (int)currentPunch.type == 1 && Plugin.HasHeavyParryFrames(currentPunch))
		{
			Plugin.Log.LogWarning((object)("Cannonball Break intercepted " + $"window={Plugin.HasHeavyParryFrames(currentPunch)} " + $"id={((Object)__instance).GetInstanceID()}"));
			return false;
		}
		return true;
	}
}